Hi I have a form where the user is able to add additional rows to a table containing text inputs for specifying one or more orders (see below). I''m wondering if this is something I could use Ajax for, i.e. to get rid of the table row formatting within the javascript. I''ve seen the form_remote_tag allows me to serialize a form and perhaps update it with a new value, but its not so clear how to support two submits, one for adding new rows to the table, and another for submitting the form. Or is this something that could also be achieved using link_to_remote ? Any ideas ? --- <html> <head> <title>Table Prototype</title> <script> var buys = 1; function add() { var table = document.getElementById(''buys''); var lastRow = table.rows.length; var row = table.insertRow(lastRow); var c1 = row.insertCell(0); var i1 = document.createElement(''input''); i1.setAttribute(''type'', ''text''); i1.setAttribute(''name'', ''buy'' + (buys + 1) + ''[symbol]''); i1.setAttribute(''size'', ''5''); c1.appendChild(i1); var c2 = row.insertCell(1); var i2 = document.createElement(''input''); i2.setAttribute(''type'', ''text''); i2.setAttribute(''name'', ''buy'' + (buys + 1) + ''[quantity]''); i2.setAttribute(''size'', ''5''); c2.appendChild(i2); var c3 = row.insertCell(2); var i3 = document.createElement(''input''); i3.setAttribute(''type'', ''text''); i3.setAttribute(''name'', ''buy'' + (buys + 1) + ''[price]''); i3.setAttribute(''size'', ''5''); c3.appendChild(i3); } </script> </head> <body> <%= start_form_tag :action => ''create'' %> Trades <p> <table id="buys"> <tr> <td>Stock</td> <td>Quanty</td> <td>Price</td> </tr> <tr> <td><input type="text" name="buy1[symbol]" value="" size="5"></td> <td><input type="text" name="buy1[quantity]" value="" size="5"></td> <td><input type="text" name="buy1[price]" value="" size="5"></td> </tr> </table> </p> <p> (+) <a href="#" onclick="add();">Add Buy</a> </p> <%= submit_tag "Save" %> <%= end_form_tag %> </body> </html>
I haven''t had a chance to experiment with Rails and its ajax support much, but I do know javascript and how the DOM works. I''m assuming you can define a partial that has your new table row and then using ajax, you can get that partial and insert it into your table with innerHTML Again, i''m not sure how the ajax stuff works in rails, but I do know how to do it myself manually using javascript. I''d just set the output of my xmlhttprequest call to be the partial html code and just insert it into my table. Hope someone who knows Rails better can elaborate on that for you. On 5/26/05, Erik Eide <erik.eide-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Hi > > I have a form where the user is able to add additional rows to a table > containing text inputs for specifying one or more orders (see below). > > I''m wondering if this is something I could use Ajax for, i.e. to get > rid of the table row formatting within the javascript. > > I''ve seen the form_remote_tag allows me to serialize a form and > perhaps update it with a new value, but its not so clear how to > support two submits, one for adding new rows to the table, and another > for submitting the form. > > Or is this something that could also be achieved using link_to_remote ? > > Any ideas ? > > --- > > <html> > <head> > <title>Table Prototype</title> > <script> > var buys = 1; > > function add() { > var table = document.getElementById(''buys''); > var lastRow = table.rows.length; > var row = table.insertRow(lastRow); > > var c1 = row.insertCell(0); > var i1 = document.createElement(''input''); > i1.setAttribute(''type'', ''text''); > i1.setAttribute(''name'', ''buy'' + (buys + 1) + ''[symbol]''); > i1.setAttribute(''size'', ''5''); > c1.appendChild(i1); > > var c2 = row.insertCell(1); > var i2 = document.createElement(''input''); > i2.setAttribute(''type'', ''text''); > i2.setAttribute(''name'', ''buy'' + (buys + 1) + ''[quantity]''); > i2.setAttribute(''size'', ''5''); > c2.appendChild(i2); > > var c3 = row.insertCell(2); > var i3 = document.createElement(''input''); > i3.setAttribute(''type'', ''text''); > i3.setAttribute(''name'', ''buy'' + (buys + 1) + ''[price]''); > i3.setAttribute(''size'', ''5''); > c3.appendChild(i3); > } > </script> > </head> > > <body> > <%= start_form_tag :action => ''create'' %> > > Trades > > <p> > <table id="buys"> > <tr> > <td>Stock</td> > <td>Quanty</td> > <td>Price</td> > </tr> > <tr> > <td><input type="text" name="buy1[symbol]" value="" size="5"></td> > <td><input type="text" name="buy1[quantity]" value="" size="5"></td> > <td><input type="text" name="buy1[price]" value="" size="5"></td> > </tr> > </table> > </p> > > <p> > (+) <a href="#" onclick="add();">Add Buy</a> > </p> > > <%= submit_tag "Save" %> > <%= end_form_tag %> > > </body> > </html> > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- - Ramin http://www.getintothis.com/blog _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Whatever method you use to add elements to a form, don''t do innerHTML = innerHTML + newelements because whenever you do that, the old elements get reset to their default value (unless browsers have gotten smarter since last time I tried that) If I had to do what you''re trying to do, I''d do it with js and the DOM, like you''re doing it already. Tyler On 5/26/05, Ramin <i8ramin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I haven''t had a chance to experiment with Rails and its ajax support much, > but I do know javascript and how the DOM works. I''m assuming you can define > a partial that has your new table row and then using ajax, you can get that > partial and insert it into your table with innerHTML > > Again, i''m not sure how the ajax stuff works in rails, but I do know how to > do it myself manually using javascript. I''d just set the output of my > xmlhttprequest call to be the partial html code and just insert it into my > table. > > Hope someone who knows Rails better can elaborate on that for you. > > > On 5/26/05, Erik Eide <erik.eide-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org > wrote: > > Hi > > > > I have a form where the user is able to add additional rows to a table > > containing text inputs for specifying one or more orders (see below). > > > > I''m wondering if this is something I could use Ajax for, i.e. to get > > rid of the table row formatting within the javascript. > > > > I''ve seen the form_remote_tag allows me to serialize a form and > > perhaps update it with a new value, but its not so clear how to > > support two submits, one for adding new rows to the table, and another > > for submitting the form. > > > > Or is this something that could also be achieved using link_to_remote ? > > > > Any ideas ? > > > > --- > > > > <html> > > <head> > > <title>Table Prototype</title> > > <script> > > var buys = 1; > > > > function add() { > > var table = document.getElementById (''buys''); > > var lastRow = table.rows.length; > > var row = table.insertRow(lastRow); > > > > var c1 = row.insertCell(0); > > var i1 = document.createElement(''input''); > > i1.setAttribute(''type'', ''text''); > > i1.setAttribute(''name'', ''buy'' + (buys + 1) + ''[symbol]''); > > i1.setAttribute(''size'', ''5''); > > c1.appendChild(i1); > > > > var c2 = row.insertCell(1); > > var i2 = document.createElement(''input''); > > i2.setAttribute(''type'', ''text''); > > i2.setAttribute(''name'', ''buy'' + (buys + 1) + ''[quantity]''); > > i2.setAttribute(''size'', ''5''); > > c2.appendChild(i2); > > > > var c3 = row.insertCell(2); > > var i3 = document.createElement(''input''); > > i3.setAttribute(''type'', ''text''); > > i3.setAttribute(''name'', ''buy'' + (buys + 1) + ''[price]''); > > i3.setAttribute(''size'', ''5''); > > c3.appendChild(i3); > > } > > </script> > > </head> > > > > <body> > > <%= start_form_tag :action => ''create'' %> > > > > Trades > > > > <p> > > <table id="buys"> > > <tr> > > <td>Stock</td> > > <td>Quanty</td> > > <td>Price</td> > > </tr> > > <tr> > > <td><input type="text" name="buy1[symbol]" value="" size="5"></td> > > <td><input type="text" name="buy1[quantity]" value="" size="5"></td> > > <td><input type="text" name="buy1[price]" value="" size="5"></td> > > </tr> > > </table> > > </p> > > > > <p> > > (+) <a href="#" onclick="add();">Add Buy</a> > > </p> > > > > <%= submit_tag "Save" %> > > <%= end_form_tag %> > > > > </body> > > </html> > > _______________________________________________ > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > > > -- > - Ramin > http://www.getintothis.com/blog > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > >
Erik Eide wrote:> I have a form where the user is able to add additional rows to a table > containing text inputs for specifying one or more orders (see below). > > Any ideas ?Here''s how I am doing it for my current project. I use the Capture helper to capture my table-row HTML -- that way I can create the HTML right in the context where it belongs -- the markup is less coupled to the Javascript, which is easier for the designer. Then I pass that captured snippet to a Javascript variable, and I can use the Prototype library to insert it as many times as I like. (In my app, I also run a regexp before every insert, to replace "INDEX" with an incrementing value, so that my fields don''t all have the same name.) Here''s the code: ######## <table id="my_table"> <tr><th>Quantity</th><th>Description</th><th>Unit Price</th></tr> <!-- Capture the following snippet into the Ruby "line_html" variable: --> <% line_html = capture do %> <tr> <td><%= text_field_tag "INDEX_quantity" %></td> <td><%= text_field_tag "INDEX_description" %></td> <td><%= text_field_tag "INDEX_unit_price" %></td> </tr> <% end %> </table> <!-- Create a JS "line_html" variable from the Ruby "line_html" variable: --> <script language="javascript">line_html = ''<%= escape_javascript (line_html) %>''</script> <!-- Link to a JS function that will insert the snippet into the table: --> <%= link_to_function "Add new row", "new Insertion[''Bottom'']($ (''my_table''), line_html)" %> ######### Hope that helps! :sco
In the beta book under the Ajax chapter they mention using JS Insertion.Bottom and Insertion.Top to add elements to existing HTML, maybe you could use this? On 5/27/05, Scott Raymond <sco-t5wuiNL5qhAfgQka0SPgqQ@public.gmane.org> wrote:> Erik Eide wrote: > > I have a form where the user is able to add additional rows to a table > > containing text inputs for specifying one or more orders (see below). > > > > Any ideas ? > > Here''s how I am doing it for my current project. I use the Capture > helper to capture my table-row HTML -- that way I can create the HTML > right in the context where it belongs -- the markup is less coupled > to the Javascript, which is easier for the designer. Then I pass that > captured snippet to a Javascript variable, and I can use the > Prototype library to insert it as many times as I like. (In my app, I > also run a regexp before every insert, to replace "INDEX" with an > incrementing value, so that my fields don''t all have the same name.) > Here''s the code: > > ######## > > <table id="my_table"> > <tr><th>Quantity</th><th>Description</th><th>Unit Price</th></tr> > <!-- Capture the following snippet into the Ruby "line_html" > variable: --> > <% line_html = capture do %> > <tr> > <td><%= text_field_tag "INDEX_quantity" %></td> > <td><%= text_field_tag "INDEX_description" %></td> > <td><%= text_field_tag "INDEX_unit_price" %></td> > </tr> > <% end %> > </table> > > <!-- Create a JS "line_html" variable from the Ruby "line_html" > variable: --> > <script language="javascript">line_html = ''<%= escape_javascript > (line_html) %>''</script> > > <!-- Link to a JS function that will insert the snippet into the > table: --> > <%= link_to_function "Add new row", "new Insertion[''Bottom'']($ > (''my_table''), line_html)" %> > > ######### > > Hope that helps! > :sco > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Hi Thanks to all those who replied with suggestions. Scott, have you tested your solution in IE ? It works great in Firefox, but fails in Internet Explorer when clicking ''Add'', with "Invalid target element for this operation", for line 505 of prototype.ps I tried adding DEFER to the <script> tag, as suggested by Microsoft when using insertAdjacentHTML, but that didn''t help.. http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/insertadjacenthtml.asp <!-- Create a JS "line_html" variable from the Ruby "line_html" variable: --> <script language="javascript" DEFER>line_html = ''<%escape_javascript(line_html)%>''</script> Erik Here''s how I am doing it for my current project. I use the Capture helper to capture my table-row HTML -- that way I can create the HTML right in the context where it belongs -- the markup is less coupled to the Javascript, which is easier for the designer. Then I pass that captured snippet to a Javascript variable, and I can use the Prototype library to insert it as many times as I like. (In my app, I also run a regexp before every insert, to replace "INDEX" with an incrementing value, so that my fields don''t all have the same name.) Here''s the code: ######## <table id="my_table"> <tr><th>Quantity</th><th>Description</th><th>Unit Price</th></tr> <!-- Capture the following snippet into the Ruby "line_html" variable: --> <% line_html = capture do %> <tr> <td><%= text_field_tag "INDEX_quantity" %></td> <td><%= text_field_tag "INDEX_description" %></td> <td><%= text_field_tag "INDEX_unit_price" %></td> </tr> <% end %> </table> <!-- Create a JS "line_html" variable from the Ruby "line_html" variable: --> <script language="javascript">line_html = ''<%= escape_javascript (line_html) %>''</script> <!-- Link to a JS function that will insert the snippet into the table: --> <%= link_to_function "Add new row", "new Insertion[''Bottom'']($ (''my_table''), line_html)" %> ######### Hope that helps! :sco On 5/27/05, Erik Eide <erik.eide-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi > > I have a form where the user is able to add additional rows to a table > containing text inputs for specifying one or more orders (see below). > > I''m wondering if this is something I could use Ajax for, i.e. to get > rid of the table row formatting within the javascript. > > I''ve seen the form_remote_tag allows me to serialize a form and > perhaps update it with a new value, but its not so clear how to > support two submits, one for adding new rows to the table, and another > for submitting the form. > > Or is this something that could also be achieved using link_to_remote ? > > Any ideas ? > > --- > > <html> > <head> > <title>Table Prototype</title> > <script> > var buys = 1; > > function add() { > var table = document.getElementById(''buys''); > var lastRow = table.rows.length; > var row = table.insertRow(lastRow); > > var c1 = row.insertCell(0); > var i1 = document.createElement(''input''); > i1.setAttribute(''type'', ''text''); > i1.setAttribute(''name'', ''buy'' + (buys + 1) + ''[symbol]''); > i1.setAttribute(''size'', ''5''); > c1.appendChild(i1); > > var c2 = row.insertCell(1); > var i2 = document.createElement(''input''); > i2.setAttribute(''type'', ''text''); > i2.setAttribute(''name'', ''buy'' + (buys + 1) + ''[quantity]''); > i2.setAttribute(''size'', ''5''); > c2.appendChild(i2); > > var c3 = row.insertCell(2); > var i3 = document.createElement(''input''); > i3.setAttribute(''type'', ''text''); > i3.setAttribute(''name'', ''buy'' + (buys + 1) + ''[price]''); > i3.setAttribute(''size'', ''5''); > c3.appendChild(i3); > } > </script> > </head> > > <body> > <%= start_form_tag :action => ''create'' %> > > Trades > > <p> > <table id="buys"> > <tr> > <td>Stock</td> > <td>Quanty</td> > <td>Price</td> > </tr> > <tr> > <td><input type="text" name="buy1[symbol]" value="" size="5"></td> > <td><input type="text" name="buy1[quantity]" value="" size="5"></td> > <td><input type="text" name="buy1[price]" value="" size="5"></td> > </tr> > </table> > </p> > > <p> > (+) <a href="#" onclick="add();">Add Buy</a> > </p> > > <%= submit_tag "Save" %> > <%= end_form_tag %> > > </body> > </html> >
On May 27, 2005, at 4:29 PM, Erik Eide wrote:> Scott, have you tested your solution in IE ? It works great in > Firefox, but fails in Internet Explorer when clicking ''Add'', with...> "Invalid target element for this operation", for line 505 of > prototype.psYou''re right. I hadn''t checked IE yet, and indeed it fails. Has anyone else used Prototype''s Insertion methods to add a row to a table in IE/win? :sco
One way I''ve got it working in both IE and Firefox is by wrapping the header table with the with a <span> or <div> tag, and then inserting new tables below the existing one. When reading a little further down in the docs for insertAdjacentHTML, it seems it doesn''t apply to table, tbody, or tr elements .. http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/insertadjacenthtml.asp Some sample code: <p> <span id="buys"> <table> <thead> <tr> <td>Stock</td> <td>Quanty</td> <td>Price</td> </tr> </thead> <tbody> <tr> <td><input type="text" name="buy_1[symbol]" value="" size="5"></td> <td><input type="text" name="buy_1[quantity]" value="" size="5"></td> <td> <input type="text" name="buy_1[price]" value="" size="5"></td> </tr> </tbody> </table> </span> <% line_html = capture do %> <table> <tr> <td><input type="text" name="buy_INDEX[symbol]" value="" size="5"></td> <td><input type="text" name="buy_INDEX[quantity]" value="" size="5"></td> <td> <input type="text" name="buy_INDEX[price]" value="" size="5"></td> </tr> </table> <% end %> </p> <p> <script language="javascript" DEFER> line_html = ''<%= escape_javascript (line_html) %>'' </script> <%= link_to_function "Add Buy", "new Insertion[''Bottom'']($(''buys''), line_html)" %> </p> Erik On 5/28/05, Scott Raymond <sco-t5wuiNL5qhAfgQka0SPgqQ@public.gmane.org> wrote:> On May 27, 2005, at 4:29 PM, Erik Eide wrote: > > Scott, have you tested your solution in IE ? It works great in > > Firefox, but fails in Internet Explorer when clicking ''Add'', with > ... > > "Invalid target element for this operation", for line 505 of > > prototype.ps > > You''re right. I hadn''t checked IE yet, and indeed it fails. Has > anyone else used Prototype''s Insertion methods to add a row to a > table in IE/win? > > :sco > >
On 5/29/05, Erik Eide <erik.eide-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> One way I''ve got it working in both IE and Firefox is by wrapping the > header table with the with a <span> or <div> tag, and then inserting > new tables below the existing one.That''s the same conclusion that I (reluctantly) arrived at, at least for the time being. Surely, in some future version of Prototype, there could be some way to easily insert a row to a table with the Insertion methods, but until then, multiple tables it is. :sco
On 5/29/05, Erik Eide <erik.eide-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> If you''re willing to share it, i''d be interested to see how you > replace the value of INDEX with an incrementing account ?No problem. Here''s the relevant code from my Javascript: var Invoice = { indexed_html: function() { return this.line_html.replace(/INDEX/g, this.line_index++) }, add_line: function() { new Insertion.Bottom($(''datarows''), this.indexed_html()) }, line_index: 1 } After capturing the row HTML to a Ruby variable, I copy it to the JS Invoice object like so: <script>Invoice.line_html = ''<%= escape_javascript(line_html) %>''</script> And then I can add a new row with this: <%= link_to_function ''Add New Line'', "Invoice.add_line()" %> As you can see, add_line() just uses Prototype''s Insertion, and calls indexed_html(), which replaces the string ''INDEX'' with the value of line_index, and then increments that number. Cheers, :sco