1

I have a page dynamically created with buttons. I would like to find the corresponding button data-ids value if I click li link edit or show? I tried with closest () but without success.

<div class=\"btn-group\">
    <button type=\"button\" class=\"btn dropdown-toggle actions\" data-ids=\"1\" data-toggle=\"dropdown\" aria-expanded=\"false\">
        <span class=\"glyphicon glyphicon-edit\"></span>
    </button>
    <ul class=\"dropdown-menu\" role=\"menu\">
        <li><a href=\"\" class="edit">Edit</a></li>
        <li><a href=\"\" class="show">Show</a></li>
    </ul>
</div>
<div class=\"btn-group\">
    <button type=\"button\" class=\"btn dropdown-toggle actions\" data-ids=\"2\" data-toggle=\"dropdown\" aria-expanded=\"false\">
        <span class=\"glyphicon glyphicon-edit\"></span>
    </button>
    <ul class=\"dropdown-menu\" role=\"menu\">
        <li><a href=\"\" class="edit">Edit</a></li>
        <li><a href=\"\" class="show">Show</a></li>
    </ul>
</div>
...

JS

$('.edit').on('click', function(e) {

    e.preventDefault();
    var ids = $(this).closest('button.actions').attr('data-ids');
});

How could I do, seen that it is not a parent element? Thank you

Paolo Rossi
  • 2,490
  • 9
  • 43
  • 70

5 Answers5

1

Find a valid parent (btn-group), and the use find() to get the desired child.

var ids = $(this).closest('.btn-group')    //common parent containing the desired element
                 .find('button.actions')   //find the element
                 .data('ids'); 

Use data() instead of attr().

Also, are you appending this markup dynamically? If no, there is no need to escape quotes \"\".

If the elements are appended dynamically, you need to use delegation.

Event binding on dynamically created elements

Fiddle : http://jsfiddle.net/uxtu6qm3/3/

Community
  • 1
  • 1
Shaunak D
  • 20,588
  • 10
  • 46
  • 79
1

button.actions isn't parent of .edit, use

var ids = $(this).closest('ul').prev().attr('data-ids');

OR

var ids = $(this).closest('.btn-group').find('button.actions').attr('data-ids'); 
pavel
  • 26,538
  • 10
  • 45
  • 61
  • 1
    works, just you can't put there escaped quotes http://jsfiddle.net/uxtu6qm3/5, use the first one with `prev`, it should be a little bit faster. – pavel Jun 05 '15 at 08:44
  • Comment: Any speed difference is negligible for a click event (unless they click it 50,000 times per second!) :) The second option is better for maintenance as it will be more likely to survive changes to the DOM. – iCollect.it Ltd Jun 05 '15 at 09:52
1

If the elements are dynamically added, you need to change to use a delegated event handler, attached to a non-changing ancestor element:

e.g.

$(document).on('click', '.edit', function(e) {

This version of on applies the jQuery selector (i.e. .edit) at event time and not when the event was registered. This means the elements only need to exist when the click occurs for it to work.

The other issue is that the item you seek is not an ancestor, so you need to search up then down another branch.

e.g.

  $(this).closest('.btn-group').find('button.actions')

Which finds the common btn-group ancestor then searches down for the action button.

JSFiddle: http://jsfiddle.net/TrueBlueAussie/uxtu6qm3/4/

Note: I obviously had to convert the literal HTML to HTML for a JSFiddle (i.e. remove the escaping)

iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
  • @TrueBlueAussie - I makes the fiddle as point of question poster. Not as a developer. Untill you have didn't change the html you can't give the right answer for this question. I am always right in my point – Sudharsan S Jun 05 '15 at 09:00
  • 1
    @JqueryKing: The HTML *is* valid for a *string literal template* so does not require correction, just not valid for a JSFiddle. I'm afraid in this case "your arrogance is writing cheques that your skills cannot cash" :) – iCollect.it Ltd Jun 05 '15 at 09:17
1

".actions" is not the parent element of edit button. You need to get the common parent of both nodes, then find the .action element

var ids = $(this).closest(".btn-group").find('button.actions').attr('data-ids');

or

var ids = $(this).parent().prev().attr('data-ids');
Anoop Joshi P
  • 25,373
  • 8
  • 32
  • 53
  • @TrueBlueAussie - I makes the fiddle as point of question poster. Not as a developer. Untill you have didn't change the html you can't give the right answer for this question. I am always right in my point as 'JQUERYKING' – Sudharsan S Jun 05 '15 at 09:08
1

I believe the simplest way to achieve this would be to add the data-ids attribute to the dropdown-menu ul as well. Then you can use

$('.edit').on('click', function(e) {
  e.preventDefault();
  var ids = $(e.target).parent().data('ids');
});
rrowland
  • 2,734
  • 2
  • 17
  • 32