JScript doesn't support an input method, and also VBScript just provides a simple InputBox function. This is not too comfortable, if you intend to retrieve a user input within a script. Fortunately you can use a front end as a GUI for WSH scripts. Basically a programmer has two possibilities to use forms:
Althought I have introduced both techniques to implement forms in my WSH books, I saw many request within the WSH newsgroups for a GUI. Samples shown are not well commented and there are no explanation about the odds and the evens using IE as a front end. Therefore I decided to release a sample to the public that demonstrates the techniques implementing forms using Microsoft Internet Explorer. I hope this sample will clearify some confusion within the scripters community, and I hope the sample will be helpful to others.
The first task implementing a user input form is to create a HTML document which provides the necessary elements. The simplest method is to use a HTML editor like Microsoft Front Page or Microsoft FrontPage Express and create a HTML document containing the form. After designing the form you need to alter the HTML source code and add a few things. The alternative is to create the HTML document from scratch using a simple editor, this means: and "hack" the HTML-Tags for the form into the editor's window and add some and scripts to handle auxillary functions.
Because I intend to discuss things in details (and because coding on the HTML level was the way how I wrote my first HTML pages six years ago), I like to introduces here the source code of the HTML document. Let's have a first look at the HTML-Tags to create the form.
<form name="ValidForm"> <p>Name: <input type="text" size="5" name="fName"> Age: <input type="text" size="3" name="fAge"><br> Password: <input type="password" Size="12" Maxlength="8" name="fPassw"> <input type="button" name="Button1" value="OK"><br> <input type="checkbox" name="fPrinter" value="1" CHECKED>Printer <input type="checkbox" name="fScreen" value="2">Screen<br> Remarks:<br> <TEXTAREA Cols="40" ROWS="5" name="fRemark"></TEXTAREA></p> </form>
The Form is embedded into the <FORM> ... </FORM>-Tag. The name-Attribute of the <FORM>-Tag defines the object name (which we need later on to access the form items within our scripts). Each form element is described with its own HTML tag. A text box may be inserted using the code:
<input type="text" size="5" name="fName">
Use the type attribute to define the form element's type. Here I should note that the name attribut is required again to identify the item later on within scripts. The size attribute may be set to restrict the size of the text box.
A text area input field requires the <TEXTAREA> ...</TEXTAREA> tags. Using these tags allows you to implement any required form. The most important thing is to define unique names for each item within the form. The code given above defines the following form.
Now, after we have build such a form, we need a few auxillary functions within the HTML document. First of all, we can intend to initialize the form items during loading. This may be done within a script procedure:
Sub window_onload() ' Here we may initialize the form Set TheForm = Document.ValidForm TheForm.fName.Value="" ready = 0 ' User input not ready End Sub
The window_onload() event procedure will be invoked during loading the HTML document. Within the procedure given above I have used only one statement to retrieve the form's object reference and assign it to the object variable TheForm. Then the code:
TheForm.fName.Value=""
may be used to set the content of the first text box (with the name fName) to an empty string. If required, statements to initialize the other form items may be added. The last statement is the most importand one:
ready = 0 ' User input not ready
The MS IE document containing the form runs as an asynchronous process beside our VBScript/JScript program. Therefore we need something to coordinate the two processes. I choose the variable ready as a flag, indicating whether the user has clicked the form's OK button or not. During loading the form, the ready value is set to 0 (which means: form still in input mode.
The user can fill in the fields within the form. If all values are entered, he may click the OK button to close the form and returns control to the script. I have mentioned that the HTML document browse process runs independently from the WSH script process. Therefor it is not possible to close the HTML document from a script within the document itself. Instead the WSH script need to close the form. I used a simple trick to flag the WSH script that the user has clicked the OK button: The ready value must be set to 1. This will be done within the following procedure:
Sub Button1_OnClick ' If the user clicks the OK button, we must flag this to ' the polling WSH script ready = 1 ' User input is ready End Sub
The OnClick event procedure of the Button1 object will be called each time the user clicks the OK button. And within this procedure the ready value will be set to 1.
To allow the WSH script to check the internal state of the ready value, I have implemente another small function CheckVal():
Public Function CheckVal () ' This is called from the host to check whether ' the user has clicked the OK-button CheckVal = ready End function
This function may be called from the WSH script and returns the ready value. If this value is set to 1, the WSH script knows that the OK button was clicked. Well that's all we need on the HTML side. The whole HTML source code will be shown within the next code listing.
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Microsoft FrontPage Express 2.0"> <title>Form input - by Günter Born</title> </head> <body bgcolor="#C0C0C0"> <script language="VBScript"> <!-- Dim ready Public TheForm Sub Button1_OnClick ' If the user clicks the OK button, we must flag this to ' the polling WSH script ready = 1 ' User input is ready End Sub Sub window_onload() ' Here we may initialize the form Set TheForm = Document.ValidForm TheForm.fName.Value="" ready = 0 ' User input not ready End Sub Public Function CheckVal () ' This is called from the host to check whether ' the user has clicked the OK-button CheckVal = ready End function '--> </script> <h3>Form</h3> <hr> <form name="ValidForm"> <p>Name: <input type="text" size="5" name="fName"> Age: <input type="text" size="3" name="fAge"><br> Password: <input type="password" Size="12" Maxlength="8" name="fPassw"> <input type="button" name="Button1" value="OK"><br> <input type="checkbox" name="fPrinter" value="1" CHECKED>Printer <input type="checkbox" name="fScreen" value="2">Screen<br> Remarks:<br> <TEXTAREA Cols="40" ROWS="5" name="fRemark"></TEXTAREA></p> </form> </body> </html> |
OK, we have implemented the HTML document with a form. But how to invoke the form from a WSH script, and how to retrieve the user input from the form's fields? This task isn't trivial, but it is not too hard to understand. The idea is quite simple: we need to invoke an instance of the Internet Explorer within the WSH script. Then we can load the HTML document containing the form. I have discussed this technique within another sample at the WSH Bazaar:
Set oIE = WScript.CreateObject("InternetExplorer.Application") oIE.left=50 ' window position oIE.top = 100 ' and other properties oIE.height = 380 oIE.width = 450 oIE.menubar = 0 ' no menu oIE.toolbar = 0 oIE.statusbar = 0 ' commented out, because it causes a corrupted window ' oIE.resizable = 0 ' disable resizing oIE.navigate path & "Form1.htm" ' Form oIE.visible = 1 ' keep visible
The code sequence shown above invokes the Internet Explorer and loads the document Form1.htm. The object variable oIE points to the IE object instance. The variable path points to the folder containing the HTML document file. Before we can access the Internet Explorer object modell, we need to be sure that the document is loaded and that the IE is now ready for further processing (I have discussed the details in my WSH Tutorial). The check may be made using the following code:
Do While (oIE.Busy) ' Important: wait till MSIE is ready WScript.Sleep 200 ' suspend 200 ms to lower CPU load Loop
I have added a Sleep method call to lower CPU load (this requires WSH 2, or you need to use WSHWait provided from WSHExtend). After the IE is ready, both IE and the WSH script runs as two separate processes. The following figure shows the form as it is displayed in the Internet Explorer.
The user may type the requested values into the form's text boxes. If all values are filled in, a click to the OK button shall close the form. At this point we need a trick recognize within the WSH script that the user has clicked the form's OK button. Above I have introduced the CheckVal function, which returns the ready value. The following code sequence loops until the ready value is set to 1 (which indicates the user has clicked the OK button).
' Wait till the user clicks the OK button ' Use the CheckVal function Do ' Wait to results WScript.Sleep 200 Loop While (oIE.document.script.CheckVal()=0)
Here we follow the object model to call the CheckVal procedure within the HTML document. The oIE object variable points to the application object of the IE process. Then we need to follow the path to the document object which contains the script object. And within the script object we have the CheckVal() function.
After exiting the loop, all data the user has entered into the form, are accessible. But how to access the form's data? This is as simple as calling the CheckVal procedure. Do you remember that I recommend to assign an unique name to your form items? Well, all we need is a reference to the item's object. The IE object is contained within the oIE object variable. The form is part of the document object, which contains the ValidForm object describing the form. To access the first text box, which was names as fName, we can use the following statement:
oIE.Document.ValidForm.fName.Value
The Value property contains the current value the user has entered into the text box Name. Remember that this value is always provided as a string. Using this technique, you may access any form's item from your WSH script. If you need a confirmation of user input data, you can check the values. If a value entered is wrong, you may show a message box indicating that a value may be not accepteable. The sample form shown below displays the user input within a dialog box (see the following figure - I have used a German version of the WSH, therefor the status values are shown as Wahr and Falsch instead of True and False).
After you retrieved all values from the form, you may close the form using the command:
oIE.Quit
This command executes the Quit method provided by the object referenced within the oIE object variable. This causes the IE to close the HTML document and terminates. The following code listing contains the whole VBScript program. The implementation in JScript is up to you.
'************************************************ ' File: Form1.vbs (WSH sample in VBScript) ' Author: Günter Born ' ' Uses Internet Explorer 4.0/5.0 for form input. ' ' In no way shall the author be liable for any ' losses or damages resulting from the use of this ' program. Use AS-IS at your own risk. ' ' The code is the property of the author. You may ' use the code and modify it, as far as this header ' remains intact. Further updates and other samples ' may be found on my site: ' http://www.borncity.de '************************************************ Option Explicit Dim oIE ' declare variables Dim path Dim Title Dim Text2 Dim name, age, password, printer, screen, remark Title = "WSH sample form input - by G. Born" Text2 = "You entered:" & vbCRLF ' *** get script path -> because form (HTML file) ' *** must be in the same folder!!! path = WScript.ScriptFullName path = Left(path, InstrRev(path, "\")) ' *** launch Internet Explorer *** Set oIE = WScript.CreateObject("InternetExplorer.Application") oIE.left=50 ' window position oIE.top = 100 ' and other properties oIE.height = 380 oIE.width = 450 oIE.menubar = 0 ' no menu oIE.toolbar = 0 oIE.statusbar = 0 ' commented out, because it causes a corrupted window ' oIE.resizable = 0 ' disable resizing oIE.navigate path & "Form1.htm" ' Form oIE.visible = 1 ' keep visible ' Important: wait till MSIE is ready Do While (oIE.Busy) WScript.Sleep 200 Loop ' Wait till the user clicks the OK button ' Use the CheckVal function ' Attention: Thanks to a note from M. Harris, we can make ' the script a bit more fool proof. We need to catch the case ' that the user closes the form without clicking the OK button. On Error Resume Next Do ' Wait till OK button is clicked WScript.Sleep 200 Loop While (oIE.document.script.CheckVal()=0) ' If an error occur, because the form is closed, quit the ' script If err <> 0 Then WScript.Echo "Sorry, a run-time error occured during checking" & _ " the OK button " & vbCRLF & _ "Error: " & err.number & " " & _ "I guess the form was getting closed..." WScript.Quit ' end script End if On Error Goto 0 ' switch error handling off ' User has clicked the OK button, retrieve the values name = "Name: " & oIE.Document.ValidForm.fName.Value age = "Age: " & oIE.Document.ValidForm.fAge.Value password = "Password: " & oIE.Document.ValidForm.fPassw.Value printer = "Printer: " & oIE.Document.ValidForm.fPrinter.Value _ & " Status: " & oIE.Document.ValidForm.fPrinter.Checked screen = "Screen: " & oIE.Document.ValidForm.fScreen.Value _ & " Status: " & oIE.Document.ValidForm.fScreen.Checked remark = "Printer: " & oIE.Document.ValidForm.fRemark.Value MsgBox Text2 & vbCRLF & name & vbCRLF & _ age & vbCRLF & password & vbCRLF & _ printer & vbCRLF & screen & vbCRLF & _ remark _ , vbOKOnly + vbInformation, Title oIE.Quit ' close Internet Explorer Set oIE = Nothing ' reset object variable ' End |
That's all - pretty simple isn't it? (But it took me several weeks till I found out all about this technique - the whole stuff is discussed within my WSH books. Within the title Microsoft Windows Script Host 2.0 Developer's Guide I have introduced also alternative ways to use IE forms.)
Download the sample Form.zip
Attention: Since Microsoft released Windows XP SP2 and several security paches for Internet Explorer in 2004, the solution discussed above won't work anymore. IE will block the form's script for security reasons. Fortunately I found a way how to solve this pitfall. Futher details can be found in Newsletter #10.
(c) Günter Born