I'm working on my login page with the Devise Gem. I encounter this weird thing when i click on the buttons. The messages displays itself at the end of the former one instead of replacing it. Do you know the potential reason of this strange behavior? Thanks a lot!
My session/new.rb
<h2>Log in</h2>
<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="form-inputs">
<%= f.input :email,
required: false,
autofocus: true,
input_html: { autocomplete: "email" } %>
<%= f.input :password,
required: false,
input_html: { autocomplete: "current-password" } %>
<%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
</div>
<div class="form-actions">
<%= f.button :submit, "Log in" %>
</div>
<% end %>
<%= render "users/shared/links" %>
A picture of the render in the browser
login page
I tried to find where i can limit this behaviour but unfortunately i didn't found it.
When you login unsuccessfully.
It will render flash
Ex: flash[:alert] = "You need to sign in ...."
After that, in application.html.erb display this error
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
Make sure notice and alert in front of <%= yield %> and no repeat alert or notice
This is my first attempt in creating forms in Bootstrap 4 using its native validation.
When I execute this code the default error messages appear since I have not set the novalidate value.
<%= form_tag contact_path, class: "needs-validation", method: 'get' do %>
<div class="row">
<div class="form-group col-12 col-sm-12 col-md-4 col-lg-4 col-xl-4">
<%= label_tag "#{t :label_name}" %><%= text_field_tag :name, params[:name], class: "form-control", :minlength => 2, :maxlength => 40, placeholder: "#{t :contact_placeholder_name}", required: "required" %>
<div class="invalid-feedback"><%= "#{t :label_name} #{t :contact_error_required}" %></div>
</div>
<div class="form-group col-12 col-sm-12 col-md-4 col-lg-4 col-xl-4">
<%= label_tag "#{t :label_email_address}" %><%= email_field_tag :email, params[:email], class: "form-control", :minlength => 15, :maxlength => 70, placeholder: "#{t :contact_placeholder_email}", required: "required" %>
<div class="invalid-feedback"><%= "#{t :label_email_address} #{t :contact_error_required}" %></div>
</div>
<%= submit_tag "#{t :contact_submit}" %>
</div>
<% end %>
I have the following with no success. The last one produced the same markup as the previous one.
<%= form_tag contact_path, class: "needs-validation novalidate", method: 'get' do %> - questioned if this would work since it's not identified as a class in the Bootstrap documentation.
<%= form_tag contact_path, class: "needs-validation", :novalidate, method: 'get' do %> *** error ***
<%= form_tag contact_path, class: "needs-validation", novalidate: "novalidate", method: 'get' do %>
<%= form_tag contact_path, class: "needs-validation", novalidate: true, method: 'get' do %>
How do I reproduce the following markup in Rails to get my custom error messages to appear? I have not seen anything about how to declare novalidate in Rails anywhere online.
<form class="needs-validation" novalidate>
After over two years I decided to try again. I forgot that I posted this question.
I'm using Bootstrap 4.5.0 with Rails 5.2.4.3.
I took the script from Tyler Fredrizzi's answer and added it to the head section in application.html.erb. I don't remember if the Bootstrap I was using in 2018 required an additional script or not.
Here is my form_tag statement.
<%= form_tag contact_path, novalidate: "novalidate", class: 'needs-validation', method: "get" do %>
The default popup messages still displayed when form errors occurred. I updated my submit button to remove them.
<%= submit_tag "#{t :contact_submit}", class: "btn btn-default", formnovalidate: true %>
It took a bit but I finally got it working.
I'm not sure if your question has been answered but I just ran into the same issue and was able to resolve it by using an html hash in my form_with tag.
<%= form_with model: #user, html: { class: "needs-validation", novalidate: true } do |f| %>
For some reason, I can't add a comment. On #nlfauria's answer, the key there is to use the form_with if you are using Rails >5.0.0.
I can confirm that the Bootstrap 4 validations work with the form_with tag and not with form_for, which was the default used by Devise. I utilized the same Javascript from the example given on the bootstrap page, which I linked here.
If you switch to the form_with, ensure that you use form.text_field and required: true in your fields to match the expected syntax of the new form_with.
To clarify, I am currently using Rails 6.0.0 and Bootstrap 4.3.1, so please be aware the expected behavior may be difference.
For Turbolinks 5.0.0 and >, in the javascript code that was posted in the Bootstrap Forms page, there a few things to do to make this work.
Move the Javascript to assets/javascripts and wherever you want to put it. (In the new Turbolinks issue page, there were suggestions of putting the JS in the header to avoid multi-loading issues)
Change the load event to turbolinks:load, as the JS action has changed for how documents are handled. See the code below.
This is in my app/assets/javascripts/application.js, as I will use these validations for all of my forms.
(function() {
'use strict';
window.addEventListener('turbolinks:load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
I'm no expert in JavaScript, so if someone has a better method, any advice would be much appreciated.
Here is the form I used with all of my code:
<%= form_with(model: resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, novalidate: true, class: 'needs-validation' }) do |f| %>
<div class='form-group'>
<div class="input-group">
<%= render 'shared/input_group_prepend_label', label: 'Name' %>
<%= f.text_field :name, autofocus: true, autocomplete: "name", class: 'form-control rounded' %>
<div class="valid-feedback">
Looks good!
</div>
</div>
</div>
<div class="input-group form-group">
<%= render 'shared/input_group_prepend_label', label: 'Email' %>
<%= f.email_field :email, autofocus: true, autocomplete: "email", class: 'form-control' %>
<div class="valid-feedback">
Looks good!
</div>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div class='form-group'>
<div class="input-group">
<%= render 'shared/input_group_prepend_label', label: 'New Password' %>
<%= f.password_field :password, autocomplete: "new-password", class: 'form-control', placeholder: 'Leave blank if you dont want to change it' %>
</div>
<small id="passwordHelpBlock" class="form-text text-light">
Your password must be 6-20 characters long, contain letters and numbers, and must not contain spaces, special characters, or emoji.
</small>
</div>
<div class="input-group form-group">
<%= render 'shared/input_group_prepend_label', label: 'Confirm New Password' %>
<%= f.password_field :password_confirmation, autocomplete: "new-password", class: 'form-control', placeholder: 'Confirm you new password!' %>
</div>
<div class="input-group form-group">
<%= render 'shared/input_group_prepend_label', label: 'Current Password' %>
<%= f.password_field :current_password, autocomplete: "current-password", class: 'form-control', placeholder: 'Please input your current password to confirm changes.', required: true %>
<div class="invalid-feedback">
Please input your current password to confirm changes!
</div>
</div>
<%= render 'shared/form_submit_button_custom_label', form: f, custom_label: 'Update Information' %>
<% end %>
You'll want something like:
<%= form_tag contact_path, { class: "needs-validation novalidate", method: :get } do %>
The method signature expects two args, both potentially hashes, your current attempts are throwing all the arguments into the first hash.
form_with is the new hotness, however, so you might consider switching to it.
I added simple_form gem and its corresponding instructions, and i see the editor and all, but when I add the class to my form...it doesn't seem to be working. However, when I delete the class: 'summernote', the form functions correctly.
Here's what i have in my _form.html.erb. Note that the form works 100% fine as long as i don't assign it a class of summernote.
<%= simple_form_for ([#project, #task]) do |f| %>
<div class="form-group">
<%= f.input :description, input_html: { class: 'summernote' } %>
</div>
<h3>Extra Tasks?</h3>
<div id="tasks">
<%= f.fields_for :extratasks do |extratask| %>
<%= render 'extratask_fields', f: extratask %>
<% end %>
<div class="links">
<%= link_to_add_association 'add extratask', f, :extratasks %>
</div>
</div>
<%= f.submit %>
<% end %>
I've also tried doing <%= f.input :description, as: :summernote%> , but that only causes the original input field to overlap the summernote field.
Please, try this I think work:
f.input :description, html: { class: 'summernote' }
I'm making a Rails web app with the limited knowledge I have - mostly from the Hartl Rails Tutorial. I'm also using Bootstrap.
I decided it would be good to have a dropdown login form in the navbar, in addition to the form at '/login'. The form looks nice enough, but I can't get it to work.
Here is my current code for my working, '/login' form:
<%= form_for(:session, url: login_path) do |f| %>
<div class="form-group">
<%= f.label :username %>
<%= f.email_field :username, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
</div>
<%= f.submit "Log in", class: "btn btn-primary center-block" %>
<% end %>
Here's my code for the non-working navbar form:
<%= form_for(:session, url: login_path, method: :post,
html: { role: "form", id: "navbar-login" }) do |f| %>
<div class="form-group-sm">
<%= f.label :username %>
<%= f.text_field :username, class: 'form-control',
name: 'username', placeholder: 'Username' %>
</div>
<div class="form-group-sm">
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control',
id: 'password', name: 'password',
placeholder: 'Password' %>
<%= link_to "Forgot password?", '#' %>
</div>
<%= f.submit "Log in", class: "center-block" %>
<% end %>
And here's my sessions_controller.rb create method:
def create
user = User.find_by(username: params[:session][:username])
if user && user.authenticate(params[:session][:password])
log_in user
redirect_to user
else
flash.now[:danger] = "That email and password combination isn't
correct."
render 'new'
end
end
The error I get when submitting the form is as follows:
NoMethodError in SessionsController#create
undefined method `[]' for nil:NilClass
The error also points to this line of the create method:
user = User.find_by(username: params[:session][:username])
I guess the answer is pretty simple, but I can't quite figure it out. I'm sure it must be either form_for or the create method that isn't working.
Thanks in advance for any help.
Remove the name attribute from every field in the form.
Rails handles it for you and the way you are naming it is not creating the param that you expect.
I have an application that I have been working on and have everything wired up to my liking but was wondering if this is possible:
I am displaying a users username in an edit.html.erb template. I want it to display the users username inside of the <%= f.text_field :username, :class=> "uneditable-input" %>. I am using Bootstrap and in the documentation, it states to add a class of uneditable-input, when I hove rover the username text field, it shows a little white stop sign but I am still able to click on the field and edit it. Any help?
<%= render 'shared_partials/errors', errors_object: #user %>
<div class="page-header">
<h2> Edit Your Profile<small> - <%= #user.username %></h2></small>
</div>
<div class="well">
<%= form_for #user do |f| %>
<%= f.label :username %>
<%= f.text_field :username, :class=> "uneditable-input" %>
<%= f.label :password %>
<%= f.password_field :password, :class=> "input", :placeholder=>"Password goes here" %><br/>
<%= f.submit "Update Changes", class: 'btn btn-primary' %>
<% end %>
</div>
Make the field disabled.
<%= f.text_field :username, :class=> "uneditable-input", :disabled => true %>
While submitting the form, browser will not send the value for the field username and thats correct, why it should be sent if it is un-editable.