Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Frame Element Events 1

Status
Not open for further replies.

Skie

Programmer
Jun 21, 2004
475
US
I'm trying to setup an HTA with frames. What I want to happen is when an item is checked in the first frame it moves to the second frame. The easy solution would be to use a list box, but the actual data I'll be using will be longer than a single row of a list box.

Anyhow, here's my HTA:
Code:
<html>
<head>
<HTA:APPLICATION/>
<script type="text/vbscript">
Sub Window_OnLoad
  Set oFSO = CreateObject("Scripting.FileSystemObject")
  Set oFile = oFSO.CreateTextFile("junk.htm")
  oFile.Write "<script src=""scripts.vbs"" type=""text\vbscript""></" & "script>" & vbCrLf
  For i = 1 to 10
      sID = "chk" & cStr(i)
      oFile.Write _
          "<input type=checkbox id='" & sID & "' " & _
          "name='" & cStr(i) & "' " & _
          "onPropertyChange='SubForCheckBoxes me'/>" & _
          "<label for='" & sID & "'>" & sID & "</label></br>" & vbCrLf
  Next
  oFile.Close
  oFrame1.location.replace("junk.htm")
  Set oFile = oFSO.CreateTextFile("junk2.htm")
  oFile.Close
  oFrame2.location.replace("junk2.htm")
End Sub
</script>
</head>
<iframe id=oFrame1 application=yes width=100% src="junk.htm"/>
<iframe id=oFrame2 application=yes width=100% src="junk2.htm"/>
</frameset>
</html>

And here's scripts.vbs:
Code:
Const ForReading = 1
Const ForAppending = 8
Sub SubForCheckBoxes(oMe)
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFile = oFSO.OpenTextFile("junk2.htm",ForAppending)
    oFile.Write "<input type=checkbox id='" & oMe.ID & "' checked=true/>"
    oFile.Write "<label for='" & oMe.ID & "'>" & oMe.ID & "</label></br>"
    oFile.Close
    top.oFrame2.location.reload
    Set oFile = oFSO.OpenTextFile("junk.htm",ForReading)
    sAll = oFile.ReadAll
    oFile.Close
    aAll = Split(sAll,vbCrLf)
    Set oFile = oFSO.CreateTextFile("junk.htm")
    For Each sLine in aAll
        If InStr(sLine,oMe.ID) = 0 Then oFile.Write sLine & vbCrLf
    Next
    sNext = cStr(cInt(oMe.Name) + 1)
    top.oFrame1.location.reload
    Do While top.oFrame1.document.readystate<>"complete"
        
    Loop
    oNext = top.oFrame1.document.getElementsByName(sNext)
    If oNext Is Nothing Then
    Else
        oNext.Focus
    End If
End Sub

One problem with this code is that the oNext.Focus doesn't seem to work, but I'm not getting an error (unless oNext is nothing). I'd thought it maybe had to do with me focussing before the reload was completed, but I added the readystate line and it doesn't make a difference. Any help here would be appreciated.
 
[1] I refrain from commenting the merit of getting the behaviour from rebuilding src files. I only salvage the case from within the framework.
[2] Using very ie-specific kind of script outlook for hta using vbs is fine. After all, it is restricted to ie as browser. But, there are those junk like </frameset>. Lack of body in the main hta page... which have some impact on the referencing/rendering which have no apparent effect in this particular case.
[3] The reference to Next is erronous.
[4] The use of name as (1,2,3,...) is real bad, I don't like it _at all_... Problems can be waiting to appear. Why not use the same construction as id and then when construct the sNext, extract the number by adding one and then re-construct the name from it?
[5] The single most damaging line to hinder the focus() to function, apart from [3], is the line:
>top.oFrame1.location.reload
You've to comment it out.

Here is a minimal revision.

