Walidacja za pomocą vuelidate w VUE

0

Witam serdecznie,
Mam mały problem z vuelidate w Vue.

Mam taki kod:


      <template>
      <CCard>
        <CCardHeader>
          <CIcon name="cil-input-power"/>
          Edytuj administratora
        </CCardHeader>
        <CCardBody>
          <CRow>
            <CCol sm="12">
              <CForm>
                <CRow>
                  <CCol md="6">
                    <CInput
                      label="Imię"
                      :lazy="false"
                      :value.sync="$v.form.name.$model"
                      :isValid="checkIfValid('name')"
                      v-model="record.name"
                      placeholder="Imię administratora"
                      invalidFeedback="To pole jest wymagane i musi zawierać minimum 3 znaki i maksimum 255 znaków"
                    />
                  </CCol>
                  <CCol md="6">
                    <CInput
                      label="Nazwisko"
                      :lazy="false"
                      :value.sync="$v.form.surname.$model"
                      :isValid="checkIfValid('surname')"
                      v-model="record.surname"
                      placeholder="Nazwisko administratora"
                      invalidFeedback="To pole jest wymagane i musi zawierać minimum 3 znaki i maksimum 255 znaków"
                    />
                  </CCol>
                </CRow>
    
                <CInput
                  label="Telefon"
                  :lazy="false"
                  :value.sync="$v.form.phone.$model"
                  :isValid="checkIfValid('phone')"
                  v-model="record.phone"
                  placeholder="Numer telefonu administratora"
                  invalidFeedback="To pole jest wymagane i musi zawierać minimum 3 znaki i maksimum 255 znaków"
                />
    
                <CInput
                  label="Adres email"
                  v-model="record.email"
                  plaintext
                />
    
                <CRow>
                  <CCol md="6">
                    <CInput
                      :isValid="checkIfValid('password')"
                      :lazy="false"
                      :value.sync="$v.form.password.$model"
                      v-model="record.password"
                      label="Hasło (minimum 8 znaków)"
                      type="password"
                      placeholder="Hasło administratora do logowania"
                      invalidFeedback="To pole jest wymagane i musi zawierać minimum 8 znaków. Wymagane znaki to: liczby, duże i małe litery"
                    />
                  </CCol>
                  <CCol md="6">
                    <CInput
                      :isValid="checkIfValid('password')"
                      :value.sync="$v.form.password2.$model"
                      v-model="record.password2"
                      label="Powtórz hasło"
                      type="password"
                      placeholder="Ponownie hasło do logowania"
                      invalidFeedback="Pola hasła muszą być identyczne"
                    />
                  </CCol>
                </CRow>
    
                <CSelect id="status_id"
                         label="Status"
                         v-model="record.status_id"
                         :value.sync="record.status_id"
                         :plain="true"
                         :options="statuses"
                >
                </CSelect>
    
                <CTextarea
                  label="Notatka"
                  placeholder="Notatka o administratorze"
                  rows="9"
                  :lazy="false"
                  v-model="record.description"
                />
    
                <CButton
                  color="primary"
                  @click="submit"
                >
                  Zapisz
                </CButton>
                <CButton
                  class="ml-1"
                  color="success"
                  @click="goBack"
                >
                  Cofnij
                </CButton>
              </CForm>
              <br/>
            </CCol>
          </CRow>
        </CCardBody>
      </CCard>
    </template>
    
    <script>
    import axios from 'axios';
    import Vue from 'vue';
    import CKEditor from 'ckeditor4-vue';
    import Swal from "sweetalert2";
    import {validationMixin} from "vuelidate"
    import {required, minLength, email, sameAs, helpers} from "vuelidate/lib/validators"
    
    export default {
      data() {
        return {
          form: this.getEmptyForm(),
          submitted: false,
    
          record: {
            name: "",
            surname: "",
            phone: "",
            email: "",
            status_id: "",
            description: "",
            password: "",
            password2: "",
          },
          statuses: [],
        }
      },
      computed: {
        formString() {
          return JSON.stringify(this.form, null, 4)
        },
        isValid() {
          return !this.$v.form.$invalid
        },
        isDirty() {
          return this.$v.form.$anyDirty
        },
      },
      mixins: [validationMixin],
      validations: {
        form: {
          name: {
            required,
            minLength: minLength(3),
            maxLength: 255
          },
          surname: {
            required,
            minLength: minLength(3),
            maxLength: 255
          },
          phone: {
            required,
            minLength: minLength(3),
            maxLength: 255
          },
          password: {
            minLength: minLength(8),
            maxLength: 255,
            strongPass: helpers.regex('strongPass', /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}/)
          },
          password2: {
            maxLength: 255,
            sameAsPassword: sameAs("password")
          }
        }
      },
      methods: {
        goBack() {
          this.$router.replace({path: '/administrators'})
        },
        store() {
          let self = this;
          axios.post(this.$apiAdress + '/api/administrators/' + self.$route.params.id + '?token=' + localStorage.getItem("api_token"),
            {
              _method: 'PUT',
              name: self.record.name,
              surname: self.record.surname,
              phone: self.record.phone,
              status: self.record.status,
              description: self.record.description,
              password: self.record.password,
              password2: self.record.password2,
            })
            .then(function (response) {
              if (response.data.status == 'success') {
                Swal.fire(
                  'Sukces',
                  'Rekord zmieniony poprawnie!',
                  'success'
                ).then(function () {
                  self.$router.push('/administrators');
                });
              } else {
                Swal.fire(
                  'Błąd',
                  response,
                  'error'
                )
              }
            }).catch(function (error) {
            if (error.response.data.message != '') {
              let errorDetails = ""
              for (let key in error.response.data.errors) {
                errorDetails += `${error.response.data.errors[key]}<br/>`
              }
              Swal.fire(
                'Błąd',
                errorDetails,
                'error'
              )
              window.scrollTo({top: 0});
            } else {
              Swal.fire(
                'Błąd',
                error,
                'error'
              )
              self.$router.push({path: 'login'});
            }
          });
        },
        checkIfValid(fieldName) {
          const field = this.$v.form[fieldName]
          if (!field.$dirty) {
            return null
          }
          return !(field.$invalid || field.$model === '')
        },
    
        submit() {
          this.validate();
          if (this.isValid) {
            //this.submitted = true
            this.store();
          }
        },
    
        validate() {
          this.$v.$touch()
        },
    
        reset() {
          this.form = this.getEmptyForm()
          this.submitted = false
          this.$v.$reset()
        },
    
        getEmptyForm() {
          return {
            name: "",
            surname: "",
            phone: "",
            description: "",
            password: "",
            password2: "",
            status_id: null,
          }
        }
      },
      mounted: function () {
        let self = this;
        axios.get(this.$apiAdress + '/api/administrators/' + self.$route.params.id + '/edit?token=' + localStorage.getItem("api_token"))
          .then(function (response) {
            self.statuses = response.data.statuses;
            self.record = response.data.record;
          }).catch(function (error) {
          console.log(error);
          self.$router.push({path: '/login'});
        });
      }
    }
    </script>

  1. Kiedy uruchamiam stronę - wyświetla mi się formularz z danymi. To jest ok.
  2. Po kliknięciu przycisku „zapisz” walidacja zaczyna działać.
  3. Mój problem polega na tym, że kiedy zaczyna się walidacja, mam wszystkie pola oznaczone jako niepoprawne (nawet te wypełnione i pobrane z bazy danych). Jeżeli do tak uzupełnionego pola dodam jakiś znak - pole wejściowe zostanie oznaczone jako poprawne

