I have a beginner's question on Formvalidation.io. Maybe it's not even specific for that library but more related to Javascript in general.
I'd like to disable a validator after a certain field (let's say its name is postcode) has been validated and is valid. However, all my approaches result in either the validator not being disabled or being disabled if any field of my form is valid (not only the specific one).
I use the core.field.valid event and the library's documentation states:
The event parameter presents the field name.
I'm uncertain how that happens.
I tried:
document.addEventListener('DOMContentLoaded', function(e) {
const fv = FormValidation.formValidation(
document.getElementById('adminForm'),
{
fields: {
postcode: {
validators: {
notEmpty: {
message: 'Please enter a postcode.'
}
}
}
},
plugins: {
submitButton: new FormValidation.plugins.SubmitButton(),
defaultSubmit: new FormValidation.plugins.DefaultSubmit(),
trigger: new FormValidation.plugins.Trigger({
event: {
postcode: 'change',
}
})
}
}
);
fv.on('core.field.valid', function(e) {
if (e.field === 'postcode') {
fv.disableValidator('postcode');
}
});
});
But the if-condition is not true even when the field is validated and valid.
(tried to adapt it from the example given here)
I also tried what I found in the documentation on the on() method (as it states regarding function(field): "field is name of invalid field"):
const validFieldHandler = function(postcode) {
fv.disableValidator('postcode');
};
fv.on('core.field.valid', validFieldHandler);
Result is the same (validator is not disabled).
The following however (as probably to expect) disables the validator if any field of the form is valid.
fv.on('core.field.valid', function(e) {
fv.disableValidator('postcode');
});
Thank you for any advice you can offer! It's my first question here, so please let me know if you need additional information!
Best regards,
Sebastian
Found the solution myself:
fv.on('core.field.valid', function(field) {
if (field === 'postcode') {
fv.disableValidator('postcode');
}
});
Related
So I have the following select2:
productFamilySelect.select2({
tags: true
});
By default the name of the associated select element is product_family_id, so is there a way to change the name of the input to lets say product_family_name, if selected value if one that user entered? This is so, that I could in the backend for sure distinguish between an already existing value, and one that user thought of. Checking by id in the database does not really suit, as this value could actually be numeric in on itself.
After some digging into select2 custom events I found a way:
firstly add createTag callback like so:
productFamilySelect.select2({
tags: true,
createTag: function (params) {
var term = $.trim(params.term);
if (term === '') {
return null;
}
return {
id: term,
text: term,
newTag: true
}
}
});
Then, add the following listener:
productFamilySelect.on('select2:select', function (e) {
if (e.params.data.newTag === true) {
$(this).attr('name', 'product_family_name');
} else {
$(this).attr('name', 'product_family_id');
}
});
Seems a bit hacky, since it is outside the config of the actual select2 config, but well it dos the job :)
I'm using the bootstrap validator plugin to valid my form client side and it seems to fail when revalidating a summernote textarea. It validates the first time, but when the text is updated the validation doesn't update.
Here's the validation (snipped out other validation fields)
function validateEditor() {
// Revalidate the content when its value is changed by Summernote
$('#application-form').bootstrapValidator('revalidateField', 'application'));
};
$('.application-form')
.bootstrapValidator({
excluded: [':disabled'],
fields: {
application: {
validators: {
callback: {
message: 'Please do not leave this blank.',
callback: function(value, validator) {
var code = $('[name="application"]').code();
// <p><br></p> is code generated by Summernote for empty content
return (code !== '' && code !== '<p><br></p>');
}
}
}
}
}
}).on('success.form.bv', function(e) {
e.preventDefault();
console.log('Form successfully validated.');
})
.find('[name="application"]')
.summernote({
height: 400,
onkeyup: function() {
validateEditor(); // Revalidate form onkeyup
},
onpaste: function() {
validateEditor(); // Revalidate form on paste
},
});
Here's the markup (again snipped from other fields)
<div class="form-group">
<textarea name="application"></textarea>
</div>
This is a huge issue because if the textarea is left blank the first time, the form can never be resubmitted since the validation doesn't update when the error is fixed by the user.
I had the same problem, but with FormValidation.io, which is a very similar plugin.
Solution : My textarea had the required attribute. I removed it and bam, problem solved.
Now, I'm genuinely sorry if this isn't a direct solution to your problem, your code obviously doesn't have the required attribute, but I just thought I'd share with other people still, because this was driving me nuts for hours and this was the most relevant post about this problem on here.
That is all.
Got a quick question about a form validation using jQuery. So I have huge-butt form, which is validated and submitted properly. The only problem I keep running into is that when I try to submit it, and the form is invalid, the window does not scroll to the invalid field. It tries to - the view sort of jumps about half an inch above the submit button and that's it - the invalid field is not actually shown on the page. In terms of the jQuery default settings on the validator, I have the following code:
$.extend($.validator, {
defaults: {
messages: {},
groups: {},
rules: {},
errorClass: "error",
validClass: "valid",
errorElement: "label",
focusInvalid: true,
errorContainer: $([]),
errorLabelContainer: $([]),
onsubmit: true,
ignore: ":hidden",
ignoreTitle: false,
}
When the validator runs, this is the focusInvalid() function definition:
focusInvalid: function() {
if ( this.settings.focusInvalid ) {
try {
$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
.filter(":visible")
.focus()
// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
.trigger("focusin");
} catch(e) {
// ignore IE throwing errors when focusing hidden elements
}
}
},
Finally, on form validation:
if ( validator.form() ) {
if ( validator.pendingRequest ) {
validator.formSubmitted = true;
return false;
}
return handle();
} else {
validator.focusInvalid();
return false;
}
focus isn't the correct function for scrolling the page to a particular element. You need scrollTop, or a similar function. There are several questions about this, I like this answer which includes a simple example, and even includes the alternative solution with animation.
Thanks guys! It was fixed by having the script add custom classes to the invalid forms and focusing on them. We tried scrollTop, but that didn't work at all, so we went with a focus scenario. The invalidHandler function code is below for anyone who's interested:
// invalidHandler to set focus to invalid controls
invalidHandler: function(event, validator) {
var $invalidElement = $(validator.errorList[0].element);
if ($invalidElement.hasClass('chosen-select')) {
$invalidElement.trigger('chosen:activate');
} else if ($invalidElement.siblings('ul.token-input-list').length > 0) {
var $inputToken = $invalidElement.siblings('ul.token-input-list').find('input');
$inputToken.focus();
}
}
We're working on a Kendo UI grid that is bound to REST endpoint. The messaging portion is working great.
Where we're having trouble is trying to mask a phone number input. We like the following behavior:
1) User clicks into phone number cell.
2) User enters 1234567890.
3) When leaving the cell, the format is changed to (123) 456-7890.
We looked already at custom formats. Those seem date/time and number specific. I haven't found a way to do a custom format for a string column.
We also looked at doing this with a formatPhoneNumber function that is called on each cell's change event. I'm not happy with that approach, though it does work.
Here is the base code for the grid. I'd like to just find a way to include a custom format, or bind to a function when defining the column or field properties.
EditGridConfig = function() {
var self = this;
self.gridConfig = {
columns: [
{ field: 'PhoneNumber', title: 'Phone Number', width: '150px' },
],
data: [],
toolbar: [
{ name: "save" },
{ name: "cancel" }
],
dataSource: {
type: "json",
transport: {
read: "/api/BusinessEntity",
update: {
url: function(parent) {
return "/api/BusinessEntity/" + parent.Id;
},
dataType: "json",
type: "PUT"
}
},
schema: {
model: {
id: "Id",
fields: {
PhoneNumber: { type: "string" },
}
}
}
},
editable: "incell"
};
self.selectedData = ko.observable();
};
Here is the change event and formatPhoneNumber function we are using to get the phone number to format when focus leaves the cell. I'm just not happy with this approach, and am looking for a "cleaner" way to do it.
change: function (e) {
if (e.field == "PhoneNumber") {
console.log('before' + e.items[0].PhoneNumber);
e.items[0].PhoneNumber = formatPhoneNumber(e.items[0].PhoneNumber);
console.log('after' + e.items[0].PhoneNumber);
}
}
function formatPhoneNumber(number) {
return number.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
}
Thanks much for any suggestions!
Sorry for answering my own question. I thought I would add some more detail along the lines of #James McConnell's answer so other people won't struggle like I did trying to wire up the jQuery.on event with the .mask function.
Thanks to James' hint, I wound up using the Masked Input jQuery plugin and wiring up to dynamically created events using jQuery.on.
Here is the helper function I wrote (simplified for example):
applyDynamicInputMask = function(container, selector, event, mask) {
$(container).on(event, selector, function() {
var $this = $(this);
$this.mask(mask);
});
};
And to call it:
applyDynamicInputMask(document, "[name='PhoneNumber']", 'focusin', "(999) 999-9999");
edit: function (e) {
//if edit click
if (!e.model.isNew()) {
$('input[name=Time]').attr("data-role", "maskedtextbox").attr("data-mask", "00:00");
//init mask widget
kendo.init($('input[name=Time]'));
}
}
Have you tried a jQuery plugin? We use this one at work:
http://digitalbush.com/projects/masked-input-plugin/
You can bind the plugin to any jQuery selector, so just slap a custom class on the input that needs formatted, and use that to hook up the plugin. Not sure if this is a viable solution, but it's what I've used in the past. HTH! :)
I want to display a parsley message in an else clause of my javascript code:
if ( ...is valid ) {
//do things
} else {
//display parsley error
}
I know that Parsley allows custom validators as documented here: http://parsleyjs.org/documentation.html#javascript
But I merely want to display the message until the field is modified. I could create a validator such as:
$( '#myInput' ).parsley( {
validators: {
alwaysFalse: function ( val ) {
return false;
}
}
, messages: {
myMessage: "Form is invalid"
}
});
But then how would I trigger this and only this validator? (There is another validator already attached)
your messages object should be a mirror of your validators object but with the messages to display.
messages: {
alwaysFalse: "Form is invalid"
}
and you could try
validators: {
alwaysFalse: function(val){
return false;
},
required: function ( val ) {
return false;
}
}
also
Warning : you must remove parsley-validate auto-binding code in your forms DOM to allow you to override the default processing and use Parsley purely from javascript.
it seems like what you really want this: http://parsleyjs.org/documentation.html#parsleyfield
check out parsley-error-container
the trigger should be $( '#myInput' ).parsley( 'validate' );
or not 100% sure on this but you should be able to call each one like this:
$( '#myInput' ).parsley('alwaysFalse');
and if they need inputs or data:
$( '#myInput' ).parsley('alwaysFalse','inputs','data');