How can I create this dynamic form? - ruby-on-rails

Imagine a dropdown with 3 options:A,B,C and a div with the id of myform.
When the user selects an option from the list, the div's content should be replaced by the form corresponding to the option. The thing is, the forms have nothing in common.
I was thinking of tackling this in the following way:
create a new controller FormCreator
create a new action build_form , which will take a type as a parameter (A/B/C)
create A.html.erb, B.html.erb and C.html.erb
depending on the type, I will render either A/B/C, with layout rendering disabled
use ajax to replace the content of the div with what the controller produced
Is there a better way of doing this?

Here's guideline how I would do it: When some option is selected, for example A, with AJAX GET AController#new as JSON and return form rendered by erb. Than $('#myForm').html(withResponse). Main idea is that on select.change event you hit correct resource controller new action and replace div content with it's response.
Not complete answer but I hope it will give you an idea

Why not just hide the forms and reveal/hide them upon select list selection? It doesn't matter which controller or action you render the forms/select list from but they should probably post to their own controller and render only the previously posted form on validation failure.

Use a javascript select to call your AJAX controller with :onchange => remote_function(...)
In your controller =>
def FormCreator
if params[:form] == 1
render :update do |page|
page.replace_html 'form_div', :partial => 'form_1'
#make a file with just the form called _form_1.erb, this is called a partial
#because the file name starts with '_'
#form_div is the id of the div that holds all 3 forms.
end
end
#repeat for all forms
end

Related

how to add a `preview` action to resources?

I am looking for the right approach to include a preview action between new and create actions.
Let's assume I have the following:
resources :users
By default, when the form is submitted:
if new, call create action;
if edit, call update action.
In this way, I can use the same form (partial) for new and create, which is great!
How can I configure the resources to include a preview between actions. I mean, forcing new to call preview and then preview to call create.
I could add a new route/action and point the form for that action, however the same form cannot be used for new and edit.
There is a way to configure the resources to do that?
Have a look at this railscast: multibutton form, it shows a form with both a 'preview' and 'submit' button, maybe that's something you might want to do.
By the way, couldn't you use the same form by passing locals to the partial? For example:
<%= form_for #profile, url: dynamic_path do |f| %>
...
<% end %>
<%= render 'form', dynamic_path: profile_preview_path %>
you have several ways to do this:
you change the url of the form to your preview action (for which you have to add a route).
you use your create action for preview and create:
i.e. you add a parameter (like ':go_to_preview') to the form submit request. if you find it in the controller you render preview.
when the user wants to confirm the preview, you submit the data again (without that parameter) and this time create the record.
there are also 2 more dynamic possibilities:
you create the preview in real-time - if that is possible (like here on SO) - and use just the create action,
a variation of the first option: when the user submits the form, you send an ajax post request to a preview action, render a partial and include it on the page, then while your user still has the form he just filled, the user decides if she wants to modify or submit definitely.
I would suggest adding a DateTime column "finished_at", "published_on", etc... whatever is appropriate for your domain.
Using blog posts as an example:
scope :published, where("published_on IS NOT NULL")
scope :draft, where(:published_on => nil)
Use the scopes and new field where appropriate to limit the follow up actions.
This approach gives you more than you asked for :
a way to limit processing based on "state"
Data on creation times versus publishing times

Append form partial in the new view of the same model in rails

