Skip to content

Easy going JavaScript templates

September 14, 2010

Its a long time I miss publishing something interesting (ok, actually, publishing at all!) but this is for two good reasons:

one – I was really involved on Licorize development

two – I spent  one month on holidays in Iceland :-)

three – this is the kind of blog-post that may attract lots of spit

I’m little squeamish, and I tried to delay this moment as much as I can, but Licorize beta is now available and I’ve returned happy, alive and healthy from Iceland.

Damn! I cannot procrastinate any longer.

This history started about two years ago when I found the  John Resig  micro-templating paper; John’s idea was intriguing even if it seemed hardly original: separate presentation and data. This is an old liet motif for many programming-pattern-book-writers, and this is usually enough to worn me to shun away, but in this case something hit me, say because Resig seems a practical fella or say because the <script type=”text/html” > smells of “beautiful hack”. I don’t know  why, but micro-templating remains impressed on my mind.

What is  a  JavaScript template?  In brief it is a way to call a JavaScript  function for injecting dynamically html contents client side.

The simplest usage could look like this:

var data={id:1,description:”my item”,price:”123.45”};

var place= document.getElementById(“results”);
results.innerHTML = template(“item_row”, data);

For web 2.0 applications this is a really powerful approach to page generation: send templates to clients, use JSON for communicating with the server, generate contents using templates+data and create the fastest applications you have ever seen! If you add the great support jQuery offers for JSON, this could be a really nice solution.

I didn’t get deep into Resig’ solution at the time, but I kept the JavaScript templating idea in a closet for a while,  until last April when I started working on Licorize.

Licorize is an empowered bookmarking system that allows collecting to-dos, ideas, images and much more while you are working on-line, and then organize your work in team. But for the moment what is interesting is that Licorize uses small pieces of html to represent information on a sorted list. Here an example:

image

The main Licorize requirement was to be a fast web 2.0 application: to me this means use one page only.  I know that is not completely true, but coming from a “classical” background of Java-JSP developer, it was a revolutionary approach.

I then recalled the JavaScript templating idea, and started programming around.

A short googling on “javascript templating” left me astonished about the number of JavaScript  frameworks already available, so I started trying some of them.

Before you, dear reader, read more I warn that this is the hard core part, if you believe emacs is the best editor for writing web-apps or you think the XML-XSLT is the cleanest approach to produce html pages, leave before its too late! What you will see below is an approach that searches to maximize compatibility of writing code, also HTML, with an IDE.

Yes please, let me out!

Ok, so lets me state some of my personal principles concerning programming:

  1. a simple rough solution is far better than a powerful but complex one
  2. it is incredible stupid to invent new languages/tag/whatever while the existing ones work just fine
  3. your designer’s work worth as much as your “dirty code”
  4. you cannot nowadays write code without a decent IDE, or better: you cannot write decent code without a great IDE!  This is why I use IntelliJ!
  5. every trick is legal if it makes your life easier (not only writing code :-) )

Taking in mind these points I started exploring the JavaScript template galaxy.

Starting from Resig’s example I noticed that the suggested syntax generates confusion when you use a .jsp to generate the “template” page. JSP standard tags are also used for defining JavaScript variable placeholders:

Actually the following code, from Resig’s example,  generates panic in most JSP coders (Example 1):

<script type=”text/html” id=”user_tmpl”>
<% for ( var i = 0; i < users.length; i++ ) { %>
<li><a href=”<%=users[i].url%>”><%=users[i].name%></a></li>
<% } %>
</script>

here “users[i]” is a JavaScript variable not a JSP one!

If you think that generating templates using dynamic pages is useless you are on the wrong path, in good company with those that think that out.print(“<%=users[i].url%>”) could be an acceptable price to pay for using templating – no way!

Analyzing this example I found that is not strictly necessary to have iteration or conditional support in the template definition language: you can narrow the scope of templates and use JavaScript for doing iteration. With this approach you gain flexibility and you do not need strange syntax. See the code above transformed (Example 2):

<script type=”text/html” id=”user_tmpl”>
<li><a href=”<%=users.url%>”><%=users.name%></a></li>
</script>

<script type=”text/javascript”>

for ( var i = 0; i < users.length; i++ ) {
template(“user_tmpl”,users[i]);
}
</script>

The code is a little bit longer, but more readable and flexible (e.g.: if you need to use a different row template in function of user data).

What in Resig’ approach is in the right direction is that the template is mainly written in html, that means that templates can be created by UI guys, using (almost) standard html tags.

If you believe that this is the most obvious approach, and that everybody would start with this, you are wrong: there are lots of libraries where the template is created with “string concatenation”.

Seems peculiar to me that  library writers are mostly focused on implementing “for”, “if”, “while” statements inside templates instead of making it easy to write them down. Why they want to waste its time implementing (badly) something already happily existing in JavaScript?

In this category mustache.js , Tempest or nano, but the list is far from being exhaustive.

