0

I have multiple buttons in a for loop. I want to show only one modal when I click a button, but now it shows all modals for every button when I click the button. I want to show one modal for each button. How do i fix the problem?

  each user in users
    tr
      td= user.email
      td
        .ui.basic.blue.button#more More
          .ui.mini.modal.myModal
            i.close.icon
            .header
              | #{user.email}
            .content
              |#{user.email}  
            .actions
              .ui.positive.right.labeled.icon.button
                 | Yep!
                 i.checkmark.icon 

JQuery

$('#more').click(function(){
  $('.ui.modal.myModal').modal({
  }).modal('show');
});
Patrick Hund
  • 19,163
  • 11
  • 66
  • 95
Scott Kim
  • 233
  • 1
  • 4
  • 13
  • You can't repeat ids. Change your `#more` to a class, and then you can use a contextual lookup to find the modal related to the more button you clicked. – Taplar Aug 20 '18 at 15:30
  • Also as a side note, not everyone who reads questions on StackOverflow may understand whatever templating engine you are using. While it is much more probable that they understand html. When you make questions regarding javascript, please provide the generated html that the script will run against, not the templating, to include as many people able to answer your question as possible. – Taplar Aug 20 '18 at 15:31
  • @Taplar Users should post in whatever language they're working with. Other potential answers may make use of Pug. – Sean Aug 20 '18 at 18:16
  • @sean afaik, javascript only works with html, yes? So if you are asking a question about an interaction of javascript with the browers, you should show what the end result the browser is working with, imho. Providing the templating that generates the markup just makes it one step harder to debug. It takes very little effort to inspect the page and copy the generated html – Taplar Aug 20 '18 at 18:18
  • @Taplar See my answer for how inclusion of the templating language can allow for more performant answers. Feel free to ask users to additionally provide compiled code if you don't understand the templating language, but to suggest they should never include templating code isn't productive. – Sean Aug 20 '18 at 18:34

2 Answers2

0
.ui.basic.blue.button#more More

Ids are expected to be unique within a DOM (Does ID have to be unique in the whole page?). If you need an identifier to repeat, that reflects a class. First change your definition to use a class.

.ui.basic.blue.button.more More

Then you should be able to change your click handler to perform a contextual lookup, to find which modal is associated with that button.

$('.more').click(function(){
  $(this).closest('td').find('.ui.modal.myModal').modal({
  }).modal('show');
});

This logic finds the parent td of the button you clicked, and then finds the nested modal in it. If the modal is a child of the more element, you could just do a find, rather than the closest() step.

Taplar
  • 24,788
  • 4
  • 22
  • 35
  • Hello, this solved my problem, but it does not shows up modal when I close the modal, and try to open it again. what should i do? thx – Scott Kim Aug 21 '18 at 08:44
  • this solved my problem, but it does not shows up modal when I close the modal, and try to open it again. what should i do? thx – Scott Kim Aug 21 '18 at 12:38
  • @ScottKim do you have an example of the issue? You may also want to make a new question regarding the re-open issue. – Taplar Aug 21 '18 at 18:08
0

As Taplar's answer points out, id attributes are meant to be unique within a DOM.

Another approach would be to tie each button to its modal using classes or data attributes within the loop. You can get the index of the loop in pug and use that to create unique classes or data attributes.

each user, index in users
  tr
    td= user.email
    td
      // add a unique data attribute serialized with the id
      .ui.basic.blue.button(data-modal= 'modal-' + index) More
        .ui.mini.modal.myModal(data-modal= 'modal-' + index)
          i.close.icon
          .header
            | #{user.email}
          .content
            | #{user.email}  
          .actions
            .ui.positive.right.labeled.icon.button
              | Yep!
              i.checkmark.icon

This allows you to have more performant jQuery that avoids relying on DOM traversal

$('.button[data-modal]').click(function() {
  $('.modal[data-modal=' + $(this).attr('data-modal') + ']').modal().modal('show');
})
Sean
  • 6,873
  • 4
  • 21
  • 46
  • Hello, this still shows multiple modals, but another answer solved the problem, but it does not shows up modal when I close the modal, and try to open it again. what should i do? thx – Scott Kim Aug 21 '18 at 09:01
  • This solution should work if implemented correctly. Are you sure you added the `index` part of the each loop? `each user, index in users` – Sean Aug 21 '18 at 15:21
  • 1
    Thx for the help! I fixed it ! – Scott Kim Aug 22 '18 at 13:38