Reputation: 12197
I would like to ask for more an opinion than a question: What would the community recommend to do when you must do a webpage with lots of data, for example, a products listing, that should have some functionality like buy (adds to cart), sorting, etc. if you have to manipulate the data of the current product - price, title, image, link and other attributes? How you do it in your projects?
For example we have a page with dozens of products, each of them has attributes: price, title, description, image(URL), link(URL). How would you store the data to use it on some user interaction? Personally, I've done it by just inserting each of the attribute in tags, something like:
<div class="product" data-product_id="123">
<div class="pr_title">Title</div>
<div class="pr_body">Body</div>
<div class="pr_img"><img src="http://www.www.www/img.png"></div>
<div class="pr_link"><a href="http://www.stackoverflow.com/">Buy!</a></div>
</div>
This way I have my html structure for presentation and I worked with data in jQuery by something like:
var url = $('.product').find('.pr_link').find('a').attr('href');
But when the project got big and there were 10-15 more attributes added to each element, getting data from current product got pretty complicated and the code became mostly unreadable.
I thought of using same structure, but to keep data in some object like:
var products = {
1: {
title: "abc",
description: "lorem ipsum",
price: 25.19,
img: "http://www.www.www/img.png",
link: "http://www.stackoverflow.com"
}
}
and keep markup as simple as possible, only using elements and styles needed for design with css:
<div class="product" data-product_id="123">
<div class="title">Title</div>
<div>Body</div>
<img src="http://www.www.www/img.png">
<a href="http://www.stackoverflow.com/">Buy!</a>
</div>
so onClick
I would need to retrieve the id of the product and query it in our object "products":
var url = products[id].title;
While this is the most convenient way to work with it requires a new object.
Another idea was to keep all data in data-
attributes of the parent div element like:
<div class="product" data-product_id="123" data-title="abc" data-body="Body">
but for much as I know jQuery doesn't work with data attributes well (natively).
So what are your suggestions? Maybe you have some even better ideas to share.
P.S. I tried to find some information on the subject, but most likely failed to find the way to formulate it well so I found nothing about it. If there are links or even similar questions on stack exchange sites, please feel free to post them. Thank you in advance!
Upvotes: 14
Views: 3571
Reputation: 2296
I have to agree to Enes, you shouldnt embed your data into the jquery code or, as you already mentioned, your code will quickly become so complex as to be unsupportable. An MVC framework will help with this.
There are a couple mentioned in the answers above such as http://angularjs.com and http://backbonejs.org although i cant vouch for either of them but you should have a look to see if they help solve your problems.
I am currently rewriting a scrumwall application i originally developed in jquery and raw php into the agile toolkit. With agiletoolkit (aka atk4 on stackoverflow), you define models which map to the database tables, html templates and views which have placeholders where you want the data to go and pages where you add models, forms and grids. It provides the links between javascript and php and has features including ajax refreshes of views.
You could use html5 features but only the latest browsers will support this so you may have problems if the users are not in a controlled environment (e.g. a single company where there is a standard web browser).
Upvotes: 1
Reputation: 13461
You can use HTML5
data
attribute to store products data, as you have several properties of products to associate with each product block, you can JSON encode
the object and assign to the top element, and then can access that on user interaction on that element or any child element.
var product = {
title: "abc",
description: "lorem ipsum",
price: 25.19,
img: "http://www.www.www/img.png",
link: "http://www.stackoverflow.com"
};
$(selector).data('product',JSON.stringify(product));
then to retrieve the object you can do on any event's callback
$product = $.parseJSON($(elem).data('product'));
In fact both facebook
and twitter
used data attributes to store associated data with tweets
and stories
. For example here goes some html of a FB story
<li data-ft='{"qid":"5757245005920960301","mf_story_key":"7164261693049558180"}'
id="stream_story_4fe5d7d51bc415443080257">
You can see facebook is storing JSON encoded data into the data-ft
attribute.
Similarly an example of a Twitter tweet
html
<div data-tweet-id="216534496567230464" data-item-id="216534496567230464"
data-screen-name="onimitch" data-user-id="123682011" data-is-reply-to="">
So twitter is saving associated data for a tweet into different attributes like data-tweet-id
, data-user-id
.
So As they both handle's a lot amount of data, I think You can also use either of the method to save your data without any performance issue.
If you store data with individual keys then be aware of the automatic data conversion that .data()
does as @nnnnnn has already mentioned in comment.
Demo With .data() : http://jsfiddle.net/joycse06/vcFYj/
Demo With .attr() : http://jsfiddle.net/joycse06/vcFYj/1/
Upvotes: 5
Reputation: 7316
Although there are many excellent clientside mvc frameworks, check out Backbone.js, which is a powerful-but-easy-to-use framework for managing the interface between your data source (usually an http server), and your DOM. In short, it keeps "your truth out of the DOM"
As a contrived example, if you are creating a simple address book app, you would probably have a clientside Contact
Backbone model, which would roughly (or exactly) mirror the model you have on your server.
Backbone manages requesting and parsing the contact data (json, xml, etc) from the server (or localstorage, etc) into these Contact
model objects, and you provide a js callback to update your DOM when changes occur. This also works in reverse: Backbone updates the server when the model objects change, either instantly, after some delay, or when you explicitly call the save
function.
Backbone might not be the correct framework for you. But check them all out before you decide to roll your own solution. Even so, you could create your own clientside MVC layer, if you feel you:
Upvotes: 1
Reputation: 7590
You can use (as you already are) the data- attributes in HTML through jQuery. When you create the DIV from the server data, you can do something like this:
$('.product').data(yourProduct); // yourProduct would be the JSON representation of the data
To retrieve:
var url = $('product').data('product-link'); // if the JSON object has a product-link property that is.
The caveat someone mentioned above that your data is exposed to the browser is of course still valid, so take care.
Upvotes: 0
Reputation: 1720
The combination of DOM and jQuery is one of the most powerful things the Web has. You are not taking all of them.
Make the DOM help you and work for you. Organize better the DOM. Take all of it. Your example can be optimized this way:
<div class="product" data-product_id="123">
<div class="pr_title">Title</div>
<div class="pr_body">Body</div>
<img class="prodcut-image" src="http://www.www.www/img.png">
<a class="product-link" href="http://www.stackoverflow.com/">Buy!</a>
</div>
To select with jQuery, simple write:
var url = $('.product .product-link').attr('href');
I believe that your problem is that your are forgetting the way CSS selectors work. It's not necessary to transverse into every level of the DOM.
You can take off some DIV's in your example. A link not necessary have to be in-line. A CSS rule can make them work like a DIV.
Upvotes: 0
Reputation: 2817
I don't recommend you to keep your data in an object and fill HTML with it,
There are reasons for this:
I understand that your data is static for minimum about 5 min.. What I recommend is,
p.s. Any detail will help me to help you more.
Upvotes: 2
Reputation: 1514
You should try AngularJS. It works great with jQuery and it is easy to learn. AngularJS contains two way data binding and extends HTML by new attributes and elements. Last but not least it is MVC framework by Google. See more at http://www.angularjs.com
Upvotes: 1
Reputation: 687
No need to use ids or references within the DOM. Keep it clean.
Just use the data() function in jquery and bind it to the html elements. That way when you click on each element you will be able to get the object by calling this from within your click event.
//loop through your elements in the dom or build them dynamically.
$.each('div.products', function(){
$(this).data('product', <your data>);
};
//assign a handler to each element and grab the data object by using this. :)
$(container).delegate('.products', 'click' function(){
console.log($(this).data('product'))
});
Upvotes: 3
Reputation: 9847
You don't need to traverse the whole object tree. How about putting IDs:
<div class="pr_link" id='id_link_123'><a href="http://www.stackoverflow.com/">Buy!</a></div>
and retrive them as:
// ....
var id = 123;
// ....
var url = $("#id_title_" + id + " a").attr('href');
Upvotes: 1