-3

This code works perfect:

attributes = $("#testForm").data();
console.log(attributes);
console.log(Object.keys(attributes).length);

but only one time, when I dynamically added additional data attributes onclick event, it shows same value. I know that .data() is caches somehow, but how to handle it dynamically

Example:

<form id="testForm" data-id="33" data-size="45">

When I call the code above, it returns 2, but when I added more data attributes, like:

<form id="testForm" data-id="33" data-size="45" data-color="red" data-activity"1">

Code above still returns 2.

$(function ($) {
    attributes = $("#testForm").data();
    console.log(attributes);
    console.log(Object.keys(attributes).length);
    
   $('#testButton').on('click', function () {
     $("#testForm").attr( 'data-size' , 'test' );
     $("#testForm").attr( 'data-use' , 'test' );
      attributes = $("#testForm").data();
      console.log(attributes);
      console.log(Object.keys(attributes).length);
   });
 
 });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="filter-body" id="testForm" data-length="1">
          <button id="testButton">test<button>
        </form>

getAttribute() and attr() require specific data-attribute name, in my case I will have 10,15 or more data-attributes of element, with different name, so I can pass specific name, I'm looking to get length of all of them, but dynamically.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • I get 4 when I run it with the last
    . Please use the `<>` snippet tool, and create a working example of the problem
    – Carsten Løvbo Andersen Jan 11 '22 at 10:39
  • 2
    _"when I dynamically added additional data attributes onclick event"_ - how exactly? – CBroe Jan 11 '22 at 10:40
  • 1
    Please [edit] your post and provide a [mre]. – Sebastian Simon Jan 11 '22 at 10:40
  • @CBroe Well, on click event, getting form element and add additional data attributes to it. – Doroteya Garbachkova Jan 11 '22 at 10:42
  • Don't store a snap-shot and use that. `Object.keys($("#testForm").data()).length` or `document.querySelector("#testForm").dataset.length` – Andreas Jan 11 '22 at 10:42
  • @CarstenLøvboAndersen Yes, but when I add additional attributes to same form it is still 4. – Doroteya Garbachkova Jan 11 '22 at 10:42
  • 1
    @DoroteyaGarbachkova _“it is still 4”_ — So it’s working? Again, please simply [edit] the post and provide all the necessary details there. The comments are _not_ for providing details that are part of the question, piece by piece. – Sebastian Simon Jan 11 '22 at 10:44
  • 2
    The `data` method only reads the values of custom data attributes on first invocation (as clearly mentioned in the docs.) So either add your additional data _using_ the `data` method (then jQuery will handle storage internally), or, if you _need_ them to be actual custom data attributes, use https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset instead of jQuery's `data` method. – CBroe Jan 11 '22 at 10:45
  • 1
    Does this answer your question? [jQuery's data() attribute does not update when element data changes](https://stackoverflow.com/questions/21588044/jquerys-data-attribute-does-not-update-when-element-data-changes) – A_A Jan 11 '22 at 10:47
  • @SebastianSimon "“it is still 4” — So it’s working?", no it's not working, because I have added new attributes and they are 6 already or 7 etc. and it show still 4 .. I think that question is clear enough, key word is dinamically, – Doroteya Garbachkova Jan 11 '22 at 10:47
  • @A_A I already check this post, but it's work with specific name of data attributes, I mean you should pass data-attribute name, I want length of all attributes – Doroteya Garbachkova Jan 11 '22 at 10:49
  • @freedomn-m I understand that .data is cached, I'm looking for other solution – Doroteya Garbachkova Jan 11 '22 at 10:58
  • 1
    Your answer is here: [jquery data does not update](https://stackoverflow.com/questions/21588044/jquerys-data-attribute-does-not-update-when-element-data-changes) – freedomn-m Jan 11 '22 at 11:00
  • 1
    And why is [this answer](https://stackoverflow.com/a/43643202/6548154) not working for you? – A_A Jan 11 '22 at 11:03
  • @freedomn-m And `getAttribute()` and `attr()` require specific data attribute name, in my case I will have 10,15 or more data attributes with different names, and I want just length, but dinamically, so your link doesn't provide answer to my question. – Doroteya Garbachkova Jan 11 '22 at 11:04
  • _"but it's work with specific name of data attributes, I mean you should pass data-attribute name, I want length of all attributes"_ - well then you will have to loop over them and count yourself while doing so, I think - the `dataset` I mentioned is a `DOMStringMap `, and that does not appear to have a length or size property. https://stackoverflow.com/questions/14046481/looping-through-elements-data-attributes shows how you can loop over the contained attributes. – CBroe Jan 11 '22 at 11:05
  • @CBroe I think that you are the only one who understand the problem. I tried with dataset and it works, will you post it as answer, or to delete question? Please, those who downvote question for "minimal reproducible example", please, fix it, there is code snipper and question is clear enough already. Thanks! – Doroteya Garbachkova Jan 11 '22 at 11:17

1 Answers1

2

The data method only reads the values of custom data attributes on first invocation, as mentioned in the docs. So either add your additional data using the data method (then jQuery will handle storage internally), or, if you need them to be actual custom data attributes, use HTMLElement.dataset instead of jQuery's data method.

That is a DOMStringMap, which does not appear to have any length or size properties - so you will have to loop over all the entries, and count them while doing so. https://stackoverflow.com/a/43021996/1427878 shows how to loop over them with a simple for-in loop.

CBroe
  • 91,630
  • 14
  • 92
  • 150