How do I pick the date format? - vue.js

How do I get bootstrap datetimepicker to pick date format as DD/MM/YY.Below is my code.Having referenced this SO answer. I created the following JSFiddle. As at now the result of the datepicker is like Fri Jan 12 2018 09:27:28 GMT+0300.
Below is the template code:
<div id="app" class="container">
<h3>Bootstrap Datetimepicker (eonosdan) Sample</h3>
<hr/>
<div class="row">
<div class="col-md-4">
<label>Select Date</label>
<vue-datetimepicker></vue-datetimepicker>
</div>
</div>
</div>
<template id="dttemplate">
<div class='input-group date'>
<input type='text' v-model="value" class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>{{value}}
</div>
</template>
The JS component is as below:
Vue.component('vue-datetimepicker', {
template: '#dttemplate',
props: ['value'],
mounted: function() {
var vm = this
var mycomp = $(this.$el).datetimepicker({format: 'DD-MM-YYYY'})
mycomp.on('dp.change', function(e) {
vm.value = e;
app.$data.requestdate = e.date.format('DD-MM-YYYY');
vm.$emit('change', vm.value)
})
}
});
new Vue({
el: '#app',
data: {},
methods: {requestdate:moment().format('DD-MM-YYYY')}
})
<div class="form-group">
<date-picker v-model="requestdate"></date-picker>
</div>
Taking out the props: ['value'] from the component and v-model="value" results in datetimepicker being properly formatted.But well that renders it useless in terms of reusability.
Edit: After updating my code to the above it 'sort of works' but it renders the component only useful for a single datetimepicker.

Related

VeeValidate with Yup: input type="number" value is converted to string on submit

