How to send extra parameters on a link/button_to_remote call? - ruby-on-rails

Prototype's Ajax accepts a parameter called 'parameters' with an hash array for parameters (prototype doc) which would automatically be sent as GET or POST vars, but I could not find how to add items to that array using the Rails button_to_remote method.
I could just add the parameters to the URL sent to the method, but that feels hackish.. Is there a better solution out there?

I actually found the solution! You can pass parameters in the function using the :with option, like this:
<%=button_to_remote "+3", {:url =>task_path(#project, #story, task), :with=>"'actual=3'"}%>
The trick is that the value for :with is a javascript expression that should return a key-value pair in the URL format, like "key=value". That's why there's extra quotes around the value on the same above.
A function could also be used to pull the information from the page, if necessary:
:with=>"getValuesForPostbackFunction()"
The function will be evaluated before the form is submitted.

Using button_to_remote the only way to send parameters to the next action is putting them into the URI.
button_to_remote is intended as a functional equivalent of link_to_remote, which also has no other way of adding parameters.
If you need more fine-grained control, you need to build the full form and submit that to your action.

Add hidden input fields in the form that you're calling the button_to_remote on.
<input type="hidden" name="name" value="myValue">

Related

Query Parameters in URL from a Rails form

I have a filter sidebar that starts with a Rails form_tag and contains a range slider and a bunch of check_box_tag.
It posts and filters fine. It even persists on the next page as I render it with the checkbox values.
However, if you refresh the page, or send a link to someone, the filters are lost.
The only way I've seen how to do it is to use redirect_to and merge the params, but I'd rather not make a second call.
How can I pass all the options as query params?
As you're not creating anything I would recommend using GET requests with query string parameters. So the query can be shared with the url.
Url for your example image would be something like:
http://www.yourwebsite.com/?max_price=5
Which gives you a params[:max_price] in controller.

Passing html object properties into embedded ruby code

How can I pass html object properties into embedded ruby code in an html.erb file?
Lets say I have a ruby method A that accepts a string parameter(and also the return value of A is string). I think of scenarios like the following:
<input type="text" id="t" value="Leaves">
<%= A(document.getElementById("t").value) %>
Obviously I can't write code that way.
I want to pass the value/text of the textbox into method A and print A's return value into the html body. How can I do that?
Also, if I want to continuously check the value of the textbox and append A's return value(when passed the current value of the textbox to A) to the body of the document, what should I do? And if I instead wanted to set some paragraph p's text to this return value, what should I have done?
You can use a HTML parser like Nokogiri.
frag = Nokogiri::HTML.fragment('<input type="text" id="t" value="Leaves">')
frag.at_css('#t').attr('value')
But it seems like a rather silly and overcomplicated solution to something that most likely can be solved by not using HTML strings to pass around data in your views / helpers in the first place.

Form_tag url_for_options nil action to the controller itself

My case is that i have more controllers with sharing one view and i'm trying to change dinamycally the action on a form passing a variable defined in the controller
Trying some solution i've observed that if i have a nil variable in url_for_options form_tab variable, the form in the view has the right controller path from where the view was called
<%= form_tag nil, :method => :get, :class => 'search' do %>
is it a bug or a feature?
Note that if you pass an empty string, instead of nil, you get a slightly different behavior:
form_tag nil
creates
<form action="(URL based on current controller and action)">....
While
form_tag ""
creates
<form action>....
If the URL of the page you're on is, say, "/foo/bar" (for FooController#bar), then the two are functionally equivalent.
If the URL of the current page is "/foo/bar?a=1&b=2", the former will continue to point at just "/foo/bar", while the latter will result in a form that submits to the full URL (querystring included). This is because the HTML standard (no action or empty action = use current URL, including querystring) is used by the latter. Instead the former triggers a Rails standard (nil for url_for => use current controller and method).
Just thought it's worth mentioning as there are cases where the HTML standard for an action-less form is more useful (ie. where you want querystring parameters to be sticky), and the subtle difference in behavior between nil and "" is easy to miss.
The solution is using an empty action attribute on a form to submit that form to the current page. and is described on RFC 2396
4.2. Same-document References
A URI reference that does not contain a URI is a reference to the
current document. In other words, an empty URI reference within a
document is interpreted as a reference to the start of that document,
and a reference containing only a fragment identifier is a reference
to the identified fragment of that document. Traversal of such a
reference should not result in an additional retrieval action.
However, if the URI reference occurs in a context that is always
intended to result in a new request, as in the case of HTML's FORM
element, then an empty URI reference represents the base URI of the
current document and should be replaced by that URI when transformed
into a request.
A strange behaviour when
url_for_options == nil
<form accept-charset="UTF-8" action="/welcome" class="search" method="get">
url_for_options == ""
<form accept-charset="UTF-8" action class="search" method="get">
It is not a bug. If you don't provide any action to 'form_tag' or 'form_for', By default it will be posted to same controller where view is called from.

Multi-step form using GET requests

We have the unusual requirement of a multi-step form through GET requests. So, instead of POSTing the forms, we're using GET requests to pass new parameters to the query. So, the basic idea is that there's a treatment, and a date passed to the query. A three-step form if you will.
Show available treatments, pick one
Show available dates (there's business logic in the background that figures these out)
Pick a time
The URL will go through the following states
site.com/bookings/new
site.com/bookings/new/[id|name_of_treatment] (by this, I mean it could either by the ID field or the name of the the treatment)
site.com/bookings/new/[id|name_of_treatment]/2010-12-12/
So, my route looks like this:
map.connect 'bookings/new/:massage_type/:date', :controller => :bookings, :action => :new
massage_type is synonymous with the treatment_id.
So my form_tag looks like this:
<% form_tag( {:action => "new"}, :method => "get" ) do %>
The problem I'm having is that I want it to just give me back the URL site.com/bookings/new/[id|name_of_treatment]/ but instead it gives back the following URL:
http://localhost:3000/bookings/new?massage_type[treatment_id]=1&commit=actionnew
I don't suppose anyone knows?
Forms that use GET are adding the input values as query parameters. There's no way to make the form post to a different URL, where the input values are part of the URL instead - it's just not supported by the HTML standard.
You could use URL rewrite to remap the incoming URLs of this type to the one you want, however that's not really a good solution, because this would result in a second request.
However, what I don't understand is why does the form need to do GET to that specific URL. Is it a requirement that these URLs can be constructed by the user manually, instead of using the form?
If there is no such requirement, I would advise to use standard POST form to http://localhost:3000/bookings/new and modify the form in the response based on the parameters in the POST body, as necessary.
Better yet, write some Ajax that would update the form according to the user's choice, without making a full form submit, until the user has finished all the choices.
By definition, the result of a GET request will have a query string (?param1=value1&param2=value2&...) in its URL. To get rid of those, you'll have to either start using POST or immediately redirect to the desired URL upon receiving a GET request.
I rather like the redirect approach because it doesn't show that confusing/annoying message about resubmitting POST data when the user refreshes their browser.

ASP.NET MVC - Html.BeginForm(). Can I post back to a different route and keep existing querystring values?

I have a post-only action that has a different route. In my form, I need to post to it, but also keep the querystring values I currently have.
Initial response: /my/first/path/?val1=hello
Needs to post to: /my/other/path/?val1=hello
It seems when I specify a route, it of course only returns the route and doesn't append the querystring values of my original page (for obvious reasons).
Is it possible to cleanly append querystring values to my the action attribute of the form tag? Thanks.
Not exactly what you are asking, but I was very happy by doing:
html.BeginForm(
c => c.SomeAction(model.SomeValue, model.OtherValue, anyDefaultValueIWant)
)
That uses hidden fields instead. I don't see why you specifically need it to be in the query string.
You're trying to POST and GET at the same time. If you want that you work, you'll need to input val1 as a hidden value. POST requests don't have query strings.
<input type="hidden" name="val1" value="hello"/>
You can't post and retain querystring values.
If you need to retain the querystring values when you post I would suggest populating them in hidden fields within your form.

Resources