can't submit form select option Vuelidate - forms

I'm using Vuelidate version 0.7.6, for form validation, i have a selected option to validate it with submit form, if a chose a validate option or a null option i have error i wrote the same code for input text it works, but for select no:
<div class="col-md-4">
<label for="exampleFormControlS1">Famille:</label>
<select
class="form-control form-control-sm mt-2"
id="exampleFormControlSelect1"
name="family"
v-model="familyId"
#change="onChange($event)"
:class="{
'is-invalid': $v.family.$error,
'is-valid': !$v.family.$invalid,
}"
><option value="null">- -- -</option>
<option
v-for="lineItem in familyListe"
:key="lineItem.id"
:value="lineItem.id"
>
{{ lineItem.name }}</option
>
</select>
<div class="invalid-feedback">
<span v-if="!$v.family.required">Famille requise</span>
</div>
</div>
validations: {
family: {
required,
},
}

I guess you should change v-model to "family" instead of "familyId" to validate your field correctly.
<select
class="form-control form-control-sm mt-2"
id="exampleFormControlSelect1"
name="family"
v-model="family"
#change="onChange($event)"
:class="{
'is-invalid': $v.family.$error,
'is-valid': !$v.family.$invalid,
}"
>...
onChange method according to Vuelidate Docs: Form submission
methods: {
onChange() {
console.log("onChange!");
if (this.$v.$invalid) {
this.submitStatus = "ERROR";
} else {
this.submitStatus = "OK";
}
}
}
Check the following CodeSandbox for details:
https://codesandbox.io/s/stackoverflow-69434609-vuelidate-t11qy?file=/package.json

Related

How to disable autocomplete with v-form

I want to disable chrome autocomplete in my v-form. How do I do that? I don't see a autocomplete property on the v-form.
https://next.vuetifyjs.com/en/api/v-form/
While it is a property on a normal html form
https://www.w3schools.com/tags/att_form_autocomplete.asp
By setting autocomplete="username" and autocomplete="new-password" on v-text-field you can actually turn off the autocomplete in chrome.
here is a code that worked for me:
<v-form lazy-validation ref="login" v-model="validForm" #submit.prevent="submit()">
<v-text-field
v-model="user.email"
label="Email"
autocomplete="username"
/>
<v-text-field
v-model="user.password"
label="Password"
type="password"
autocomplete="new-password"
/>
<v-btn type="submit" />
</v-form>
Edit: autocomplete isn't set as a prop in vuetify docs but if you pass something to a component which isn't defined as prop in that component, it will accept it as an attribute and you can access it through $attrs.
here is the result of the above code in vue dev tools:
and here is the rendered html:
I wasn't able to get autofill disabled with the above methods, but changing the name to a random string/number worked.
name:"Math.random()"
https://github.com/vuetifyjs/vuetify/issues/2792
use autocomplete="off" in <v-text-field
<v-text-field
autocomplete="off"
/>
Just add:
autocomplete="false"
to your <v-text-field> or any input
autocomplete="null"
This one prevents Chrome autofill feature
I have not been able to get any of the previous proposals to work for me, what I finally did is change the text-flied for a text-area of a single line and thus it no longer autocompletes
Try passing the type='search' and autocomplete="off" props.
I also ran into a similar problem. Nothing worked until I found this wonderful Blog "How to prevent Chrome from auto-filling on Vue?" by İbrahim Turan
The main catch is that we will change the type of v-text-field on runtime. From the below code you can see that the type of password field is assigned from the value fieldTypes.password. Based on focus and blur events we assign the type of the field. Also, the name attribute is important as we decide based on that in the handleType() function.
I'm also pasting the solution here:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<div id="app">
<div v-if="isloggedin" class="welcome">
Welcome {{username}}
</div>
<div v-else id="form-wrapper">
<label for="username">Username: </label>
<input
v-model="username"
class="form-input"
type="text"
name="username"
value=""
autocomplete="off"
/>
<label for="password">Password: </label>
<input
v-model="password"
class="form-input"
:type="fieldTypes.password"
name="password"
value=""
#focus="handleType"
#blur="handleType"
autocomplete="off"
/>
<button class="block" type="button" #click="saveCredentials">
Submit Form
</button>
</div>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
username: '',
password: '',
isloggedin: false,
fieldTypes: {
password: 'text',
}
}
},
methods: {
saveCredentials() {
this.isloggedin = true;
},
handleType(event) {
const { srcElement, type } = event;
const { name, value } = srcElement;
if(type === 'blur' && !value) {
this.fieldTypes[name] = 'text'
} else {
this.fieldTypes[name] = 'password'
}
}
}
}
</script>

