Vuetify :header-date-format - vuetify.js

I want to use v-date-picker's :header-date-format to format the hearder,
but not working. Not too much discussion in the stackoverflow, wonder how to use it.
my code is like this :
<div id="app">
<v-app id="inspire">
<v-row justify="center">
<v-date-picker v-model="picker"
:header-date-format="customFormatHeader">
</v-date-picker>
</v-row>
</v-app>
</div>
js :
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
picker: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10),
}
},
method: {
customFormatHeader(isoDate) {
const currentDate = new Date(isoDate)
const month = currentDate.toLocaleString('default', {month: 'long' })
const year = currentDate.toLocaleString('default', { year: 'numeric' })
return year + month
}
})

Related

Issue with displaying Chartjs annotation elements in Nextjs

I am transferring my CRA to a Nextjs and I am having a bit of an issue with anything that uses the <canvas> element. The charts and data are mostly there, but my annotations are now missing from the charts. I have tried importing everything with the dynamic function for the parent element, but it still seems to not show the missing features.
I am also seeing some weird things happening on an arcgis map which is not visualizing 3d elements on a <canvas>. So my guess is that this has something with the way that canvas or d3 interact with the browser.
// parent component
import moment from 'moment-timezone';
import React, { useRef } from 'react';
import {
Chart as ChartJS,
LinearScale,
CategoryScale,
BarElement,
PointElement,
LineElement,
Legend,
Tooltip,
} from 'chart.js';
// import { Chart } from 'react-chartjs-2';
import { ArrowRight } from '../../icons/ArrowRight';
import Link from 'next/link';
import { chartOptions } from '../../lib/chartOptions';
import dynamic from 'next/dynamic';
const Chart = dynamic((): any => import('react-chartjs-2').then((m: any) => m.Chart), {
ssr: false,
});
ChartJS.register(
LinearScale,
CategoryScale,
BarElement,
PointElement,
LineElement,
Legend,
Tooltip,
);
export const MarkupCard = ({ item }: any) => {
const chartRef = useRef();
const userName = item.user_id.split('#')[0];
return (
<div className="w-2/3 pb-10 mx-auto border-2 border-blue items-center rounded-lg my-4 py-4 flex flex-row justify-between">
<div className="w-full text-left pl-4 pb-6 h-72">
<div className="w-full flex flex-row justify-between">
<h2 className="text-lg font-bold">{userName} Marked up a chart</h2>
<div className=" w-1/3 text-right pr-4">
<h2>
{moment(item.created_at)
.tz(process.env.NEXT_PUBLIC_TIMEZONE ?? '')
.format('MM-DD-YYYY hh:mm:ss a')}
</h2>
</div>
</div>
<h2>Route: {item.routeLongName}</h2>
<Chart
style={{ height: '100px', width: '99%' }}
ref={chartRef}
plugins={item.details.options.plugins}
className="trips-chart"
type="line"
options={chartOptions(item.details.options, item.details.annotations)}
data={item.details.chartData}
/>
</div>
<Link href={`/app/markupDetail/${item.id}`}>
<button className="mx-6 h-full flex">
<ArrowRight />
</button>
</Link>
</div>
);
};
// chart component
import React, { useEffect, useState } from 'react';
import { useDispatch } from 'react-redux';
import { supabase } from '../../client';
import { actions } from '../../store';
import { SocialNote } from '../../types';
import { Card } from './Card';
const SocialFeed = () => {
const [feed, setFeed] = useState<SocialNote[]>([]);
const dispatch = useDispatch();
const loadPage = async () => {
dispatch(actions.setLoaded(true));
const { data, error } = await supabase
.from('notes')
.select('*')
.order('last_update', { ascending: false });
if (data) {
setFeed(data);
console.log(data);
return data;
} else {
return error;
}
};
useEffect((): (() => void) => {
loadPage();
return () => supabase.removeAllSubscriptions();
}, []);
return (
<div className="w-full mx-auto overflow-y-auto">
{feed.map((item, key) => (
<Card key={key} item={item} />
))}
</div>
);
};
export default SocialFeed;
// chartoptions.js
export const chartOptions: any = (options: any, annotations: any) => {
const { title } = options;
const { tooltip } = options.plugins;
return {
title,
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index' as const,
intersect: false,
},
plugins: {
annotation: { annotations: annotations },
tooltip,
legend: {
position: 'top' as const,
},
title,
},
};
};
// next.config.js
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
module.exports = nextConfig
CRA
Nextjs
Turns out I just needed to register Annotations in ChartJS.register()
This was not the case for React, but was required for Nextjs
import Annotation from 'chartjs-plugin-annotation';
ChartJS.register(
Annotation,
LinearScale,
CategoryScale,
BarElement,
PointElement,
LineElement,
Legend,
Tooltip,
);

vuetifyjs v-list. If click to item second time item not active. v-model="undefined"

