JQuery validate custom error message is not showing up - javascript

Following is the form validation javascript in my application:
$('#EmploymentHistoryForm').validate({
ignore: ':hidden, [readonly=readonly]',
rules: {
'MemberJob.Phone': {
PhoneFieldValidation: true
}
},
messages: {
'MemberJob.Phone': {
PhoneFieldValidation: $.viewUrl.url.invaliedPhoneMessage
}
},
showErrors: function (errorMap, errorList) {
ShowErrors(errorMap, errorList, this.validElements());
},
submitHandler: function (form, event) {
event.preventDefault();
return false;
}
});
Here, $.viewUrl.url.invaliedPhoneMessage is set at the cshtml page (in ASP.NET MVC), and while debugging the javascript I can see proper value in that variable when $('...').validate function gets hit.
I have registered a new validator "PhoneFieldValidation" in JQuery validators collection:
$.validator.addMethod("PhoneFieldValidation", ValidatePhoneAndAltPhone);
Following is the rendered HTML for the input control for which I have added this validation rule:
<input class="PhoneFieldValidation" id="MemberJob_Phone" name="MemberJob.Phone" type="text" required="required" aria-required="true">
I can see the validation getting fired correctly. That means, "ValidatePhoneAndAltPhone" method is getting called, and returning a boolean result based on the input.
However, the error message is not getting displayed properly. It displays "Warning: No message defined for MemberJob.Phone" instead of "Invalid Phone Number".
While debugging through customMessage function of jquery.validate.js, I could see "this.settings.messages" collection is not having the message for "MemberJob.Phone" field, and that looks to be the root cause of this issue.
Any idea of how to resolve this issue?
I know we can add "data-msg-[rulename]" attribute in the HTML tag which will fix the issue. But I am sure the current approach I am following is also correct. Seems I am missing something.
Any help on this will be much appreciated.
Thanks

You never mentioned where $.viewUrl.url.invaliedPhoneMessage comes from.
If there is already a message defined in your custom PhoneFieldValidation method, then you would not define a message within the messages object.
Otherwise, you cannot use a JavaScript variable within the messages object without a function.
The whole problem is being caused by the Unobtrusive plugin which is automatically constructing the .validate() method call. You cannot call .validate() more than once on the same form; and all subsequent calls are ignored. Instead, you can simply define the custom message for PhoneFieldValidation within its .addMethod() method.
$.validator.addMethod("PhoneFieldValidation", function(value, element) {
// your custom method function here;
}, "This is your custom validation error message");

Related

Parsley Custom Validator with JS Promise

