How to work with custom Custom data-* attributes [duplicate] - javascript

I am updating a data attribute by jQuery, Like:
jQuery('div').data('hidden', 'true');
alert(jQuery('div').data('hidden'));
Data attribute value got changed and returned new value which is true but DOM is still showing the old value which is false.

When you use .data() to update a data value, it is updating internal object managed by jQuery, so it will not be updated in the data-* attribute

I was beating around the bush so badly :( and able to solve the problem. Seams like we can't do achieve this using the jquery data method if the html is dynamic and the data attribute changed later after accessing the first time.
According to jQuery.data()
The data- attributes are pulled in the first time the data property is
accessed and then are no longer accessed or mutated (all data values
are then stored internally in jQuery).
So what I did is, changed it to attr method which won't give you the parsed value for integer, so you have to use '+' operand to convert like:
+ myElement.attr('data-index');
Note: You have to be careful, it will convert the result to NaN if there is any string in the data attr. BTW it's your choice of implementation of the code.

Related

Getting different results from attribute.dataset and jquery .data() method

I was getting unexpected results and when I debugged into the problem, I found that I was not getting right data-attribute value by Jquery .data() method. It was pretty clear that value was not right and when I changed my code to attribute.dataset.name (native property of an element) It returned me the expected value.
here's the screenshot of an error
Any ideas, what could be the possible reason because I am using a lot of data-attributes in my situation and don't want to change the code everywhere I am accessing data-attributes by Jquery .date() method.
.data(prop) and .dataset[prop] can be different if:
The HTML dataset contains one value
jQuery's .data has been called on the element previously to store a value associated with the same key
Example:
$('div').data('foo', 'newFooVal');
console.log($('div').data('foo'));
console.log($('div')[0].dataset.foo);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-foo="oldFooVal"></div>
jQuery's .data will retrieve:
Any previous value set with .data (which will be completely unrelated to the dataset)
If no previous value has been set to that key with that element, the value for that key in the dataset will be returned
So you have to be careful with what setting and retrieving. It's admittedly not entirely intuitive, since it'll do something different in different situations.

jQuery data function returning the first value

I have a one span tag with data attribute, data-kr-id. On clicks of different items of the list, I update this span's data-kr-id attributes and it gets updated.
When for the first time I retrieve this(data-kr-id) value using jQuery's data method, I get the correct value. But from the subsequent time, I always get the same value as of the first time. But on using jQuery's attr function, I get the correct value. Can't figure out why.
CODE: Where I set the data-kr-id value:
$_applozicWtLauncherBtn.attr('data-kr-id', seller.UserId);
CODE: Where I retrieve the values:
var topicId = $applozic(this).data("kr-id");
topicId = $applozic(this).attr("data-kr-id");
In the above code where I retrieve values, using data method gives me old value(the value of the first item I retrieved), but using attr method gives me correct value.
UPDATE :
As informed by everyone, I was setting the data attributes with attr method and retrieving the value with data method. After using data method for setting the attribute, When I was retrieving the values, I was getting a getting empty string. After digging a bit deeper, I realized there are two different versions of the jQuery are being used here.
Sorry for the incomplete information and late update.
You set value only using attr, Second time when you set data-kr-id value using attr then data value remains same, so need to set value with data also
// With Attr
$_applozicWtLauncherBtn.attr('data-kr-id', seller.UserId);
// With Data
$_applozicWtLauncherBtn.data('kr-id', seller.UserId);
Actually jquery's .data() fetches value from the property (same as .prop()) not from attributes. Main difference is .attr() fetches data from HTML tag which you can see it will reflect on your HTML when you update it with .attr(). But when you use .prop() or .data() it will not reflect in HTML tag but it will update value in it's property for that HTML tag as per the DOM tree.
You'll find out more about difference property and attribute from here.
Initially this property will set when your element is created. So for the first time your .data() and .attr() will work fine. When you update value from .attr() it will manipulate DOM but property will be remain same.

What is the difference between .data('sth') and .attr('data-sth')? [duplicate]

What is the difference in usage between $.data and $.attr when using data-someAttribute?
My understanding is that $.data is stored within jQuery's $.cache, not the DOM. Therefore, if I want to use $.cache for data storage, I should use $.data. If I want to add HTML5 data-attributes, I should use $.attr("data-attribute", "myCoolValue").
If you are passing data to a DOM element from the server, you should set the data on the element:
<a id="foo" data-foo="bar" href="#">foo!</a>
The data can then be accessed using .data() in jQuery:
console.log( $('#foo').data('foo') );
//outputs "bar"
However when you store data on a DOM node in jQuery using data, the variables are stored on the node object. This is to accommodate complex objects and references as storing the data on the node element as an attribute will only accommodate string values.
Continuing my example from above:
$('#foo').data('foo', 'baz');
console.log( $('#foo').attr('data-foo') );
//outputs "bar" as the attribute was never changed
console.log( $('#foo').data('foo') );
//outputs "baz" as the value has been updated on the object
Also, the naming convention for data attributes has a bit of a hidden "gotcha":
HTML:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
JS:
console.log( $('#bar').data('fooBarBaz') );
//outputs "fizz-buzz" as hyphens are automatically camelCase'd
The hyphenated key will still work:
HTML:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
JS:
console.log( $('#bar').data('foo-bar-baz') );
//still outputs "fizz-buzz"
However the object returned by .data() will not have the hyphenated key set:
$('#bar').data().fooBarBaz; //works
$('#bar').data()['fooBarBaz']; //works
$('#bar').data()['foo-bar-baz']; //does not work
It's for this reason I suggest avoiding the hyphenated key in javascript.
For HTML, keep using the hyphenated form. HTML attributes are supposed to get ASCII-lowercased automatically, so <div data-foobar></div>, <DIV DATA-FOOBAR></DIV>, and <dIv DaTa-FoObAr></DiV> are supposed to be treated as identical, but for the best compatibility the lower case form should be preferred.
The .data() method will also perform some basic auto-casting if the value matches a recognized pattern:
HTML:
<a id="foo"
href="#"
data-str="bar"
data-bool="true"
data-num="15"
data-json='{"fizz":["buzz"]}'>foo!</a>
JS:
$('#foo').data('str'); //`"bar"`
$('#foo').data('bool'); //`true`
$('#foo').data('num'); //`15`
$('#foo').data('json'); //`{fizz:['buzz']}`
This auto-casting ability is very convenient for instantiating widgets & plugins:
$('.widget').each(function () {
$(this).widget($(this).data());
//-or-
$(this).widget($(this).data('widget'));
});
If you absolutely must have the original value as a string, then you'll need to use .attr():
HTML:
<a id="foo" href="#" data-color="ABC123"></a>
<a id="bar" href="#" data-color="654321"></a>
JS:
$('#foo').data('color').length; //6
$('#bar').data('color').length; //undefined, length isn't a property of numbers
$('#foo').attr('data-color').length; //6
$('#bar').attr('data-color').length; //6
This was a contrived example. For storing color values, I used to use numeric hex notation (i.e. 0xABC123), but it's worth noting that hex was parsed incorrectly in jQuery versions before 1.7.2, and is no longer parsed into a Number as of jQuery 1.8 rc 1.
jQuery 1.8 rc 1 changed the behavior of auto-casting. Before, any format that was a valid representation of a Number would be cast to Number. Now, values that are numeric are only auto-cast if their representation stays the same. This is best illustrated with an example.
HTML:
<a id="foo"
href="#"
data-int="1000"
data-decimal="1000.00"
data-scientific="1e3"
data-hex="0x03e8">foo!</a>
JS:
// pre 1.8 post 1.8
$('#foo').data('int'); // 1000 1000
$('#foo').data('decimal'); // 1000 "1000.00"
$('#foo').data('scientific'); // 1000 "1e3"
$('#foo').data('hex'); // 1000 "0x03e8"
If you plan on using alternative numeric syntaxes to access numeric values, be sure to cast the value to a Number first, such as with a unary + operator.
JS (cont.):
+$('#foo').data('hex'); // 1000
The main difference between the two is where it is stored and how it is accessed.
$.fn.attr stores the information directly on the element in attributes which are publicly visible upon inspection, and also which are available from the element's native API.
$.fn.data stores the information in a ridiculously obscure place. It is located in a closed over local variable called data_user which is an instance of a locally defined function Data. This variable is not accessible from outside of jQuery directly.
Data set with attr()
accessible from $(element).attr('data-name')
accessible from element.getAttribute('data-name'),
if the value was in the form of data-name also accessible from $(element).data(name) and element.dataset['name'] and element.dataset.name
visible on the element upon inspection
cannot be objects
Data set with .data()
accessible only from .data(name)
not accessible from .attr() or anywhere else
not publicly visible on the element upon inspection
can be objects
You can use data-* attribute to embed custom data. The data-* attributes gives us the ability to embed custom data attributes on all HTML elements.
jQuery .data() method allows you to get/set data of any type to DOM elements in a way that is safe from circular references and therefore from memory leaks.
jQuery .attr() method get/set attribute value for only the first element in the matched set.
Example:
<span id="test" title="foo" data-kind="primary">foo</span>
$("#test").attr("title");
$("#test").attr("data-kind");
$("#test").data("kind");
$("#test").data("value", "bar");

Can a DOM element have an attribute whose value is an arbitrary object (not a string)?

I'd like to do something like this:
var elem = document.createElement("input");
elem.setAttribute("my-attribute", myObject);
document.getElementById("parent").appendChild(elem);
Later I will need to fetch myObject when performing some actions on this (and similar) element(s).
Note: I need this as an attribute (and not, for example, as a member of the element object, as in elem.myAttribute = myObject), as for some elements the value is a string which is hard-coded into the HTML of the page. What I need is the ability to set this attribute programmatically for other elements, and to use values which are not always plain strings.
I tried this and it worked in my browser (Firefox 14), but I need to know if this works cross-browser, and also if I'll be able to fetch the values of such attributes using jQuery if I decide to use jQuery in my page later on.
No - attributes by definition store string values. The obvious approach is to store the object as a property but you say that's not suitable.
Either:
1) Use jQuery's data API (since it does not literally log the data on the element, so you can store whatever you want, not only strings)
2) Stringify the object and append that to the element as an HTML5 data attribute.
var elem = document.querySelector('p'),
obj = {foo: 'bar'};
elem.setAttribute('data-myObj', JSON.stringify(obj));
/* ...then, later... */
var data = JSON.parse(elem.getAttribute('data-myObj'));
Note, though, that, because we're dealing with JSON, you will not be able to store methods as part of this object. They will be stripped out by JSON.stringify().
Finally, using attributes means you'll muddy your HTML since they show up in any HTML dumps (unlike properties) but this is purely a cosmetic weakness.
You can use the data attribute in jquery to do this (http://api.jquery.com/data/)
You can use html 5 data attributes:
http://ejohn.org/blog/html-5-data-attributes/
And these can be retrieved using the jquery data api.
These will have to be stringifed however
"As of jQuery 1.4.3 HTML 5 data- attributes will be automatically pulled in to jQuery's data object"

Can a DOM object be an index/key in Javascript array?

Would like to maintain a map/hash of DOM objects. Can they serve as key objects? If not, what are the alternatives, please? If there are better ways - kindly enlist them as well.
You can put anything as the key, but before actual use it is always converted to string, and that string is used as a key.
So, if you look at what domObject.toString() produces, you see it is not a good candidate. If all of your dom objects have an id, you could use that id.
If not, and you still desperately need a key based on DOM object, you probably could do with using, for example, _counter attribute with automatic counter in background putting new unique value in a DOM object if _counter is not yet present.
window already maintains all DOM objects as properties. Instead of putting your own keys for each 'DOM object' try to use window or document object and methods that uses index based on the layout of DOM tree.
No, because object keys are strings.
You'd have to "serialise" your objects by id or something, then perform a lookup later. Probably not worth it, depending on what your actual goal is here.
No, but you can set an attribute on the DOM element that contains a number, which you would have as the index in a numerically-indexed array.
Easiest is to set a data-attribute on the element instead.
Not exact. But I think you want something like below. You can do with jquery,
The .serializeArray() method creates a JavaScript array of objects, ready to be encoded as a JSON string. It operates on a jQuery object representing a set of form elements. The form elements can be of several types
Refer below link :
http://api.jquery.com/serializeArray/

Categories