froadie
froadie

Reputation: 83063

JQuery selector by data attribute when data is added dynamically?

I have a ul with several items. I populate the list dynamically after page load using jquery. As I add each list item, I also add an "itemID" to the data of that element using the jquery ".data()" function. Something like this:

var item = $('<li>My Item Name</li>');
item.data('itemID', '123ABC456');

Later, I need a selector to determine if there is any item in my item list with a specific itemID. First I tried using:

$('*[data-itemID="123ABC456"]');

This didn't work - and on further research, I discovered that this syntax only works if the data attribute was set in the DOM when the page was loaded; it doesn't work if you use the ".data" jquery method dynamically.

Next I tried:

$(':data(itemID==123ABC456)');

For some reason, this doesn't work. If I run simply $(':data(itemID)'), however, then I do get all the li elements that have an itemID in their data.

I know that the itemID attribute is set correctly, as when I call .data() on that list item I get:

Object { itemID="123ABC456"}

How can I select all elements that have an itemID of "123ABC456" in their data?

Upvotes: 13

Views: 11253

Answers (4)

Sergey Beloglazov
Sergey Beloglazov

Reputation: 170

If you need to find the first occurrence and return its data, you can use a simple "for" loop:

function find(id) {
  let liList = $('li');
  // Use "for" loop instead of .each() for breaking the loop and returning the desired data
  for (let i = 0; i < liList.length; i++) {
    if ($(liList[i]).data('itemID') === id) {
      // Return the founded element
      return $(liList[i]);
    }
  }
  return null;
}

//Fill the list
let item = $('<li>Item #1</li>');
item.data('itemID', '1'); // Set ID=1
$('ul').append(item);
item = $('<li>Item #2</li>');
item.data('itemID', '5'); // Set ID=5
$('ul').append(item);
item = $('<li>Item #3</li>');
item.data('itemID', '10'); //Set ID=10
$('ul').append(item);

//Try to find an existing element
let item5=find('5');
document.write('Found item "'+item5.text()+'" has ID='+'5'+'<br>'); // Will show "Item #2"

//Try to find an element that doesn't exist
let item2=find('2');
document.write('Found item is "'+item2+'" when searching ID='+'2'+'<br>'); //null will be here
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<ul></ul>

Upvotes: 0

Ethan Doh
Ethan Doh

Reputation: 520

Instead of

$(item).data('itemID', '123ABC456')

use

$(item).attr('data-itemID', '123ABC456')

Then you can use

$('[data-itemID=123ABC456]') 

as a selector

Upvotes: 9

Barmar
Barmar

Reputation: 781141

How about putting the itemID in the DOM:

var item = $('<li itemID="'+itemid+">My Item Name</li>');

Upvotes: 0

Mark Pieszak - Trilon.io
Mark Pieszak - Trilon.io

Reputation: 67001

http://jsfiddle.net/w28p9/1/ <-- jsFiddle example showing differences with data-attribute & jquery.data()

jQuery.data() is different than HTML5 data-NAME attributes which you are trying to search for.

http://api.jquery.com/jQuery.data/

jQuery.data() saves inside of the jquery element (this data is hidden from plain sight). Looking for [data-itemID] would work if inside of the actual had: <li data-itemID="12345"></li>.

To retrieve and look for the actual hidden .data() try:

// of course be more specific than just searching through all <li>'s
$('li').each(function () {
    if ( $(this).data('itemID') === '123ABC456' ) {
        // do whatever you wanted to do with it
    } 
});

Hope that helps!

Upvotes: 12

Related Questions