Search code examples
javascripthtmldomhandlebars.jsgetelementbyid

I'm having trouble making an svg tooltip appear correctly next to my product options using Javascript and HTML DOM elements


Hi I'm quite new to web development so please bear with me. I have an SVG I want to make appear dynamically depending on which product option it is next to, displaying a different string for each product option. I have the tooltip part working, where it displays the tooltip, however I can't get my Javascript part of it working for it to display dynamically and change the string it displays or to not show at all.

I need string to be added in between the tags and when the function proves false, the svg to not display at all, and right now it does neither of that.

Here is the code I have so far, If someone could show me where I'm going wrong?

<script>
    function productTooltip() {
        const ttip = "{{id}}";
        if (ttip === "4146") {
            document.getElementById('mySvg').style.display = "inline";
            span.append("RAM", 'tooltiptext');
        } else if (ttip === "1734") {
            document.getElementById('mySvg').style.display = "inline";
            span.append("SSD", 'tooltiptext');
        } else {
            document.getElementById('mySvg').style.display = "none";
        }
    }
</script>
<div class="tooltip">
    <svg id="tooltipsvg" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path display="inline" id="mySvg" d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.496 6.033h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286a.237.237 0 0 0 .241.247zm2.325 6.443c.61 0 1.029-.394 1.029-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94 0 .533.425.927 1.01.927z"/>
        <span class="tooltiptext"></span>
    </svg>
</div>

Please note that "const ttip = "{{id}};" is using handlebars. And 4146 and 1734, are just examples of the Id's of the elements I am trying to use to generate the tooltips.

Any help is appreciated, thanks!


Solution

  • I think your issue is a misunderstanding of the Element.append() API.

    You are using span as if it is a variable, but haven't shown us where it get assigned a value - which, in order to call .append(), should be a DOM Element.

    It looks like you are trying to target the <span class="tooltiptext"> element by passing the string "tooltiptext" as the second argument to .append(), but this is not the correct usage. The second argument, just as the first, is an HTML node or string to append to the target element.

    Furthermore, .append() will cause issues when your productTooltip is called more than once, because each time it will append a new text node to the element - ie., the text will keep growing. Instead, we should replace the current child text node, using Element.replaceChildren().

    I think the solution has two parts:

    1. Assign a reference to <span class="tooltiptext"> to the span variable.
    2. Replace the.append() calls with .replaceChildren().

    The resulting JavaScript becomes:

    const span = document.querySelector(".tooltiptext");
    
    function productTooltip(ttip) {
      const ttip = "{{id}}";
    
      if (ttip === "4146") {
        document.getElementById('mySvg').style.display = "inline";
        span.replaceChildren("RAM");
      } else if (ttip === "1734") {
        document.getElementById('mySvg').style.display = "inline";
        span.replaceChildren("SSD");
      } else {
        document.getElementById('mySvg').style.display = "none";
      }
    }
    

    I have created a fiddle for reference.