[a] scripts.vbs
[tt]
Const ForReading = 1
Const ForAppending = 8
Sub SubForCheckBoxes(oMe)
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.OpenTextFile("junk2.htm",ForAppending)
oFile.Write "<input type=checkbox id='" & oMe.ID & "' checked=true/>"
oFile.Write "<label for='" & oMe.ID & "'>" & oMe.ID & "</label></br>"
oFile.Close
top.oFrame2.location.reload
Set oFile = oFSO.OpenTextFile("junk.htm",ForReading)
sAll = oFile.ReadAll
oFile.Close
aAll = Split(sAll,vbCrLf)
Set oFile = oFSO.CreateTextFile("junk.htm")
For Each sLine in aAll
If InStr(sLine,oMe.ID) = 0 Then oFile.Write sLine & vbCrLf
Next
sNext = cStr(cInt(oMe.Name) + 1)
[red]'[/red]top.oFrame1.location.reload
[red]'[/red]Do While top.oFrame1.document.readystate<>"complete"
[red]'[/red]
[red]'[/red]Loop
[red]set[/red] oNext = top.oFrame1.document.getElementsByName(sNext)[red](0)[/red]
If oNext Is Nothing Then
Else
oNext.Focus
End If
End Sub
[/tt]
main hta page
[tt]
<html>
<head>
<HTA:APPLICATION/>
<script type="text/vbscript">
Sub Window_OnLoad
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.CreateTextFile("junk.htm")
oFile.Write "<script src=""scripts.vbs"" type=""text[highlight]/[/highlight]vbscript""></" & "script>" & vbCrLf
For i = 1 to 10
sID = "chk" & cStr(i)
oFile.Write _
"<input type=checkbox id='" & sID & "' " & _
"name='" & cStr(i) & "' " & _
"onPropertyChange='SubForCheckBoxes me'/>" & _
"<label for='" & sID & "'>" & sID & "</label></br>" & vbCrLf
Next
oFile.Close
oFrame1.location.replace("junk.htm")
Set oFile = oFSO.CreateTextFile("junk2.htm")
oFile.Close
oFrame2.location.replace("junk2.htm")
End Sub
</script>
</head>
[blue]<body>[/blue]
<iframe id=oFrame1 application=yes width=100% src="junk.htm"/>
<iframe id=oFrame2 application=yes width=100% src="junk2.htm"/>
[red]<!--[/red] </frameset> [red]-->[/red]
[blue]</body>[/blue]
</html>
[/tt]
 
Further note:
I've forgotten to mention that there is an incompatiblity between the .reload and .focus(). The revision will not eliminate the checkbox checked. This incompatibility is related to the merit or de-merit of what I refrain from commenting [1]. In other words, if it is insisted that the checkbox disappeared in oFrame1, then the focus will not be possible along the line of thinking of oNext.focus(). That's is price to pay. But, rebuilding the src files is only one possible approach. It may not be the best. Rather, I would say one can consider using purely dom functionality to achieve the same with much more secure control and have focus() readily available too.
 
Further note (2):
But I must say the opinion is just from inspecting the script. Please don't take it as remotely the whole story. I haven't thoroughly tested it. The op should know better.
 
Thanks for all the info. All this time I've had my / and \ mixed up in <scritp type=...>. I binned the name and decided to use getElementByID instead. I wouldn't have left the name as a 1-10, but as it turns out I don't need it.

I removed the manipulation of the files and reload so that the focus works. I decided to tag on some span tags and simply manipulate the display setting. I also improved the selection of oNext.

Any other feedback is appreciated as well as some more information about "DOM functionality".

HTA
Code:
<html>
<head>
<HTA:APPLICATION/>
<script type="text/vbscript">
Sub Window_OnLoad
  Set oFSO = CreateObject("Scripting.FileSystemObject")
  Set oFile = oFSO.CreateTextFile("junk.htm")
  Set oFile2 = oFSO.CreateTextFile("junk2.htm")
  oFile.Write "<script src=""scripts.vbs"" type=""text/vbscript""></" & "script>" & vbCrLf
  oFile2.Write "<script src=""scripts.vbs"" type=""text/vbscript""></" & "script>" & vbCrLf
  For i = 1 to 10
      sChk = "Chk" & cStr(i)
      sSpan = "Span" & cStr(i)
      oFile.Write _
          "<span id='" & sSpan & "'><input type=checkbox id='" & sChk & "' " & _
          "onClick='MoveCheckBoxes me'/>" & _
          "<label for='" & sChk & "'>" & sChk & "</label></br></span>" & vbCrLf
      oFile2.Write _
          "<span id='" & sSpan & "' style='display:none;'><input type=checkbox checked=true id='" & sChk & "' " & _
          "onClick='MoveCheckBoxes me'/>" & _
          "<label for='" & sChk & "'>" & sChk & "</label></br></span>" & vbCrLf
  Next
  oFile.Close
  oFile2.Close
  top.oFrame1.location.reload
  top.oFrame2.location.reload
End Sub
</script>
</head>
<body>
<iframe id=oFrame1 application=yes width=100% src="junk.htm"/>
<iframe id=oFrame2 application=yes width=100% src="junk2.htm"/>
</body>
</html>

