Search code examples
javascripthtmlcssvbscripthta

How do I change the color of multiple HTML elements with one click?


I have an HTA with loads of options. I have been able to change the color theme of the app with some Theme buttons using a combo of CSS and VBScript. However, I have been doing each element manually. Like this:

'********************************************************************
'* ThemeTheMatrix - This subroutine sets the CSS styles to the Matrix theme.
'********************************************************************
Sub ThemeTheMatrix
  txtTheme = "Green"
  'Main Body 
  strColor1="Black"
  'Main Text 
  strColor2="Chartreuse"
  
  'TextBox Background 
  strColor3="DimGray"
  'TextBox Border 
  strColor4="DarkGray"

  'Button Background
  strColor5="Black"
  'Button Text
  strColor6=strColor2

  ChangeColor()
End Sub

'********************************************************************
'* ChangeColor - This subroutineapplies the colors set by one of the Theme subroutines.
'********************************************************************
Sub ChangeColor
  'Set Main Body colors
  document.bgColor=strColor1
  document.body.text=strColor2
  
  'Set Button colors
  btn1.style.color=strColor6
  btn1.style.backgroundcolor=strColor5

  btn2.style.color=strColor6
  btn2.style.backgroundcolor=strColor5
...
  'Set TextBox colors
  txt1.style.backgroundcolor=strColor3
  txt1.style.color=strColor2
  txt1.style.borderColor=strColor4

  txt2.style.backgroundcolor=strColor3
  txt2.style.color=strColor2
  txt2.style.borderColor=strColor4
...
  'Set DropDown colors
  Opt1.style.backgroundcolor=strColor3
  Opt1.style.color=strColor2
  Opt1.style.borderColor=strColor4

  Opt2.style.backgroundcolor=strColor3
  Opt2.style.color=strColor2
  Opt2.style.borderColor=strColor4
...
End Sub

When a user clicks the Matrix button it triggers the first sub which sets the variable values and calls the ChangeColor sub. The ChangeColor sub then goes through each ID and changes the values shown. Is there a way to name or tag each type of element (button, text, etc.) with the same tag and then change all of those items with a single command? Currently, I get an error message when more than one element has the same ID. I am pushing 30 buttons, and nearly two dozen text fields with more being requested. I would very much like to automate this a bit more.


Solution

  • Here's a theme selector example that uses GetElementsByTagName:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8" http-equiv="X-UA-Compatible" content="IE=9">
    <hta:application id=oHTA
      icon=mspaint.exe
    >
    <script language="VBScript">
    Sub ThemeChange
      Set oElements = document.GetElementsByTagName("input")
      For Each oElement in oElements
        If oElement.Type="button" Then oElement.ClassName = "b" & Theme.Value
        If oElement.Type="text" Then oElement.ClassName = "t" & Theme.Value
      Next
    End Sub
    </script>
    <style>
    .b1 {color:Green; width:6em}
    .t1 {color:Blue; width:6em}
    .b2 {color:Orange; width:6em}
    .t2 {color:Red; width:6em}
    .b3 {color:Pink; width:6em}
    .t3 {color:Purple; width:6em}
    </style>
    </head>
    <body>
    <select id=Theme onchange=ThemeChange()>
      <option value=1>Theme 1</option>
      <option value=2>Theme 2</option>
      <option value=3>Theme 3</option>
    </select><br><br>
    <input type=button class=b1 value='Button 1'>
    <input type=text class=t1 value='Text 1'><br><br>
    <input type=button class=b1 value='Button 2'>
    <input type=text class=t1 value='Text 2'><br><br>
    <input type=button class=b1 value='Button 3'>
    <input type=text class=t1 value='Text 3'><br><br>
    </body>
    </html>
    

    To use GetElementsByClassName, replace the script section above with this code:

    <script language="VBScript">
    CurrentTheme = 1
    Sub ThemeChange
      Set oElements = document.getElementsByClassName("b" & CurrentTheme)
      For Each oElement in oElements
        oElement.ClassName = "b" & Theme.Value
      Next
      Set oElements = document.getElementsByClassName("t" & CurrentTheme)
      For Each oElement in oElements
        oElement.ClassName = "t" & Theme.Value
      Next
      CurrentTheme = Theme.Value
    End Sub
    </script>