Disable second input when first is filled in Vue - vue.js

I have a form, with two input fields.
How do I disable the alternate field when one is filled? For example, both fields start as being enabled. But, when I enter something in field 1, field 2 should be disabled, and vice versa -- so the user can only use one of the fields, not both at the same time.
In jQuery, I used the keyup event, and checked the length (> 0) of the field that generated the event, and disabled the other field. Similarly, for the other field. In Vue, I don't know how to reference another field, to disable it with :disable="true".

Something like this should work:
<input type="text" v-model="firstField" :disabled="!!secondField" />
<input type="text" v-model="secondField" :disabled="!!firstField" />
This assumes that you have a data attribute for both firstField and secondField.

Take a look
<div id="app">
<input type="text" v-model="text1" :disabled="shouldDisable1" #keyup="disable('second')">
<input type="text" v-model="text2" :disabled="shouldDisable2" #keyup="disable('first')">
</div>
new Vue({
el: "#app",
data: {
text1: '',
text2: '',
shouldDisable1: false,
shouldDisable2: false
},
methods: {
disable(input) {
if(input == 'first') {
this.shouldDisable1 = true
if (this.text2 == '') this.shouldDisable1 = false
}else {
this.shouldDisable2 = true
if (this.text1 == '') this.shouldDisable2 = false
}
}
}
})
See it in action in jsfiddle

Related

How can I defined as Default checked in a checkbox with Vuejs

