Modular VBS-HTML checkbox state retrieval

Anything VBScript-related, including Windows Script Host, WMI, ADSI, and more.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Locked
User avatar
uengin
Posts: 5
Joined: Sat Jun 23, 2012 4:44 pm

Modular VBS-HTML checkbox state retrieval

Post by uengin » Sat Jun 23, 2012 5:04 pm

Hello Ladies an Gentlemen,

Been trying to work out for the better part of the weekend how to retrieve checkbox states from an IE object in VBS, but not having very much luck so far.

Objectives:
1) Modularity
2) Flexible dialog function
3) Single file container

Purpose:
Use the function to pass it various HTML to design the dialog to give the user the selection to run various options based on option list represented with checkboxes.

Here's my Current code:

Code: Select all

'Option Explicit
Dim sHtml, sTitle
Dim iWid, iHgt
Dim arResult
Set oIE = CreateObject( "InternetExplorer.Application" )
iWid = 380
iHgt = 280
sTitle = "Software Selection"
sHtml = "<Form name=""Form""><div align=""left""> " &_    
        "<p><a>Please select software and configuration to deploy:</a>

</p> " &_
        "<input type=""checkbox"" name=""SW"" Value=""LAP""> Local Admin Password</p>  " &_
        "<input type=""checkbox"" name=""SW"" Value=""AL7""> Setup 1</p>  " &_
        "<p><input type=""checkbox"" name=""SW"" Value=""AL711""> Setup 2 </p>" &_
        "<input type=""checkbox"" name=""SW"" Value=""DS""> Desktop Shortcuts </p>" &_
        "<p><input type=""hidden"" id=""OK"" name=""OK"" value=""0"" > " &_
        "<p><input type=""hidden"" id=""Cancel"" name=""Cancel"" value=""0""></p>  " &_
        "<p><input type=""submit"" id=""ContinueButton"" value=""  Continue "" onClick=""VBScript:Cancel.Value=-1""></p> " &_
        "</p> " &_
        "</div></form>"
        
'at one stage I was trying to pass the elements array, didn't have much luck there
arResult = CustomDlg (sTitle, sHtml, iWid, iHgt, True, oIE)
    
'Here I want to be able to access the 

Function CustomDlg(strTitle, strHtml, iWidth, iHeight, boolGbl, oGblObj)
    'boolGbl indicates to the function whether there is a global IE object that has been created that the caller would like the function to use
    'oGblObj is the global object being passed in to the function if boolGbl is true
    ' This function uses Internet Explorer to create a dialog.
    Dim  sTitle, iErrorNum
    
    ' Create an IE object if global not speficied
    If Not boolGbl Then
        Set oGblObj = CreateObject( "InternetExplorer.Application" )
    End If
    ' specify some of the IE window's settings
    oGblObj.Navigate "about:blank"
    oGblObj.Document.Title = strTitle
    oGblObj.MenuBar        = False
    oGblObj.ToolBar        = False
    oGblObj.AddressBar     = false
    oGblObj.Resizable      = False
    oGblObj.StatusBar      = False
    oGblObj.Width          = iWidth
    oGblObj.Height         = iHeight
    ' Center the dialog window on the screen
    With oGblObj.Document.ParentWindow.Screen
        oGblObj.Left = (.AvailWidth  - oGblObj.Width )  2
        oGblObj.Top  = (.Availheight - oGblObj.Height)  2
    End With
    ' Wait till IE is ready
    Do While oGblObj.Busy
        WScript.Sleep 200
    Loop

    ' Insert the HTML code to prompt for user input
    oGblObj.Document.Body.InnerHTML = strHtml

    ' Hide the scrollbars
    oGblObj.Document.Body.Style.overflow = "auto"
    ' Make the window visible
    oGblObj.Visible = True
    

    On Error Resume Next
    Do While oGblObj.Document.All.OK.Value = 0 and oGblObj.Document.All.Cancel.Value = 0
        WScript.Sleep 200
        iErrorNum=Err.Number
        If iErrorNum <> 0 Then    'user clicked red X (or alt-F4) to close IE window
            CustomDlg = 0
            'De-allocate object if not global
            If Not boolGbl Then
                oGblObj.Quit
                Set oGblObj = Nothing
            'If object is global we dont want it de-allocating it
            Else
                oGblObj.Visible = False
            End If
            Exit Function
        End if
    Loop
    On Error Goto 0
    
    oGblObj.Visible = False

    ' Read the user input from the dialog window
    CustomDlg = oGblObj.Document.All.OK.Value
    
    ' Close and release the object
    If Not boolGbl Then
        oGblObj.Quit
        Set oGblObj = Nothing
    'If object is global we dont want it de-allocating it
    Else
        oGblObj.Visible = False
    End If
