I have a Rails 3 application with simple navigation that contains links to controllers actions using link_to helper.
Now, I need to add a link which will refer to partial. Is it possible to combine the link_to and render: partial methods?
Generally, what I need is to combine somehow the following codes and have a link_to which is rendering the partial:
<%= link_to 'List', security_users_path , remote:true, class:'e-icon e-icon-camera' %>
<% #security_user = SecurityUser.new %>
<%= render partial: 'security_users/sign_in', :locals => {:security_user => #security_user} %>
If it is not possible, what other alternatives I have if I want to render a partial?
Related
I am creating blog application in rails. I have a common form for creating and updating blog.
This is view of edit and new.html.erb
<%= render :partial => "form"%>
This is view of _form.html.erb blog:
<%= form_for #blog do |f| %>
<%= f.text_field :title, :placeholder => "Title" %><br>
<%= f.cktext_area :article, :placeholder => "Content", :ckeditor => {:toolbar => "MyToolbar"} %>
<%= f.submit %>
<% end %>
My blog is creating successfully but I am getting error on update action. This is my edit and update action in blog controller:
def edit
#blog = Blog.find_by_slug(params[:id])
end
def update
#blog = Blog.find(params[:id]) || not_found
#blog.update_attributes(params[:blog])
redirect_to "/blogs/#{#blog.slug}"
end
When I open form from edit view, and click on update button, it throws error:
No route matches [PUT] "/blog/2"
My routes.rb is:
resources :blogs
get 'blog', to: 'blogs#index'
get '/blog/:id', to: 'blogs#show', as: 'blog'
I am not getting where it is going wrong. I tried to add "url: blogs_path" in form_for, it removes the error but doesn't save the edit changes.
Can anybody help me where I am going wrong here?
Thank you.
Okay. I dont understand why you want to go against conventions. Anyway, using form_for resource would automatically generate action URL as a PUT to /resources/:id if its an update operation.
So to override this you need to do two things.
update your routes to support this:
Add this line to your routes file:
put 'blog/:id' => 'blogs#update', :as => 'update_blog'
It is important that you put this line above your 'resources :blogs` call.
2 . specify the URL to which the form should submit:
You will need to create the form tag like this:
<%= form_for #blog, :url => update_blog_path(#blog) do |f| %>
Try this and let us know.
I'm using simple_form to render my forms and trying to get the following behavior: I want the client to choose from 3 options. In every option he supplies additional field or two.
So I'd like something like this:
Please set your preferences:
o Pay me on a specific day - [input field to get the day]
o Pay me a specific amount of money - [input field for the amount]
o Pay me on a regular basis - [radio buttons to choose between weekly/monthly basis]
I can create the radio buttons as follows, but can't add nested fields under them:
<%= simple_form_for #client, action: 'edit_payment_method' do |f| %>
<%= f.input :payment_type, label: 'Please set your preferences:',
collection: [ ['Pay me on a specific day', :specific_day],
['Pay me a specific amount of money', :specific_money],
['Pay me on a regular basis', :regular_basis]
], as: :radio_buttons %>
<%= f.button :submit, 'Submit' %>
<% end %>
What would be the best way to create the nested text boxes?
As for the fields, I don't need to send them to different controllers (per payment_type), it's fine if I send them all to one method and read the relevant values according to the payment type he chose.
Thanks! Zach
The simple_form collection_radio_buttons is likely what you want. Its options parameter accepts a block which allows you to customize what is rendered with each radio button. Take a look at the example in rdocs here.
Edited:
Here is basically what you need to do in a relatively generic way (hasn't been tested, but I'm running something similar). Put your additional controls in the partial for each radio button:
<% radio_buttons = [
{ :text => 'Pay me on a specific day', :value => :specific_day, :partial => "<textbox_partial_name>", :locals => { :any_locals => :your_partial_needs} },
{ :text => 'Pay me a specific amount of money', :value => :specific_money, :partial => "<textbox_partial_name>", :locals => { :any_locals => :your_partial_needs} },
{ :text => 'Pay me on a regular basis', :value => :regular_basis, :partial => "<radio_partial_name>", :locals => { :any_locals => :your_partial_needs} },
] %>
<%= simple_form_for #client, action: 'edit_payment_method' do |f| %>
<%= f.label t("account.update_payment_method.title") %>
<%= f.collection_radio_buttons :payment_type, (collection.collect do |r| [r[:text], r[:value], r[:partial].nil? ? "" : r[:partial], r[:locals].nil? ? {} : r[:locals]] end), :second, :first do |builder| %>
<%= builder.label{builder.radio_button(:class => 'payment_method_options') + builder.text} %>
<% unless builder.object[2].blank? %>
<%= render :partial => builder.object[2], :locals => builder.object[3] %>
<% end %>
<% end %>
<%= f.button :submit, 'Submit' %>
<% end %>
You can omit :partial for any radio button that doesn't need additional controls, along with :locals if your partial doesn't need it. There are also ways to simplify this code for your situation, but this example illustrates how to add more complex control structures to each radio button if needed.
OK.. I've managed to solve this somehow, not sure that it's the best alternative, but I'm posting it so if someone needs it in the future he at least has something to start with.
I went with creating a "regular" form using simpleform and then using JQuery to move the inner input fields (which were created regularly) next to the radio buttons.
Add JQuery support to your rails app:
add gem "jquery-rails" to your Gemfile
bundle install
rails generate jquery:install
The form I've used (regular simpleform):
Notice the class that is attached to the radio buttons and the ids that are attached to the input fields. I'll use it later to move the elements.
<%= simple_form_for #client, url: 'update_payment_data' do |f| %>
<%= f.input :payment_type, label: t('account.update_payment_method.title'),
input_html: { class: 'payment_method_options' },
collection: [ [t('account.update_payment_method.sum_based.title'), :amount],
[t('account.update_payment_method.days_in_month_based.title'), :days_in_month],
[t('account.update_payment_method.optout.title'), :optput]
], as: :radio_buttons %>
<%= f.input :payment_amount, label: "Payment amount threshold",
input_html: { id: 'payment_amount_box' } %>
<%= f.input :payment_days_in_month, label: "Payment days in month",
input_html: { id: 'payment_days_in_month_box' } %>
<%= f.button :submit, t('account.update_payment_method.update') %>
<% end %>
In the same page - the JQuery code:
<script>
$(document).ready(function() {
var amount_box = $("#payment_amount_box");
var amount_box_parent = amount_box.parent();
amount_box.detach().appendTo($(".payment_method_options:eq(0)").parent());
amount_box_parent.remove();
var dim_box = $("#payment_days_in_month_box");
var dim_box_parent = dim_box.parent();
dim_box.detach().appendTo($(".payment_method_options:eq(2)").parent());
dim_box_parent.remove();
});
</script>
I think it's pretty self-explanatory, it just looks for what is going to be the inner input fields (by id) and moves them into the appropriate place under the span that simpleform creates for each radio button.
I had to play a little bit with the css to make it look how I wanted (display:block for example), but that's more or less it.
Hope it helps.. Zach
What's the diference between:
<% content_for :something do %>
and
<% provide :something do %>
#provide works in almost the same manner as #content_for, save that #provide does not concatenate blocks. That is--and the following code is cribbed from the documentation--say you have these #content_fors, possibly in multiple templates but defined in this order:
<%Qcontent_for :navigation do %Q<
<li><%= link_to 'Home', :action => 'index' %></li>
<% end %>
<% content_for :navigation do %>
<li><%= link_to 'Login', :action => 'login' %></li>
<%Qend %>
Now, the following will render both navigation items in an un-ordered list, 'Home' first then 'Login':
<ul><%= content_for :navigation %></ul>
#provide will not concatenate and would have rendered a list with but one element.
Provide will send straight to the layout whereas ONCE content_for will allow addition information to be sent to the yield.
Use provide if you know you will only send once to the layout, use content_for if you will or may dynamically send more information.
It's actually a little more complex than that but the above is the shortened version.
Dave
Hey,
I'm working on a page having a nested layout. first I have the applicationlayout with my "mainmenu" now I want to add a second menu only on this page. I got this working via
<% render :partial => "mypartial", :layout => 'navigation' %>
this adds my second navigation to the form and renders a partial.
At this point I try to distinguish between two different partials. so my file looks like this
<% if :passed_text == "page1" %>
<%= render :partial => "mypartial1", :layout => 'navigation' %>
<% else %>
<%= render :partial => "mypartial2", :layout => 'navigation' %>
<% end %>
my navigation is as follows:
<%= link_to "Mypartial1", partial_path, :passed_text => :page1 %>
<%= link_to "Mypartial2", partial_path, :passed_text => :page2 %>
<%= yield %>
but it ignores my parameters. I guess I'm missing something basic, but all this is new to me.
thanks for your help
okay I found an answer:
first I have to check for:
params[:passed_text]
instead of :passed_text
secondly passing the parameters has to be in brackets
partial_path( :passed_text => :page1)
this works fine
I am using will_paginate in my rails 3 application.
In my Controller i have a line as
def index
#blogs = Blog.paginate(:per_page => 5, :page => params[page])
end
And in my index.html.erb
<div>
<% if #blogs.size.zero? %>
No Blogs Found
<% else %>
<%= render #blogs if #blogs %>
<% end %>
</div>
<%= will_paginate #blogs%>
And in my partial _blog.html.erb
<% #blogs.each do |blog| %>
<%= link_to blog.title, blog_path(blog.id)%>
<% end %>
When i run the app by $rails s
The partial displays the contents per_page times..
For the first page it displays for 5 times ..
How to avoid so ..
Give me some suggestions...
EDIT
I changed the partial code in _blog.html.erb to
<%= link_to blog.title, blog_path(blog.id)%>
which is the right one as already by default rails 3 will send the collection #blogs to the partial noneed for the loop in the partials ..
When render is passed a collection, it automatically renders the partial multiple times.
Therefore you want your partial _blog.html.erb to just be:
<%= link_to blog.title, blog_path(blog.id)%>
You don't need an each statement there because the render statement takes care of this.
See 3.4.5 "Rendering Collections" in http://guides.rubyonrails.org/layouts_and_rendering.html