I am trying to make VeeValidate 3 infinite args rule work:
https://logaretm.github.io/vee-validate/guide/basics.html#rule-arguments
Here is the code :
const aValidationFunction(value, values) {
//iterations and business here
}
extend('my_rule', {
validation : aValidationFunction,
computesRequired : true,
immediate : true,
// message etc.....
})
My rule usage im my code :
Child Component
<ValidatedInput name="inputA"
:label="this.$t('XXXX.yyy')"
:iid="'inputA'"
type="text"
:rules="myRulesA"
:immediate="true"
v-model="XXXX.yyyy">
</ValidatedInput>
<ValidatedInput name="inputB"
:label="this.$t('XXXXX.zzzzz')"
:rules="myRulesB"
:iid="'inputB'"
type="text"
:immediate="true"
v-model="XXXX.zzzzz">
</ValidatedInput>
export default {
name: 'ChildComponent',
components: { ValidatedInput },
props: ['myRulesA', 'myRulesB'], ...........
Father component
<ValidationObserver>
<ChildComponent :my-rules-A="rulesA" :my-rules-A="rulesB" />
............
</ValidationObserver>
computed : {
rulesA() {
return { my_rule: ['#inputB', '#anotherInputBBB'], another_rule: ['#anotherInputA', '#anotherInputB'] //a rule with two args, it works};
},
rulesB() {
return {my_rule: ['#inputA', '#anotherInputAAAAA']};
},
but if i put console.log(values) in my code aValidationFunction it prints me ['#inputA', '#inputB']
Any idea ?
Targeting other fields in cross field validations doesn't work with infinite parameters.
https://github.com/logaretm/vee-validate/issues/2839#issue-667100530
Related
I code a Gatsby app with a Main page and two components. The value from a select form will be used to query a Postgresql database through a graphql query.
What I can already do: in the form component, I get the value from the select menu and pass it from this child component to the parent (the main page). In the data component, I can query the database with graphql and get the results with hardcoded values.
What I can't do yet: get the value from the select component to the data component and use it in my graphql query.
I tried different ways to get the value without success using this.props.value1 or this.state.value1. I also tested a simple component to make sure I could get the value from the parent to a child component and it worked seamlessly. So it's the way I try to import the value in a querying component that is the problem.
**//Data component**
let val = 88 //for hardcoded test. That works.
const DataPage = () => {
const data = useStaticQuery(query)
return (
<div>
<p>From Postgres: {data.postgres.allEstivalsList[val].nbr}</p>
</div>
)
}
const query = graphql`
{
postgres {
allAveragesList {
avg
}
allEstivalsList {
year
nbr
}
}
}
`;
export default DataPage;
**//Main page**
export default class App extends React.Component {
constructor(props) {
super(props);
}
state = {
value1: null,
// other values
}
render() {
return (
<div>
<p>Get state in main page: {this.state.value1}</p>
<DataPage val = {this.state.value1} />
<SelectForm clickHandler={y => { this.setState({ value1: y }); }} />
</div>
)
}
}
**//Form component**
export default class IndexPage extends React.Component {
state = {
value1: null,
}
handleClick = () => {
this.props.clickHandler(this.state.value1);
this.setState(prevState => {
return { value1: prevState.value1 };
});
};
render() {
return (
<Formlayout>
<p>Test -- Value for the selected year: {this.state.value1}</p>
<select onChange = {(e) => this.setState({ value1: e.target.value })}>
<option value="">-- Year --</option>
<option value="1">1901</option>
<option value="2">1902</option>
<option value="3">1903</option>
</select>
<button onClick={this.handleClick}>Go!</button>
</Formlayout>
)
}
}
I'd appreciate to get some directions to get the select value in the data component. As my test variable val is effectively working when used in the query, what I'd like to achieve is to apply to that variable the state from the component. And that's where I'm stuck right now.
The GraphQL query is executed at the build time, not at runtime. Have a look at the docs, it's possible to query data at build and at runtime.
https://www.gatsbyjs.org/docs/client-data-fetching/
// edit
Normally you would pre generate all (static) content pages - e.g. if you have data for 50 years, you let gatsby build those 50 pages and then you could navigate by path to the page.
If you want to pass a variable to the query, check the docs: https://www.gatsbyjs.org/docs/graphql-reference/#query-variables
query GetBlogPosts(
$limit: Int, $filter: MarkdownRemarkFilterInput, $sort: MarkdownRemarkSortInput
) {
allMarkdownRemark(
limit: $limit,
filter: $filter,
sort: $sort
) {
edges {
node {
frontmatter {
title
date(formatString: "dddd DD MMMM YYYY")
}
}
}
}
}
I'm using VueJS2 with vuelidate library. I can validate the fields based on the validation objects. The validation will execute during computed time. But My validations objects is fixed, instead of dynamic. I have some fields will hide based on the selection.
import { validationMixin } from 'vuelidate'
import { required, maxLength, email } from 'vuelidate/lib/validators'
export default {
mixins: [validationMixin],
validations: {
company_name: { required },
company_position_title: { required }
},
methods: {
submit(){
this.$v.touch();
if(this.$v.$invalid == false){
// All validation fields success
}
}
}
}
HTML
<v-select
label="Who are you?"
v-model="select" // can be 'company' or 'others'
:items="items"
:error-messages="selectErrors"
#change="$v.select.$touch();resetInfoFields();"
#blur="$v.select.$touch()"
required
></v-select>
<v-text-field
label="Company Name"
v-model="company_name"
:error-messages="companyNameErrors"
:counter="150"
#input="$v.companyName.$touch()"
#blur="$v.companyName.$touch()"
v-show="select == 'Company'"
></v-text-field>
<v-text-field
label="Company Position Title"
v-model="company_position_title"
:error-messages="companyPositionErrors"
:counter="150"
#input="$v.companyPosition.$touch()"
#blur="$v.companyPosition.$touch()"
v-show="select == 'Company'"
></v-text-field>
<v-btn #click="submit">submit</v-btn>
Problem
When I select 'other' option and click submit, the this.$v.$invalid is still true. It should be false as there is no validation fields required.
When I select 'company', that two fields must required and validated.
you need a dynamic validation schema
validations () {
if (!this.select === 'company') {
return {
company_name: { required },
company_position_title: { required }
}
}
}
More info: Dynamic validation schema
Another way is using requiredIf
itemtocheck: {
requiredIf: requiredIf(function () {
return this.myitem !== 'somevalue'
}),
minLength: minLength(2) },
I have a this md-dialog https://codepen.io/patapron/pen/oLaxap
<md-button ng-click="answer('not useful')" >
Not Useful
</md-button>
<md-button ng-click="answer('useful')" style="margin-right:20px;" >
Useful
</md-button>
How do to I get remove the md-autofocus from the buttons?
Objetive: Any button must be pre-selected paint in grey.
There is an easier way to do this without having to write a custom directive. Angular Material has the ability to remove autofocus built-in.
In your controller where you are writing the .show function, set the focusOnOpen to false focusOnOpen: false
The documentation explains it here $mdDialog
Here is an example of how mine looks
function deleteMediaDialog() {
var dialogData = {
};
$mdDialog.show({
controller : 'deleteMediaDialogController',
controllerAs : 'vm',
templateUrl : 'app/main/apps/scala-media/dialogs/delete/delete-dialog.html',
parent : angular.element($document.body),
focusOnOpen : false,
clickOutsideToClose: true,
locals : {
dialogData: dialogData
}
});
}
I solved by mysleft. Directive magic
scope.$watch(function () { return ele.attr('class'); }, function () {
if (ele.hasClass('md-focused')) {
ele.removeClass('md-focused');
}
});
I need to make certain form fields required or not based on the value of other fields. The built-in RequiredValidator directive doesn't seem to support this, so I created my own directive:
#Directive({
selector: '[myRequired][ngControl]',
providers: [new Provider(NG_VALIDATORS, { useExisting: forwardRef(() => MyRequiredValidator), multi: true })]
})
class MyRequiredValidator {
#Input('myRequired') required: boolean;
validate(control: AbstractControl): { [key: string]: any } {
return this.required && !control.value
? { myRequired: true }
: null;
}
}
Sample usage:
<form>
<p><label><input type="checkbox" [(ngModel)]="isNameRequired"> Is Name Required?</label></p>
<p><label>Name: <input type="text" [myRequired]="isNameRequired" #nameControl="ngForm" ngControl="name" [(ngModel)]="name"></label></p>
<p *ngIf="nameControl.control?.hasError('myRequired')">This field is required.</p>
</form>
This works fine if the user first toggles the check box and then types or erases text in the text box. However, if the user toggles the check box while the text box is blank, then the validation message doesn't update appropriately.
How can I modify MyRequiredValidator to trigger validation when its required property is changed?
Note: I'm looking for a solution that only involves changes to MyRequiredValidator. I want to avoid adding any logic to the App component.
Plunker: https://plnkr.co/edit/ExBdzh6nVHrcm51rQ5Fi?p=preview
I would use something like that:
#Directive({
selector: '[myRequired][ngControl]',
providers: [new Provider(NG_VALIDATORS, { useExisting: forwardRef(() => MyRequiredValidator), multi: true })]
})
class MyRequiredValidator {
#Input('myRequired') required: boolean;
ngOnChanges() {
// Called when required is updated
if (this.control) {
this.control.updateValueAndValidity();
}
}
validate(control: AbstractControl): { [key: string]: any } {
this.control = control;
return this.required && !control.value
? { myRequired: true }
: null;
}
}
See this plunkr: https://plnkr.co/edit/14jDdUj1rdzAaLEBaB9G?p=preview.
I'm trying to validate fields in my form, but I keep getting an error message.
Here is my code:
Ext.define('ExtDoc.views.extfields.FieldsValidator',{
valEng: function(val) {
var engTest = /^[a-zA-Z0-9\s]+$/;
Ext.apply(Ext.form.field.VTypes, {
eng: function(val, field) {
return engTest.test(val);
},
engText: 'Write it in English Please',
// vtype Mask property: The keystroke filter mask
engMask: /[a-zA-Z0-9_\u0600-\u06FF\s]/i
});
}
});
And I define my field as follow:
{
"name": "tik_moed_chasifa",
"type": "ExtDoc.views.extfields.ExtDocTextField",
"label": "moed_hasifa",
"vtype": "eng",
"msgTarget": "under"
}
The first snippet is in a separate js file, and I have it in my fields js file as required.
When I start typing text in the text field, I keep seeing the following error msg in the explorer debugger:
"SCRIPT438: Object doesn't support property or method 'eng' "
What could it be? Have I declared something wrong?
You have defined your own class with a function valEng(val), but you don't instantiate it, neither do you call the function anywhere.
Furthermore, your function valEng(val) does not require a parameter, because you are not using that parameter anywhere.
It would be far easier and more readable, would you remove the Ext.define part and create the validators right where you need them. For instance if you need them inside an initComponent function:
initComponent:function() {
var me = this;
Ext.apply(Ext.form.field.VTypes, {
mobileNumber:function(val, field) {
var numeric = /^[0-9]+$/
if(!Ext.String.startsWith(val,'+')) return false;
if(!numeric.test(val.substring(1))) return false;
return true;
},
mobileNumberText:'This is not a valid mobile number'
});
Ext.apply(me,{
....
items: [{
xtype:'fieldcontainer',
items:[{
xtype: 'combobox',
vtype: 'mobileNumber',
Or, you could add to your Application.js, in the init method, if you need it quite often at different levels of your application:
Ext.define('MyApp.Application', {
extend: 'Ext.app.Application',
views: [
],
controllers: [
],
stores: [
],
init:function() {
Ext.apply(Ext.form.field.VTypes, {
mobileNumber:function(val, field) {
var numeric = /^[0-9]+$/
if(!Ext.String.startsWith(val,'+')) return false;
if(!numeric.test(val.substring(1))) return false;
return true;
},
mobileNumberText:'This is not a valid mobile number'
});
}