1

In code I do this:

var markerName = $(fileInput).closest('tr.file-input-row').find('input[type="text"]')[0].value.replace(/[^a-z0-9]/gi, '-');
$.data(fileInput, 'for', markerName);

in this case, markerName is "file-1"

If I check using:

$('input[type="file"][data-for="file-1"]')

I get an object with length equal to 0... so not found.

However, if I do:

$('input[type="file"]:first').data().for

in this case, the first input[type="file"] is the same input I set the data attribute for, I get:

"file-1"

...as expected.

It looks like it is being set, but it is then not accessible.

Any thoughts why?

TIA

Phil
  • 157,677
  • 23
  • 242
  • 245
Paul Allsopp
  • 622
  • 1
  • 9
  • 23
  • BTW: I use data attributes all the time, and this is the first time I have had this issue – Paul Allsopp Aug 03 '17 at 00:04
  • 1
    How is the element added to the page? What is the HTML? – epascarello Aug 03 '17 at 00:06
  • 1
    `$.data(fileInput, 'for', markerName);` does not add an attribute – epascarello Aug 03 '17 at 00:09
  • 1
    @Phil OP is not asking about the difference between `.data()` and `.attr()` – guest271314 Aug 03 '17 at 00:12
  • Whoever marked this as duplicate, while I agree the linked answer can answer this, I don't agree the question is a duplicate of that one. This question implies the user did not know there was a difference. – Corvus Crypto Aug 03 '17 at 00:13
  • @guest271314 I know that, but the answer can be found in the other post. The *duplicate* vote does not mean the questions are the same; it means the answer may be found in an existing post – Phil Aug 03 '17 at 00:13
  • @Phil OP is expecting object returned by call to `jQuery()` to contain either `jQuery.data()` or `.data()` properties. Which Answer at linked Question addresses that inquiry? – guest271314 Aug 03 '17 at 00:14
  • No, OP is expecting `$.data` to assign a DOM attribute which could be used in a selector which it does not (as explained elsewhere) – Phil Aug 03 '17 at 00:15
  • @Phil Disagree with that assessment of the Question. Where does OP expect a `DOM` attribute to be set? Or use any code which gets `DOM` attribute? OP only uses `jQuery.data()` and `jQuery()` at code at Question – guest271314 Aug 03 '17 at 00:16
  • @Phil I agree with guest271314. This expectation warrants an explanation that there is a difference whereas that linked question you marked as duplicate requires them to already expect there is a difference in behavior regarding DOM modification to link these together. Just an opinion though. – Corvus Crypto Aug 03 '17 at 00:18
  • @CrazyMerlin `jQuery()` function does not return object properties or values set at `jQuery.data()` or `.data()` – guest271314 Aug 03 '17 at 00:18
  • @CorvusCrypto OP does not specifically ask about `DOM` or attributes. OP appears to expect `jQuery()` call, that is `$()` to return an object including the `$.data()` and, or `.data()` object previously set. Have not previously viewed that specific inquiry at SO – guest271314 Aug 03 '17 at 00:20
  • @guest271314 I'm not sure how this could be clearer. OP calls `$.data(fileInput, 'for', 'file-1')` then is wondering why `$('input[type="file"][data-for="file-1"]')` does not match. It does not match because `$.data()` does not set a `data-for` attribute. The reasons for this are explained in the other question – Phil Aug 03 '17 at 00:24
  • @Phil Object returned by `jQuery()` does not include `$.data()` or `.data()` objects, which are different methods from each other themselves. `jQuery.data()` does not appear as being discussed at linked Question. – guest271314 Aug 03 '17 at 00:29
  • @guest271314 I still don't know where you're getting this from. I think perhaps you're reading the question incorrectly – Phil Aug 03 '17 at 00:30
  • 1
    @guest271314 I originally was setting the data attribute using $(element).data('for', 'xyz'), and it was not working. That is why I switched to using a data store. I did not understand though that setting the element in the datastore did not add an attribute, although now I feel silly because it obviously would not – Paul Allsopp Aug 03 '17 at 00:32
  • @CrazyMerlin What are you trying to accomplish? Set an attribute at HTML? – guest271314 Aug 03 '17 at 00:40
  • @guest271314 I hope this demonstrates the problem ~ https://jsfiddle.net/5b0g3nkm/. This really comes down to a misunderstanding about what `$.data()` (and similarly `.data()`) does which is why this question was best answered by the duplicate (though the accepted answer below is adequate). Quite simply, OP was expecting `$.data` to change the element's attributes – Phil Aug 03 '17 at 00:48
  • @guest271314 I have a form that has a row containing a text input and a file input. A user can click a button and add as many rows as they need, and then hit submit. The form is posted via ajax. Any files that cannot be stored need to have a message returned, and the corresponding input flagged as error. To do this, I am using the text input value as a reference (it has to be unique) – Paul Allsopp Aug 03 '17 at 00:48
  • @CrazyMerlin How is the requirement that you are describing related to original Question? – guest271314 Aug 03 '17 at 00:50
  • @guest271314 In the original question, markerName denotes the input from the user as to what they want the file stored as, so I wanted to store that name as a data attribute on the related file input. I could have approached it many different ways, as it is new front-end code, but I cannot change the PHP response without a LOT of code-rewrite. This is an application that is being completely overhauled, but day-to-day fixes still need to be applied – Paul Allsopp Aug 03 '17 at 00:56
  • 1
    data attributes seemed like a better choice than searching for the text input with a given value – Paul Allsopp Aug 03 '17 at 00:58

