views:

133

answers:

4

I've been using JSON to handle AJAX functionality in my rails applications ever since I heard about it, because using RJS/rendering HTML "felt" wrong because it violated MVC. The first AJAX-heavy project I worked on ended up with 20-30 controller actions tied directly to specific UI-behaviors and my view code spread over controller actions, partials and rjs files. Using JSON allows you to keep view specific code in the view, and only talk to view agnostic/RESTful controller actions via AJAX to get needed data.

The one headache I've found from using pure JSON is that you have to 'render' HTML via JS, which in the case of AJAX that has to update DOM-heavy elements, can be a real pain. I end up with long string building code like

// ...ajax 
success: function(records){
  $(records).each(function(record){
    var html = ('<div id="blah">' + record.attr +
      etc +
    ')
  })
}

where etc is 10-15 lines of dynamically constructing HTML based on record data. Besides of the annoyance, a more serious draw back to this approach is the duplication of the HTML structure (in the template and in the JS).* Is there a better practice for this approach?

(My motivation for finally reaching out is I am now tasked with updating HTML so complex it required two nested loops of Ruby code to render in the first place. Duplicating that in Javascript seems insane.)

  • One thing I've considered is loading static partial files directly from the file system, but this seems a bit much.
+1  A: 

You could use the load function in jQuery; This loads the content of a page into a div like this:

$('#content').load("content/" + this.href.split('#')[1] + ".html", '', checkResponse);

Just make a dynamic view and you are good to go...

D4V360
I _could_, but that brings me back to the bad old days of having a specific action/partial for each AJAX update I want to do. For a RESTful fanatic, that is very painful. I'm hoping it's not the only pragmatic solution.
floyd
+1  A: 

I would go with creating an HTML structure that contains placeholders for the elements you'll need to update via AJAX. How much structure it applies will depend on what you're updating; if you know the number of elements you'll have ahead of time, it would be something to the effect of

<div id="article1">
    <div id="article1Headline"></div>
    <div id="article1Copy"></div>
    <div id="article1AuthorInfo"></div>
</div>
<div id="article2">
    <div id="article2Headline"></div>
    <div id="article2Copy"></div>
    <div id="article2AuthorInfo"></div>
</div>

You then write code that references the id of each element directly, and inserts into the .innerHTML property (or whatever syntactically more sugary way jquery has of doing same thing). IMHO, it's not really so terrible to have to assign the contents of each element, the part that you don't want to have to sprinkle through your AJAX functions is the HTML structure itself; in your app the content is volatile anyway.

However, it looks like you might have a list of an unknown number of elements, in that case it may be that you'd need to just put in a placeholder:

<div id="articleList"></div>

In that case I don't really see a way to avoid building the HTML structure in the javascript calls, but a reasonable amount of decomposition of your javascript should help that:

function addArticle( headline, copy, authorInfo, i ){
    createDiv( "article" + i + "Headline", headline );
    createDiv( "article" + i + "Copy", copy);
    createDiv( "article" + i + "AuthorInfo", authorInfo );
}

(not working code of course, but you get the idea,)

Paul
Yeah, I'm already using placeholders where-ever possible. The more common-sense suggestion of decomposing the function themselves is helpful. Actually, I like that code so much it seems like a potential jQuery plugin...and indeed: http://blogs.microsoft.co.il/blogs/basil/archive/2008/08/21/jquery-create-jquery-plug-in-to-create-elements.aspx
floyd
+2  A: 

I like the idea of templating. In my experience it can really clean up that messy string manipulation!

There are many solutions, for example, check out John Resig's (creator of jQuery):

http://ejohn.org/blog/javascript-micro-templating/

Ben
awesome link, thanks
floyd
A: 

Just happened to find exactly what I was looking for: Jaml

floyd
This is still somewhat messy and you have to sort of include layout in your Javascript. I really like John Resig's templating in one of the other answers which very clearly (mostly) separates UI and controller. Great if Jaml works for you though :)
Jaanus