client_side_validations 'Cannot read property 'user[email]' of undefined' - ruby-on-rails

So I am trying to get client_side_validations gem working and when I tab out of my email field, I get this error:
Uncaught TypeError: Cannot read property 'user[email]' of undefined
This is my form helper:
<%= form_for(resource, :as => resource_name, :class => "send-with-ajax", :url => user_registration_path(resource), :validate => true) do |f| %>
<%= f.email_field :email, :id => "form-email", :placeholder => "your-email#address.com", :input_html => {:autofocus => true}, :validate => true %>
<%= f.submit :label => "Submit", :value => "Sign Me Up!" %>
<div class="ajax-response"><%= devise_error_messages! %></div>
<% end %>
Which generates this HTML:
<form accept-charset="UTF-8" action="/users" class="new_user" data-validate="true" id="new_user" method="post" novalidate="novalidate">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden" value="9JdqaiushdauhsdioauhdoiuhNLSAVCGrc+PLJAQ=" />
<input data-validate="true" id="form-email" input_html="{:autofocus=>true}" name="user[email]" placeholder="your-email#address.com" size="30" type="email" />
<input label="Submit" name="commit" type="submit" value="Sign Me Up!" />
<div class="ajax-response"></div>
</form>
Edit 1: Even when I change the form helper from f.email_field :email, to f.text_field :email...I am still getting this error.

So I found the solution, it seems that either client_side_validations or devise are altering the id of the form - which would break the JS validation.
So the solution is to enforce the id of the form, so my form_for helper now looks like this:
<%= form_for(resource, :as => resource_name, :class => "send-with-ajax", :url => user_registration_path(resource), :validate => true, :html => { :id => 'user_new' }) do |f| %>
I found this solution here.

Have a look at the following #263 Client Side Validations. This should help.

Related

Rails Devise Calling POST instead of PUT in reset password

I am using devise for authentication and i have a problem in the recover password form, whose link is sent by e-mail. When I define a new password, the form is sending a POST request, instead of a PUT. It's redirecting to user/password# with 'Email can't be blank' notice.
So, edit.html.erb has method: : put, but it isn't working.
<%= form_for(resource, as: resource_name, url: user_password_path(resource_name), html: { method: :put }) do |f| %>
I'm stuck in this all day and haven't figured a way out
This is the full edit.html.erb
<h2>Change your password</h2>
<%= form_for(resource, as: resource_name, url: user_password_path(resource_name), method: :PUT) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<%= f.hidden_field :reset_password_token %>
<div class="field">
<%= f.label :password, "New password" %><br />
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em><br />
<% end %>
<%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
</div>
<div class="field">
<%= f.label :password_confirmation, "Confirm new password" %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>
<div class="actions">
<%= f.submit "Change my password" %>
</div>
<% end %>
This is the generated form
<h2>Change your password</h2>
<form class="new_user" id="new_user" action="/user/password.user" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="_method" value="patch" /><input type="hidden" name="authenticity_token" value="Zf5rxkU11tVmt4i8hDpFPDL5y+/jzRQT/O/si6RnraidCN5vxofmVS1abO4nJ8iqlncZfCRr1jdLjMfxwMx45A==" />
<input type="hidden" value="xk6EkLsyxCyvvpDyY6Ug" name="user[reset_password_token]" id="user_reset_password_token" />
<div class="field">
<label for="user_password">New password</label><br />
<em>(6 characters minimum)</em><br />
<input autofocus="autofocus" autocomplete="new-password" type="password" name="user[password]" id="user_password" />
</div>
<div class="field">
<label for="user_password_confirmation">Confirm new password</label><br />
<input autocomplete="new-password" type="password" name="user[password_confirmation]" id="user_password_confirmation" />
</div>
<div class="actions">
<input type="submit" name="commit" value="Change my password" data-disable-with="Change my password" />
</div>
</form>
My passwords controller
# frozen_string_literal: true
# Deals with user login and generates JWT
class User::PasswordsController < Devise::PasswordsController
prepend_before_action :require_no_authentication
# Render the #edit only if coming from a reset password email link
append_before_action :assert_reset_token_passed, only: :edit
skip_before_action :verify_authenticity_token
respond_to :json
wrap_parameters :user
before_action :configure_permitted_parameters, if: :devise_controller?
def create
super
end
def edit
super
end
def update
super
end
def new
super
end
end
My routes.rb
constraints subdomain: 'api' do
scope module: 'user' do
devise_for :users,
path: '/user',
path_names: {
registration: 'signup',
sign_in: 'login',
sign_out: 'logout'
},
controllers: {
sessions: 'user/sessions',
registrations: 'user/registrations',
passwords: 'user/passwords'
}
Server log
Thanks in advance
I ran into this same issue using the Devise password reset functionality. I was adding Devise to an API Rails application (config.api_only = true) and apparently the Rack::MethodOverride middleware that is responsible for identifying the hidden method attribute and changing the request to a PUT/PATCH request was not included in the API-only middleware stack. As a result, the request made it to the main app still as a POST request.
I added the following line to config/application.rb, which solved the problem:
config.middleware.insert_after Rack::Runtime, Rack::MethodOverride

