I am new to rails and a little bit stuck with a challenge: I have a model with a "status" column, which can be 0 or 1. In index view, I want to put a direct link to change status from 0 to 1, this I can do. What I would like to do is ask a reason (text filed) for the status change, and send that text as a parameter to the corresponding action.
Can anyone point me in the right direction on how to do this?
Thanks!
You can use form_tag for the same, radio buttons for 0 or 1 and a text field for the reason
If I understand correctly, your question is "how to pass form data along with a link" ?
While you can't do this strictly in term of html implementation, there are several ways to make it look at if you do.
Styling a button like a link
Probably the easiest way would be to use a form, then style your button as a link. The advantage of that is that it won't need any javascript.
You first set up a form :
<%= form_tag my_action_path do %>
<%= text_field_tag :reason %>
<%= submit_tag 'Do it', class: 'submit' %>
<% end
Then, you style your input accordingly :
.submit { border: 0 none; background: none; text-decoration: underline; cursor: pointer; }
.submit:hover { text-decoration: none; }
See it running.
This implementation will fire a POST request, this is probably what you should use since the action implies user writing something rather than reading it (you can still pass method: :get if you prefer a GET request).
Add input data as query string
You can also hook click event on link and change url to include input's content. Provided the following html :
<%= text_field_tag :reason %>
<%= link_to 'do it', my_action_path %>
You could do this in javascript :
$('a').click(function(event){
event.preventDefault(); # prevent link to be followed
# compute an url adding the input content
var new_url = $(this).attr('url') + '&?reason=' + $('input').val();
# redirect user to that url
window.location.href = new_url;
});
I'm not very fond of this solution, because you may have url encoding / length problems, and adding inputs outside forms is not valid html. And if you add a form, well, you have to also handle it's submit event (since pressing the "return / enter" key in a text field will submit its form).
Use a form and submit it when clicking link
You can also use a regular form, then trigger its submit when clicking the link :
<%= form_tag my_action_path do %>
<%= text_field_tag :reason %>
<%= link_to 'Do it', my_action_path %>
<% end %>
Here, the javascript would be something like that :
$('a').click(function(event){
event.preventDefault(); # do not follow link
$('form').submit(); # submit form instead
});
Related
I see some issues similar but they seem contrived and mostly for previous versions of Rails.
What is the simplest way to submit a form with an anchor tag (link) instead of the normal button
<%= f.submit 'Search', :class => "button expand"%>
What is the most concise way (best practice) way to change that to a link that submits?
I often use js/jquery to submit forms. It's very useful if the submit button is outside of the form or if there is more than one button that submits the same form.
$(".submit-btn").click(function(event) {
event.preventDefault();
$("#form-id").submit();
});
The event.preventDefault(); prevents the default button/submit behaviour.
Here is a coffeescript example I have used in a rails 4 project:
ready = ->
if $("#form-id").length > 0
$(".submit-btn").click (event) ->
event.preventDefault()
$("#form-id").submit()
$(document).ready ready
$(document).on "page:load", ready
Also note, this way the link can be any type of element - not necessarily a submit button. You do not have to have the submit button inside the form, but if you do the preventDefault will prevent the default form submission behaviour.
Submit
To extend the answers provided already, HTML forms have to be submitted with a submit button.
I'm not sure exactly what special characteristics the submit button has over a link - it essentially calls the submit action, which a link cannot (info):
--
Link
This means if you wish to replace a submit button with a link, you'll essentially have to mimick the submit method in your application. This can be done with JS (JQuery):
#app/assets/javascripts/application.js
$(document).on("click", "#your_link", function(){
$("#form").submit();
});
#app/views/controller/your_view.html.erb
<%= form_tag your_path, id: "form" do %>
<%= link_to "Submit", your_path, id: "your_link" %>
<% end %>
This is so simple:
Then:
<%= f.submit '', :class => "hidden", :id => 'form_submit_button' %>
content_tag(:a, 'Submit', :name => 'submit', :id => 'submit_link')
and in JS:
$(document).ready(function() {
$(document).on("click","#submit_link",function() {
$('#form_submit_button').click();
});
});
I am not sure about exact sytax so there might be some syntax error. Feel free to ask for more help.
I'm trying to make a dynamic form, where the names of some forms at the bottom are based off the values of some forms at the top. For example...
At the top of the page there would be two dropdown menus. At the bottom of the page, there would be two radiobuttons. The name of the first radiobutton would have the name of the first dropdown menu choice, and the second radiobutton would have the name of the second dropdown menu choice.
This is what I have so far:
<%= simple_form_for(#game) do |f| %>
<%= f.error_notification %>
<center>
<div class="form-inputs">
<%= choices = options_for_select( Team.all.map { |team| team[:name] } ) %>
<p>Team 1:</p>
<%= f.select :first_team_name, choices %>
<p>Team 2:</p>
<%= f.select :second_team_name, choices %>
<p>Who you think will win</p>
<%= f.text_field :user_guess %>
</br>
<%= f.submit "Simulate!", class: "btn btn-large btn-primary"%>
</div>
</center>
<% end %>
The text field would be replaced by those radiobuttons instead of a text field.
How do I access the value of the dropdown menus before submitting the form?
For a more comprehensive answer, I'd recommend watching the railscasts episode on this topic, but you'd need a pro (read: paid) subscription.
Since you're not doing anything super complex, you could do it quick & dirty with some javascript:
$(function(){
$('select').change(function(){
html = ''
$('select').each(function(){
html += $(this).val() + '<input type="checkbox" name="game[user_guess]" val="' + $(this).val() +'"/>'
})
$('div.user_guess').html(html)
})
})
If you're pasting the code directly in, you'll need to add a div in your view as well:
<p>Who you think will win</p>
<div class="user_guess"></div>
Don't feel good building HTML with javascript? You can make the change() handler make an ajax call that will load server-generated HTML, which can be made with proper form helpers and such. But for such a simple task it seems like overkill.
(Also, be aware that if the team names can be user defined, this javascript may open you to script injection attacks, so sanitize as needed.)
note that if you want the form to change upon user interaction without the user actually having to submit the form before it changes (rebuilding the page and reloading the view), you have to use javascript. I think. There might be funky things you can do with CSS but that would be really obnoxious to implement.
I'm trying to submit a form using link_to as follows:
<%= form_for(#post, :url=> '/post/action', :method=> 'post', :html => {:id=>'form_id'} ) do |f| %>
....
<%= link_to 'submit', "/post/action", :onclick=>"document.getElementById('form_id').submit()" %>
....
but it is not posting the form, it is simply redirecting my form to the specified url. Does anyone know how to do this?
You can use:
<%= link_to 'submit', "#", :onclick => "$('#form_id').submit()" %>
if you are using JQuery and a later version of rails.
Above will work but if you have a really long page it will navigate to top of the page because of "#" so if you want to avoid that you can do:
<%= link_to 'submit', "", :onclick => "$('#form_id').submit()" %>
I think both things happen. The browser starts to submit the form, but it also follows the link's href. You can fix it by linking to # instead of /post/action...
...however, I don't recommend doing it. There are a few better approaches:
First, you can use a button instead of a link. You'll have to style it to make it look like a link, but that should not be a problem. It will be better, because it won't break the Principle of Least Surprise (people who read the code expect forms to be submitted with buttons) and you won't need the JavaScript.
If you insist on using a link, you should at least move the JavaScript code from the view to a JavaScript file. Then have this behavior added unobtrusively (although, you won't have a good fallback with the link). Assuming you're using jQuery, it should be as simple as:
$(document).on('click', '[data-submit-form]', function(e) {
e.preventDefault();
$(this).closest('form').submit()
}
I have a block -iterator to display a user and a related action to be displayed on the same line for every iteration ?
You can visualize like this :-
user1 update_attribute_button
user2 update_attribute_button.
...
and so on.
But if I use a button_to method the button is getting displayed on a newline. which I don't want.heres my code snippet:-
<% #post.bids.each do |bid| %>
<p>
<%= bid.user.email %>
<%= button_to "Offer Bid", offer_bid_post_bid_path(#post, bid), :action => "offer_bid">
</p>
<% end %>
But with the above code the 'email' and 'offer bid' are appearing in two lines, but i want to display them as pairs, with each pair appearing on one line.
I can achieve it using a 'link_to'.
If I use 'link_to' instead of 'button_to' I'm able to achieve my idea, but not able to do it with a button_to. Why is this difference between link_to and button_to.
I want to display the 'offer bid' as a button only.
Now, How to make the button_to buttin appear on the same line as the 'email'.
Please let me know if the question's description is not clear.
Thanks in advance.
A button_to generates a form and a div around the button. So, if you do not restrict the width of the container which is before the button, it will take 100% of the width pushing the button down.
<% #post.bids.each do |bid| %>
<p>
<div style="float: left; width: auto;"><%= bid.user.email %></div>
<%= button_to "Offer Bid", offer_bid_post_bid_path(#post, bid), :action => "offer_bid" %>
</p>
<% end %>
This is not to do with rails but rather how web browser's render forms.
A button_to is just a convenient way to create a form with a non-visible field. If you want the form on the same row as the email address you'll need to put it into a container, most usually a div, set the div to float left and overflow hidden.
button_to renders to a form tag, so I just altered the CSS to ensure the form tag doesn't create a new line.
But to apply it only to a specific form tag then give add form_class: "myButton" see below.
In your something.html.erb
<%= button_to "Offer Bid", offer_bid_post_bid_path(#post, bid), :action => "offer_bid", form_class: "myButton">
Put this in your application.css
myButton {
display: inline;
}
I have a simple form that looks like so
<% remote_form_for post, :url => post_path(post), :method => :put do |f| -%>
<%= f.submit "Approve" %>
<%= f.submit "Deny" %>
<% end -%>
Which renders
<input type="submit" value="Approve" name="commit"/>
<input type="submit" value="Deny" name="commit"/>
In my controller I have the following logic
#post.approved = params[:commit] == 'Approve' ? true : false
So problem is that if the user clicks the "Approve" button or the "Deny" button the parameter that is sent is that :commit => "Approve".
Does anybody know of a bug relating to this or another (simple) way to perform the same functionality?
Thanks.
JS lib (Prototype I guess) doesn't know what button was pressed. It just serializes the form field values for the Ajax request. When using normal form POST, browsers attach right value to the commit param.
You can add hidden form field (eg action). Then add JS code to set required value of the hidden field when appropriate button is pressed (and before the Ajax request is sent).
Another option is to override the "name" parameter of the second button.
<%= f.submit "Deny", :name => "commit_deny" %>
I think Submit is unique per form (HTML thing) so yopu have two options:
Use 2 forms whith 1 submit each, that lead to the same action (CSS it to you liking)
Use 2 button-type controls (i.e. not submits) and submit with both onClick events (javascript needed)