Reputation: 10070
I'm working on a web application that uses ajax to communicate to the server. My specific situation is the following:
I have a list of users lined out in the html page. On each of these users i can do the following: change their 'status' or 'remove' them from the account.
What's a good practice for storing information in the page about the following:
P.S.: I'm using jQuery.
Upvotes: 10
Views: 18150
Reputation: 34426
jQuery Data
If you want to store custom data against a jQuery object, use the data function.
$('#myField').data('name', 'Jack');
var name = $('#myField').data('name');
HTML5 data-* Attributes
You can also use the HTML5 data-*
attributes, though the APIs for accessing these are only partially supported by the different browsers. Here's some more information about that.
<div data-userid="123" class="user-row">
programmatically:
$('#myElement').attr('data-fruit', 'apple');
// or
document.getElementById('myElement').dataset.fruit = 'apple';
Hidden Fields
If you want to do things the old browser-compatible way and stuff the metadata directly into your html, you can use hidden fields. It's a bit cruder but easy enough to do.
<input type="hidden" name="UserID" value="[userid]" />
You can easily use jQuery selectors to query your list and find html blocks that contain user items that have the relevant hidden fields that match the metadata you are querying for.
Upvotes: 5
Reputation: 488714
There is a lot of debate as to what is best to use. You can store the data a lot of ways, and they all make someone happy - custom attributes will of course not validate if you use XHTML, and using classes to store one or two bits of data is clumsy at best and only gets worse with the amount of things you want to know. Personally, not only am I not a big fan of XHTML, I am also not much of a validation nazi, so I recommend going with the custom attributes.
There is, however, an option that reconciles custom attributes with standards: data-
attributes. As John Resig (the author of jQuery) writes about in his blog, this is a new attribute being introduced in HTML5 that allows you to specify custom data attributes with the data-
prefix. So a perfectly valid element might look like this:
<ul>
<li data-userid='5' data-status='active'>Paolo Bergantino</li>
</ul>
This has the upside that while you are still using custom attributes which may be bad if you are using XHTML, your code is going to age very well as this is the way that we will be storing data related to a particular item in the future.
Some further reading is Attributes > Classes: Custom DOM Attributes for Fun and Profit.
Upvotes: 9
Reputation: 10844
The metadata plugin to jquery is your answer.
<html >
<head>
<script src="/js/jquery-1.3.2.js"></script>
<script src="/js/jquery.metadata.js"></script>
</head>
<body>
<ul>
<li type="text" class="{UID:'1',status:'alive'}">Adam</li>
<li type="text" class="{UID:'2',status:'alive'}">Bob</li>
<li type="text" class="{UID:'3',status:'alive'}">Carol</li>
</ul>
<script>
$('li').each(function(){window.console.log($(this).metadata().UID)});
</script>
</body>
</html>
Upvotes: 2
Reputation: 45731
In this case, I think custom attributes might be overkill. You can store the user-id in the id-attribute, since there will only be one instance of the user in the list, right? Also, the status of the user could be stored in the class-attribute. In this way, each user could be given different styling in CSS, such as green for active, yellow for a non-activated account, and red for a suspended account.
The code for fetching the status will, however, be a little more complex compared to using a custom attribute (But only if you also want to have multiple classes). On a more positive note, the HTML will validate with this approach whereas it would not with custom attributes.
<ul id="userList">
<li id="uid123" class="active">UserName X</li>
<li id="uid456" class="suspended">Mr. Troll</li>
</ul>
/**
* Simple function for searching (strict) for a value in an array
* @param array arr The array to look in
* @param mixed val The value to look for in arr. Note that the value is looked for using strict comparison
* @return boolean true if val is found in arr, else false
*/
function searchArray(arr, val) {
for(var i = 0, len = arr.length; i < len; i++) {
if(arr[i] === val) {
return true;
}
}
return false;
}
/**
* Gets a known status from a string of class names. Each class name should be separated
* by a space.
* @param string classNames The string to check for a known status
* @return string|false The status if found in classNames, else false
*/
function getStatus(classNames) {
// The different statuses a user can have. Change this into your own!
var statuses = ['active', 'suspended', 'inactive'],
nameArr = classNames.split(" ");
for(var i = 0, nameLen = nameArr.length; i < nameLen; i++) {
// If we find a valid status among the class names, return it
if(searchArray(statuses, nameArr[i])) {
return nameArr[i];
}
}
return false; // We didn't find any known status in classNames
}
var id = $("li").attr("id"); // Fetches the id for the first user
var status = getStatus($("li").attr("class")); // Fetches the status of the first user
Upvotes: 2
Reputation: 111127
To answer the question of "how to get it into the document in the first place", I suggest a layout similar to this:
<ul id="users">
<li id="someUserId" class="someStatus">Some Username</li>
<li id="someOtherUserId" class="someOtherStatus">Some Username</li>
</ul>
This allows you to easily select a lot of info about your users:
$('#users > li') // all user elements
$('.someStatus') // all users of a particular status
Then in your event handlers it's also easy to get the current status:
$(this).attr('class') //get current status once you have a user element selected.
Another alternative is to dump javascript to the page and simply have it use the jquery data
functionality to store the data as soon as the page loads. You'd still need an id on the element in order to find the right one though.
Upvotes: 1
Reputation: 36513
Perhaps using custom attributes, so for a user's list element, add attributes for the variables:
<li uid="theuserid" ustatus="thestatus"></li>
The values can then be got with the attr function:
$("li").attr("uid")
And
$("li").attr("ustatus")
Note: The selectors will need to be changed, obviously
Please note that there are differing opinions on the use of custom attributes - however, this should be fine for every major browser. It is also the least complex solution I can think of. It doesn't require jumping to sibling elements to get data, or finding elements nearby, which can all add a small amount of overhead to processing - I try to minimise the amount of extra bloat I add to the DOM when doing such things.
Upvotes: 6
Reputation: 509
There is jQuery's data function
$('li').data('userid',uid); // sets the value of userid
uid = $('li').data('userid'); // retrieves the value of userid
official documentation: http://docs.jquery.com/Data
Upvotes: 17
Reputation:
There are various ways of doing it depending on the kind of data you are storing and how much information you are storing in the page in general. It's best to devise a consistent scheme so you can write a simple library call to do the work. For example,
You can store data in the class of a particular element. This may require additional wrapper elements in order to be able to provide an additional class to drive your CSS. This also restricts the storable content format. User ID may well fit into a class attribute.
You can store data in an unused href of a Javascript activated link. This has the additional feature of showing the data in the status bar as part of the URL on rollover. For instance you can store '#userid' or even just 'userid' in the href.
You can store data in additional elements. For instance you can have a nested div with a class that indicates storage which also triggers CSS to take the element out of the display. This is the most general and extensive support you can probably arrange in page.
Rather than a nested div you could also use nested input tags with type="hidden". This is kind of more expected / traditional and doesn't require CSS to take them out of the display. You can use the id attribute to identify these inputs, or you can use the location on the page. For instance, put them inside the link that the user clicks and then just search inside the current link in the onclick handler.
Upvotes: 1