10

My code have data attribute set for many elements (Not For All Elements) in below manner.

  1. <div id='dvStorage' data-testing='storage_div'>

And, for some of the elements (Not For All Elements) data attribute is set with below approach.

  1. $("#ElementID").data("testing", "data value");

Now, the problem comes. When any button on the document is clicked, I need to find its parent having data attribute (testing) is set. As mentioned, all elements do not have data attribute, so I need to travese upwards in the hierarchy until the expected element is found.

For #1 approach, $("#buttonID").closest("[data-testing]") works. But not for #2 approach.

For #2 approach, I need to iterate through button parents() and verify if it has .data("testing") or not. I need to avoid this iteration. And have one common approach that works for #1 and #2.

Here, it is not required to verify value of data-testing, but to get the first parent in hierarchy having "testing" set as its data attribute.

Thanks in advance.

JSFIDDLE Demo

DevD
  • 155
  • 1
  • 1
  • 9

6 Answers6

11

You only have two choices:

As you mentioned in the first choice, you have to iterate through all of the elements because $("#ElementID").data("testing", "data value"); will NOT update the attribute data-testing, because the value is stored internally in the DOM.

The second method is to provide add another class that can be used in the selector:

$("#ElementID").data("testing", "data value").addClass("has-testing");

Thus your new selector would be:

$("#buttonID").closest("[data-testing], .has-testing");

JS Fiddle Example

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
2

try this (work for #2): data-selector

e.g: $('[data-testing] , :data(testing)')
Rohit Suthar
  • 3,528
  • 1
  • 42
  • 48
MJ Vakili
  • 2,798
  • 1
  • 19
  • 25
0

Try this:

$(this).parents("[data-testing]:first");

where $(this) will be the current clicked element inside the click handler.

K K
  • 17,794
  • 4
  • 30
  • 39
0

Try this: $("#buttonID").closest(["data-testing"]) just change to following:

$("#buttonID").closest("[data-testing]");

or use $(this).parents("[data-testing]") for your choice

2nd demo

Ahosan Karim Asik
  • 3,219
  • 1
  • 18
  • 27
0

You can try below solution:

$("body *[data-testing]:first");

for your reference: http://jsfiddle.net/on24Lzxj/

Stack Overflow User
  • 4,052
  • 6
  • 29
  • 47
0

Instead of setting data-testing through .data(), you can use attr():

$("#div1").attr("data-testing", "div1_Data");

This will add the attribute and value to the element.

Then your normal selector should work:

$("#buttonID").closest("[data-testing]")

Edit based on comments:

Settings attributes using .attr() and getting them using .data() can be problematic (as evident by Eriks fiddle-example here), since the latter only checks the actual element attribute once.

I would suggest to use .attr() when both setting and getting, but since the implementation could not be changed this is not an option in this case.

I'll leave my answer here anyway, as I would still recommend it if this was not the case.

Mackan
  • 6,200
  • 2
  • 25
  • 45
  • Thanks Mackan. But, the question was with .data() only, and i could not change the implementation. – DevD Apr 10 '15 at 06:35
  • This also will be hit or miss. `.data()` reads are cached after the first read, so any `attr()` update after the first won't be read by `.data()`. [JsFiddle Example](http://jsfiddle.net/bckq2uv1/) – Erik Philips Apr 10 '15 at 15:55
  • @ErikPhilips You're adding attr oddly in your example. You never added `data-`, or am I misunderstanding? Uodated example: http://jsfiddle.net/bckq2uv1/1/ – Mackan Apr 10 '15 at 16:37
  • 1
    @Mackan nice catch! Yes my example is incorrect. But you'll notice how the `.data()` does not return the expected *larry* on the second read :) – Erik Philips Apr 10 '15 at 16:39
  • @ErikPhilips yes - I was on my phone last time so I didn't have a very good overview. It is indeed odd behaviour (according to me), but then again I would just use `attr()` straight through. `data()` seems a bit .. touchy :) – Mackan Apr 10 '15 at 18:31