Consider the following example:
Suppose there is a object with enum property. If enum property has 5 value, the field value should be equal to 5, if enum is super object must have properties up and down. So the js code can be like that:
if (obj.enum === 5) {
if (obj.value != 5) {
//error here
}
}
if (obj.enum === 'super') {
if (obj.up === undefined || obj.down === undefined ) {
//error here
}
}
How to integrate this code into loopbackjs???
E.g. this is not a fields validation (custom or not), this it model validation. So isValid funciton (see below) and validate method can not be used. The validate validates only one property.
Here is very similar question but it ended up with custiom property validation.
Here is example with isValid funciton in validatable.js. Please note that this only invoking validation, there is no way to add additional errors or add additional validation
Use this answer as workaround. Pass one of always present fields to validate method and add custom error code and messages inside customValidator funciton.
Related
I'm using yup for validation and there's this amazing cast method that I would like to try, however it is not clear from the documentation, how do I get the error message in case of failure? cast either transforms and validates and returns the result or returns null and that's it. That's not acceptable - I also require an error message. At the same time I wouldn't want to run it twice, like - once for validation, once for cast.
cast either transforms and validates and returns the result or returns null and that's it
cast DOES NOT validate the result - it simply transforms it. validate(Sync)/isValid(Sync) casts and then validates.
If you want to provide an error message on a specific schema in case of failed cast you do it with typeError
At the same time I wouldn't want to run it twice, like - once for validation, once for cast.
As I said, the validate methods always run casting first before validating (if cast fails, then it doesn't run validation). If you want cast and validation functionality, then you just call the validation methods and it returns the cast result (if valid) - you don't need to call cast unless you ONLY want to cast (without validating).
You can throw Validation Error anytime you want.
Here is my full implementation:
phone: yup
.string()
// .test('is-valid', 'phone.invalid', async (value) => {
// if (typeof value === 'string') {
// const number = phoneUtil.parseAndKeepRawInput(value, 'TR');
// return phoneUtil.isValidNumber(number);
// }
// return false;
// })
.transform((value) => {
if (typeof value === 'string') {
const number = phoneUtil.parse(value, 'TR');
if (phoneUtil.isValidNumber(number)) {
return phoneUtil.format(number, PhoneNumberFormat.E164);
}
}
throw new ValidationError(
new ValidationError('phone.invalid', value, 'phone', 'is-valid')
);
})
.required()
.nullable(false),
Commented section is unnecessary and replaced in transform
The reason behind throwing nested Validation Error is completely because of my error parsing logic.
I am working in JavaScript where I need to check the instanceof a custom JavaScript object & if the instance of that object is customTypeA then I need perform certain functions, where as in all other cases, we need to perform some different set of logic.
More detailed scenario:
We have generic form submit button which gets included on all form pages. Now we have a common JavaScript for form submit and specific JavaScript files for each form pages. Each of these specific JavaScript files create an object with name of commonObjectName. Where on form submit JavaScript calls validate & submit on commonObjectName, which will in turn invoke validate & submit for the respective JavaScript instance.
Now, when I need to perform certain checks between validate & submit actions for form A, where as they are not needed for form B, so I wrote below code in formSubmit.js
var commonObjInstanceOfFormA = commonObjectName instanceof FormAJavascript;
if(commonObjInstanceOffFormA) {
//do something
} else {
//do something else
}
Now, the problem occurs when I am on Form B. FormAJavascript type gives a reference error since it is not included on form B at all.
Is there a way to find the type of contructor of commonObjectName in a string format or find the instance of the object in efficient way so that I can perform a different set of logic for type A & different for Type B?
Why not check for it with good old typeof commonObjectName != 'undefined'? It will do the check first and only if it succeeds in finding commonObjectName it will then try to match it by type, then repeat same for objectB on formB.
var commonObjInstanceOfFormA = typeof commonObjectName != 'undefined' && commonObjectName instanceof FormAJavascript;
var commonObjInstanceOfFormB = typeof commonObjectName != 'undefined' && commonObjectName instanceof FormBJavascript;
if(commonObjInstanceOffFormA) {
//do something
} else {
//do something else
}
Declare any types you subsequently want to test against whilst preserving them if they exist:
var FormAJavascript = FormAJavascript || null;
Test with:
if (FormAJavascript != null && commonObjectName instanceof FormAJavascript)
Finally I ended up using my form page id to confirm which form this is, I am trying to get formId in javascript & asserting it against string 'formA'. If assertion succeeds, then it means it is form A.
I would still like to have an elegant way of finding the form, instead of checking for form id on every single form. But atleast this works.
I'm beginning to learn OOP in Javascript and my instructor is not very good and I'm learning out of a very bad book. (http://www.amazon.com/JavaScript-The-Web-Technologies-Series/dp/0538748877/ref=cm_cr_pr_product_top) However I'm doing my best to use this site and any resource possible to follow along. That said! We're going over OOP and I'm trying to make a simple object oriented form validator but I'm having a problem with passing the input value to the method inside of the object. I apologize if I got the phrasing wrong. Here's my code.
function validate() {
this.isEmpty = function(value) {
if(value == "" || value.length < 1 || value == null) {
// testing alert
alert(value);
return false;
}
}
}
And my HTML
<form action="" method="get">
<label for="name">Name</label>
<input type="text" id="name" name="name">
<input type="submit" value="submit" id="submit">
</form>
Basically what I don't get is how I can pass the input value of the field "name" to the object? And my follow up to that would be how do I pass multiple inputs? For example if I wanted to check if "name" and another field named "email" were empty?
Can anyone shed some light on how I would go about doing this in regular JS? Am I even attempting this in the right way? I have no idea since this is my first time trying anything object oriented.
Well first it's important to know which concepts you are trying to model when doing OO. You were speaking about a "validator" concept, but perhaps it's still not specific enough. What exactly are you validating? Think about it, a "Validator" object suggests that it's actually quite flexible and is an object that could be helpful to validate many disparate models. If this isin't what you have in mind, then be more specific. For instance, you could name your class MyFormValidator (it's just an example).
Here's a very simple example of a specific validator class that takes a form as an argument and implements a public validate method to trigger validation on demand. The example is very simple and not quite flexible. There's a lot of space for improvements, such as removing UI concerns (like the messages), from the validator, but I did not want to make the example too complex.
*Note: _members identifies private members. You can enforce true privacy with the module pattern and/or priviledged functions, but I prefer naming conventions.*
function MyFormValidator(form) {
this.form = form;
this._errors = [];
}
MyFormValidator.prototype = {
constructor: MyFormValidator,
validate: function () {
var errors = this._errors,
name = this._valueOf('name');
//clear previous errors
errors.length = 0;
if (this._isEmpty(name)) {
errors.push('The name is mandatory');
}
return !errors.length;
},
errors: function () { return this._errors.slice() },
_valueOf: function (fieldName) {
return this.form.querySelector('[name="' + fieldName + '"]').value;
},
_isEmpty: function (value) {
return value == "" || value.length < 1 || value == null;
}
};
//Setting up form validation
var form = document.querySelector('form'),
validator = new MyFormValidator(form);
form.addEventListener('submit', function (e) {
if (!validator.validate()) {
e.preventDefault(); //prevent submit
alert(validator.errors());
}
});
DEMO: http://jsfiddle.net/Q2d5c/
When a JavaScript function is invoked inline, "this" points to the containing DOM element.
So if you want to validate the following tag:
<input name="test" onblur="validate();">
Then your validate function can grab its container's value:
function validate(){
alert(this.value); //the value of input field "test"
//to get the name of this input:
alert(this.name);
}
Personally I don't code like this because the code is sensitive to its context. Instead I use this style:
<input name="test" onblur="validate(this);">
function validate(d){
alert(d.value); //value
alert(d.name); //name
}
As you can see, the object is explicitly passed in, and you can see that on the call stack, "this" is placed in the tag directly. Later if you want to use the same function from another location, you can, by manually getting the object, and pass it in:
<input name="test" id="test">
<button onclick="validate(document.getElementById('test'));">Validate</button>
Unless it's an inline callback (closure) function, I avoid using the ambiguous "this" pointer to increase code readability.
I do not recommend to use a framework when learning javascript. After you learn javascript itself, then you should dive into frameworks, not now. So i will not tell anything about vanilla yet.
You can get values of inputs in several ways. The best is to get their value by id:
var name = document.getElementById("name").value
So there you have it, the value of the input assigned to name variable.
After that you can pass that variable to validate function and see the results.
You would also want to catch the form's submit event and do the validation before the form gets submitted. To do so:
var form = document.getElementsByID('form'); //you should assign id 'form' to the form element
form.addEventListener("submit", function(e) {
e.preventDefault(); //do not submit the form
var name = document.getElementById("name").value
validate(name);
});
It is simply done like that:
<script type="text/javascript">
function MsgAlert()
{
var value = document.getElementById('abc').value;
alert(value);
}
</script>
<input id="abc"></input>
<button onClick="MsgAlert();">PassValue</button>
I have the following code snippet that defines the property values in my form.
function retrieve(){
setSelectedIndex(document.producerSetForm.GA1,"<%=ssnGA1%>");
setSelectedIndex(document.producerSetForm.GA2,"<%=ssnGA2%>");
setSelectedIndex(document.producerSetForm.GA3,"<%=ssnGA3%>");
setSelectedIndex(document.producerSetForm.GA4,"<%=ssnGA4%>");
setSelectedIndex(document.producerSetForm.GA5,"<%=ssnGA5%>");
}
where these ssnGA1,ssnGA2 etc may or may not be having a value. I need to check whether whether they have a value to do some more processing. I tried
var len=<%=ssnGA1.toString().length()%>;
if(len !=0)
but it works only if the value is present. else it giving javascript error. Please help. THANKS
You have to check if your string is not undefined/null first, on example:
if ( ssnGA1 && ssnGA1.toString().length ) {
// do something
}
Also, length is a property, not a function, see MDN for details.
I'm reading through the Backbone.js source and am somewhat confused by these lines (L230-238, v0.5.3)
unset : function(attr, options) {
if (!(attr in this.attributes)) return this;
options || (options = {});
var value = this.attributes[attr]; // ?: value appears to be unused (?)
// Run validation.
var validObj = {};
validObj[attr] = void 0; //void 0 is equivalent to undefined
if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;
Am I crazy or does the last line run a validation against a hash object with a single undefined attribute?
It seems like the validation is intended to run on an instance of the Model object with the attribute-to-be-unset removed.
Current source on github with lines highlighted
you're correct in your assessment of what it does, but that's the intended functionality.
when you call unset, you can only tell it to unset one attribute at a time: model.unset("myAttr")
when unsetting, validation is called to make sure the model will be put into a valid state. if the attribute being set to undefined will cause the model to be invalid, the unset fails. if it is valid for the attribute to be undefined, the attribute is removed from the model.
the reason it passes a "hash object with a single undefined attribute" is that all objects in javascript as "hash objects" - key value pairs, or associative arrays. it doesn't matter how you get an object, it is an associative array.
an object with one empty attribute named after the model's attribute that is being unset, is created in lines 236-237. this is so that monkeying with the object passed into the validate method won't change the state of the model itself.
hope that helps explain things.