Vue

by luka kupunia

HTML

<div id="app">
  <input v-for="(input , index) in creditCardNumber" ref="input" :class="{error : !input.correct}" maxlength="4" type="text" v-model="input.value" :key="index" @keydown="detectKey($event,index);preventKey($event,'number')" @paste="preventKey($event,'number')" @input="handleInput($event,index);preventKey($event,'number')">
</div>

CSS

body {
    margin: 0;
}
input {
    font-size: 24px;
    display: inline-flex;
    width: 100px;
    margin: 10px;
}

Vue

new Vue({
  el: "#app",
  data: {
    creditCardNumber: [
				{value: '',correct: true},
				{value: '',correct: true},
				{value: '',correct: true},
				{value: '',correct: true},
			]
  },
  methods: {
  	handleInput(e,index) {
			this.creditCardNumber[index].value.length === 4 &&
			this.changeInputFocus(index,'right')

			this.creditCardNumber[index].value.length === 0 &&
			this.changeInputFocus(index,'left')

			this.creditCardNumber[index].correct = this.creditCardNumber[index].value.length == 4
		},
		detectKey(e,index) {
			this.creditCardNumber[index].value.length === 4 &&
			e.keyCode != 8 &&
			e.keyCode > 47 &&
			e.keyCode < 58 &&
			this.changeInputFocus(index,'right')

			e.target.selectionStart === 0 &&
			e.keyCode === 8 && 
			this.changeInputFocus(index,'left')
		},
		changeInputFocus(index,direction) {
			let nextInput = direction === 'right' ? index + 1 : index - 1 
			if (this.$refs.input[nextInput] == undefined) return
			this.$refs.input[nextInput].focus()
			this.$refs.input[nextInput].selectionStart = 4
        	this.$refs.input[nextInput].selectionEnd = 4
		},
		preventKey(e, type, customKey) {
            if (e.type == 'paste' && type === 'number') {
                let pastedText = (e.clipboardData || window.clipboardData).getData('text')
                !pastedText.match(/^[0-9]*$/) ? e.preventDefault() : ''
            }
            if (e.type == 'paste' && type === 'letter') {
                let pastedText = (e.clipboardData || window.clipboardData).getData('text')
                !pastedText.match(/^[A-Za-z]+$/) ? e.preventDefault() : ''
            }
            let char = String.fromCharCode(e.keyCode);
            if (e.keyCode === 39) return true
            if (e.keyCode === 37) return true
            if (e.keyCode === 8) return true
            if (e.keyCode === 9) return true
            if (e.key === customKey) return true
            if (type === 'number') {
                if (/^[0-9]*$/.test(char)) return true;
    ...