none
HTA Pop-up Table Trouble

    Question

  • I've got a pop-up in an HTA that's giving me fits.  The pop-up is a table that is triggered off a text input box.  I want to be able to populate that text input box based on the cells that are clicked in the pop-up table.  I've got everything working, except for 2 things:

    1. The "onclick" value for each cell in the table doesn't recognize the function that I'm calling when I click it.  It just says "'functionName' is undefined", even though the very same function can be run from elements in the main body of the HTML.  I believe this is a parent/child issue.  But I'm not sure, and I can't seem to figure it out.
    2. Once I click a cell in the table, I'm not quite sure how I identify which cell was pressed in the function that gets called using "onclick".  I could create a separate function for each cell to call, but I was hoping to have 1 function that was smart enough to know which cell called it and Msgbox (for now) which one that was.

    Here's the code that's giving me fits.  And for the record, I know that VBScript isn't cross browser friendly, but I need to expand this into other things that require it later.  Also, my secondary goal is to keep this HTA entirely self contained, no external files.

    <html>
    	<head>
    		<title>PickTable</title>
    		<hta:application
    		scroll="no"
    		singleinstance="no"
    		windowstate="normal"
    		>
    	</head>
    
    	<SCRIPT Language="VBScript">
    	Dim TablePopup ' Hidden/Pop-up PickTable variable must be declared globally.
    
    	Function RunTest()
    		Msgbox "A choise has been clicked."
    	End Function
    
    	Function ShowTable()
    		' Dim PopupBody
    	 
    		Set TablePopup = Window.createPopup()
    		intMouseX = Window.Event.OffsetX + 10
    		intMouseY = Window.Event.OffsetY + 15
    
    		TablePopup.Document.Body.Style.BackgroundColor = "white"
    		TablePopup.Document.Body.Style.Border = "1px solid black"
    		TablePopup.Document.Body.Style.cursor = "default"
    		TablePopup.Document.Body.Style.FontFamily = "tahoma"
    		TablePopup.Document.Body.Style.FontSize = "10pt"
    		TablePopup.Document.Body.Style.OverflowY = "auto"
    		TablePopup.Document.Body.Style.PaddingLeft = "5px"
    		TablePopup.Document.Body.innerHTML = HiddenTable.innerHTML
    		TablePopup.Show intMouseX, intMouseY, 200, 100, document.body
    
    	End Function
    
    	</script>
    
    	<BODY>
    		<input id="DateTextBox" type="text" value="click here" onclick="ShowTable">
    
    		<table>
    			<tr>
    				<td>
    					<span onclick="RunTest">Choise 1</span>
    				</td>
    				<td>
    					<span onclick="RunTest">Choise 2</span>
    				</td>
    			</tr>
    		</table>
    
    		<DIV id="HiddenTable" style="display:none">
    			<DIV>
    				<table>
    					<tr>
    						<td onmouseover="this.style.background='#E0E0E0'"
    						  onmouseout="this.style.background='none'">
    							<span onclick="RunTest">Choise 3</span>
    						</td>
    						<td onmouseover="this.style.background='#E0E0E0'"
    						  onmouseout="this.style.background='none'">
    							<span onclick="RunTest">Choise 4</span>
    						</td>
    					</tr>
    					<tr>
    						<td onmouseover="this.style.background='#E0E0E0'"
    						  onmouseout="this.style.background='none'">
    							<span onclick="RunTest">Choise 5</span>
    						</td>
    						<td onmouseover="this.style.background='#E0E0E0'"
    						  onmouseout="this.style.background='none'">
    							<span onclick="RunTest">Choise 6</span>
    						</td>
    					</tr>
    				</table>
    			</DIV>
    			<DIV onmouseover="this.style.background='grey'"
    			   onmouseout="this.style.background='none'" 
    				<SPAN onclick="parent.location.href='http://www.google.com'">Google</SPAN> 
    			</DIV>
    		</DIV>
    	</BODY>
    </html>
    
    

    Thank you in advance!

    Thursday, August 04, 2011 9:32 PM