2 Answers2

2

This is not working because you aren't updating the DOM object when you perform the data-for adjustment in the first part of your code. To update the DOM object you should use attr(key, value).

For more info on the differences between data and attr there is a good answer related to this: jQuery Data vs Attr?

Corvus Crypto
  • 2,141
  • 1
  • 13
  • 14
-1

If I check using:

$('input[type="file"][data-for="file-1"]')

Neither .data() nor jQuery.data() is part of the object returned by jQuery() : $() call.

guest271314
  • 1
  • 15
  • 104
  • 177
  • I would certainly expect [`.data()`](https://api.jquery.com/data/) to be available on any object returned from a `jQuery()` call, even one matching zero element; it's part of the API – Phil Aug 03 '17 at 00:28
  • @Phil Not as part of the object returned by `jQuery()`, though chaining `.data()` to the `jQuery()` call would retrieve `.data()` attached to the `jQuery()` object. OP uses `jQuery.data()`, which cannot be chained to `jQuery()` call. From perspective here, OP was expecting to view either the `$.data()` set as part of the returned `jQuery()` object, which is a reasonable expectation, though not the case, at least not without adjusting jQuery source or writing code which would achieve that. – guest271314 Aug 03 '17 at 00:31
  • 1
    OP is only using `$.data` to [*"store arbitrary data associated with the specified element"*](https://api.jquery.com/jquery.data/). There's no chaining or anything else. I think you should definitely read the question again (and OP's recent comments) – Phil Aug 03 '17 at 00:35
  • @Phil You are probably correct. Re-read OP and found "attribute". Amazing, no HTML appears at Question, though inquiry appears to be about setting an attribute at HTML. OP can omit `jQuery()` from pattern altogether and use `HTMLElement.dataset`, to avoid confusion. – guest271314 Aug 03 '17 at 00:39
  • 1
    I was attempting to "find" a specific input. While using HTMLElement.dataset would of course be possible, it is more cumbersome, because jQuery has already done all the boilerplate – Paul Allsopp Aug 03 '17 at 00:51
  • I did not see the issue as being a HTML-specific issue, because I was both setting and retrieving the data via jQuery – Paul Allsopp Aug 03 '17 at 00:52
  • How would using `HTMLElement.dataset` be "cumbersome"? – guest271314 Aug 03 '17 at 00:52
  • Because of browser differences, and having to write different code for the main browsers + any version anomalies. jQuery has taken care of that – Paul Allsopp Aug 03 '17 at 14:24
  • All in all, the confusion lies in what jQuery has termed .attr() and .data(). I say this because if you add a data attribute to an element, you can access it using the .data() method. But you cannot add a data attribute using the .data() method. – Paul Allsopp Aug 03 '17 at 14:30
  • @CrazyMerlin It depends on what requirement and expected result are. Each of the modern browsers support [`HTMLElement.dataset`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset#Browser_compatibility). You can utilize `HTMLElement.dataset` to store arbitrary data at the `DOM` element, which also sets the `data-*` attribute at HTML. You can also get and set, and iterate key, value pairs of `HTMLElement.dataset` using `Object` and `JSON` methods. – guest271314 Aug 04 '17 at 01:11