See how to use Javascript and RJS to add and remove form fields dynamically. This episode will build upon the previous episode allowing you to create any number of tasks in one form the same time a project is created.
Great episode. You teased me though. You mentioned in last episode that by moving the task creation into the projects view we lost the error handling of the task model. Will you be covering that in future episodes? Could you point in a direction to learn about that. Thank you again for your great work.
Is it a matter of passing an errors hash back to the parent model? Can you still have the additional form change to show that errors have occurred like it does when it is on it's own view page using it's own model?
@AdulteratedJedi, I think UJS deserves its own episode. I'll consider doing one in the future. Thanks for the suggestion!
@Jlehman, there are ways to handle the validation properly, I just haven't had enough time to show it yet. Hopefully I will get around to it in the next episode.
@Mislav, I created the surrounding ".task" div so it is easier to add more fields to the task if you need to. Thanks for the tip on $(this), I'll adjust the sample code here to reflect that.
I was using RJS doing similar tasks, this is a much DRY and faster approach (although the html source code is harder to read, I can live with it by gaining that much!). Using helper function for the RJS is cool. Shared forms in different viewers become cleaner by calling RJS function in the application_helper. I can't wait to see the proper way to do validations in your complex form editing episode!
@David, good question. You can create a more traditional TasksController which handles the CRUD operations (create, read, update, destroy). You can then link to these actions on the project show page or the tasks index page. This way the user can fallback to this approach if he doesn't have javascript enabled.
Being able to add/edit multiple models at once is more for convenience and doesn't have to be the only way it is done.
I'm trying to do this but with a file_field instead of a text_field but I wont get it to work. When a user input error occurs and the new-template is rendered again my file fields are gone… I understand that I will probably have to use some other kind of techinque here, but which? Any clues?
Hey Ryan, any reason why those video do not work on the iphone? I keep on downloading them and they either appear as audio only when getting the ipod version or the video is not compatible when using the itunes version. Any idea?
For a future topic I'd like to see how to move seamlessly between a show and edit action. This is a pretty common in the real world - users browses though content and then goes into edit mode. Can you recycle a bunch of form elements for the show view and lock them somehow?
@Erik, I posted a tutorial on railsforum.com a while back which uses a different technique. It's not nearly as clean but it may handle the file field better:
http://railsforum.com/viewtopic.php?id=1065
@emmanuel, hmm, the iPod version of the videos should work on the iPhone. Are you certain that's the one you are trying? I think others have gotten it to work so I'm not sure what could be the problem.
@Arthur, I want to remove a tag higher up than the "p" tag so it is easier to add more fields to the tack if need be.
Amazing. I used the ajax version from the rayn's railsforum tutorial, but it really is a code mess :) This non-ajax variation is intuitive and clean. I will wait for the validation and edit tips.
Two other things...if i want to start with 0 tasks field on the view and let the user adds field as it wants how can i do that?
Is it possibile to download somewhere the episodes code?
@erv2, making them draggable is probably possible, but out of the scope of this tutorial. You may want to post on railsforum.com about it.
@Skyblaze, if you don't build any tasks in the "new" action of the controller it should start with zero and still work fine. I honestly haven't tested it yet though.
I can't seem to get this to work whenever you go back and reload the page and try to add more and submit. When you go back and reload the tasks will load up correctly and will have input names of "project[task_attributes][5][name]". When when you submit this you get an error: "undefined method `stringify_keys!' for "5":String. What's worse, if you reload the page and then try and add more tasks, you get this error: "Conflicting types for parameter containers. Expected an instance of Array, but found an instance of Hash. This can be caused by passing Array and Hash based paramters qs[]=value&qs[key]=value." Any suggestions? Thanks.
@Michael, this episode was just for the creation form, not for editing the project. I'll be addressing editing in the next screencast which will provide a solution to this problem.
I took the alternative download and it worked fine. but if I take the ipod RSS/Itunes subscribe, I can see all the episode as a podcast but they are audio only. So I have to download manually all the movie rather than through itune (which is fine with me)
Also, I have a question for you, How do you deal with the root controller not showing the same page for 2 different urls
If I look at rubyonrails.org I can see the following urls rendering the same page which can be annoying (especially for search engine as they see it as a different url)
@Emmanuel, thanks for letting me know. I'll try to fix the ipod feed soon.
Regarding the root URL, I just have a home controller with this route:
map.home '', :controller => 'home'
I think what you're seeing is how Rails behaves. I'm guessing rubyonrails.org either isn't running on Rails or has the root index.html page cached and their web server is interpreting that.
LOVE the casts...so helpful. I got this one working great but am having trouble getting the update to work since the model assumes the tasks are being "created". Any advice?
I wish I could get a sneak peek into the next episode... I've tried to implement the editing functionality... and got only so far before hitting a brick wall. HOW DO YOU MAKE EVERYTHING LOOK SO EASY!?!!?! The moment I watch a rails casts... I slap my forehead & say... why didn't I think about that?
@scott & TheCompWiz, there's some gotchas involved in getting the editing part to work. I'll explain everything in the next episode coming to you on Monday. :)
Great as always, but I have suggestion to all who care about W3C standards. If you use "project[task_attributes][]" in fields_for, you will get autogenerated id for tags with brackets which is not allowed as id. It is possible to assign own id by :id => "project_task_attributes" or something similar. Just remember --- id must be uniq.
hey piter was faster then me ...
ok, about the ids... If you think about it giving unique ids will get really difficult as soon as you start adding and removing new rows. You could remove the id totaly but the other problem is that you should use labels for your fields. If you go for label followed by field you would need the id for the for-attribute. So the only decent way to go (beside some complicated js that guaranties unique ids) is to go by the seldom used possibility of putting the field inside of the label - so you don't have a need for the for-attribute <label><input/></label>
When, and only when, I add the JS link to ADD the partial i get this error from my partial:
`@raid[attendee_attributes]' is not allowed as an instance variable name
I want to thank you a lot for your railscasts. They helped me quick start with Rails.
Regarding this episode, I have problem with remove js call in IE6 (FF works just fine). Actually, I think insert_html makes problem because even alert('something') doesn't work when it is put instead of 'this.up('something').remove()'. Error that IE 'raises' is 'Object doesn't support this property or method'.
Do you have any idea how to solve this problem please?
This is great, but I'm only getting one record in my child table added, and the second one is not - can you explain somewhere how the tables are related?
Sorry, I'm very new to rails, and only testing really, but I'm a little bit stuck - I will move onto part 3 in the meantime.
Hello,
I have been trrying to make this work but will forms for people ans organisation instead of projects and tasks.
<%fields_for "person[organisation_attributes][]",organisation do |org_form|%>
<div id = "organisation"><%=render :partial=>'organisation_with_index_nil_for_person',:collection=>@person.organisations,:locals=>{:org_form=>org_form}%>
In the fields_for section i am getting an error message "undefined local variable or method organisation."
in my Person model i have
class Person < ActiveRecord::Base
has_and_belongs_to_many :organisations
My Organisation model is as
class Organisation < ActiveRecord::Base
has_and_belongs_to_many :people
Please can anyone help me to figure out the mistake.Have been trying since long.
@Anks
I had the same problem.
Apparently render :partial passes the partial name as the variable name, not the child model name in the collection, as one would assume.
Hi Ryan (and all the rails guys out there)
after some trouble I have finally gotten it and now I can add and remove articles. What I would like to know now is showing the remove link only if the article is not the first so I surrounded the link_to_function helper with a if but basically I don't know how I can check out if it is the first element of the collection.
i'm having problems with the remove function. i can add new items, but when i click on the remove, i get a javascript error: $(this).up is not a function.
Hi guys,
anyone has used a dynamic field text with pagination for display. I mean after adding N fields a pagination system starts working in order to keep everything ordered within the view.
For those getting the error on IE: 'Object doesn't support this property or method'. As you probably saw it is being caused by this line: 'this.up('.something').remove()'
I spent about 3 hours tracking down this bug and its occurring because the scriptaculous prototype library (which provides functions like up, down, remove, etc) doesn't work the same way in IE.
For details read the bottom of this page:
http://prototypejs.org/learn/extensions
I can't believe this isn't documented better?!? Clearly lots of people are using embedding their own javascript into RJS.
It seems you have to use the Element.extend(something) function or the shorthand version of it $('something') so get those DOM objects to use scriptaculous functions.
So you can write the above line of code like this:
'Element.extend(this).up($('.something')).remove()'
And it works in all browsers. This seems pretty ridiculous so if someone has a better solution to this please post it.
I was wondering if anyone else was having issues with the nested fields for? if i use a boolean in the nested fields it creates multiple records (and thus causes validation issues)
Hi Brian...like everyone else, those Railscasts are awesome.
When I try to add a task, it works except that for some reason, the HTML that's inserted is putting escape characters for the first < and the last >, which results in showing the HTML code (as if displaying a text paragraph) in the browser rather than the input field.
Great webcast, as usual. I following along successfully until the sequence that moves the fields_for statement to the partial and creates the link_to_function statement in the view. Now I an RJS error. Under IE6 I get an unspecified object error; under Firefox I get "Reference error: Insertion is not defined". In the interpolated javascript statement, all the html brackets are translated to escape sequences, e.g. <a href="#" onclick="try {
new Insertion.Bottom("tasks", "\n \u003Cp\u003ETask: \u003Cinput id=\"project_task_attributes__name\" name=\"project[task_attributes][][name]\" size=\"30\" type=\"text\" /\u003E \u003C/p\u003E\n\n");
} ...
I'm using Rails 2.0.2 and Ruby 1.8.6. Can someone suggest where I may have lost my way or how I can go about tracking down the problem, please?
@Lauren & mike,
euhm after I posted this, continued to watch the railscast. And Ryan included it in the application.rhtml and even says again that you should not forget to include it !
So instead of flaming, you should have watched the cast more carefully I guess :)
Thanks, Walter. You apparently have a different concept of "flaming" than I do, but you were right about missing javascript_include_tag and I appreciate your taking the time to provide the answer.
Ryan also provided a nice description of this technique in Mike Clark's new book, Advanced Rails Recipes.
I'm in problem a few days. I suppose the mass assignment is my problem.
I' using this 'technique' with a Interview and EmployeeData model.
I have a join table and model InterviewsEmployeeDatas (using has_many like in #47 episode).
everything is doing fine except submit action. When I try to save interview I got a response: 500 Internal Server Error.
Do you have similar problem, or I have to write more about code structure I used.
Is OK to to do this in mass ass.
interview_employee_datas.build(attributes)
or have to deal with employee_datas , instead
Hi Ivan, i never faced such a problem. But i would like to ask to you that if you did just like the example, could you explain where the object, mapped into you case, Task ryan uses at line
Hey Ryan, Great railscast episode (watched all three). I was trying to make use of your moving from link_to_remote to link_to_function. It worked for me when I tried a simple page.insert_html. However, when I tried using a replace_html, I get a memory overload condition on my mongrel server like it is looping again and again for some reason. Here is my helper function: def add_policy_link(name)
link_to_function name do |page|
page.replace_html 'policiestabs', :partial => 'policies/policies_tabs'
page.call 'createPoliciesTabs'
end
end
.... Is there some obvious reason why this is the case?Thanks, John
Thanks for yuor interesting in my problem, it was a damn mistake with mass assignement as i supposed... I used something like this...
<% fields_for "project[task_attributes][]", task do |task_form| %>
and when changed this line:
<%= task_form.text_field :name %> with a line providing more infos about the text_field e.g. "project[task_attributes][#{@aNumber}]" it worked fine for me.... but still don't know where I've made mistake..
I have the <%= javascript_include_tag :defaults %> line in the head of my projects.html.erb file and that changes nothing. This error seems a bit different than some of those that others have been getting. Can anyone spot what might be going wrong here, or should I post my code? So far as I can tell, I followed the code to the T, but alas...
Thanks in advance, and also, excellent screencasts Ryan!
Great Railcast man, I am integrating this saving multiple model concept while creating a Company and multiple People inside it on a single page for , Company.new action.
I have been able to save multiple People corresponding to a single company until I started using link_to_function and the partial alternative for saving unlimited TASKS for a PROJECT or PEOPLE for a COMPANY(in my case).
Actually when I saw the HTML which was being appended inside my <div id="persons">
with the help of code below, I was surprised to find, the div with id="persons" totally empty -
<%= link_to_function "Add a Person" do |page|
page.insert_html :bottom, :persons, :partial=>"person", :object=>Person.new end %>
.
.
.
________________________________
And below is my Partial _person.html.erb
Hey @Ryan, I loved the whole complex forms series. I have tried to integrate Saving multiple tasks with a project object in my application which is saving multiple people for a New company object. And it works COOL in Internet Explorer, But I was very disturbed to see there were no params entries under company for company[person_attributes] generated on form submit in Mozilla Firefox 3.
And hence just the company fields got saved, and no record for person associated to that company were saved. Please help me with this weird difference in the Form Submit on an IE page and on a Firefox page.
Nevermind you guys, I have fixed it, it was one silliest bug I have ever hunted down.....the form close tag was misplaced.
The Complex forms series is fabulous.
@Ryan have you crafted any railscast on Message objects with file attachments management associated to them as seperate file_column objects or a different plugin...!!?!
never mind, i found my answer after doing a lot of digging around. i just researched on client-side RJS programming and conditional RJS. (whew!! totally little to no experience with these at all, so figuring it out by myself really meant something.)
if anyone would like to see how i did it, just reply/comment :)
I'm following the example using Attachment Fu to allow my users to upload 1..n images. Its almost working ! However, I only upload the number of images that where originally created in the New method of the controller
3.times {@article.images.build}
Will allow me to upload 3 images.
I can add more file_field uploads, they appear on my form, I can remove them etc. Its almost like :object => statement in the helper is not creating an object . .
I do know that my virtual attribute setter in the model is only receiving the number of objects defined in the controller.
I hope that makes sense and somebody can help. New to rails so I may be making an obvious mistake. . .
<% fields_for "proposal[proposalsection_attributes][]" do |proposalsection_form| %>
-A number of checkboxes are supposed to be in it,
-Each is supposed to save an instance of proposalsection if checked before submit!!
[their quantity is fixed for a proposal].
-On submit before putting any checkboxes code it is giving me the error -
NameError in Proposal#new
Showing app....where line #40 raised:
`@proposal[proposalsection_attributes]' is not allowed as an instance variable name
I'm having the same problem as Vikas. I found a full gist example of this technique at http://gist.github.com/33011 which supposedly worked fine. I used all this code simply changing out the models for my own names, but making sure to have everything singular/plural and the right model as needed. No matter what I do I keep getting the same error:
@line_sheet[new_page_image_attributes]' is not allowed as an instance variable name
and it's driving me crazy. Can anyone offer any help, I'll give you as much info as you need if you'd be willing. Thanks guys.
Ryan, to get this magic to work could I use jquery instead of :defaults? The reason I ask is we are already using jquery and when I add :defaults in some other javascript on the same page stops working since it requires jquery.
Also having another issue where the remove links don't work on IE7 or IE8. Does anyone know why? It almost seems that the javascript_include_tag :defaults isn't being used since it has the same behavior when javascript_include_tag isn't in your application.rhtml file.
First of all: Thanks for the great tutorials. I was basically thrown into cold water concerning the use of ruby on rails and they help a lot.
But now I am having some unexplainable trouble with the "moving to partial" part of this tutorial...
Have a look at this thread:
http://railsforum.com/viewtopic.php?pid=103348#p103348
is this whole technique w/ fields_for useless if you want a radio button then?
I tried hardcoding the id and name of the radio buttons, using a variable i which I indexed myself and still according to firebug they are missing an index, which means when i should have 2 groups of 2 radio buttons, i have 1 group of 4.
I am trying to include the add and remove links in an app I am writing. The add part was easy, but I am having no luck with remove. I have tried a few variations shown below..
<div id="person">
This is a test.
<%= link_to_function "Delete", "this.up('.person').remove()" %>
</div>
this.up("person") is undefined
Line 1
<div id="person">
This is a test.
<%= link_to_function "Delete", "$(this).up('person').remove()" %>
</div>
$(this).up("person") is undefined
I have Mixed thoughts about this episode, useful information as usual, however I do not like the Obtrusiveness of the javascript.
Maybe you could clean it up in a later episode using something Dan Webbs excellent Low Pro Library, or indeed UJS?
Great episode. You teased me though. You mentioned in last episode that by moving the task creation into the projects view we lost the error handling of the task model. Will you be covering that in future episodes? Could you point in a direction to learn about that. Thank you again for your great work.
As always a well done screencast Ryan. I have no complaints about the javascript, it is the predominant scripting language of the web after all. :)
In the case of this simple single field child model you can add errors by hand to the parent model (which the form is tied to) easily
Is it a matter of passing an errors hash back to the parent model? Can you still have the additional form change to show that errors have occurred like it does when it is on it's own view page using it's own model?
Ryan,
Why did you create a ".task" DIV to remove the task? You could have just removed the paragraph. Also, "this" needs to be enclosed in a "$()" call:
$(this).up('p').remove()
This is because of IE, in which DOM elements are not extended by default.
@AdulteratedJedi, I think UJS deserves its own episode. I'll consider doing one in the future. Thanks for the suggestion!
@Jlehman, there are ways to handle the validation properly, I just haven't had enough time to show it yet. Hopefully I will get around to it in the next episode.
@Mislav, I created the surrounding ".task" div so it is easier to add more fields to the task if you need to. Thanks for the tip on $(this), I'll adjust the sample code here to reflect that.
Nice episode. I'm waiting for Part 3! :)
I was using RJS doing similar tasks, this is a much DRY and faster approach (although the html source code is harder to read, I can live with it by gaining that much!). Using helper function for the RJS is cool. Shared forms in different viewers become cleaner by calling RJS function in the application_helper. I can't wait to see the proper way to do validations in your complex form editing episode!
This might be a preview to Ryan's railscast. I found this tidbit: http://www.railsforum.com/viewtopic.php?id=2548.
It helped me with my validation problem. Can't wait for the railscasts though. Keep up the great work Ryan.
Great last couple of Railscasts! How do you go about grace degradation with something like this?
@David, good question. You can create a more traditional TasksController which handles the CRUD operations (create, read, update, destroy). You can then link to these actions on the project show page or the tasks index page. This way the user can fallback to this approach if he doesn't have javascript enabled.
Being able to add/edit multiple models at once is more for convenience and doesn't have to be the only way it is done.
Great episode as always. I am officially big fan of Ryan's casts.
If by any chance, can you make an episode about creating/consuming RESTful web services?
Big thanks for your generous contribution to rails community.
I'm trying to do this but with a file_field instead of a text_field but I wont get it to work. When a user input error occurs and the new-template is rendered again my file fields are gone… I understand that I will probably have to use some other kind of techinque here, but which? Any clues?
Actually that link jlehman posted gave me a clue.
Hey Ryan, any reason why those video do not work on the iphone? I keep on downloading them and they either appear as audio only when getting the ipod version or the video is not compatible when using the itunes version. Any idea?
Thanks
For a future topic I'd like to see how to move seamlessly between a show and edit action. This is a pretty common in the real world - users browses though content and then goes into edit mode. Can you recycle a bunch of form elements for the show view and lock them somehow?
To remove the text field you should also call
$(this.parentNode).remove() and it will remove the p node.
@ari: http://railscasts.com/about
@Erik, I posted a tutorial on railsforum.com a while back which uses a different technique. It's not nearly as clean but it may handle the file field better:
http://railsforum.com/viewtopic.php?id=1065
@emmanuel, hmm, the iPod version of the videos should work on the iPhone. Are you certain that's the one you are trying? I think others have gotten it to work so I'm not sure what could be the problem.
@Arthur, I want to remove a tag higher up than the "p" tag so it is easier to add more fields to the tack if need be.
Very good episode, looking forward to the error handling. Also, how about adding draggable list to arrange the order of the tasks?
Amazing. I used the ajax version from the rayn's railsforum tutorial, but it really is a code mess :) This non-ajax variation is intuitive and clean. I will wait for the validation and edit tips.
Two other things...if i want to start with 0 tasks field on the view and let the user adds field as it wants how can i do that?
Is it possibile to download somewhere the episodes code?
@erv2, making them draggable is probably possible, but out of the scope of this tutorial. You may want to post on railsforum.com about it.
@Skyblaze, if you don't build any tasks in the "new" action of the controller it should start with zero and still work fine. I honestly haven't tested it yet though.
I'll post the full code after the final episode.
I can't seem to get this to work whenever you go back and reload the page and try to add more and submit. When you go back and reload the tasks will load up correctly and will have input names of "project[task_attributes][5][name]". When when you submit this you get an error: "undefined method `stringify_keys!' for "5":String. What's worse, if you reload the page and then try and add more tasks, you get this error: "Conflicting types for parameter containers. Expected an instance of Array, but found an instance of Hash. This can be caused by passing Array and Hash based paramters qs[]=value&qs[key]=value." Any suggestions? Thanks.
@Michael, this episode was just for the creation form, not for editing the project. I'll be addressing editing in the next screencast which will provide a solution to this problem.
Great! Thanks for the quick reply ryan, keep up the good work!
@Ryan
I took the alternative download and it worked fine. but if I take the ipod RSS/Itunes subscribe, I can see all the episode as a podcast but they are audio only. So I have to download manually all the movie rather than through itune (which is fine with me)
Also, I have a question for you, How do you deal with the root controller not showing the same page for 2 different urls
If I look at rubyonrails.org I can see the following urls rendering the same page which can be annoying (especially for search engine as they see it as a different url)
rubyonrails.org/
rubyonrails.org/index
rubyonrails.org/index.html
but on railscast ( I am not sure how you named your default controller, I cannot see a page for railscasts.com/index.html
@Emmanuel, thanks for letting me know. I'll try to fix the ipod feed soon.
Regarding the root URL, I just have a home controller with this route:
map.home '', :controller => 'home'
I think what you're seeing is how Rails behaves. I'm guessing rubyonrails.org either isn't running on Rails or has the root index.html page cached and their web server is interpreting that.
LOVE the casts...so helpful. I got this one working great but am having trouble getting the update to work since the model assumes the tasks are being "created". Any advice?
I wish I could get a sneak peek into the next episode... I've tried to implement the editing functionality... and got only so far before hitting a brick wall. HOW DO YOU MAKE EVERYTHING LOOK SO EASY!?!!?! The moment I watch a rails casts... I slap my forehead & say... why didn't I think about that?
@scott & TheCompWiz, there's some gotchas involved in getting the editing part to work. I'll explain everything in the next episode coming to you on Monday. :)
Hello,
Great as always, but I have suggestion to all who care about W3C standards. If you use "project[task_attributes][]" in fields_for, you will get autogenerated id for tags with brackets which is not allowed as id. It is possible to assign own id by :id => "project_task_attributes" or something similar. Just remember --- id must be uniq.
thanks for this awesome screencast.
hey piter was faster then me ...
ok, about the ids... If you think about it giving unique ids will get really difficult as soon as you start adding and removing new rows. You could remove the id totaly but the other problem is that you should use labels for your fields. If you go for label followed by field you would need the id for the for-attribute. So the only decent way to go (beside some complicated js that guaranties unique ids) is to go by the seldom used possibility of putting the field inside of the label - so you don't have a need for the for-attribute <label><input/></label>
Indeed, putting field inside of the label is good practice, but AFAIR Internet Explorer doesn't respect such syntax. Correct me if i'm wrong...
When, and only when, I add the JS link to ADD the partial i get this error from my partial:
`@raid[attendee_attributes]' is not allowed as an instance variable name
Hi Ryan,
I want to thank you a lot for your railscasts. They helped me quick start with Rails.
Regarding this episode, I have problem with remove js call in IE6 (FF works just fine). Actually, I think insert_html makes problem because even alert('something') doesn't work when it is put instead of 'this.up('something').remove()'. Error that IE 'raises' is 'Object doesn't support this property or method'.
Do you have any idea how to solve this problem please?
Cancel that. It works now with code from this page '$(this).up('something').remove()'
Tnx anyway for these casts and code snippets :)
@Ryan Bates: Thanks for showing how to do this client-side. The idea of doing server requests just seemed silly. You make me luv Rails again. :-)
This is great, but I'm only getting one record in my child table added, and the second one is not - can you explain somewhere how the tables are related?
Sorry, I'm very new to rails, and only testing really, but I'm a little bit stuck - I will move onto part 3 in the meantime.
Hello,
I have been trrying to make this work but will forms for people ans organisation instead of projects and tasks.
<%fields_for "person[organisation_attributes][]",organisation do |org_form|%>
<div id = "organisation"><%=render :partial=>'organisation_with_index_nil_for_person',:collection=>@person.organisations,:locals=>{:org_form=>org_form}%>
In the fields_for section i am getting an error message "undefined local variable or method organisation."
in my Person model i have
class Person < ActiveRecord::Base
has_and_belongs_to_many :organisations
My Organisation model is as
class Organisation < ActiveRecord::Base
has_and_belongs_to_many :people
Please can anyone help me to figure out the mistake.Have been trying since long.
@Anks
I had the same problem.
Apparently render :partial passes the partial name as the variable name, not the child model name in the collection, as one would assume.
render :partial => 'organisation_with_index_nil_for_person'
is sending a variable named organisation_with_index_nil_for_person to your partial, but your are expecting a variable named organisation.
Try renaming your partial to _organisation.rhtml and call it with:
<%= render :partial => 'organisation', :collection => @person.organisations %>
It worked for me. Further reference, see http://dev.rubyonrails.org/ticket/5524
Hi Ryan (and all the rails guys out there)
after some trouble I have finally gotten it and now I can add and remove articles. What I would like to know now is showing the remove link only if the article is not the first so I surrounded the link_to_function helper with a if but basically I don't know how I can check out if it is the first element of the collection.
Could you please help me with this?
Thanks and have a nice day!
Hi,
i'm having problems with the remove function. i can add new items, but when i click on the remove, i get a javascript error: $(this).up is not a function.
am i missing something?
thanks for your help.
Oops, my bad. realised i was using an old version of prototype. i used Element.remove(this.parentNode) instead.
cheers!
Is there any reason the code you have on this screen cast shouldn't work with rails 2.0?
My code matches your code to the character and i get an rjs error.
Hi Harrel,
I get an rjs error too using rails 2.0. Can anybody help? Mine says ReferenceError: Insertion is not defined
I found in a german forum that you only need to add this to the application.rhtml file:
<%= javascript_include_tag :defaults %>
And it works!!
Hi guys,
anyone has used a dynamic field text with pagination for display. I mean after adding N fields a pagination system starts working in order to keep everything ordered within the view.
THANKS.
For those getting the error on IE: 'Object doesn't support this property or method'. As you probably saw it is being caused by this line: 'this.up('.something').remove()'
I spent about 3 hours tracking down this bug and its occurring because the scriptaculous prototype library (which provides functions like up, down, remove, etc) doesn't work the same way in IE.
For details read the bottom of this page:
http://prototypejs.org/learn/extensions
I can't believe this isn't documented better?!? Clearly lots of people are using embedding their own javascript into RJS.
It seems you have to use the Element.extend(something) function or the shorthand version of it $('something') so get those DOM objects to use scriptaculous functions.
So you can write the above line of code like this:
'Element.extend(this).up($('.something')).remove()'
And it works in all browsers. This seems pretty ridiculous so if someone has a better solution to this please post it.
I was wondering if anyone else was having issues with the nested fields for? if i use a boolean in the nested fields it creates multiple records (and thus causes validation issues)
Somehow everyone that has gotten it to work has decided to move on without sharing their discoveries. If only there were more people like Ryan
Hi Brian...like everyone else, those Railscasts are awesome.
When I try to add a task, it works except that for some reason, the HTML that's inserted is putting escape characters for the first < and the last >, which results in showing the HTML code (as if displaying a text paragraph) in the browser rather than the input field.
Here is an example of what's inserted:
<input id="continuum_stage_attributes__name"
name="continuum[stage_attributes][][name]" size="30" type="text" />
Any ideas?
Great webcast, as usual. I following along successfully until the sequence that moves the fields_for statement to the partial and creates the link_to_function statement in the view. Now I an RJS error. Under IE6 I get an unspecified object error; under Firefox I get "Reference error: Insertion is not defined". In the interpolated javascript statement, all the html brackets are translated to escape sequences, e.g. <a href="#" onclick="try {
new Insertion.Bottom("tasks", "\n \u003Cp\u003ETask: \u003Cinput id=\"project_task_attributes__name\" name=\"project[task_attributes][][name]\" size=\"30\" type=\"text\" /\u003E \u003C/p\u003E\n\n");
} ...
I'm using Rails 2.0.2 and Ruby 1.8.6. Can someone suggest where I may have lost my way or how I can go about tracking down the problem, please?
Thanx, great tutorial, loved it :)
Anyway ruby got me loving programming again and to all people complaining it does not work, had same thing.
And solution is simple, you are using the Insert method from the rjs library but forgot to include the javascript lib files.
To make the long story short you get rid of the Reference errors by adding this line to your view html template (mine is project.rhtml):
<%= javascript_include_tag :defaults %>
here is my full project.rhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>Project: <%= controller.action_name %></title>
<%= stylesheet_link_tag 'scaffold' %>
<%= javascript_include_tag :defaults %>
</head>
<body>
<p style="color: green"><%= flash[:notice] %></p>
<%= yield %>
</body>
</html>
@Lauren & mike,
euhm after I posted this, continued to watch the railscast. And Ryan included it in the application.rhtml and even says again that you should not forget to include it !
So instead of flaming, you should have watched the cast more carefully I guess :)
Thanks, Walter. You apparently have a different concept of "flaming" than I do, but you were right about missing javascript_include_tag and I appreciate your taking the time to provide the answer.
Ryan also provided a nice description of this technique in Mike Clark's new book, Advanced Rails Recipes.
-- Mike
Hi!
in the page.insert_html line, the Task.new call is used as parameter.
Where the Task object comes from?
Thanks,
--
Guerra
Hi people!
I'm in problem a few days. I suppose the mass assignment is my problem.
I' using this 'technique' with a Interview and EmployeeData model.
I have a join table and model InterviewsEmployeeDatas (using has_many like in #47 episode).
everything is doing fine except submit action. When I try to save interview I got a response: 500 Internal Server Error.
Do you have similar problem, or I have to write more about code structure I used.
Is OK to to do this in mass ass.
interview_employee_datas.build(attributes)
or have to deal with employee_datas , instead
Thanks in advance!
Hi Ivan, i never faced such a problem. But i would like to ask to you that if you did just like the example, could you explain where the object, mapped into you case, Task ryan uses at line
page.insert_html :bottom, :tasks, :partial => 'task', :object => Task.new
comes from?
He does a Task.new and i cant figure out what i have to do in the model to make this work.
Thanks,
--
Guerra
Hey Ryan, Great railscast episode (watched all three). I was trying to make use of your moving from link_to_remote to link_to_function. It worked for me when I tried a simple page.insert_html. However, when I tried using a replace_html, I get a memory overload condition on my mongrel server like it is looping again and again for some reason. Here is my helper function: def add_policy_link(name)
link_to_function name do |page|
page.replace_html 'policiestabs', :partial => 'policies/policies_tabs'
page.call 'createPoliciesTabs'
end
end
.... Is there some obvious reason why this is the case?Thanks, John
I'm trying to implement this but with:
collection_select
instead of:
text_field
Using :index => nil works fine with text_field but not with collection_select. How can I get arround this?
Hi Guerra!
Thanks for yuor interesting in my problem, it was a damn mistake with mass assignement as i supposed... I used something like this...
<% fields_for "project[task_attributes][]", task do |task_form| %>
and when changed this line:
<%= task_form.text_field :name %> with a line providing more infos about the text_field e.g. "project[task_attributes][#{@aNumber}]" it worked fine for me.... but still don't know where I've made mistake..
Howdy - I also have been having some issues getting this javascript to work. I'm running Rails 2.0 and using firefox.
Once I try to get the
"Add a task" button to work, I get the following error:
RJS error:
TypeError: element is null
new Insertion.Bottom("tasks", " \n \t\u003Cp\u003E\n\t Task: \u003Cinput id=\"project_task_attributes__name\" name=\"project[task_attributes][][name]\" size=\"30\" type=\"text\" /\u003E\n \t\u003C/p\u003E\n ");
I have the <%= javascript_include_tag :defaults %> line in the head of my projects.html.erb file and that changes nothing. This error seems a bit different than some of those that others have been getting. Can anyone spot what might be going wrong here, or should I post my code? So far as I can tell, I followed the code to the T, but alas...
Thanks in advance, and also, excellent screencasts Ryan!
Chris
Hey Ryan,
Great Railcast man, I am integrating this saving multiple model concept while creating a Company and multiple People inside it on a single page for , Company.new action.
I have been able to save multiple People corresponding to a single company until I started using link_to_function and the partial alternative for saving unlimited TASKS for a PROJECT or PEOPLE for a COMPANY(in my case).
Actually when I saw the HTML which was being appended inside my <div id="persons">
with the help of code below, I was surprised to find, the div with id="persons" totally empty -
code for company/new.html.erb
_______________________________
.
.
.
<div id="persons" >
<%= render :partial =>'person', :collection=>@company.people %>
</div>
<%= link_to_function "Add a Person" do |page|
page.insert_html :bottom, :persons, :partial=>"person", :object=>Person.new end %>
.
.
.
________________________________
And below is my Partial _person.html.erb
<div>
<% fields_for "company[person_attributes][]", person do |p| %>
<table width="96%">
<tr>
<td width="21%" align="right">First Name</td>
<td colspan="2"><%= p.text_field :first_name, :class=>"textbox", :style=>"width:180px" %>
Last Name
<%= p.text_field :last_name, :class=>"textbox", :style=>"width:180px" %></td>
</tr>
<tr>
<td align="right">Designation</td>
<td colspan="2"><%= p.text_field :jobtitle, :class=>"textbox", :style=>"width:180px" %></td>
</tr>
</table>
<% end %>
</div>
.............................
Please tell me why nothing rendered inside my <div id="persons"> however it kept adding on the page outside the div, to the HTML being generated below with all weird escape characters, like
______________________________
<a href="#" onclick="try {
new Insertion.Bottom("persons", " \u003Cdiv \u003E\n \n \n \u003Ctable width=\"96%\" border=\"0\" align=\"left\" cellpadding=\"5\" cellspacing=\"0\"\u003E\n \u003Ctr\u003E\n \u003Ctd width=\"21%\" align=\"right\"\u003EFirst Name\u003C/td\u003E\n \u003Ctd colspan=\"2\"\u003E\u003Cinput class=\"textbox\" id=\"company_person_attributes__first_name\" name=\"company[person_attributes][][first_name]\" size=\"30\" style=\"width:180px\" type=\"text\" /\u003E\n \u0026nbsp;Last Name\u0026nbsp;\n \u003Cinput class=\"textbox\" id=\"company_person_attributes__last_name\" name=\"company[person_attributes][][last_name]\" size=\"30\" style=\"width:180px\" type=\"text\" /\u003E\u003C/td\u003E\n...>Add a Person</a>
_____________________________
I'm trying this code (I'm a noobie) but get the following error:
RJS Error:
ReferenceError: Insertion is not defined.
Oh yeah, and I'm using Rails 2.1 if that makes a difference??
Please disregard my previous posts, I was able to solve this. I needed to add some code to the <head>
Hey @Ryan, I loved the whole complex forms series. I have tried to integrate Saving multiple tasks with a project object in my application which is saving multiple people for a New company object. And it works COOL in Internet Explorer, But I was very disturbed to see there were no params entries under company for company[person_attributes] generated on form submit in Mozilla Firefox 3.
And hence just the company fields got saved, and no record for person associated to that company were saved. Please help me with this weird difference in the Form Submit on an IE page and on a Firefox page.
Nevermind you guys, I have fixed it, it was one silliest bug I have ever hunted down.....the form close tag was misplaced.
The Complex forms series is fabulous.
@Ryan have you crafted any railscast on Message objects with file attachments management associated to them as seperate file_column objects or a different plugin...!!?!
I wish there was any...:)
I have the same problem that #66. Chris Small
Some help?
Hey Ryan, or anyone for that matter who still sees this,
Any idea how to set a limit on the number of row of fields you can "Add more"?
never mind, i found my answer after doing a lot of digging around. i just researched on client-side RJS programming and conditional RJS. (whew!! totally little to no experience with these at all, so figuring it out by myself really meant something.)
if anyone would like to see how i did it, just reply/comment :)
Fantastic stuff Ryan. If you knew how long I've been trying to understand handling nested models...
Hi,
Thanks for the Rails cast!
I have integrated this solution seamlessly into my own app with resounding success except for one thing.
If I use the add task link (add member in my case) then all works as it should and I get a 4th row.
Now if I hit the refresh button in my browser the 4th row dissapears.
Is there a solution to this?
Thanks again.
I have the same problem as tal@35:
`@raid[attendee_attributes]' is not allowed as an instance variable name
From what I've been able to gather, this might be an acknowledged problem with nesting in partials, but I can't seem to get around it.
Great Work Ryan!!
Keep more of these coming!!
I'm following the example using Attachment Fu to allow my users to upload 1..n images. Its almost working ! However, I only upload the number of images that where originally created in the New method of the controller
3.times {@article.images.build}
Will allow me to upload 3 images.
I can add more file_field uploads, they appear on my form, I can remove them etc. Its almost like :object => statement in the helper is not creating an object . .
I do know that my virtual attribute setter in the model is only receiving the number of objects defined in the controller.
I hope that makes sense and somebody can help. New to rails so I may be making an obvious mistake. . .
Thanks in advance
you forgot to mention to include the javascript libraries in the header or else you get an RJS error.
<%= javascript_include_tag :defaults %>
@Ryan Thank you very much.
I used it in many models but this one didn't cut it !!
:proposal has_many :sections, :through=>:proposalsections
I am in create proposal form and have this in it
<% fields_for "proposal[proposalsection_attributes][]" do |proposalsection_form| %>
-A number of checkboxes are supposed to be in it,
-Each is supposed to save an instance of proposalsection if checked before submit!!
[their quantity is fixed for a proposal].
-On submit before putting any checkboxes code it is giving me the error -
NameError in Proposal#new
Showing app....where line #40 raised:
`@proposal[proposalsection_attributes]' is not allowed as an instance variable name
Extracted source (around line #40):
37: <%= proposal_form.text_area :description, :rows=>7, :cols=>30 %>
38: </p>
39:
40: <% fields_for "proposal[proposalsection_attributes][]" do |proposalsection_form| %>
41:
42:
43: <div>
Can anyone analyze what is it which is Wrong here?
I'm having the same problem as Vikas. I found a full gist example of this technique at http://gist.github.com/33011 which supposedly worked fine. I used all this code simply changing out the models for my own names, but making sure to have everything singular/plural and the right model as needed. No matter what I do I keep getting the same error:
@line_sheet[new_page_image_attributes]' is not allowed as an instance variable name
and it's driving me crazy. Can anyone offer any help, I'll give you as much info as you need if you'd be willing. Thanks guys.
Wonderful screencast! Exactly what I want -- except I'm having trouble getting it to work!!
It tells me "undefined method `stringify_keys!" -- any idea what might be going on?
If it helps, the relevant portions of my application are at http://pastie.org/498539.
It works for creating a new model, but has trouble updating an existing one.
It seems to be trying to pull the id of my submodel...
(Thanks in advance!)
Ryan, to get this magic to work could I use jquery instead of :defaults? The reason I ask is we are already using jquery and when I add :defaults in some other javascript on the same page stops working since it requires jquery.
Got it! Part three fixed everything for me beautifully.
Also having another issue where the remove links don't work on IE7 or IE8. Does anyone know why? It almost seems that the javascript_include_tag :defaults isn't being used since it has the same behavior when javascript_include_tag isn't in your application.rhtml file.
First of all: Thanks for the great tutorials. I was basically thrown into cold water concerning the use of ruby on rails and they help a lot.
But now I am having some unexplainable trouble with the "moving to partial" part of this tutorial...
Have a look at this thread:
http://railsforum.com/viewtopic.php?pid=103348#p103348
Great tutorial by the way. Informative but annoying at how easy you make it look!
I used tutorial 1 but decided to use a partial to display each task, as I thought this made a lot of sense.
However, when I loaded up tutorial 2, you then create a partial to create tasks.
Is it possible to have two partials in the same view? And if so how do I go about it?
Nice episode, i always read parts of it if i'm stuck at something.
I just wonder how to do it with UJS (lowpro) in a clean way.
great screencast...
is this whole technique w/ fields_for useless if you want a radio button then?
I tried hardcoding the id and name of the radio buttons, using a variable i which I indexed myself and still according to firebug they are missing an index, which means when i should have 2 groups of 2 radio buttons, i have 1 group of 4.
Here you can find the same but in PDF format:
http://media.pragprog.com/titles/fr_arr/multiple_models_one_form.pdf
I am trying to include the add and remove links in an app I am writing. The add part was easy, but I am having no luck with remove. I have tried a few variations shown below..
<div id="person">
This is a test.
<%= link_to_function "Delete", "this.up('.person').remove()" %>
</div>
this.up("person") is undefined
Line 1
<div id="person">
This is a test.
<%= link_to_function "Delete", "$(this).up('person').remove()" %>
</div>
$(this).up("person") is undefined
Any help would be appreciated
Bob
Awesome, you're great, I love your screencasts :)