Answers

  • I beg to differ with my learned colleague jrv, but most of what has been said here so far doesn't seem right to me.  Here is an approach that seems to me to do everything you want wityhout putting script into the popup (except for the snippets in the controls themselves) and the window closes automatically when it looses focus ...

    <html>
     <head>
      <title>PickTable</title>
      <hta:application
      scroll="no"
      singleinstance="no"
      windowstate="normal"
      >
     </head>

     <SCRIPT Language="VBScript">
     Dim TablePopup ' Hidden/Pop-up PickTable variable must be declared globally.

     Function RunTest()
      Msgbox "A choise " & TablePopup.document.all.hSelection.value & " was clicked."
     End Function

     Function RunTest2()
      Msgbox "A choise " & hSelection.value & " was clicked."
     End Function
     Function ShowTable()
      ' Dim PopupBody
     
      Set TablePopup = Window.createPopup()
      intMouseX = Window.Event.OffsetX + 10
      intMouseY = Window.Event.OffsetY + 15

      with TablePopup.Document.Body
       .Style.BackgroundColor = "white"
       .Style.Border = "1px solid black"
       .Style.cursor = "default"
       .Style.FontFamily = "tahoma"
       .Style.FontSize = "10pt"
       .Style.OverflowY = "auto"
       .Style.PaddingLeft = "5px"
       .innerHTML = HiddenTable.innerHTML
      end with ' TablePopup.Document.Body
      TablePopup.Show intMouseX, intMouseY, 200, 100, document.body
      TablePopup.document.all.hSelection.onclick = getRef("RunTest")

     End Function

     </script>

     <BODY>
      <input id="DateTextBox" type="text" value="click here" onclick="ShowTable">

      <table>
       <tr>
        <td>
         <span onclick="hselection.value=1:Runtest2">Choise 1</span>
        </td>
        <td>
         <span onclick="hselection.value=2:Runtest2">Choise 2</span>
        </td>
       </tr>
      </table>

      <DIV id="HiddenTable" style="display:none">
       <DIV>
        <table>
         <tr>
          <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'">
           <span onclick="vbscript:hselection.value=3:hselection.click">Choise 3</span>
          </td>
          <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'">
           <span onclick="vbscript:hselection.value=4:hselection.click">Choise 4</span>
          </td>
         </tr>
         <tr>
          <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'">
           <span onclick="vbscript:hselection.value=5:hselection.click">Choise 5</span>
          </td>
          <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'">
           <span onclick="vbscript:hselection.value=6:hselection.click">Choise 6</span>
          </td>
         </tr>
        </table>
       </DIV>
       <DIV onmouseover="this.style.background='grey'"
          onmouseout="this.style.background='none'"
        <SPAN onclick="parent.location.href='http://www.google.com'">Google</SPAN>
       </DIV>
       <input type=hidden id="hselection" onclick="vbscript:msgbox hselection.value">
      </DIV>
     </BODY>
    </html>

    BTW, I like the use of the hidden DIV to store the HTML for the popup.  I usually do that by writing to the document, but you technique is better, I think.

    Question:  Is "choise" an English spelling?  We Americans spell it "choice".


    Tom Lavedas
    • Marked as answer by RussellNS Friday, August 05, 2011 6:47 PM
    Friday, August 05, 2011 1:44 PM
    Moderator

