How do I replicate v-models :value with :value? - vue.js

I get different behavior between using #input and v-model, and #input and :value.
What is v-model doing different with :value that I dont get with only using :value?
I created an example at jsFiddle that show the difference: that the top input field would allow only numbers to be typed into the input, while the bottom will allow everything to be typed in.
What do I need to do to get the same functionality by using only #input and :value?

You can achieve this by adding an ref to the input and updating input value through it. Check here. https://jsfiddle.net/RiddhiParekh/nzfr0xy3/
Template =>
<div id="app">
<div>
<input #input="mask1"
v-model="message1"
type="text"
placeholder="Only numbers are allowed">
<p>Message1 is: {{ message1 }}</p>
<hr/>
<input #input="mask2"
:value="message2"
type="text"
ref="myInput"
placeholder="Try numbers">
<p>Message2 is: {{ message2 }}</p>
</div>
</div>
Script =>
new Vue({
el: "#app",
data: {
message1: "",
message2: ""
},
methods: {
mask1(input){
const validCharsForNumberFields = /[0-9]*(,|\.)?[0-9]*/gm
this.message1 = input.target.value.match(validCharsForNumberFields)[0]
},
mask2(input){
const validCharsForNumberFields = /[0-9]*(,|\.)?[0-9]*/gm
console.log(input)
this.$refs.myInput.value = input.target.value.match(validCharsForNumberFields)[0]
this.message2 = this.$refs.myInput.value
},
}
})

Related

Changing one Vuejs v-model value is changing all other values

