skip to Main Content

I have an SVG image of a selection widget with left and right arrows and a rectangle showing the selected number/color (see code snippet below). I want to make this SVG image interactive, so the viewer can click the arrows to cycle through the available number/color pairs. Everything needs to be within the <svg></svg> tags; I can’t use external HTML or scripts. The SVG file will be added to an HTML webpage in an <object> tag to preserve interactivity.

I figured out how to make the arrows into anchor elements that light up and call a JavaScript function when clicked, but I’m not sure how to make the left and right functions change which number is visible. Currently, I have all the number/color pairs as svg groups with a common class, cls-security, and a unique class for the specific number, net-0 through net-8. All groups with the class cls-security are styled with visibility: hidden, but the group which also has the class on overrides that with visibility: visible. My thought is that the cycleLeft() function should identify which element with the class cls-security also has the class on, remove the class on from that element, go to the previous element with the class cls-security (looping around to the end if necessary), and add the class on to that element; and the cycleRight() function should do the same thing but move to the next element with the class cls-security instead of the previous element with that class. However, I’m struggling to figure out how to implement that.

Everything discussed in the above paragraph could be changed if there is a better way to go about getting the effect that I want.

Am I on the right track? Is there a better way to go about doing what I want?

<svg id="Object-Panel-Security" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="132" height="72" viewBox="0 0 132 72">
    <defs>
        <style>
            .cls-txt-security {
                font-size: 16px;
                font-family: Arial, Helvetica, sans-serif;
                text-anchor: middle;
            }
            .cls-btn-security {
                opacity: 0;
            }
            a:active > .cls-btn-security {
                opacity: 1;
            }
            .cls-security {
                visibility: hidden;
            }
            .cls-security.on {
                visibility: visible;
            }
        </style>
    </defs>
    <g id="Object-Panel-Security-BG">
        <rect x="0" width="132" height="72"/>
        <rect x="4" y="4" width="124" height="64" fill="#dbcad1"/>
        <polygon points="27 12 27 27 31 27 31 45 27 45 27 60 25.875 60 12 36.125 12 35.875 25.875 12 27 12"/>
        <polygon points="105 12 105 27 101 27 101 45 105 45 105 60 106.125 60 120 36.125 120 35.875 106.125 12 105 12"/>
    </g>
    <text id="Object-Panel-Security-Title" class="cls-txt-security" transform="translate(66 27)">Sec Net</text>
    <a href="javascript:void(0)" onclick="cycleLeft()" id="Object-Panel-Security-Cycle-Left">
        <rect x="12" y="12" width="19" height="48" fill="#bebebe" opacity="0"/>
        <polygon points="25 18 25 29 29 29 29 43 25 43 25 54 14.5 36 25 18" fill="#fff" class="cls-btn-security"/>
    </a>
    <a href="javascript:void(0)" onclick="cycleRight()" id="Object-Panel-Security-Cycle-Right">
        <rect x="101" y="12" width="19" height="48" fill="#bebebe" opacity="0"/>
        <polygon points="107 18 107 29 103 29 103 43 107 43 107 54 117.5 36 107 18" fill="#fff" class="cls-btn-security"/>
    </a>
    <g id="Object-Panel-Security-Network-X" class="cls-security net-0">
        <rect x="35" y="34" width="62" height="22" fill="#a6a6a6"/>
        <text class="cls-txt-security" transform="translate(66 51)">X</text>
    </g>
    <g id="Object-Panel-Security-Network-1" class="cls-security net-1 on">
        <rect x="35" y="34" width="62" height="22" fill="#ca0000"/>
        <text class="cls-txt-security" transform="translate(66 51)">1</text>
    </g>
    <g id="Object-Panel-Security-Network-2" class="cls-security net-2">
        <rect x="35" y="34" width="62" height="22" fill="#7cb400"/>
        <text class="cls-txt-security" transform="translate(66 51)">2</text>
    </g>
    <g id="Object-Panel-Security-Network-3" class="cls-security net-3">
        <rect x="35" y="34" width="62" height="22" fill="#005eca"/>
        <text class="cls-txt-security" transform="translate(66 51)">3</text>
    </g>
    <g id="Object-Panel-Security-Network-4" class="cls-security net-4">
        <rect x="35" y="34" width="62" height="22" fill="#e6ba08"/>
        <text class="cls-txt-security" transform="translate(66 51)">4</text>
    </g>
    <g id="Object-Panel-Security-Network-5" class="cls-security net-5">
        <rect x="35" y="34" width="62" height="22" fill="#00a1b9"/>
        <text class="cls-txt-security" transform="translate(66 51)">5</text>
    </g>
    <g id="Object-Panel-Security-Network-6" class="cls-security net-6">
        <rect x="35" y="34" width="62" height="22" fill="#ca00b9"/>
        <text class="cls-txt-security" transform="translate(66 51)">6</text>
    </g>
    <g id="Object-Panel-Security-Network-7" class="cls-security net-7">
        <rect x="35" y="34" width="62" height="22" fill="#de7f00"/>
        <text class="cls-txt-security" transform="translate(66 51)">7</text>
    </g>
    <g id="Object-Panel-Security-Network-8" class="cls-security net-8">
        <rect x="35" y="34" width="62" height="22" fill="#00ca94"/>
        <text class="cls-txt-security" transform="translate(66 51)">8</text>
    </g>
    <script>//<![CDATA[
        function cycleLeft() {
            return false;
        }
        function cycleRight() {
            return false;
        }
    //]]></script>