I have tried all that I have read in other questions and they did not answer me the problem.
I have a checkbox like this in a list
<input type="checkbox" v-model="selected" :value="post.rut">
I have the model defined like this:
data: function() {
return {
selected: []
}
}
The problem is that If I add checked as default.. it does not change at all I mean it keeps the checkbox not checked
<input type="checkbox" v-model="selected" :value="post.rut" checked>
If I remove the v-model, it works BUT I can not send the value to the controller because I need the v-model to bind so I wonder how can I set as default checked in that checkbox input like that?
Thanks
you have the input value as post.rut you can put it in selected array in data like :
data: function() {
return {
selected: [this.post.rut]
}
}
If you already know which field you want to selected based on the post you can do like so:
data: function() {
return {
selected: [this.post.rut]
Here is a working example of what you asked for.
Note: You need not use v-model and :value at the same time since v-model itself is a two way binder.
var app = new Vue({
el: '#app',
data() {
return {
selected: true
};
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input type="checkbox" v-model="selected"/>
</div>

Hide one item from input list that is dynamically generated unless other input from list has value in vue / vuetify

So the process is like this. I have a form that is created from api. I want to show all the inputs except for one. That one will only be shown if the user adds value to another specific input from the form.
Something like this is the idea.
<Form>
<div-for="formItem in state.formItemData">
<template v-if="formItem.one !== ''">
<form-input
v-model="invoiceForm.two"
:key="formItem.id"
ref="two"
></form-input>
</template>
</div>
</Form>
const invoiceForm = computed({
get: () => state.forms.formData,
set: (value) => {
state.forms.formData= value
}
})
The concept in your problem is very simple, you just must make use of a computed property that evaluates if there are values in input 1 and it will rerender the component showing input2.
new Vue({
el: '#app',
data: {
input1: '',
input2: ''
},
methods: {
verification() {
console.log(this.input1);
}
},
computed: {
notEmpty() {
return this.input1 !== '' && this.input1.length > 3;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input #change="verification" type="text" v-model="input1"> <input v-if="notEmpty" type="text" v-model="input2">
</div>
You should use a v-show if you're eventually going to show/hide it when rendering, especially if it's going to be multiple times. The Vue documentation says that the v-if will not be rendered when the initial condition is false.
Source: https://v3.vuejs.org/guide/conditional.html#v-if-vs-v-show

vue.js v-model on input can not differentiate between empty input and invalid input

I am trying to validate some input data (e.g. number) on an input-tag connected to some data via v-model.
The problem is, if I have invalid data (e.g. "1e"), the data will be "". Same goes obviously for empty input.
How can I differentiates empty input or invalid input?
var app = new Vue({
el: "#app",
data: {
budget: "",
},
methods: {
updateBudget() {
// do some input validation here. E.g.
if (this.budget === "") {
console.log("This is triggered on both:");
console.log("(1) empty input -> budget = ''");
console.log("(2) invalid input, e.g. -> budget = '1e'");
console.log("Problem: I can't split this in the above cases!");
};
},
},
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.12/dist/vue.js"></script>
<div id="app">
<input v-model="budget" type="number" placeholder="Budget" min="0" step="0.01" #input="updateBudget" />
</div>
I'd appreciate a hint. Thanks
1e is not a number (also +, -). The output is empty as it's not a valid number, try to insert 1e0 or -1, you'll be able to catch the value. There are some related issues:
It is exactly how the spec says.
How to prevent extra characters
To catch the exact number without worry about 'e' use the internal Vue implementation. It takes care of such situations. (v-model.number)
<input
v-model.number="budget"
type="number"
placeholder="Budget"
min="0"
step="0.01"
#input="updateBudget"
/>
By the way, if you want to check 'e' explicitly, I think, it's better to use 'type=text'.
I did a custom solution based on some regex. Something like:
<template>
<div id="app">
<input v-model="budget" type="text" #input="validateAndUpdateInput" />
</div>
</template>
<script>
[...]
methods: {
validateAndUpdateInput: function() {
if (!/^-?([0]?|[1-9]{1}\d{0,15})([.]{1}\d{0,2})?$/.test(this.budget)) {
this.budget = this.previousInput;
//alert("not valid");
} else {
this.previousInput = this.budget;
this.$emit("update-input", this.budget);
}
},
[...]
</script>

Updating v-model data in form inputs with a series of methods in a Vuetify project?

I am attempting to update a series of v-text-fields (type='number') so that after the user has entered in a numeric value, the number shown in the input will be updated with commas (so a value of 5032 would become 5,032 for example). I found this article and was able to accomplish what I'm after with a single input using the example provided...
Markup:
<div id="app">
<div v-if="visible === true">
Enter Amount: <br>
<input type="number"
v-model="amount"
placeholder="Enter Amount"
#blur="onBlurNumber"/>
</div>
<div v-if="visible === false">
Enter Amount: <br>
<input type="text"
v-model="amount"
placeholder="Enter Amount"
#focus="onFocusText"/>
</div>
Script:
data: {
amount: null,
temp: null,
visible: true
},
methods: {
onBlurNumber() {
this.visible = false;
this.temp = this.amount;
this.amount = this.thousandSeprator(this.amount);
},
onFocusText() {
this.visible = true;
this.amount = this.temp;
},
thousandSeprator(amount) {
if (amount !== '' || amount !== undefined || amount !== 0 || amount !== '0' || amount !== null) {
return amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else {
return amount;
}
}
}
...but I want to make the methods generic enough to work with any numeric v-text-fields I am using. I have been able to update a parameter value within my methods, but have been unable to actually update the v-model data of the v-text-field.
Markup:
<div id="app">
<div v-if="visible === true">
<v-text-field
class="mb-3 d-inline-block"
type="number"
prepend-inner-icon="attach_money"
v-model="amount"
label="Amount"
mask="##########"
outline
:rules="[v => !!v || 'Amount is required']"
#blur="onBlurNumber(amount)"
required>
</v-text-field>
</div>
<div v-if="visible === false">
<v-text-field
class="mb-3 d-inline-block"
prepend-inner-icon="attach_money"
v-model="amount"
label="Amount"
outline
#focus="onFocusText(amount)"
>
</v-text-field>
</div>
Script:
onBlurNumber(data) {
this.visible = false;
this.temp = data;
data = this.thousandSeprator(data);
},
onFocusText(data) {
this.visible = true;
data = this.temp;
},
I can log the value of data in these methods and confirm that the commas are being applied correctly, but now I don't know how to send the data value back to update the v-text-field's v-model. I experimented with selecting the v-text-field using a ref value but the ref turns up as an undefined value when the method is triggered.
Does anyone know how I can update the v-model of the v-text-field using arguments in this sort of fashion so the methods are reusable?
I assume that you have multiple data items for each of the text fields:
data: function() {
return {
// Field 1
temp1: null,
amount1: null,
visible1: true,
// Field 2
temp2: null,
amount2: null,
visible2: true
}
}
In your markup, when calling the method you could then pass the name of the property, or maybe its suffix.
<v-text-field #blur="onBlurNumber('2')"
And in your script, you could update the data items by using dynamic properties:
methods: {
onBlurNumber(suffix) {
this["visible" + suffix] = false;
this["temp" + suffix] = this["amount" + suffix];
this["amount" + suffix] = this.thousandSeprator(this["amount" + suffix]);
},
Here's a working example of two independent text inputs that are calling the same methods to achieve this. We could refactor this to reduce the number of data items using arrays if needed.

How to prevent Vue input from setting value?

I have the following Vue code:
// HTML
<div id="app">
Value: <pre>{{ value }}</pre>
<input type="text" :value="value" #input="setValue">
</div>
// JS
new Vue({
el: "#app",
data: {
value: '',
},
methods: {
setValue(event){
/* Remove non-numeric values */
this.value = event.target.value.replace(/[^\d]/g, '');
}
}
});
I have it set up on JSFiddle here: http://jsfiddle.net/eywraw8t/353729/.
Why does the input allow me to enter non-numeric values?
If you run the code above, and enter non-numeric gibberish into the input element (e.g. asdasfa), you'll see that the input element will contain your entered text (asdasfa), but the element above the input will be empty!
I would like to restrict users to only being allowed to enter numbers into the input. I would like to do this using only Vue, no 3rd party libraries or type="number".
because the value of this.value doesn't change (always ='') so it will not trigger re-render.
The solution:
you can use this.$forceUpdate() to force re-render.
or use bind key with different value.
new Vue({
el: "#app",
data: {
value: '',
errorDescription: ''
},
methods: {
setValue(event){
/* Remove non-numeric values */
this.value = event.target.value.replace(/[^\d]/g, '')
this.errorDescription = 'Only Number allow'
this.$forceUpdate()
}
}
})
.error {
background-color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
Value: <pre>{{ value }}</pre><span class="error">{{errorDescription}}</span>
<input type="text" :value="value" #input="setValue">
</div>
The issue is Vue doesn't see a change to your value data property because when you filter out non-numbers, you are essentially assigning the same string value back to it. Since strings are immutable and identical when their contents are the same, this doesn't trigger Vue's reactivity.
An easy solution is to manually set the <input> value to the new, number-only value.
this.value = event.target.value = event.target.value.replace(/\D/g, '')
http://jsfiddle.net/9o2tu3b0/