Assign v-validate multiple validation rules (predefined and custom) - javascript

I can't figure out how to assign multiple rules to vee-validate. Usualy you pipe | the rules inside v-validate attribute, but the problem is that I also try to include one custom method.
<input id="number" type="tel" v-model="cardDetail.number" v-card-focus
class="form__input"
v-validate="'required'" <!-- need to add requireNumberIfCreditCard method -->
data-vv-validate-on="blur"
name="number" required>
<label for="number" class="form__label">
{{ $root.trans.translate('cardNumber') }}
</label>
<p class="form__error" v-show="errors.has('number')">
{{ errors.first('number') }}
</p>
This is my javascript
export default {
data() {
return {
cardDetail: {
number: '',
}
}
},
computed: {
requireNumberIfCreditCard() {
if (this.paymentMethod === 'creditCard') {
return this.cardDetail.number ? "required" : "";
}
}
}
};
How should my HTML look like so I will be also able to add custom mthods to vee-validate? If you need any additional informations, please let me know and I will provide. Thank you!

The attribute v-validate is bound to your data, so you can use anything you want within it. Further, it supports different syntaxes - one, which you're using is a string (i.e. 'required'). Another form it supports is an object, which is what you need:
<input id="number" type="tel" v-model="cardDetail.number" name="number"
v-validate="{ required: (requireNumberIfCreditCard == 'required') }">
I recommend you change your computed value to return true/false, in which case you can just use it directly.
Working example: https://codesandbox.io/s/km4lw12823

Related

How to use hasOwnProperty with AngularJS Directive `attrs` object

