Accessing data attribute using jquery returns undefined?
Asked Answered
M

3

16

Inside my view i have a button as follow:

<button data-assigned-id="@IdUser" onclick="updateClick()" type="button" class="btn btn-sm btn-default"></button>

My div

<div id="partial_load_div">

</div>

Script

function updateClick() {
    var id = $(this).data('assigned-id');
    $('#partial_load_div').show();
    $('#partial_load_div').load('/Users/UpdatePartial?id=' + id);
}

The id is always shows as undefined, i checked and @IdUser has always value

then in chrome dev i got the error

GET http://localhost:19058/Users/UpdatePartial?id=undefined 400 (Bad Request)

Any idea how to fix this?

Marandamarasca answered 6/4, 2016 at 12:29 Comment(2)
Delete onclick="updateClick()" and add a class name or id for use a a selector and then $('#mybutton').click( function) { var id = $(this).data('assigned-id'); ....Deryl
@StephenMuecke thanks for your comment, that works fine! could you add your comment into an answer so that i can mark it?Marandamarasca
D
12

In your current script, $(this) refers to the Window object (not your button) which does not have a data- attribute so its undefined.

You could solve this by passing the element to the function

<button data-assigned-id="@IdUser" onclick="updateClick(this)" type="button" ... ></button>
function updateClick(element) {
    var id = $(element).data('assigned-id');
    ....

However a better approach is to use Unobtrusive Javascript rather than polluting your markup with behavior.

<button data-assigned-id="@IdUser" id="mybutton" type="button" class="btn btn-sm btn-default"></button>
$('#mybutton').click(function() {
    var id = $(this).data('assigned-id'); // $(this) refers to the button
    ....
});
Deryl answered 6/4, 2016 at 23:57 Comment(6)
Any idea how to fix Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience when i apply this script?Marandamarasca
That error wont happen because of the code in my answer. My best guess is that your .load() is loading a partial view that has script tag in it (if so, remove it - partials should never have scripts)Deryl
I have the follwoing scripts in my partial <script src="~/Scripts/jquery.validate.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.js"></script> and <script src="~/Scripts/jquery.validate.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.js"></script> i think those are important for validation since my partial view is a formMarandamarasca
You definitely need to remove those from your partial. Move them into the main view (or layout)Deryl
and my validation will still work? ok will give it a try thanks a lotMarandamarasca
And because you dynamically loading content that contains a form that you want to validate, you need to reparse the validator in the success callback of the .load() event. Refer this answerDeryl
B
18

When reading data attributes using data() you need to remove the - and camel case the value. So you want:

var id = $(this).data('assignedId');

the docs on data() show this:

As of jQuery 1.4.3 HTML 5 data- attributes will be automatically pulled in to jQuery's data object. The treatment of attributes with embedded dashes was changed in jQuery 1.6 to conform to the W3C HTML5 specification.

For example, given the following HTML:

<div data-role="page" data-last-value="43" data-hidden="true" data-options='{"name":"John"}'></div>

All of the following jQuery code will work.

$( "div" ).data( "role" ) === "page";
$( "div" ).data( "lastValue" ) === 43;
$( "div" ).data( "hidden" ) === true;
$( "div" ).data( "options" ).name === "John";

The second statement of the code above correctly refers to the data-last-value attribute of the element. In case no data is stored with the passed key, jQuery searches among the attributes of the element, converting a camel-cased string into a dashed string and then prepending data- to the result. So, the string lastValue is converted to data-last-value.


I didn't notice how your binding the click event. If you want to use $(this) you have to bind the event using jquery. So you need:

<button data-assigned-id="works" id="button">
clickme</button>

$(window).ready(function() {
     //bind the event using jquery not the onclick attribute of the button
     $('#button').on('click', updateClick);

});


function updateClick() {
    alert($(this).data('assignedId'));
}

Working fiddle

Butterfly answered 6/4, 2016 at 12:32 Comment(3)
thanks for taking the time answering my question! I'm still getting the same error. i don't know why doesn't workMarandamarasca
I didn't notice another issue you had @Maro. See updateButterfly
They just strip the dashes and store the keys in all-lowercase. You have to use a case-insensitive lookup in order to get anything that you actually camel-cased in your HTML. Worst specification ever, but thanks for pointing it out, I never would have guessed.Joon
D
12

In your current script, $(this) refers to the Window object (not your button) which does not have a data- attribute so its undefined.

You could solve this by passing the element to the function

<button data-assigned-id="@IdUser" onclick="updateClick(this)" type="button" ... ></button>
function updateClick(element) {
    var id = $(element).data('assigned-id');
    ....

However a better approach is to use Unobtrusive Javascript rather than polluting your markup with behavior.

<button data-assigned-id="@IdUser" id="mybutton" type="button" class="btn btn-sm btn-default"></button>
$('#mybutton').click(function() {
    var id = $(this).data('assigned-id'); // $(this) refers to the button
    ....
});
Deryl answered 6/4, 2016 at 23:57 Comment(6)
Any idea how to fix Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience when i apply this script?Marandamarasca
That error wont happen because of the code in my answer. My best guess is that your .load() is loading a partial view that has script tag in it (if so, remove it - partials should never have scripts)Deryl
I have the follwoing scripts in my partial <script src="~/Scripts/jquery.validate.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.js"></script> and <script src="~/Scripts/jquery.validate.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.js"></script> i think those are important for validation since my partial view is a formMarandamarasca
You definitely need to remove those from your partial. Move them into the main view (or layout)Deryl
and my validation will still work? ok will give it a try thanks a lotMarandamarasca
And because you dynamically loading content that contains a form that you want to validate, you need to reparse the validator in the success callback of the .load() event. Refer this answerDeryl
H
3

As far as my usage was concerned, even though the attribute was data-assignedId (Camel cased), when retrieving it you would have to use data('assignedid'). Using camel casing returned undefined.

Holleyholli answered 30/4, 2021 at 10:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.