End Function
Any help you could provide is much appreciated and thank you in advance

User avatar
uengin
Posts: 5
Joined: Sat Jun 23, 2012 4:44 pm

Modular VBS-HTML checkbox state retrieval

Post by uengin » Mon Jun 25, 2012 12:23 am

Thank you for your reply. It has definitely cleared up some of the confusion in my head. I definitely need to have a better understanding how how IE, HTML objects and VBScript interact and behave. However, the way you have set up that function for the time being leaves me in a predicament. I had the CustomDlg() function looking like this before I modified it to look like in my first post:

Code: Select all

Function CustomDlg(strTitle, strHtml, iWidth, iHeight)
    ' This function uses Internet Explorer to create a dialog.
    Dim oIE, sTitle, iErrorNum
    ' Create an IE object
    Set oIE = CreateObject( "InternetExplorer.Application" )
    ' specify some of the IE window's settings
    oIE.Navigate "about:blank"
    oIE.Document.Title = strTitle
    oIE.MenuBar        = False
    oIE.ToolBar        = False
    oIE.AddressBar     = false
    oIE.Resizable      = False
    oIE.StatusBar      = False
    oIE.Width          = iWidth
    oIE.Height         = iHeight
    ' Center the dialog window on the screen
    With oIE.Document.ParentWindow.Screen
        oIE.Left = (.AvailWidth  - oIE.Width )  2
        oIE.Top  = (.Availheight - oIE.Height)  2
    End With
    ' Wait till IE is ready
    Do While oIE.Busy
        WScript.Sleep 200
    Loop
    

    ' Insert the HTML code to prompt for user input
    oIE.Document.Body.InnerHTML = strHtml

    ' Hide the scrollbars
    oIE.Document.Body.Style.overflow = "auto"
    ' Make the window visible
    oIE.Visible = True
    ' Set focus on Cancel button
    oIE.Document.All.CancelButton.Focus

    On Error Resume Next
    Do While oIE.Document.All.OK.Value = 0 and oIE.Document.All.Cancel.Value = 0
        WScript.Sleep 200
        iErrorNum=Err.Number
        If iErrorNum <> 0 Then    'user clicked red X (or alt-F4) to close IE window
            CustomDlg = 0
            oIE.Quit
            Set oIE = Nothing
            Exit Function
        End if
    Loop
    On Error Goto 0

    oIE.Visible = False

    ' Read the user input from the dialog window
    CustomDlg = oIE.Document.All.OK.Value
    ' Close and release the object
    oIE.Quit
    Set oIE = Nothing
End Function
I was calling this function from another function that looked like this:

Code: Select all

