My first JavaScript attempt was to add some "fade to yellow". Spurred
on
by this success I am attempting a little Ajax. But I am not succeeding
this time.
I want to reduce a list of records to just one category determined by a
select box. The user chooses a category and bang the list is updated. I
am getting some data on the screen but it is not updating the DIV
properly. Interestingly, the data I see on the screen is not visible in
the HTML source (CTRL-U firefox).
In the main template there are 3 things going on:-
1) a select box with an onchange Ajax call
2) a render_partial for the body of the table
3) a DIV around 2)
<select name="location_filter_id" onchange="new
Ajax.Updater(''div_items'',
''/todos/todo_items/'' +
this.options[this.selectedIndex].value)">
<% @locations.each do |l| %>
<option value="<%= l.id %>">
<%= l.name %>
</option>
<% end %>
</select>
...
<table id="2">
<tr><th>column 1</th></tr>
<div id=''div_items''>
<%= render_partial ''partial_items'' %>
</div>
</table>
The Ajax will update the DIV "div_items" by calling action
"todo_items"
with the parameter chosen in the select. The action generates the HTML
for this DIV by rendering the *same* partial as is rendered in the main
template (DRY), but with a filter variable set.
Note - I have opted to do the filtering in the main HTML template. I
could have selected a new list in the action from the DB using the
select ID in a condition, however I am having difficulties getting that
to work across associations. I dont want to use find_by_sql.
So, the "todo_items" action puts the (select) ID into a variable named
@filter and then renders the partial called partial_items which
generates some HTML, that I assume is sent back to the Ajax call to be
magically inserted into the DIV.
def todo_items
@todos = Todo.find(:all,:order => "position ASC")
@locations = Category.find_all(["ckey = ?", "where"])
@mywhens = Category.find_all(["ckey = ?", "when"])
@todo = Todo.new
@todo.position = 0
@filter = @params[''id'']
if @params[''position''] != nil
@todo.position = @params[''position'']
end
render_partial ''partial_items''
end
The partial _partial_items.rhtml loops through the list records
filtering (if necessary) out as it goes:-
<% for todo in @todos %>
<% if @filter == 0 || todo.location.category.id.to_s == @filter %>
<td><%= todo.description %></td>
<% end %>
<% end %>
Well, it doesnt work, and I am stumped.
Peter
Hi ! Cutting Peter said the following on 2005-05-23 10:07:> <table id="2">This is not a valid ID. Start with a letter. Hope that helps, François
You weren''t too clear on what doesn''t work, so I assume
you''re
struggling with Ajax. After a quick read your code looks fine. Try
breaking down the problem into smaller chunks to see where the problem is::
o Try updating your DIV without Ajax from a simple button:
$(''div_items'').innerHTML = "Hello world!"
o Same as above but call it from your select
o Try having a dead-simple action that returns "Hello world". Try
to
call this with your ajax code; again, first from the simple button then
from your more complex select.
o Extend your Hello world action to return the incoming id; tie this
into your select onchange code.
If all the above works, then your action itself likely has the bug.
Let us know how it goes....
Cutting Peter wrote:
>My first JavaScript attempt was to add some "fade to yellow".
Spurred on
>by this success I am attempting a little Ajax. But I am not succeeding
>this time.
>I want to reduce a list of records to just one category determined by a
>select box. The user chooses a category and bang the list is updated. I
>am getting some data on the screen but it is not updating the DIV
>properly. Interestingly, the data I see on the screen is not visible in
>the HTML source (CTRL-U firefox).
>
>In the main template there are 3 things going on:-
>1) a select box with an onchange Ajax call
>2) a render_partial for the body of the table
>3) a DIV around 2)
>
><select name="location_filter_id" onchange="new
>Ajax.Updater(''div_items'',
''/todos/todo_items/'' +
>this.options[this.selectedIndex].value)">
> <% @locations.each do |l| %>
> <option value="<%= l.id %>">
> <%= l.name %>
> </option>
> <% end %>
></select>
>...
><table id="2">
> <tr><th>column 1</th></tr>
> <div id=''div_items''>
> <%= render_partial ''partial_items'' %>
> </div>
></table>
>
>The Ajax will update the DIV "div_items" by calling action
"todo_items"
>with the parameter chosen in the select. The action generates the HTML
>for this DIV by rendering the *same* partial as is rendered in the main
>template (DRY), but with a filter variable set.
>
>Note - I have opted to do the filtering in the main HTML template. I
>could have selected a new list in the action from the DB using the
>select ID in a condition, however I am having difficulties getting that
>to work across associations. I dont want to use find_by_sql.
>
>So, the "todo_items" action puts the (select) ID into a variable
named
>@filter and then renders the partial called partial_items which
>generates some HTML, that I assume is sent back to the Ajax call to be
>magically inserted into the DIV.
>
> def todo_items
> @todos = Todo.find(:all,:order => "position ASC")
> @locations = Category.find_all(["ckey = ?",
"where"])
> @mywhens = Category.find_all(["ckey = ?", "when"])
> @todo = Todo.new
> @todo.position = 0
> @filter = @params[''id'']
> if @params[''position''] != nil
> @todo.position = @params[''position'']
> end
> render_partial ''partial_items''
> end
>
>The partial _partial_items.rhtml loops through the list records
>filtering (if necessary) out as it goes:-
>
><% for todo in @todos %>
> <% if @filter == 0 || todo.location.category.id.to_s == @filter %>
> <td><%= todo.description %></td>
> <% end %>
><% end %>
>
>Well, it doesnt work, and I am stumped.
>Peter
>_______________________________________________
>Rails mailing list
>Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
>http://lists.rubyonrails.org/mailman/listinfo/rails
>
>
Francois''s suggestion to change the table id to begin with a letter
didn''t help.
I guessed the following test based on the David''s test suggestions. (I
have never seen .innerHTML before (HTML noob as well!))
<select name="location_filter_id"
onchange="$(''div_items'').innerHTML = ''Hello
world!''">
<% @locations.each do |l| %>
<option value="<%= l.id %>">
<%= l.name %>
</option>
<% end %>
</select>
It writes "hello world!" just below the select box - but does not
update
the DIV. This is similar to what I was seeing when I originally said
that the data from the Action appeared on the screen but it was not
updating the DIV properly.
It seems that the data generated by the select onchange clause is just
dumped directly after the select box and the DIV reference is ignored.
So it looks like the problem is probably not in the action - something
is not happening in the client.
I also understand now why I do not see the generated data in the HTML
source since it has been injected? *after* the page was loaded.
So why is the generated data not getting into the DIV? The DIV ids
match.
Peter