Some other libraries have the sensibility to propose a way to write html in a more comfortable way; usually they use the trick of “<script type=’text/…..’>” tag, as proposed by Resig or a in a mixed way with  “<![CDATA[“ tag

In this category there are  jQuery TemplatesjQuote, Srender.

A special place in my heart is the pure templating framework. It is at first glance a really clean solution, but going in detail this is a sort of exercise of sadism. Do not misunderstand me, I really appreciate the power of this library and the effort to use standard like css selectors, but are we sure that this stuff is a good thing for humanity?

image

By the way, the above code and (Example 2) produce almost the same result. Which one is more  readable? ;-)

As you can guess I left this framework as fast as I could moving to ones closer to html.

After the scary templating tour I got a clearer vision of my requirements:

  1. templates’ html MUST be writable in HTML not in JavaScript
  2. templates must work with the IDE, not against it
  3. in templates it should be possible to include a “<script>” tag
  4. templates should be generated dynamically server side

From now on, I will be using jQuery by default in the code.

In Open Lab developers work side by side with graphic designers, so the closer to html is the solution the easier is to interact with each other. Resig’s approach is in the right path, but look what happens inserting his kind of template in a .jsp page:

image

There is no way for the IDE to distinguish between template-language and jsp-language.

Another problem was the <script> tag used to identify the template that, on Chrome browser only, conflicts with standard <script type=”text/javascript”> tags.  Why I need a nested script tag in the template? I’m a little bit reluctant to tell you, but sometime I use old third party server-side components that produce some JavaScript code within the component itself. Bleah! (Still, I’m confident that most of you do just that…). And this would not be allowed.

After testing lots of different solutions, the best one  I found is to include  my template in a <div> with all the contents inside an HTML comment block. My solution has of course the limitation of forbidding the usage of html comments in templates, but it is an acceptable limitation for us.

Here is how it  looks like:

image

Regarding IDE compatibility, as you can see above, the html comment blocks code completion, syntax checking and hints. A little workaround solved the problem: I built a small java class to print the same template stub:

image

this solution preserve all IDEs capability as error highlighting, tag matching, JavaScript  checking, hints – and my happiness!

Seems peanuts, but this can speed up development a lot!

Here the simple class that wraps template tags:

image

In order to solve mixing jsp tags with templates, I decided to drop the use of  “<% %>” using instead the less disturbing “## ##”.

So a simple template example will look like:

image

The last blow dealt to “things well-done” was to remove any statement inside the template; so no “for”, “if”, “while” etc.

Maybe you can now argue that this leaves the template too poor and inexpressive, and actually it is true. This is why we added a callback function for “decorating” the resulting html. The decorator is generally not necessary and it is used only for really complicated and hyper-active templates.

We’ll now go in deep on our template solution analyzing each step:

Template definition

Write your template in a page (jsp or plain html) using the stub described above. In case you will use a .jsp page for carrying the template you can use the JST class methods to wrap the template transparently from the IDE point of view.

image

Here I created a div identified with “stripTemplates” to carry templates; in this example templates are inside my main page in order to minimize requests, but you can easily load templates in a subsequent ajax call.

Load templates in memory (the DOM)

Once the page is loaded you have to load templates in memory. You can have more then one template both in the same html block or in different ones.

A typical usage:

image

Once templates has been loaded, the container is removed. I tried to keep templates in the page and recall them from there, but it was less performant, so I opted to keep them on a JavaScript variable.

Have now a closer look to the loadTemplate() method:

image

we get all “.__template__”  elements and then the first comment child-element. We support multiple templates for each container. Then the template is loaded in memory end removed from the page.

If you want to load templates in a distinct ajax call something like

image

should work fine.

Getting data

This is the easiest part: usually you will call your server to obtain a JSON object or JSON array, obviously your data should be “compatible” with the template you are using.

For instance data compatible with templates above could be:

image

data can be with more properties than required, in this case extra data will be ignored, or with less data and in this case the “##..##” placeholder will be removed before template is rendered.

Rendering a template

Finally we can render the template and draw it somewhere on the page:

image

“createFromTemplate” will receive JavaScript data and return a jQuery object that you can handle for further refinements or just append somewhere.

Have a look to the rendering function:

image

code is quite straight: the template (string) is recalled from memory, then for each attribute in “jsonData” we replace “##attributeName##” with its value. Remaining “##…##” are then removed. A jQuery object is then created and returned.

Probably some of you noticed the “decorator” call before returning the object.

Decorators

As I told you before, we decided to remove statements inside template definitions, this does not mean that you never need some “logic rendering” for the template, I only oppose writing logic inside the template,  with some bizarre and original syntax! This is why we use a post-processing approach based on classical JavaScript callbacks.

You can define decorators in this way:

image

your decorator will receive the rendered template and the data, so you have lots of flexibility. Of course here we suppose the decorator is used for fine-tuning the final result not to twist the layout completely: we require layout to be clearly readable on the template itself. If you need a completely different structure depending on data received, simply use multiple templates; this is by far a better solution with respect to making templates excessively complex.

Decorators are the best place where to add event listeners and behaviors on your resulting component.

Conclusions

I know that this is a rough, non-conformist, maybe ugly approach and that this is not suitable for everyone, but it works really well in our group making happy both programmers and designers.

I think this was a great goal!  In only sixty lines of  code!

Love,

Roberto

P.S.: You can see templates at work here in Licorize.

P.P.S: You reader are probably the only one surviving up to this line, as a prize there is a complete code example here.

Ultra-light jQuery calendar

April 6, 2010

CalendarPicker: a new concept for date selection.

Read the component history.

Sometime I maintain my promises (rarely indeed :-) ), so I worked a little bit on CalendarPicker, receiving some suggestions from my previous post.

