VUEJS - How to Convert Date from API Response - vue.js

I'm doing my project with API and the default birthdate from the response is YYYY-MM-DD but I wanna format and show the birthdate in my modal dialog in this format DD-MM-YYYY,
here's the code
axios
.post("test/test).
.then((response) => {
if (response.data.patients.length === 0) {
this.showAlert(this.$t("tess"), "error");
} else {
this.dataLoad = response.data.patients[0].patient;
console.log(this.dataLoad);
}
})
I save the response in dataLoad and wanna show the format DD-MM-YYYY in modal dialog
<v-row>
<v-col cols="4">Birthdate</v-col>
<v-col cols="1">:</v-col>
<v-col cols="7">{{
this.dataLoad && this.dataLoad.birthdate
}}</v-col>
</v-row>

Call the following function.
function formatDate(dateStr)
{
var parts = dateStr.split("-");
return parts[2]+ "-" + parts[1]+ "-" + parts[0];
}
Alternatively, you can use it as follows.
<v-row>
<v-col cols="4">Birthdate</v-col>
<v-col cols="1">:</v-col>
<v-col cols="7">{{
this.dataLoad && this.dataLoad.birthdate.split("-").reverse().join("-")
}}</v-col>
</v-row>

you can first of all prepare the birth Date like the format you want after that you can load it to your component:
new Vue({
el: '#vueRoot',
data: {birthDate: '1963-11-22'},
computed:{
birthDateDdmm(){
return new Date(this.birthDate + 'T00:00:00Z')
.toLocaleDateString('en-GB',{timeZone:'UTC'})
},
birthDateAuto(){
return new Date(this.birthDate + 'T00:00:00Z')
.toLocaleDateString([],{timeZone:'UTC'})
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id='vueRoot'>
<h1>input => {{birthDate}}</h1>
<h1>dd-MM-yy => {{birthDateDdmm}}</h1>
<h1>respect user prefs => {{birthDateAuto}}</h1>
</div>

Related

Checking validation of VTextField

I have a CodePen demonstrating the issue at Checking validation of VTextField. The CodePen code is below as well.
Inside of the updateTitle method, I would like to be able to check to see whether or not the value is valid, because I need to run some custom logic when the value changes and what is executed will depend upon whether or not the value is valid.
I can see that v-text-field has a valid and validationState property. Is it possible to access either property inside of updateTitle?
HTML
<div id="app">
<v-app id="inspire">
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
:value = "title"
:rules="[rules.required, rules.counter]"
label="Title"
counter
maxlength="20"
#input="updateTitle"
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</v-app>
</div>
JS:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
title: 'Preliminary report',
rules: {
required: value => !!value || 'Required.',
counter: value => value.length <= 10 || 'Max 10 characters'
}
}
},
methods: {
updateTitle( value ) {
console.log( "update", value );
}
}
})
The answer is to provide a ref to the v-text-field. This allows one to access the field via the special $refs property and call the validate function. The changes to the CodePen are:
<v-text-field
ref = "theField"
:value = "title"
:rules="[rules.required, rules.counter]"
label="Title"
counter
maxlength="20"
#input="updateTitle"
></v-text-field>
updateTitle( value ) {
const isValid = this.$refs.theField.validate();
console.log( "update", value, isValid );
}

Why my Vuetify's Datepicker doesn't work?

I'm new to vuejs + vuetify. I am using a datepicker to filter a datatable. The filtering part is working, however, when I clear the field the table does not return to original form. I tested using the html's input-date and worked perfectly. What am I doing wrong?
This is the datepicker component:
<template>
<v-menu
ref="menu"
v-model="menu"
:close-on-content-click="false"
transition="scale-transition"
offset-y
max-width="290"
min-width="290"
>
<template v-slot:activator="{ on }">
<v-text-field
clearable
dense
color="#15C98A"
outlined
v-model="computedDataFormatada"
label="data inicio"
append-icon="mdi-calendar-outline"
readonly
v-on="on"
></v-text-field>
</template>
<v-date-picker
v-model="date"
#input="dataEscolhida"
locale="pt"
color="#15C98A"
no-title
></v-date-picker>
</v-menu>
</template>
<script>
export default {
name:'DataPicker',
props:['label'],
data() {
return {
date: null,
menu: false,
};
},
computed: {
computedDataFormatada () {
return this.formataData(this.date)
},
},
methods: {
dataEscolhida() {
this.$emit('selecionado',this.computedDataFormatada);
this.menu = false;
},
formataData(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}/${month}/${year}`;
}
}
};
</script>
This is the way I'm filtering:
<v-data-table
fixed-header
single-select
item-key="id"
:headers="headers"
:items="customFilter"
:items-per-page="5"
class="elevation-1"
></v-data-table>
computed:{
customFilter(){
let startDate = this.dataInicioFiltro;
let endDate = this.dataFimFiltro;
return _.filter(this.grupos, (function (info) {
let date = info.data;
if ( (_.isNull(startDate) && _.isNull(endDate))||(_.isEmpty(startDate) && _.isEmpty(endDate)))
return true;
else if((!_.isEmpty(startDate) && _.isEmpty(endDate)))
return date ===startDate;
else if((_.isEmpty(startDate) && !_.isEmpty(endDate)))
return date ===endDate;
else
return (date >= startDate && date <= endDate);
}))
}
}
And this is how I'm using the component in the view:
<data-filtro label="data inicial" #selecionado="dataInicioFiltro=$event" />
I'm also using the lib lodash.
Ok everyone, I finally solved it out! Just have to use the event click:clear

Vuetify async search is only submitting one character at a time and doesn't concat characters

I have the following vue component:
<template>
<v-form ref="form" #submit.prevent="search">
<v-row class="pa-0">
<v-col cols="12" md="2" class="d-flex">
<v-autocomplete
:items="projects"
item-value="id"
:item-text="item => `${item.number.number} ${item.name}`"
outlined
v-model="form.project_id"
label="Project number"
:search-input.sync="project"
dense
hide-details="auto"
class="align-self-center"
clearable
/>
</v-col>
</v-row>
</v-form>
</template>
<script>
export default {
watch: {
project( value )
{
this.queryProjects( { search: '', number: value } );
}
},
data()
{
return {
project: '',
projects: [],
}
},
methods: {
async queryProjects( search )
{
console.log(search);
if(!search)
{
return;
}
let response = await fetch(route('projects.search', search));
this.projects = await response.json();
},
}
}
</script>
This component should filter projects based on project number. The queryProject function is triggered but the problem is in the value from the project watcher. After each number entered the autocomplete field is set back to null and so it doesn't concat the complete project number. So if you would like to search for 19320 each number is parsed one by one and not as a whole number.
When a character is typed the output in console is the following:
1 for watcher value
{number: "1"} for queryProject search value
null for watcher value so looks like each character resets the input or rerenders the component.
The problem was in the line
:item-text="item => `${item.number.number} ${item.name}`"
When changed to just item-text="name" everything was working again.
A related bug report: https://github.com/vuetifyjs/vuetify/issues/11370

How can I solve [object Promise] on vue?

My code like this :
<v-row dense>
<v-col
v-for="(item, i) in items"
:key="i"
cols="12"
>
<v-card
dark
>
<div class="d-flex flex-no-wrap justify-space-between">
<div>
<v-card-title
class="headline"
v-text="item.doctor"
></v-card-title>
<v-card-subtitle v-text="item.hospital"></v-card-subtitle>
<v-card-subtitle>{{available(item.doctorId, item.hospitalId)}}</v-card-subtitle>
</div>
<v-avatar
class="ma-3"
size="125"
tile
>
<v-img :src="item.src"></v-img>
</v-avatar>
</div>
</v-card>
</v-col>
</v-row>
methods: {
// available (doctorId, hospitalId) {
available: async function (doctorId, hospitalId) {
let fromDate = moment()
let toDate = moment().add(2, 'days')
while (fromDate <= toDate) {
const payload = {
hospitalId: hospitalId,
doctorId: doctorId,
date: fromDate.format('YYYY-MM-DD')
}
// this is async/ajax to call api by vuex store
// await this.checkAvailibility(payload)
// if (this.availibility.items.length > 0) {
if(fromDate.diff(moment(), 'days') == 0) {
return `<v-icon class="mr-2" color="success">check_circle</v-icon>Available Today`
}
else if(fromDate.diff(moment(), 'days') == 1)
return `<v-icon>check_circle</v-icon>Available Tomorrow`
else
return `<v-icon>check_circle</v-icon>Available ${fromDate}`
// }
fromDate = fromDate.add(1, 'days')
}
},
},
Demo and full code like this :
https://codepen.io/trendingnews/pen/vYENWqR?editors=1010
This error might occur because I use async. But I need that. Because I want to call ajax via vuex store
How can I solve this problem without remove async?
Note :
this.availibility.items.length is used to check whether a doctor is available or not on a certain day. if greater than 0 means it is available
I commented that because it called vuex store

Validate vuetify textfield only on submit

temp.vue
<v-form ref="entryForm" #submit.prevent="save">
<v-text-field label="Amount" :rules="numberRule"r></v-text-field>
<v-btn type="submit">Save</v-btn>
</v-form>
<script>
export default {
data: () => ({
numberRule: [
v => !!v || 'Field is required',
v => /^\d+$/.test(v) || 'Must be a number',
],
}),
methods: save () {
if (this.$refs.entryForm.validate()){
//other codes
}
}
}
</script>
What happens here is while typing in the text field itself the rule gets executed. I want to execute the rule only on submit. How to do that in vuetify text field?
Vuetify rules are executed when the input gets value,
But if you want that to happen only on the form submit, you have remodified the rules that are being bound to that input,
Initially, rules should be an empty array, when you click on the button you can dynamically add/remove the rules as you wanted, like this in codepen
CODEPEN
<div id="app">
<v-app id="inspire">
<v-form ref="entryForm" #submit.prevent="submitHandler">
<v-container>
<v-row>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="user.number"
:rules="numberRules"
label="Number"
required
></v-text-field>
</v-col>
</v-row>
<v-row>
<v-btn type="submit" color="success">Submit</v-btn>
</v-row>
</v-container>
</v-form>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
valid: false,
firstname: '',
user: {
number: ''
},
numberRules: []
}),
watch: {
'user.number' (val) {
this.numberRules = []
}
},
methods: {
submitHandler () {
this.numberRules = [
v => !!v || 'Field is required',
v => /^\d+$/.test(v) || 'Must be a number',
]
let self = this
setTimeout(function () {
if (self.$refs.entryForm.validate()){
//other codes
alert('submitted')
}
})
}
}
})
If you're like me and just want to prevent validation from running on every key stroke, apply validate-on-blur prop on your text fields and now validation will only be perform after user has completed typing the whole input.
So not an exact answer to the OP, but I think this is what most of us want to achieve. This prop has been documented here.
I have another way to solve this problem without setting up watchers:
<v-form lazy-validation v-model="valid" ref="form">
<v-text-field
class="w-100"
light
label="Nome"
v-model="form.nome"
:rules="[rules.required]"
rounded
required
outlined
hide-details="auto"
></v-text-field>
<v-btn
rounded
height="50"
width="200"
:disabled="!valid"
:loading="isLoading"
class="bg-btn-secondary-gradient text-h6 white--text"
#click="submitContactForm()"
>
Enviar
</v-btn>
</v-form>
There is a prop called lazy-validation on vuetify, as you can see on the docs: https://vuetifyjs.com/en/api/v-form/#functions
So, the v-form has a method that you can see through $refs called validate(), and it can return true or false, based on your form rules.
And, the function that will trigger the validation on submit will be like this:
submitContactForm() {
const isValid = this.$refs.form.validate();
if (isValid) {
alert("Obrigado pelo contato, sua mensagem foi enviada com sucesso!");
this.form = {
nome: "",
celular: "",
email: "",
mensagem: ""
};
this.$refs.form.resetValidation(); // Note that v-form also has another function called resetValidation(), so after we empty our fields, it won't show the validation errors again.
}
},