4

This is my minimal working example, the following example uses version 2.x of element UI which we are currently using in this project.

https://codepen.io/peter-peter-the-typescripter/pen/WNGxWEB

{{ input }}
<el-input-number placeholder="Please input" :value="input" @input="onInput" />

onInput(val) {
  console.log('input', val)
  this.input = val
  this.$emit('input', val)
}

In previous version 1.x, input was able to emit value during on @change with little delay (few ms). However, it changes on v2.x. Can you tell me how to edit this code so it emits and validate the value almost immediately after I finish typing?

Is it possible to create similar behaviour what we had in version 1.x?
Check it here: https://element.eleme.io/1.4/#/en-US/component/input-number

Thank you.

Irfandy Jip
  • 1,308
  • 1
  • 18
  • 36
Denis Stephanov
  • 4,563
  • 24
  • 78
  • 174
  • what type of validation are you trying to achieve what was the problem you were getting can you please be specific – Chandan Dec 11 '20 at 18:11
  • @Chandan element ui provide props for validation (min, max, ...), and when you unfocus input, value is validated and emited. For instance I can set on input max value 100, but I type 10000. Input validate my number and set max number by my rule, so value will be 100. This happens after I unfocus input, but I need ensure this behaviour on the fly. User should edit input and see other calculations based on entered number. – Denis Stephanov Dec 11 '20 at 18:40
  • @Chandan also I edited question and add link to number input of version 1 which is my goal here – Denis Stephanov Dec 11 '20 at 20:00
  • @DenisStephanov so what you need is to stop the user's input when it didn't fulfill its validation as the user types? – Irfandy Jip Dec 13 '20 at 15:42
  • @IrfandyJip Hi, check pls url to docs of element ui version 1.x. Number input in this versions is exactly what I need. It emits value immediately by user interaction and validate it. Version 2 emmit and validate after you go out from input – Denis Stephanov Dec 14 '20 at 09:25
  • @DenisStephanov i have posted answer can you verify does it fit your requirement? – Chandan Dec 14 '20 at 16:18
  • @Chandan Hello, I saw it thank you, but I am not close to my PC, I try it immediately hen I will be. As I can see there is custom validation, so there is no way to programically trigger element UI event on change instead of leaving input? – Denis Stephanov Dec 14 '20 at 22:17
  • try using watchers in vue, – Aliasgher Nooruddin Dec 15 '20 at 05:50
  • @DenisStephanov, thanks for replying, what setup are you using? Are you using webpack to bundle your web? (Y/N). If **yes**, I can think of some way you can create your own "InputNumber.vue" which uses the `` behind the scene. If **not**, the answer provided by both Chandan and KienHT which uses `@input.native` are the only way to emit the events. Cause I've tried using 2.14.1 on the codepen, and it seems that the `@change` is even bugged. Since it only emits after you unfocused the input. – Irfandy Jip Dec 15 '20 at 14:34

3 Answers3

3

Try this:

<el-input-number placeholder="Please input" v-model="input" @input.native="onInput" />

Instead of using v-bind, just use v-model and use native input event instead. According to this document, there is no input event, but only change event for el-input-number tag.

Link to their document: https://element.eleme.io/#/en-US/component/input-number#inputnumber

KienHT
  • 1,098
  • 7
  • 11
  • Thank you for effort but this handle raw event object. I am looking for how to trigger default input event but with little delay after typing, instead of leaving input. :/ – Denis Stephanov Dec 11 '20 at 19:56
  • I added link to number input of element ui 1.x, there you can see what behaviour I need to achieve – Denis Stephanov Dec 11 '20 at 19:59
  • 2
    I'm not sure if you have this problem, but the default input event triggers twice every time. Some people have reported this issue – KienHT Dec 12 '20 at 01:22
  • Thank you but I was hoping there will be some way how to achieve that but it looks don't ... I upvote both of you guys to split bounty for effort – Denis Stephanov Dec 15 '20 at 19:33
2

Because validation is not applied on input change until unfocus and v-model or v-bind not seem to working we can access input tag using DOM or ref and then validate inside our function

<el-input-number placeholder="Please input" v-model="input" :min="min" :max="max" @input.native="onInput" />

You can access input using either DOM when component mounted or you can use ref to access el-input-number component and then use that to access input.

Here i used native input event because then only i can access input changes when typed by user and apply validation on input value.

var Main = {
  data() {
    return {
      input: '',
      min: 0,
      max: 100,
    }
  },
  mounted() {
    this.maxInputLength = String(this.max);
    this.inputElem = this.$el.querySelector('.el-input__inner'); // this.$el.querySelector('input');
  },
  methods: {
    onInput(evt) {
      let val = evt.target.value;
      let integer = parseInt(val);
      if (integer >= this.max || val.length > this.maxInputLength) {
        this.inputElem.value = 100;
      }
      else if (integer == 0) {
        this.inputElem.value = 0;        
      }
      else {
        this.inputElem.value = val;
      }
      this.$emit('input', val);
    },
  }
}
Chandan
  • 11,465
  • 1
  • 6
  • 25
  • Hi, it seems that there is no better way how to achieve my requirements so I upvoted you and kien to split bounty for effort. thank you – Denis Stephanov Dec 15 '20 at 19:36
0

Why not using the validation framework provided with element-ui, which supports validations on input?

var Main = {
    data() {
      return {
        ruleForm: {
          name: '',
        },
        rules: {
          name: [
            { required: true, message: 'Please input Activity name', trigger: 'change' },
            { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'change' }
          ],
        }
      };
    },
    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            alert('submit!');
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      }
    }
  }
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
@import url("//unpkg.com/element-ui@2.14.1/lib/theme-chalk/index.css");
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui@2.14.1/lib/index.js"></script>
<div id="app">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="120px" class="demo-ruleForm">
  <el-form-item label="Activity name" prop="name">
    <el-input v-model="ruleForm.name"></el-input>
  </el-form-item>
  <el-form-item>
    <el-button type="primary" @click="submitForm('ruleForm')">Create</el-button>
    <el-button @click="resetForm('ruleForm')">Reset</el-button>
  </el-form-item>
</el-form>
</div>
dreijntjens
  • 4,577
  • 26
  • 28
  • hi, my main problem is with emmiting input value ... my use case is when user typed some value, value is validated and for instance edited by input min / max validations, and then with little delay (200ms) emitted, I need use this value to other calculations which should be in real time ... but instead emitting after user change with delay, value is emitted after you leave input . which is too late for my calculations ... user should see calculations, and by these calculations change number value – Denis Stephanov Dec 16 '20 at 13:07
  • I don't think it is a good approach to modify a user input. as it could be come very confusing. Personnaly I would debounce the input so people are allowed to multiple characters, Is the input not correct the the output is not correct (Garbage in = Garbage out). Still you could use some computed values to make sure you have some decent input values for your calculations – dreijntjens Dec 16 '20 at 13:36
  • its default behavior of number input in EL UI, if input has max 100, and user enter 10000, then after debounce element UI change this value to max available, which is 100 – Denis Stephanov Dec 16 '20 at 15:13