First of all thanks to everybody for precious feedbacks.

The hottest news in CalendarPicker is the usage  of mouse wheel to change dates; it is enabled on years, months and days bars.

I used the great mousewheel plugin by Brandon Aaron; just include the script for activate it.

Then I changed a little the CSS to enhance “today” with a yellow border.

image image

Another new feature is the ability of customizing the amount of  years/month/days displayed, so you can have bizarre configurations like these:

image image

Maxime Haineault argued that the next/prev buttons are no fashionable: now you can hide them!

Introducing the wheel movement I had to optimize calls, so callback function is invoked only when the user stops to play with the wheel.

I tried to maintain the code short (actually 180 rows), but the customization of years/months/days requires some computation for cell size; I first tried using only css properties in order to makes cells sharing space equally, but no luck. I need a css-expert’s hint!

You can see CalendarPicker at work here.

Feedback welcome!

So hard to have a date

March 23, 2010

An overview of 13+1  jQuery calendars, and a new ultra-light calendar picker.

When I was teenager (oh God, so many years ago!), my secret dream was to have a date with Elisa, curly hairs, blue eyes, tall, wonderful, curvy-classmate; actually this was the secret dream of every boy in my class. Unluckily  I looked younger, thinner, callow then others boys, so there was no chance of it coming true. So I decided to learn programming!

Today, I still need a date, well not the same kind of  “date”, a “date” in the sense of calendar ones, amazing how the years change your priorities!

Developing a new secret product (actually Licorize!) I needed to pick a date in order to roll-unroll the user log.

Using a third party component is a way to speed-up my development,  I narrowed my research to jQuery components; probably there are lots of calendar component for motools,  prototype, or stand alone ones, but jQuery is my choice, not going to change that!

I initially thought this was a simple quest: “of course there will be thousands of date pickers to choose…”

But nowadays is still hard to have a date, at least in a stylish way…

…  (if you want to see my component at work just go straight here ).

Here is the list of calendar components I’ve tried (before developing my own!).

Eyecon Date Picker

Firstly I came to Eyecon Date Picker. This is a really nice component. What I loved on this component is the flexibility for moving far in the past (or the future) with few clicks. imageimageimage

Clicking on the top row the component changes “scale” moving through years or months.

Date Picker  is released under MIT and GPL license, so it is usable also in commercial products (that actually is my case).

Date picker is fully skinnable, is quite light,  and really easy to use.

Basic usage is really straightforward:

$('#date').DatePicker({
	flat: true,
	date: '2008-07-31',
	current: '2008-07-31',
	calendars: 1,
	starts: 1
});

Another interesting feature is that it supports period selection:

image

and a cell renderer that can be used to highlight holidays, disable some days or whatever your application needs.

I was so happy to have found this component that I included it immediately on Licorize, before discovering a little spot that made me discard it: when you change scale by clicking on a month or on a year it closes the popup (when in popup mode). It is completely acceptable in mostly cases, but unluckily not in mine.

jQuery UI Datepicker

Then I tried the “standard” jQuery UI Datepicker, that is a really rock solid component. imageSupports keyboard navigation, internationalization, lots of options, events, and methods. It is skinnable with ui theme roller.

It is hard to find a component so well engineered.

It relies on an input field, this means it is intended mainly for  data insertion. It can be used as stand-alone calendar too.

Probably playing with the options you can steer Datepicker where you need.

The minimal usage is really “minimal”:

$("#datepicker").datepicker();
...
<input type="text" id="datepicker">

On the other hand,  mastering this component is not a joke with dozen of parameters. Even the weight is considerable (if you are interested in this single component only). This happens for every jQuery.ui component, either you accept it and embrace the whole platform or you extract a single part – it may be hard. This is why I didn’t adopt it.

Date Range Picker

An interesting extension of jQuery.ui date picker is Date Range Picker by Filament Group.

This manifests the quality of ui components. Seeing this component at work is quite impressive:

image

It supports preset ranges in menu (e.g.: “Office closed”), range clicking and other catching features. In one world power, but definitively not lightness!

jQuery Datepicker

Keith Wood  released jQuery Datepicker under both GPL and MIT license.

Great the demo/documentation site!

imageimagejQueri.ui datepicker is based on this component: the ui one has only less features… this should give you an idea about the power of this plugin.

Every kind of feature is supported, multi-languages, cell renderer, range selection, inline, years/months fast switching, cell disabling, date formats, multi events and much more.

The usage is simple, as simple as your requirements are.

Keith developed also the Date Entry plugin image a single input field with a pad for changing date fields.

jQuery date picker

Kelvin Luck gives us a strong jQuery date picker. It is unobtrusive and really well documented, lots of use cases are ready to be used.

