David Johnson
2006-Jun-03 02:00 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
Thank you in advance. Although I have many years of experience in general, including cross- platform processing, I am not an HTML/Javascript programmer. As a result, I do not have certain specific baseline skills and/or knowledge that are presumed in the Rails and Ajax documentation. I am experienced with DOM manipulations, so the bare mechanics of manipulating the browser GUI via Javascript and the DOM tree are self evident. However, this does not get the input data back to the server side of the application. The immediate question that have is this: When I dynamically add rows of inputs to a table, how do get the values entered by the user into those rows back to the rails application? The specific example is a screen for editing a question with its list of answers as a sovereign application. Both code snips are from views/question/_form.rhtml. I realize that I do not have the server side of the interface represented from controllers/question_controller.rb. In part, this is because I have a gap in my knowledge about what the HTTP post will provide back to the ruby app - it is presumed to be self evident in the books I have available. The following javascript is the code that inserts the new row into the table in the browser context (not the backing RDBMS): function insertAnswer () { table = document.getElementById ("answersTable"); body = document.getElementById ("answersBody"); row = document.createElement("tr"); row.setAttribute("id",""); // need to build a Ruby friendly naming scheme for // elements so they can be passed as parameters data = document.createElement("td"); row.appendChild(data); data = document.createElement("td"); row.appendChild(data); data = document.createElement("td"); node = document.createElement("input") node.setAttribute ("type","checkbox"); data.appendChild(node); row.appendChild(data); data = document.createElement("td"); node = document.createElement("input") node.setAttribute ("type","text"); node.setAttribute ("size","3"); data.appendChild(node); row.appendChild(data); data = document.createElement("td"); node = document.createElement("input") node.setAttribute ("type","text"); data.appendChild(node); row.appendChild(data); data = document.createElement("td"); btn = document.createElement("button") btn.setAttribute ("name","linkPresentation"); btn.setAttribute ("type","button"); btn.setAttribute ("onClick","linkAnswerToPresentation"); node = document.createElement("img"); node.setAttribute ("src","/images/file-document.png"); btn.appendChild(node); data.appendChild(btn); row.appendChild(data); data = document.createElement("td"); node = document.createElement("input") node.setAttribute ("type","text"); data.appendChild(node); row.appendChild(data); data = document.createElement("td"); btn = document.createElement("button") btn.setAttribute ("name","linkAudio"); btn.setAttribute ("type","button"); btn.setAttribute ("onClick","linkPresentationToAudio()"); node = document.createElement("img"); node.setAttribute ("src","/images/file-audio.png"); btn.appendChild(node); data.appendChild(btn); row.appendChild(data); data = document.createElement("td"); node = document.createElement("input") node.setAttribute ("type","text"); data.appendChild(node); row.appendChild(data); data = document.createElement("td"); btn = document.createElement("button") btn.setAttribute ("name","linkArt"); btn.setAttribute ("type","button"); btn.setAttribute ("onClick","linkPresentationToArt()"); node = document.createElement("img"); node.setAttribute ("src","/images/file-art.png"); btn.appendChild(node); data.appendChild(btn); row.appendChild(data); data = document.createElement("td"); btn = document.createElement("button") btn.setAttribute ("name","answer"); btn.setAttribute("id","delete_"+table.rows.length); btn.setAttribute ("type","button"); btn.setAttribute ("onClick","deleteAnswer(this)"); node = document.createElement("img"); node.setAttribute ("src","/images/trashcan_empty.png"); btn.appendChild(node); data.appendChild(btn); row.appendChild(data); body.appendChild(row); } The equivalent RHTML fragment that builds the table from previosly stored data is: <% answers = Answers.find (:all, :conditions => "parent_id = " + @question.id.to_s) for answer in answers presentation = Presentations.find_by_id (answer.presentation_id.to_s); -%> <tr> <td><%= answer.id %></td> <td><%= answer.seq %></td> <td><input type="text"><%= answer.iscorrect %></input></td> <td><%= text_field_tag ''answer.points'', answer.points %></td> <td><%= text_field_tag ''presentation.text'', presentation.text %></td><td><input name="loadText" type="img" value="file..." src="/images/file-document.png" onClick="linkPresentation()"/></td> <td><%= presentation.audio %></td> <td><input name="loadText" type="img" value="file..." src="/images/file-audio.png" onClick="linkAudio()"/></td> <td><%= presentation.visual %></td> <td><input name="loadText" type="img" value="file..." src="/images/file-art.png" onClick="linkArt()"/></td> <td><INPUT NAME="delete" TYPE="img" VALUE="Del" src="/images/trashcan_empty.png" onClick="deleteAnswer(this)"/></td> </tr> <% end %>
David Felstead
2006-Jun-03 04:49 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
If you name your input tags with a [] suffix, the data returned in your ''params'' hash will be returned in an array. For example, if the following HTML is submitted back to your controller: <input name="foo[]" type="hidden" value="a"/> <input name="foo[]" type="hidden" value="b"/> <input name="foo[]" type="hidden" value="c"/> If you look in params[''foo''] you will see [''a'', ''b'', ''c''] At a bare level that is the way it works. You can get even cleverer by using named fields in your params to better encapsulate your data - you might want to look in the source files rails/action_pack/lib/action_controller/cgi* to examine how the params hash is constructed. Cheers! -David Felstead On 6/3/06, David Johnson <johnson_d@cox.net> wrote:> Thank you in advance. > > Although I have many years of experience in general, including cross- > platform processing, I am not an HTML/Javascript programmer. As a > result, I do not have certain specific baseline skills and/or knowledge > that are presumed in the Rails and Ajax documentation. > > I am experienced with DOM manipulations, so the bare mechanics of > manipulating the browser GUI via Javascript and the DOM tree are self > evident. However, this does not get the input data back to the server > side of the application. > > The immediate question that have is this: When I dynamically add rows > of inputs to a table, how do get the values entered by the user into > those rows back to the rails application? > > > > The specific example is a screen for editing a question with its list of > answers as a sovereign application. Both code snips are from > views/question/_form.rhtml. > > I realize that I do not have the server side of the interface > represented from controllers/question_controller.rb. In part, this is > because I have a gap in my knowledge about what the HTTP post will > provide back to the ruby app - it is presumed to be self evident in the > books I have available. > > > > > The following javascript is the code that inserts the new row into the > table in the browser context (not the backing RDBMS): > > function insertAnswer () { > table = document.getElementById ("answersTable"); > body = document.getElementById ("answersBody"); > > row = document.createElement("tr"); > row.setAttribute("id",""); > // need to build a Ruby friendly naming scheme for > // elements so they can be passed as parameters > data = document.createElement("td"); > row.appendChild(data); > data = document.createElement("td"); > row.appendChild(data); > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","checkbox"); > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > node.setAttribute ("size","3"); > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","linkPresentation"); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","linkAnswerToPresentation"); > node = document.createElement("img"); > node.setAttribute ("src","/images/file-document.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","linkAudio"); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","linkPresentationToAudio()"); > node = document.createElement("img"); > node.setAttribute ("src","/images/file-audio.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","linkArt"); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","linkPresentationToArt()"); > node = document.createElement("img"); > node.setAttribute ("src","/images/file-art.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","answer"); > btn.setAttribute("id","delete_"+table.rows.length); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","deleteAnswer(this)"); > node = document.createElement("img"); > node.setAttribute ("src","/images/trashcan_empty.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > body.appendChild(row); > } > > > > The equivalent RHTML fragment that builds the table from previosly > stored data is: > > <% > answers = Answers.find (:all, :conditions => "parent_id = " + > @question.id.to_s) > for answer in answers > presentation = Presentations.find_by_id > (answer.presentation_id.to_s); > -%> > <tr> > <td><%= answer.id %></td> > <td><%= answer.seq %></td> > <td><input type="text"><%= answer.iscorrect %></input></td> > <td><%= text_field_tag ''answer.points'', answer.points %></td> > <td><%= text_field_tag ''presentation.text'', presentation.text % > ></td> > <td><input name="loadText" type="img" value="file..." > src="/images/file-document.png" onClick="linkPresentation()"/></td> > <td><%= presentation.audio %></td> > <td><input name="loadText" type="img" value="file..." > src="/images/file-audio.png" onClick="linkAudio()"/></td> > <td><%= presentation.visual %></td> > <td><input name="loadText" type="img" value="file..." > src="/images/file-art.png" onClick="linkArt()"/></td> > <td><INPUT NAME="delete" TYPE="img" VALUE="Del" > src="/images/trashcan_empty.png" onClick="deleteAnswer(this)"/></td> > </tr> > <% end %> > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Scott Becker
2006-Jun-03 07:31 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
This isn''t a direct answer to your question (someone else handled that already), but on the javascript / DOM generation side of things, I just wanted to point you in the direction of the super handy Script.aculo.us Builder class: http://wiki.script.aculo.us/scriptaculous/show/Builder You can really cut down the lines needed to build those table rows... its a nice thing :) -- Scott Becker Electro Interactive, Inc. http://www.ElectroInteractive.com Blog: http://synthesis.sbecker.net On 6/2/06, David Johnson <johnson_d@cox.net> wrote:> Thank you in advance. > > Although I have many years of experience in general, including cross- > platform processing, I am not an HTML/Javascript programmer. As a > result, I do not have certain specific baseline skills and/or knowledge > that are presumed in the Rails and Ajax documentation. > > I am experienced with DOM manipulations, so the bare mechanics of > manipulating the browser GUI via Javascript and the DOM tree are self > evident. However, this does not get the input data back to the server > side of the application. > > The immediate question that have is this: When I dynamically add rows > of inputs to a table, how do get the values entered by the user into > those rows back to the rails application? > > > > The specific example is a screen for editing a question with its list of > answers as a sovereign application. Both code snips are from > views/question/_form.rhtml. > > I realize that I do not have the server side of the interface > represented from controllers/question_controller.rb. In part, this is > because I have a gap in my knowledge about what the HTTP post will > provide back to the ruby app - it is presumed to be self evident in the > books I have available. > > > > > The following javascript is the code that inserts the new row into the > table in the browser context (not the backing RDBMS): > > function insertAnswer () { > table = document.getElementById ("answersTable"); > body = document.getElementById ("answersBody"); > > row = document.createElement("tr"); > row.setAttribute("id",""); > // need to build a Ruby friendly naming scheme for > // elements so they can be passed as parameters > data = document.createElement("td"); > row.appendChild(data); > data = document.createElement("td"); > row.appendChild(data); > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","checkbox"); > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > node.setAttribute ("size","3"); > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","linkPresentation"); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","linkAnswerToPresentation"); > node = document.createElement("img"); > node.setAttribute ("src","/images/file-document.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","linkAudio"); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","linkPresentationToAudio()"); > node = document.createElement("img"); > node.setAttribute ("src","/images/file-audio.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","linkArt"); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","linkPresentationToArt()"); > node = document.createElement("img"); > node.setAttribute ("src","/images/file-art.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","answer"); > btn.setAttribute("id","delete_"+table.rows.length); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","deleteAnswer(this)"); > node = document.createElement("img"); > node.setAttribute ("src","/images/trashcan_empty.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > body.appendChild(row); > } > > > > The equivalent RHTML fragment that builds the table from previosly > stored data is: > > <% > answers = Answers.find (:all, :conditions => "parent_id = " + > @question.id.to_s) > for answer in answers > presentation = Presentations.find_by_id > (answer.presentation_id.to_s); > -%> > <tr> > <td><%= answer.id %></td> > <td><%= answer.seq %></td> > <td><input type="text"><%= answer.iscorrect %></input></td> > <td><%= text_field_tag ''answer.points'', answer.points %></td> > <td><%= text_field_tag ''presentation.text'', presentation.text % > ></td> > <td><input name="loadText" type="img" value="file..." > src="/images/file-document.png" onClick="linkPresentation()"/></td> > <td><%= presentation.audio %></td> > <td><input name="loadText" type="img" value="file..." > src="/images/file-audio.png" onClick="linkAudio()"/></td> > <td><%= presentation.visual %></td> > <td><input name="loadText" type="img" value="file..." > src="/images/file-art.png" onClick="linkArt()"/></td> > <td><INPUT NAME="delete" TYPE="img" VALUE="Del" > src="/images/trashcan_empty.png" onClick="deleteAnswer(this)"/></td> > </tr> > <% end %> > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Mark Reginald James
2006-Jun-04 01:52 UTC
[Rails] Re: How to get dynamically created inputs from html form back to rails app
Scott Becker wrote:> This isn''t a direct answer to your question (someone else handled that > already), but on the javascript / DOM generation side of things, I > just wanted to point you in the direction of the super handy > Script.aculo.us Builder class: > > http://wiki.script.aculo.us/scriptaculous/show/Builder > > You can really cut down the lines needed to build those table rows... > its a nice thing :)Thanks, that''s useful to know. A much quicker method that often works for building complex structures is to just clone one that already exists in the page (either a visible one or a hidden prototype), and then insert the dynamic parts in the appropriate places. -- We develop, watch us RoR, in numbers too big to ignore.
David Johnson
2006-Jun-04 02:38 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
Thank you! This is too easy ... and it is beginning to make sense. I will definitely look at the cgi* files to see what is going in internally. On Sat, 2006-06-03 at 14:49 +1000, David Felstead wrote:> If you name your input tags with a [] suffix, the data returned in > your ''params'' hash will be returned in an array. For example, if the > following HTML is submitted back to your controller: > > <input name="foo[]" type="hidden" value="a"/> > <input name="foo[]" type="hidden" value="b"/> > <input name="foo[]" type="hidden" value="c"/> > > If you look in params[''foo''] you will see [''a'', ''b'', ''c''] > > At a bare level that is the way it works. You can get even cleverer > by using named fields in your params to better encapsulate your data - > you might want to look in the source files > rails/action_pack/lib/action_controller/cgi* to examine how the params > hash is constructed. > > Cheers! > > -David Felstead
David Johnson
2006-Jun-04 02:40 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
Looks very interesting ... I''ll certainly consider it. Thanks! On Sat, 2006-06-03 at 03:31 -0400, Scott Becker wrote:> This isn''t a direct answer to your question (someone else handled that > already), but on the javascript / DOM generation side of things, I > just wanted to point you in the direction of the super handy > Script.aculo.us Builder class: > > http://wiki.script.aculo.us/scriptaculous/show/Builder > > You can really cut down the lines needed to build those table rows... > its a nice thing :) > > -- > Scott Becker > Electro Interactive, Inc. > http://www.ElectroInteractive.com > Blog: http://synthesis.sbecker.net > > On 6/2/06, David Johnson <johnson_d@cox.net> wrote: > > Thank you in advance. > > > > Although I have many years of experience in general, including cross- > > platform processing, I am not an HTML/Javascript programmer. As a > > result, I do not have certain specific baseline skills and/or knowledge > > that are presumed in the Rails and Ajax documentation. > > > > I am experienced with DOM manipulations, so the bare mechanics of > > manipulating the browser GUI via Javascript and the DOM tree are self > > evident. However, this does not get the input data back to the server > > side of the application. > > > > The immediate question that have is this: When I dynamically add rows > > of inputs to a table, how do get the values entered by the user into > > those rows back to the rails application? > > > > > > > > The specific example is a screen for editing a question with its list of > > answers as a sovereign application. Both code snips are from > > views/question/_form.rhtml. > > > > I realize that I do not have the server side of the interface > > represented from controllers/question_controller.rb. In part, this is > > because I have a gap in my knowledge about what the HTTP post will > > provide back to the ruby app - it is presumed to be self evident in the > > books I have available. > > > > > > > > > > The following javascript is the code that inserts the new row into the > > table in the browser context (not the backing RDBMS): > > > > function insertAnswer () { > > table = document.getElementById ("answersTable"); > > body = document.getElementById ("answersBody"); > > > > row = document.createElement("tr"); > > row.setAttribute("id",""); > > // need to build a Ruby friendly naming scheme for > > // elements so they can be passed as parameters > > data = document.createElement("td"); > > row.appendChild(data); > > data = document.createElement("td"); > > row.appendChild(data); > > data = document.createElement("td"); > > node = document.createElement("input") > > node.setAttribute ("type","checkbox"); > > data.appendChild(node); > > row.appendChild(data); > > data = document.createElement("td"); > > node = document.createElement("input") > > node.setAttribute ("type","text"); > > node.setAttribute ("size","3"); > > data.appendChild(node); > > row.appendChild(data); > > data = document.createElement("td"); > > node = document.createElement("input") > > node.setAttribute ("type","text"); > > data.appendChild(node); > > row.appendChild(data); > > data = document.createElement("td"); > > btn = document.createElement("button") > > btn.setAttribute ("name","linkPresentation"); > > btn.setAttribute ("type","button"); > > btn.setAttribute ("onClick","linkAnswerToPresentation"); > > node = document.createElement("img"); > > node.setAttribute ("src","/images/file-document.png"); > > btn.appendChild(node); > > data.appendChild(btn); > > row.appendChild(data); > > > > data = document.createElement("td"); > > node = document.createElement("input") > > node.setAttribute ("type","text"); > > data.appendChild(node); > > row.appendChild(data); > > data = document.createElement("td"); > > btn = document.createElement("button") > > btn.setAttribute ("name","linkAudio"); > > btn.setAttribute ("type","button"); > > btn.setAttribute ("onClick","linkPresentationToAudio()"); > > node = document.createElement("img"); > > node.setAttribute ("src","/images/file-audio.png"); > > btn.appendChild(node); > > data.appendChild(btn); > > row.appendChild(data); > > > > data = document.createElement("td"); > > node = document.createElement("input") > > node.setAttribute ("type","text"); > > data.appendChild(node); > > row.appendChild(data); > > data = document.createElement("td"); > > btn = document.createElement("button") > > btn.setAttribute ("name","linkArt"); > > btn.setAttribute ("type","button"); > > btn.setAttribute ("onClick","linkPresentationToArt()"); > > node = document.createElement("img"); > > node.setAttribute ("src","/images/file-art.png"); > > btn.appendChild(node); > > data.appendChild(btn); > > row.appendChild(data); > > > > data = document.createElement("td"); > > btn = document.createElement("button") > > btn.setAttribute ("name","answer"); > > btn.setAttribute("id","delete_"+table.rows.length); > > btn.setAttribute ("type","button"); > > btn.setAttribute ("onClick","deleteAnswer(this)"); > > node = document.createElement("img"); > > node.setAttribute ("src","/images/trashcan_empty.png"); > > btn.appendChild(node); > > data.appendChild(btn); > > row.appendChild(data); > > > > body.appendChild(row); > > } > > > > > > > > The equivalent RHTML fragment that builds the table from previosly > > stored data is: > > > > <% > > answers = Answers.find (:all, :conditions => "parent_id = " + > > @question.id.to_s) > > for answer in answers > > presentation = Presentations.find_by_id > > (answer.presentation_id.to_s); > > -%> > > <tr> > > <td><%= answer.id %></td> > > <td><%= answer.seq %></td> > > <td><input type="text"><%= answer.iscorrect %></input></td> > > <td><%= text_field_tag ''answer.points'', answer.points %></td> > > <td><%= text_field_tag ''presentation.text'', presentation.text % > > ></td> > > <td><input name="loadText" type="img" value="file..." > > src="/images/file-document.png" onClick="linkPresentation()"/></td> > > <td><%= presentation.audio %></td> > > <td><input name="loadText" type="img" value="file..." > > src="/images/file-audio.png" onClick="linkAudio()"/></td> > > <td><%= presentation.visual %></td> > > <td><input name="loadText" type="img" value="file..." > > src="/images/file-art.png" onClick="linkArt()"/></td> > > <td><INPUT NAME="delete" TYPE="img" VALUE="Del" > > src="/images/trashcan_empty.png" onClick="deleteAnswer(this)"/></td> > > </tr> > > <% end %> > > > > > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails
Julian ''Julik'' Tarkhanov
2006-Jun-04 03:19 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
On 3-jun-2006, at 9:31, Scott Becker wrote:> This isn''t a direct answer to your question (someone else handled that > already), but on the javascript / DOM generation side of things, I > just wanted to point you in the direction of the super handy > Script.aculo.us Builder class: > > http://wiki.script.aculo.us/scriptaculous/show/Builder > > You can really cut down the lines needed to build those table rows... > its a nice thing :)Holy bejezus. Never thought there is such a thing there. Many thanks, my sunday is spent :-) -- Julian ''Julik'' Tarkhanov please send all personal mail to me at julik.nl
Julian ''Julik'' Tarkhanov
2006-Jun-04 03:21 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
On 4-jun-2006, at 4:40, David Johnson wrote:> Looks very interesting ... I''ll certainly consider it. > > Thanks!I don''t know what is going on with insertions, but I know that an input _DELETED_ through the DOM in Safari is still going to get submitted. I would excercise double alertness if I was on Safari in your place. -- Julian ''Julik'' Tarkhanov please send all personal mail to me at julik.nl
David Johnson
2006-Jun-04 03:31 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
I would hope that it would be submitted - without a submission I would not know to delete it from the database. I will certainly construct a full suite of tests to ensure that oddities of all of the browsers are being covered. On Sun, 2006-06-04 at 05:21 +0200, Julian ''Julik'' Tarkhanov wrote:> On 4-jun-2006, at 4:40, David Johnson wrote: > > > Looks very interesting ... I''ll certainly consider it. > > > > Thanks! > > I don''t know what is going on with insertions, but I know that an > input _DELETED_ through the DOM in Safari is still going to get > submitted. I would excercise double alertness if I was on Safari in > your place. > > -- > Julian ''Julik'' Tarkhanov > please send all personal mail to > me at julik.nl > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails
David Johnson
2006-Jun-05 02:12 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
I spoke too soon. This works for all text input elements, but it appears that this does not work if the element is a checkbox. I''ll have to check the cgi* source code still, but someone might be able to answer this more quickly. Is this a bug in rails or "by design" behavior? logged output of submission: # note that iscorrect should contain ["","on",""], at the very least. {"iscorrect"=>["on"], "audiofilename"=>["xxx", "", "yyy"], "commit"=>"Save", "imagefilename"=>["", "", ""], "points"=>["", "", ""], "action"=>"update", "id"=>"16", "question"=>{"explanation_presentation"=>{"textvalue"=>""}, "tip_presentation"=>{"textvalue"=>"Matthew 1:18"}, "points"=>"5", "time_allowed"=>"30", "presentation"=>{"textvalue"=>"Who was found to be with child through the Holy Spirit?"}, "parent"=>{"name"=>"Matthew (red level)"}}, "controller"=>"question", "presentationtext"=>["", "aaa", ""], "parent_id"=>{"1"=>""}} ["on"] ["", "aaa", ""] ["xxx", "", "yyy"] ["", "", ""] My environment is: WEBrick 1.3.1 ruby 1.8.4 (2005-12-24) [i386-linux] excerpt from Ruby controller: def update p params isCorrect=params[''iscorrect''] presentationText = params[''presentationtext''] audioFileName = params[''audiofilename''] imageFileName = params[''imagefilename''] p isCorrect p presentationText p audioFileName p imageFileName end javascript excerpt: function insertAnswer () { table = document.getElementById ("answersTable"); body = document.getElementById ("answersBody"); row = document.createElement("tr"); row.setAttribute("id",""); // need to build a Ruby friendly naming scheme for // elements so they can be passed as parameters data = document.createElement("td"); row.appendChild(data); data = document.createElement("td"); row.appendChild(data); data = document.createElement("td"); node = document.createElement("input") node.setAttribute ("type","checkbox"); node.setAttribute ("name","iscorrect[]") data.appendChild(node); row.appendChild(data); data = document.createElement("td"); node = document.createElement("input") node.setAttribute ("type","text"); node.setAttribute ("size","3"); node.setAttribute ("name","points[]") data.appendChild(node); row.appendChild(data); data = document.createElement("td"); node = document.createElement("input") node.setAttribute ("type","text"); node.setAttribute ("name","presentationtext[]") data.appendChild(node); row.appendChild(data); data = document.createElement("td"); btn = document.createElement("button") btn.setAttribute ("name","linkPresentation"); btn.setAttribute ("type","button"); btn.setAttribute ("onClick","linkAnswerToPresentation"); node = document.createElement("img"); node.setAttribute ("src","/images/file-document.png"); btn.appendChild(node); data.appendChild(btn); row.appendChild(data); data = document.createElement("td"); node = document.createElement("input") node.setAttribute ("type","text"); node.setAttribute ("name","audiofilename[]") data.appendChild(node); row.appendChild(data); data = document.createElement("td"); btn = document.createElement("button") btn.setAttribute ("name","linkAudio"); btn.setAttribute ("type","button"); btn.setAttribute ("onClick","linkPresentationToAudio()"); node = document.createElement("img"); node.setAttribute ("src","/images/file-audio.png"); btn.appendChild(node); data.appendChild(btn); row.appendChild(data); data = document.createElement("td"); node = document.createElement("input") node.setAttribute ("type","text"); node.setAttribute ("name","imagefilename[]") data.appendChild(node); row.appendChild(data); data = document.createElement("td"); btn = document.createElement("button") btn.setAttribute ("name","linkArt"); btn.setAttribute ("type","button"); btn.setAttribute ("onClick","linkPresentationToArt()"); node = document.createElement("img"); node.setAttribute ("src","/images/file-art.png"); btn.appendChild(node); data.appendChild(btn); row.appendChild(data); data = document.createElement("td"); btn = document.createElement("button") btn.setAttribute ("name","answer"); btn.setAttribute("id","delete_"+table.rows.length); btn.setAttribute ("type","button"); btn.setAttribute ("onClick","deleteAnswer(this)"); node = document.createElement("img"); node.setAttribute ("src","/images/trashcan_empty.png"); btn.appendChild(node); data.appendChild(btn); row.appendChild(data); body.appendChild(row); } 1 ) h< ()"); y ル ); t") ") t") } utt butt d"); Q taチ h< ; } On Sat, 2006-06-03 at 21:38 -0500, David Johnson wrote:> Thank you! > > This is too easy ... and it is beginning to make sense. > > I will definitely look at the cgi* files to see what is going in > internally. > > On Sat, 2006-06-03 at 14:49 +1000, David Felstead wrote: > > If you name your input tags with a [] suffix, the data returned in > > your ''params'' hash will be returned in an array. For example, if the > > following HTML is submitted back to your controller: > > > > <input name="foo[]" type="hidden" value="a"/> > > <input name="foo[]" type="hidden" value="b"/> > > <input name="foo[]" type="hidden" value="c"/> > > > > If you look in params[''foo''] you will see [''a'', ''b'', ''c''] > > > > At a bare level that is the way it works. You can get even cleverer > > by using named fields in your params to better encapsulate your data - > > you might want to look in the source files > > rails/action_pack/lib/action_controller/cgi* to examine how the params > > hash is constructed. > > > > Cheers! > > > > -David Felstead >
David Felstead
2006-Jun-05 23:52 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
HTML check box tags do not POST a value to the server if they are unchecked, so in this case the behaviour you''re experiencing is correct, if undesired. Have a look at the API call for check_box (http://ap.rubyonrails.com/classes/ActionView/Helpers/FormHelper.html#M000193) to see how you can work around this. The cliff notes version is that you add a second hidden input field to post a value for unchecked checkboxes like so: <input type="checkbox" name="foo[]" value="on"/> <input type="hidden" name="foo[]" value="off"/> This will solve your problem - instead of ["on"] you will get ["off","on","off"] Cheers! -David Felstead On 6/5/06, David Johnson <johnson_d@cox.net> wrote:> I spoke too soon. This works for all text input elements, but it > appears that this does not work if the element is a checkbox. > > I''ll have to check the cgi* source code still, but someone might be able > to answer this more quickly. > > Is this a bug in rails or "by design" behavior? > > logged output of submission: > # note that iscorrect should contain ["","on",""], at the very least. > > {"iscorrect"=>["on"], "audiofilename"=>["xxx", "", "yyy"], > "commit"=>"Save", "imagefilename"=>["", "", ""], "points"=>["", "", ""], > "action"=>"update", "id"=>"16", > "question"=>{"explanation_presentation"=>{"textvalue"=>""}, > "tip_presentation"=>{"textvalue"=>"Matthew 1:18"}, "points"=>"5", > "time_allowed"=>"30", "presentation"=>{"textvalue"=>"Who was found to be > with child through the Holy Spirit?"}, "parent"=>{"name"=>"Matthew (red > level)"}}, "controller"=>"question", "presentationtext"=>["", "aaa", > ""], "parent_id"=>{"1"=>""}} > > ["on"] > ["", "aaa", ""] > ["xxx", "", "yyy"] > ["", "", ""] > > > My environment is: > WEBrick 1.3.1 > ruby 1.8.4 (2005-12-24) [i386-linux] > > excerpt from Ruby controller: > > def update > > p params > > isCorrect=params[''iscorrect''] > presentationText = params[''presentationtext''] > audioFileName = params[''audiofilename''] > imageFileName = params[''imagefilename''] > p isCorrect > p presentationText > p audioFileName > p imageFileName > > end > > > > javascript excerpt: > > function insertAnswer () { > table = document.getElementById ("answersTable"); > body = document.getElementById ("answersBody"); > > row = document.createElement("tr"); > row.setAttribute("id",""); > // need to build a Ruby friendly naming scheme for > // elements so they can be passed as parameters > data = document.createElement("td"); > row.appendChild(data); > data = document.createElement("td"); > row.appendChild(data); > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","checkbox"); > node.setAttribute ("name","iscorrect[]") > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > node.setAttribute ("size","3"); > node.setAttribute ("name","points[]") > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > node.setAttribute ("name","presentationtext[]") > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","linkPresentation"); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","linkAnswerToPresentation"); > node = document.createElement("img"); > node.setAttribute ("src","/images/file-document.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > node.setAttribute ("name","audiofilename[]") > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","linkAudio"); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","linkPresentationToAudio()"); > node = document.createElement("img"); > node.setAttribute ("src","/images/file-audio.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > data = document.createElement("td"); > node = document.createElement("input") > node.setAttribute ("type","text"); > node.setAttribute ("name","imagefilename[]") > data.appendChild(node); > row.appendChild(data); > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","linkArt"); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","linkPresentationToArt()"); > node = document.createElement("img"); > node.setAttribute ("src","/images/file-art.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > data = document.createElement("td"); > btn = document.createElement("button") > btn.setAttribute ("name","answer"); > btn.setAttribute("id","delete_"+table.rows.length); > btn.setAttribute ("type","button"); > btn.setAttribute ("onClick","deleteAnswer(this)"); > node = document.createElement("img"); > node.setAttribute ("src","/images/trashcan_empty.png"); > btn.appendChild(node); > data.appendChild(btn); > row.appendChild(data); > > body.appendChild(row); > } > > > > > > > > > > > > > > > > > > 1 > ) > > > > h< > > > > > > > > > > > ()"); > y > > > ? > ); > > > > > > > > t") > > > > > > > > > > > > > > ") > > > > > > > > t") > > > > > > > > } > > utt > butt > > > > > > d"); > Q > > > > > ta? > > h< > > > ; > > > } > > > On Sat, 2006-06-03 at 21:38 -0500, David Johnson wrote: > > Thank you! > > > > This is too easy ... and it is beginning to make sense. > > > > I will definitely look at the cgi* files to see what is going in > > internally. > > > > On Sat, 2006-06-03 at 14:49 +1000, David Felstead wrote: > > > If you name your input tags with a [] suffix, the data returned in > > > your ''params'' hash will be returned in an array. For example, if the > > > following HTML is submitted back to your controller: > > > > > > <input name="foo[]" type="hidden" value="a"/> > > > <input name="foo[]" type="hidden" value="b"/> > > > <input name="foo[]" type="hidden" value="c"/> > > > > > > If you look in params[''foo''] you will see [''a'', ''b'', ''c''] > > > > > > At a bare level that is the way it works. You can get even cleverer > > > by using named fields in your params to better encapsulate your data - > > > you might want to look in the source files > > > rails/action_pack/lib/action_controller/cgi* to examine how the params > > > hash is constructed. > > > > > > Cheers! > > > > > > -David Felstead > > > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
David Johnson
2006-Jun-06 01:35 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
I was beginning to suspect that it might be a function of the HTML checkbox standard - thanks for the confirmation. I have seen this idiom frequently, and it seemed like an odd thing to not catch in Rails testing. It makes sense now. Thanks again for the feedback. On Tue, 2006-06-06 at 09:52 +1000, David Felstead wrote:> HTML check box tags do not POST a value to the server if they are > unchecked, so in this case the behaviour you''re experiencing is > correct, if undesired. > > Have a look at the API call for check_box > (http://ap.rubyonrails.com/classes/ActionView/Helpers/FormHelper.html#M000193) > to see how you can work around this. The cliff notes version is that > you add a second hidden input field to post a value for unchecked > checkboxes like so: > > <input type="checkbox" name="foo[]" value="on"/> > <input type="hidden" name="foo[]" value="off"/> > > This will solve your problem - instead of ["on"] you will get ["off","on","off"] > > Cheers! > > -David Felstead > > On 6/5/06, David Johnson <johnson_d@cox.net> wrote: > > I spoke too soon. This works for all text input elements, but it > > appears that this does not work if the element is a checkbox. > > > > I''ll have to check the cgi* source code still, but someone might be able > > to answer this more quickly. > > > > Is this a bug in rails or "by design" behavior? > > > > logged output of submission: > > # note that iscorrect should contain ["","on",""], at the very least. > > > > {"iscorrect"=>["on"], "audiofilename"=>["xxx", "", "yyy"], > > "commit"=>"Save", "imagefilename"=>["", "", ""], "points"=>["", "", ""], > > "action"=>"update", "id"=>"16", > > "question"=>{"explanation_presentation"=>{"textvalue"=>""}, > > "tip_presentation"=>{"textvalue"=>"Matthew 1:18"}, "points"=>"5", > > "time_allowed"=>"30", "presentation"=>{"textvalue"=>"Who was found to be > > with child through the Holy Spirit?"}, "parent"=>{"name"=>"Matthew (red > > level)"}}, "controller"=>"question", "presentationtext"=>["", "aaa", > > ""], "parent_id"=>{"1"=>""}} > > > > ["on"] > > ["", "aaa", ""] > > ["xxx", "", "yyy"] > > ["", "", ""] > > > > > > My environment is: > > WEBrick 1.3.1 > > ruby 1.8.4 (2005-12-24) [i386-linux] > > > > excerpt from Ruby controller: > > > > def update > > > > p params > > > > isCorrect=params[''iscorrect''] > > presentationText = params[''presentationtext''] > > audioFileName = params[''audiofilename''] > > imageFileName = params[''imagefilename''] > > p isCorrect > > p presentationText > > p audioFileName > > p imageFileName > > > > end > > > > > > > > javascript excerpt: > > > > function insertAnswer () { > > table = document.getElementById ("answersTable"); > > body = document.getElementById ("answersBody"); > > > > row = document.createElement("tr"); > > row.setAttribute("id",""); > > // need to build a Ruby friendly naming scheme for > > // elements so they can be passed as parameters > > data = document.createElement("td"); > > row.appendChild(data); > > data = document.createElement("td"); > > row.appendChild(data); > > data = document.createElement("td"); > > node = document.createElement("input") > > node.setAttribute ("type","checkbox"); > > node.setAttribute ("name","iscorrect[]") > > data.appendChild(node); > > row.appendChild(data); > > data = document.createElement("td"); > > node = document.createElement("input") > > node.setAttribute ("type","text"); > > node.setAttribute ("size","3"); > > node.setAttribute ("name","points[]") > > data.appendChild(node); > > row.appendChild(data); > > data = document.createElement("td"); > > node = document.createElement("input") > > node.setAttribute ("type","text"); > > node.setAttribute ("name","presentationtext[]") > > data.appendChild(node); > > row.appendChild(data); > > data = document.createElement("td"); > > btn = document.createElement("button") > > btn.setAttribute ("name","linkPresentation"); > > btn.setAttribute ("type","button"); > > btn.setAttribute ("onClick","linkAnswerToPresentation"); > > node = document.createElement("img"); > > node.setAttribute ("src","/images/file-document.png"); > > btn.appendChild(node); > > data.appendChild(btn); > > row.appendChild(data); > > > > data = document.createElement("td"); > > node = document.createElement("input") > > node.setAttribute ("type","text"); > > node.setAttribute ("name","audiofilename[]") > > data.appendChild(node); > > row.appendChild(data); > > data = document.createElement("td"); > > btn = document.createElement("button") > > btn.setAttribute ("name","linkAudio"); > > btn.setAttribute ("type","button"); > > btn.setAttribute ("onClick","linkPresentationToAudio()"); > > node = document.createElement("img"); > > node.setAttribute ("src","/images/file-audio.png"); > > btn.appendChild(node); > > data.appendChild(btn); > > row.appendChild(data); > > > > data = document.createElement("td"); > > node = document.createElement("input") > > node.setAttribute ("type","text"); > > node.setAttribute ("name","imagefilename[]") > > data.appendChild(node); > > row.appendChild(data); > > data = document.createElement("td"); > > btn = document.createElement("button") > > btn.setAttribute ("name","linkArt"); > > btn.setAttribute ("type","button"); > > btn.setAttribute ("onClick","linkPresentationToArt()"); > > node = document.createElement("img"); > > node.setAttribute ("src","/images/file-art.png"); > > btn.appendChild(node); > > data.appendChild(btn); > > row.appendChild(data); > > > > data = document.createElement("td"); > > btn = document.createElement("button") > > btn.setAttribute ("name","answer"); > > btn.setAttribute("id","delete_"+table.rows.length); > > btn.setAttribute ("type","button"); > > btn.setAttribute ("onClick","deleteAnswer(this)"); > > node = document.createElement("img"); > > node.setAttribute ("src","/images/trashcan_empty.png"); > > btn.appendChild(node); > > data.appendChild(btn); > > row.appendChild(data); > > > > body.appendChild(row); > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > 1 > > ) > > > > > > > > h< > > > > > > > > > > > > > > > > > > > > > > ()"); > > y > > > > > > ? > > ); > > > > > > > > > > > > > > > > t") > > > > > > > > > > > > > > > > > > > > > > > > > > > > ") > > > > > > > > > > > > > > > > t") > > > > > > > > > > > > > > > > } > > > > utt > > butt > > > > > > > > > > > > d"); > > Q > > > > > > > > > > ta? > > > > h< > > > > > > ; > > > > > > } > > > > > > On Sat, 2006-06-03 at 21:38 -0500, David Johnson wrote: > > > Thank you! > > > > > > This is too easy ... and it is beginning to make sense. > > > > > > I will definitely look at the cgi* files to see what is going in > > > internally. > > > > > > On Sat, 2006-06-03 at 14:49 +1000, David Felstead wrote: > > > > If you name your input tags with a [] suffix, the data returned in > > > > your ''params'' hash will be returned in an array. For example, if the > > > > following HTML is submitted back to your controller: > > > > > > > > <input name="foo[]" type="hidden" value="a"/> > > > > <input name="foo[]" type="hidden" value="b"/> > > > > <input name="foo[]" type="hidden" value="c"/> > > > > > > > > If you look in params[''foo''] you will see [''a'', ''b'', ''c''] > > > > > > > > At a bare level that is the way it works. You can get even cleverer > > > > by using named fields in your params to better encapsulate your data - > > > > you might want to look in the source files > > > > rails/action_pack/lib/action_controller/cgi* to examine how the params > > > > hash is constructed. > > > > > > > > Cheers! > > > > > > > > -David Felstead > > > > > > > > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails
David Johnson
2006-Jun-06 03:16 UTC
[Rails] How to get dynamically created inputs from html form back to rails app
The idiom suggested resulted in extra values being returned under Firefox (all of the hidden values were _always_ returned). Here is the idiom I ended up using for checkboxes: function checkboxClick(element) { inputValue = element.firstChild if (inputValue.getAttribute ("value") == "off") { inputValue.setAttribute ("value", "on") element.setAttribute ("background","/images/cbChecked.png"); } else { inputValue.setAttribute ("value", "off") element.setAttribute ("background","/images/cbUnchecked.png"); } } function insertRow () { table = document.getElementById ("answersTable"); body = document.getElementById ("answersBody"); row = document.createElement("tr"); // other non-checkbox stuff not shown ... data = document.createElement("td"); data.setAttribute("id","correct_"+table.rows.length); data.setAttribute ("background","/images/cbUnchecked.png"); node = document.createElement("input") node.setAttribute ("type","hidden"); node.setAttribute ("name","iscorrect[]") node.setAttribute ("value","off") node.setAttribute ("style", "background-repeat: no-repeat") data.appendChild(node); data.setAttribute ("onClick","checkboxClick(this)"); row.appendChild(data); // other non-checkbox stuff not shown ... body.appendChild (row) } On Mon, 2006-06-05 at 20:35 -0500, David Johnson wrote:> I was beginning to suspect that it might be a function of the HTML > checkbox standard - thanks for the confirmation. > > I have seen this idiom frequently, and it seemed like an odd thing to > not catch in Rails testing. It makes sense now. > > Thanks again for the feedback. > > On Tue, 2006-06-06 at 09:52 +1000, David Felstead wrote: > > HTML check box tags do not POST a value to the server if they are > > unchecked, so in this case the behaviour you''re experiencing is > > correct, if undesired. > > > > Have a look at the API call for check_box > > (http://ap.rubyonrails.com/classes/ActionView/Helpers/FormHelper.html#M000193) > > to see how you can work around this. The cliff notes version is that > > you add a second hidden input field to post a value for unchecked > > checkboxes like so: > > > > <input type="checkbox" name="foo[]" value="on"/> > > <input type="hidden" name="foo[]" value="off"/> > > > > This will solve your problem - instead of ["on"] you will get ["off","on","off"] > > > > Cheers! > > > > -David Felstead > >