2

I'm trying to create a popout menu for an array of values that are echoed from the database. On the click of the svg, the popout menu that corresponds with the svg in the echo, needs to be shown. Except so far, it only works for the first one that is echoed. How to I fix it so that it show the popout that corresponds with the correct svg. Here's what I've currently got :

PHP/HTML :

echo('
    <svg class="option-3" width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M9 10.5C9.82843 10.5 10.5 9.82843 10.5 9C10.5 8.17157 9.82843 7.5 9 7.5C8.17157 7.5 7.5 8.17157 7.5 9C7.5 9.82843 8.17157 10.5 9 10.5Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
        <path fill-rule="evenodd" clip-rule="evenodd" d="M15 10.5C15.8284 10.5 16.5 9.82843 16.5 9C16.5 8.17157 15.8284 7.5 15 7.5C14.1716 7.5 13.5 8.17157 13.5 9C13.5 9.82843 14.1716 10.5 15 10.5Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
        <path fill-rule="evenodd" clip-rule="evenodd" d="M3 10.5C3.82843 10.5 4.5 9.82843 4.5 9C4.5 8.17157 3.82843 7.5 3 7.5C2.17157 7.5 1.5 8.17157 1.5 9C1.5 9.82843 2.17157 10.5 3 10.5Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>  
    <div class="menu-option-popout"></div>
');

JS :

document.querySelector(".option-3").addEventListener("click", function(){
    document.querySelector(".menu-option-popout").style.display = "block";
});

2 Answers 2

1

If each popout <div> appears immediately after its corresponding <svg> tag (as in your example), you can take advantage of the .nextElementSibling property to get the <div> that follows the <svg> that was clicked.

At the end of your HTML:

<script>
// Add an event listener to each .option-3 element:
document.querySelectorAll('.option-3').forEach(item => {
  item.addEventListener('click', event => {
    let popout = event.target.nextElementSibling; // This element's next element (a .menu-option-popout)
    popout.style.display = 'block'; // Show the popout
  })
})
</script>
Sign up to request clarification or add additional context in comments.

2 Comments

I get the error event.target.nextElementSibling is not a function?
My mistake, nextElementSibling is a property, not a method. Just remove the () after nextElementSibling and it should work. I've updated my code.
0

First of all PHP is executed first, so you will not be able to call php from a JS action unless using AJAX features. But it is not your use case here.

That said, we can continue with :

echo('
    <svg class="option-3" width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M9 10.5C9.82843 10.5 10.5 9.82843 10.5 9C10.5 8.17157 9.82843 7.5 9 7.5C8.17157 7.5 7.5 8.17157 7.5 9C7.5 9.82843 8.17157 10.5 9 10.5Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
        <path fill-rule="evenodd" clip-rule="evenodd" d="M15 10.5C15.8284 10.5 16.5 9.82843 16.5 9C16.5 8.17157 15.8284 7.5 15 7.5C14.1716 7.5 13.5 8.17157 13.5 9C13.5 9.82843 14.1716 10.5 15 10.5Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
        <path fill-rule="evenodd" clip-rule="evenodd" d="M3 10.5C3.82843 10.5 4.5 9.82843 4.5 9C4.5 8.17157 3.82843 7.5 3 7.5C2.17157 7.5 1.5 8.17157 1.5 9C1.5 9.82843 2.17157 10.5 3 10.5Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>  
    <div class="menu-option-popout"></div>
');

should be written as this to improve the readability of your generated HTML document :

echo '<svg class="option-3" width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M9 10.5C9.82843 10.5 10.5 9.82843 10.5 9C10.5 8.17157 9.82843 7.5 9 7.5C8.17157 7.5 7.5 8.17157 7.5 9C7.5 9.82843 8.17157 10.5 9 10.5Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
        <path fill-rule="evenodd" clip-rule="evenodd" d="M15 10.5C15.8284 10.5 16.5 9.82843 16.5 9C16.5 8.17157 15.8284 7.5 15 7.5C14.1716 7.5 13.5 8.17157 13.5 9C13.5 9.82843 14.1716 10.5 15 10.5Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
        <path fill-rule="evenodd" clip-rule="evenodd" d="M3 10.5C3.82843 10.5 4.5 9.82843 4.5 9C4.5 8.17157 3.82843 7.5 3 7.5C2.17157 7.5 1.5 8.17157 1.5 9C1.5 9.82843 2.17157 10.5 3 10.5Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>  
    <div class="menu-option-popout"></div>'.PHP_EOL;

And it is only HTML stored inside database, so there are many things to look at :

  • Any bad escaped string can put the mess inside your displayed datas
  • Any bad char's encoding can put the mess inside your displayed datas

Maybe just call the equiv .toogle() JQuery method of ECMAScript on that .option-3 class will work and display your item as you wish.

3 Comments

OP didn't mention jQuery, just native JS.
Sorry. I forgot to mention that it isn't HTML that is being stored in the database, but rather the data is being echoed onto the screen with HTML. I just haven't included the whole echo here.
That's why I did not have done the job but give a way to go. I do not like to give ready to use solutions, but put people on the right path to work a bit themselves. It does not hurt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.