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.
Related
What would be the best way to create validator that checks if model value is unique or not, but it does not return false - it only shows message "the value already exists" (I can still save the model)?
Validators usually don't return boolean values, they add errors for given model attribute(s).
One of the ways (with minimal completions) will be using built-in UniqueValidator and saving without running validation.
At first call $model->validate() to fill model with errors.
You can use $model->validate('fieldName') to validate only needed field.
Then call $model->save(false) or $model->save('fieldName') (for just one field).
This will prevent validation before saving and model values will be saved "as is".
Another way for just saving one attribute without triggering events, etc. will be using updateAttributes after calling validate():
$model->updateAttributes(['fieldName' => 'fieldValue']);
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/
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.
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.
I've been search for quite a while and haven't been able to find an answer to this.
I am using asp.net MVC 3 with unobtrusive validation. My model is bound with data annotations for simple validation (required fields, regex, etc..). However, I have more complex validation that occurs on the server. I'm doing an ajax post which returns me validation add'l messages that come from my domain model. All I want to do is put those validation messages on the form in the place of the existing ones. I don't want to use partial views since all I've really got are messages coming back and there isn't a need to refresh the whole view. Also, I'm not adding new rules or new inputs to the form so $.validator.unobtrusive.parse won't work. These are just messages I want to put on the form. The $.post call returns a list of message with which field is/was affected and the validation message.
Here's kind of what I'm looking to do
$.post(url, { someData}, function (data) {
for (message in data.Messages) {
$("#form").validate().addMessage(message.Field, message.Text);
}
});
Thanks for your help
Per request, here's a sample of the returning JSON, it's fairly simple.
{"id":0,"messages":["Level":0,"Message":"Style is required","Name":"Style"}],"operationResult":false}
messages is a list of objects that contain the severity level, the property the error belonged to and the error message. I would use the name in the messages object to match where it want on the form.
I had exactly the same requirement, I actually found the following method.
var validator = $("form").validate();
validator.showErrors({field : "Error Message"})