I have very simple HTML (password.html.erb):
<h1>Enter business password to enter:</h1>
<input type="text" id="password" name="enter password"/>
<input type="submit" method="post" name="Submit"/>
This should, on clicking of submit, trigger an action in my controller called 'check':
def check
#entered = params['password']
if #entered == current_customer.business.manager_password_digest
puts("success!")
redirect to '/manage'
else
flash[:danger] = 'Invalid password'
render 'password'
end
end
Here is my route:
get '/password' => 'pages#password'
post '/password' => 'pages#check'
But when I click submit, nothing happens. Is it not possible to use an input in this way?
You haven't told your button to execute which action on click. for this you should use action for the submit button.
<h1>Enter business password to enter:</h1>
<input type="text" id="password" name="enter password"/>
<input type="submit" method="post" name="Submit"/ action = '/password'>
You should be using rails helpers and you need to specify the path where you want to post the data:
<h1>Enter business password to enter:</h1>
<%= form_tag("/password") do %>
<%= text_field_tag :password %>
<%= submit_tag 'Submit' %>
<% end %>
Related
I wrote a helper method that will output the HTML to authenticate a form:
module ApplicationHelper
def auth_token
"<input type=\"hidden\" name=\"authenticity_token\" value=\"#{form_authenticity_token}\"".html_safe
end
end
And I tried using it in this portion of my HTML code in the application.html.erb:
<% if logged_in? %>
<p>Logged In</p>
<form action="<%= session_url %>" method="POST">
<input type="hidden" name="_method" value="DELETE">
<%= auth_token %>
<input type="submit" value="Logout">
</form>
<% else %>
<p>Logged out</p>
<form action="<%= new_session_url %>" method="GET">
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
<input type="submit" value="Login">
</form>
<% end %>
I'm testing one button at a time, so only the logout button is using this helper method at the moment! However, once I log in, the logout button doesn't show (but the paragraph text does appear). And when I type out the form authentication input tag explicitly instead of using my helper method, it works. I double checked my helper method and erb tags, and it looks correct to me. Any ideas on why this is happening?
> is missing in your helper method, add > at the end of string.
module ApplicationHelper
def auth_token
"<input type=\"hidden\" name=\"authenticity_token\" value=\"#{form_authenticity_token}\">".html_safe
end
end
You can just use form_tag (Rails 4):
<%= form_tag(session_url) do %>
# ...
<% end %>
Or form_with (Rails 5+):
<%= form_with(url: session_url, method: :post) do |f| %>
# ...
<% end %>
Both will render the authenticity_token input for you.
I have a resource Invoice and every invoice has an edit path:
http://localhost:3000/invoices/1/edit
On my index page where I will all my invoices I want to have an input field and a submit button to jump right to the edit page for a certain invoice:
<form class="form-inline" action="???" method="get">
<div class="form-group">
<input type="text" class="form-control date" placeholder="Invoice ID" name="id" >
</div>
<button type="submit" class="btn btn-info">Show</button>
</form>
How do I have to define the action so that if I enter for example 1 and click on Show it goes right to my edit method?
I think you're looking for something like this in your html
<%= form_tag find_invoice_url do |f| %>
<%= f.text_field :invoice_number =>
<%= f.submit "Search" =>
<= end =>
then you would need to add a route
post '/invoices/find_invoice', to: "invoices#find_invoice",
as: "find_invoice"
then in your controller something like
def find_invoice
invoice = Invoice.find_by_id(params[:invoice_number])
if invoice
redirect_to invoice_url(invoice.id) #whatever your edit route is
else
redirect_to root_url #anywhere really
end
end
if you are iterating through all the invoices, you wouldn't need an input field.
assuming that you have an invoice obhect, you would just do something like
<%= form_tag edit_invoice_path(invoice), method: "get" do -%>
<%= submit_tag "Show", class="btn btn-info" %>
<% end %>
You may want the button to say edit instead - that's more of a ux "principle of least surprise" issue
I want to print a simple message as an alert like after a user write his email click on the subscribe button.
Your email is saved, you'll be contacted for a beta very soon!
This is my view:
<form action="/welcome/subscribe" date-remote="true">
<div>
<div id="bottomm">
<input id="bottom" type="text" name="email" placeholder="email" />
</div>
<div>
<input type="submit" value="Ok" class="fit" />
</div>
<%= alert %>
</div>
</form>
This is the subscribe method in my controller :
def subscribe
#test = Test.new
#test.email = params['email']
#test.save
redirect_to root_url, notice: "Your email is saved, you'll be contacted for a beta very soon!"
end
But nothing is showing. I saw some people with the same issue as mine on stack but I tried the solutions but it didn't worked.
I tried to do these but none worked for me.
flash.keep
flash[:notice] = "..."
flash.now[:notice] = "..."
flash[:alert] = "..."
flash.now[:alert] = "..."
and redirecting after
Do you have a block either in application.html.erb or whatever your root view is to actually display the flash, like so:
<% if notice.present? %>
<p><%= notice %></p>
<% end %>
If not, that could be the problem.
I have a frontend rails app that is requesting a rails API. When my user wants to create an account, he is submitting the account form on the front-end app :
<h1>Create Account</h1>
<form action="http://localhost:3000/accounts" method="post">
<input name="authenticity_token" value="<%= form_authenticity_token %>" type="hidden">
<div class="form-group">
<%= label_tag 'account[name]', "name" %>
<input type="text" name="account[name]" required>
</div>
<div class="form-group">
<%= label_tag "account[contact_mail]", "E-Mail" %>
<input type="text" name= "account[contact_mail]" required>
</div>
<div class="form-group">
<%= label_tag "account[contact_tel]", "Telephone" %>
<input type="text" name= "account[contact_tel]" required>
</div>
<div class="form-group">
<%= label_tag "account[iban]", "Iban" %>
<input type="text" name= "account[iban]">
</div>
<div class="form-group">
<%= label_tag "account[bic]", "Bic" %>
<input type="text" name= "account[bic]">
</div>
<input type="submit">
<% if #errors %>
<ul class="list-unstyled">
<%#errors.each do |error|%>
<li class="has-error"><%=error%></li>
<% end -%>
</ul>
<% end -%>
</form>
On submit the method create from the front-end app account controller is called. The create method from the front-end app is then calling the create method on the rails API which is responsible for updating the database and rendering JSON to the front end app.
1) AccountController#create from the front-end app :
def create
# Post sur API create Account
#response = HTTParty.post(ENV['API_ADDRESS']+'api/v1/accounts',
:body => { :name => params[:account][:name],
:contact_mail => params[:account][:contact_mail],
:contact_tel => params[:account][:contact_tel],
:legal_status => params[:account][:legal_status],
:iban => params[:account][:iban],
:bic => params[:account][:bic]
}.to_json,
:headers => { 'X-User-Email' => session[:user_email], 'X-User-Token'=> session[:user_token], 'Content-Type' => 'application/json' } )
# Erreur Mauvais Auth Token
if #response["error"] == "You need to sign in or sign up before continuing."
redirect_to unauthorized_path
# erreur de validation
elsif #response["errors"]
#errors = #response["errors"]
flash[:alert] = "heello"
render :new
else
account_id = #response["account"]["id"]
redirect_to account_path(account_id)
end
end
2) AccountController#create from the API :
def create
#account = Account.new(account_params.merge(admin: current_user))
authorize #account
if #account.save
render :show
else
render_error
end
end
render error is a method that render errors in JSON format :
def render_error
render json: { errors: #account.errors.full_messages }, status: :unprocessable_entity
end
If there are validations errors when submitting the from to the API, I display them on the front end app next to the form :
<% if #errors %>
<ul class="list-unstyled">
<%#errors.each do |error|%>
<li class="has-error"><%=error%></li>
<% end -%>
</ul>
My problem is that I also wish to prepopulate the form with the data the user already submitted for better user experience.
I know there are already posts about how to prepopulate forms with rails in case of validation errors but I feel they did not really address my problem with this "double app pattern" and with my front-end app not having any models (all models / DB interactions are dealt in the API)
How can I prepopulate my form with the user's input after I receive an error from my JSON API ?
In the form you have, you could add value attributes to the input fields that populate with irb instance variables
<input type="text" name="account[name]" value="<%= #account_name %>" required>
Then in AccountController#create, set the instance variables based on the the params you received when you want to display the invalid data.
```
elsif #response["errors"]
#errors = #response["errors"]
#new code
#account_name = params[:account][:name]
#set each variable, extra to method or class for cleaner style
flash[:alert] = "heello"
render :new
```
When the form initially renders these variables will be uninitialize/nil so there will be no values in the form boxes, and then you can explicitly set them in the controller when the validation fails but you want to maintain data in the form.
This is definitely an overly-manual way to accomplish maintaining the form state, and I suggest if you want to reuse the pattern in your app you take a look at using form_for. This post might give you some insight into doing that with plain ruby objects instead of model objects. Is it possible to create form for simple class
I have the following code in ruby 1.9 rails 3.2. I've followed a few different webpages to try to update a sub-field within a page. For some reason it's still redirecting to a new page, but it's not using the layout to render ... which is strange.
Routes:
match 'search' => 'content#search'
View:
<%= form_tag({:action => 'search'},:id => 'searchForm',:remote => true, :update => "ajaxstuffhere", :position => :bottom) do %>
<p>
<label id="parkname">Park Name:</label><br/>
<%= text_field :search, :parkname, :size => 25 %>
</p>
<p>
<label id="stateprovince">State / Province:</label><br/>
<% tstate = State.new %>
<% tstate.name = "Select a State / Province" %>
<% #states = [] %>
<% #states << tstate %>
<% states = State.all.sort{|x,y| [x.country_id, x.name] <=> [y.country_id, y.name] } %>
<% states.each do |state| %>
<% #states << state %>
<% end %>
<%= puts "statelist is : " + #states.inspect.to_s %>
<%= collection_select(:search, :state, #states, :id, :name) %>
</p>
<p>
<label id="zipcode">Zip Code:</label><br/>
<%= text_field :search, :zipcode, :size => 5 %>
</p>
<p>
<label id="distanceSearchLabel">Max Distance:</label><br/>
<select id="distancePick" name="search[distance]">
<option value="">Select Distance</option>
<option value="10">10km</option>
<option value="50">50km</option>
<option value="100">100km</option>
<option value="250">250km</option>
<option value="500">500km</option>
<option value="1000">1000km</option>
</select>
</p>
</p>
<p>
<%= submit_tag 'Search' %>
</p>
<div style="clear:both;">
</div>
<h2>Narrow your Search</h2>
By Amenities
<br />
<p>
<label id="parkname">Price:</label><br/>
<%= text_field :search, :pricelow, :size => 5 %>
<%= text_field :search, :pricehigh, :size => 5 %>
</p>
<p>
<label id="parkname">Age:</label><br/>
<%= text_field :search, :age, :size => 5 %>
</p>
<p>
<%= check_box :search,:pets_allowed %><label id="petsallowedcb">Allows Pets</label><br/>
</p>
<%= check_box :search,:big_rigs %><label id="bigrigcb">Allows Big Rigs</label><br/>
<p>
<%= submit_tag 'Search' %>
</p>
<% end %>
Controller:
def search
...
render :partial => 'search'
end #seach def
I have an empty div within the html page with ID "ajaxstuffhere". When I click the submit button on the form, it loads the _search.html.erb in a new page instead of in the specified div.
Thanks for the help!
Edit: Here is the post request from the server :
Started POST "/search" for 70.28.21.25 at 2013-09-25 13:22:54 +0000
Processing by ContentController#search as HTML
Parameters: {"utf8"=>"â", "search"=>{"parkname"=>"as", "state"=>"", "zipcode"=>"", "distance"=>"", "pricelow"=>"", "pricehigh"=>"", "age"=>"", "pets_allowed"=>"0", "big_rigs"=>"0"}}
Rendered content/_search.html.erb (424.3ms)
Completed 200 OK in 637ms (Views: 105.6ms | ActiveRecord: 478.6ms)
Also, the HTML rendering of the form:
<form accept-charset="UTF-8" action="/search" data-remote="true" id="searchForm" method="post" position="bottom" update="ajaxstuffhere"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div>
<p>
<label id="parkname">Park Name:</label><br/>
<input id="search_parkname" name="search[parkname]" size="25" type="text" />
</p>
...
<input name="commit" type="submit" value="Search" />
</form>
Edit: 1 week later and still not functional
I have a new homepage.js.erb file with the following:
("#ajaxstuffhere").hide();
Which allegedly is supposed to be returned and executed when data-remote="true" is set on the form. Note that I switched to the homepage controller until I can get an ajax response working.....
Well ... that didn't work so I tried a coffee script alternative:
<script>
$(document).ready ->
$("#ajaxstuffhere").on("ajax:success", (e, data, status, xhr) ->
$("#ajaxstuffhere").append "<p>RESPONSE</p>" //xhr.responseText
).bind "ajax:error", (e, xhr, status, error) ->
$("#ajaxstuffhere").append "<p>ERROR</p>"
</script>
I dropped this right in the body of the html.erb file. It should get executed when the page loads, I would think?
At any rate, if the data-remote="true" tag did the ajax request, the response should just add "response" to the ajaxstuffhere field ... except this is not the case. The page still reloads and the AJAX response is probably lost
Is your submit button in the right place? This would be easier with a code snippet of the view with the form.
It turns out I have a line :
<%= render :partial => '/inc/analytics' %>
For Google Analytics, inside of the layout. During a post request, the line forced the page to navigate to a new page.
I have no idea why this is the case, perhaps google has some kind of actionlistener that overrides the one that rails puts on for remote forms.
Any more information related to this is welcome