B Seven
B Seven

Reputation: 45941

How to handle the same jQuery event handler on multiple elements?

Suppose you have the following code to update many elements:

<div class='item'>
  Name:<input type='text' name='name' data-id='123' value='Name 1'>
  <button class='update'>update</button>
</div>

<div class='item'>
  Name:<input type='text' name='name' data-id='456' value='Name 2'>
  <button class='update'>update</button>
</div>

And JavaScript to handle the update:

function updateName(name, id){
  ...
}

What is the jQuery handler that can find the value and id and call updateName?

$('button.update').click(function() {
  name = ?
  id = ?
  updateName(name, id)
}

EDIT:

The expected behavior is that when the user updates the input field, the updated value is sent to updateName(), not the original value.

Also, note that the data-id and value are on the input, not the button.

http://jsfiddle.net/e3g6nfc1/8/

Upvotes: 2

Views: 507

Answers (3)

George Mauer
George Mauer

Reputation: 122212

Inside event handlers this is the unwrapped DOM element

$('button.update').click(function() {
  var name = this.name
  var id = $(this).data('id');
  updateName(name, id)
}

note that you want var in this case or else name and id jump out of the scope of that function and possibly become global variables.

I've argued before that this is awkward and bad to use. You can achieve the same effect without using it like so:

$('button.update').click(function(e) {
  var name = e.currentTarget.name
  var id = $(e.currentTarget).data('id');
  updateName(name, id)
}

You also don't have to use jquery for data. on reasonably modern browsers $(domElement).data('foo') is equivalent to domElement.dataset['foo']


Edit: Not sure if I missed this in the question or if it got edited but it seems like you're asking not for attributes on the button but the element before it. In that case you want $.fn.prev which will look something like this

$('button.update').click(function(e) {
  var $prev = $(e.currentTarget).prev();
  updateName($prev.name, $prev.data('id'))
}

note that this assumes that the input element is directly before the button. If you want to find the closest preceding input element you would use $.fn.prevAll

  var $prev = $(e.currentTarget).prevAll('input').last();

Upvotes: 4

MrYellow
MrYellow

Reputation: 408

Not sure why the answers here are trying to find the input attributes on the button element...

<div id="container">
    <div class='item'>
      Name:<input type='text' name='name' data-id='123' value='Name 1'>
      <button class='update'>update</button>
    </div>

    <div class='item'>
      Name:<input type='text' name='name' data-id='456' value='Name 2'>
      <button class='update'>update</button>
    </div>
</div>

Delegating the events to attach only to the container (selecting only those children with .update class), catching them as they "bubble up". previousElementSibling used to target the input but jQuery selectors could also be used to find it if the layout were more complex.

$('#container').on('click','.update',function(e) {
    updateName(
        e.currentTarget.previousElementSibling.name, 
        $(e.currentTarget.previousElementSibling).data('id')
    );
});

JSFiddle

Upvotes: 1

Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85633

Like this:

$('button.update').click(function() {
  name = $(this).attr('name');//to get value of name attribute
  id = $(this).data('id'); // to get value of attribute data-id
  updateName(name, id)
}

You may also use prop() method to get name or data-id:

name = $(this).prop('name');
id = $(this).prop('data-id');

But best is to use data() method for data-* attribute.

Upvotes: 2

Related Questions