How to get bind date from Vue Material DatePicker? - javascript

Probably a basic question, but I'm just beginning to learn Vue/Javascript in general.
I have a basic DatePicker component DatePicker.vue:
<template>
<div>
<md-datepicker v-model="selectedDate">
<label>Select date</label>
</md-datepicker>
</div>
</template>
<script>
import Vue from "vue";
export default Vue.extend( {
name: "LabeledDatepicker",
data: () => ({
selectedDate: null,
}),
});
</script>
This component is used in a view like so:
<template>
<div class="date-picker">
<DatePicker />
</div>
</template>
In my script I have two properties called fromDate and toDate which I want to get from two datepickers in my component.
<script lang="ts">
import Vue from "vue";
import DatePicker from "./DatePicker.vue";
export default Vue.extend({
components: {
DatePicker,
},
data() {
return {
fromDate: null,
toDate: null,
};
How do I bind the values selected in the datepickers to fromDate and toDate so I can use them in my API requests? I have tried to use v-model="fromDate", but fromDate was still null even after I selected a date.

Your datepicker component needs to accept props if you want to both populate the value with existing values and update it from within the component. Alternatively, use "emit" from your datepicker component and then attach a method to handle change custom event in Vue.js

Related

set default data for input in vue

I want to set a default value for input of data picker with vue,but the data doesn't show!
in the inspect element show this code:
script:
new Vue({
el:'#app2',
data: {
datePicker: '2021/01/05'
},
components:{
datePicker
}
html:
<div id="app2">
<date-picker :column="1" v-model="date" mode="single" />
</div>
Add value-type it will set the format of binding value and format will help to assign the display format.
<date-picker :column="1" v-model="datePicker" value-type="YYYY/MM/DD"
format="YYYY/MM/DD" mode="single" />
and
new Vue({
el:'#app2',
data(){
return {
datePicker: '2021/01/05'
}
},
components:{
datePicker
}

Vue JS CheckBoxGroup with a prop array as v-model

I am stuck at making a CheckBoxGroup with a prop array as v-model.
I have read the vuejs guide: https://v2.vuejs.org/v2/guide/forms.html#Checkbox which has the v-model array in the data of the same component, but it is obviously pretty useless if I want to make this component reusable and insert the v-model via props and for example check some of the boxes from "outside".
So I tried following:
CheckBoxgroup.vue
<template>
<div>
<label v-for="day in allDays" :key="day">
<input v-model="checkedDays" type="checkbox" :value="day" />
<span>{{ day }}</span>
</label>
<div>Checked days: {{ checkedDays }}</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
#Component
export default class CheckBoxGroup extends Vue {
#Prop() checkedDays!: string[]
#Prop() allDays!: string[]
}
</script>
Index.vue
<template>
<div>
<checkbox-group :checked-days="checkedDays" :all-days="allDays" />
</div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import CheckboxGroup from './checkBoxGroup.vue'
#Component({
components: { CheckboxGroup },
})
export default class Index extends Vue {
// This list would usually come from an API
allDays = ['Monday', 'Tuesday', 'Wednesday']
checkedDays = ['Monday']
}
</script>
So the code is working almost fine, but I am getting
[Vue warn]: Avoid mutating a prop directly since the value will be
overwritten whenever the parent component re-renders...
Is there any way around it? Any help would be appriciated.
you can't mutate the parent state from the children directly, however you can emit the event from child to parent to mutate from there as below:
Vue.component('check-box-group', {
template: `
<div>
<label v-for="day in allDays" :key="day">
<input
v-model="checkedDays"
:value="day"
#click="$emit('update-checked-days', { newCheckedDay: day })"
type="checkbox"
/>
<span>{{ day }}</span>
</label>
<div>Checked days: {{ checkedDays }}</div>
</div>
`,
props: {
checkedDays: {
type: Array, default: () => ([])
},
allDays: {
type: Array, default: () => ([])
},
}
})
new Vue({
el: "#app",
data() {
return {
allDays: ['Monday', 'Tuesday', 'Wednesday'],
checkedDays: ['Monday']
}
},
methods: {
HandleUpdateCheckedDays({newCheckedDay}) {
const indexOfCheckedDay = this.checkedDays.findIndex(checkedDay => checkedDay === newCheckedDay)
if (indexOfCheckedDay === -1) { // if not exists then add to checkedDays
this.checkedDays.push(newCheckedDay)
} else {
this.checkedDays = this.checkedDays.filter((_, i) => i !== indexOfCheckedDay)
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div id="app">
<check-box-group
:checked-days="checkedDays"
:all-days="allDays"
#update-checked-days="HandleUpdateCheckedDays"
/>
</div>
note: remember that TS class composition is deprecated.
Thanks for the answer, I actually managed to solve it also with v-model, but it looks kind of hacky and not very reusable for cases if data is injected from the outside Models.
So I will go with your solution.

Vue.js passing data between components

I want to store input-value from App.vue, and use it in another component. How can I do it? I don't need the show the value in the template, I just need the value inside other components function. In JS I could just use a global var, but how can I achieve it in Vue?
App.vue:
<template>
<div id='app'>
<!-- App.vue has search bar -->
<b-form-input #keydown='search' v-model='input'></b-form-input>
<div>
<!-- Here's my other components -->
<router-view />
</div>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
input: '',
value: ''
}
},
methods: {
search () {
this.value = this.input
this.input = ''
}
}
}
</script>
Another component:
<template>
<div>
<p>I'm another component</p>
<p>App.vue input value was: {{value}} </p>
</div>
</template>
<script>
export default {
props: ['value'],
data () {
return {
value: ''
}
}
}
</script>
This is the basic logic I'm trying to achieve. Input value in App.vue --> anotherComponent.vue
If components are not parent and child you can use store for this:
More advanced vuex store that should be your default GO TO - NPM.
Or simple solution with js object.
a. Create store.js file and export object with property in which you will store value.
b. Import store.js object to vue scripts and use it simply like:
import Store from 'store.js'
Store.value

Vuelidate: setting $model does not update component

Given the following Vue component that uses Vuetify and Vuelidate:
<template>
<div id="app">
<v-date-picker v-model="$v.picker.$model"></v-date-picker>
</div>
</template>
<script>
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
import { required } from 'vuelidate/lib/validators'
Vue.use(Vuetify)
new Vue({
el: "#app",
data() {
return {
picker: new Date().toISOString().substr(0, 10)
};
},
validations: {
picker: {
required
}
}
});
</script>
I would like to programmatically change the value of this.picker. I tried both changing the v-model as well as the Vuelidate $model:
this.picker = new Date().toISOString().substr(0, 10)
and
this.$v.picker.$model = new Date().toISOString().substr(0, 10))
Neither of them caused a change in the UI nor produced an error message.
How can I programmatically update the DatePicker's value?
Try just assigning v-model to picker instead of $v.picker.$model.
You said you tried changing v-model, but this should work.
<v-date-picker v-model="picker"></v-date-picker>

How to get property value from component in vue.js 2.0?

I have this component:
<template>
<div class="animated fadeIn">
<div class="col-sm-6 col-lg-6">
<datepicker class="form-control" :value="config.state.fromDate" :disabled="config.disabledFrom"></datepicker>
</div>
<div class="col-sm-6 col-lg-6">
<datepicker :value="config.state.toDate" :disabled="config.disabledTo"></datepicker>
</div>
</div>
</template>
<script>
import Datepicker from 'vuejs-datepicker'
var d = new Date()
var year = d.getFullYear()
var month = d.getMonth()
var day = d.getDate()
var fromD = new Date(year - 1, month, day)
var toDD = new Date(year, month, day)
console.log(fromD.toString())
console.log(toDD)
export default {
data() {
return {
config: {
disabledFrom: {
to: fromD
},
disabledTo: {
from: toDD
},
state: {
fromDate: (d.getDate() - 1).toString(),
toDate: new Date(year, month, day).toString()
}
}
}
},
components: {
Datepicker
}
}
</script>
I import this component like so:
import picker from '../components/DateFilter'
In this vue I have a button that when clicked i want it to get a property from the component that I am importing:
<template>
<div class="animated fadeIn">
<picker></picker>
</div>
<div>
<button #click="onChange2" class="btn btn-primary">search</button>
</div>
</template>
the method has an alert to show me the value:
onChange2: function() {
alert(picker.datepicker.value)
}
error message:
Cannot read property 'value' of undefined
other attempts:
alert(picker.data.config.state.value)
alert(picker.config.state.value)
I am new to vue and I havent been able to figure out where I am doing this wrong.
It is techincally possible to access child properties by using this.$children (or this.$parent) but please dont! It will introduce coupling between your components which is bad, very bad.
Instead you should use props to pass data down to your children, and emit events up to your parents.
If this is the vue-datepicker you are using, here's one example to do what you want:
// childcomponent.vue
<template>
<div class="child-component">
<datepicker v-on:selected="doSomethingInParentComponentFunction"></datepicker>
</div>
</template>
<script>
import Datepicker from 'vuejs-datepicker'
export default {
components: {
Datepicker
},
methods: {
doSomethingInParentComponentFunction (selectedDate) {
this.$emit("selected", selectedDate)
}
}
}
</script>
And in parent:
// parentcomponent.vue
<template>
<div class="parent-component">
<child-component v-on:selected="dateSelectedInChild"></child-component>
</div>
</template>
<script>
import ChildComponent from 'childcomponent'
export default {
components: {
ChildComponent
},
methods: {
dateSelectedInChild (selectedDate) {
console.log(selectedDate)
}
}
}
</script>
You can read more about this on the links above, or on this article which summarize this and more.
picker is a component class, not an instance of a component. It doesn't have any properties you can access. Similarly, Datepicker (not datepicker, which is just the HTML tag form) is a component, not an instance.
You're thinking about Vue data backwards. You provide initial values to your datepickers, but you don't have them storing new values anywhere. You expect to be able to "look into" children to get values, but instead, you should be sending those values out of the children via events (read this).

Categories