function SelectBusinessUnit()
    '============================================================================='
    ' Please note that the following HTML defines and returns business units as:
    ' BusinessUnit1 = 1    BusinessUnit2 = 2    BusinessUnit3 = 3
    '============================================================================='
    'Option Explicit
    Dim sHtml, sTitle
    Dim iWid, iHgt
    'Business Unit Dialog
    sTitle = "Business Unit"
    iWid = 400
    iHgt = 180

    sHtml = "<div align=""center"">" & vbcrlf _
          & "<p><input type=""hidden"" id=""OK"" name=""OK"" value=""0"">" _
          & "<input type=""submit"" value=""  BusinessUnit1   "" onClick=""VBScript:OK.Value=1"">" _
          & "<input type=""submit"" value=""   BusinessUnit2   "" onClick=""VBScript:OK.Value=2"">" _
          & "<input type=""submit"" value=""  BusinessUnit3   "" onClick=""VBScript:OK.Value=3""></p>" _
          & "<p><input type=""hidden"" id=""Cancel"" name=""Cancel"" value=""0"">" _
          & "<input type=""submit"" id=""CancelButton"" value=""       Cancel       "" onClick=""VBScript:Cancel.Value=-1""></p></div>"
    'wscript.echo CustomDlg (sTitle, sHtml, iWid, iHgt)
    SelectBusinessUnit = CustomDlg (sTitle, sHtml, iWid, iHgt)
end function
And hence use the result from this in the main body of my code to make a decision like so:

Code: Select all

iBU = SelectBusinessUnit()
Select Case iBU
    Case 1
        Call Common 
        Call BusinessUnit1()
    Case 2
        Call Common
        Call BusinessUnit2()
    Case 3
        Call Common
        Call BusinessUnit3()
    Case Else
        WScript.Echo strDUError
        WScript.Quit
End Select
So, At this stage, I do not see whether if I start with the suggestion you have provided to be able to preserve the rest of my code to keep it compatible.

As you can probably see, I am trying to keep is as modular as possible, hence probably complicating it. I am willing to start from a simple base and complicate it later but I want to present this aspect of my code so you can see where I am coming from and be better able to advise me whether I can start from this base code and develop it to fit with the rest of my code lat
er.... Or can you suggest a different approach where I can converge on the use above?

User avatar
uengin
Posts: 5
Joined: Sat Jun 23, 2012 4:44 pm

Modular VBS-HTML checkbox state retrieval

Post by uengin » Mon Jun 25, 2012 1:04 pm

Again, thanks for your reply (and also your critique).If you would like to understand why I have my code like this:++++++++++++++++++++++++++++++++++++++++++When you have logical functions performing discrete tasks, the main flow of the designed code, in my opinion is easier to understand especially 2 years after you have written it. Being fancy is not at all my objective.Also, if you include the common function/sub-routine in every function that requires it, this is code replication in to multiple locations. If you need to change this code, then you have to make changes to everywhere it appears (given you rememberhow many times you replicated it), hence in my defence, congregating common code to one function/subroutine aids in maintainability if nothing else.++++++++++++++++++++++++++++++++++++++++++As for your advice, actually, setting up and returning IE; I didn't think about. That's an alternative I will explore, thank you for that. So, the function can return the IE object and I can parse the elements and their values as I wish; This what your suggestion is, am I right?in regards to HTA, I know very little about HTA... So, I might also read in to this to revise my code and perhaps adapt it to an HTA may be....

User avatar
uengin
Posts: 5
Joined: Sat Jun 23, 2012 4:44 pm

Modular VBS-HTML checkbox state retrieval

Post by uengin » Mon Jun 25, 2012 4:13 pm

Oh wow. This looks good.Any online resources you can advise for me to get in to the nitty gritty of HTA?I gather you could embed images as well (though this might be an advanced feature) ?

User avatar
uengin
Posts: 5
Joined: Sat Jun 23, 2012 4:44 pm

Modular VBS-HTML checkbox state retrieval

Post by uengin » Thu Jun 28, 2012 2:11 pm

Jvierra,This is absolutely magnificent!!!Thank you for putting me on to HTA. I got more done in the past 2-3 days than I had developed that VBScript in the week I worked on that.My development of it was not trouble free though but as my understanding grew and I learned more I resolved every issue I came across so far, except the last one. I'll PM you if you don't mind. Ok, Thanks again JV!Oh also, thats so much for the sampler and demodlg packages, they were great in aiding my learning, and indeispensible resource. Much appreciated!!!


uengin2012-06-28 21:13:16

Locked