How to enable required validation in vuelidate based on onChange event of select field

I have to enable required validation for the input field based on the onChange event of select field. I'm using vuelidate package for form validation in my project. Kindly provide solution to accomplish it.
My Template Code Below:
<template>
<section class="page_blk">
<form #submit="submitForm($event)" class="cryp_form">
<div class="input_ctrl_wrp">
<label for="username">Template</label>
<div class="input_select">
<select #change="getTemplate" v-model="$v.adForm.tnc.$model" name="" id="">
<option value="">Select</option>
<option value="New">New</option>
<option :value="term.idTnCTemplate"
v-for="term in termsList"
:key="term.idTnCTemplate">{{term.title}}</option>
</select>
<i class="fal fa-angle-down"></i>
</div>
</div>
<div class="input_ctrl_wrp">
<label for="username">Title</label>
<div class="input_text">
<input v-model="$v.adForm.title.$model" placeholder="" type="text">
</div>
</div>
<div class="input_ctrl_wrp">
<label for="username">Terms Of Trade</label>
<div class="input_textarea">
<textarea v-model="$v.adForm.content.$model" name="" rows="10"></textarea>
</div>
</div>
</form>
</section>
</template>
My Script Below:
<script>
import { required,requiredIf, decimal, numeric } from "vuelidate/lib/validators";
export default {
data() {
return {
adForm: {
tnc: '',
title: '',
content: '',
}
}
},
validations: {
adForm: {
tnc: {
required
},
title: {
required
},
content: {
required: requiredIf( (abc) => {
console.log('abc',abc)
return true;
})
},
schedule: {
required
}
}
},
methods: {
submitForm(e) {
},
getTemplate(e) {
}
},
mounted() {
}
}
</script>
I want to toggle the validation to required for the title and content field, if the user select new and other option from dropdown. Please provide solution to accomplish it. Thanks in advance.

Accessible error messages in powermail

