Angularjs custom validation directive Async call real time validation - ajax

I am using custom validation directive to validate a field in a form and the validation process includes a AJAX call to verify user information with server API. We want to validate the field as long as user stops typing for a certain period of time.
I have two questions:
1.Why is the function below not working?(with link function in the custom directive) The log message was never shown no matter how many times I type in the binded input field (I am pretty sure I enabled log message display since other logs were shown correrctly)
scope.$watch(attrs.ngModel, function() {
$log.debug("Changed to " + scope.$eval(attrs.ngModel));
});
2.What is the best way to detect that the user has stopped typing for the program to execute the validation process? And is it possible to cancel the validation process before it is finished if user starts to type again?

attrs.ngModel will equal the string value in the html context. What you want to do is bind the ngModel value to the directive's scope:
scope: {
model: '=ngModel'
}
Then watch the directives scope:
scope.$watch("model", function() {
console.log("Changed");
});
example: http://jsfiddle.net/BtrZH/5/

Related

Where i need to put validation code?

I have a form with a number of fields.
Some of them are userId, userFirstName, userLastName.
When user inputs incorrect userId value then near userId field page must show error message and add this error into validationSummary(this is standart behavior for asp.net mvc unobtrusive validation). If userId is correct then page must remove errors and autopopulate userFirstName and userLastName(This is not standart behavior)
How can i implement this?
Here is what come to my mind:
Remote validation attribute
It has a bad customization in my case. That's why i decide to don't use it.
Add special method for jquery validation plugin ( for example
jQuery.validator.addMethod("userIdValidation", function(value, element) {
//some logic
return something;
}, "Please specify the correct userId"); )
and put there logic for validation and for autopopulate other fields.
In this case i mix validation and other stuff.
3 . Add special method for jquery validation plugin ONLY for validation and add special handler for input change event for autopopulate.
In this case i need to send TWO ajax requests to server for one thing. And ofcourse it is not good too. So what is the right way? I am confused.
Have you thought about using a partial view to display the userFirstName and userLastName?
You can fire an AJAX request that sends the userId, and then returns a partial view of the name fields. Within the controller being called, you can validate the incoming userId, and then grab the name details in one query. If thevalidation fails, you can return the partial view with empty fields.

Real-Time Validations in Backbone-Forms

I am using Backbone-Forms and have created a model with the following schema:
schema:
title:
type: "Text"
validators: ["required"]
description:
type: "TextArea"
validators: ["required"]
location:
type: "Text"
validators: ["required"]
When I try and submit the form with empty fields, the validation correctly takes place and they all receive the error class.
However, when I then update an input to have content, the error class doesn't get removed from my input until I try and submit the form again.
Likewise, if I originally enter a valid input and then delete all content, it doesn't inform me of an error until I try and submit the form again whereas I would like to know immediately.
Is there a way to trigger validation on a modified input field?
From the docs: http://backbonejs.org/#Model-validate:
isValidmodel.isValid()
Models may enter an invalid state if you make changes to them silently ... useful when dealing with form input. Call model.isValid() to check if the model is currently in a valid state, according to your validate function.
also from https://github.com/thedersen/backbone.validation#what-gets-validated-when
What gets validated when?
If you are using Backbone v0.9.1 or later, all attributes in a model will be validated. However, if for instance name never has been set (either explicitly or with a default value) that attribute will not be validated before it gets set.
This is very useful when validating forms as they are populated, since you don't want to alert the user about errors in input not yet entered.
If you need to validate entire model (both attributes that has been set or not) you can call validate() or isValid(true) on the model.
The Backbone-Forms docs specifically mention model.validate:
https://github.com/powmedia/backbone-forms#model-validation
You could easily hook model.Validate up to whatever edit events or click events you want.
Also, you might find this useful (not sure if it is compatible with Backbone.Forms though):
https://github.com/thedersen/backbone.validation
The way you can do "Real-Time Validations" with Backbone-Forms is by extending the Backbone.Form model and attaching event(s) to call your custom method(s) to validate the field, then just "new"ing your custom form instead of Backbone.Form
(Backbone.Form is just a subclass of Backbone.View)
Here's some sample code:
var MyCustomForm = Backbone.Form.extend({
events: {
"blur input": "validateRealTime"
},
validateRealTime: function(e){
if(e.currentTarget.value == "") return;
var err = this.fields[e.currentTarget.name].validate();
if(err)
myDisplayErrorMethod(err.message);
}
});
The great thing about this is that it'll utilize the validators you defined in the model schema so you get all the same validations and messages you defined there as well (if you actually did define custom mesesages).
Also if you defined several validators as I did, each time the user "blur"s from the field, it'll call your validators in order until all validators pass. So that was a plus.
Side note, you'll notice I did if(e.currentTarget.value == "") return;. That's just my use case, I didn't want to show errors just because users clicked and clicked away.

Backbone.js: run validations and fire error events on set, but don't abort set if validations fail

