Is there a way to toggle visibility for multiple password fields with a dynamic form using vuetify vuejs?

658 Views Asked by At

I have a dynamic form that is constructed based off of json from the backend of input types, id, names, values, etc. One of my forms has two password fields that come from the backend. Is there a way to toggle visibility for multiple password fields on the same dynamic form? I'm having trouble figuring out how to do this to one at a time. Right now, the toggle icon switches both password fields on the screen.

<template>
  <div class="pb-4" >
    <template v-for="formField in formFields">
      <v-row 
        :key="formField.key"
        dense
        align="center"
      >
        <v-col
          md="3"
          class="font-weight-bold text-right pr-10"
          align-self="center"
        >
          {{formField.name}}
          <span v-if="formField.required" class="small">&nbsp;*</span>
        </v-col>
        <v-col
          md="8"
          align-self="center"
          class="pl-3"
        >
          <v-text-field
            v-if="formField.type === 'password'"
            :id="formField.key"
            :key="formField.key"
            v-model="formField.value"
            :append-icon="showPasswordIcon ? '$vuetify.icons.values.eye' : '$vuetify.icons.values.eyeSlash'"
            :type="showPasswordIcon ? 'text' : 'password'"
            :hint="getHintText(formField)"
            :value="formField.name"
            :required="formField.required"
            :valid="(!formField.isValid) ? false : undefined"
            dense
            @input="inputHandler(formField)"
            @blur="inputHandler(formField, false)"
            @click:append="showPasswordIcon = !showPasswordIcon"
          />
          <v-text-field
            v-if="formField.type === 'text'"
            :id="formField.key"
            v-model="formField.value"
            dense
            :valid="(!formField.isValid) ? false : undefined"
            @input="inputHandler(formField)"
            @blur="inputHandler(formField, false)"
          />
          <v-checkbox
            v-if="formField.type === 'boolean'"
            :id="formField.key"
            v-model="formField.value"
            class="mt-2"
          />
          <v-text-field
            v-if="formField.type === 'number'"
            :id="formField.key"
            v-model.number="formField.value"
            dense
            :valid="(!formField.isValid) ? false : undefined"
            class="mb-0"
            type="number"
            @input="inputHandler(formField)"
            @blur="inputHandler(formField, false)"
          />
        </v-col>
      </v-row> 
    </template>
  </div>
</template>

Thank you so much for any tips on this!

1

There are 1 best solutions below

0
Jason Landbridge On

Easiest solution might be to add an extra property to each element in the formFields, like visible, that tracks if a password should show its text. You can do that on API response and then insert it.

Then in your loop you can do

:type="formField.visible ? 'text' : 'password'"

This way, every formField is responsible for their own password visibility.

Next, you change

@click:append="showPasswordIcon = !showPasswordIcon"

to

@click:append="toggleShowPassword(formField.key)"
toggleShowPassword(key){
    let formfield = this.formfields.find(x => x.key === key)
    if(formfield){
        formfield.visible = !formfield.visible
    }
}

That should work!