Bonjour,
Je suis en train de réaliser une appli web, j'utilise le framework VueJS pour la partie front.
Comme mon application contient pas mal de formulaire, j'ai décidé de créer des composants pour les champs standard (Input, Select, Textarea).
Voici ci-dessous le code du composant pour les champs de type Input text :
fieldsComponents: {
'text': Vue.component('text-field', {
props: {
'form': '',
'name': '',
'label': {
type: String,
default: ""
},
'value': '',
'fieldClass': {
type: String,
default: "form-control"
},
'isInvalid': {
type: Boolean,
default: false
},
'required': {
type: String,
default: "required"
},
'parentClass': {
type: String,
default: "clear-field"
},
'maxlength': {
type: Number,
default: 45
}
},
computed: {
id: function() { return this.$parent.computFieldId(this.form, this.name, this.$options.name); },
fieldName: function() { return this.$parent.computFieldName(this.form, this.name, this.$options.name); },
fieldClassComputed: function() {
return this.isInvalid === true ? this.fieldClass +' is-invalid' : this.fieldClass;
},
parentId: function() { return this.id + '-field'; },
requiredComputed: function() { return this.required === 'required' ? 'required' : null; }
},
// v-on:input="$emit(\'input\', $event.target.value)" is required for the v-model functionnality, see https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components
template: '<div :id="parentId" :class="parentClass">'
+ '<label v-if="label.length" :for="id" :class="requiredComputed">{{label}}</label>'
+ '<div class="field-wrapper text-wrapper form-group"><input :class="fieldClassComputed" type="text" :id="id" :mame="fieldName" :required="requiredComputed" :maxlength="maxlength" :value="value" v-on:input="$emit(\'input\', $event.target.value)"/></div></div>'
}),
Voici ci-dessous le code du composant pour les champs de type Textarea :
'textarea': Vue.component('textarea-field', {
props: {
'form': '',
'name': '',
'label': {
type: String,
default: ""
},
'value': '',
'fieldClass': {
type: String,
default: "form-control"
},
'isInvalid': {
type: Boolean,
default: false
},
'required': {
type: String,
default: "required"
},
'parentClass': {
type: String,
default: "clear-field"
},
'maxlength': {
type: Number,
default: 345
}
},
computed: {
id: function() { return this.$parent.computFieldId(this.form, this.name, this.$options.name); },
fieldName: function() { return this.$parent.computFieldName(this.form, this.name, this.$options.name); },
fieldClassComputed: function() {
return this.isInvalid === true ? this.fieldClass +' is-invalid' : this.fieldClass;
},
parentId: function() { return this.id + '-field'; },
requiredComputed: function() { return this.required === 'required' ? 'required' : null; }
},
template: '<div :id="parentId" :class="parentClass">'
+ '<label :for="id" :class="requiredComputed">{{label}}</label>'
+ '<div class="field-wrapper textarea-wrapper form-group"><textarea class="form-control" :id="id" :mame="fieldName" :maxlength="maxlength" v-on:input="$emit(\'input\', $event.target.value)">{{value}}</textarea></div></div>'
}),
Voici un exemple d'appel des champs depuis mon template html :
<text-field form="lambda" name="software" v-model="forms.lambda.values.software" :label="tr.lambda_form_new_software_label" :is-invalid="forms.lambda.errors.fields.includes('software')" ></text-field>
<textarea-field form="lambda" name="description" v-model="forms.lambda.values.description" :value="forms.lambda.values.description" :label="tr.lambda_form_description_label" required="false"></textarea-field>
Mon problème
J'ai un comportement différent entre les champs Input et les champs Textarea.
Le problème se situe au niveau de la gestion de la valeur (value), celle-ci est conservée "en mémoire" même si je la réinitialise.
Scénario
Chaque formulaire se trouve dans une modale.
Si je fais un debug de "forms.lambda.values.description" dans ma console, la valeur est pourtant bien une chaine de caractère vide (état initial).
J'en appel à votre aide car je ne vois pas où est le problème... peut-être du côté de "$emit" qui est un concept que je ne maitrise pas.
Merci d'avance,