Topic: Need help thinking about AJAX...

I'm working on my first application that really requires ajax, and I need to get a prototype done quickly to start testing on if its even going to work on the mobile devices it'll be access from.

I think I need each ajax request to generate two changes on the screen, and I'm a little unsure how to approach that.  The rough setup is that the view has three areas
1.  Abbreviated Descriptive Content -- this won't change
2.  Progress indicator (1/24, changing to 2/24 ... upto 24/24)
3.  An table of "something" initiating the action -- for now we're trying to just use standard links.  Each link is labelled with an identifier number, like '100', '101', etc.  Clicking on the link should toggle the background color and increment/decrement the progress indicator.

I beleive I know enough to make either 2 or 3 happen, but not how to make both happen.  Can anyone offer some advice over how to due multiple page changes in one ajax action?

Thanks

My RoR journey  -- thoughts on learning RoR and lessons learned in applying TDD and agile practices.

Re: Need help thinking about AJAX...

RJS is definitely the answer. It makes changing multiple areas of a page through AJAX a breeze. Were you planning on storing the current progress in a variable in JavaScript then updating that? Or in a session? Or maybe the progress is marked by something else already...

Here's an extremely generic example if it helps though:

page.replace_html :foo, "The content of the HTML element with id='foo' will be replaced with this string"
page.replace_html :bar, :partial => 'some_partial' # works just like rendering partials but updates that element

Last edited by ryanb (2006-09-28 11:26:35)

Railscasts - Free Ruby on Rails Screencasts

Re: Need help thinking about AJAX...

This is another one of those "its really that easy" moments.... Thanks...

My RoR journey  -- thoughts on learning RoR and lessons learned in applying TDD and agile practices.

Re: Need help thinking about AJAX...

Hmm I'm not quite there... I got the views refactored to the a nice set of partials and got them hooked up to the rjs template.  However I can't seem to figure out how to get link_to_remote to work.

I'm using:

  <%= link_to_remote "#{mark_cell.couple.competitor_identifier}", :url=>{:action=>:rjs_mark, :couple_id=>mark_cell.id, 
                                                   :round_atomic_dance_id=>@rad.id,
                                                   :judge_id=>@judge.id} -%>

When I click the link, nothing happens -- should I see a request in the server log?

A sample line from View source

<div id="c-100" class="not-marked">
  <a href="#" onclick="new Ajax.Request('/mark_entry/rjs_mark?judge_id=1&amp;couple_id=1&amp;round_atomic_dance_id=1', {asynchronous:true, evalScripts:true}); return false;">100</a></div>

I have no clue about what the onclick should look like, but I could believe this is correct.

The action (currently very messy) is

  def rjs_mark
    @rad = RoundAtomicDance.find(params[:round_atomic_dance_id])
    @judge = Judge.find(params[:judge_id])
    couple = Couple.find(params[:couple_id])
    if @rad.marked?(@judge, couple)
      CallbackMark.find_by_couple_id_and_judge_id_and_round_atomic_dance_id(couple.id,@judge.id,@rad.id).destroy
    else
      CallbackMark.create(:judge_id=>@judge.id,
                          :couple_id=>couple.id,
                          :round_atomic_dance_id=>@rad.id)
    end
    @couple = CompetingCouple.find_by_couple_id_and_event_round_id(couple.id,@rad.event_round.id)
    @round=@rad.event_round
  end

and the template
page.replace_html "c-#{@couple.id}", :partial=>'mark_cell', :locals=>{:mark_cell=>@couple}
page.replace_html :progress, :partial=>'progress'

Both partials work when not used in the rjs.

My RoR journey  -- thoughts on learning RoR and lessons learned in applying TDD and agile practices.

Re: Need help thinking about AJAX...

NielsenE wrote:

When I click the link, nothing happens -- should I see a request in the server log?

Yep, it should send a request. Have you included the javascript files?

<head>
  ...
  <%= javascript_include_tag :defaults %>
</head>

Railscasts - Free Ruby on Rails Screencasts

Re: Need help thinking about AJAX...

Yeah, I was missing that.

Now only one of the two actions works.  (The second one).  The first one doesn't generate any change in the page.  However if I reload the page it ends up in the correct state.  There's no error message in development.log, server.log nor in FireFox's JavaScript Console (I had some error message before when I was trying to update a non-existant element.)

Where else should I be looking to debug rjs actions?

My RoR journey  -- thoughts on learning RoR and lessons learned in applying TDD and agile practices.

Re: Need help thinking about AJAX...

Try FireBug if you haven't already. It shows you the javascript returned from the request. Usually you can tell the problem from that.

Alternatively you can go to the url itself that generates the javascript and see the same thing (usually).

If you don't see the problem, paste the returned javascript here and maybe we can see something.

Railscasts - Free Ruby on Rails Screencasts

Re: Need help thinking about AJAX...

Yeah I went to the direct url to examine the returned javascript and its definitely a little off.

[code=js]try {
Element.update("progress", "<div id=\"progress\">1/6</div>\n");
Element.update("c104", "<div id=\"c104\" class=\"not-marked\">\n  <a href=\"#\" onclick=\"new Ajax.Request('/mark_entry/rjs_mark?judge_id=1&amp;couple_id=5&amp;round_atomic_dance_id=1', {asynchronous:true, evalScripts:true}); return false;\">104</a></div>\n");
} catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.update(\"progress\", \"<div id=\\"progress\\">1/6</div>\n\");\nElement.update(\"c104\", \"<div id=\\"c104\\" class=\\"not-marked\\">\n  <a href=\\"#\\" onclick=\\"new Ajax.Request(\'/mark_entry/rjs_mark?judge_id=1&amp;couple_id=5&amp;round_atomic_dance_id=1\', {asynchronous:true, evalScripts:true}); return false;\\">104</a></div>\n\");'); throw e }[/code]
I've tried flipping the order of the two lines in the rjs and the behavoir isn't any different.  In both cases the progress bar counter works, while the link div doesn't get updated.  All that should happen is that the class on the div should flip from "not-marked" to "marked" (or vice versa).  This would appear to indicate that the partial is rendering incorrectly; however the partial renders fine when call through on the "master" page (loops through the partial with the collection of links).  The fact that the progress counter increments/decrements as needed shows that the database is getting hit correctly.

My RoR journey  -- thoughts on learning RoR and lessons learned in applying TDD and agile practices.

Re: Need help thinking about AJAX...

Is the variable the partial uses to set the marked/not-marked class set in the AJAX action? Perhaps it is only set in the "master" action? You can post the AJAX action and the partial here if you want.

Also, if all you're doing is changing the class of the element, you can try one of these in the RJS file:

page << "$('c104').className = 'marked';" # this should work
page['c104'].className = 'marked' # this might work too
page['c104'].class_name = 'marked' # or maybe this

I would test it, but I'm too lazy. wink

Railscasts - Free Ruby on Rails Screencasts