I use standard v-list component of vuetifyjs. For create menu and show list of items.
But if I click second time the active element is hide. And I don't see active element of menu. It is bad for my menu. Link for example v-list
If use pug template below
v-list(dense)
v-list-item-group(color="success" v-model="selectedItem")
v-list-item(v-for="(gallery, key) in galleries" :key="key")
v-list-item-content
v-list-item-title(v-text="gallery")
I have solution. It needs watch variable and set force index by key of clicked item. If we have 'undefined' set force data method
Run examle solution Solution
Code below:
<template>
<div id="app">
<v-app id="inspire">
<v-card max-width="300" >
<v-list dense>
<v-list-item-group
v-model="selectedItem"
color="primary"
>
<v-list-item
v-for="(item, i) in items"
:key="i"
>
<v-list-item-content #click="setItem(i)">
<v-list-item-title v-text="item.text"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card>
</v-app>
</div>
</template>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
index: 0,
selectedItem: 0,
items: [
{ text: 'Real-Time'},
{ text: 'Audience' },
{ text: 'Conversions'},
],
}),
watch: {
selectedItem() {
if (typeof this.selectedItem === 'undefined') {
setTimeout(() => {
this.selectedItem = this.index;
}, 500);
}
},
},
methods: {
setItem(index) {
this.index = index;
},
},
})
Another solution would be to disable the v-list-item that has the same index as the selectedItem
<template>
<div id="app">
<v-app id="inspire">
<v-card max-width="300" >
<v-list dense>
<v-list-item-group
v-model="selectedItem"
color="primary"
>
<v-list-item
v-for="(item, i) in items"
:key="i"
:disabled="i == selectedItem"
>
<v-list-item-content>
<v-list-item-title v-text="item.text"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card>
</v-app>
</div>
</template>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
selectedItem: 0,
items: [
{ text: 'Real-Time'},
{ text: 'Audience' },
{ text: 'Conversions'},
],
}),
})

Vuetify autocomplete with solo selection and toggle "Select All"

Vuetify newbie here.
My goal is to have a v-autocomplete with solo selection of elements, and a toggle for "Select All".
My approach was by modifying 'v-select__slot' and to change its contents, is this the best approach?
Question: I was not succesfull cleaning previous selections, what is the best way to clean previous selected elements?
Question: After the "Select All" change event, how to close the drop-down?
<div id="app">
<v-app id="inspire">
<v-container fluid>
<v-autocomplete v-model="selectedFruits" :items="fruits" solo ref="selector" :readonly="readonly" #change="changed">
<template v-slot:prepend-item>
<v-list-item ripple #click="toggle">
<v-list-item-action>
<v-icon :color="selectedFruits.length > 0 ? 'indigo darken-4' : ''">{{ icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Select All</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-divider />
</template>
</v-autocomplete>
</v-container>
<br/>
{{selectedFruits}}
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
fruits: [
'Apples',
'...',
'Zucchini',
],
selectedFruits: [],
readonly: false,
}),
computed: {
likesAllFruit () {
return this.selectedFruits.length === this.fruits.length
},
likesSomeFruit () {
return this.selectedFruits.length > 0 && !this.likesAllFruit
},
icon () {
if (this.likesAllFruit) return 'mdi-close-box'
if (this.likesSomeFruit) return 'mdi-checkbox-blank-outline'
return 'mdi-checkbox-blank-outline'
},
},
methods: {
changed () {
var el = this.$refs.selector.$el.getElementsByClassName('v-select__slot')[0]
// var add_me = document.createTextNode(this.selectedFruits);
// el.appendChild(add_me, null);
},
toggle () {
this.$nextTick(() => {
var backup = this.$refs.selector.$el.getElementsByTagName('input')[0]
var text = ""
if (this.likesAllFruit) {
this.selectedFruits = []
text = "No fruits"
} else {
this.selectedFruits = this.fruits.slice()
text = "All fruits"
}
var el = this.$refs.selector.$el.getElementsByClassName('v-select__slot')[0]
el.textContent = ''
var add_me = document.createTextNode(text);
el.appendChild(add_me, null);
el.appendChild(backup, null);
})
},
},
created() {
}
})
Example:
https://codepen.io/dotmindlabs/pen/JjXbQyo?editors=1010
TIA
For displaying the toggle selection used a v-slot:label.
Regarding the closing of the drop-down after clicking toggle, it can be achieved with :menu-props="{closeOnClick: true,closeOnContentClick:true}"
Example HTML:
<div id="app">
<v-app id="inspire">
<v-container fluid>
<v-autocomplete
v-model="selectedFruits"
:items="fruits"
:menu-props="{ closeOnClick: true, closeOnContentClick: true }"
>
<template v-slot:label>
<div class="indigo--text">{{ label }}</div>
</template>
<template v-slot:selection="{ item, index }">
<span>{{ item }} </span>
</template>
<template v-slot:prepend-item>
<v-list-item
ripple
#click="toggle"
>
<v-list-item-action>
<v-icon :color="selectedFruits.length > 0 ? 'indigo darken-4' : ''">{{ icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Select All</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-divider class="mt-2"></v-divider>
</template>
</v-autocomplete>
</v-container>
{{selectedFruits}}
</v-app>
</div>
Javascript
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
fruits: [
'Apples',
'....',
'Zucchini',
],
selectedFruits: [],
}),
computed: {
likesAllFruit () {
return this.selectedFruits.length === this.fruits.length
},
icon () {
if (this.likesAllFruit) return 'mdi-close-box'
if (this.likesSomeFruit) return 'mdi-minus-box'
return 'mdi-checkbox-blank-outline'
},
label (){
if (typeof this.selectedFruits === "string") { return ""}
return this.selectedFruits.length > 0 ? "All Fruit" : ""
}
},
methods: {
toggle () {
if (this.likesAllFruit) {
this.selectedFruits = []
} else {
this.selectedFruits = this.fruits.slice()
}
},
},
created(){
this.selectedFruits = this.fruits.slice()
}
})
Codepen:
https://codepen.io/dotmindlabs/pen/RwapobY?editors=1011

