post without changing page? - ruby-on-rails

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.

Related

Rails 5 after submitting form / action stay on exactly the same spot on page

I have this webshop, and on one page you see
products;
with a submitting form for a booking;
your order with its bookings;
with a removing link for a booking;
and an updating form for a booking.
Both the order.bookings and the products make potentially long lists on a html page.
The whole booking works by only a booking_controller.
What the booking_controller does:
Takings in the (new) params of a single booking or the destroy action.
Saves the new order.
Redirects to the store.
Works fine, just using ruby and html.erb.
Only problem, and this really needs to change, is that obviously after each redirect the browser goes to the top of the page. The browser isn't focussed. Or better to say, the browser should remain, but doesn't.
I get that your doing all these things on the server-side, so a page reload, or better to say, data-refresh, is necessary. What I don't want is building this whole thing again on the client-side (JS).
Can't I simply say something like: after data refresh redirect to exact same spot on page. Ignoring all the difficulties an asynchronous request would give, or am I exaggerating and is a little JS easy?
With Rails, using ajax is very easy however if you're not familiar with ajax at all it can be a bit daunting at first. Luckily there are many tutorials on the subject. Basically, add the remote: true option to your form_for statement and rails will automatically understand you want it to make a 'POST' request in JS format. It's important to realize that the incoming HTTP request is in JS format because you'll then need to specify handling that event in the controller. Such as:
def create
#Do whatever saving and processing you need here
respond_to do |format|
format.html { redirect_to some_path_here }
format.js { } #By not adding anything in the brackets here, you're telling rails to fetch a js view file that follows standard rails convention and so it should be named 'create.js.erb'
end
Then in your controller's views folder create the view file create.js.erb. In that file you'll want to refresh whatever part of the page needs updating which usually involves hiding the old div that was there and appending a partial in its place. I usually leave an empty div with an ID on the page (in this case your new_whatever_page.html.erb that I then call in the js.erb file to append a partial to:
In your create.js.erb add:
$("#the-id-of-the-div-in-your-new-view-page").html("<%= escape_javascript(render 'order_table') %> #This basically says, find the div on the current page with a matching id and then append the partial named _order_table.html.erb to it.
Now just make a partial named
_order_table.html.erb
in the same views folder and put whatever content you want to insert or update.

Advice on handling frontend User Inputs

I've been working with Ruby & RoR for a few weeks now and must say, this is a beautiful language, it's been very enjoyable to work with.
I'm hoping someone can point me in the right direction for an article that explains collecting user inputs on the frontend, everything I've found so far has been confusing.
Basically, I want to create an input field in a front end view that passes the result to my controller so I can feed it to an API wrapper.
In irb I can do this, but I don't understand the equivalent for a view that's accessible on the front end.
customeremail = gets.chomp
ticketfind = Desk.customers(:email => customeremail)
I don't necessarily need to store the data in a database, I'd almost rather prefer not to. Basically just need the input to pass off to the API, so I can redirect to a form which I'll submit to the API. I'm certain I can figure it out with some good links, I just don't think I'm googling the right thing.
Thanks for reading!
What you want is a simple form on your view...
<%= form_tag "/my_controller/my_action" do %>
<%= text_field_tag ":customer_email" %>
<%= submit_tag "Save" %>
<% end %>
This site explains about form_tag
http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html
And in your my_controller your my_action method...
def my_action
ticketfind = Desk.customers(:email => params[:customer_email])
Unlike Josh I prefer to use form helpers, but there's always more than one way to do it.
When forms are submitted in HTML they create a POST request to the server based on the URL you pointed the form to. The server picks up the POST request and maps it to the controller via your route map.
Ex:
<!-- This will POST form data to localhost:3000/users/create -->
<form action='users/create'>
<input type='text'/>
<input type='submit'/>
</form>
This should ping your server and route to UsersController#create. Rails stashes the form data in params
http://www.w3schools.com/tags/att_form_action.asp
I would recommend that you learn to do this without ERB first. Create a form with raw HTML so you can start to learn what's going on. You can use an ERB template, but only embed the variables in Ruby (e.g. don't use form helpers). You can then refactor to that (I personally prefer raw HTML over ERB heleprs). If you use Chrome or FF, you can open up the developer console and watch how the network requests work when you submit the form (I forget if this clears with each refresh or not, so you might not actually be able to do this in this example, but it's helpful in AJAX flows)

How do you handle widgets in rails?

StackOverflow, for example, has a user's reputation displayed up top. Clearly, this is grabbed from the database, and it's displayed on every page. Of course, this isn't in every controller action on every page, because that would be incredibly redundant.
How do you handle this kind of situation in rails? The only way I can think of it is to use before_filters to pass the models into the page, but that just seems like abuse of that feature. There seems to be the cells gem that does what I want, but I'd imagine this is a common problem and there must be a simple solution for it in rails without having to resort to plugins or gems.
What you are looking for is the layout. In rails this is where you define headers, footers, and sidebars that frame your site. Look for app/views/layouts/application.html.erb in your generated rails code. Towards the bottom you will see:
<body>
<%= yield %>
</body>
The yield is where rest of the app gets invoked. Everything before and after the yield will appear on every page. So, using your example, you might query the database and set the instance variable #reputation in the application controller:
#reputation = User.find( current_user ).reputation
then display it in the layout like this:
<body>
<%= #reputation %>
<%= yield %>
</body>
This is covered thoroughly in the book "Agile Web Development With Rails". If you are going to develop in Rails I recommend getting the latest edition.
I would just make a partial with the widget in it and render it in the layout(s) where you want it to appear. Let it do whatever it needs to do, eg connect to the db, run some js to connect to an external site, etc.
If you're concerned about optimisation then deal with it when it becomes a problem.
I guess, you can put the code you need into a view helper. And then render some partial, like it was said before, in the layouts where you want it to appear, calling helper's function.
Look here:
Rails view helpers in helper file

Ruby on Rails registration data?

I am trying to build a registration page, with two steps.
The first step displays a form with name, email, pass.
The second step will display a ReCaptcha.
The problem is how do I store the form data and display a new form with a captcha?
I was thinking sessions, but I know you're not supposed to store sensitive information in sessions.
I was thinking of using Ajax to render the ReCaptcha if the name, email, pass.. pass validations.
Any advice? Thank you.
My advice is that I think that two forms for a situation like this is unnecessarily complicated unless there is some application specific imperative to decouple the username/password capture and the CAPTCHA check.
You're probably right to be concerned about using the session to store the intermediate data but if you do want to go that way there's a great screencast showing the technique for a similar application here.
Personally I would go the Javascript route. Load both forms at the same time, step 1 being visible and and step 2 being hidden. Validate step 1 with an AJAX call to the server (if you need that) or client-side if you don't. If step 1 is valid then unhide the step 2 form (and optionally hide the step 1 form if you like).
UPDATE: Adding further info at questioner's request
There are lots of ways to hide and show page content but a common approach is to wrap it in a <div> block marked hidden using CSS and then use some Javascript (e.g. JQuery) to toggle it hidden or unhidden. Like this:
<div id="step2" style="display:none">
<% form_for .... %>
<% end %>
</div>
When the page is loaded for the first time the form will be hidden. Then in JQuery (for example) do:
$(function() {
$('#step2').show();
});
to unhide it. See the documentation for show, hide and toggle for more usage examples.
If you need something simple, you can retain the parameters in the second step using hidden fields.
If you need something more complicated (multiple steps, comming back to previous step, partial validations, etc) you may use a wizard plugin. Here is a list of wizard plugins from Ruby Toolbox.
There are lots of ways of doing this.
railscast #217, demostrates a generic way of dealing with multistep forms, capable of handling tricky things like going forwards and backwards multiple times. Give it a look.

Agile web development with rails - Ajax

i m using rails 2.3.3 and web browser Firefox i have added ajax and java script and it is working too but i have to reload the page every time when i press Add to Cart button to show item additionn in the side bar it don’t show it without reloading.
anyone please help me how can it show item addition in side bar when i press Add to Cart button with out reloading the page?
If you haven't already done so, install Firebug for Firefox, for these reasons:
it'll tell you if you have a Javascript error.
it'll show you if your Ajax request is being received and its contents.
you can inspect your page elements such as the cart to see if it's set to be shown, if the ID is correct, etc. in a much faster way than browsing through the source.
and more (CSS, etc).
If you can't figure it out by looking at the Firebug console, and since you're following a tutorial, why don't you download the Depot source code and compare it with your own to see what you're doing wrong.
If you have the book, the complete source is listed at the end of the book. You can also download the source from here.
The standard ajax helper methods are link_to_remote, form_remote_tag, form_remote_for, button_for_remote. (I might have missed a few.) If you're not using one of them, you could be doing something wrong.
If you're using one of the helper methods with remote as part of the name, you might be missing the update option or the update option is pointed to the wrong html element.
For a form_remote_tag helper:
form_remote_tag(:url => {:controller => controller_name, :action => action_name, :id => id},
:update => element_to_update)
The element_to_update should be the html element's id that you're updating.

Resources