isValid throwing false to valid inputs and error messages incomplete
See original GitHub issueI am doing a devise registration multi-step using stimulus and following part of https://github.com/DavyJonesLocker/client_side_validations-simple_form/wiki/Validations-with-simple_form-Twitter-Bootstrap-integration but I did some changes because wasn’t working properly:
let valid = true;
$('input:visible, select:visible').each(function() {
const settings = window[this.form.id].ClientSideValidations.settings;
if (!$(this).isValid(settings.validators)) {
valid = false
}
});
if (valid) {
//code to go to next step
if (e.currentTarget.id === "nextBtn") this.index++;
}
Steps to reproduce
First bug (isValid throwing false): Get redirect to registration page by a link. Then I tried to trigger validation unfocusing from input or clicking in next btn. Works normally if I refresh the page. Second bug (Error message incomplete): unfocus inputs to trigger validation throught gem
Expected behavior
First bug: To email input focus normally. Unfocus at input should trigger validations to show up errors messages in case have any. Click at next button should too trigger validations and shows errors messages or, in case of all inputs are valid, go to the next tab. Second bug: The errors messages include also the input type like “Email can’t be blank”
Actual behavior
First bug: Unfocus and click on next btn didn’t trigger anything. I tried debug and it seems like $(this).isValid(settings.validators)
always throw false, even if I fill all inputs with valid values. It didn’t shows up any errors messages too.
Second bug: Error message shows up like “can’t be blank”.
System configuration*
Rails version: 6.0.3.4
Ruby version: 2.6.6
Client Side Validations version: 17.1.0
Client Side Validations Simple Form version: 11.1.0
Bootstrap version (if used): 4.5.3
Code snippet from your model of the validations*
devise validation and validates :role, presence: true
Relevant part of application.js
require('@client-side-validations/client-side-validations')
require('@client-side-validations/simple-form/dist/simple-form.bootstrap4')
it’s after turbolinks.start()
The whole form code from your template
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), validate: true, data: { controller: "form" }) do |f| %>
<%= f.error_notification %>
<div class="tab" data-target="form.tab">
<%= f.input :email,
required: true,
autofocus: true,
input_html: { autocomplete: "email" },
validate: true %>
<%= f.input :password,
required: true,
hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length),
input_html: { autocomplete: "new-password" },
validate: true %>
<%= f.input :password_confirmation,
required: true,
input_html: { autocomplete: "new-password" } %>
</div>
<div class="tab" data-target="form.tab">
<%= f.input :role, collection: %w[pj manager],
validate: true %>
</div>
<div class="form-actions">
<button class="btn-orange" type="button" id="prevBtn" data-action="form#nextPrev" data-target="form.prevBtn">Previous</button>
<button class="btn-orange" type="button" id="nextBtn" data-action="form#nextPrev" data-target="form.nextBtn">Next</button>
</div>
<% end %>
The resulting HTML*
<form class="simple_form new_user" id="new_user" novalidate="novalidate" data-controller="form" data-client-side-validations="{"html_settings":{"type":"SimpleForm::FormBuilder","error_class":"invalid-feedback","error_tag":"div","wrapper_error_class":"form-group-invalid","wrapper_tag":"div","wrapper_class":"form-group","wrapper":"vertical_form"},"number_format":{"separator":".","delimiter":","},"validators":{"user[email]":{"presence":[{"message":"can't be blank"}],"uniqueness":[{"message":"has already been taken","case_sensitive":true,"allow_blank":true}],"format":[{"message":"is invalid","with":{"source":"^[^@\\s]+@[^@\\s]+$","options":""},"allow_blank":true}]},"user[password]":{"presence":[{"message":"can't be blank"}],"confirmation":[{"message":"doesn't match Password","case_sensitive":true}],"length":[{"messages":{"minimum":"is too short (minimum is 6 characters)","maximum":"is too long (maximum is 128 characters)"},"allow_blank":true,"minimum":6,"maximum":128}]},"user[role]":{"presence":[{"message":"can't be blank"}]}}}" action="/users" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="ccfkjL7QIt6kcFNVkn0Emu5bdXnt+DXVieim/YbPBXHiywdNiPE1u5qjyohRyK3MplNwyhJtG4T+I9ts9WGasQ==">
<div class="tab current-tab" data-target="form.tab">
<div class="form-group email required user_email"><label class="email required" for="user_email">Email <abbr title="required">*</abbr></label><input class="form-control string email required" autocomplete="email" autofocus="autofocus" required="required" aria-required="true" type="email" value="" name="user[email]" id="user_email"></div>
<div class="form-group password required user_password"><label class="password required" for="user_password">Password <abbr title="required">*</abbr></label><input class="form-control password required" autocomplete="new-password" required="required" aria-required="true" type="password" name="user[password]" id="user_password"><small class="form-text text-muted">6 characters minimum</small></div>
<div class="form-group password required user_password_confirmation"><label class="password required" for="user_password_confirmation">Password confirmation <abbr title="required">*</abbr></label><input class="form-control password required" autocomplete="new-password" required="required" aria-required="true" type="password" name="user[password_confirmation]" id="user_password_confirmation"></div>
</div>
<div class="tab" data-target="form.tab">
<div class="form-group select required user_role"><label class="select required" for="user_role">Role <abbr title="required">*</abbr></label>
<select class="form-control select required" name="user[role]" id="user_role">
<option value=""></option>
<option value="pj">pj</option>
<option value="manager">manager</option>
</select>
</div>
</div>
<div class="form-actions">
<button class="btn-orange" type="button" id="prevBtn" data-action="form#nextPrev" data-target="form.prevBtn" style="display: none;">Previous</button>
<button class="btn-orange" type="button" id="nextBtn" data-action="form#nextPrev" data-target="form.nextBtn">Next</button>
</div>
</form>
Browser’s development console output*
- [X ] I confirm that my browser’s development console output does not contain errors
Additional JavaScript Libraries*
Using JS framework Stimulus
Repository demostrating the issue
Debugging CSV issues is a time consuming task. If you want to speed up things, please provide a link to a repository showing the issue.
* Failure to include this requirement may result in the issue being closed.
Issue Analytics
- State:
- Created 3 years ago
- Comments:8 (4 by maintainers)
Sorry, this is not possible out of the box
Feel free to request it as a feature in the main repo at https://github.com/DavyJonesLocker/client_side_validations-simple, but I will label as
help-wanted
because I do not have resources to implement itYou can customize error rendering by following this guide: https://github.com/DavyJonesLocker/client_side_validations#customize-error-rendering
For your specific use case, I think this will work:
Note the changed line from the original file at https://github.com/DavyJonesLocker/client_side_validations-simple_form/blob/master/src/main.bootstrap4.js:
@isaporto thanks.
Much easier to replicate and debug.
The issue depends on dynamically added fields that are activated when
showCurrentTab
javascript is executedRef: https://github.com/DavyJonesLocker/client_side_validations/wiki/Validating-dynamically-added-forms
This should work