Ruby on Rails: load different partial with radio buttons - ruby

I want to load different partials with generated content into a form with ajax.
So how do i make this work?
For example, i have a form with the radio buttons "fruits" and "vegetablles", so when i select one of them, the corresponding partial should be loaded directly into the template dynamically with the right content.
Its a simple form created with scaffolding (edit, show, destroy)
should be prototype normally?

All you do is :
In your controller, you should have the following methods:
def fruits
#myfruit = Fruit.new # what you want!
respond_to do |format|
format.js
end
end
Then, you should have your fruit.js.erb corresponding to that action (suppose you have jQuery here) :
$("#fruits-holder").replaceWith('<%= escape_javascript(render #myfruit) %>');
You then need a partial view like _fruit.html.erb that contains the html you want
As Codeglot stated, if you want more precise answer, post more information about your problem. I cannot be more specific right now.

Related

Controller 'new' action with two pages, rendering the second page if fails to save

my def new action in my controller does two actions. The first action selects a customer, and then upon selecting we go to another page and add further information on this page.
my class name is content_text. In the first page I am trying to assign it a customer, and in the second page i am
When I am at the first page my url looks like
/site_content/new?source_content_text_id=20
When I get to the second page I have params in my url and it looks similar to
/new?utf8=✓&customer_id=2&source_content_text_id=20&commit=Set+Customer
My problem is, if there is an issue with my form, and my class won't save, I am rendering :new. But this takes me to the first page, and i'd like to get it so that it renders the second new page instead.
This is my controller action.
def create
#content_text.content_area = #source_content_text.content_area
if #content_text.save
redirect_to [#content_text], notice: 'Content Text was successfully created.'
else
render :new
end
end
When I try to sub the render :new with
render 'new?utf8=✓&customer_id=2&source_content_text_id=20&commit=Set+Customer'
I get a Missing template error.
Is it possible to do what I am hoping to do?

Rails form, load new record page rather than redirecting to it

I'm creating my first app in rails.
Basically, I have a new customer form, normally when you enter a new customer you are redirected to the record you created.
However as I am loading all my pages via ajax I want to load the new record in rather than re-direct to it.
I already have the form firing via ajax, I just need to know how I can access the new record URL to load it into my container.
Hope that makes sense. Thanks in advance!
You can add an option :remote => true to your form_for helper method, so that instead of page redirect the form gets posted via ajax.
For Ex :
<%= form_for(#post, :remote => true) do |f| %>
...
<% end %>
Then create a new template named create.js.erb which will get rendered after create method has been executed.
In this template, you can display the details of the new record you created.
For Ex :
$('some_element').replaceWith('<%=#posts.name %>');
Edit: You mentioned using load in your javascript. I would generally avoid this as you're making two round trips to the server. 1) Create 2) Get html to load into a div. Additionally, if there is an error that happens, it will be more difficult to catch and do the "good thing", whatever that might be.
Once you've added the remote: true option to your form, you need to deal with what happens on the server side of things.
Assuming your using REST, you'll have a controller with a create action in it. Normally, this method is creating the item and then subsequently returning the HTML for the create page. Instead of this, we need to create a javascript view for the action. This will tell the calling page what to when this action is hit.
Let's assume your form has a div called "new_record_form" and that you have another div called "new_records". You'll want to blank out the form elements in the form, effectively resetting it. You'll also want to add the new record to the "new_records" div.
To add the record to the new records div, you might do something like this.
$("#new_records").append("#{#new_record.name}");
When you submit the form, you should see this added. One great way to debug issues is to use the inspector. If you're in chrome, right click anywhere, inspect element and select network. Do this prior to form submission. You'll be able to see the ajax call and the response. Your logs will also be helpful.
Don't forget to blank out the form as well.
Note: You mentioned all your pages are ajax, but I highly suggest you evaluate if this makes 100% sense due to the various issues that result. Not saying this is the best article on the subject but might be worth a read.

Show taxons instead of products at root url?

just loosing ideas about proper way to display taxons instead of products in body of spree_application layout.
The spree/home/index.html.erb template renders spree/shared/_products but I would like to render spree/taxons/show instead, for each taxonomy.
No wonder, spree/home/index.html.erb miss taxonomies context so render :template => 'spree/taxons/show' would know nothing about #taxon .
Any idea how simply display taxons instead of products at the homepage, using spree/taxons/show view preferably ?
You should override the spree/home/index.html.erb template in your application's views directory if you want to override the content of this page. As for preparing the content, I would recommend writing a decorator for the HomeController and overriding the index action, like this:
class HomeController < Spree::StoreController
def index
# code goes here
end
end

Rails3: one controller many partials for form data submission

I am not sure if this is the best approach but I have a controller that originally I intended to control a show index that renders many partials on it (a header partial and then, has some if else magic to render different partials based on the step the user is in in filling out a form... a form has many sections across several pages). I think ultimately ajax is the way to go but I am not even to that point yet. I am not sure this is the right way to do it, so I guess that is what I am asking... is the many different partials to one controller the way ? or does each "page" of form data have to be broken out into its own controller? allowing the user to fill out form (check boxes, comment section) and click "next" passing the model of the data they are filling out along the way and saving that model in each next?
U may not need several controllers, but 1 controller with some actions may be a good start. =)
Then each action should load only the partial it needs. like u can give the action name to the partial, making easy to know which partial to render.
Or maybe u can try to use wicked.
There is a railscasts for it.
Well, you could use a method to decide which partial to render.
Use this example or do some meta programming.
class YourController < ApplicationController
def index
render :partial => partial_selector(param)
end
private
def partial_selector param
#logic to decide what partial do render
#returns the partial name
end
end

Need advice on using Grails and Ajax to append to a div like in Rails

I'm just starting out in Grails and need some advice on using Ajax. I want to append some html to the bottom of a div inside a form. This is basically what I have:
-form-
-div id="listOfchildren"-
childrow 1 input fields
childrow 2 input fields
childrow 3 input fields
-/div-
-form-
-a-Add Child 4-/a-
When I click on the "Add Child" I want to make an ajax call that results in a new childrow getting inserted into the "listOfchildren" div. So the document would look like this:
-form-
-div id="listOfchildren"-
childrow 1 input fields
childrow 2 input fields
childrow 3 input fields
childrow 4 input fields
-/div-
-form-
-a-Add Child 5-/a-
In Rails I would do something simple like this:
render :update do |page|
page.insert_html :bottom, "list_of_children", :partial => child_partial
page.replace "add_link", :partial => 'add_link'
end
The previous code sends an javascript back to the browser with two commands. The first command tells the browser to append some html to the bottom of a div. The second command updates the "add link" counter.
In grails I can only see how to replace an entire div (which would wipe out the user's existing input) and I don't see how I can call multiple functions from the ajax response. I can probably do this if I was to write some javascript functions in prototype or whatever, but I'd like to avoid that if there is a simpler way.
Thanks!
Nate
First, you need to add prototype.js to your header of the page, or if applicable to the header in your layout template:
<g:javascript library="prototype" />
Then instead of the a link use the remoteLink tag that comes with Grails:
<g:remoteLink action="ajaxyAddChild" update="listOfChildren">
Add Child 4
</g:remoteLink>
The remoteLink tag will default to go back to the controller that called the render for the page. So you just need to add a method called ajaxyAddChild, or whatever you want to call it, and have it do the business logic (better put into a Service) and output the HTML you want to render in that div - or render a GSP file for that div. The update= part of the remoteLink is the id of the element on the page to update.
There is a plugin for grails which allows you to do rails-esque render :update calls. This plugin will let you do exactly what your rails code did above. The plugin is called "dynamic javascript" and can be found at http://grails.org/Dynamic+Javascript+Plugin. It looks like the plugin doesn't have an out-of-the-box insert_html method, so using this plugin your render :update block would become (I haven't tested this so tell me if it doesn't work):
renderJavascript{
callFunction "$('list_of_children').insert", g.render(template: 'child_template')
replace 'add_link', [text:g.render(template:"add_link")]
}
However, I agree with mattS that it seems odd to make a call to the server to do this. Couldn't this be done client-side with javascript?

Resources