Rails: submit Ajax form via anchor click - ruby

I'm porting an existing app to rails that makes extensive use of stylized anchors for form submission:
<a class="lozenge-button h25 blue" href="#">
<span class="left"></span>
<span class="center">Send</span>
<span class="right"></span>
</a>
However in Rails these anchors won't work for Ajax form submission, since Rails' UJS seems to require an input tag rather than an anchor (i.e. submit_tag("Submit", remote: true)).
Is there a way to make my anchors fire the Ajax form submission? I managed to get the anchor to submit the form with the following:
$('#my_anchor').click(function() { $(this).closest('form').submit();});
... but it bypasses Ajax and does a normal form submit that reloads the page.

I ended up solving it in a way very similar to this question:
<%= f.submit id: 'hidden_submit_button', style: 'display: none;' %>
<a class="lozenge-button h25 blue" href="#" onclick="$('#hidden_submit_button').click(); return false;">
<span class="left"></span>
<span class="center">Send</span>
<span class="right"></span>
</a>

You can try this
var form = $(this).closest('form');
$.post(form.attr('action'), form.serialize());

In Rails, you add remote:true to your link helper method. Then rails_ujs, (Rails unobtrusive javascript) takes care of sending it via ajax. See The Rails Ajax Guide so your code would become (in ERB)
<%= link_to the_rails_path,remote:true,class:"lozenge-button h25 blue" do %>
<span>etc</span>
<span>etc</span>
<%end%>

Related

making rails submit form_with through AJAX on keypress