I use VeeValidate and Yup for form validation and don't know why my input field with type="number" is converted to string on submit.
When I input 78 and submit the form the output of the console.log in the onSubmit(values) function is the following:
values: {
prioritaet: "78"
}
Am I doing something wrong here or is this the normal behavior of VeeValidate and Yup? I would like to have a number instead of a string after submit.
My code looks like this:
<template>
<div class="container m-3">
<div class="row bg-primary align-items-center py-2">
<div class="col">
<h3 class="text-light mb-0">Format {{ this.action }}</h3>
</div>
<div class="col-auto">
<h5 class="text-light mb-0">{{ this.formatTitle }}</h5>
</div>
</div>
<Form #submit="onSubmit" :validation-schema="formatSchema" v-slot="{ errors }" ref="formatForm">
<div class="row mt-4">
<div class="col">
<h5>Formatdaten</h5>
</div>
</div>
<div class="row mb-2">
<div class="col-4">
<label for="prioritaet-input">Priorität: </label>
</div>
<div class="col">
<Field type="number" name="prioritaet" id="prioritaet-input" class="w-100" />
</div>
</div>
<div class="row justify-content-end">
<div class="col-auto me-auto">
<button class="btn btn-outline-primary">Änderungen übernehmen</button>
</div>
<div class="col-auto">
<button class="btn btn-outline-primary">Abbrechen</button>
</div>
<div class="col-auto">
<button type="sumbit" class="btn btn-outline-primary">Speichern</button>
</div>
</div>
<div class="row mt-4">
<template v-if="Object.keys(errors).length">
<span class="text-danger" v-for="(message, field) in errors" :key="field">{{ message }}</span>
</template>
</div>
</Form>
</div>
</template>
<script>
import { Form, Field } from "vee-validate";
import deLocale from "../assets/yup-localization.js";
import * as Yup from "yup";
import { markRaw } from "vue";
import { mapActions, mapState } from "vuex";
Yup.setLocale(deLocale);
export default {
name: "FormatBearbeitungsSchirm",
props: ["material_id"],
data() {
let action = "neu";
let formatTitle = "Format neu";
let formatSchema = markRaw(Yup.object().shape({
prioritaet: Yup.number().min(1).max(100).integer().label("Priorität"),
}));
return { formatSchema, action, formatTitle };
},
created() {
},
components: {
Form,
Field,
},
methods: {
onSubmit(values) {
console.log("values", values);
},
},
};
</script>
It looks like there is currently no support for specifying the .number modifier on the internal field model value of <Field>, so the emitted form values would always contain a string for number-type fields.
One workaround is to convert the value in the template, updating <Form>'s values slot prop in <Field>'s update:modelValue event:
<Form #submit="onSubmit" v-slot="{ values }">
<Field 👆
type="number"
name="prioritaet" 👇
#update:modelValue="values.prioritaet = Number(values.prioritaet)"
/>
<button>Submit</button>
</Form>
demo
Another simple workaround is to convert the property inside onSubmit before using it:
export default {
onSubmit(values) {
values.prioritaet = Number(values.prioritaet)
// use values here...
}
}
You must use the .number modifier.
You can read about it here
If you want user input to be automatically typecast as a Number, you can add the number modifier to your v-model managed inputs:
const app = new Vue({
el: "#app",
data: () => ({
mynumber1: undefined,
mynumber2: undefined
}),
methods: {
submit() {
console.log(typeof this.mynumber1, this.mynumber1)
console.log(typeof this.mynumber2, this.mynumber2)
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.14/dist/vue.js"></script>
<div id="app">
<form>
<!-- number modifier -->
<input type="number" v-model.number="mynumber1" placeholder="Type here" />
<!-- no modifier -->
<input type="number" v-model="mynumber2" placeholder="Type here" />
<input type="button" #click="submit" value="submit" />
</form>
</div>

VueJS how to push form params to vue router?

I'm trying to create an edit form. How can I get the parameters from the url (vue-router) and pass them to the html form? And how can I push my form data to url?
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<form class="form-horizontal">
<!-- MultiSelect -->
<div class="form-group">
<label class="col-xs-2 col-md-1 control-label">User</label>
<div class="col-xs-10 col-md-3">
<multiselect
v-model="user"
:options="userList"
:searchable="true"
label="Name"
track-by="Name">
</multiselect>
</div>
</div>
<!-- MultiSelect -->
<div class="form-group">
<label class="col-xs-2 col-md-1 control-label">Team</label>
<div class="col-xs-10 col-md-3">
<multiselect
v-model="team"
:options="teamList"
:searchable="true"
label="Name"
track-by="Name">
</multiselect>
</div>
</div>
<!-- DatePicker -->
<div class="form-group">
<label class="col-xs-2 col-md-1 control-label">Birthday</label>
<div class="col-xs-10 col-md-3">
<date-picker
v-model="calendarDate"
:shortcuts="shortcuts"
:first-day-of-week="1"
appendToBody
></date-picker>
</div>
</div>
<!-- Button -->
<div class="form-group">
<label class="col-md-1 control-label"></label>
<div class="col-md-4">
<button #click="EditUser" class="btn btn-primary">Edit</button>
</div>
</div>
</form>
So I want to bind data between the models and vue-router. When I open edit.html#/user=5&team=3&bday=1991-01-10 appropriate multiselect fields must be filled. How to do it?
You can use query in your route URL:
Store all of your multiselect fields in a computed variable, and add a watcher to push the new parameters to your URL when there are any changes in the parameter:
computed: {
queryParams({ user, team, calendarDate }) {
return {
user: user,
team: team,
bday: calendarDate
}
}
},
watch: {
queryParams() {
this.$router.push( name: this.$route.name, query: this.queryParams })
}
}
When your page is created, use a function to get the query and set the form variables:
created() {
this.setQueryParams();
},
methods() {
setQueryParams() {
const query = this.$route.query;
this.user = query.user;
this.team = query.team;
this.calendarDate = query.bday;
// you might need to do some formatting for the birthday and do some checks to see if the parameter exists in the query so you don't get errors
}
}

Vue.js convert all inputs to a v-model

I just want to know if what i'm doing is correct.
The goal
here is to convert all input fields in a v-model.
Right now im using jQuery to do that, and is working well.
Is there any way to do it with pure vue.js?
Some considerations:
I don't want to use v-model or any vue attribute on the html like ref="foo".
The data must be in and object and I don't want to predefine.
Thanks
const vueApp = new Vue({
el: '#vue-app',
data: {
dataForm: {}
},
created() {
$("input").each(function(){
var $input_name = 'dataForm.' + $(this).attr('name');
$(this).attr('v-model', $input_name);
});
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="vue-app">
<div class="">
First Nane : {{ dataForm.firstName }}
</div>
<div class="">
Last Name : {{ dataForm.lastName }}
</div>
<div class="">
<input type="text" name="firstName" value="">
<input type="text" name="lastName" value="">
</div>
</div>

Vue.JS checkbox without v-model

Trying to create a checkbox without using v-model
<input type="checkbox" :value="value" #change="$emit('input', $event.target.checked)" />
The checkbox will check and uncheck, and the input event is sent to the parent, but the value doesn't change. My parent component looks like this:
<custom-component v-model="some_boolean_value"></custom-component>
For checkboxes, use :checked instead of :value. See demo below.
Vue.component('custom-component', {
template: '#custom',
props: ['value']
})
new Vue({
el: '#app',
data: {
some_boolean_value: true
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<p>some_boolean_value: {{ some_boolean_value }}</p>
<custom-component v-model="some_boolean_value"></custom-component>
</div>
<template id="custom">
<div style="border: 2px dashed red;">
<input type="checkbox" :checked="value" #change="$emit('input', $event.target.checked)" />
</div>
</template>

vuejs :disabled doesn't work

I have a problem on reactivating the button even if the conditional statement works.
it looked like the v-model wasn't communicating with the data but with a simple interpolation the value was updated.
I don't really know where I'm doing wrong on the code.
<template>
<div class="col-sm-6 col-md-4">
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">{{stock.name}}
<small>(Price: {{stock.price}})</small>
</h3>
</div>
<div class="panel-body">
<div class="pull-left">
<input v-model="quantity" type="number" class="form-control" placeholder="Quantity">
</div>
<div class="pull-right">
<button class="btn btn-success" #click="buyStock" :disabled="isDisabled">Buy</button>
</div>
<p>{{quantity}}</p>
</div>
</div>
</div>
</template>
<script>
export default {
props: [
"stock",
],
data() {
return {
quantity: 0,
}
},
methods: {
buyStock() {
const order = {
stockId: this.stock.id,
stockPrice: this.stock.price,
quantity: this.quantity
};
console.log(order);
this.$store.dispatch("buyStock", order);
this.quantity = 0;
}
},
computed: {
isDisabled() {
if (this.quantity <= 0 || !Number.isInteger(this.quantity)) {
return true;
} else {
return false;
}
}
}
}
</script>
By default, the v-model directive binds the value as a String. So both checks in your isDisabled computed will always fail.
If you want to bind quantity as a number, you can add the .number modifier like so:
<input v-model.number="quantity" type="number" ... >
Here's a working example:
new Vue({
el: '#app',
data() {
return { quantity: 0 }
},
computed: {
isDisabled() {
return (this.quantity <= 0 || !Number.isInteger(this.quantity))
}
}
})
<template>
<div class="col-sm-6 col-md-4">
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">{{stock.name}}
<small>(Price: {{stock.price}})</small>
</h3>
</div>
<div class="panel-body">
<div class="pull-left">
<input v-model="quantity" type="number" class="form-control" placeholder="Quantity">
</div>
<div class="pull-right">
<button class="btn btn-success" #click="buyStock" :disabled="isDisabled">Buy</button>
</div>
<p>{{quantity}}</p>
</div>
</div>
</div>
</template>
<script>
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
<input v-model.number="quantity" type="number">
<button :disabled="isDisabled">Foo</button>
</div>