This is because there is no data-detail property in the HTML element.
Here is a brief description . data () , .prop () and . attr () :
The DOM is an object that has methods and properties (from the DOM ) and attributes (from the HTML rendering). Some of these properties get their initial value using attributes
id->id, class->className, title->title, style->style etc.
Consider this element: <input type="checkbox" checked data-detail="somedata" >
Result of the following:
$('input').prop('id'); // => " "-empty string, property id exist on the element (defined by DOM) , but is not set. $('input').attr('id');// => undefined - doesn't exist.
If you do the following: $('input').attr('id',"someID"); $('input').prop('id'); // => "someID" $('input').attr('id'); // => "someID"
And:
$('input').prop('id',"someOtherID"); $('input').prop('id');// => "someOtherID" $('input').attr('id');// => "someOtherID"
So, some attributes and properties have a 1: 1 mapping . (change change result attr, etc.).
Consider the following: <input type="text" data-detail="somedata" value="someValue"> $('input').prop('value'); // => "someValue" $('input').val(); // => "someValue" $('input').attr('value'); // => "someValue"
And if you do:
$('input').prop('value','newVal'); // or $('input').val('newVal'); $('input').prop('value'); // => "newVal" -value of the property $('input').val(); // => "newVal" -value of the property $('input').attr('value'); // => "someValue" -value of the attr didn't change, since in this case it is not 1:1 mapping (change of the prop value doesn't reflect to the attribute value).
1) How to get:
- Keep in mind that attribute name is data-* and property name is dataset , therefore:
<input type="checkbox" data-detail="somedata" >
$('input')[0].dataset; //=> [object DOMStringMap] { detail: "somedata"} $('input')[0].dataset.detail; // => "somedata" $('input').prop('dataset'); //=>[object DOMStringMap] { detail: "somedata"} $('input').prop('dataset').detail; // => "somedata" $('input').data('detail'); // => "somedata" $('input').attr('data-detail'); // => "somedata"
2) How to install:
I) $('input').prop('dataset').detail='newData';
$('input').prop('dataset'); //=> [object DOMStringMap] { detail: "newData"} $('input').prop('dataset').detail; // => "newData" $('input').attr('data-detail'); // => "newData" $('input').data('detail'); // => "newData"
II) $('input').attr('data-detail','newData');
$('input').prop('dataset'); //=> [object DOMStringMap] { detail: "newData"} $('input').prop('dataset').detail; // => "newData" $('input').attr('data-detail'); // => "newData" $('input').data('detail'); // => "newData"
So, you can see that the display is 1: 1, the attr change reflects prop and vice versa.
But check out the third way:
III) $('input').data('detail','newData');
$('input').prop('dataset'); // => [object DOMStringMap] { detail: "somedata"} $('input').prop('dataset').detail; // => "somedata" $('input').attr('data-detail'); // => "somedata" $('input').data('detail'); // => "newData" <-----******
So what is going on here?
$(elem).data(key, value) does not change the HTML5 data-* attributes of the HTML5 data-* element. It stores its values ββin $.cache internally.
So, to get data-* you will never go wrong in .data() :
$(".saveBtn").on("click", function() { var saveBtn = $(this); var detail = saveBtn.data("detail"); var relevantInput = saveBtn.parent().next(); var value = relevantInput.prop("value"); });