All replies

  • Has to be a Sub.  Fuctions cannot be called in events.  Change to Sub and it will likely work.

     


    jv
    Thursday, August 04, 2011 10:23 PM
  • Also you can't call back to code in teh parent of teh Popup.

    If you want more functionality you need to use a Dialog.

    Look into showModalDialog and showModelessDialog.

    Popups are just for basic info.

     


    jv
    Thursday, August 04, 2011 10:30 PM
  • Great suggestion, and thank you.  However, I changed them from Subs to Functions as a troubleshooting effort before I submitted.  I forgot to change them back.  I get the same results either way, as Functions or Subs.

    I'm thinking it has something to do with the parent/child relationship.  In the HiddenTable elements themselves I've tried onclick="parent.location='RunTest'" and onclick="this.document='RunTest'" as well as a few others I forget.  I've also tried changing the way the ShowTable Sub populates the table with similar permutations, and I can't seem to find joy.

    Any and all help is welcome.

     

    Thank you,

    Neal

    Thursday, August 04, 2011 10:34 PM
  • You cannot call scripts from a popup.  It is a security and functionality restriction. You can embed whatever you want into the popup but no script.  That is why I recommended using a modal dialog.  It is allowed to run scripts and to send mesages back the the parent.

     

     


    jv
    Thursday, August 04, 2011 10:41 PM
  • I wanted to say THANK YOU SOOO MUCH!!! I read your statement that "you can't call back to code in the parent" as if to mean "maybe you can call code if it's included with the child." So I tinkered with it a bit and got something to work.

    It's not exactly what I wanted, but at least I can use it as a foundation to build from.

    The only thing it won't do is reset the "hidden" style without losing focus. Can you think of another way to do that?  Is there a way to forcibly close a pop-up from a script contained within the pop-up?

    Oh, and I do plan on checking out showModalDialog and showModelessDialog.  Thank you for those suggestions as well!  What I'm doing will probably be easier that way, but this way seems like it has the potential to look more seamless.  So for now I'll run with this until I punt and go the showModal approach.  Here's the code:

    <html>
    	<head>
    		<title>PickTable</title>
    		<hta:application
    		scroll="no"
    		singleinstance="no"
    		windowstate="normal"
    		>
    	</head>
    
    	<SCRIPT Language="VBScript" id="HTAScripts">
    		Dim objCallingElement ' Future functionality - multiple text boxs
    		Dim TablePopup     ' Hidden/Pop-up PickTable variable must be
    		            ' declared globally.
    
    		Function RunTest()
    			Msgbox "A choise has been clicked."
    		End Function
    
    		Function ShowTable(objCell)
    			objCallingElement = objCell
    			Set TablePopup = Window.createPopup()
    			intMouseX = Window.Event.OffsetX + 10
    			intMouseY = Window.Event.OffsetY + 15
    
    			TablePopup.Document.Body.Style.BackgroundColor = "white"
    			TablePopup.Document.Body.Style.Border = "1px solid black"
    			TablePopup.Document.Body.Style.cursor = "default"
    			TablePopup.Document.Body.Style.FontFamily = "tahoma"
    			TablePopup.Document.Body.Style.FontSize = "10pt"
    			TablePopup.Document.Body.Style.OverflowY = "auto"
    			TablePopup.Document.Body.Style.PaddingLeft = "5px"
    			TablePopup.Document.Body.innerHTML = HiddenTable.innerHTML
    			TablePopup.Show intMouseX, intMouseY, 200, 100, document.body
    		End Function
    	</script>
    
    	<BODY>
    		<input id="InputTextBox1" type="text"
    		  value="click here" onclick="ShowTable(me)">
    
    		<table>
    			<tr>
    				<td>
    					<span onclick="RunTest">Choise 1</span>
    				</td>
    				<td>
    					<span onclick="RunTest">Choise 2</span>
    				</td>
    			</tr>
    		</table>
    
    		<DIV id="HiddenTable" style="display:none">
    			<table>
    				<tr>
    					<td onmouseover="this.style.background='#E0E0E0'"
    						onmouseout="this.style.background='none'">
    						<span id="Choise3" value="30">Choise 3</span>
    						<SCRIPT LANGUAGE="VBScript"
    						      EVENT="OnClick" FOR="Choise3">
    						<!--
    							Parent.InputTextBox1.Value = Choise3.Value
    							Parent.HiddenTable.Style.Visibility = "hidden"
    						-->
    						</SCRIPT>
    					</td>
    					<td onmouseover="this.style.background='#E0E0E0'"
    						onmouseout="this.style.background='none'">
    						<span id="Choise4">Choise 4</span>
    						<SCRIPT LANGUAGE="VBScript"
    						      EVENT="OnClick" FOR="Choise4">
    						<!--
    							Parent.InputTextBox1.Value = "Choise4"
    							Parent.HiddenTable.Style.Visibility = "hidden"
    						-->
    						</SCRIPT>
    					</td>
    				</tr>
    				<tr>
    					<td onmouseover="this.style.background='#E0E0E0'"
    						onmouseout="this.style.background='none'">
    						<span id="Choise5">Choise 5</span>
    						<SCRIPT LANGUAGE="VBScript"
    						      EVENT="OnClick" FOR="Choise5">
    						<!--
    							Parent.InputTextBox1.Value = "Choise5"
    							Parent.HiddenTable.Style.Visibility = "hidden"
    						-->
    						</SCRIPT>
    					</td>
    					<td onmouseover="this.style.background='#E0E0E0'"
    						onmouseout="this.style.background='none'">
    						<span id="Choise6">Choise 6</span>
    						<SCRIPT LANGUAGE="VBScript"
    						      EVENT="OnClick" FOR="Choise6">
    						<!--
    							Parent.InputTextBox1.Value = "Choise6"
    							If Choise3.Value = 30 Then
    								Choise3.Value = 60
    							End If
    							Parent.HiddenTable.Style.Visibility = "hidden"
    						-->
    						</SCRIPT>
    					</td>
    				</tr>
    			</table>
    			<DIV onmouseover="this.style.background='grey'"
    				 onmouseout="this.style.background='none'" >
    				 <SPAN onclick="parent.location.href='http://www.google.com'">
    					Google
    				</SPAN> 
    			</DIV>
    		</DIV>
    	</BODY>
    </html>
    
    

    Friday, August 05, 2011 5:48 AM
  • Ok - you found a leak.  I can show you why it will not work.

    Change your line:  Parent.HiddenTable.Style.Visibility = "hidden"
    TO: window.close

    Watch what happens. YOu will see that it does work however, it will alwaysvause a security challenge. Popup windows are security limited.  They cannot be hiden windows.  In fact, in IE no window can be hidden.  An objest can ge hidden,

    Add in this line: Me.style.visibility="hidden"
    Note that the object can be hidden.

    This wont work: Me.parent.style.visibility="hidden"

    The scope allowed i very limited.  Objects are not allowed to touch other object and events don't bubble.  This  has allbeen done to prevent exactly what you are trying to do.  It was done to prevent malware from doing bad things.  Years ago much of waht you aretrying to do actually worked although the model clearly was never intended to work that way.

    The wat we do context menus is with html injection.  We insert a bit of html at the locationfor th menu.  It is not a popup.  It just shows and hides.  All script then works correctly.

    There ae numerous free Javscript libraries for managing menus.  Here is an example of one:
    http://www.javascriptkit.com/script/script2/outlinemenu.shtml This one is pretty cool as it is animated.

    If you look at teh DOM reference you will notice that only IE supports the createPopup method.  Micorsft keeps it for legacy support but it will disappear in future versions of IE.  HTML5 has better ways for creating menus based on CSS and behaviors I believe.

     

     

     


    jv
    Friday, August 05, 2011 8:19 AM
  • I beg to differ with my learned colleague jrv, but most of what has been said here so far doesn't seem right to me.  Here is an approach that seems to me to do everything you want wityhout putting script into the popup (except for the snippets in the controls themselves) and the window closes automatically when it looses focus ...

    <html>
     <head>
      <title>PickTable</title>
      <hta:application
      scroll="no"
      singleinstance="no"
      windowstate="normal"
      >
     </head>

     <SCRIPT Language="VBScript">
     Dim TablePopup ' Hidden/Pop-up PickTable variable must be declared globally.

     Function RunTest()
      Msgbox "A choise " & TablePopup.document.all.hSelection.value & " was clicked."
     End Function

     Function RunTest2()
      Msgbox "A choise " & hSelection.value & " was clicked."
     End Function
     Function ShowTable()
      ' Dim PopupBody
     
      Set TablePopup = Window.createPopup()
      intMouseX = Window.Event.OffsetX + 10
      intMouseY = Window.Event.OffsetY + 15

      with TablePopup.Document.Body
       .Style.BackgroundColor = "white"
       .Style.Border = "1px solid black"
       .Style.cursor = "default"
       .Style.FontFamily = "tahoma"
       .Style.FontSize = "10pt"
       .Style.OverflowY = "auto"
       .Style.PaddingLeft = "5px"
       .innerHTML = HiddenTable.innerHTML
      end with ' TablePopup.Document.Body
      TablePopup.Show intMouseX, intMouseY, 200, 100, document.body
      TablePopup.document.all.hSelection.onclick = getRef("RunTest")

     End Function

     </script>

     <BODY>
      <input id="DateTextBox" type="text" value="click here" onclick="ShowTable">

      <table>
       <tr>
        <td>
         <span onclick="hselection.value=1:Runtest2">Choise 1</span>
        </td>
        <td>
         <span onclick="hselection.value=2:Runtest2">Choise 2</span>
        </td>
       </tr>
      </table>

      <DIV id="HiddenTable" style="display:none">
       <DIV>
        <table>
         <tr>
          <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'">
           <span onclick="vbscript:hselection.value=3:hselection.click">Choise 3</span>
          </td>
          <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'">
           <span onclick="vbscript:hselection.value=4:hselection.click">Choise 4</span>
          </td>
         </tr>
         <tr>
          <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'">
           <span onclick="vbscript:hselection.value=5:hselection.click">Choise 5</span>
          </td>
          <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'">
           <span onclick="vbscript:hselection.value=6:hselection.click">Choise 6</span>
          </td>
         </tr>
        </table>
       </DIV>
       <DIV onmouseover="this.style.background='grey'"
          onmouseout="this.style.background='none'"
        <SPAN onclick="parent.location.href='http://www.google.com'">Google</SPAN>
       </DIV>
       <input type=hidden id="hselection" onclick="vbscript:msgbox hselection.value">
      </DIV>
     </BODY>
    </html>

    BTW, I like the use of the hidden DIV to store the HTML for the popup.  I usually do that by writing to the document, but you technique is better, I think.

    Question:  Is "choise" an English spelling?  We Americans spell it "choice".


    Tom Lavedas
    • Marked as answer by RussellNS Friday, August 05, 2011 6:47 PM
    Friday, August 05, 2011 1:44 PM
    Moderator
  • I beg to differ with my learned colleague jrv, but most of what has been said here so far doesn't seem right to me.  Here is an approach that seems to me to do everything you want wityhout putting script into the popup (except for the snippets in the controls themselves) and the window closes automatically when it looses focus ...

    What doesn't seem right? The Popup won't execute anything that tryir to touch the parent in certain ways.  It is limited but can be made to work.

    Using jscript is how most menus have been built and usually on-the-fly instead of saving in a hidden DIV.  I use an XML date iland becuse it is readable and can be manipulated like text but is always hidden. 

    Yes many things can be done however using popup this way has always seemed to me to be the most difficult approach once you learn how to do it with jscript.

     Ny th4e way - in your code - if you take the message boxes out teh menu willno longer be closable.  It is closng because the focus has cahnged.  It is not really hiding but is being pushed behind the main page I believe.  Without calling msgbox ther is no way to hide the popup the way it is designed.  Usually clicking outside of the popup is how it is closed.  Perhaps an oncahnge event in teh parent control that is being set can close the popup.  The parent CAB close the popup but it cannot close itself.

     

     

     


    jv
    Friday, August 05, 2011 1:53 PM
  • What doesn't seem right? The Popup won't execute anything that tryir to touch the parent in certain ways.  It is limited but can be made to work.
    jv


    You are right in that.  I may have overstated my objections.  I apologize.  The only incorrect statement was "Fuctions cannot be called in events" in your first response.

    However, as I showed, though it is not possible for the child to access the parent (as you stated), it is possible to do the reverse - which results in the desired result (I think).


    Tom Lavedas
    Friday, August 05, 2011 2:06 PM
    Moderator
  • Nope Tom - it won't work.  Comment ot the message box and you will see that the menu won't close when clicked.

     


    jv
    Friday, August 05, 2011 2:23 PM
  • This is exactly what I was looking for.  Thanks to both of y'all so much!

    The popup closing thing is more of a "like to have" since it was aesthetic in nature.  But since we're on asthetics, I've molded the script you provided into more of the direction I'll be heading, and I can't get a sub/function to fire unless I actually click on the value of the cell rather than the cell itself.  Here's what I have to illustrate:

    <html>
     <head>
      <title>PickTable</title>
      <hta:application
      scroll="no"
      singleinstance="no"
      windowstate="normal"
      >
     </head>
    
     <SCRIPT Language="VBScript">
      Dim TablePopup ' Hidden/Pop-up PickTable variable must be declared globally.
    
      Function RunTest()
       InputTextBox.Value = TablePopup.document.all.hSelection.value
      End Function
    
      Function ShowTable()
       Set TablePopup = Window.createPopup()
       intMouseX = Window.Event.OffsetX + 10
       intMouseY = Window.Event.OffsetY + 15
    
       with TablePopup.Document.Body
        .Style.BackgroundColor = "white"
        .Style.Border = "1px solid black"
        .Style.cursor = "default"
        .Style.FontFamily = "tahoma"
        .Style.OverflowY = "auto"
        .innerHTML = HiddenTable.innerHTML
       end with ' TablePopup.Document.Body
    
       TablePopup.Show intMouseX, intMouseY, 200, 100, document.body
       TablePopup.document.all.hSelection.onclick = getRef("RunTest")
    
      End Function
    
     </script>
    
     <BODY>
      <input id="InputTextBox" type="text" value="click here" onclick="ShowTable">
    
      <DIV id="HiddenTable" style="display:none">
    
       <input type=hidden id="hSelection">
       <!-- <input type=hidden id="hSelection" onclick="vbscript:msgbox hSelection.value"> -->
    
       <table>
        <tr>
         <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'" width="50">
         <span onclick="vbscript:hSelection.value=3:hSelection.click">3</span>
         </td>
         <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'" width="50">
         <span onclick="vbscript:hSelection.value=4:hSelection.click">4</span>
         </td>
         </tr>
         <tr>
         <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'" width="50">
         <span onclick="vbscript:hSelection.value=5:hSelection.click">5</span>
         </td>
         <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'" width="50">
         <span onclick="vbscript:hSelection.value=6:hSelection.click">6</span>
         </td>
        </tr>
       </table>
    
      </DIV>
     </BODY>
    </html>
    
    

    Now if I change the <td> that controls this from:

         <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'" width="50">
         <span onclick="vbscript:hSelection.value=3:hSelection.click">3</span>
         </td>
    
    

    to:

         <td onmouseover="this.style.background='#E0E0E0'"
            onmouseout="this.style.background='none'" width="50"
            onclick="vbscript:hSelection.value=3:hSelection.click">3
         </td>
    
    
    Then all of a sudden, the HTA starts erroring on the "this" object.  I've tried eleventy billion combinations.  It seems I can include almost anything I want in the <td> attributes except "onclick" values.

    Any insights?

     

    P.S. The "Choise" thing was an "I've been  up for 48 hours beating my head against the wall with this and didn't think" thing.  Good catch!

    Friday, August 05, 2011 7:02 PM
  • I found that destroying the popup object causes it to close, as in

      Function RunTest()
       InputTextBox.Value = TablePopup.document.all.hSelection.value
       set TablePopup = nothing
      End Function

    And causing the SPAN to fill the whole table data box makes it clickable anywhere in the colored area, as in ...

    <span style="width:100%;height:100%" onclick=...>

    HTH


    Tom Lavedas
    Friday, August 05, 2011 7:42 PM
    Moderator
  • I found that destroying the popup object causes it to close, as in


    Tom Lavedas


    Tom - very good.  I still say jscipt menus are way cooler but - in a pinch - this will work.

    Here is a sample of things you can do with an HTA to display interesting sorts of things.  It is mostly buiilt to show how to launch dialogs and how to have an automatically scrolling log file box.

    HTASampler


    jv
    Friday, August 05, 2011 8:26 PM