Backbone.Validation plugin - How to validate only the attributes that is set - backbone.js

How to validate just the one's that are set. Is there another method other than model.isValid(true) or model.validate() which would not validate the complete model. Here are some config that is there in my code
_.extend Backbone.Model.prototype, Backbone.Validation.mixin
Backbone.Validation.configure
forceUpdate: true
setting one attribute with {validate:true} is triggering validate on the entire model
thanks

model.isValid(true) validates all the fields of a model for which validations are defined, ignoring the fact if any filed is set or not.
For eg:
Suppose you have a model having three fields viz. field1, field2, field3
var model = Backbone.Model.extend({
validate: function(){
//validation rules for field1, field2, field3
}
});
Now suppose you did model.isValid(true), it will validate all three fields no matter what. (passing true as argument do that). While if u do model.isValid() then it will only validate the fields that are set.
Now coming to your question, you are asking for something that could validate only the field you have set. For that u may use following:
var isValid = model.isValid('field1');

There is preValidate method available, it only validates attributes passed to it.
Method description: https://github.com/thedersen/backbone.validation#prevalidate

Related

CakePHP 3.x Custom Validation Field Required

As I'm building form elements dynamically I want to be able to check and see if a form field is required or not via a custom validation rule. The problem is that when I add a custom validation rule, it forces the field to not be empty. If I allow the field to be empty, it doesn't check my custom validator unless something is entered in the field.
How can I check in a callback whether to allow or not a field as required?
In my SubmissionsTable
public function validationDefault(Validator $validator)
{
$validator
->add("custom_value_q", [
"custom" => [
"rule" => [$this, "customFieldIsRequired"],
"message" => "Message Here"
]
]
);
return $validator;
}
public function customFieldIsRequired($value, $context)
{
//logic here
return true;
}
Returning true in your custom one when empty $value is passed in should do the trick.
If you want the field to allow empty string (= empty), use allowBlank('custom_value_q') on top, logically you don't need to invoke the custom validator function then, that's why it is bypassed in the empty case.
//UPDATE
You do, however, have the option to provide a callback for allowEmpty(), with this it should be possible to only invoke the custom validation rule if you really want it (if the field needs to be validated because non blank).
$validator->allowEmpty('fieldname', function ($context) {
return !isset($context['data']['description']) || $context['data']['description'] !== '';
});
I know this is a bit old, but I'm facing the same problem, and as I see in github the discussion about it is still open (https://github.com/cakephp/cakephp/issues/8925 and https://github.com/cakephp/cakephp/issues/12484).
In this case, when you have a field that may be empty on some situations (may be if other field was filled), you can do this:
$validator->allowEmptyString('field_a', function ($context) {
// check whether the field can or cannot be empty
return $canBeEmpty;
});
as this may be incorrectly evaluated when an empty form is built (for new entities) as all fields are empty probably, you may have to add the attribute required => false to the form input, if not the field would be marked as required and ask to be filled mandatory.
While having to instruct the form helper whether the field should or shouldn't be required is far from ideal, it's not a big deal, and works to validate entities and modeless forms as well.
Only for validating entities, according to this (https://github.com/cakephp/cakephp/issues/12484#issuecomment-414465002) you may use application rules, which are evaluated only when the entity is being persisted, so a field can be allowed to be empty in validations and then application rules will be applied anyway.

Set the value of a different field when a field value changes

I'm using Angular Schema Form and I want to set a model property to null when a field value changes. I've tried using onChange in the form definition like so
{
key: '7_11',
type: 'radios',
titleMap: [{value: 'no', name: 'No'}, {value: 'yes', name: 'Yes'}],
onChange: function(modelValue,form) {
if (!modelValue) {
// model['8_1'] = null
}
}
}
Notice that the model property I'm trying to set is bound to a different field than the field that has changed
I can't do it in the manner indicated by the comment, because model is not in scope in the onChange listener.
Update
A second example is this Plunker demo. Say we want to clear the 2 checkboxes (by removing the corresponding properties from the model) whenever some text is entered in the Name field, how could this be achieved?
I should also point out that for reasons I won't bore you with, I can't implement this using a conditional and destroyStrategy.
Well, it is not uncommon (because it is kind of natural) to set the model and the form inside the scope of the same controller.
If that is the case, you can set X by $scope.model.X = modelValue.
Or perhaps you are in a position where you can't reach the scope of the model, in that case it is more complicated. On the other hand I would recommend to do it all in the same place.
(Sometimes that is not possible. For example, I have dynamic forms and schemas in my application, however in those cases I use generalized functionality like the filter functionality in ASFDS or ASF conditions and avoid hard-coding UI using onChange) .
For example, this would set foo2 if foo is changed in the plunkr:
onChange: function(modelValue,form) {
if (modelValue) {
$scope.model.foo2 = ["Yes"];
}
},

Syphon serializes disabled fields

Looks like Syphon is currently serializing every form field regardless of its state. Is there a way to easily tell Syphon to not serialize disabled fields?
Standard form submit does not include disabled fields and neither does JQuery serialize() method.
Since my primary concern was with disabled checkboxes getting serialized I was able to stop it from serializing those by adding this validator:
Backbone.Syphon.KeyAssignmentValidators.register("checkbox", function ($el, key, value) {
return $el.prop("checked") && $el.is(":enabled");
});
Note: this is a global change and effects all views.

Getting Ext Model Data from TreeModel

When adding data to a ExtJS TreeStore, the data is transformed into a TreeModel. When you call getData() on these TreeModels, it returns not just the fields specified in the original Ext.data.Model for the object, but also a bunch of other fields like qshowDelay, isFirst, allowDrag,...
What is the best way to get rid of all of these extra added fields so that I can POST just the fields specified in the original Ext.data.Model for the object?
The persist property is false for the added fields. So if you only want the modified fields for posting, you can use the model's modified property, and it will not include the added fields. If you want the data from all the original fields you can do something like:
var fields = Ext.Array.filter(MyModel.getFields(), function(field){
return field.persist!=false;
});
var data = Ext.copyTo(data, record.data, Ext.Array.pluck(fields, 'name'));

Understanding Backbone Model set, validate and change callbacks

The Backbone documentation says:
Model.set will fail if validation fails - it won't set the value therefore it won't trigger any callback. We can pass { silent: true } to Model.set - then it will set the value but won't trigger any callback neither.
So,
Why does Backbone Model require a valid state to simply set an attribute value? What if we want to set attributes as the user interacts with the UI, but the model is not valid yet? It means change callbacks are unavailable unless we pass { silent: true } then manually trigger the change?!
Please say you know a better way of handling this :)
I'm not sure how to answer the Why questions but you could say that there are arguments for why it is good that set runs validations. For instance, it makes it dead simple to do client side validation in real time.
If your problem could be solved by only validating the value that is currently being changed by the user, you can do that by combining your validate method with the hasChanged method.
For example something like this:
Backbone.Model.extend({
defaults : { name : "" },
validate : function (attrs) {
var errors = {};
if(this.hasChanged("name") && attr.name.length == 0) {
errors.name = "Need a name yo!";
}
//...
if(_.keys(errors).length > 0) {
return errors;
}
}
})
In Backbone whenever you call set on model , It keeps track of what attributes of model has been changed and what attributes are newly added.Calling validate allows it be more efficient in doing it .Passing {silent:true} as options in set function causes validate and change to not execute so if doesnt fire any change events.
If you want to set attributes as the user interacts with the UI, but the model is not valid yet
In this case you can set the change in a plain object make sure object keys are sames as model's attribute and then at some point just set in your model.
var uiChanges = {name:'x'}; //just fill it with your changes
ur_model.set(uiModel); //then set it ,this way it fires change events only once
To check the diff between your plain object and model you can use the
ur_model.changedAttributes(uiChanges);
changedAttributes -
Return an object containing all the attributes that have changed, or false if there are no changed attributes.
You can further use it save only those attributes that have changed rather than saving entire model again.

Resources