Implementing dynamic ranking mechanism in Javascript - javascript

I have to implement this functionality as a part of a webapp I'm working on:
I have a file which contains entries in the form of
key1, val1, val2, val3, val3
key2, bval1, bval2, bval3
where key1 is a key to the values. Each val has a rank
that is the index in this array. e.g.val1 is rank 1, val2 is rank2
and so on.
Now, I want to a make a UI which will allow the user to
change the ranks of the values associated with a particular key
and finally write that changes out to the file.
Interacting with a database will be second part of the project
so would want to avoid that as of now.
Can all of this be accomplished just by javascript(or jQuery)
If yes, how do I model each value and provide up and down
arrows to allow the user to change the ranking. Can anyone
point to some resources(or plugins) that I can read and learn?
Any help would be greatly appreciated.

Although it binds your hands a bit visually, you might want to take a look at jQuery UI's Sortable and Dragable plugins. A demo is here. If you follow their documentation and examples, modeling this becomes trivial.
As for writing it out to a file, you may not need to do that (assuming you're talking about doing this on the server). As long as the list of values is not huge, you can use JSON.stringify to serialize your array/object and write it out persistently to a cookie.
Since you are writing out to a database, you may be specifically targeting Gears/Webkit/iOS browsers, in which case you may want to look into window.localStorage (it will eventually have full support in other browsers, but for now I think it can only safely be used in recent webkit browsers, including iPhone and iPad.)

Perhaps you can store the data with cookies.
But the "write changes out to a file" part... might not be possible (i don't think it's possible) with JUST javascript/jquery, you would need server-side assist from PHP,Python,Ruby,Perl etc...

Related

JS "upgrade" patterns

Are there any patterns for cases when something (in my case it's a filters) is stored on client (e.g. localStorage) and you need to run a script once per user/version to migrate data you store. For example, initially there is a filter saved in localStorage with a key myFilter after some time you decide that you need to separate filters per environment, so you need separate dev-myFilter, train-myFilter, etc. You update your code to work with environment-dependant filters, but there are users who have old myFilter and you want with next deployed version to run script which will update the key of saved filter if there is one.
Question is - what are patterns/best practices for that?
I don't know about "best practices", but the obvious technical solution, just like with any API or storage format, is to store a version number alongside the data. If you didn't do so from the start, assume version == 1 when absent.
You may be able to avoid this if the data structure is so unique between versions that the version can be determined simply by examining it.
Either way, you simply perform the translation whenever you spot that the user's data is in the old format.
The downside of this is that you have to keep checking; for a web application this is unlikely to be a bottleneck, but if you can make your data forward-compatible from the outset then you may save a bit of processing time on each request. But for the data to be useful you've got to read it anyway, so a little branching for as long as you wish to maintain backward-compatibility is, again, unlikely to be a big problem.

"Null" HTML DOM Element?

I'm writing a framework which uses javascript/html as the client and it-doesn't-matter as the back end.
From time to time I have a need to store data in the HTML DOM. Ideally I'd like to store the data against a DOM element, but I want this element to have no UI impact.
At the moment I'm thinking I'll use a <span> with no text content and decorate it with attribution so that my framework can pick up that it is a data container and behave appropriately.
Is there a better choice? (For the avoidance of doubt, I know there are other ways I could do things - I'm not interested in these, purely in what the best HTML element to use to contain data without having a UI impact).
Edit (explanation of architecture):
I've created a server-side technology which is based on top of a generic reporting engine I've previously created. This server-side thing essentially works as a web-server - this might seem like an unusual choice to make but, given organisational constraints, it's the best choice - for the sake of argument, assume this is true. One of the things I need this system to do is to generate dynamic forms to capture data which is in a tree-like form. This has been fine and has worked well - my question is because when a sub-form is hidden (for example, the user has made all required decisions in a given sub-section of the data), I destroy the data capture elements - if the form is embedded within a parent form which needs access to the data captured in a destroyed sub-form, I need a way of embedding the data into the DOM so it can be collected to be passed back to the server. The requirements are a lot more complicated that this, but it'll take far too long to detail them all.
Well (and for the avoidance of doubt), the HTML elements are not supposed to store data. If you really want to, use the <input type="hidden"> element.
For your purpose, I recommend (in that order) using localstorage or cookie or web database.
here are some resources :
localstorage : http://diveintohtml5.info/storage.html
cookie : http://www.the-art-of-web.com/javascript/setcookie/
web database : http://www.tutorialspoint.com/html5/html5_web_sql.htm
As JLRishe pointed out, if you need, for whatever reason, a text node storage, then span is a good choice as div is (and as lot of elements are as long as you display: none them).
You could just create javascript objects...
var myData ={
property1:"aaaaa",
property2:500,
property3:{morestuff1:"AAA", ... },
property3:["list1", "list2", ... ],
....
}
Easy to access and easy to manipulte within the DOM if you need.
No UI impact.... (no render)
The obvious choice here is to use HTML data attribute. If you have a table and want to store info about the table that is not shown to the user - you could just:
<table id="mytable" data-id="2000" data-rows="20" data-whatever="whatever">
You could then get it with jQuery easely with:
$("#mytable").data('rows');
Which would give you 20.
It's not good practice to store data in the DOM, if you're not actually using it for the purpose of layout. Yikes!
To better suit your needs, HTML5 provides a JavaScript API for handling client side storage. Depending on your circumstances, you have 2 options to choose from. The APIs are exactly the same, the only difference is the lifetime of the storage.
They are:
localStorage: Local storage is persistent; data stored in local storage is even available to the webpage after the user closes the browser completely and reopens it.
sessionStorage: As the name says, this data is only available for the current session.
Here's a link that will help you better understand these APIs so you can solve your particular problem: http://www.w3schools.com/html/html5_webstorage.asp

Server-side ruby vs client-side js api speed/organization

Say I have certain string attributes of an AR object, 'filename' and 'title' for instance, and the way I wish to dynamically fill in a select box on the front end is to ajax in the JSON representation of this object and either display the title attr as the select option's text if it exists, or use the filename attr as the select option's text if the title attr is blank. Now, should I be doing the this-else-that logic I just described on the server-side and returning it w/in my object's JSON representation as something like a 'display_name' attr, or should I be returning the vanilla as_json representation of the object w/ only the AR attrs included and let the js make the decision whether to display the title attr or the filename attr as the select option's text? From what I can tell, JS is much faster than ruby, but at the same time, it seems more maintainable to have this logic on the server-side. I'd also like to know, in general, is executing logic faster on the client side w/ js, or on the server-side w/ ruby? Thanks!
You really shouldn't have to worry about speed too much here - it's highly unlikely that you are really going to suffer from performance problems caused by if/else statements unless you're doing something wrong.
Instead, go for clarity and simplicity. In this case, that probably means rendering the pages on the server directly, unless the data is already in JSON for some reason.
My recommendation is to put logic where it belongs. If the logic is about presentation/rendering, then I would put it in your presentation layer. From your description, this seems to be your client-side JS.
I recommend you keep your APIs agnostic of how their data is rendered/presented as much as possible. This will allow you to change your views without having to also change the structure of the payload returned by the APIs.
In my experience, presentation layers tend to change more often than the underlying structure of the data they present.
I agree with the previous answer, I wouldn't worry about speed here, and go for clear separation of concerns.

Data structure visualizer for javascript

I am looking for a javascript library which renders an arbitrary (but acyclic) JSON data blob into some sort of semi-interactive HTML view. James Padolsey's Prettyprint library comes close, but its output is very verbose ("object" and "array" headers on everything, for instance), is only marginally interactive (the ability to collapse and expand subtrees would be nice, especially) and not particularly customizable. I also found jstree, but it looks like that doesn't do arbitrary JSON data blobs, only ones specifically constructed to be fed to it. Also, a strict treeview is not really right for the data I have; I want more of a key/value presentation (but with some values being nested objects).
I do not need the ability to modify the data structure, just show it in a more-or-less human readable fashion.
Any suggestions?
I have a small project to display jsobjects.
Its not very pretty and could use some improvements but it might help out a little.
It is built on "jquery-1.4.2.min.js" but should work with older versions.
Files:
http://empirium.dnet.nu/js/object-browser.js
http://empirium.dnet.nu/js/object-browser.css
This is an example on how to use it:
http://empirium.dnet.nu/OBTest.html
Clicking on the bold black type will open and close complex datastructures that are not visible imediatly.
I hope you have some use for it and if you have any suggestions please just comment here.
Its not an active project, just something I wrote to do some debugging.

Optimal way to pass system values to javascript

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.
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.
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.
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.
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 %>
};
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:
linktext
Unobtrusiveness is a very difficult thing in JS and i'd be eager to know something about that, too.
hope that helped.

Categories