I have a Ruby on Rails app.I am using Devise for authentication.I have set a 30 minutes timeout for the users which auto logs out the users on 30 minutes of browser inactivity.The problem I am facing is that when the session logs out on timeout after 30 minutes,it takes to the login screen and the browser saved email address and password shows up in the login text boxes.But on clicking the login button it doesn't logs me into the application.When the page reloads after the login fail,I can login as usual.
When i checked the problem further,I found that the email address and password values are nil even though it shows up on the browser screen.
The Login form code is given below:
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name,:role => "super_admin")) do |f| %>
<%= f.email_field :email, :placeholder => "EMAIL", :data => { :'placeholder' => 'EMAIL'}, :class => 'with_holder' %>
<%= f.password_field :password, :placeholder => "PASSWORD", :class => 'disablecopypaste with_holder' , :data => { :'placeholder' => 'PASSWORD'}%>
<% if devise_mapping.rememberable? -%>
<%= f.check_box :remember_me %>
<% end -%>
<a id="save_post" href="javascript:void(0);">LOG IN</a>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
<%= link_to "FORGOT PASSWORD?", new_password_path(resource_name, :role => 'super_admin') %>
<% end -%>
Am I doing anything wrong here?it would be really helpful if anyone can help me with this problem
If you see Email and Password on your login form when reloading the page, it is the browser behavior, not your Devise. It could be because your input has autocomplete attribute and you have selected to Save Password on your browser. Try setting autocomplete=off on your input to see if it helps
At Last found out the issue..The issue was in submitting the form,the form was not being submitted in usual method.It as being submitted from a JS method which catches the click event of <a id="save_post" href="javascript:void(0);">LOG IN</a> and submits the POST action of its parent form.
The issue was that the form was not being Loaded at the time of the click and hence it was returning empty strings for the email and password fields.Once I changed the method of submitting the form to the usual way ie putting a form submit button
<%= f.submit "LOG IN", :id => "login_submit" %>
it works fine
As the button is also an element inside the form,it will only get loaded once other elemts inside the form get loaded,hence it wont return empty strings on clicking the button.
Related
I have a problem when trying to submit a form with a div (instead of a f.submit button)
<%= form_for #user, url: {action: "submit_user"}, html: {id: "user_submit", class: "form"}, :method => "post" do |f| %>
<%= f.text_field :first name, :required => true, :placeholder => 'first name', :autocomplete => :off %>
<%= f.text_field :last name, :required => true, :placeholder => 'last name', :autocomplete => :off %>
<div id="submituser" class="some very fancy css here" onclick = "document.forms['user_submit'].submit();">
<% end %>
The problem is that the form is sent, but without the validations (causing it to send blank first and last name if nothing is entered)
note that when using
<% f.submit "submit" %>
validations do work.
Thanks
I guess document.forms['user_submit'].submit(); does not trigger the submit event, so You have to launch validation manually. But what is the point of using div instead of button? You could style a button with some very fancy css here too. OR make a 'hidden' submit button and add onclick = "document.form.button.click()" to div :-)
Found my answer here:
Difference between handling $(“form”).submit or an click event?
And i quote #Giovanni Sferro:
The click callback is called only if the user actually click on the submit button. But there are cases in which you would submit the form automatically by javascript, in that case the click callback is not fired while the submit callback is. I would recommend to use always the submit for validation and intrinsic action of the form, while using the click callback for animation or other things related to the action of clicking on the button.
so my (working) code looks like this:
<div id="submituser" class="some very fancy css here" onclick = '$("#user_submit input[type=\"submit\"]").click();'>
I'm trying to implement the password reset functionality in an app, using Devise. I'm at a point where the "forgot password" link works (in that it sends the email), and the email contains the link to "Change my password".
The change password link works and sends you to a form (at the URL http://localhost:3000/users/password/edit?reset_password_token=c7cKb4hMhSLRs72n9dYj) asking for the new password (and to confirm it), but after typing in a new password and clicking "Chang my password", it redirects to localhost:3000/users/password and says "Please review the problems below:" and presents a from with one field for Email, and a button for "Send password reset instructions". This is, of course, the form for submitting your email to get password reset instructions, but it also has an error notice of "can't be blank", as if someone clicked the button with the field empty.
I used a tutorial to configure ActionMailer to send the email, which I thought was going to be the most difficult part of this process, but now I can't figure out why the form to change one's password is not working.
I'm very new to Rails, and this is my first time working with Devise and ActionMailer, so I apologize if I haven't included some needed information. Just let me know and I can add anything that helps.
Thanks.
Ok, so with the help of someone at a Rails meeting tonight, I found out what the problem was. It didn't really have anything to do with the controllers or routes, but rather I had caused the bug by incorrectly adding some code to the form. Here's the corrected code for my form:
<h2>Change your password</h2>
<%= simple_form_for(resource, :as => resource_name, :url => password_path(resource_name),
html: { method: :put, class: "pure-form pure-form-stacked" }) do |f| %>
<%= f.error_notification %>
<%= f.hidden_field :reset_password_token %>
<%= f.input :password, label: "New password", autofocus: true, required: true %>
<%= f.input :password_confirmation, label: "Confirm new password", required: true %>
<div><%= f.submit "Change my password", class: "pure-button" %></div>
<% end %>
<%= render "devise/shared/links" %>
My problem was that instead of including the class: "pure-form pure-form-stacked line as a second key/value pair into html: {}, I had a second html: {} line.
In case that's not clear, I had this:
html: { method: :put },
html: { class: "pure-form pure-form-stacked" }
instead of this:
html: { method: :put, class: "pure-form pure-form-stacked" }
and for some reason, in the first version, only the second html: {} was being submitted with the form, so it didn't get processed as a put request.
I have been recently working with Ruby on Rails and have run into an issue that I can not quite figure out. I need to create a bunch of form mockups, that do not function. That is they should have the submit button, but it should not do anything upon being clicked. Normally using html I would do something along the lines of
<form action="#">
</form>
Trying to convert this to use Rails form helpers, I have done the following
<%= form_tag "#" do %>
<%= label_tag :username, "Username: " %>
<%= text_field_tag :username %>
<br />
<%= label_tag :password, "Password: " %>
<%= password_field_tag :password %>
<br />
<%= submit_tag "Login" %>
<% end %>
This generates a form that is similar to what I want to achieve, however when clicking the submit button it tries to access /# via post which is not the desired result. Currently the only thing I can think of to achieve this is to set the disabled attribute of the button, but is there a better way?
Unfortunately this can't be achieved with form helpers. Defining a form_for or a form_tag requires an action for the form. You can set
:action => "#"
But this will require including the action in routes -> having a controller with action for it -> rendering some page yet again.
You could manipulate the form after loading with javascript however (sust remember to set :remote to true - ). Or alternatively, if you insist on using the form helpers - replace the submit_tag with a button_tag:
<%= button_tag "Login", :type => 'button'%>
Try
<% form_tag "#", :onSubmit => "return false" do %>
Have you tried with button_tag instead of submit_tag? See here. Just make sure you don't use the default, or you will be right back where you started.
I get a NoMethodError when submitting this form, I've no idea how to get it to work. It's just a password reset form though the Devise gem, and trying the #user.send_reset_password_instructions in the console works just fine.
Here's the form in my view:
<%= form_tag reset_password_path(:email), :id => 'forgotten_password' do %>
<%= email_field_tag :email, nil, :placeholder => 'Email address' %>
<%= submit_tag "Reset password" %>
<% end %>
In my routes:
get "/dashboard/reset_password/:email" => "docs#reset_password", :as => :reset_password
In my controller:
def reset_password
#user = User.where(:email => params[:email]).first
#user.send_reset_password_instructions
end
Here's the error:
No route matches [POST] "/dashboard/reset_password/email"
Your route needs to have the POST method in it, not GET. And it should be /email not /:email
post "/dashboard/reset_password/email" => "docs#reset_password", :as => :reset_password
You defined your route to respond to GET requests, and your form is sending a POST request. Try changing the method of your route from get to post
So, part one is to make your route a POST instead of a GET (as mentioned previously). Typically whenever you're sending data to the server and it's causing a change (like setting the reset password token on a user account and sending them an email) you use a POST.
Change your route to look like this:
POST "/dashboard/reset_password" => "docs#reset_password", :as => :reset_password
Note: I also dropped the :email part of the path. You don't really need that.
Part two, you'll need to tweak your form a little. You don't need to pass the :email symbol to the path. I'm not actually sure what that will do for you in this case. You get the email in the params hash in the controller (params[:email]) because you've got an email field in your form.
Change your form to look like this:
<%= form_tag reset_password_path, :id => 'forgotten_password' do %>
<%= email_field_tag :email, nil, :placeholder => 'Email address' %>
<%= submit_tag "Reset password" %>
<% end %>
That should generate the POST form path '/dashboard/reset_password' in your form HTML. When the user clicks on the "Reset password" button on the page the :email field in the form will get submitted to you. Rails will stuff it into the params and your controller method 'reset_password' be able to read it just fine.
You might also want to do some error catching in your controller method. The most common problem with email password reset is that there's a typo in the email and you won't be able to find the user. It's helpful to return a message to the user when that happens.
Good luck!
I wrote the following form:
<% remote_form_for :login,
:url => {:controller => :usuarios, :action => :login },
:html => { :multipart => true } do |f| %>
<p class="login_field">
Login:<br />
<%= f.text_field 'login' %>
</p>
<p class="login_field">
Clave:<br />
<%= f.password_field 'clave' %>
</p>
<br />
<p align ="right">
<%= f.submit 'Ingresar' %>
</p>
<p class="forgot">
<%= link_to "Olvidó su clave?", { :controller => 'usuarios', :action => 'olvido_contrasena', :login => }, :post => true %>
</p>
<br />
<p id="error_msg_login"></p>
<% end %>
Now, In my controller I have:
def olvido_contrasena
if request.post?
u= Usuario.find_by_login(params[:login][:login])
puts u.email
if u and u.enviar_nueva_clave
flash[:message] = "Una nueva clave ha sido enviada a su correo electronico."
redirect_to :action=>'login'
else
flash[:warning] = "No se pudo enviar la nueva clave."
puts "fail"
redirect_to "/admin_main"
end
end
end
However, I have two problems:
The action is called as a GET (and it should be a POST).
The param[:login][:login] is not being sent....
What can I do here?
Thank you!
I solved my problem by adding a new view with a new form after the user clicks the "forgot password" link.
EASIEST and CLEANEST solution.
Basically -
You are clicking on link, which doesn't submit the form you have created, but "Submit" button can submit it.
As you are click a link, this is sending the GET request. If you want to send post request with form data, you may use, javascript event listeners to submit form on click of link.
As form is not being submitted, you are getting login[login] as nil.
To submit form with javascript you will be doing something like this with jquery -
$(".linkClass").click(function(event){
event.preventDefault(); //This will stop get request.
$("#formId").submit();
})
In your example code, the login-value is actually empty:
<%= link_to "Olvidó su clave?", { :controller => 'usuarios', :action => 'olvido_contrasena', :login => }, :post => true %>
Also - "post => true" is not how to make it into a POSTed form.
Usually you'd use button_to (instead of link_to) but as you are already inside a form (and forms don't nest), you can fake a post by passing as a query string parameter the attribute "_method" (yes, it starts with an underscroe). so your example would become:
<%= link_to "Olvidó su clave?", { :controller => 'usuarios', :action => 'olvido_contrasena', :login => #usario.login, "_method" => 'post'} %>
Now the problem is that the person is not already logged in... so you can't get their "login" - and the login field above the link is not part of the link. So you'll probably need to add some funky javascript to update the link field-value when somebody types something into the field.
... but your controller action should also deal with the case when somebody has not yet typed anything in. For example, if params[:login] is blank. it should render a "forgot your password? well enter your login name here" kind of page.