I have a view like this:
= simple_form_for #fixed_number, url: polymorphic_path([:manage, #numberable, :fixed_number]), method: :put do |f|
= f.input :number
= f.submit 'Ok', class: "btn btn-success"
= f.button :button, "Delete", class: "btn btn-danger", method: :delete
Obviously I want that Delete button to send the DELETE method. It doesn't work - it uses the PUT specified for the whole form. Can I have one form that changes method for a particular button?
I found a solution. I don't know if it's the best one. In particular it relies on UJS and CSS. I replaced the delete button with a styled link:
= link_to "Delete", f.options[:url], method: :delete, class: "btn btn-danger"
Related
In a Rails (5.2.4.2) app
I am using button_to + remote: true, and this is working as expected -> ajax call fired, all is OK.
But then I add 'params' to the button_to. Params are added to the form as hidden input (as expected) but when I click on the button, the request made is not remote, and all the page content is updated.
Problematic: button_to + remote + params -> this code seems to ignore the remote:true, although I see data-remote="true" in the form tag
<%= button_to ent_path(ent),
{remote: true,
method: :patch,
class:"btn btn-primary",
params: {ent: {active_a: false}}
} do
%>
<span>TEEEST</span>
<% end %>
Working as expected:
<%= button_to ent_path(ent),
{remote: true,
method: :patch,
class:"btn btn-primary",
} do
%>
<span>TEEEST</span>
<% end %>
So my purpose is to have the button_to remote and update the ent record, changing the active_a attribute depending on some logic
You want to pass any extra parameters via the link path, like this
<%= button_to ent_path(ent, active_a: false),
{remote: true,
method: :patch,
class:"btn btn-primary",
} do
%>
<span>TEEEST</span>
<% end %>
Turned out the remote:true was working properly. But there was a redirect_back in the controller that was executed in case of some custom logic, so that appeared as if the button is working without remote:true
I am currently working with button_tag to create a remote styled answer submission quiz. When pressing this button, instead of posting the new record, it is throwing an error.
ActiveRecord::RecordNotFound (Couldn't find Answer without an ID):
When looking at the server logs I see it is trying to work with these params when trying to post Parameters: {"{\"answer_id\":59}"=>nil, "id"=>"15"}
What I am looking, or expecting to see is this.
Parameters: {"answer_id"=>"59", "id"=>"15"}
Here is the button_tag I am using.
<% #question.answers.each do |answer| %>
<%= button_tag "#{answer.answer.titleize}", class: 'btn btn-block btn-lg btn-primary', data: {
remote: true,
method: :post,
url: answer_question_path(#question),
params: { answer_id: answer.id }
} %>
<% end %>
Here is my response controller which is responsible for submitting the POST request.
class ResponsesController < ApplicationController
def answer
question = Question.find(params[:id])
answer = question.answers.find(params[:answer_id])
response = question.responses.find_or_initialize_by(user: current_user)
if response.update(answer: answer)
head :ok
else
puts 'Something went wrong chief'
end
end
private
def responses_params
params.require(:response).permit(:user_id, :question_id, :answer_id)
end
end
I have tried using to_json on the parameter with no success and have not been able to find any solution elsewhere on SO or other forums. Any ideas?
This seems to be an issue with button_tag in the feature I am using it for.
button_tag creates a button element that defines a submit button, resetbutton or a generic button which can be used in JavaScript. button_tag is also an action view helper but is defined as a FormTagHelper.
button_to generates a form containing a single button that submits to the URL created by the set of options. button_to is a UrlHelper while button_tag is a ViewHelper.
Below is the button_tag code I was using which was creating the issue described above. Using button_tag fixed my parameters issue and also looks a bit cleaner. I hope this helps anybody else having issues with button_tag in the future.
<%= button_tag "#{answer.answer.titleize}", class: 'btn btn-block btn-lg btn-primary', data: {
remote: true,
method: :post,
url: answer_question_path(#question),
params: { answer_id: answer.id }
} %>
<%= button_to "#{answer.answer.titleize}",
answer_question_path(#question),
class: 'btn btn-block btn-lg btn-primary',
params: { answer_id: answer.id },
remote: true %>
In my view, using Slim:
= form_with url: update_pn_price_path(#price)
.form-group
= label_tag :part_number
= text_field_tag :part_number, #price.part_number, required: true
.form-group
=> submit_tag t(:save), class: 'btn btn-primary btn-sm'
= link_to 'Cancel', '', class: 'btn btn-link btn-sm', data: { cancel_in_place: true }
This always submits using a standard submit, not remotely. Log shows:
Processing by PricesController#update_pn as HTML
What am I doing wrong? Why won't it submit using JS?
I'm surprised to see that your view compiles. There are a few problems that I can spot.
You start indenting content as though it would be in the form. However you didn't open a form tag or provided a block to the form_with method.
= form_with url: update_pn_price_path(#price)
.form-group
Should at least be changed to:
= form_with url: update_pn_price_path(#price) do
.form-group
Since a variable is provided to a block, the preferred way is to capture it in a variable (form in the code below). If you're not planning to use it you should still capture it in an underscored variable to indicate that it is there, but not being used (_form).
= form_with url: update_pn_price_path(#price) do |form|
.form-group
Since you're using a form builder, the preferred way of creating elements is through the form builder interface. Since you're not creating the submit tag through the form builder this might be another reason why the submit isn't done remotely.
I would at least replace:
=> submit_tag t(:save), class: 'btn btn-primary btn-sm'
With:
= form.submit t('save'), class: 'btn btn-primary btn-sm'
But preferably update the whole form to use the form builder. The result should look something like this:
= form_with model: #price, url: update_pn_price_path(#price) do |form|
.form-group
= form.label :part_number
= form.text_field :part_number, required: true
.form-group
= form.submit t('save'), class: 'btn btn-primary btn-sm'
= link_to 'Cancel', '', class: 'btn btn-link btn-sm', data: {cancel_in_place: true}
For more/other form builder methods see the FormBuilder and FormHelper documentation.
Here's what solved the issue. Rookie mistake, but posting here in case someone else runs into it.
My form shown above was inside another form. You can submit such an 'inner' form, but not remotely. The form was being inserted via an AJAX call, so I changed that to insert to the end of the HTML body, and then positioned using CSS. That put it outside the containing form and made things work as expected.
<li class="li_spacing"><%= button_to "Website", #restaurant.website, :target => '_blank', :class => "btn btn-primary" %></li>
Everything works except for :target => '_blank'. Why does this not render the the link in a new page?
Change from button_to to a link_to:
<%= link_to "Website", #restaurant.website, target: "_blank" %>
button_to is generated inside a form, if you still wish to use it:
button_to "Website", #restaurant.website, class: 'btn btn-primary', form: {target: '_blank'}
A common way to open a link in a new window was to add a target="_blank" to the link tag.
But for security reasons this should not be done anymore. It is recommended to use rel=noreferrer instead:
link_to 'title', url, rel: 'noreferrer'
Or as a button:
button_to 'title', url, form: { rel: 'noreferrer' }
If you are using button_to helper then it is automatically wrapped in a form by rails. So what you can do is to pass the attribute target: '_blank' as:
button_to "Website", #restaurant.website, class: 'btn btn-primary', form: {target: '_blank'}
I wanted to edit my simple_form submit button, replacing the label by a glyphicon but couldn't do it.
Is there a nice way to perform this trick ?
Many thanks !
EDIT:
Haml code with working button :
= link_to [:admin, comment], method: :delete, data:{confirm: "are you sure ?"}, class: "btn btn-sm btn-danger" do
%i.glyphicon.glyphicon-trash
But it does't work with a submit button...
The good way to do it was to simply put a button input instead of a simple submit one, since a button in a from submits it.
= f.button :submit do
%i.glyphicon.glyphicon-user
Add user
It actually works.
It seems that simple_form is more strict on the form submit's code structure.
for rails 4.2+ and 'simple_form (~> 3.1.0) what worked for me was changing
<%= f.button :submit, class: 'btn btn-success' %>
to
<%= f.button :button, class: 'btn btn-success' do %>
<span class="glyphicon glyphicon-ok" aria-hidden="true></span> Update Form
<% end %>
by changing
the :submit to a :button
adding a span to introduction the glyphicon
add the text label, which was auto generated but now I need to supply it if I want any text