How can I update my VueJs Data function properties value while fetching data from API using axios?

I have successfully fetched data from API. The fetched data shows in the alert function. However, the properties in the data function such as - 'Recovered' is not updating. I can show the fetched data using Vanilla JS. But I want to update them automatically and want to show them like this {{Recovered}}.
How can I do it??
<template>
<div class="container">
<h2>Total Recovered: {{Recovered}}</h2>
</div>
</template>
<script>
import axios from 'axios'
export default {
name:'CoronaStatus',
data: function () {
return {
Recovered: '',
TotalConfirmed: '',
TotalDeaths: '',
// test: '30',
// test_2: 'maheeb',
// componentKey: 0,
}
},
mounted(){
this.globalStatus();
},
methods:{
globalStatus: function(){
// const self = this;
// this.componentKey += 1;
axios.get('https://api.covid19api.com/summary')
.then((response) => {
// this.recovered = response.data.Global.NewConfirmed;
this.Recovered= response.data.Global.TotalRecovered;
alert(this.Recovered);
// document.getElementById('test_5').innerHTML = "total: " + this.TotalRecovered;
}).catch(err=> console.log(err));
},
}
}
</script>
<style scoped>
</style>
The easiest solution would be to refetch the information every hour with setInterval.
The best solution would be to use the WebHook provided by covid19api.com.
Vue.config.devtools = false;
Vue.config.productionTip = false;
var app = new Vue({
el: '#app',
data: {
Recovered: "Loading ..."
},
mounted() {
setInterval(() => {
this.globalStatus();
}, 3600000); // Call globalStatus every hour
this.globalStatus();
},
methods: {
globalStatus: function() {
axios
.get("https://api.covid19api.com/summary")
.then(response => {
this.Recovered = response.data.Global.TotalRecovered;
})
.catch(err => console.log(err));
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<div id="app">
<h2>Total Recovered: {{ Recovered }}</h2>
</div>

Auto select rows in v-data-table

I would like to programmatically checkmark a row in a v-data-table when an external listener notifies me of a particular value.
As an example, here is a Vuetify selectable table: https://vuetifyjs.com/en/components/data-tables#selectable-rows
In the example, If I were passed the value of 'Gingerbread' after the table and its data have already been instantiated, how would I programmatically select that corresponding row?
You can do this by pushing your values in your model like this:
HTML:
<div id="app">
<v-app id="inspire">
<v-btn #click="select">button</v-btn>
<v-data-table
v-model="selected"
:headers="headers"
:items="desserts"
:single-select="singleSelect"
item-key="name"
show-select
class="elevation-1"
>
<template v-slot:top>
<v-switch v-model="singleSelect" label="Single select" class="pa-3"></v-switch>
</template>
</v-data-table>
</v-app>
</div>
VueJS:
new Vue({
el: '#app',
vuetify: new Vuetify(),
methods: {
select: function() {
let result = this.desserts.find((dessert) => {
return dessert.name == 'Gingerbread'
})
this.selected.push(result)
}
},
data () {
return {
singleSelect: false,
selected: [],
headers: [
{ text: 'Dessert (100g serving)', value: 'name' },
{ text: 'Calories', value: 'calories' },
],
desserts: [
{ name: 'Gingerbread', calories: 356 },
{ name: 'Jelly bean', calories: 375 }
],
}
},
})
The v-data-table component has a property called filteredItems which you can use to add items to the selected array
<v-data-table v-model="selected":items="itemsArray" ref="table"></v-data-table>
function selectAll() {
this.$refs.table.filteredItems.map(item => {
if(...some condition...) {
this.selected.push(item)
}
})
}

Resources