I have reached out in several place and the help has been good but hasn't managed to make it work for me.
Hopefully you guys can help me here.
I am using JS inside a template page of a Flask application. I am using parsley validation to verify a web form. I have also created a custom validator which should ajax call with axios to the back end to determine if an email address is already registered.
My Flask Backend returns a boolean string to my html page. All of this looks right. I am getting back the right value. However when I return out of my ".then" function in my axios function the Parsley validator doesn't work/respond.
If i remove the axios POST call. and just simply say "return false" or "return true" the function works. The validation message is returned to the screen.
So there appears to be an issue with putting the return statment inside my .axios .then function?
Could some one see if I am doing anything wrong here? I cannot for the life of me work out why it doesn't work.
Thanks.
Tim.
I have included the FAILING JS Code here.
<script type="text/javascript">
window.Parsley.addValidator('existingEmail', {
validateString: function(value) {
// Performing a POST request
var promise = axios.post('/api/v1.0/existingEmailCheck', {email : value})
.then(function(response){
var result = (response.data.toLowerCase() === "true");
console.log(result)
return result
});
console.log(promise)
return promise
},
messages: {
en: "This email address has already been registered.",
}
});
</script>
I have also included a slightly modified (without axios call) code that works here.
<script type="text/javascript">
window.Parsley.addValidator('existingEmail', {
validateString: function(value) {
var string = "false" //This Simulates the Incoming Data.
var result = (string.toLowerCase() === "true");
console.log(result)
return result //Always returns false (due to hard coding)
//However this means that it triggers the error message and validation fails
//When you change the string to "true" it works as expected and validates
},
messages: {
en: "This email address has already been registered.",
}
});
</script>
The example works as expected. Which leads me to believe the error in the first code example is somewhere between the call and the IF ELSE that returns the False or True
Any help people can give me would be awesome!
I think you need to return a jQuery promise instead of whatever axios returns (native promise?).
FWIW, it looks like you could use the builtin remote validator.
Just attempted to use Axios myself (Wanted to do away with jQuery and it's huge library). Ended up creating a AsyncValidator (uses Ajax behind the scenes).
In your HTML just import jQuery and Parsley
<script src="/js/jquery-3.3.1.min.js"></script>
<script src="/js/parsley.min.js"></script>
Define your DOM element to support remote validators
<input id="id" class="form-control" name="id" type="text" data-parsley-remote data-parsley-remote-validator='checkExists' placeholder="Username / ID" data-parsley-checkExists="" data-parsley-minlength="5" data-parsley-required-message="Please enter username / id" required>
In your index.js file, add you Async validator.
Parsley.addAsyncValidator('checkExists', function (xhr) {
return false === xhr.responseJSON;
}, '/data-management/verify-data?filter=signup');
The resulting Ajax request being made is /data-management/verify-data?filter=signup&id=value value being the value of the input field.
That ended up working for me. Let me know if you need help.

How to use HTML form.checkValidity()?

Reading a website's source code that uses MVC, I struggled trying to understand some of it.
Code snippet of the view:
function submitForm (action) {
var forms = document.getElementById('form')
forms.action = action
if (forms.checkValidity()) {
forms.submit()
} else {
alert('There is still an empty field')
}
}
I want to execute some code if the form is missing certain inputs.
checkValidity() is a HTML5 method and
When the checkValidity() method is invoked, if the element is a candidate for constraint validation and does not satisfy its constraints, the user agent must fire a simple event named invalid that is cancelable (but in this case has no default action) at the element and return false. Otherwise, it must only return true without doing anything else.
Please learn more about how to use form validation constraints here.
There are number of useful methods you can use, customize and even build custom validation methods.
You also can find basic explanation and examples in w3schools.
Hope this helps.
For Me this works in jQuery
$('#formSection')[0].checkValidity();
just use a required
Example
<input type"text" id="id" required>
if you press the submit button there an alert text saying PLEASE FILL OUT THIS FIELD

What is the specific validation error when validationError=true in an openFaces component

I'm using openFaces' dateChooser and I set a pattern.
If I put in it a wrong value (like: 33/33/33) and try to submit the validationError is set to true because of the wrong format but I don't know how to get the specific error message or component that caused the validation error.
Here is a part of my code:
<o:dateChooser
id="DateColBtnGeneralView"
pattern="#{configurationController.defaultDateFormat}"
value="#{homeController.firstDate}">
<f:convertDateTime pattern="#{configurationController.defaultDateFormat}"/>
</o:dateChooser>
<o:commandButton
action="#{homeController.submitDates}"
onsuccess="contractClientDialogValidation(event)
value="Submit" />
function contractClientDialogValidation (event) {
if (event.validationError) {
alert("I want to show you the right error message according to the wrong value and component");
}
}
The validationError is set to true in case a required component is left empty or in case of an incorrect date format or in case an input number is too long or etc.
The validation errors are primarily related to the UpdateModelValues and InvokeApplication phases within the JSF lifecycle.
Inside your <h:form/> element you can choose to have a <h:messages id="errorMessages"/> tag.
When the ajax request/response lifecycle is complete, render the <h:messages/> tag.
See point 3 of this link

custom error display with parsley.js 2.x

I need to show a list of validation errors in a popup.
I've disabled UI modification with <form data-parsley-ui-enabled="false"... and subscribed to the "parsley:field:error" event, where I collect error information, and then on "parsley:form:validated" I display the popup, ofcourse only on the condition isValid() == false.
But I am having problems with getting the actual error message in the "parsley:field:error" handler. The handler gets a single parameter containing an object, which so far I inspected to have several properties:
$element - the actual jQuery field,
constraints - list of constraints
options.i18n - it has some raw error message strings which I can get iterating with an n variable like so: obj.options.i18n.<LANGUAGE_CODE>.[obj.constraints[n].name], but they ocasionally contain placeholders (%s) and therefore are not suitable for display to the end
user; and sometimes there's an array instead of a single string, which defeats the idea completely;
The question is, how do I get the actual error message which would got displayed if I hadn't disabled the UI?
Solution
Use the following way to access a prioritized error message (i.e data-parsley-priority-enabled=true):
$.listen('parsley:field:error', function(parsleyField) {
// parsley field
console.log(parsleyField);
// which constraint has failed
console.log(parsleyField.validationResult[0].assert.name);
// the data-parsley-<constraint>-message
console.log(parsleyField.options[parsleyField.validationResult[0].assert.name+'Message']);
// the default constraint fail message
console.log(window.ParsleyValidator.getErrorMessage(parsleyField.validationResult[0].assert));
});
Short Explanation
You were almost there, the messages are stored in the options object itself, and the format for the message is like this: <constraint>Message, for example: requiredMessage.
Which is similar to the "data attribute to js variable conversion" convention like in jQuery, this has been mentioned in the docs: <parsleynamespace>-<constraint>-message becomes <constraint>Message.
Got this idea after seeing the annotated source for ui.js, check the _getErrorMessage function.
To access all the validation messages for a field on error (i.e data-parsley-priority-enabled=false), you can simply iterate through the
parsleyField.validationResult array:
for (i=0; i<parsleyField.validationResult.length; i++) {
console.log(parsleyField.options[parsleyField.validationResult[i].assert.name+'Message']);
}

"query function not defined for Select2 undefined error"

Trying to use Select2 and getting this error on multiple item input/text field:
"query function not defined for Select2 undefined error"
Covered in this google group thread
The problem was because of the extra div that was being added by the select2. Select2 had added new div with class "select2-container form-select" to wrap the select created. So the next time i loaded the function, the error was being thrown as select2 was being attached to the div element. I changed my selector...
Prefix select2 css identifier with specific tag name "select":
$('select.form-select').select2();
This error message is too general. One of its other possible sources is that you're trying to call select2() method on already "select2ed" input.
In case you initialize an empty input do this:
$(".yourelement").select2({
data: {
id: "",
text: ""
}
});
Read the first comment below, it explains why and when you should use the code in my answer.
I also had this problem make sure that you don't initialize the select2 twice.
For me this issue boiled down to setting the correct data-ui-select2 attribute:
<input type="text" data-ui-select2="select2Options.projectManagers" placeholder="Project Manager" ng-model="selectedProjectManager">
$scope.projectManagers = {
data: [] //Must have data property
}
$scope.selectedProjectManager = {};
If I take off the data property on $scope.projectManagers I get this error.
This issue boiled down to how I was building my select2 select box. In one javascript file I had...
$(function(){
$(".select2").select2();
});
And in another js file an override...
$(function(){
var employerStateSelector =
$("#registration_employer_state").select2("destroy");
employerStateSelector.select2({
placeholder: 'Select a State...'
});
});
Moving the second override into a window load event resolved the issue.
$( window ).load(function() {
var employerStateSelector =
$("#registration_employer_state").select2("destroy");
employerStateSelector.select2({
placeholder: 'Select a State...'
});
});
This issue blossomed inside a Rails application
I also got the same error when using ajax with a textbox then i solve it by remove class select2 of textbox and setup select2 by id like:
$(function(){
$("#input-select2").select2();
});
It seems that your selector returns an undefined element (Therefore undefined error is returned)
In case the element really exists, you are calling select2 on an input element without supplying anything to select2, where it should fetch the data from. Typically, one calls .select2({data: [{id:"firstid", text:"firsttext"}]).
Also got the same error when using ajax.
If you're using ajax to render forms with select2, the input_html class must be different from those NOT rendered using ajax. Not quite sure why it works this way though.
if (typeof(opts.query) !== "function") {
throw "query function not defined for Select2 " + opts.element.attr("id");
}
This is thrown becase query does not exist in options. Internally there is a check maintained which requires either of the following for parameters
ajax
tags
data
query
So you just need to provide one of these 4 options to select2 and it should work as expected.
I got the same error. I have been using select2-3.5.2
This was my code which had error
$('#carstatus-select').select2().val([1,2])
Below code fixed the issue.
$('#carstatus-select').val([1,2]);
I have a complicated Web App and I couldn't figure out exactly why this error was being thrown. It was causing the JavaScript to abort when thrown.
In select2.js I changed:
if (typeof(opts.query) !== "function") {
throw "query function not defined for Select2 " + opts.element.attr("id");
}
to:
if (typeof(opts.query) !== "function") {
console.error("query function not defined for Select2 " + opts.element.attr("id"));
}
Now everything seems to work properly but it is still logging in error in case I want to try and figure out what exactly in my code is causing the error. But for now this is a good enough fix for me.

Categories