image

It can be used both inline or as input field, in single or multiple views for period selection.

The basic usage is the standard one:

$('.date-pick').datePicker();

It supports internationalization and cell rendering.

Probably the look-and-feel is not at the top.

jCalendar

imageI have to cite the jCalendar by Ted Serbinsky:

This is an outdated component and how the author says “this project has been  superceded by the most excellent jQuery UI

So why didn’t I  believe in Ted and do the same thing? We’ll see that after all the reviews.

jQuery date-picker

image

Now is the turn of  Ted Devito with jQuery date-picker:

This is a quite rough (and even uncompleted) component, at least compared with previous jquery ones, but at least it has the gift of simplicity.

Usage is in jQuery style:

$(‘input’).simpleDatepicker();

jQuery Calendar Widget

Then I found jQuery Calendar Widget Plugin by Ei Sabai Nyo that is by far the most compact calendar I ever found: 99 lines of (unpacked :-) ) code!

image

Ok, probably it is not so powerful, but can be easily integrated and used in your applications; yours, not in mine!

Dyndatetime

Dyndatetime is an iron-looking date selector. Releases under GNU by thetoolman, it has a cold appearance, but is filled of interesting features. First of all it allows fast year switching by holding the fast back /forward buttons.

imageimage

Documentation is at least weak, well ok absent, but there is a test page with a couple of examples. It supports multiple languages, date formats, time formats (!)  and some small custom features. Easy to use and effective.

jCal

imageAnother nice example is jCal by Jim Palmer.

This is a multiday calendar date picker. The focus here is on date range selection, but this seems a nice piece of code.

It is released under MIT license.

jQuery Date Input

imageLast but not least is the jQuery Date Input by Jon Leighton, “no frills”, as the author says. “No frills” but a really mature component. Release under MIT license supports all main features like first day of week,  date formatting, css.

Stable and cool, is really pleasant to use.

But it is still not on my way.

… and now?

At this point you are probably asking what I’m looking for: well have you seen on these components a shine of innovation?

I want something more, more original, prettier, cool… not another grid, please!

Someone can argue there is no reason to innovate on calendars. A calendar is a calendar, full stop!

Well I’m usually reluctant to change user habits, but sometime I need fresh new air. Licorize, ops, my secret product, is full of new user interface techniques, so why not innovate moving in time?

The inspiration come to me looking at jQuery timepickr by Maxime Haineault:

image

This is a new way to select hours. It’s usage is practical and immediate. The author was brave in choosing to accept the practical limitation of 15 minutes steps, that could receive lots of user complaints, but this always happens when innovating.

And now, I’m proud to announce my new free-light-weight-jquery-date-picker…

(read about the new version here)

image

At last I decided to develop my own component. I called it CalendarPicker (try a demo here). Calendar picker is released it under MIT license.

Eureka! It looks different from all the others, supports multiple languages, and allows fast movement across months and years.

I know that this approach is not suitable for every context, but I hope someone else will find it useful.

The basic usage looks like:

$("#calendarFilterBox").calendarPicker();

Of course you will probably need to do something with the selected date ;-)

In this case the callback function will help you:

var dateSelector;
$(function(){
  dateSelector=$("#calendarFilterBox").calendarPicker({callback:function(cal){
    alert(cal.currentDate);
  }});
});

A function will allow to change the current date. For instance to set date to today:

dateSelector.changeDate(new Date());

A more comprehensive example with names customization looks like this:

$(function(){
  dateSelector=$("#calendarFilterBox").calendarPicker({
    monthNames:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "…more…],
    dayNames: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
    callback:function(cal){
       $("#mydate").html(cal.currentDate+"");
  }});
});

Your feedback will be deeply appreciated, as always.

An html sanitizer for C#

March 4, 2010

sanitizer After 3 months gestation and some bug fixes, HtmlSanitizer is reporting no hacking successes.

Does it mean that it rocks? I don’t think so, but it is probably strong enough to sail in stormy waters.

See my previous post to know how it works, but mainly test it online with the Patapage playground.

Being honest I received some complaints concerning the black list approach to CSS styles, but no one has hacked the current version (yet :-) ). In any case the code is open to changes, and I’m happy to receive your feedbacks.

Now we are proud to announce that there is a porting to C# by Beyers Cronje (thank you). You can find C# sources here (and Java ones here).  Warning: source code is already patched as suggested by Isaiah.

Other portings are welcome!

L’arte è pericolosa!

February 20, 2010

Chissà se Remo Salvadori, l’autore di “Continuo infinito presente”, aveva previsto una simile “evoluzione” per la sua opera.

Passando come ogni mattina tra il duomo e il battistero, finalmente pedonalizzato (almeno dopo le ore 9.30, prima di tale ora è una ridda di furgoni impazziti!), sono rimasto piacevolmente sorpreso nel trovare nel cuore del tempio del Rinascimento un’opera di arte contemporanea. Stentavo a crederci, mancava poco che cadessi dalla bicicletta per lo stupore, a Firenze!

