{"id":67183,"date":"2006-06-05T13:11:00","date_gmt":"2006-06-05T13:11:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/06\/05\/how-can-i-dynamically-add-controls-to-an-hta\/"},"modified":"2006-06-05T13:11:00","modified_gmt":"2006-06-05T13:11:00","slug":"how-can-i-dynamically-add-controls-to-an-hta","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-dynamically-add-controls-to-an-hta\/","title":{"rendered":"How Can I Dynamically Add Controls to an HTA?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>Hey, Scripting Guy! How can I dynamically add controls to an HTA?<BR><BR>&#8212; TR<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, TR. Dum-de-dum-dum. Dum-de-dum-de &#8211; oh, wait : you were talking to <I>us<\/I>, weren\u2019t you? Sorry; we saw the word \u201cdynamically\u201d and figured this question must have been addressed to someone else. When people hear the words <I>Scripting Guys<\/I> they think of all sorts of things, but \u201cdynamic\u201d usually isn\u2019t one of them.<\/P>\n<P>And no, TechNet won\u2019t allow us to print the words people <I>do<\/I> associate with the Scripting Guys.<\/P>\n<P>OK, now that we know that <I>we\u2019re<\/I> supposed to answer the question we better get down to business. First of all, we should note that the <I>real<\/I> answer to your question is, \u201cIt depends.\u201d After all, the exact method for dynamically adding controls to an HTA depends on what type of control you want to add and what you want those controls to do. (For example, do you want a script to run when the control is clicked?) Therefore, we\u2019re going to show you a somewhat-generic method for adding dynamic controls to an HTA and for determining whether or not that control has been clicked. That probably won\u2019t solve your actual problem, but, with any luck, it should be enough information to get you started.<\/P>\n<P>We should also note that if you have no idea what we\u2019re talking about, HTA is short for HTML Application. Among other things, HTAs utilize the Internet Explorer object model as a way to provide a graphical user interface for a script; that means you can create a script that looks like a real application, complete with radio buttons and drop-down lists and what-have-you. For more information, check out our <A href=\"http:\/\/null\/technet\/scriptcenter\/hubs\/htas.mspx\"><B>HTA Developers Center<\/B><\/A>.<\/P>\n<P>And now, back to our regularly-scheduled program.<\/P>\n<P>Our sample HTA is pretty simple. It consists of a window with a single button, labeled <B>Add Button<\/B>. Each time you click <B>Add Button<\/B>, a new button is added to the screen; if you click any of those new buttons, a subroutine will report back the ID of the button that was clicked. When you first start up the HTA it looks something like this:<\/P><IMG border=\"0\" alt=\"Hey, Scripting Guy!\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/dynamic1.jpg\" width=\"387\" height=\"265\"> \n<P><BR>No, it\u2019s <I>not<\/I> very fancy at the moment. But don\u2019t worry: we\u2019re not done yet.<\/P>\n<P>As you can see, the code for our HTA isn\u2019t much fancier:<\/P><PRE class=\"codeSample\">&lt;script Language=&#8221;VBScript&#8221;&gt;<\/p>\n<p>    intButtonCount = 1<\/p>\n<p>    Sub AddButton\n        strHTML = DataArea.InnerHTML       \n        strHTML = strHTML &amp; &#8220;&lt;input id=&#8221; &amp; intButtonCount &amp; &#8221; type=&#8221; &amp; Chr(34) &amp; &#8220;button&#8221; &amp; Chr(34) &amp; _\n            &#8221; value= &#8221; &amp; Chr(34) &amp; &#8220;Button &#8221; &amp; intButtonCount &amp; Chr(34) &amp; &#8221; onClick=&#8221; &amp; Chr(34) &amp; _\n                &#8220;NewButtonSubroutine&#8221; &amp; Chr(34) &amp; &#8220;&gt;&#8221;\n        DataArea.InnerHTML = strHTML\n        intButtonCount = intButtonCount + 1\n    End Sub<\/p>\n<p>    Sub NewButtonSubroutine\n        Set objButton = window.event.srcelement\n        strID = objButton.id\n        Msgbox &#8220;You clicked Button ID &#8221; &amp; strID\n    End Sub<\/p>\n<p>&lt;\/script&gt;<\/p>\n<p>&lt;body&gt;\n    &lt;input id=addbutton type=&#8221;button&#8221; value=&#8221;Add Button&#8221; onClick=&#8221;AddButton&#8221;&gt;\n    &lt;span id=DataArea&gt;&lt;\/span&gt;\n&lt;\/body&gt;\n<\/PRE>\n<P>So how exactly does this all work? Let\u2019s break the HTA down into subsections and see if we can answer that question. For starters, take a look at the <B>&lt;body&gt;<\/B> tag. As you can see, there isn\u2019t much there; all we have is the HTML code for adding a button, along with this tag:<\/P><PRE class=\"codeSample\">&lt;span id=DataArea&gt;&lt;\/span&gt;\n<\/PRE>\n<P>That\u2019s not much, but it\u2019s important. The <B>&lt;span&gt;<\/B> tag sets aside a named area of our HTA; as you\u2019re about to see, once we have a named area we can then dynamically add items to that area. That\u2019s step 1 in the process: in order to add new controls to an HTA you need a designated area within the HTA where controls can be added. Make sense? Good.<\/P>\n<P>Oh: note that we\u2019ve given this spot the ID DataArea. We\u2019ll need to use that ID any time we refer to this portion of the HTA.<\/P>\n<P>Next, let\u2019s take a look at the AddButton subroutine; this is the subroutine that gets called each time we click <B>Add Button<\/B>. As you might expect, this is also the subroutine that dynamically adds controls each time the button is clicked (and thus each time the subroutine is called).<\/P>\n<P>The first thing we do inside this subroutine is assign the value of DataArea\u2019s <B>InnerHTML<\/B> property to a variable named strHTML:<\/P><PRE class=\"codeSample\">strHTML = DataArea.InnerHTML\n<\/PRE>\n<P>The InnerHTML property represents all the HTML coding contained within the DataArea span. For all intents and purposes, that means information about all the controls, text, images, etc. within that span is now stashed away in the variable strHTML.<\/P>\n<P>That brings us to this nightmarish line of code:<\/P><PRE class=\"codeSample\">strHTML = strHTML &amp; &#8220;&lt;input id=&#8221; &amp; intButtonCount &amp; &#8221; type=&#8221; &amp; Chr(34) &amp; &#8220;button&#8221; &amp; Chr(34) &amp; _\n    &#8221; value= &#8221; &amp; Chr(34) &amp; &#8220;Button &#8221; &amp; intButtonCount &amp; Chr(34) &amp; &#8221; onClick=&#8221; &amp; Chr(34) &amp; _\n        &#8220;NewButtonSubroutine&#8221; &amp; Chr(34) &amp; &#8220;&gt;&#8221;\n<\/PRE>\n<P>Yes, we know what it looks like. But let\u2019s explain what\u2019s going on here and see if that helps any. All we\u2019re doing is assigning a new value to strHTML: this time it\u2019s getting the existing value of strHTML (all the current controls, text, images, etc.) <I>plus<\/I> HTML code for adding a brand-new button. The portion of the code for adding a brand-new button looks like this:<\/P><PRE class=\"codeSample\">&#8220;&lt;input id=&#8221; &amp; intButtonCount &amp; &#8221; type=&#8221; &amp; Chr(34) &amp; &#8220;button&#8221; &amp; Chr(34) &amp; _\n    &#8221; value= &#8221; &amp; Chr(34) &amp; &#8220;Button &#8221; &amp; intButtonCount &amp; Chr(34) &amp; &#8221; onClick=&#8221; &amp; Chr(34) &amp; _\n        &#8220;NewButtonSubroutine&#8221; &amp; Chr(34) &amp; &#8220;&gt;&#8221;\n<\/PRE>\n<P>Believe it or not, that gobbledygook resolves to the code required to add a new button to the HTA. As you probably know, the HTA tag for a button looks like this:<\/P><PRE class=\"codeSample\">&lt;input id=1 type=&#8221;button&#8221; value=&#8221;Button 1&#8243; onClick=&#8221;NewButtonSubroutine&#8221;&gt;\n<\/PRE>\n<P>Those elements &#8211; and only those elements &#8211; are present in our crazy line of code. However, we did have to make a few modifications:<\/P>\n<TABLE border=\"0\" cellSpacing=\"0\" cellPadding=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>The HTA tag for a button includes a number of double quotes (e.g., <B>type=\u201dbutton\u201d<\/B>). In VBScript, all string values must be enclosed in double quotes, and putting double quotes within double quotes can be tricky. Therefore, we simply replaced the double quotes with their ASCII equivalent: <B>Chr(34)<\/B>. See all the Chr(34) notations in our code? Those are just double quotes. If you see <B>\u201ctype=\u201d &amp; Chr(34) &amp; \u201cbutton\u201d<\/B> you can simply read that as <B>type=\u201dbutton\u201d<\/B> (which is exactly how the script reads it).<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>If we want to be able to distinguish between buttons then each button needs to have a unique ID. To do that we defined a global variable named intButtonCount at the beginning of our <B>&lt;script&gt;<\/B> tag, and assigned intButtonCount the value 1. Each time we add a new button we then increment intButtonCount by 1. What does that mean? That means our first new button will have an ID of 1, our second new button will have an ID of 2, etc. That\u2019s why the button ID is assigned the value of intButtonCount. Like so: <B>id=&#8221; &amp; intButtonCount<\/B>.<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>We also want each button to have unique label. Therefore, we set the value (label) of each button to the word <I>Button<\/I> plus the button ID. That\u2019s what happens here: <B>&#8221; value= &#8221; &amp; Chr(34) &amp; &#8220;Button &#8221; &amp; intButtonCount &amp; Chr(34)<\/B>.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Got all that? If not, don\u2019t fret. Instead, just slowly walk through the line of code piece-by-piece, substituting the current value of intButtonCount as needed, and sticking in double quote marks any time you see Chr(34). Sooner or later it should start making sense. If it doesn\u2019t substitute in this line of code, which adds a button without an ID, a label, or an onClick event:<\/P><PRE class=\"codeSample\">strHTML = strHTML &amp; &#8220;&lt;input type=&#8221; &amp; Chr(34) &amp; &#8220;button&#8221; &amp; Chr(34) &amp; &#8220;&gt;&#8221;\n<\/PRE>\n<P>That button won\u2019t look like much and it won\u2019t actually do anything, but once you understand how we created that very simple button you can start adding additional parameters such as value, id, and onClick.<\/P>\n<P>After we\u2019ve assigned a new value to strHTML we then set DataArea\u2019s InnerHTML property to that new value:<\/P><PRE class=\"codeSample\">DataArea.InnerHTML = strHTML\n<\/PRE>\n<P>The net effect? We\u2019ll have a new, dynamically-created button within our HTA. Click <B>Add Button<\/B> a few more times and you\u2019ll have all sorts of new buttons on the HTA:<\/P><IMG border=\"0\" alt=\"Hey, Scripting Guy!\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/dynamic2.jpg\" width=\"387\" height=\"265\"> \n<P>Etc.<\/P>\n<P>Now, what about being able to distinguish between buttons 1, 2, and 3? Well, each button we add is configured to call the same subroutine (NewButtonSubroutine) any time someone clicks the button. That subroutine looks like this:<\/P><PRE class=\"codeSample\">Sub NewButtonSubroutine\n    Set objButton = window.event.srcelement\n    strID = objButton.id\n    Msgbox &#8220;You clicked Button ID &#8221; &amp; strID\nEnd Sub\n<\/PRE>\n<P>Inside the subroutine we use the first line of code to create an object reference to the <B>window.event.srcelement<\/B> object. This object represents the item that fired the event triggering the subroutine. In other words, if we click button 2, then the window.event.srcelement is equal to button 2.<\/P>\n<P>As soon as we have an object reference we can assign the button ID to a variable named strID; after that we can use the <B>Msgbox<\/B> function to echo back the ID of the button that was clicked:<\/P><IMG border=\"0\" alt=\"Hey, Scripting Guy!\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/dynamic3.jpg\" width=\"138\" height=\"107\"> \n<P><BR>Not very fancy, but you get the idea.<\/P>\n<P>As we noted, this probably doesn\u2019t <I>fully<\/I> answer your question, TR, but we hope it gets you headed down the right path. If you need more specific information, just let us know.<\/P>\n<P>And remember: if you want to make sure we see your email, don\u2019t use words like dynamic. Instead, use a subject line like <B>Hey, You Lousy, Good-for-Nothing Bums<\/B>. You can bet <I>that<\/I> email will get to us, even if it\u2019s not specifically addressed to us!<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I dynamically add controls to an HTA?&#8212; TR Hey, TR. Dum-de-dum-dum. Dum-de-dum-de &#8211; oh, wait : you were talking to us, weren\u2019t you? Sorry; we saw the word \u201cdynamically\u201d and figured this question must have been addressed to someone else. When people hear the words Scripting Guys they think of [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,4,5,30],"class_list":["post-67183","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-vbscript","tag-web-pages-and-htas"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I dynamically add controls to an HTA?&#8212; TR Hey, TR. Dum-de-dum-dum. Dum-de-dum-de &#8211; oh, wait : you were talking to us, weren\u2019t you? Sorry; we saw the word \u201cdynamically\u201d and figured this question must have been addressed to someone else. When people hear the words Scripting Guys they think of [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67183","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=67183"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67183\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=67183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=67183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=67183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}