custom error display with parsley.js 2.x - javascript

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']);
}

Related

JQuery validate custom error message is not showing up

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");

Aurelia Validation - Stop property name appearing in error message

I'm using the new aurelia-validation packages and when a validation fails the error message that is created contains the property name. Quite often the underlying property name isn't very user friendly so you don't want to show it on the page.
ValidationRules
.ensure('isDeliveryAddressValid').required()
.on(this.order);
I have tried added a custom message to validation rules but this just appends something different on to my property name.
ValidationRules
.ensure('isDeliveryAddressValid').required({message:'must have a value.'})
.on(this.order);
Is there a way to remove the property name from the validation error so my validation renderer can show a better message?
This is a quirk of validate.js, the underlying validation engine for aurelia-validatejs. Searching through their docs I found:
If you need an error not to be prefixed by the attribute add a leading ^ to the error and it won't be prepended.
So something like this should work:
ValidationRules
.ensure('isDeliveryAddressValid').required({message:'^Delivery Address Valid must have a value.'})
.on(this.order);

Unable to get property '0' of undefined or null reference Lookup field

Recently lookup field in dynamic CRM form started throwing this error:
"Unable to get property '0' of undefined or null reference"
when we tried to change this lookup field. There is no Javascript called on Onchange event
I have attached a screenshot of the error:
In this case, if I did not know where this setaddionalparams function is located, my first move would be to disable all (or one by one) custom events on the form in the Handler Properties dialog that is called when you double click on the event handler in the Form Properties dialog in the Events tab (this one). If the error stops appearing then obviously the function is somewhere in your code.
Good luck!
UPDATE
There can be more reasons why you still see this error, please check scripts attached to the Ribbon, scripts inside HTML Web Resources and IFrames if you have any.
In addition, it may not be a direct call to the attribute by name, it may be a for loop that iterates through all attributes in the form. In this case you will need to search the code by the following keyword getValue()[0]. It seems like someone accesses a lookup attribute without checking if it's null. It should be fixed like this:
var productId = null;
var lookupValue = Xrm.Page.getAttribute("productid").getValue();
if (!!lookupValue && lookupValue.length > 0){
productId = lookupValue[0].id;
}

Displaying success/failure message on the form using dojo

I am creating a application using dojo 1.8.
I have a form with buttons to perform some action. Once the action is done, I get the status of the backend process execution. Currently I am using alert boxes to intimate user about the status. I know, it is very old fashioned. So what I am trying is: If the status is "success" then I will display a message (in green text) on the top of the form else the error message (in red).
For that in HTML file, I created two DIVs
<div id="successNotification" data-dojo-attach-point="successNotification"></div>
<div id="failureNotification" data-dojo-attach-point="failureNotification"></div>
and in the postCreate method, in requestCompleteCallback method of request.invokePluginService, I am trying to set the innerHTML of the DIV tag.
But below code always results in "successNotification is undefined" error.
if (ifSuccess == 'true' || ifSuccess )
{
var successNotification = dijit.byId("successNotification");
}
In the same block I have used dijit.byId("some other component") and that works fine.
what am I doing wrong?
I'm noticing several things here. First of all, your if code does not look valid (there's a ' after true).
Then, if you're creating custom widgets you should not retrieve widgets or DOM nodes by their ID, which means you should not use either:
dijit.byId()
dojo.byId()
dojo/dom::byId()
dijit/registry::byId()
The correct way is by using the attach points you created by using the data-dojo-attach-point attribute. When you inherit from the dijit/_TemplateMixin mixin, you can simply use: this.successNotification and if you inherit from dijit/_WidgetsInTemplateMixin as well, then you can use the same syntax to retrieve widget instances.
In your case it would be:
if (ifSuccess) {
var successNotification = this.successNotification;
}

Conditional call based on JSON data

I am trying to modify my Javascript page, which uses Ext Js library.(I don't have any idea about ext js, haven't worked on it either)
What I want To do is that based on the JSON DATA particularly the field "successProperty", I want to decide whether to upload the grid or give an alert.
What I can possibly do is to add an event to the class. but i don't Know how to do it.
Can someone give me a nice example which can help me out in achieving what i need .
Thanks.
please let me know if I need to give any more details
thanks again..
The 'successProperty' is not what you think. That property is used internally by ExtJS to know how to find out if the method had an error. Its a string containing the "name" of the property inside the returned JSON which will tell the ExtJS framework that something went wrong, and not the error status itself. So, that is why ExtJS let you "define" that property. And as your server side will be defined by you, you can choose any name you like for your success status, and if you choose something different than success (which is the default successProperty) then you define it in the successProperty configuration property of the JsonReader.
And the easy way to detect if an error happened when you load a grid is checking the 3rd parameter (called success) of the callback in the load method:
store.load({
params:{start:0, limit:15},
callback: function(result, options, success) {
if (!success) {
alert('error!!');
}
}
});
There are more generic ways of handling server side errors, instead of defining a callback on every store.load you can use:
// Listen to "exception" event fired by all proxies
Ext.data.DataProxy.on('exception', function(proxy, type, action, ex) {
alert('Error through DataProxy.exception at ' + type + '.'+ action);
});
Or if were already using Ext.Direct you could use its exception event (probably you are not using Ext.Direct, so don't expect it just work by itself):
Ext.Direct.on('exception', function(ex) { alert(ex.message); });
I put together a complete example with the first 2 ways of catching errors: http://jsfiddle.net/vZGvM/.
The example has no errors but you can simulate an error by pointing the url of the ScriptTagProxy to any invalid url (it will take a time to respond if you do that, but you will see both alerts).

Categories