Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error messages is broken #8

Open
joweste opened this issue Jun 29, 2020 · 5 comments
Open

Error messages is broken #8

joweste opened this issue Jun 29, 2020 · 5 comments

Comments

@joweste
Copy link

joweste commented Jun 29, 2020

Hi, I am try to use vuelidate with your component.
The problem is that error messages validations is never showing.
Is possible you fix it?
If I use v-text-field all is ok.

I am using next code.

<vuetify-money
                        v-model="preco_proced.qm2"
                        class="purple-input"
                        label="Qtde M2 Filme"
                        placeholder="0,00"
                        :clearable="true"
                        :valueWhenIsEmpty="'0.000000'"
                        :options="optionsNumberFilme"
                        :error-messages="valorErrors($v.preco_proced.qm2)"
                        persistent-hint
                        required
                        @input="$v.preco_proced.qm2.$touch()"
                        @blur="$v.preco_proced.qm2.$touch()"
                      /> 


methods: {
    valorErrors(model) {
      //debugger;
      const errors = [];
      if (!model?.$dirty) return errors;
      !model.required && errors.push("Valor é obrigatório");
      console.log(model.isNumber);
      !model.isNumber && errors.push("Valor é obrigatório");
      console.log(errors);
      return errors;
    },
@juareznasato
Copy link
Owner

Hi!
I don't know how you could integrate with vuelidate.
I use veevalidate and I make the validation directly on the v-model value.

@joweste
Copy link
Author

joweste commented Jun 29, 2020

Hi!
I don't know how you could integrate with vuelidate.
I use veevalidate and I make the validation directly on the v-model value.

I think In your source code component you forgot to pass the props error message.
As you can see in your source code, there is no props to error-messages.

https://github.com/juareznasato/vuetify-money/blob/master/src/components/VuetifyMoney.vue

<template>
  <div>
    <v-text-field
      v-model="cmpValue"
      v-bind:label="label"
      v-bind:placeholder="placeholder"
      v-bind:readonly="readonly"
      v-bind:disabled="disabled"
      v-bind:outlined="outlined"
      v-bind:dense="dense"
      v-bind:hide-details="hideDetails"
      v-bind:error="error"
      v-bind:rules="rules"
      v-bind:clearable="clearable"
      v-bind:backgroundColor="backgroundColor"
      v-bind:prefix="options.prefix"
      v-bind:suffix="options.suffix"
      v-on:keypress="keyPress"
    ></v-text-field>
  </div>
</template>

<script>
export default {
  model: { prop: "value", event: "input" },
  props: {
    value: {
      // type: String,
      type: [String, Number],
      default: "0" 

@joweste
Copy link
Author

joweste commented Jul 2, 2020

Suggestion to fix. It is working to me.

<template>
  <div>
    <v-text-field
      v-model="cmpValue"
      v-bind:label="label"
      v-bind:placeholder="placeholder"
      v-bind:readonly="readonly"
      v-bind:disabled="disabled"
      v-bind:outlined="outlined"
      v-bind:dense="dense"
      v-bind:hide-details="hideDetails"
      v-bind:error="error"
      v-bind:error-messages="errorMessages"
      v-bind:rules="rules"
      v-bind:clearable="clearable"
      v-bind:backgroundColor="backgroundColor"
      v-bind:prefix="options.prefix"
      v-bind:suffix="options.suffix"
      v-on:keypress="keyPress"
    ></v-text-field>
  </div>
</template>

<script>
export default {
  model: { prop: "value", event: "input" },
  props: {
    value: {
      // type: String,
      type: [String, Number],
      default: "0"
    },
    label: {
      type: String,
      default: ""
    },
    placeholder: {
      type: String,
      default: undefined
    },
    readonly: {
      type: Boolean,
      default: false
    },
    dense: {
      type: Boolean,
      default: false
    },
    error: {
      type: Boolean,
      default: false
    },
    hideDetails: {
      type: [Boolean, String],
      default: false
    },
    errorMessages: {
      type: [Array, String],
      default: () => []
    },
    rules: {
      type: [Array, String],
      default: () => []
    },
    disabled: {
      type: Boolean,
      default: false
    },
    outlined: {
      type: Boolean,
      default: false
    },
    clearable: {
      type: Boolean,
      default: false
    },
    backgroundColor: {
      type: String,
      default: "white"
    },
    valueWhenIsEmpty: {
      type: String,
      default: ""  // "0" or "" or null 
    },
    options: {
      type: Object,
      default: function() {
        return {
          locale: "pt-BR",
          prefix: "",
          suffix: "",
          length: 11,
          precision: 2
        };
      },
    },
  },
  data: () => ({}),
  /*
   v-model="cmpValue": Dessa forma, ao digitar, o valor é atualizado automaticamente no componente pai.
   O valor digitado entra pelo newValue do Set e é emitido para o componente pai.
   the-vue-mask nao funciona corretamente ao incluir valores existentes no componente pai.
  */
  computed: {
    cmpValue: {
      get: function() {
        return this.value !== null && this.value !== ""
          ? this.humanFormat(this.value.toString())
          : this.valueWhenIsEmpty;
      },
      set: function(newValue) {
        this.$emit("input", this.machineFormat(newValue));
      },
    },
  },
  methods: {
    humanFormat: function(number) {
      if (isNaN(number)) {
        number = "";
      } else {
        // number = Number(number).toLocaleString(this.options.locale, {maximumFractionDigits: 2, minimumFractionDigits: 2, style: 'currency', currency: 'BRL'});
        number = Number(number).toLocaleString(this.options.locale, {
          maximumFractionDigits: this.options.precision,
          minimumFractionDigits: this.options.precision,
        });
      }
      return number;
    },
    machineFormat(number) {
      if (number) {
        number = this.cleanNumber(number);
        // Ajustar quantidade de zeros à esquerda
        number = number.padStart(parseInt(this.options.precision) + 1, "0");
        // Incluir ponto na casa correta, conforme a precisão configurada
        number =
          number.substring(
            0,
            number.length - parseInt(this.options.precision)
          ) +
          "." +
          number.substring(
            number.length - parseInt(this.options.precision),
            number.length
          );
        if (isNaN(number)) {
          number = this.valueWhenIsEmpty;
        }
      } else {
        number = this.valueWhenIsEmpty;
      }
      if (this.options.precision === 0) {
        number = this.cleanNumber(number);
      }
      return number;
    },
    keyPress($event) {
      // console.log($event.keyCode); //keyCodes value
      let keyCode = $event.keyCode ? $event.keyCode : $event.which;
      // if ((keyCode < 48 || keyCode > 57) && keyCode !== 46) {
      if (keyCode < 48 || keyCode > 57) {
        // 46 is dot
        $event.preventDefault();
      }
      if (this.targetLength()) {
        $event.preventDefault();
      }
    },
    // Retira todos os caracteres não numéricos e zeros à esquerda
    cleanNumber: function(value) {
      let result = "";
      if (value) {
        let flag = false;
        let arrayValue = value.toString().split("");
        for (var i = 0; i < arrayValue.length; i++) {
          if (this.isInteger(arrayValue[i])) {
            if (!flag) {
              // Retirar zeros à esquerda
              if (arrayValue[i] !== "0") {
                result = result + arrayValue[i];
                flag = true;
              }
            } else {
              result = result + arrayValue[i];
            }
          }
        }
      }
      return result;
    },
    isInteger(value) {
      let result = false;
      if (Number.isInteger(parseInt(value))) {
        result = true;
      }
      return result;
    },
    targetLength() {
      if (
        Number(this.cleanNumber(this.value).length) >=
        Number(this.options.length)
      ) {
        return true;
      } else {
        return false;
      }
    },
  },
};
</script>

@juareznasato
Copy link
Owner

Ok joweste. Thanks for your help.
Released in version 1.0.3

@DevAngelCrow
Copy link

Does this mean that the @blur (v-on:blur) event cannot be accessed in the vuetify-money component?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants