Getting Parsley 2 working with Bootstrap 4 - parsley.js

By default, Parsley only handles updating a single element's class (usually the input field in which the invalid entry is). However, with Bootstrap 4 we must update both the form-group and the input field classes to render them with the validation icons. Otherwise, only the border colour is changed.
How can I use Parsley to correctly, completely style my input fields when validating user input in the client?

In order to correctly style Bootstrap 4 with Parsley, you must modify the classes of the div.form-group surrounding your input fields (assuming you want the validation icons, like I did).
According to the documentation you need to add .has-success or .has-danger to the div.form-group and then specify form-control-success and form-control-danger respectively to the input fields.
However, Parsley only supports updating the class on a single element by default. Fortunately, it supports event binding, so with a little function added to the end of your parsley.js file, we can handle updating the div.form-group styles when the user has fixed a validation error.
First configure Parsley:
errorClass: "form-control-danger",
successClass: "form-control-success"
These are the correct classes to apply to the input fields, which Parsley works on by default. Next, append the following to the parsley.(min).js file.
window.Parsley.on('field:validated', function(e) {
if (e.validationResult.constructor!==Array) {
this.$element.closest('.form-group').removeClass('has-danger').addClass('has-success');
} else {
this.$element.closest('.form-group').removeClass('has-success').addClass('has-danger');
}
});
The above will listen for when fields have been validated, and, hence update the relevant div.form-group according to the Bootstrap 4 documentation to ensure that the input field gets rendered appropriately.

Related

AngularJS: invalid input is not styled as invalid until I click on the input field and click out of it

I am setting input field to invalid from javascript like this:
$scope.formName.fieldName.$setValidity("string", false);
This is working, but it affects the view only after clicking in a input field and then clicking out of it.
How can I change it in order to see the invalid field immediatelly?
You'll need to attach an ng-change="checker(model)" to your input field. Then just apply an ng-class to it to check for formName.fieldName.$error.string (since you put string as the error key) or you can also do formName.fieldName.$invalid && !formName.fieldName.$pristine
I've attached this codepen for you to play around with and see how to apply an invalid class on the field without having to lose focus on it.
Hope that helps!

Parsley error message on hidden field

I need to validate a single selection row on a datatables. I don't know which is the best way it can be done. Right now I've put a hidden type input that is filled by javascript when the users clicks a row on datatables. When I validate form, parsley doesn't submit it if required hidden input is blank, but no error message is shown.
I've also tried to get field:error event, but it is not fired on hidden field.
window.Parsley.on('field:error', function() {
// This global callback will be called for any field that fails validation.
console.log('Validation failed for: ', this.$element);
});
Is there any way I can show with parsley a validation error message if hidden field is blank on form submit? I know I can do it without parsley, just checking if field is blank on submit, but as the other form fields are being validated through parsley I would like to know a way to show parsley error message somewhere in the form by parsley.
Assuming you have removed the "type=hidden" part of the excluded option, it should work fine.
Tip: You should trigger an 'input' event on your hidden field whenever you modify it.
Post a working example if it still doesn't work.

ExtJS -- tag field ignoring forceSelection flag on enter/blur

I'm using the Ext.form.field.Tag component. I have configured
createNewOnEnter:true,
createNewOnBlur:true,
forceSelection:true
but if I type in a value that's not the in the dropdown list/store records and tab-out or click enter the value gets selected. I want the value to be selected on enter/blur ONLY if it exists in the dropdown. But when createNewOnEnter and createNewOnBlur are set to true, forceSelection becomes false. I verified this by setting a debugger in the "change" event handler.
I dont have a fiddle but you can copy paste the above config into the live editor in the API Docs here
thanks
There are some configurations that are incompatible with each other, and ExtJS does not provide for all thinkable configurations of components (although they try, but then, Tagfield is quite new). This is the relevant part of the form/field/Tag.js file that explains your experience:
if (me.createNewOnEnter || me.createNewOnBlur) {
me.forceSelection = false;
}
To get what you want, you would have to override some parts of the tag field definition to suit your needs. You should look into overriding the assertValue and the onKeyUp functions.

