views:

71

answers:

5

What is the most effective way to pass object and category ids or other system variables which shouldn't be presented to the user, from server to the browser?

Let's say I have a list of items where I can do something with each of them by javascript, for example show tooltip html or add to favorites by ajax, or display on a map. Where is it best to save that tooltip html, or database id, or geoposition?

Some options I can think of are:

  • some dictionary within <script></script> tag for each item,
  • microformats,
  • inline xml,
  • rel attributes,
  • css class names with specific information, e.g. class="lat-12345 uid-45678",
  • one <script></script> with a dictionary of html ids mapping dictionaries with system values in the template,
  • javascript generated from the database and included via <script src="..."></script> with a dictionary of html ids mapping dictionaries with system values in the template,
  • ajax requests for all cases when I need more information than just id,
  • event handlers with parameters within html tags, e.g. onmouseover="tooltip(this, 123, 'Hello world!')".

P.S. I prefer unobtrusive solutions and also the loading/execution time is important.

A: 

ASP.NET offers a very convenient way to do this. You can simply write a JavaScript object. I am sure other templating engines offer similar ways to do this.

var person = {
    Name : <%= _person.Name %>,
    Age : <%= _person.Age %>
};
ChaosPandion
+1  A: 

I'd prefer a single AJAX call to fetch whatever data you know you need at the outset, so you can have a simple JSON object available in your script. You can, of course, supplement that with additional calls should you find you need more information.

If that's impractical, then "hardcoding" a JavaScript object in a <script>...</script> tag is the next best option. Of course, "hardcoding" is from the browser's perspective. The actual content would surely be written by server-side script from your database.

VoteyDisciple
+1  A: 

Perhaps I am missing something... why not just JSON?

How you "send" it (either in the initial page load as "javascript" or via AJAX or whatnot) is really just a trivial detail determined mostly by when the data is available. (JSON is a subset of legal JavaScript syntax.)

Then it's just a matter of the correct transformation. Of course, by pushing this to JSON/JS, you may render some non-JS clients non-interoperable, if that's a consideration for you. If such is indeed the case, why not just perform the transformation server-side using well, any number of the techniques you put at top?

You can also use arbitrary attributes in HTML (the HTML5 spec may include "data-*" which is formally legalized) -- while not technically "correct", all major web-browsers will accept unknown attributes which can be accessed through the DOM API.

pst
+1  A: 

One method you can use is custom attributes. I think you refer to this as micro-formats, but I am not entirely sure if they are the same thing so I have written a description below.

Having hit the same question before, I basically use something like the following:

<div data-pid="1234">
    <a href="#" class="add-to-favourites">
        <img src="addToFavourites.png" />
    </a>
</div>

$("a.add-to-favourites").click(function() {
    $.load("/Favourites/Add.php?prodID="+$(this).parent().attr("data-pid"));
});

This should do exactly what you want to do. The reason I have put the pid in the div, not the a tag, is that you can then place all the other product information within the div with other actions the user can take, for example displaying a tooltip on mouseover using data-description, or displaying on a map using data-geo-x and data-geo-y. Of course you can name these anything you want.

Support / Acceptance

This is becoming a perfectly accepted way to do what you want to do. HTML 5 supports this for precisely the kind of thing you are trying to achieve.

So it is supported by HTML 5, but what about HTML 4?

It may make HTML 4 invalid, but the world is moving on to bigger and better things. Older browsers (IE6 and before, FF1 / 2, Opera 7 / 8 / 9) are becoming less common so it shouldnt be a problem. It wont actually break older browsers - the functionality will still work.

Important validity note

Make sure you prepend the data- onto the attribute name. This will make the attribute perfectly valid in HTML 5.

A few extra hints

In jQuery 1.5, I have heard from an answer to my question that you can simply specify attr("pid") to return the value of data-pid. If this is the case then I would be careful when naming the second part of the attribute name after the name of an actual attribute (for example, instead of data-id, use data-pid - especially if the id attribute is specified. I am not sure what effect it would have if you didn't do this, but its better to avoid the problem in the first place than have issues with the site at a later date due to this.

Hope this is what you were looking for.

ClarkeyBoy
Microformats like hCard and hCalender define all specific data within spans with specific classes. Others like vCard and iCalender define specific data in a specific text format in a separate file referenced by link or anchor. See http://microformats.org/
Aidas Bendoraitis
A: 

I would implement a Javascript singleton AppCacheManager that initializes in the document.ready event. A bit JS oop and you have a fully fledged OOP datastore.

Whenever information is needed, you load it through Ajax / RESTful Webservice and cache it in the AppCache Manager. So you have 2 caches: 1. Browser Cache, possible due to RESTful webservice URL caching, and 2: the JS Cache Manager.

You access all requests to the AppCacheManager which transparently fetches the new data or returns the cached data, so that the client doesnt need to know anything of the caching.

in short:

  • write a JS CacheManager
  • don't fetch the whole data at once but in small parts when needed and cache them
  • define a convenient interface for the cachemanager

Example usage:

<a href="linkurl" onmouseover="CacheManagerFactory.getInstance().getTooltip('TooltipID');">linktext</a>

Unobtrusiveness is a very difficult thing in JS and i'd be eager to know something about that, too.

hope that helped.

ovm
So basically you would pass the system variables (e.g. tooltip id) via inline event handlers (e.g. `onmouseover`). In my opinion it creates too much noise in the markup structure and adds up to the bandwidth.Unobtrusive Javascript is not difficult at all. It just means that you traverse through the DOM and add event handlers on document load instead of defining them in the markup. If you use some Javascript framework like jquery, then it's even easier.
Aidas Bendoraitis
I guess JS CacheManager might be a good solution for some specific project with lots of non-changing data which should be optionally shown quite often for the same visitor. But my question is more generic.
Aidas Bendoraitis