how to add Active Admin form input :html {multiple => ""}?

ActiveAdmin form:
my problem: I can not get a form with multiple choice files(
I tried:
ActiveAdmin.register Foto do:
form :html => { :multipart => true } do |f|
f.inputs "Upload" do
f.input :foto, :as => :file
end
f.actions
end
end
this does not work, then I made a simple html page with two forms:
<!DOCTYPE doctype html>
<html>
<head>
</head>
<body>
<!--**not** work multiple choice files-->
<form accept-charset="UTF-8" action="#" enctype="multipart/form-data" method="post">
<input id="image" name="image" type="file"/>
</form>
<!--**great** work multiple choice files-->
<form accept-charset="UTF-8" action="#" method="post">
<input id="image" name="image" type="file" multiple=""/>
</form>
</body>
</html>
Question: how to add a property to multiple input field ?
I tried:
f.input :foto, :as => :file, :html => {:multiple => ""}
f.input :foto, :as => :file, :html => {:multiple => ""}
f.input :foto, :as => :file, :html => {"multiple" => "multiple"}
f.input :foto, :as => :file, :html => {:multiple => :multiple}
this does not work
help me, please.
You should use
f.input :foto, as: :file, input_html: { multiple: true }

simple_form 'form-inline' not working

I'm trying to make two input (firstname and lastname) to next to each other.
Here is my code and it's currently just showing two big rows of input window.
= simple_form_for #user, html: {class: 'form-inline'} do |f|
= f.fields_for :profile, #user.profile || Profile.new, html: {class: 'form-inline'} do |p|
.form-1
.form-1-detail
.input-text
= f.input :last_name, required: true
.input-text
= f.input :first_name, required: true
I'm now sure how to make them to display inline. Can anyone help me?
Thanks!
Updated. This is the actual HTML generate from
= simple_form_for #user, html: {class: 'form-inline'} do |f|
= f.fields_for :profile, #user.profile || Profile.new do |p| # removed form-inline here
.form-1
.form-1-detail
.form-group
= f.input :last_name, required: true
.form-group
= f.input :first_name, required: true
</div><form class="simple_form form-inline" novalidate="novalidate" id="new_user" action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="DhQSodBk8kxdE6q9uPJDKSs9FfxCNLyXFYT3bZ42HlZfHefxfG3BDq9qkFpxkX7MBZI4Mc4Wje6LKw7Gp1YcjQ==" />
<div class="form-1">
<div class="form-1-detail">
<div class="form-group">
<div class="input string required user_last_name"><label class="string required" for="user_last_name"><abbr title="required">*</abbr> 姓</label><input class="string required" placeholder="姓" type="text" name="user[last_name]" id="user_last_name" /></div>
</div>
<div class="form-group">
<div class="input string required user_first_name"><label class="string required" for="user_first_name"><abbr title="required">*</abbr> 名</label><input class="string required" placeholder="名" type="text" name="user[first_name]" id="user_first_name" /></div>
</div>
</div>
</div></form>
You should install the simple_form wrappers:
rails generate simple_form:install --bootstrap
From there you can structure a inline_form using it's corresponding wrapper:
simple_form_for #user, wrapper: :inline_form, html: { class: 'form-inline' } ...
They have an example app: https://github.com/rafaelfranca/simple_form-bootstrap
The specific view that using this is (sorry it's ERB however):
https://github.com/rafaelfranca/simple_form-bootstrap/blob/master/app/views/examples/_inline_form_sf.html.erb
Try using f.input_field instead of f.input.
Reference: https://github.com/plataformatec/simple_form#stripping-away-all-wrapper-divs
The simple_form gem uses Bootstrap, right? I compared your code to the Bootstrap Form docs and I think you should be using form-group classes inside the form-inline.
= simple_form_for #user, html: {class: 'form-inline'} do |f|
= f.fields_for :profile, #user.profile || Profile.new do |p| # removed form-inline here
.form-1
.form-1-detail
.form-group
= f.input :last_name, required: true
.form-group
= f.input :first_name, required: true
Alternatively, unless you have unique CSS that you need to apply for the form-1 and form-1-detail classes, this might be able to be shortened to:
= simple_form_for #user, html: {class: 'form-inline'} do |f|
= f.fields_for :profile, #user.profile || Profile.new do |p| # removed form-inline here
.form-group
= f.input :last_name, required: true
.form-group
= f.input :first_name, required: true
If that doesn't work, can you post the actual HTML that is generated for the form in the browser?

Case insensitive omniauth-identity email login

By default the intridea / omniauth-identity rails gem uses email to login and they are case sensitive. How do I make the login email case insensitive? Adding ":case_sensitive => false" to the model as seen below does not work.
#models/identity.rb
class Identity < OmniAuth::Identity::Models::ActiveRecord
attr_accessible :email, :name, :password, :password_confirmation
validates_presence_of :name
validates_uniqueness_of :email, :case_sensitive => false
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\#([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
end
For example, even with the model above if you signed up with "bob#aol.com" and then tried to login with "BOB#aol.com" the login would produce an OMNIAUTH::ERROR of invalid credentials.
Any suggestions?
Ok, so I thought user ForgetTheNorm had the solution, but it turns out modifying the locate_conditions breaks sign up. The solution is actually much simpler than I originally thought. Downcase the auth-key BEFORE it is submitted with the form. This is true of everywhere you use the key. For instance, to login or sign up.
#login-form
<%= form_tag('/auth/identity/callback', :method => 'post', :id => 'actual-login-form') do %>
<div class="field">
<%= label_tag :auth_key, 'Email' %>
<br />
<%= text_field_tag :auth_key, nil, :class => 'user-auth-field user-auth-key' %>
</div>
<div class="field">
<%= label_tag :password %>
<br />
<%= password_field_tag :password, nil, :class => 'user-auth-field' %>
</div>
<div class="actions">
<%= submit_tag 'Sign in', :class => 'btn-default', :id => 'modal-sign-in' %>
</div>
<% end %>
#signup-form
<%= form_tag('/auth/identity/register', :method => 'post', :id => 'actual-signup-form') do %>
<%= label_tag(nil, 'Choose your username') %>
<%= text_field_tag 'name', nil, :class => 'signup-form-input', :tabindex => '1' %>
<%= label_tag(:email, 'Your current email address') %>
<%= text_field_tag 'email', nil, :class => 'signup-form-input user-auth-key', :tabindex => '2' %>
<%= label_tag(:password, 'Create a password') %>
<input type="password" name="password" id="password" class="signup-form-input" tabindex="3" />
<%= label_tag(:password2, 'Confirm your password') %>
<input type="password" name="password_confirmation" id="password_confirmation" class="signup-form-input" tabindex="4" />
<%= submit_tag('Sign Up for Pholder', :id => 'signup-submit', :tabindex => '5') %>
<% end %>
Relevant jQuery/JS:
$('#actual-login-form, #actual-signup-form').on('submit', function(){
//lower case auth key (email addresses) for all user validation
$(this).find('.user-auth-key').val( $(this).find('.user-auth-key').val().toLowerCase() )
})
You can find solutions in
https://github.com/intridea/omniauth-identity/issues/22
For the sake of clarity...
#config/initializers/omniauth.rb
provider :identity, locate_conditions: lambda { |req|
{ model.auth_key => req['auth_key'].downcase }
}
As ujeezy noted above, the omniauth-identity gem on Rubygems does not
support this feature, this is still true. Make sure your gemfile is as
he stated:
#Gemfile
gem 'omniauth-identity', git: 'https://github.com/intridea/omniauth-identity.git'

Rails devise plugin customization

In my current Ruby on Rails project, the devise plugin has been used for authentication. To change the password, I added the devise plugin's passwords/edit.html.erb file into the user directory in my project. Everything's working fine except the error messages are not showing.
This is my current update_password method
def update_password
#user = User.find(current_user.id)
if #user.update_with_password(params[:user])
sign_in #user, :bypass => true
redirect_to root_path
else
render "edit"
end
end
I've mentioned the require validation in the user model as follows
validates_presence_of :name, :primary_locale, :current_password, :password, :password_confirmation
This is my edit form code:
<div id="loginForm" class="editPwFormHeight">
<div id="loginHeader"><h3><%= image_tag("wif_small.png"); %></h3></div>
<div id="loginContent">
<%= form_for(#user, :url => { :action => "update_password", :locale => params[:locale] }, :method => "post") do |f| %>
<%= f.hidden_field :reset_password_token %>
<p><%= f.password_field :current_password, :class => "login_txt", :placeholder => I18n.t('wi.common.enterCurrentPw'), :autocomplete => "off" %></p>
<p><%= f.password_field :password, :class => "login_txt", :placeholder => I18n.t('wif.common.newPw'), :autocomplete => "off" %></p>
<p><%= f.password_field :password_confirmation, :class => "login_txt", :placeholder => I18n.t('wif.common.confirmPw'), :autocomplete => "off" %></p>
<p>
<input id="user_submit" name="commit" type="submit" value="<%= I18n.t('wif.common.updatePw') %>" class="login_btn" />
<input id="user_cancel" name="commit" type="button" value="<%= I18n.t('wif.common.cancel') %>" class="login_btn" />
</p>
<% end %>
</div>
</div>
Anyone can help me to solve this issue. I wanted to show the error message if the user has not typed the current password, or any other error which are currently supporting by the devise
You need to add the following line to your template:
<%= devise_error_messages! %>
You can customise the messages themselves by editing Devise's translation files, e.g. config/locales/devise.en.yml
If you're not using devise's built-in controllers, then you will need to register the DeviseHelper module as a helper in your controller using the helper method.

Resources