Use data-disabled-with on a non form submit button - ruby-on-rails

Rails provides data-disabled-with for button tags on form submits. Super awesome. However, link tags don't get this desired behavior. They're great to prevent users from clicking a button too many times and producing an unwarranted effect.
Is there a way I can do something like:
Purchase me

Rails provides this functionality via the :disable_with parameter of the link_to helper. See docs.
For example:
link_to("Create", create_post_path(#post), remote: true, disable_with: "Creating...")
Recognizing of course that creating a resource via a GET request isn't idiomatic Rails/REST... but this hopefully illustrates how it could be used.

Related

post without changing page?

I'm thinking AJAX is probably the most logical route to my answer, but I can't find a way to use an AJAX post without making my routing convention useless. As far as I have been able to tell, using
<%= form_for(#post) do |f| %>
you can not give the form_for helper an ID- at least, not with 'do |f|' in there. If I'm understanding this line of code correctly..
$("#test").ajaxForm({url: '/posts', type: 'post'})
Then I would need to give my form tag an ID. If that is true, I could get around that by doing
<form id="test">
But then not only would I have to rename all my helpers, I would have to edit my controller to parse the data posted by the form. Given the size of my project, that could take a week... and it cuts the potential for scale to an extent.
A synopsis for why I'm doing this-
I have a form that is technically an "edit" page, but it is more of a mix of show, edit, and new. There is a mix of info from last month's work, edit boxes for last month's work, and new boxes for this month's. There are four main "blocks" to the page, and each has a separate set of information which may or may not be stored in a separate database table, which may or may not be related to any of the other tables.
It is important for employees to be able to post updates on a regular basis- every few seconds or so. However, this kills system resources as each time they post, it re-loads the entire page. I have code bashed out to use AJAX to refresh specific blocks upon button click, but it does me no good if the entire page automatically re-freshes after the post anyway. Is there a way to either disable the reload in the update action, or to post in a different manner using AJAX so that the page does not refresh/redirect?
Using rails 3.0.20
Using ruby 1.8.7 (2012-10-12 patchlevel 371)
Using Ubuntu 12.04 LTS
I would look at the form_for docs (http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for).
The quick answer is you need to add remote: true to your form_for.

Haml: link_to vs button_to

From what I understand, link_to is used for get methods, and button_to is used for post methods.
On the other hand, I was told that with HTML5 semantics, <button> is used for any type of clickable...well, button. In the case I have a clickable button that sends a user to a form to fill out, should I create a button_to or a link_to?
It's simpler that you think.
That methods are Rails helpers and don't have anything to do with haml.
Yes, one method is for get and another for post methods. If you need to post any data to controller, use button_to (for example when deleting a record). Otherwise, link_to is enough.
Moreover, you can make link_to posting data using :method parameter:
= link_to "Something", some_path, :method => :post
Answering your question, use link_to.
The main principle difference between the #link_to, and #button_to is that the #link_to just creates a link tag A, and makes simple AJAX request without an additional data, while #button_to creates a FORM with a custom data, so the form can be used to make extended AJAX request to a webserver. The form data includes embedded CSRF-token, which is used to authentication the request. In case of #link_to CSRF-token must be serualized and send in on_click event.
You should use links to point the user to a resource, like an article.
But you have to tend to use buttons to point to an action(like "Create"/"Send" on your edit page). If this doesn't agree with your interface -- style them like as a link.
Here's why: you cannot point your user to any non-GET action via link_to if he lacks the javascript support. So, buttons are the only options to make your send/destroy action to be triggered in this case.
Feel free to use both approaches if your link points to a page that eventually leads to a modification of a resource (link/button to an edit/create page that shows a form), like in your case.
If you want to simply send a user to somewhere, it is get request. So you should use link_to in this case. By the way, you can use the link_to for post requests and other requests (like button_to too) if you will specify :method. For example: =link_to "some path", some_path, :method => :get

How Does Rails 3's "data-method='delete'" Degrade Gracefully?

Rails 3 does some cool stuff to make Javascript unobtrusive, so they've done things like this:
= link_to "Logout", user_session_path, :method => :delete
..converts to
Logout
But it just occurred to me.. When I turn off javascript the method isn't DELETE anymore, it's GET as expected. So are there plans to, or is there some way to, allow these data- attributes to degrade gracefully, so that link still is a DELETE request?
The change they made in Rails 3 with these data- attributes wasn't about graceful degradation, it was about unobtrusive JavaScript.
In Rails 2, specifying :method => :delete on a link would generate a whole bunch of inline JavaScript that would create a form with a hidden input and then submit the form. That was the same as it is now: turn off JavaScript and it defaults to a GET request. As such, supporting the case of no JavaScript is the same as it was before.
One option is to use a form/button instead of a link so you can include the method as a hidden field, much like the Rails 2 JavaScript does. Another option is to have the GET version take you to an intermediate page which in turn has the form/button.
The benefit of the new approach is that it's unobtrusive. The JavaScript for changing the HTTP verb exists in an external file and uses the data- attributes to determine which elements it should be attached to.
Rather than using the link_to method -- which would require you use JavaScript to ensure that the HTTP method is DELETE -- use the button_to method, which will create a form with a hidden input element which tells Rails to treat the HTTP method as DELETE rather than POST. If necessary, you can then use CSS to style the button in the form so that it looks like a link.
The only chance you have is define a form. A link can't be a POST with _method="delete" without Javascript or by form.
It is not possible without javascript.
I make a small jQuery plugin for converting data-method link attribute to pseudo hidden forms (used in laravel project for example).
If you want to use it : https://github.com/Ifnot/RestfulizerJs

How to create one form with many possible actions in Rails?

I want to create one form with 2 buttons in rails. Both forms operate on the same data in different ways, and I would prefer to keep the associated functionality in two different methods. Previously I've redirected to the appropriate method after doing a string comparision on params[:commit], but my gut says there's a better approach. Suggestions?
Two different submit buttons that send the form to two different actions:
<%= submit_tag('Insert', :onclick=>"document.myForm.action = 'insert';") %>
<%= submit_tag('Update', :onclick=>"document.myForm.action = 'update';") %>
Instead of "myForm" you need to put whatever is in the "name" property of your tag.
You can set that property in your default form:for tag like this:
<%= form_for(#something, :html => {:name => "myForm"}) do |f| %>
Without using JavaScript, your only solution is what you mention: checking which button was clicked by looking at the POST data in the controller. This is simply due to the nature of the HTML form element. It cannot have more than one value for its action attribute.
If you're not worried about what will happen when JavaScript isn't available, then you can write some script to change the action attribute when one of the submit buttons is clicked, prior to actually submitting the form. In the case of an ajax request, it could simply submit to the correct URL directly without altering attributes on the form.
I also used the params[:commit] method on a form already. Using the I18n helpers makes this a bit less fragile as you can use the same lookup in the view and controller, so you don't encounter the problem that the string changes a bit.
Besides that I can only think of using JavaScript to handle the clicks on the buttons and then send the form data to different Rails actions (Maybe you can change the HTML action attribute of the form with JavaScript before you submit the form).
If you're using prototype.js, you can use Form.serialize() to grab your data from your form and from there use the different buttons to post to different actions.

can link_to lead to rendering sth?

i want to render a partial within a view. so that when button MORE is clicked everything stays the same just additional characters are shown. in my case the whole article.
<%= #article1.content[0..300] + "..." %>
<%= link_to "more", ....... %>
i dont know what the right methot would be. somehow i have to explain to rails that when button more is clicked it shows me the whole article. maybe i shouldn't use method link_to ..
thank you in advance for your replys
What you're looking for is link_to_remote or link_to_function.
link_to_remote will be fetching the rest of the article from your controller and replacing/appending to a DOM element with a partial via RJS. This allows you to minimize unnecessary data being sent, and facilitates handling users that have javascript disabled.
With link_to_function, the entire article will be served when the page is loaded, but the everything beyond the first 300 characters will be hidden by CSS. This is easier to set up but sends a lot more data, it also relies on the user having javascript enabled.
Without looking at the source the average user probably couldn't distinguish between the two methods.
Which choice you go with is up to you. Sorry, I haven't got time to provide code examples, but the internet is full of them.
try link_to_function, use truncate for part and insert hidden tag with full text, switch them using javascript in link_to_function

Resources