scripts.vbs
Code:
Sub MoveCheckBoxes(oChk)
    sID = oChk.ID
    iNext = cInt(Replace(oChk.ID,"Chk",""))
    sID = "Span" & cStr(iNext)
    iInc = 1
    iNext = iNext + iInc
    If oChk.Checked Then
        Do While True
            sNext = "Chk" & cStr(iNext)
            sSpan = "Span" & cStr(iNext)
            Set oNext = top.oFrame1.document.getElementByID(sNext)
            Set oSpan = top.oFrame1.document.getElementByID(sSpan)
            If oNext Is Nothing Then
'                MsgBox "Is Nothing"
                iInc = -1
            Else
                If oNext.Id = oChk.ID Then
'                MsgBox "Is Self"
                ElseIf oSpan.style.display <> "none" Then
'                    MsgBox "Is Good"
                    oNext.Focus
                    Exit Do
                End If
            End If
            iNext = iNext + iInc
            If iNext < 1 Then Exit Do
        Loop
        oChk.Checked = False
        sJunk1 = "none"
        sJunk2 = "inline"
    Else
        Do While True
            sNext = "Chk" & cStr(iNext)
            sSpan = "Span" & cStr(iNext)
            Set oNext = top.oFrame2.document.getElementByID(sNext)
            Set oSpan = top.oFrame2.document.getElementByID(sSpan)
            If oNext Is Nothing Then
'                MsgBox "Is Nothing"
                iInc = -1
            Else
                If oNext.Id = oChk.ID Then
'                MsgBox "Is Self"
                ElseIf oSpan.style.display = "inline" Then
'                    MsgBox "Is Good"
                    oNext.Focus
                    Exit Do
                End If
            End If
            iNext = iNext + iInc
            If iNext < 1 Then Exit Do
        Loop
        oChk.Checked = True
        sJunk1 = "inline"
        sJunk2 = "none"
    End If
    Set oJunk1 = top.oFrame1.document.getElementByID(sID)
    If oJunk1 Is Nothing Then
    Else
        oJunk1.style.display = sJunk1
    End If
    Set oJunk2 = top.oFrame2.document.getElementByID(sID)
    If oJunk2 Is Nothing Then
    Else
        oJunk2.style.display = sJunk2
    End If
End Sub

Thanks again
 
>Any other feedback is appreciated as well as some more information about "DOM functionality".

This is how you can do it.

[1] main.hta
I would much prefer to add some quotes etc, but I leave it as closely as the original. Some minor additions are mostly not critical though.
[tt]
<html>
<head>
<hta:application />
</head>
<body>
<iframe name=oFrame1 id=oFrame1 application=yes width=100% src="junk.htm"></iframe>
<iframe name=oFrame2 id=oFrame2 application=yes width=100% src="junk2.htm"></iframe>
</body>
</html>
[/tt]
[2] junk.htm
Note: adding language attribute to the input element is very much needed here in this situation for better error-free behaviour.
[tt]
<html>
<head><title></title>
<script type="text/vbscript">
sub subForCheckBoxes(oMe)
set onode=oMe.removeNode(false)
set oform2=top.frames("oFrame2").document.formname2
oform2.insertAdjacentHTML "BeforeEnd","<br />" & onode.outerHTML & onode.id
end sub
</script>
</head>
<body>
<form name="formname1">
<script type="text/vbscript">
for i=1 to 10
sID="chk" & i
document.write "<input [blue]language='vbscript'[/blue] type=checkbox id='" & sID & "' " & _
"name='" & sID & "' " & _
"onPropertyChange='SubForCheckBoxes me' />" & _
"<label for='" & sID & "'>" & sID & "</label></br>" & vbCrLf
next
</script>
</form>
</body>
</html>
[/tt]
[3] junk2.htm
I add a form element as a container for the moved checkbox control. It is just my preference. I find it conceptually more satisfactory to contain the moved checkbox into a form element. You can spare the form element and use just body. In that case, change the corresponding line in the sub appeared in junk.htm
[tt]
<html>
<body>
<form name="formname2" language="vbscript"></form>
</body>
</html>
[/tt]
 
Further note:
As the SubCheckBoxes is no longer available to junk2, hence, to eliminate the minor annoyance of calling a inexisting handler, the quickest fix is to replace the corresponding line by this.
[tt]
oform2.insertAdjacentHTML "BeforeEnd","<br />" & replace(onode.outerHTML, "onpropertychange=""SubForCheckBoxes me""","") & onode.id
[/tt]
If there are some hard coding of the string to be replace, you can always make it less contingent to the original construction of it in the document.write line. But, this is the quickest to get it function.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top