0

I have a gallery program that has buttons on each of the images. Each button is meant to open a menu, and it is the same menu for every image (which is a simple list of folders to move the image to). I have a PHP foreach loop that is able to assign a different js function name to each of the buttons, in the efforts to be able to have a toggle button for each image.

I'm hoping somebody can illustrate how to implement a better solution for this, rather than having the foreach loop assigning a different function name like this: <button onclick="function1()"></button>, <button onclick="function2()"></button>, and so on. This is because there could be up to 200 different images and this would require up to 200 different javascript functions to be written.

There must be another way to assign the same js function to any and all of the assigned buttons.

The problem I'm having is that if I have only 1 function; whenever I click on the first image, the menu pops up which is great. But then when I click on the following or any other image's button, it only opens up the menu on the first image again, and does not open the menu on the selected image.

So for example I want to be able to have: <button onclick="function()"></button>, and that should be able open a menu on any of the image's buttons.

There must be an easier solution rather than writing out 200 js functions.

Thanks in advance.

My PHP code:

<button onclick="toggle_pinit()" type="button" id="pinit_button"><img src="1.png"/></button>

and my Javascript code:

function toggle_pinit() 
{
    var button = document.getElementById('pinit_button');
    {
        var div = document.getElementById('pinit_menu'); // display select_show
        if (div.style.visibility == 'hidden') 
        {
            div.style.visibility = 'visible';
        }
        else 
        {
            div.style.visibility = 'hidden';
        }
    }
}

1 Answer 1

1

First of all, IDs should be unique. If multiple elements should have it, use a class instead. Then, using JS directly in your HTML is not really a good practice. Separate your HTML from your styles and your scripts.

That beying said, here is how I would do it:

// Wait until the document is loaded
window.addEventListener('DOMContentLoaded', function() {
  // Find all pin buttons and put them into an iterable Array
  var pinBtns = Array.from(document.querySelectorAll('.pinit_button')),
      // Find the menu
      pinMenu = document.getElementById('pinit_menu'),
      // Just for the demo
      pinSrc = document.getElementById('src'),
      selectedSrc = '';
      
  // For each of the buttons
  pinBtns.forEach(function(btn) {
    // Listen for clicks on them
    btn.addEventListener('click', togglePin);
  });
  
  // Do whatever you want here
  function togglePin(e) {
    // Get the src of the clicked image
    var newSrc = e.target.src;
    // If it was already selected, close the menu
    if (selectedSrc === newSrc) {
      pinMenu.classList.remove('open');
      // Reset the image src
      selectedSrc = '';
    // Otherwise, open it
    } else {
      pinMenu.classList.add('open');
      // Show the src in the menu's text
      pinSrc.innerText = e.target.src;
      // Store it for later use
      selectedSrc = newSrc;
    }
    
  }
});
body {
  font-size: 12px;
  font-family: Arial, Helvetica, sans-serif;
}

.pinit_button {
  cursor: pointer;
}

#pinit_menu {
  margin: 1em 0;
  padding: .5em;
  background: #0072ff;
  color: #fff;
  display: none;
}

#pinit_menu.open {
  display: block;
}
<p>Click on an image:</p>
<button class="pinit_button"><img src="https://placeimg.com/50/50/animals"></button>
<button class="pinit_button"><img src="https://placeimg.com/50/50/arch"></button>
<button class="pinit_button"><img src="https://placeimg.com/50/50/nature"></button>
<button class="pinit_button"><img src="https://placeimg.com/50/50/people"></button>
<button class="pinit_button"><img src="https://placeimg.com/50/50/tech"></button>

<div id="pinit_menu">Here you can do whatever you need, knowing that the image you clicked on has this src: <span id="src"></span></div>

Sign up to request clarification or add additional context in comments.

4 Comments

When I run snippet, user clicks on an image once, it displays pinit_menu, then user clicks on same image again, and pinit_menu disappears. But then user clicks on the same image again, and nothing happens. Is it possible to get the toggle truly working? This is great code btw. It almost works, but I'm still having the issue that it's only working on the first image, and the toggle only reacts once. It won't toggle off and it doesn't work on the other images other than first.
@AceThanks Sorry about that, I messed up in the togglePin function. I think I fixed it, tell me if that works for you
Actually I think it's working just fine, it's just that the menu comes up in the same place. If I organise the menu it should be fine. But I will try your new toggle. P.s. there was supposed to be a pinit_menu div in the foreach loop, so that each image has it's own pinit_menu div that can open up, but I like your approach. Just use the same div and center it perhaps.
Oh ok, I did not guess that from your question

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.