AngularJS - Form validation triggered on load

I added field validation attributes like "required" and "pattern" in my form, and the form is inside a ng-controller. The validation works. But it seems the validations are triggered on page load, and I see all the fields are marked as invalid with error message when the page load.
I tried to add "novalidation" attribute to the form as indicated in the examples on AngularJS website, but no luck.
I would like to have the validation triggered the first time the user tries to interact with it. How can I do that?
Update
Here's an example https://jsfiddle.net/davidshen84/00t197gx/
<div class="mdl-cell mdl-cell-6-col mdl-textfield mdl-js-textfield">
<input class="mdl-textfield__input" type="text" id="screenname" pattern="[a-zA-Z0-9]{3,}" ng-model="comment.screenname" required/>
<label class="mdl-textfield__label" for="screenname">Screen Name</label>
</div>
On load, you should see all the input fields had a red line under them which indicate they are in the invalid state. And the line turns to blue once validated.
Note: The style on the check button does not work...should not be a concern in the problem.
Angular is going to check the form the same way at any point (load or later) and render the result. If you don't want to display the results on load, add logic to check whether the form has been interacted with. You can hide your error messages using ng-if="yourFormName.$dirty", or display according to the status of an individual field with yourFormName.yourFieldName.$dirty.
Click here for live demo.
What is currently implemented (wrong IMHO) is that MDL automatically validates input and doesn't mind "novalidate" form attribute. I had to implement check for empty input value (skip validation and remove is-invalid class) and, since angular form validation requires "novalidate" attribute, check:
if (input.form.novalidate = true) // skip validation
that way you can actually turn off mdl validation and leave everything to angular.
One more thing is actually required. You can create angular directive which validates expression and add is-invalid class if necessary:
div class="mdl-textfield" mdl-validator="form.email.$error"

ng-maxlength preventing a valid value from being databound to input field

I have the following field in a form:
<input type="text" name="dedicatedstaff" ng-model="staffingRecord.dedicatedStaff"
tabindex="9" ng-pattern="/^[0-9]{0,4}(\.[0-9]{1,2})?$/" ng-maxlength="7" />
The form is to edit an existing record. No matter what value is in the existing record, the field fails validation and the databind becomes undefined. Some example values that exist on the records are 1, 2.5, 12.5, 99.25, 4.0. I believe every one of these should pass both the pattern and maxlength validations, but it isn't working. I've checked the model and the values are present when loading the form.
When I remove the ng-maxlength directive and just have the ng-pattern, it works fine and those values pass validation. If I remove ng-pattern and just have max-length, it fails. It also doesn't matter if the INPUT is of type text or number. If ng-maxlength is present, it fails. Browser also does not make a difference (tested Chrome, IE & Firefox). I have also verified that it is the maxlength error in the error list.
I am also using ng-maxlength with almost every other field on this particular form, and they also work just fine. And if I type the exact values listed above after form load when ng-maxlength is present validates fine at that point. But that's not a reasonable workflow to make the client type the values over again every time they load the form.
I don't understand it as I use this same pattern in other forms within the app and they work fine. I can get by with just ng-pattern on this particular field, but I would much rather figure out why, in this one case, it won't validate properly on load.
I'm using AngularJS 1.2.14, with JQuery 1.9.1.
I figured it out. It was actually the INPUT type after all. After further testing, I realized my initial test of that variation was incorrect. Changing the INPUT type to NUMBER fixed the validation issues.
<input type="number" name="dedicatedstaff" ng-model="staffingRecord.dedicatedStaff"
tabindex="9" ng-pattern="/^[0-9]{0,4}(\.[0-9]{1,2})?$/" ng-maxlength="7" />

Resources