I have a Nuxtjs/Vuejs application within which I am creating multiple Nodes. These Nodes have the Radio button for which I have assigned v-model. However, when I change the value of one Vuejs v-model is affecting all other Node Values. Following is the code sample that I have created for the Node. The ID value is unique for each Node.
<template>
<div ref="el">
<div class="header">
Node: {{ ID }}
</div>
<div>
Syntax:
<input
id="identifierTypeURN"
v-model="identifierSyntax"
type="radio"
value="URN"
name="instanceIdentifierURN"
#change="instanceIdentifiersSyntaxChange('URN')"
>
<label for="identifierTypeURN">URN</label>
<input
id="identifierTypeWebURI"
v-model="identifierSyntax"
type="radio"
value="WebURI"
name="instanceIdentifierWebURI"
#change="instanceIdentifiersSyntaxChange('WebURI')"
>
<label for="identifierTypeWebURI">WebURI</label>
</div>
</div>
</template>
I am aware that this is happening because I am using the same v-model name for all the Nodes so I changed to something like this. But still the issue persists:
<template>
<div ref="el">
<div class="header">
Identifiers
Node: {{ ID }}
</div>
<div>
Syntax:
<div v-for="node in allNodeInfo" :key="node.identifiersId">
<div v-if="node.identifiersId === ID">
<input
id="identifierTypeURN"
v-model="node.identifierSyntax"
type="radio"
value="URN"
name="instanceIdentifierURN"
#change="instanceIdentifiersSyntaxChange('URN')"
>
<label for="identifierTypeURN">URN</label>
<input
id="identifierTypeWebURI"
v-model="node.identifierSyntax"
type="radio"
value="WebURI"
name="instanceIdentifierWebURI"
#change="instanceIdentifiersSyntaxChange('WebURI')"
>
<label for="identifierTypeWebURI">WebURI</label>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
ID: '',
nodeId: '',
eventCount: '',
bizStep: '',
allNodeInfo: [],
instanceIdentifierSyntax: ''
}
},
mounted () {
this.$nextTick(() => {
const id = this.$el.parentElement.parentElement.id
const data = this.$df.getNodeFromId(id.slice(5))
this.ID = data.data.ID
this.nodeId = data.data.nodeId
this.allNodeInfo = JSON.parse(JSON.stringify(this.$store.state.modules.ConfigureIdentifiersInfoStore.identifiersArray, null, 4))
const identifiersNode = this.allNodeInfo.find(node => node.identifiersId === this.nodeId)
this.instanceIdentifierSyntax = identifiersNode.identifierSyntax
console.log(JSON.stringify(this.allNodeInfo, null, 4))
})
},
methods: {
// On change of the IdentifierSyntax change, change the value in the respective node info
instanceIdentifiersSyntaxChange (syntaxValue) {
// Change the value of the respective syntax within the Node information in IdentifiersNode array
console.log(this.ID + " --- " + syntaxValue)
}
}
}
</script>
<style>
</style>
I know I am making some small mistake where I need to differentiate each Nodes V-model but nothing is clicking me. Can someone please help me.
You have to pass your node and your v-model also to your methods within this event.. like this, because for every loop in your v-for there will be a "new created node" which includes your v-model and than you can refer to this:
#change="instanceIdentifiersSyntaxChange('URN', node, identifierSyntax)"
In your methods you just do everything based on your node.identifierSyntax = HERE WHAT YOU WANT..
Hopefully I understood the question correct and helped you out!
EDIT: (Standard procedure)
Normally it looks like this when you add a single "input" to your v-for.
Template:
<div v-for="node in inputs" :key="node.id">
<input v-model="node.someDefinition" :value="node.someDefinition"/>
<div #change="another_Function(node, someDefinition)></div>
</div>
<button #click="add_new_Input>ADD</button>
Script:
data() {
return {
id: 0,
inputs: [{ //this is representing the first input when side will be loaded
id: this.id,
//your stuff in here as well
}]
}
}
methods: {
add_new_Input() {
this.inputs.push({
id: this.id += 1
})
}
}
This should be enough.. So in your template you have a v-for where your are looping over an array (or something else but in my case it's an array) with all inputs - be aware every input of me gets an unique ID when it will be created or added.
Also you have - in my case here - an input-tag where you can get the v-model or set the :value. It's binded to my unique node which I have created in my methods.
If you pass your #change you also have to pass the current node and the v-model / value that the correct one will be changed.
Hopefully it now helps you out!

How do I display a value as a decimal place in vuejs input field?

I'm trying to display a 2000.00 in an input field in vuejs but it strips the .00.
<div id="app">
<input
class="form-control"
type="number"
v-model="solicitorsFees"/>
</div>
new Vue({
el: "#app",
data: {
solicitorsFees: 2000.00,
},
})
How do I get the input field to display 2000.00?
jsfiddle
I can do this with a calculated property. But I need to apply this to multiple input fields.
solicitorsFeesDecimal: function(){
return(this.solicitorsFees.toFixed(2))
},
<input class="form-control" type="number" v-model="solicitorsFeesDecimal"/>
Solution:
<input class="form-control" type="number" :value="(this.solicitorsFees).toFixed(2)"/>
The appropriate solution is to use a computed property with a custom getter and setter, as well as using the v-model.number modifier:
Template
<div id="app">
<input
class="form-control"
type="number"
v-model.number="solicitorsFeesDisplay"/>
</div>
Script
new Vue({
el: "#app",
computed: {
solicitorsFeesDisplay: {
get: function() {
return this.solicitorsFees.toFixed(2)
},
set: function(newValue) {
this.solicitorsFees = newValue
}
}
},
data() {
return {
solicitorsFees: 2000.00
}
},
})
See a working example on CodeSandbox.
you should you step in input field:
<input type="number" v-model="solicitorsFees" step="0.01">
This solves the problem:
<input class="form-control" type="number" :value="(this.solicitorsFees).toFixed(2)"/>
You can simply use parseFloat and toFixed together to define the number of decimal places you want.
v-model= parseFloat(solicitorsFees).toFixed(2)
Also, another suggestion is to make the data object as a function, as in your fiddle you are using an object.
data () {
return {
solicitorsFees: 2000.00
}
}

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 value update not working for on-click events

I have a application where I'm updating value of input element on button click.
I'm using Vue JS v-model for data binding.
HTML :
<div id="app">
<div>{{ response }}</div> <br>
<input type="text" v-model="response.ruleName" value="" placeholder="" class="editing">
<button #click="myalert">Click me</button>
</div>
JS :
var response = {
ruleName: "ruleJohn",
}
new Vue({
el: "#app",
data () {
return {
response
}
},
methods: {
myalert: function(e) {
document.querySelector('.editing').value = e.target.innerText;
},
}
})
Here is working fiddle : https://jsfiddle.net/38Lj971g/
Now, When I try to edit input value with keyboard, response values does change.
When I try to click button, Though input value changes but response doesn't.
How to deal with v-model for such on-click data updates ?
Don't edit the input value directly, instead edit the v-model it gets its data from, like so:
<button #click="response.ruleName = 'Click me'">Click me</button>
or, if you wish to use the method:
myalert: function(e) {
this.response.ruleName = e.target.innerText;
}

Array of inputs, with last field always blank for new add

JSBin and Stackoverflow snippet are below.
I am trying to have a list of input components. If all input components are filled with a value (not blank), then there should be a "new blank field" visible at the end for the user to type into. When he types into it, it should make this field apart of the list above it, maintaining focus in it.
However the problem I'm having is, focus maintains in the new field, and never moves into the array. Here is my code:
JSBIN and stackoverflow snippet - https://jsbin.com/cudabicese/1/edit?html,js,output
const app = new Vue({
el: '#app',
data: {
inputs: [
{ id:'foo', value:'foo' },
{ id:'bar', value:'bar' }
]
},
methods: {
addRow(e) {
this.inputs.push({
id: Date.now(),
value: e.target.value
})
},
deleteRow(index) {
this.inputs.splice(index, 1)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
<div id="app">
<ul>
<li v-for="(input, index) of inputs">
<input type="text" v-model="input.value">
</li>
<li v-if="inputs.filter(input => !!input.value).length">
<input type="text" #input="addRow">
</li>
</ul>
</div>
I'd recommend you put the input for the list within a computed function vs directly using the data. The examples at https://v2.vuejs.org/v2/examples/ are a good place to start.