I have a directive named ip-abc which is used to check the input values of fields and convert to dollar formatted values. I have a condition where if we have the value as "0", then I will convert that to $0.
ipabc.js
var filterFunc = function (value) {
if(value == '0'){
if(attrs.hasOwnProperty('ipZeroDollar')){
var currencyValue = $filter('currency')(value);
currencyValue = currencyValue.toString();
return currencyValue.replace('.00','');
}
}
The problem which I am facing is that, how can I set ipZeroDollar = true in HTML. As of now, (attrs.hasOwnProperty('ipZeroDollar')) is coming as false.
<div ng-class = {'//something'}
<input type="tel" name="amount" class="form-control" ng
model="Data.Amount" maxlength="15" required ip-abc/>
</div>
The problem which I am facing is that, how can I set ipZeroDollar = true in HTML. As of now, (attrs.hasOwnProperty('ipZeroDollar')) is coming as false.
The camelCase needs to be normalized to kebab-case in the HTML:
<input type="tel" name="amount" class="form-control"
ng-model="Data.Amount" maxlength="15" required
ip-abc ip-zero-dollar />
For more information, see
AngularJS Developer Guide - Attribute Normalization
AngularJS attrs Type API Reference
The DEMO
angular.module("app",[])
.directive("ipAbc", function() {
return {link: postLink};
function postLink(scope,elem,attrs) {
var hasIpZeroDollar = attrs.hasOwnProperty("ipZeroDollar");
console.log("hasIpZeroDollar",hasIpZeroDollar);
}
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app"
<input type="tel" name="amount" class="form-control"
ng-model="Data.Amount" maxlength="15" required
ip-abc ip-zero-dollar />
</body>
This is how you use hasOwnProperty().
let obj = {color: 'yellow'}
obj.hasOwnProperty('color') // returns true
It seems like you would want to call hasOwnProperty() on Data since that looks like its an object, and that is where you are getting the amount.

How to use custom validators of github.com/1000hz/bootstrap-validator

From the documentation http://1000hz.github.io/bootstrap-validator/:
Add custom validators to be run. Validators should be functions that receive the jQuery element as an argument and return a truthy or falsy value based on the validity of the input.
Object structure is: {foo: function($el) { return true || false } }
Adding the validator to an input is done just like the others, data-foo="bar".
You must also add default error messages for any custom validators via the errors option.
I don't quite understand how to define my own custom validator and how to use it with this plugin.
Could anyone give me a simple example or hint?
You need to call your plugin manually, as custom options will not work with data-attributes:
$().validator({
custom: {
'odd': function($el) { return Boolean($el.val() % 2);}
}
})
then use it like this:
<input placeholder="plz enter odd value" data-odd>
Don't forget to add error messages, see code
I wanted to flesh out the answers here with a bit more detail.
I was attempting to do this while using the data-api (putting data-toggle="validator" in the form tag). Removing that from my <form> tag and enabling it with Javascript, my custom function works:
$('#sign-up_area').validator({
custom: {
'odd': function($el) { return Boolean($el.val() % 2);}
},
errors: {
odd: "That's not an odd number!"
}
});
I also had to add a value to the data-odd attribute thusly:
<div class="row">
<div class="form-group col-xs-12 col-md-12">
<label class="control-label" for="test">Odd/Even:</label>
<input type="text" name="test" id="test" class="form-control" placeholder="Enter an odd integer" data-odd="odd" >
<span class="help-block with-errors"></span>
</div>
</div>
Interesting to note that if I add the following to the <input> element, it takes precedence over the error message declared in javascript:
data-odd-error="Not an odd number, yo!"
However, I get an error in console if I only use the data-odd-error attribute but NO error message specified in Javascript. Thus, you must declare an error message in Javascript.
First of all add your own custom validator, for example:
var validatorOptions = {
delay: 100,
custom: {
unique: function ($el) {
var newDevice = $el.val().trim();
return isUniqueDevice(newDevice)
}
},
errors: {
unique: "This Device is already exist"
}
}
Second, you need to "bind" the form input for the custom validator, for example:
<input id="add_new_device_input" class="form-control" data-unique="unique">
If you want to add to this input more validators error you must to add the custom error to the input: data-unique-error="This device is already exist"
for example:
<input id="add_new_device_input" class="form-control" data-unique="unique" data-unique-error="This device is already exist" data-error="The Device pattern is invalid" pattern="<Add some regex pattern here>">
The "data-error" is the default validator error and it called "native" key, the following code will demonstrate how the validator print the error messages according to the validator key:
function getErrorMessage(key) {
return $el.data(key + '-error')
|| $el.data('error')
|| key == 'native' && $el[0].validationMessage
|| options.errors[key]
}

Knockout validation throttle

Hi i have a css binding on a input type which adds the class CircleErrors if it matches my function. My problem is it has a delay on taking the class off it only happens when i tab off the input box. I want the class to be removed on key down of the keyboard.. i know there is a throttle you can use for knockout but i am not sure how to go about doing it.
<input id="firstName" type="text" placeholder="First name" data-bind="value: Registration.FirstName, css: { CircleErrors: Registration.FirstName().length == 0 && Registration.FirstNameValidation(), valueUpdate: 'afterkeydown' }">
You've misplaced your valueUpdate parameter. It's inside the css parameter - you need to move it outside the }:
<input id="firstName" type="text" placeholder="First name" data-bind="value: Registration.FirstName, css: { CircleErrors: Registration.FirstName().length == 0 && Registration.FirstNameValidation() }, valueUpdate: 'afterkeydown'">
Here's a demo with it working
Use the textInput binding instead of the value binding for the first name property (and for any text input fields for that matter). To quote the docs
Unlike the value binding, textInput provides instant updates from the
DOM for all types of user input, including autocomplete,
drag-and-drop, and clipboard events.
You don't need the valueUpdate binding any more, however it was inside your CSS binding so would not have had any effect.
<input id="firstName" type="text" placeholder="First name" data-bind="textInput: Registration.FirstName, css: { CircleErrors: Registration.FirstName().length == 0 && Registration.FirstNameValidation() }">
Demo
this is what you looking for
` var reg = new (function() {
var self = this;
this.FirstName = ko.observable('');
this.checkifEmpty = ko.observable(false);
this.check=function(){
if(this.FirstName()!=null&&this.FirstName()!=undefined && this.FirstName() !=''){
this.checkifEmpty(true);
}else{
this.checkifEmpty(false);
}
}
this.FirstNameValidation = function() {
return true;
}
})();
ko.applyBindings(reg);
`

jQuery Validate multiple extensions

I am using https://github.com/DiegoLopesLima/Validate this validation plugin to validate the form
I added extensions and I want to use 2 extension rule in one field
Something like this
'data-validate' => ' max , min ', // in field
jQuery.validateExtend({
min: {
conditional: function(value) {
return false;
}
},
max: {
conditional: function(value) {
return false;
}
}
});
Here is example how use in one rule I want multiple rules
<form>
<input type="text" name="age" data-validate="age" />
</form>
jQuery('form').validate();
jQuery.validateExtend({
age : {
required : true,
pattern : /^[0-9]+$/,
conditional : function(value) {
return Number(value) > 17;
}
}
});
This may not exactly be the answer you are looking for but this can be done in pure HTML. The drawback is that it requires a modern browser (IE10, Chrome, Firefox etc.) to be used. The advantage is that its much easier to use and works without JS.
Check out:
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms/Data_form_validation
Specifcally for what you need, go here and look at the "How old are you" input example:
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms/Data_form_validation#Other_validation_constraints
<input type="number" min="12" max="120" step="1" id="n1" name="age" pattern="\d+">
Looking at your code you are looking for a required age input where the value must be greater than 17, this would be for example:
<input type="number" min="18" id="age" name="age" pattern="\d+" required>
Hopefully this helps a little.

knockout js if statement to Display value based on boolean data type

I am trying to Display a value based on a table value of True or False. For example if the Value is True then I want it to Say Supported and If it's False then I want it to Say Not Supported! This is my html code
<p><input type="text" data-bind="value: Support" /></p>
Java script Code
$(function() {
dm.viewModel = function() {
var clients = ko.observableArray(),
selectedClient = ko.observable(),
clientChanged = function() {
$.getJSON(dm.WebServices + "/dm/get/clientinfo?client=" + encodeURIComponent(selectedClient()), function(data) {
if (data != null) {
dm.viewModel.Name(selectedClient());
dm.viewModel.Support(data[0]['Support']);
}
})
$('#divClientData').show();
},
LoadClients = function() {
$('#divClientData').hide();
$.getJSON(dm.WebServices + "/dm/get/clientlist", function(data) {
$.each(data, function(key, val) {
clients.push(val);
});
});
},
Name = ko.observable(),
Support = ko.observable(),
return {
Name: Name,
Support: Support
};
}();
ko.applyBindings(dm.viewModel);
dm.viewModel.LoadClients();
})
In this kind of case you can evaluate the property and render based on the value. Even a function can be provided inside the binding. You can use this:
<input type="text" data-bind="value: Support() ? 'Supported' : 'Not Supported'" />
You can do that with the if binding
See documentation here
Example from the docs:
<label><input type="checkbox" data-bind="checked: displayMessage" /> Display message</label>
<div data-bind="if: displayMessage">Here is a message. Astonishing.</div>
So for you
<div data-bind="if: Support">Supported</div>
<div data-bind="ifnot: Support">Not Supported</div>
Edit: The other answers suggesting using the value binding with a ternary condition are probably a better way to accomplish this. I'll keep this up as a reference, but I recommend that solution.
What you're looking for, in this case, is ko.computed().
EDITED: (Support appears to be in-use as a value from the data set)
Add a new value to your ViewModel, something like this:
IsSupported = ko.computed(function(){
if(this.Support() == true){
return "Supported";
} else {
return "Not Supported";
}
}, this)
Then, in your markup, you will have to change your data-bind just slightly:
<p><input type="text" data-bind="value: IsSupported" /></p>
Alternatively, if you don't want to change your Support field, you'll have to do something like this in your HTML, as suggested by other commenters:
<p><input type="text" data-bind="value: (Support() ? 'Supported' : 'Not Supported')" /></p>
I'd recommend the former, however, as really, you should keep that logic tucked away inside your ViewModel.
(See the KO docs for more info on computed: http://knockoutjs.com/documentation/computedObservables.html)
In my work I use KO boolean conditions like this:
<div id="bla" data-bind="visible: position != value"></div>
KO is very useful for those types of problems.

Categories

Resources