I've got a Backbone model with a custom validate method that validates the format of one of a the model's attributes. My model is hooked up to a view that exposes said attribute via a text field. The view has a 'save' button that the user must explicitly press to save the model changes back to the server.
When the user types an invalid attribute value, I want to visually mark the field as being in an invalid state. So far, easy - I can bind the change event of the input field to a function that calls myModel.set({ attribute: value }), and listen for the "error" event on the model to tell when the validation has failed and I should mark the input as invalid.
The problem comes when I want to handle the save button click. Because Backbone.Model.set aborts actually setting the attributes on the model if validation fails, my model will not accurately reflect the value the user has entered unless the value is valid. When the user clicks save after typing in an invalid value, I check whether the model is valid, find that it is (because the invalid attribute was never actually set), and save the old (valid) attribute value to the server.
What it seems like I want is a version of set that always makes the requested changes, but also still triggers validations and events. set(..., { silent: true }) will allow the change to go through, but will not run validations or trigger events.
In short - I want my model to sometimes exist in an invalid state (if the user has entered invalid attribute values), and I want to be able to get events when it transitions between valid and invalid. Is there a graceful way to do this with backbone, or am I thinking about this completely wrong?
I suggest you use this backbone validation plugin https://github.com/thedersen/backbone.validation
Extremely helpful.
For your usecase (to allow values to be set even if they are invalid),
you just need to do override the set function of your model.
set: function (key, value, options) {
options || (options = {});
options = _.extend(options, { forceUpdate: true });
return Backbone.Model.prototype.set.call(this, key, value, options);
}
The 'forceUpdate' property of backbone.validation allows the validate method to return true, while still calling for validations.
After the save click, you can call,
var errors = model.validate(model.validate.attributes);
This will return all the errors that your model has and you can appropriately display them.
You also have callbacks for valid and invalid which you can use freely
What I've done with this sort of validation is to reset the models attributes from the inputs before save on the save click (only doing the save if the set doesn't fail)
This way the save button click re triggers the validation - triggering the error.
It means the model is always valid and you cant progress to the next page until the input is all valid.

First time jQuery $.post takes an extraordinarily long time, subsequent times normal

On a webpage we have the following system of server side form validation. For example, if the user is adding date-details for an event (and an event can contain many such date-details), we call a javascript function on click of the 'Add' button like below.
validateForm('frmName','codelibrary/classes/myclass.php','validationArrName')
where:
#frmName = form name
#codelibrary/classes/myclass.php = location of class file, that contains classes and functions for server side validation
#validationArrName = Type of validation we apply
In the php script, validationArrName is defined as a list of keys (representing form fields) and values (representing the functions we will call to validate that form field).
validationArrName = array ('fieldName1'=>validationFun1,'fieldName2'=>validationFun2);
eg:
fieldName1 = email_address
validationFun1 = validateEmail()
On the html page, we call the server side validation through ajax as follows.
$.post(className,$("form[name="+formName+"]").serialize()+"&isValidate=1&validateArrayName="+validateArrayName,function(data){ ... });
If the validation function reports an error, we display an appropriate error message back on the html page.
The problem is that when we do this for the very first time (eg: after a hard refresh of the page), submitting this date-details form for validation takes a lot of time, as compared to subsequent requests.
We observed that instead of calling the codelibrary/classes/myclass.php file once, it actually refers to this file more than 10 times before jumping to the required location (validationArrName) and running that.
For subsequent requests, it works fine and refers to that file only once.
What could be the issue here? Could there be an issue with our usage of jquery submit ?
the best thing you can do is time stuff.
in javascript:
console.time('post load'):
$.post(className,$("form[name="+formName+"]").serialize()+"&isValidate=1&validateArrayName="+validateArrayName,function(data){
console.timeEnd('post load');
console.log('data');
...
});
in php, use microtime to time different part and echo them. they will be printed in the console.
It should not be cache or include related, as ajax starts a new connection each time.
Following your comments, I edit this answer:
I'm still at loss of what happens. However I see two possibilities. The first one is that you use a "flag" to validate forms or not. When you load the page, all forms flag are unset, and first submit check them all. Subsequent submits works correctly.
Another option is that the first time you submit a form, you dont event.preventDefault() on the submit click, but it's still a loosy explanation.
I would love to see how you call the $.post(...) function (how the submit button is binded, or how $().submit() is called).

Validate data from CakePHP form with jQuery (AJAX)

I would like to validate both single field and multiple field data from a CakePHP form.
The single field validation should be done on blur from each field while the multiple field validation should be done on submitting the form.
I would like to use the $validate property declared in the Model for validating data and I would like to display the errors near each field (single field validation) and on top of the form (for multiple field validation).
My main goal is to achieve this the most "caky" way (if there is one for validating data with jQuery). I couldn't find any useful advice out there and I'm asking you for some help to get this going.
One of my concerns is how shall I pass data from the form to jQuery and then to the action that does the validation and also how shall I return and display the errors, if there are any.
Thank you in advance!
I'd suggest first making sure everything works without jQuery, then use the jQuery Form plugin to submit your forms via AJAX. If you include the RequestHandler component in your AppController, you should find that your controllers distinguish automatically between AJAX and synchronous requests.
OK, so I coded my own solution to this, but I am still waiting for a more "caky" approach.
I made two generic jQuery functions, one for single field validation and one for multiple field validation. The function should grab the data from the specified form and send it to the form's action via AJAX, to a specially created controller method which will attempt to validate data and output an AJAX response ("" for validation has passed and errors for errors in validation). Then, the result is checked in the jQuery function and the default form behaviour is triggered only if the validation has passed. Otherwise, display the errors and return false; to prevent default submission.

Resources