To make power mails error messages accessible for screenreaders I have to change HTML.
Original Powermail
<div class="form-group powermail_fieldwrap_name has-error">
<label for="powermail_field_name">Name<span class="mandatory">*</span></label>
<input required="required" data-parsley-required-message="Dieses Feld muss ausgefüllt werden!" data-parsley-trigger="change" class="form-control " id="powermail_field_name" type="text" name="tx_powermail_pi1[field][name]" value="" data-parsley-id="12">
<ul class="help-block filled" id="parsley-id-12"><li class="parsley-required">Dieses Feld muss ausgefüllt werden!</li></ul>
</div>
Accessible
<div class="form-group powermail_fieldwrap_name has-error">
<label for="powermail_field_name">Name<span class="mandatory">*</span></label>
<input required="required" data-parsley-required-message="Dieses Feld muss ausgefüllt werden!" data-parsley-trigger="change" class="form-control " id="powermail_field_name" type="text" name="tx_powermail_pi1[field][name]" value="" data-parsley-id="12" aria-describedby="parsley-id-12">
<ul class="help-block filled" id="parsley-id-12"><li class="parsley-required">Dieses Feld muss ausgefüllt werden!</li></ul>
</div>
In short: I have to add aria-describedby="parsley-id-12" to <input>.
In my own version of Ext:powermail/Resources/Private/Partials/Form/Field/Input.html I changed additionalAttributes to additionalAttributes="{aria-describedby:'error',vh:Validation.ValidationDataAttribute(field:field)}"
Complete partial
{namespace vh=In2code\Powermail\ViewHelpers}
<div class="powermail_fieldwrap powermail_fieldwrap_type_input powermail_fieldwrap_{field.marker} {field.css} {settings.styles.framework.fieldAndLabelWrappingClasses}">
<label for="powermail_field_{field.marker}" class="{settings.styles.framework.labelClasses}" title="{field.description}">
<vh:string.RawAndRemoveXss>{field.title}</vh:string.RawAndRemoveXss><f:if condition="{field.mandatory}"><span class="mandatory">*</span></f:if>
</label>
<div class="{settings.styles.framework.fieldWrappingClasses}">
<f:form.textfield
type="{vh:Validation.FieldTypeFromValidation(field:field)}"
property="{field.marker}"
placeholder="{field.placeholder}"
value="{vh:Misc.PrefillField(field:field, mail:mail)}"
class="powermail_input {settings.styles.framework.fieldClasses} {vh:Validation.ErrorClass(field:field, class:'powermail_field_error')}"
additionalAttributes="{aria-describedby:'error',vh:Validation.ValidationDataAttribute(field:field)}"
id="powermail_field_{field.marker}" />
</div>
</div>
This ends with
The argument "additionalAttributes" was registered with type "array",
but is of type "string" in view helper
"TYPO3\CMS\Fluid\ViewHelpers\Form\TextfieldViewHelper"
I can't found a solution in templates because error id is set by parsley validation. So I add this jQuery JavaScript. Because I override some powermail templates jQuery selectors can vary.
$('form[data-parsley-validate]').parsley().on('form:error', function() {
var errorId;
$.each(this.fields, function(key, field) {
if (field.validationResult !== true) {
switch (field.$element.attr('type')) {
case 'radio':
errorId = field.$element.closest('.powermail_radio_group')
.children('.powermail_field_error_container')
.children('ul').attr('id');
break;
case 'checkbox':
errorId = field.$element.closest('.powermail_checkbox_group')
.children('.powermail_field_error_container')
.children('ul').attr('id');
break;
default:
errorId = field.$element.next('ul').attr('id');
}
field.$element.attr('aria-describedby',errorId);
}
});
});
You may use the data-attribute like data="{describedby: 'error'}"
It seems to be fixed in the current parsley.js version 2.9.1. Parsley is now adding the described-by attribute.
the problem is described in this pull request: https://github.com/guillaumepotier/Parsley.js/pull/1280
The current Powermail version 7.3.1 is coming with the outdated parsley version 2.7.2. So you have to add the current parsley.js version by your own.

Angular 2 Template Driven Forms - Array Input Elements

I have been struggling for 1 and half day and still couldn't find any solution to the problem. I am working on simple form which has select and checkboxes element.When I try submitting the form I do not get the values of select and checkboxes but rather I just get true in the console.
I am working on template driven form.
<form (ngSubmit)="addSubcontractor(subcontractorForm)" #subcontractorForm="ngForm">
<h5>Type :</h5>
<div class="form-group">
<div *ngFor="let contractor_type of contractor_types;let i = index;" class="pull-left margin-right">
<label htmlFor="{{ contractor_type | lowercase }}">
{{ contractor_type }} :
</label>
<input type="checkbox" name="_contractor_type[{{i}}]" [value]="contractor_type" ngModel>
</div>
<div class="form-group">
<select class="form-control costcodelist" name="_cc_id[]" multiple="true" ngModel>
//When I put ngModel on select I just keep getting error
//TypeError: values.map is not a function
<option *ngFor="let costcode of costcodes" [selected]="costcode.id == -1" [value]="costcode.id">{{ costcode.costcode_description }}</option>
</select>
</div>
</form>
Component Section
export class SubcontractorComponent implements OnInit, OnDestroy {
private contractor_types = ['Subcontractor', 'Supplier', 'Bank', 'Utility'];
constructor(private costcodeService: CostcodeService,
private subcontractorService: SubcontractorService) {
this.subcontractorService.initializeServices();
}
ngOnInit() {
this.costcode_subscription = this.costcodeService.getAll()
.subscribe(
(costcodes) => {
this.costcodes = costcodes;
});
}
addSubcontractor(form: NgForm) {
console.log(form.value);
}
}
When I remove ngModel from select element the code runs fine and When I submit the form I get the following output.
_contractor_type[0]:true
_contractor_type[1]:true
_contractor_type[2]:true
_contractor_type[3]:""
I do not get the checkboxes values as well the selected options from select element.
Your comments and answer will appreciated a lot.
Thanks
Here is a simple selection that i use with my Template driven form.
<form #f="ngForm" (submit)="addOperator(f.valid)" novalidate>
<label>Name</label>
<input [(ngModel)]="operator.name" name="name">
<label >Service</label>
<select #service="ngModel" name="service" [(ngModel)]="operator.service">
<option *ngFor='let service of services' [ngValue]='service'>{{service.name}}</option>
</select>
<label >Enabled</label>
<label>
<input type="checkbox" name="enabled" [(ngModel)]="operator.enabled">
</label>
<button type="submit">Create Operator</button>
</form>
.ts
operator: Operator;
ngOnInit() {
this.operator = <Operator>{}; // // Initialize empty object, type assertion, with this we loose type safety
}
addOperator(isValid: boolean) {
if (isValid) {
this.operatorsService.addOperator(this.operator).then(operator => {
this.goBack();
});
}
}
Also im importing this
import { FormsModule, ReactiveFormsModule } from '#angular/forms';

