I am using mobx-react-form (https://foxhound87.github.io/mobx-react-form/docs/getting-started-class.html) and I have a password rules validation like so, however the confirm password error comes up as soon as I tap outside of the confirm field regardless of the 2 values being exactly the same:
{
name: 'changePassword',
label: 'Change password',
fields: [
{
name: 'password',
label: t('user:Password'),
rules: 'required|string|min:8',
value: ''
},
{
name: 'password2',
label: t('user:Confirm password'),
rules: 'required|string|same:password',
value: ''
}
]
},
as per the documentation this should work as expected.
Didn't spot the fact that the change password section is nested:
{
name: 'changePassword',
label: 'Change password',
fields: [
{
name: 'password',
label: t('user:Password'),
rules: 'required|string|min:8',
value: ''
},
{
name: 'password2',
label: t('user:Confirm password'),
rules: 'required|string|same:changePassword.password',
value: ''
}
]
},
Related
In ExtJS 6.02 is it possible to have a field model that is optional but also has validation?
Example an email field that may or not be present but the email must be valid if it exists.
Ext.define('my_model', {
extend : 'Ext.data.Model',
identifier: {
type : 'sequential',
seed : 1,
increment : 1
},
fields: [{
name : 'date',
type : 'date'
}, {
name : 'msg',
type : 'string',
}, {
name : 'email',
type : 'string',
}],
validators: {
date: {
type: 'presence'
},
msg: {
type : 'length',
min : 2
},
email: {
type : 'email'
}
}
});
You can override matcher of email validator to allow empty string:
Ext.define('my_model', {
extend: 'Ext.data.Model',
identifier: {
type: 'sequential',
seed: 1,
increment: 1
},
fields: [{
name: 'date',
type: 'date'
}, {
name: 'msg',
type: 'string',
}, {
name: 'email',
type: 'string',
allowBlank: true
}],
validators: {
date: {
type: 'presence'
},
msg: {
type: 'length',
min: 2
},
email: {
type: 'email',
// Override matcher to allow empty string
matcher: /^$|^(")?(?:[^\."])(?:(?:[\.])?(?:[\w\-!#$%&'*+\/=?\^_`{|}~]))*\1#(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/
}
}
});
Ext.application({
name: 'Fiddle',
launch: function () {
var myModel = Ext.create('my_model', {
date: new Date(),
msg: 'Some Message',
//email: 'mustermann#gmail.com',
email: '',
});
console.log(myModel.isValid());
}
});
I'm trying to make a React registration form.
I have the task to create input fields for form and check their values by regex and comparing values of password and repeat password with email.
It's OK but check values of password and r.password is hard
const fieldsValidation = () => {
const newState = [...fieldsState];
for (let [index, element] of newState.entries()) {
if (element.value.length < element.valueLength) {
return changeFields(() => {
newState[index].error = true;
return newState;
});
}
};
return registerUser();
};
this is configuration which I'm trying to integrate with my react project
export const textFieldConfig = [{
id: 'email',
type: 'email',
label: 'email',
value: '',
variant: 'outlined',
size: 'small',
error: false,
helperText: 'email must include 8 char and #.',
valueLength: 8
},
{
id: 'password',
type: 'password',
label: 'password',
value: '',
variant: 'outlined',
size: 'small',
error: false,
helperText: 'password must be min 6',
valueLength: 6
},
{
id: 'repeatPassword',
type: 'password',
label: 'repeat-password',
value: '',
variant: 'outlined',
size: 'small',
error: false,
helperText: 'please include same password value',
valueLength: 6
}
];
I suppose if your Object are not changing this will do
if(textFieldConfig[1].value == textFieldConfig[2].value){
....
}
I'm trying to build an application in VueJS where I'm having a component something like this:
<template>
<div>
<base-subheader title="Members" icon="la-home" heading="Member Details" description="Home"></base-subheader>
<div class="m-content">
<div class="row">
<div class="col-xl-6">
<nits-form-portlet
title="Add Member/User"
info="Fill the details below to add user, fields which are mandatory are label with * (star) mark."
headIcon="flaticon-multimedia"
headerLine
apiUrl="api/user"
backUrl="members__home"
action="create"
:formElements="form_elements"
>
</nits-form-portlet>
</div>
<div class="col-xl-6">
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "member-add",
data() {
return {
form_elements: [
{
field_name: 'first_name',
config_elements: {
label: 'First Name *',
type: 'text',
inputStyle: 'pill',
placeholder: 'Enter first name of user',
formControl: true,
addonType: 'left-icon',
addon: {leftAddon: 'la-exclamation'},
},
value: '',
nitsFormType: 'nits-input'
},
{
field_name: 'last_name',
config_elements: {
label: 'Last Name',
type: 'text',
inputStyle: 'pill',
placeholder: 'Enter last name of user',
formControl: true,
addonType: 'left-icon',
addon: {leftAddon: 'la-exclamation'},
},
value: '',
nitsFormType: 'nits-input'
},
{
field_name: 'email',
config_elements: {
label: 'Email *',
type: 'email',
inputStyle: 'pill',
placeholder: 'Enter email of user',
formControl: true,
addonType: 'left',
addon: {leftAddon: '#'},
},
value: '',
nitsFormType: 'nits-input'
},
{
field_name: 'password',
config_elements: {
label: 'Password *',
type: 'password',
inputStyle: 'pill',
placeholder: 'Enter password',
formControl: true,
addonType: 'left-icon',
addon: {leftAddon: 'la-expeditedssl'},
},
value: '',
nitsFormType: 'nits-input'
},
{
field_name: 'confirm_password',
config_elements: {
label: 'Confirm Password *',
type: 'password',
inputStyle: 'pill',
placeholder: 'Confirm password should match',
formControl: true,
addonType: 'left-icon',
addon: {leftAddon: 'la-expeditedssl'},
},
value: '',
nitsFormType: 'nits-input'
},
{
field_name: 'role',
config_elements: {
label: 'Select Role *',
inputStyle: 'pill',
options: [
{option: 'Select one'},
{value: '1', option: 'Admin'},
{value: '2', option: 'Subscriber'},
{value: '3', option: 'Analyst'},
{value: '4', option: 'Guest'}
],
addonType: 'left-icon',
addon: {leftAddon: 'la-user-secret'},
},
value: '',
nitsFormType: 'nits-select'
},
{
field_name: 'profile_pic',
config_elements: {
label: 'Profile pic',
},
value: '',
nitsFormType: 'nits-file-input'
}
],
}
}
}
</script>
<style scoped>
</style>
Whenever I try to pass data to my component config_elements which holds an object of all attributes being passed to child component gets lost, if I move from other component to nits-form-portlet> it renders the child components appropriately, but in my Vue-debug tool it shows empty:
But the components are rendered properly:
And same happens to the props inside the component:
But in case of any event or refreshing the page it shows:
Since all the attributes are gone, if I try to configure my config_elements object data, I get the attributes but within a fraction of seconds it again goes to empty. But attributes gets passed and it displays the fields:
I am using render function to render these components so for nits-form-portlet component I have:
return createElement('div', { class: this.getClasses() }, [
createElement('div', { class: 'm-portlet__head' }, [
createElement('div', { class: 'm-portlet__head-caption' }, [element])
]),
createElement('form', { class: 'm-form m-form--fit m-form--label-align-right' }, [
createElement('div', { class: 'm-portlet__body' }, [
createElement('div', { class: 'form-group m-form__group m--margin-top-10' }, [infoElement]),
this.computedFormElements.map(a => {
if(this.error[a.field_name]) {
a.config_elements.error = this.error[a.field_name][0];
return createElement(a.nitsFormType, { attrs: a.config_elements, on: {
input: (event) => {
this.form[a.field_name] = event
}
}})
}
else
return createElement(a.nitsFormType, { attrs: a.config_elements, on: {
input: (event) => {
this.form[a.field_name] = event
}
}})
})
]),
footerElement
])
])
And I think factors affecting the template is this map statement:
this.computedFormElements.map(a => {
if(this.error[a.field_name]) {
a.config_elements.error = this.error[a.field_name][0];
return createElement(a.nitsFormType, { attrs: a.config_elements, on: {
input: (event) => {
this.form[a.field_name] = event
}
}})
}
else
return createElement(a.nitsFormType, { attrs: a.config_elements, on: {
input: (event) => {
this.form[a.field_name] = event
}
}})
})
but still I'm sharing my whole code of render function, Link to code # github hoping someone can help me with this strange situation.
It's a bit hard to tell for me without running the code, but I've noticed something that may be related.
I see that you're overwriting the formElements prop here:
a.config_elements.error = this.error[a.field_name][0];
Vue usually gives you a warning that you can't do that, but maybe because it's abstracted through the computed it's not doing so.
If you want to extend the data for use in the child component, then it's best to do copy of the object (preferably a deep copy using computed, which will allow you to have it dynamically updated)
because config_elements is an object, when you add error variable you are likely triggering an observer, that may be clearing the data in the parent.
Anyway, it's just a guess, but something you may want to resolve anyway.
I have a requirement to add a specific tabindex to radio button in my formly form.
I can do it for text field but not for radio buttons, below is the sample code, any help is appreciated -
Tried adding the tabindex=1 at three places, above templateOptions, inside templateOptions and inside options, none of them works to get the focus.
{
name: 'feedbackType',
key: 'feedbackType',
type: 'radio',
id: 'feedbackType',
//tabindex:'1',
templateOptions: {
label: Constant.feedbackForm.typeField,
for:'feedbackType',
required: true,
focus: true,
//tabindex:'1',
options: [{
name: 'Idea1',
value: 'Idea1',
//tabindex:'1'
}, {
name: 'Idea2',
value: 'Idea2'
}, {
name: 'Idea3',
value: 'Idea3'
}]
}
},
Here you go. You'll want to use ngModelElAttrs. Like this
{
name: 'feedbackType',
key: 'feedbackType',
type: 'radio',
id: 'feedbackType',
ngModelElAttrs: {
tabindex: '1'
},
templateOptions: {
label: EaseConstant.feedbackForm.typeField,
for:'feedbackType',
required: true,
focus: true,
options: [{
name: 'Idea1',
value: 'Idea1',
}, {
name: 'Idea2',
value: 'Idea2'
}, {
name: 'Idea3',
value: 'Idea3'
}]
}
},
If you want it to be dynamic, then you can do:
ngModelElAttrs: {
tabindex: '{{to.tabindex}}' // to is a shortcut for `options.templateOptions`
},
expressionProperties: {
'templateOptions.tabindex': 'someFormlyExpression' // http://docs.angular-formly.com/docs/formly-expressions
}
Good luck!
I already have a full-fledged form in javascript. All I need is a simple label Lol.
It is using prior code, but hopefully this snipet will help to see what's happening:
export default class NewEvent extends FormStep {
get inputs() {
return [{
name: 'department',
label: 'Department / Specific Ministry'
}, {
name: 'title'
}, {
name: 'description',
type: 'textarea'
}, {
name: 'checkboxApproved',
type: 'checkbox',
label: 'This copy is approved and is to be used as written.'
}, {
name: 'checkboxDetails',
type: 'checkbox',
label: 'These are the details! Please help me write a catchy description.'
}, {
name: 'location'
}, {
name: 'contactName',
label: 'Event Contact Name'
}, {
name: 'contactEmail',
label: 'Event Contact Email (required)'
}, {
name: 'contactPhone',
label: 'Event Contact Phone (optional)'
}, {
name: 'eventURL'
}, {
name: 'isNewHRock',
type: 'checkbox',
label: 'This event is a new event we\'ve never done at HRock.'
}, {
name: 'hasOccurred',
type: 'checkbox',
label: 'We\'ve had this event before, but it is not on a recurring schedule.'
}, {
name: 'needsRegistration',
type: 'checkbox',
label: 'We need to set up registration for this event.'
}, <EventPrice key = 'eventPrice' /> , <EventClassInfo key = 'eventClassInfo' /> , <EventDateTimeInfo key = 'eventDateTimeInfo' /> ]
}
}
Anyways, all these items show up as a form. AS they should. But I'd like to simply add a label in between the check boxes. I've created the following screenshot of what I'd like to add.
However, whenever I add text in there so far, it breaks the code, or it shows up in a textfield...
Help?
This is an object of "inputs". What ever function is parsing this object is creating all inputs with it, which is why you get a textbox. I don't think this is the correct place in the code to do this.