L’opera di Salvadori cinge la colonna di San Zanobi con un intreccio di cavi in un continuum senza inizio ne fine. Bella, grigia sul lastricato lucido di pioggia invernale, un cerchio di materia “nuova” posato sul passato.

szanobi_aIl giorno dopo noto che qualcuno, magari avvezzo al Chianti, o qualche furgoncino impazzito ha urtato  l’opera spostandola.

Passa una settimana e ritrovo l’opera immersa in una bussola di cartelli stradali, uno per ogni punto cardinale. Sicuramente qualche solerte amministratore ha rilevato l’enorme pericolo che l’opera poneva al passo e preoccupato dalle terribili conseguenze di un turista rantolante ai piedi del battistero ha pensato bene di segnalarla come fosse una voragine aperta nel manto stradale.

Ma forse sono io che non ho capito l’opera. I cartelli sono il suo necessario complemento, rendono bene l’idea dei nostri tempi in cui la falsa idea della sicurezza ci rende ciechi alla realtà. “Alla maniera d’oggi”!

 

 

 

P.S.: Lunedì 22 Febbrario ore 8:20: l’opera non c’è più, ma i cartelli sono rimasti!

A delicious javascript tagging input field

February 10, 2010

A brief review of existing components and the presentation of the powerful “jquery.tagInput”

Once again, working on one of our new secret products (which is called Licorize :-) ), I was in need to select a third party component for speeding up development:  this time, a tagging field.

… before continue reading do you like to go straight to live demo?

I realized in seconds that I already had in mind a delicious solution. Delicious (.com) and its wonderful tagging system its really nearly what I wanted, probably even a little more…

What I really love in this component as seen on Delicious is the smoothness of user interaction. Let me explain the concept: try to write a tag directly from the input field and the drop down will show your already used tags, in order of frequency. Amazing, mainly it saves me scrolling the list: most used on top, golden rule. This is not different from what usually the other components do, but in this case the string searched is a little bit “boldified”. This is stylish!

image

Another nice feature of delicious’s tagging field is the integration with “recommended” and “popular”: not only by clicking the tag it is inserted/removed like every nerd-programmer will be able to imagine, but even while you are typing in the input field, the suggested tag is magically highlighted – this is a masterpiece!

Of course the interface behavior is supported by meaningful contents: suggested tags are computed on the base of the analysis of the url contents and mainly, I suppose,  on other users tagging criteria; having million of users makes the term “statistic” meaningful.

(BTW you can access this data using the Delicious api)

The only things I would change in this jewel is the tag separator from [space] to [comma]; this will give you the capability to add multiple word tags, even if it may induce the user in using the tag field as a sort of notes one. So the separator “flavor” may open a Pandora’s box: if ever in my life I’ll write a tag component – which I’ll try to avoid as much as possible.

Apart from the separator, I needed exactly this component, but unluckily it is entangled in Delicious’ js library, so I decided to have a look at available jQuery based components.

As usual this list does not pretend to be complete as I’m focused on developing products, not on writing reviews, but someone else could find my hints useful (I have already wrote some reviews on charting and grid components).

The top ranked one  is jQuery tag suggestion by Remy Sharp.

image

This nice component is very easy to use and is based on an array of suggested tags that can be supplied via a js array or via Ajax.

A basic axample:

$('input.tagSuggest').tagSuggest({  tags: ['javascript', 'js2', 'js', 'jquery']});

An Ajax example

$('#tags').tagSuggest({  url: '/tag-suggestion'});

Layout is configurable via css, and some parameters will help you in fine tuning this component.

Even if this is a nice component it is quite far from Delicious one, at least because it does not implement multiple tag collection: mine, suggested, popular. Another little limitation is that the suggested tag list is static, even if called through Ajax.

Another cool component is Tagger by Chris Iufer.

image

Here the focus is on maintaining  a tag list, instead of filling a field.

Usage is really simple:

<input class=”tagger” type=”text” name=”tags[]” />

<script type=”text/javascript”>

