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.

  • j'ouvre le formulaire une 1ere fois : tous les champs sont vides;
  • je remplis les champs;
  • je ferme le formulaire;
  • je rouvre le formulaire en prenant soint de réinitialiser les valeurs dans l'objet : les champs de type Input sont vides mais pas les champs de type Textarea qui ont conservé la valeur précédente;

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,

Aucune réponse