Angular form validation: ng-show when at least one input is ng-invalid and ng-dirty

I have the following form in an Angular partial:
<form name="submit_entry_form" id="submit_entry_form" ng-submit="submit()" ng-controller="SubmitEntryFormCtrl" novalidate >
<input type="text" name="first_name" ng-model="first_name" placeholder="First Name" required/><br />
<input type="text" name="last_name" ng-model="last_name" placeholder="Last Name" required/><br />
<input type="text" name="email" ng-model="email" placeholder="Email Address" required/><br />
<input type="text" name="confirm_email" ng-model="confirm_email" placeholder="Confirm Email Address" required/><br />
<span ng-show="submit_entry_form.$invalid">Error!</span>
<input type="submit" id="submit" value="Submit" />
</form>
The trouble I'm having is with the span at the bottom that says "Error!". I want this to show ONLY if one of the inputs is both "ng-dirty" and "ng-invalid". As it is above, the error will show until the form is completely valid. The long solution would be to do something like:
<span ng-show="submit_entry_form.first_name.$dirty && submit_entry_form.first_name.$invalid || submit_entry_form.last_name.$dirty && submit_entry_form.last_name.$invalid || submit_entry_form.email.$dirty && submit_entry_form.email.$invalid || submit_entry_form.confirm_email.$dirty && submit_entry_form.confirm_email.$invalid">Error!</span>
Which is UGLY. Any better way to do this?
Method 1: Use a function on $scope set up by your controller.
So with a better understanding of your problem, you wanted to show a message if any field on your form was both $invalid and $dirty...
Add a controller method:
app.controller('MainCtrl', function($scope) {
$scope.anyDirtyAndInvalid = function (form){
for(var prop in form) {
if(form.hasOwnProperty(prop)) {
if(form[prop].$dirty && form[prop].$invalid) {
return true;
}
}
}
return false;
};
});
and in your HTML:
<span ng-show="anyDirtyAndInvalid(submit_entry_form);">Error!</span>
Here is a plunker to demo it
Now all of that said, if someone has entered data in your form, and it's not complete, the form itself is invalid. So I'm not sure this is the best usability. But it should work.
Method 2: Use a Filter! (recommended)
I now recommend a filter for this sort of thing...
The following filter does the same as the above, but it's better practice for Angular, IMO. Also a plunk.
app.filter('anyInvalidDirtyFields', function () {
return function(form) {
for(var prop in form) {
if(form.hasOwnProperty(prop)) {
if(form[prop].$invalid && form[prop].$dirty) {
return true;
}
}
}
return false;
};
});
<span ng-show="submit_entry_form | anyInvalidDirtyFields">Error!</span>