How to prepopulate date range value? - vue.js

I have an issue on my edit page while trying to prepopulate date range value.
Ex. 2022-06-03, 2022-06-04
Rather than see this
I got an error in the console.

I don't know if I understood the question correctly, but in the absence of a code snippet I refer to the official Vuetify documentation.
Basically you assign a date pattern to the Vuetify component and optionally, with a computed, calculate the divisor.
export default {
data: () => ({
dates: ['2019-09-10', '2019-09-20'],
}),
computed: {
dateRangeText () {
return this.dates.join(' ~ ')
},
},
}
<v-row>
<v-col
cols="12"
sm="6"
>
<v-date-picker
v-model="dates"
range
></v-date-picker>
</v-col>
<v-col
cols="12"
sm="6"
>
<v-text-field
v-model="dateRangeText"
label="Date range"
prepend-icon="mdi-calendar"
readonly
></v-text-field>
model: {{ dates }}
</v-col>
</v-row>

Related

computed property is not updating value in v-text-field after execution

I am doing this excercise in vue.js 2.6.
I have a toggled button that has two values: '1' or '2', and I made a computed that depending on these previous values return other values.
this returns either '1' or '2'
<v-col cols="12" sm="12" md="4" lg="4" xl="4">
<label>Toggle button</label><br />
<v-btn-toggle v-model="backendprop.prop1" color="blue" class="form-control p-0" dense borderless>
<v-btn v-for="option in BackendProp1" :key="option.value" :value="option.value">{{ option.label }}</v-btn>
</v-btn-toggle>
</v-col>
I want the value of this input to update according to computed setValueBecauseToggledButton
<v-col cols="12" sm="12" md="4" lg="4" xl="4">
<label>Value depending on Toggled Button</label><br />
<v-text-field
v-model="backendprop.prop2"
type="text"
disabled
outlined
dense
:value="setValueBecauseToggledButton"
/>
</v-col>
and this is the computed value:
computed:{
setValueBecauseToggledButton(){
return this.backendprop?.prop1?.toString() === '2' ? 'Valid prop' : ''
}
The behavior I expect is when I choose between the options of one input the other input should be updated.
Placing console.log in setValueBecauseToggledButton shows me that is working perfectly, but it does nothing on the v-text-field.
You could set a watcher on your property and then update the value for the v-text-field inside it.
<v-col cols="12" sm="12" md="4" lg="4" xl="4">
<label>Value depending on Toggled Button</label><br />
<v-text-field
v-model="backendprop.prop2"
type="text"
disabled
outlined
dense
/>
</v-col>
watch: {
'backendprop.prop1'(value){
this.backendprop.prop2 = value.toString() === '2' ? 'Valid prop' : ''
}
}

How do I watch for onChange of specific select menu that was dynamically generated?

I have a row of 3 inputs. It lay out like this:
Attribute (select) > Operators (select) > Value (text)
UI look like this:
Code for that:
<v-row v-for="(rule, index) in rules" :key="index">
<v-col cols="12" sm="6" md="3">
<v-select
dense
outlined
item-text="name"
item-value="id"
label="Attribute"
v-model="form.values.attributes"
:items="attributes"
></v-select>
</v-col>
<v-col cols="12" sm="6" md="2">
<v-select
outlined
dense
item-text="name"
item-value="id"
label="Operator"
v-model="rule.operator"
:items="operators"
></v-select>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
dense
outlined
label="Values"
v-model="rule.value"
></v-text-field>
</v-col>
</v-row>
The operator menu is dynamically populated based on API based on the selected attribute.
I have v-model="form.values.attributes", and my watch to call the API for the operators
watch: {
'form.values.attributes'() {
let data = {
$root: 'rules'
}
axios.defaults.headers['Content-Type'] = 'application/json'
axios.post(window.MTS_URL, data).then((response) => {
this.operators = response.data.operators
})
}
}
This works great with one row.
But when I clicked Add, I appended another row, and I need to support multiple rows.
How do I watch for onChange of specific select menu ?
I was thinking to move my
v-model="form.values.attributes"
to
v-model="rule.attribute"
but is it the right thing to do ?
You can try remodeling your data to experience the power of Vue.
Your template:
<template>
<v-app>
<v-row v-for="(rule, index) in rules" :key="index">
<v-col cols="12" sm="6" md="3">
<v-select
dense
outlined
item-text="name"
item-value="id"
label="Attribute"
:items="rule.attributes"
#change="onChange($event, rule, index)"
></v-select>
</v-col>
<v-col cols="12" sm="6" md="2">
<v-select
outlined
dense
item-text="name"
item-value="id"
label="Operator"
:items="rule.operators"
></v-select>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field dense outlined label="Values"></v-text-field>
</v-col>
</v-row>
</v-app>
</template>
Notice how everything is rendered in the rules data. Here the rules data will be an array containing all the rows:
rules = [
{
attributes: ["11", "22"],
operators: []
}
]
Your script should look like below:
<script>
import axios from "axios"
export default {
name: "App",
data() {
return {
rules: [{
attributes: ["11", "22", "33"],
operators: [],
}],
};
},
methods: {
async onChange(changed, rule, index) {
// where:
// `changed` is the value selected
// `rule` is the attributes and rule in the selected row
// `index` is the index in the rules array that just got changed
console.log(changed, rule, index);
const operators = await this.fetchApiData(changed);
this.$set(this.rules, index, { ...rule, operators: operators });
},
},
async fetchApiData(data) {
const response = await axios.post(window.MTS_URL, data);
return response.data.operators;
},
};
</script>
if you want to add more rows, you just need to push an object to the rules data:
this.rules.push({
attributes: ["new attribute 1", "new attribute 2"],
operators: []
})

Dynamic calculation using Vuetify

I'm trying to create dynamic calculator using Vuetify. Here's my code
<v-row class="mt-8 align-self-center">
<v-col cols="2">
<v-text-field :value="weight" label="Weight (kg)" placeholder="Type here" filled rounded></v-text-field>
</v-col>
<v-col cols="2">
<v-text-field :value="distance" label="Distance (km)" placeholder="Type here" filled rounded></v-text-field>
</v-col>
</v-row>
<v-card v-model="result" height="100" width="500">
Estimated shipping cost is: {{result}}
</v-card>
and here's my script
export default {
data() {
return {
inputDistance: '',
inputWeight: '',
result: ''
}
},
computed: {
result: function(){
var totalCost = this.inputDistance * this.inputWeight *2000;
return totalCost;
}
}
}
I have tried using v-model too but it still doesn't work. Any idea on what I suppose to write?
Thanks!
replace :value with v-model in your v-text-field, use the variable names and then remove v-model from v-card.
<v-row class="mt-8 align-self-center">
<v-col cols="2">
<v-text-field v-model="inputWeight" label="Weight (kg)" placeholder="Type here" filled rounded></v-text-field>
</v-col>
<v-col cols="2">
<v-text-field v-model="inputDistance" label="Distance (km)" placeholder="Type here" filled rounded></v-text-field>
</v-col>
</v-row>
<v-card height="100" width="500">
Estimated shipping cost is: {{result}}
</v-card>
and then use parseFloat in computed
export default {
data() {
return {
inputDistance: '',
inputWeight: '',
/** removed result variable **/
}
},
computed: {
result: function(){
var totalCost = parseFloat(this.inputDistance, 10) * parseFloat(this.inputWeight,10) *2000;
return totalCost;
}
}
}

Can you please help me with my on step behind issue in my vue code?

I got a question about my vue code I'm making a filter dropdown but when I input a key to trigger the key down event for filtering the arr it's changing the dom each time after the second event (one step behind).
Here is the code pen :
https://codepen.io/dyonvangerwen/pen/zYvjMdY
it's only keeping the values in the arr that are matching the input
template:
<div id="app">
<v-app id="inspire">
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="3">
<v-text-field
v-model="inputValue"
label="Filled"
placeholder="Placeholder"
filled
v-on:keydown="tester"
></v-text-field>
<v-card
class="mx-auto"
max-width="400"
tile
>
<v-list-ite >
<v-list-item-content v-for=" item in itemsInDropdown" :key="item">
<v-list-item-title>{{item}}</v-list-item-title>
</v-list-item-content>
</v-list-ite>
</v-card>
</v-col>
</v-row>
</v-container>
</v-form>
</v-app>
</div>
script:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
inputValue:'',
itemsInDropdown:['a','b','c','d','e','ab','cd','ea']
}),
methods:{
tester:function(){
this.itemsInDropdown = this.itemsInDropdown.filter((x)=>{
if(x.includes(this.inputValue)){
return true
}
else{return false}
})
}
}
})
It is better to use computed in this case:
Replace the method with this:
computed:{
itemsInDropdownFiltered:function(){
return this.itemsInDropdown.filter((x)=>{
return x.includes(this.inputValue);
});
}
}
Change the array to be rendered from itemsInDropdown to itemsInDropdownFiltered as follows:
<v-list-item-content v-for="item in itemsInDropdownFiltered" :key="item">