I'm trying to build a kind of calculator with rails 5.2.
I need to update results fields while I'm writing my input fields. Everything is working perfect with AJAX if I press enter Key on my keyboard but it doesn't work if I try to automaticly submit the form as soon as a field is modified.
the view input.html.erb
<%= form_with url: achatproprietaire_output_path do |form| %>
<div class="form-group mb-3">
<%= form.label :credits_conso, "Montant des crédits conso", for:"example-helping" %>
<%= form.text_field :credits_conso, id: "example-helping", placeholder: "crédits conso", class: "form-control", id: "crédit_conso" %>
<span class="help-block"><small>en euros par mois</small></span>
</div>
js file calles un application.js
$(document).ready(function(){
$("#crédit_conso").keypress(function(){
//this.form.trigger('submit.rails');
Rails.fire(form, 'submit');
});
});
js.erb file correctly called with enter key
$('#output_col').replaceWith("<%= j render 'output', capacité_emprunt_maximal: #capacité_emprunt_maximal,
montant_mensuel_maximal: #montant_mensuel_maximal,
taux_interet: #taux_interet,
taux_assurance: #taux_assurance %>");
And I have no render or redirect_to in my controller.
I've also tried to put onchange: "Rails.fire(this.form, 'submit')" in the form fields but it submit the form without AJAX.

Using page.at with CSS selector in Mechanize

I am trying to scrape a webpage with Mechanize, with the following structure:
<div id="searchResultsBox">
<div class="listings-wrap">
<div class="listings-header">
<div class="listing-cat">Category</div>
<div class="listing-name">Name</div>
</div>
<ul class="listings">
<li class="listing">
<a href="/ShowRatings.jsp?tid=1143052">
<span class="listing-cat">
<span class="icon"></span>
TEXT
</span>
<span class="listing-name">
<span class="main">TEXT</span>
<span class="sub">TEXT</span>
</span>
</a>
</li>
...
I want to navigate to the page behind the <a> HTML element. Right now, I have:
agent = Mechanize.new
page = agent.get("URL")
page = page.at('#searchResultsBox > div.listings-wrap > ul > li:nth-child(1) > a')
but it keeps returning NIL (verified by puts page.class).
I also tried using sleep to try to ensure that pages have time to load before continuing.
Is there anything I am doing wrong? I thought using the CSS selector would do the trick.
Maybe the website content is loaded dynamically, by JavaScript.
Inspect the content of your page variable and see if the content there is complete or not.
If the content is incomplete, it means that there has to be some other requests, to the serwer returning that data. You can search for them opening Chrome DevTools (or other tool). In the tab "Network" you will see all requests made by website. Search for the one containing data that you need and then scrape it by Mechanize.

Sinatra redirect to show params

Im building a simple practice Sinatra app which allows users to enter urls via a form, and once submitted the app will open each of these urls in a new table (similar to urlopener.com)
My app.rb file
require 'sinatra'
get '/' do
erb :'index.html'
end
post '/' do
urls = params[:urls]
end
My View file
<h1>Enter URLs Below </h1>
<form action="/" method="post">
<textarea rows="40" cols="50" id="urls" name="urls" ></textarea>
<br/>
<input type= "submit" value="Open 'em up!">
</form>
I am able to print the urls to the console in the post action, but am unsure how to redirect back to the index, and display each of the urls before opening them in new tabs (which I plan on using JS to do).
You don't have to redirect back to the original page (in fact, the URL hasn't changed, so redirecting doesn't make sense). Instead, you render the same template. Simply insert erb :'index.html' in the second block (post '/') as well, and put the URLs in a class variable, so that they will be available to the template:
#urls=params[:urls].split
(The split is there so you get an array of strings, rather than one long string with linebreaks.)
Finally, you add some logic to the template to check whether there are any URLs to display, and if so render them as a list:
<% if #urls && !#urls.empty? %>
<h1>URLs</h1>
<ul>
<% for #url in #urls %>
<li>
<%= #url %>
</li>
<% end %>
</ul>
<% end %>
<h1>Enter URLs Below </h1>
...etc...

Rails form_for in Twitter Bootstrap Modal with AJAX/JSON

I'm having trouble getting a Rails form_for form to work in a Bootstrap modal and update a table with AJAX. I've followed the guide at http://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html, to no avail. I've also tried following the advice in the links at the bottom of this question.
On the index view, I have a table of drivers and a button to add a new driver. The button brings up the modal with a form for a new driver. When the form is submitted, I want the modal to close and the new driver to appear in alphabetical order in the drivers table. What's happening now is that the modal comes up and shows the form, but clicking the submit button does nothing. The modal does not close and the new driver is not added to the database.
Here's a summary of app/views/drivers/index.html.erb:
<div>
Add Driver
<%= render 'new_driver' %>
</div>
<div>
<table id="drivers" class="table table-hover">
<thead>
<%= render 'list_header' %>
</thead>
<tbody>
<%= render #drivers.sort_by(&:last_name) %>
</tbody>
</table>
</div>
Here's the modal partial at app/views/drivers/_new_driver.html.erb:
<div id="driverAddModal", class="modal hide fade">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="driverAddModalLabel">Add Driver</h3>
</div>
<div class="modal-body">
<%= form_for #driver, remote: true do |f| %>
Last Name
<%= f.text_field :last_name %>
<!--more form fields-->
<%= f.submit "Add Driver", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
app/controllers/drivers_controller.rb:
class DriversController < ApplicationController
def new
#driver = Driver.new
end
def create
#driver = Driver.new(params[:driver])
respond_to do |format|
if #driver.save
format.html { redirect_to #driver, notice: 'Driver added.' }
format.js {}
format.json { render json: #driver, status: :created, location: #driver }
else
format.html { render action: "new" }
format.json { render json: #driver.errors, status: :unprocessable_entity }
end
end
end
def index
#driver = Driver.new
#drivers = Driver.all
respond_to do |format|
format.html
end
end
end
app/views/drivers/create.js.erb:
$("<%= escape_javascript(render #driver) %>").appendTo("#drivers");
app/assets/javascript/drivers.js.coffee:
$(document).ready ->
$("#new_driver").on("ajax:success", (e, data, status, xhr) ->
$("#new_driver").append xhr.responseText
).bind "ajax:error", (e, xhr, status, error) ->
$("#new_driver").append "<p>ERROR</p>"
Here are the other links I've checked out:
http://www.alfajango.com/blog/rails-3-remote-links-and-forms-data-type-with-jquery/
http://www.alfajango.com/blog/rails-3-remote-links-and-forms/
http://mrdanadams.com/2011/partials-ajax-form-submit-rails/#.UVDJuuC8K00
Rails App with Bootstrap Modal View containing form, submit and disappear modal view without reloading page
Displaying errors when a Twitter Bootstrap modal window contains a Rails form helper
"modal form" with bootstrap on rails works partially
Bootstrap modal not dismissing after form submit in Rails
Rails 3.1 and Twitter Bootstrap modal don't play nice?
Unfortunately I just don't know how to apply the advice on those pages to my app. I'm new to Rails and programming in general and this is my first foray into AJAX or JSON.
It seems like you are very new to Rails. In your case, I suggest you go and read the log files when you submit the form. And also log params[:driver] to see if all the fields are there, and watch for validation in your modal. puts driver.errors.inspect after driver.save to see if validation is the cause.
Sum up:
Check log if there is an submit request to your create controller.
output all params to see everything is submitted as expected.
output 'success' in success scope, and output driver.errors.inspect if save fail.
Then you are good to go to see all the bugs.
Oh I suggest you watch RailsCast, they got everything in there.

Easier way to click button in nested divs with Watir?

I'm new to Watir and I'm trying to click the following login button:
<div class="container login" style="display: table;">
<div class="left">
<div class="right">
<div class="joinbox">
<form id="form_login" class="hidden-submit" method="post">
<input type="submit" value="Submit">
<div class="header">
<div class="left">
<div class="mid">
<div class="right">
<a class="button button-red submit" href="#">Log In</a>
...
So far I'm able to access this button by going through every nested div:
b.div(:class, "container login").div(:class, "right").div(:class, "joinbox")......
and so on. Is this really the best way to access this button? I assume I'm missing something. Any help is appreciated!
If there is only one link (that looks like a button) with text Log In on the page, try this:
browser.a(:text => "Log In").click
You could also use class attribute:
browser.a(:class => "button button-red submit").click
May this work?
browser.form(id,form_login).submit
BTW: I have seen some tips said safari only support GET mode for submit.
I would try:
browser.a(:href => "#").click
Assumption - "#" is unique. may need a slash so it doesn't misinterpret the #. I used something similar when I was trying to reference a button with only a href value of "/login" e.g., browser.a(:href => "/login").click.

Resources