</svg>

2

Answers


  1. You can use query selectors to get the current selected one and then subtract or add a number to it.

    Since you use the class "on", you can toggle the class or just add or remove them like I show in my example below.

    function cycleLeft() {
      const parent = document.querySelector("svg > .cls-security.on")
      const elementNum = parent.querySelector("text").innerHTML
      const num = parseInt(elementNum) - 1 || 0
      parent.classList.remove("on")
      const newElem = document.querySelector(`svg > .cls-security.net-${num}`)
      newElem.classList.add("on")
    
    }
    
    function cycleRight() {
      const parent = document.querySelector("svg > .cls-security.on")
      const elementNum = parent.querySelector("text").innerHTML
      const num = Math.min((parseInt(elementNum) || 0) + 1 , 8)
      parent.classList.remove("on")
      const newElem = document.querySelector(`svg > .cls-security.net-${num}`)
      newElem.classList.add("on")
    }
    <svg id="Object-Panel-Security" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="132" height="72" viewBox="0 0 132 72">
        <defs>
            <style>
                .cls-txt-security {
                    font-size: 16px;
                    font-family: Arial, Helvetica, sans-serif;
                    text-anchor: middle;
                }
                .cls-btn-security {
                    opacity: 0;
                }
                a:active > .cls-btn-security {
                    opacity: 1;
                }
                .cls-security {
                    visibility: hidden;
                }
                .cls-security.on {
                    visibility: visible;
                }
            </style>
        </defs>
        <g id="Object-Panel-Security-BG">
            <rect x="0" width="132" height="72"/>
            <rect x="4" y="4" width="124" height="64" fill="#dbcad1"/>
            <polygon points="27 12 27 27 31 27 31 45 27 45 27 60 25.875 60 12 36.125 12 35.875 25.875 12 27 12"/>
            <polygon points="105 12 105 27 101 27 101 45 105 45 105 60 106.125 60 120 36.125 120 35.875 106.125 12 105 12"/>
        </g>
        <text id="Object-Panel-Security-Title" class="cls-txt-security" transform="translate(66 27)">Sec Net</text>
        <a href="javascript:void(0)" onclick="cycleLeft()" id="Object-Panel-Security-Cycle-Left">
            <rect x="12" y="12" width="19" height="48" fill="#bebebe" opacity="0"/>
            <polygon points="25 18 25 29 29 29 29 43 25 43 25 54 14.5 36 25 18" fill="#fff" class="cls-btn-security"/>
        </a>
        <a href="javascript:void(0)" onclick="cycleRight()" id="Object-Panel-Security-Cycle-Right">
            <rect x="101" y="12" width="19" height="48" fill="#bebebe" opacity="0"/>
            <polygon points="107 18 107 29 103 29 103 43 107 43 107 54 117.5 36 107 18" fill="#fff" class="cls-btn-security"/>
        </a>
        <g id="Object-Panel-Security-Network-X" class="cls-security net-0">
            <rect x="35" y="34" width="62" height="22" fill="#a6a6a6"/>
            <text class="cls-txt-security" transform="translate(66 51)">X</text>
        </g>
        <g id="Object-Panel-Security-Network-1" class="cls-security net-1 on">
            <rect x="35" y="34" width="62" height="22" fill="#ca0000"/>
            <text class="cls-txt-security" transform="translate(66 51)">1</text>
        </g>
        <g id="Object-Panel-Security-Network-2" class="cls-security net-2">
            <rect x="35" y="34" width="62" height="22" fill="#7cb400"/>
            <text class="cls-txt-security" transform="translate(66 51)">2</text>
        </g>
        <g id="Object-Panel-Security-Network-3" class="cls-security net-3">
            <rect x="35" y="34" width="62" height="22" fill="#005eca"/>
            <text class="cls-txt-security" transform="translate(66 51)">3</text>
        </g>
        <g id="Object-Panel-Security-Network-4" class="cls-security net-4">
            <rect x="35" y="34" width="62" height="22" fill="#e6ba08"/>
            <text class="cls-txt-security" transform="translate(66 51)">4</text>
        </g>
        <g id="Object-Panel-Security-Network-5" class="cls-security net-5">
            <rect x="35" y="34" width="62" height="22" fill="#00a1b9"/>
            <text class="cls-txt-security" transform="translate(66 51)">5</text>
        </g>
        <g id="Object-Panel-Security-Network-6" class="cls-security net-6">
            <rect x="35" y="34" width="62" height="22" fill="#ca00b9"/>
            <text class="cls-txt-security" transform="translate(66 51)">6</text>
        </g>
        <g id="Object-Panel-Security-Network-7" class="cls-security net-7">
            <rect x="35" y="34" width="62" height="22" fill="#de7f00"/>
            <text class="cls-txt-security" transform="translate(66 51)">7</text>
        </g>
        <g id="Object-Panel-Security-Network-8" class="cls-security net-8">
            <rect x="35" y="34" width="62" height="22" fill="#00ca94"/>
            <text class="cls-txt-security" transform="translate(66 51)">8</text>
        </g>
    </svg>

    Login or Signup to reply.
  2. You

    <svg id="Object-Panel-Security" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="132" height="72" viewBox="0 0 132 72">
        <defs>
            <style>
                .cls-txt-security {
                    font-size: 16px;
                    font-family: Arial, Helvetica, sans-serif;
                    text-anchor: middle;
                }
                .cls-btn-security {
                    opacity: 0;
                }
                a:active > .cls-btn-security {
                    opacity: 1;
                }
            </style>
        </defs>
        <g id="Object-Panel-Security-BG">
            <rect x="0" width="132" height="72"/>
            <rect x="4" y="4" width="124" height="64" fill="#dbcad1"/>
            <polygon points="27 12 27 27 31 27 31 45 27 45 27 60 25.875 60 12 36.125 12 35.875 25.875 12 27 12"/>
            <polygon points="105 12 105 27 101 27 101 45 105 45 105 60 106.125 60 120 36.125 120 35.875 106.125 12 105 12"/>
        </g>
        <text id="Object-Panel-Security-Title" class="cls-txt-security" transform="translate(66 27)">Sec Net</text>
        <a href="javascript:void(0)" onclick="cycleLeft()" id="Object-Panel-Security-Cycle-Left">
            <rect x="12" y="12" width="19" height="48" fill="#bebebe" opacity="0"/>
            <polygon points="25 18 25 29 29 29 29 43 25 43 25 54 14.5 36 25 18" fill="#fff" class="cls-btn-security"/>
        </a>
        <a href="javascript:void(0)" onclick="cycleRight()" id="Object-Panel-Security-Cycle-Right">
            <rect x="101" y="12" width="19" height="48" fill="#bebebe" opacity="0"/>
            <polygon points="107 18 107 29 103 29 103 43 107 43 107 54 117.5 36 107 18" fill="#fff" class="cls-btn-security"/>
        </a>
        <g id="Object-Panel-Security-Network" class="cls-security">
            <rect x="35" y="34" width="62" height="22" fill="" />
            <text class="cls-txt-security" transform="translate(66 51)"></text>
        </g>
        <script>//<![CDATA[
        var colors =
          [ { ref: 'X', fill:'#a6a6a6' } 
          , { ref: '1', fill:'#ca0000' } 
          , { ref: '2', fill:'#7cb400' } 
          , { ref: '3', fill:'#005eca' } 
          , { ref: '4', fill:'#e6ba08' } 
          , { ref: '5', fill:'#00a1b9' } 
          , { ref: '6', fill:'#ca00b9' } 
          , { ref: '7', fill:'#de7f00' } 
          , { ref: '8', fill:'#00ca94' } 
          ];
        var 
          currentRef    = 1 
        , ObjPanel      = document.querySelector('#Object-Panel-Security-Network')
        , ObjPanel_Rect = document.querySelector('#Object-Panel-Security-Network > rect')
        , ObjPanel_Text = document.querySelector('#Object-Panel-Security-Network > text')
          ;
        setPanel()
          ;
        function setPanel()
          {
          ObjPanel.className = 'cls-security net-' + currentRef
          ObjPanel_Rect.setAttribute('fill', colors[ currentRef ].fill )
          ObjPanel_Text.textContent = colors[ currentRef ].ref
          }
            function cycleLeft() 
          {
          if ( currentRef > 0) currentRef--;
          setPanel();  
                return false;
              }
            function cycleRight()
          {
          if ( currentRef < 8) currentRef++;
          setPanel(); 
                return false;
              }
        //]]></script>
    </svg>

    can simplify on this way:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search