i'd like to use the same model to create in one view (new.erb.html) more records at once with a single submit.
for example I've a model called Report with some fields such title, description and date
how can render same form partial many times when i click an add button? i think is not a nasted model's problem because is always the same model actions.
Thanks
You can do something like this (I haven't test the code myself):
haml:
.model
%input{:name => "model[][name]"}
%input{:name => "model[][desc]"}
%input{:name => "model[][date]"}
.container
%button.add-model
js:
$('.add-model').click(function(){
$('.model').clone().first().appendTo('.container');
})
controller:
def save
params[:model].each do |props|
Model.create(props)
end
end
What I do is using JavaScript (jQuery) - on page load I save the only rendered form into JS variable (actually not the form, but the inputs inside it), and then on clicking "Add more" link append more inputs into the form.
And to save many objects at once you will need handcrafted input names (something like model[][name] in order to send an array of values), as well as controller that accepts array.

Rendering a completely new partial using jquery ajax

I'm trying to write an AJAX call that renders a new partial when a particular item is selected from a drop down list. I have been searching for a solution all day with no luck :(
The only way I got it working was not using AJAX, but having a hidden div containing my second partial, and then showing it and hiding the other div when the appropriate option is selected from the drop down box. Yes this worked but I was looking for a cleaner solution.
I'm not looking for a direct answer, but if anyone has any resources that could point me in the right direction it would be greatly appreciated :)
How about adding a controller action that would render the view (so it's view would just render the partial), and then using jquery to place it:
$('#id-of-box').load("<%= some_action_path %>")
You should perform a remote AJAX call when the onchange event from your select element is being triggered, so on the page which contains your select element there should be something like this (inside a script):
$('#select_id').live('change',function(){
$.ajax({
url: 'url_bound_to_partial_renderer'
});
}
and on the action of the controller which responds to your url_to_fetch_result, you should write something like this:
# controller
# action bound to 'url_bound_to_partial_renderer' by routes.rb
def partial_renderer
...
end
#view (partial) _partial_renderer.js.erb
$('jquery_selector_path_to_container_element_of_your_partial').html("<%= escape_javascript render(:partial => 'my_partial') %>");
#view (partial) to be rendered inside container element: _my_partial.html.erb
<p>Here goes the content of the partial you want to be rendered on the container!</p>
Hope this will respond to your question.

How to implement dynamic content render when form submited (newbie ask)

I am developing rails 3 application (I am newbie in Rails).
Currently, I have a form (use "form_for") for submit, there is a div area under the form. What I want is when user click the 'submit' button of the form, based on the user input data in the form, application will first go to the database to retrieve and organize some data, then the div area under the form will be rendered with the organized data.
That's the content of the div area is rendered dynamically based on user's input in the form, and the div render happens when user click "submit" form button .
The index.html.haml:
=form_for :myform do |form|
= ...
= ...
=form.submit "submit"
%div.result
/dynamic content to be rendered here, when user submit the form
=render :partial 'result'
I think my form submission should first go to run a controller method to organize the data from Database, and what's the next step I should do? As you noticed from the above code, I have a partial there under div, I would like to update the 'result' partial when user submit form, but how to implement this??
examples of how you may update your page in response to ajax polling
#some_controller.rb
def your_action
end
# javascript erb file. views/some_controller/your_action.js.erb
$('div.result').html('<%= escape_javascript(render :partial => 'your_action' -%>');
# _your_action.html.haml
= #dynamic_data
Rails scaffolding will give you a clue on how to do this. Just include the form as partial as well in your show template. Something like this:
index.html.haml (or new.htm.haml):
= render 'new'
show.html.haml:
= render 'new'
# display your #object

Posting a form through popup in Rails

I have a model called Details, and two controller methods new and create. New method displays a form to create Details (in new.html.erb), which gets posted to the Create method that saves it. (when it succesffully saves, it it renders the new.html.erb file with the details.) This works as expected.
Now i want a separate page with a link to fill in these details. I want the click to do the intended work through a popup, example redbox. When you click on that link, a popup should show the form, whose submit should post the form, and if it is successfully done, then refresh the original page. If the post is unsaved, then the same form should show the errors. What do i need to do to make it work in Ror? I guess i need some stuff to go in new.js.rjs and maybe create.js.rjs, but i can't really figure out what to put in those files.
Redbox updates the page's dom to add a div at the end of it. So your form is a part of the main page.
So if you add a form tag in this redbox, all your page will be reloaded as there's only one.
So you add anywhere in your page (preferably at the end) :
<div id="redbox" style="display: none;">
<%= form_for #details do %>
# Whatever form fields you want here
<% end -%>
</div>
You do a link that'll open the redbox :
<%= link_to_redbox 'Open The Details Form', 'redbox' %>
This will display your redbox with your form.
And as it is the same page, not a new windows, when you'll validate your form, it'll reload the all of it.
I used a link_to_remote_redbox for this, which on clicking, fetches the form rendered by the new method call in a popup widnow. it submits to the create function and it is now working. actually i had previously made it work without ajax and i was having difficulty in making it work with ajax. the problem was solved once i made separate partials for ajax calls, and doing:
respond_to do |format|
format.js { render :template => 'detail/ajax_template'}
...
end
I provided different templates for both create and new method calls, used the :html => {:id => 'some-id'} in form and the :update => {:some-id} to replace the form with the message that it worked correctly.
So I didnt know that i needed separate templates for the different styles of forms, and that i needed to use the :update option to replace the form when i asked the above question.

Resources