How can I get country code on vue tel input?

My component
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="3">
<vue-tel-input v-model="phone"></vue-tel-input>
</v-col>
</v-row>
</v-container>
<v-btn
color="success"
#click="submit"
>
submit
</v-btn>
</v-form>
When I click submit, I just get phone. How can I get country code too?
[Reference] https://www.npmjs.com/package/vue-tel-input-vuetify
[Codepen] https://codepen.io/positivethinking639/pen/YzzjzWK?&editable=true&editors=101
It seems like vue-tel-input provides a country-changed event. According to the docs it's even fired for the first time and it returns an object:
Object {
areaCodes: null,
dialCode: "31",
iso2: "NL",
name: "Netherlands (Nederland)",
priority: 0
}
So this event handler can be added to the component and the country code can be stored in the component as you already do for the phone value.
HTML part
<div id="app">
<v-app id="inspire">
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="3">
<vue-tel-input v-model="phone" v-on:country-changed="countryChanged"></vue-tel-input>
</v-col>
</v-row>
</v-container>
<v-btn
color="success"
#click="submit"
>
submit
</v-btn>
</v-form>
</v-app>
</div>
JS Part
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
phone: null,
country: null
}
},
methods: {
countryChanged(country) {
this.country = country.dialCode
},
submit() {
console.log(this.phone);
console.log(this.country);
}
}
});
Here you can see a working version:
https://codepen.io/otuzel/pen/PooBoQW?editors=1011
NOTE: I don't use Vue on daily basis so I am not sure if this the best practice to modify the data via the event handler.
<vue-tel-input v-model="phone" v-bind="bindProps"></vue-tel-input>
data() {
return {
phone: null,
bindProps:{
mode: 'international'
}
}
}
It's achievable in vue-tel-input#3.1.1 by setting prop mode: 'international', in this case, the phone number will always be converted to +123 123 123...