$(document).ready(function(){

// add to tagger element by index

$(‘.tagger’).eq(0).addTag(‘photo, design, creative’);

// add to a specific tagger element by Id

$(‘#places’).addTag(‘mountain view’);

$(‘#places’).addTag(‘chico’);

});

</script>

But this is even farther from my goal…

Even Pines Tags by Hunter Perrin goes in the wrong direction, at least compared with Delicious. It is focused mainly on writing / removing tags (like the previous one):

image

The documentation is little bit weak but usage is still easy:

$(“#tags”).ptags();

In the same flow is JTAG by Benoît Vidis

image

cute, but not my prefered one.

Another component that cought my attention was MagicTags by Dave Geddes.

image

Nice graphics, but here the core seems the transitions effects, making the usage of this component at bit annoying.

Nice look, but similar behavior for  TestBoxList by Guillermo Rauch.

image

That’s all folks!  I didn’t find other components, maybe the “tag” search key induces too much noise in search engines, but differently from usual there aren’t dozens of components, the choice is limited.

So I reached this sad conclusion:

I MUST WRITE MY OWN COMPONENT!

At least now my requirements are clear:

  1. supporting already used tag list, eventually filled with an Ajax call
  2. filtering results using user inputs
  3. supporting suggested tags, with “smart” selection
  4. supporting multiple separators
  5. supporting frequency
  6. having a nice-ligth-stylish look
  7. be delicious!

After a couple of days of programming this is the result:

image

typing on the text field a drop down will show your used tags:

image

I’ve set up a live demo on BugVoice site (new secret product is offline for the moment).

The usage is quite easy at least in the minimal configuration:

<link rel=stylesheet href="jquery.tagInput.css" type="text/css">
<script type="text/javascript" src="jquery.tagInput.js"></script>

insert your input field:

tags: <input type="text" size="80" id="tag" >

then instantiate the component:

<script type="text/javascript">
var myTags=[
  {tag:"js",freq:30},{tag:"jquery",freq:25},
  {tag:"pojo",freq:10},{tag:"agile",freq:4},
  {tag:"blog",freq:3},{tag:"canvas",freq:8},
  {tag:"dialog",freq:3},{tag:"excel",freq:4} ]   $("#tag").tagInput({ tags:myTags})
</script>

This is just a static case example; in case you have thousands of tags, you should use something like a Json Ajax call.

There are some configuration parameters, this is the complete list:

  1. tags: is a Json array of objects with “tag” and “freq” properties; freq is not mandatory if you do not use it for sorting. It is not mandatory if jsonUrl is specified.
  2. jsonUrl: will receive the text of current tag typed in the “search” parameter.
  3. autoFilter:  true/false  default=true when active shows only matching tags, “false” should be used for server-side filtering
  4. autoStart: true/false default=false when active the dropdown will appear straight on entering the field, otherwise only while typing
  5. sortBy: “frequency”|”tag”|”none”  default=”tag”. When sorting by frequency is on, the filler should report the “freq” property for each tag
  6. tagSeparator: default=”,” any separator char as space, comma, semicolon
  7. boldify: true/false default true “boldify” the matching part of tag in the dropdown box
  8. suggestedTags: callback function to retrieve an object array like ["sugestedtag1","sugestedtag2","suggestedtag3"].If this parameter is not present tag suggestion functionality will be kept hidden.
  9. suggestedTagsPlaceHolder: jQuery proxy for suggested tag placeholder. If it is not supplied it is created below the input field. When placeholder is supplied (hence unique), tagField should be applied on a single input.Something like  $(“#myTagFiled”).tagField(…) will work fine: $(“:text”).tagField(…) probably not!

so a more complex example will look like:

<link rel=stylesheet href="jquery.tagInput.css" type="text/css">
<script type="text/javascript" src="jquery.tagInput.js"></script> 

tags: <input type="text" size="80" id="tag" >
suggested tags: <span id="suggested" class="tagInputSuggestedTagList"></span> 

<script type="text/javascript">
  $(function(){
    $("#tag").tagInput({
      jsonUrl:"tags.jsp",
      sortBy:"frequency",
      suggestedTags:  ["jquery","tagging","tag","component"],
      tagSeparator:" ",
      autoFilter:false,
      autoStart:false,
      boldify:true,
      suggestedTagsPlaceHolder:$("#suggested")
    })
})
</script>

in this case the jsonUrl “tags.jsp” is a silly JSP page that will return 4 tags starting with the text typed by the user. Here the sample code:

<%@ page import="net.sf.json.JSONArray, net.sf.json.JSONObject" %><%
  JSONArray jsa= new JSONArray();
  String search=request.getParameter("search")
  search=null?"":search;
  for (int i=1;i<5;i++){
    JSONObject o= new JSONObject();
    o.element("tag",search+i);
    o.element("freq",i);
    jsa.add(o);
  }
  out.print(jsa.toString());
%>

This component is released under MIT license. Enjoy it!

Any feedback will be really appreciated.

JavaScript grid editor: I want to be Excel

January 30, 2010

A short list of my favorite JavaScript grid components.

How many times did you hear users asking you: “something simple, a grid like excel”?

When I was a VB programmer, oh yes, I have this dark spot on my career, and it is not the only one… this request threw me in panic. Usually what your “killer” is asking you is not what you, programmer, are thinking of (namely the power of cell functions, programmability, graph etc., that probably your “killer” does not even imagine): what they are thinking about is the editor flexibility, the ability to add columns, rows, move cells blocks, copy and paste from different sources.

After the ritual pointing-out that your application is NOT Excel, the VB solution was to adopt the standard flexGrid or the mythical TrueDbGrid that made happy both the killer-user and the victim-programmer.

But my VB era is long gone and nowadays I’m fighting with JavaScript and Java web applications; how to address the same old request of “something like Excel”?

I spent some days looking around for a solution. I warn you that this post does not pretend to be a complete list of available grid/table editors and that my investigation is mainly  “emotional”: I want to feel on a web-app the same prickle that I experience when using Excel.

Of course it is not only romantic surfing, I needed to edit data to fill the graph snipplet for Patapage, so there are some “nice to have” requirements: to be free of charge, light, based on jQuery, appealing. Server side aspects as pagination, sorting, CRUD etc. are for the moment not the crucial points as the amount of information I need to manage is limited and a totally client side solution would be acceptable.

Actually the implementations I found can be classified in three main groups:

  1. data driven: these are generally components with all the features needed for listing a large number for rows, with server-side pagination, scrolling, search and sort functionality; generally are lacking editing functionality, or when the feature is present is single row based, reflecting the fact that there is an underlying database. Data binding is made through XML or Json, depending the language supported server-side
  2. light edit: here the focus is given to the “editing agility”, every row is always in editing status,  search and sort are rarely available and in any case working on a limited set of rows isn’t a real limitation. Data is filled starting from a JS object, calling methods, or from an html table.  Some of these implementation supply callback methods that can be used to interact server side.
  3. spreadsheets: oh yes! there are also some really sophisticated JS clones of the glorious one! These are generally  complex solution (in terms of dependencies), supporting formulas, graphs and lot of functionalities. Here the focus is the “simulation effect”, data management and server side integration are really in background.

When I started my search I didn’t imagine that there were so many solutions, so I decided that it would be better here to limit the result to the ones based on jQuery. Lets go in depth :

Data Driven

One great example of this category is jqGrid by Tony Tomov. This is a really well engineered solution released under MIT and GPL licenses.

imageSupports pagination, search, sort and even edit. There are two specific versions for PHP and .NET that drastically reduce the server-side implementation effort. Loading data is supported in multiple ways through XML, JSON or JS arrays and examples are supplied for PHP and MySql. There is a third party Ruby example here.

It uses jQuery.UI components for display, so the look and feel is pretty.  Switching to edit mode is something perceivable, the user will see that the edit is active, but this is not necessarily bad in this class of components.

It supports sub-grids, multiple input types, master-detail, multi-selections and other useful features.
Column configuration is done in a declarative way using JS objects:

colNames:['Inv No','Date', 'Client', 'Amount'],
colModel:[ {
  name:'id',
  index:'id',
  width:55,
  editable:false,
  editoptions:{readonly:true,size:10}
},…

that gives you the flexibility you need for well tailored applications.

Seems a rock solid components, the behavior in resizing, scrolling, paging is really pleasant.

Documentation is not the strongest point but there are lots of examples that will help setting up your grid.

by Allan Jardine released under GPL v2 and BSD is a powerful data grid component.

image

Supports pagination, resizing, filtering, multi-column sorting, jQuery UI theme roller, and lots of interesting features.

Data feeding is provided a-la-carte, from DOM, Ajax XML or JSON sources, JS arrays… it’s your choice!

There is also the icing on the cake: cells and rows grouping, cell custom renderer, multi-row selection and much more.

Provides cell editing via jEditable cell-by-cell, not a row at once, and this in some cases could be a limitation; so you may need more that one update to change a row. Probably you can work around this trivia-point.

Configurations starts from zero-config in case of DOM feeding and can be refined to a real full-control using JS objects.

It is well-documented with a large set of examples and this is another plus!

A black spot (at least for me, Java programmer): server side examples in PHP only.

Another valid example is Flexgrid by

What I really appreciated in this component is the lightness and its simplest feeding example based on an html table. In this case  the whole setup consists of:

$(“#mytable”).flexigrid();

image

Of course this is a quite minimalist approach to this component that supports also XML and JSON data feeding.

Paging, sorting, resizing and other nice features like button injection are supported.

What is missing is the edit capability that is planned but still not released.

Similarly to the previous component the configuration (if needed ;-) ) is done by JS objects.

Documentation: we all are programmers, we hate to write it but we love to read it… so here too is really succinct with few examples for PHP server-side both XML and JSON.

tgrid by Mateusz Mikołajczyk is a lightweight datagrid, that supports all main features like sorting, paging, filtering.

image

I didn’t discover the license type so be careful on usage.

Data is fed by Ajax Json calls that make this component scalable enough.

Documentation supplied is “short” but with some examples, so setup is not a big deal.

This components supports a “row rough” edit, in the sense that it is not in-place, but out of the grid: it did not give me the right feeling. Taken out the edit, tgrid runs well.

Configuration does not offer many options; something nice is the cell custom renderer that allows you to format data.

Ingrid (great name!) is a less powerful grid component, but it is really unobtrusive and cute enough to be considered. Released under GPL license, it supports column resizing, sorting, paging etc.

image

Data is fed only by providing an html table, and this could find some criticism.

Google Chrome support has some little creeps on display.

Multiple row selection is a nice feature that earns some points to this component.

Editing is not supported.

In the same spirit of loveliness jTps by Jim Palmer is released under MIT license.

image

Paging, resizing, sorting are supported; a nice feature is smooth scrolling. Even in this case editing is not supported, but the real limit of this component is in term of scalability: data feeding does not support Ajax sub-sequential loading, so all data is loaded at once. Paging is only client side limiting the meaning of this feature.

Same category for dhtmlxGrid by DHTMLX.

imagedhtmlxGrid is a JavaScript grid component with editing capabilities, and server-side data binding. It is a powerful component with so much advanced features (such as filtering, searching, grouping, charts integration, math formulas, etc.) that it could be included in “Spreadsheet” group too :-)

dhtmlxGrid is distributed under GNU GPL v2, but also available under a commercial license.

It is built over a “dhtmlxcommon” js library instead of most famous jQuery or Prototye libraries, but this is not a big deal if you need such powerful component.

For the sake of completeness I have to cite TableEditor by Brice Burgess that seems a little bit outdated (even if really well indexed), and Snowcore’ jQuery Data Grid that is in Russian and this fact did not help me to understand how to use it; moreover the site icon noie let’s me suppose that IE testing is not a priority for Snowcore :-)

Light Edit

This category, as before stated,  is mainly focused on edit agility instead of server-side data management. This fact steers the implementation towards a all-client-side approach. Implementations in this category are generally a little bit rough with respect to the previous ones.

imageA  real interesting exception is the excellent SlickGrid by Michael Leibman released under MIT style license.

Here the author is particularly careful in rendering performance; he uses a virtual rendering technique to limit the number of DOM elements in order to make SlickGrid really scalable. The example provided with 50000 rows really run in a flash.

The author states in the “grid vs data” paragraph that here the focus is on the grid, not on the data. Despite his intentions, sorting, resizing, filtering, resizing and edit callbacks, give this grid a place even in in the previous category.

Data feed can be done via JS arrays, or via Ajax using the Slick.Data.RemoteModel object provided.

imageCustom cell renderer allows you to express your creativity, as shown explicitly in the examples when injecting a Sparkline graph in the last column (see my previous post for a excursus on charting components).

Rows multi-selection, ordering, and custom row rendering using John Resig’s micro-templates makes this component really flexible.

Configuration is done as usual using JS objects.

Having all this features and also having taken care of cell movements with the keyboard and easy editing is a great achievement!  Thanks Michael.

Once again Allan Jardine provides us a useful tool called keytable that injects Excel-like key movement on a generic table.

imageThis can have multiple usages as exemplified on demos available on the site. It easy to understand how a key-movement can change the user experience when it is used on a powerful grid component like DataTables (see above). Here the author’ example.

Another really basic example of editable table is supplied by Greg Weber with uiTableEdit: there are no examples online, so I built a simple test page, and the components just add the capability to change the cell value. No key movement or other additional features are handled; it can be used as starting point for further refinement.

imageSame kind of “roughness” for tEditable by Josh Hundley, where edit is click based, and key-movement is not supported. This do not mean that this tools is useless, just that it is really far from a complete solution.

It converts DOM cells to text-areas on the fly when editing, and this makes this component almost setup-free.

A part of this category (the rough part :-) ) is my contribution, used to fill data on PataPage’ charting playground.

image image

Here the functionality are really basic: key-movement, edit, load from url, add and remove only are supported. The grid content is “saved” on a text area with \t and \n separators: same format expected when loading from url. I’m working for supporting  the ^v (paste) capability to facilitate user data insertion as block of cells.

Spreadsheet

Actually this category comprises solution wider than previous ones, in the sense that a complete solution will probably include all the features listed before; this is on one side a plus, but on the other side if you are interested in extracting some parts (e.g. table edit but not on formulas, server-side integration but not on key-movement etc.), this could be a little difficult due to the complexity of the solutions available.

Light years beyond other solutions at least as first impression, jQuery.sheet by Robert Plummer is a really wonderful library. I didn’t find the license type.

image

Really looks like an Excel sheet and the key-movement seems realistic.

Data feeding is done using a DOM table, eventually Ajax-loaded, or by adding row and cols programmatically.

The grid supports resizing, but the real wondering feature is the cell-function support. Not limited to SUM, AVG and other standard functions, but also chart are allowed.

Lots of callback will help you to integrate the sheet on you application.

There are some little bugs on cell selection and some minor layout issue with Chrome, but the overall behavior is impressive.

The last, but definitively not least, example of websheet (a web spreadsheet) is the Googledocs one. It is a really good live-teaching example, and even if it is not a ready-to-use library I suggest you to open it and dissect it with, for instance, Firebug.

It is interesting to see how many tricks they used: the whole grid is one iframe, the rows are grouped in small tables of 20 rows (probably in order to scale on IE), the cell value is stored in the td dom; when you edit a cell a text area is printed over the cell (not inside), and so on.

I tried to implement my grid using the same structure, but after some hours I surrendered; the effort to “master” the layout was over my actual estimation, and I fell back to the solution discussed above.  Would be gorgeous to have a jQuery open-source implementation like this!

Google docs spreadsheet is the only application I found that gave me  the right prickle!

Well I stopped my searching here, and I didn’t explore Mootools, Sriptacolous, Ext and maverick ones in detail.

There is a booklet for this blog post here on licorize.com. (Licorize is one of my latest creations, please take a look)

I’ll just list here some other libraries I found:

Spreadsheet Dojo Widget image

image

Ext JS DataGrid

YUI 2 DataTableimage

Simple Spreadsheetimage

BlueShoes SpSpeadsheet editor image

TrimSpreadsheet image

Sigma Grid 2.2image

Follow

Get every new post delivered to your Inbox.