Wie ktoś może jak to naprawić? ;)

0

bez sensu to jest zrobione, za dlugie i niepotrzbne, wystarczy zaraz za data default dodac validations: { } i tu okreslasz pola i co ma byc wymahgane i to wszystko tam moze z 10 linijek, po co te resety getemopty if valid itd ?

0

Przykład ze strony. Zrob to samo i dodaj tylko nowe pola. Nie brnij w to co tu masz bo tylko jeszcze bardziej bedzie niezczytelne

import { required, minLength } from 'vuelidate/lib/validators'

export default {
  data() {
    return {
      name: '',
      age: 0,
      submitStatus: null
    }
  },
  validations: {
    name: {
      required,
      minLength: minLength(4)
    }
  },
  methods: {
    submit() {
      console.log('submit!')
      this.$v.$touch()
      if (this.$v.$invalid) {
        this.submitStatus = 'ERROR'
      } else {
        // do your submit logic here
        this.submitStatus = 'PENDING'
        setTimeout(() => {
          this.submitStatus = 'OK'
        }, 500)
      }
    }
  }
}

<form @submit.prevent="submit">
  <div class="form-group" :class="{ 'form-group--error': $v.name.$error }">
    <label class="form__label">Name</label>
    <input class="form__input" v-model.trim="$v.name.$model"/>
  </div>
  <div class="error" v-if="!$v.name.required">Name is required</div>
  <div class="error" v-if="!$v.name.minLength">Name must have at least {{$v.name.$params.minLength.min}} letters.</div>
  <button class="button" type="submit" :disabled="submitStatus === 'PENDING'">Submit!</button>
  <p class="typo__p" v-if="submitStatus === 'OK'">Thanks for your submission!</p>
  <p class="typo__p" v-if="submitStatus === 'ERROR'">Please fill the form correctly.</p>
  <p class="typo__p" v-if="submitStatus === 'PENDING'">Sending...</p>
</form>
0

@masterc: problem w dalszym ciągu występuje (po wczytaniu danych z API) :(

1 użytkowników online, w tym zalogowanych: 0, gości: 1