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