How to show ajax result in v-menu content on mouse over? - vuetify.js

I have v-menu attached icons on my page.
I want to show detail info on mouse over of any icon (like tooltip).
But, content should be dynamically get with ajax request.
How can I trigger ajax request on mouse over and show result on v-menu content?

[UPDATE]
using v-menu with open-on-hover shall be enough for that purpose
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: [{name: 'php', menu: false, url: 'https://api.mocki.io/v1/b043df5a' }, {name: 'mysql', menu: false, url: 'https://api.mocki.io/v1/b043df5a'}, {name: 'vuejs', menu: false, url: 'https://api.mocki.io/v1/b043df5a'}],
fav: true,
message: false,
hints: true,
serverTooltips: []
}),
watch: {
items: {
deep: true,
handler: function (val) {
console.log(val)
val.map((item) => {
if (item.menu === true) {
axios.get(item.url).then(({data}) => {
this.serverTooltips = data
})
}
})
},
}
},
})
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div id="app">
<v-app>
<div class="text-h4">Please mouse over those buttons to see events in Cities</div>
<p>Main code is copied from <a href='https://vuetifyjs.com/en/components/menus/#popover-menu'>vuetify popover-menu example</a></p>
<div class="mb-2" v-for="item in items">
<v-menu v-model="item.menu"
:close-on-content-click="false"
:open-on-hover="true"
:nudge-width="200"
offset-x>
<template v-slot:activator="{ on, attrs }">
<v-btn
color="indigo"
dark
v-bind="attrs"
v-on="on">
Mouse over to see {{ item.name }} events
</v-btn>
</template>
<v-card v-if="serverTooltips.length">
<v-list>
<v-list-item>
<v-list-item-avatar>
<img src="https://cdn.vuetifyjs.com/images/john.jpg" alt="John">
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>Detail for {{ item.name }}</v-list-item-title>
<v-list-item-subtitle>Detail subtitle</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-btn :class="fav ? 'red--text' : ''" icon #click="fav = !fav">
<v-icon>mdi-heart</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
</v-list>
<v-divider></v-divider>
<v-list>
<v-list-item>
<v-list-item-action>
<v-switch v-model="message" color="purple"></v-switch>
</v-list-item-action>
<v-list-item-title>Enable messages</v-list-item-title>
</v-list-item>
<v-list-item>
<v-list-item-action>
<v-switch v-model="hints" color="purple"></v-switch>
</v-list-item-action>
<v-list-item-title>Enable hints</v-list-item-title>
</v-list-item>
</v-list>
<div v-if="serverTooltips.length">
{{ item.name }} located in cities:
<v-list>
<v-list-item v-for="(tooltip, index) in serverTooltips" :key="index">
<v-list-item-title>{{ tooltip.city }}</v-list-item-title>
</v-list-item>
</v-list>
</div>
<p v-else>Fetching data, please wait!</p>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn text #click="menu = false">
Cancel
</v-btn>
<v-btn color="primary" text #click="menu = false">
Save
</v-btn>
</v-card-actions>
</v-card>
</v-menu>
</div>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</body>
Anyway I advise you to cache your json information because hover event may be a little aggressive, specially if you're using mobile data.

Related

Vuetify navigation drawer, make mini on small screen rather than hide

When the browser is of a certain size width I want the navigation drawer component to revert to mini rather than hide like its doing by default:
https://vuetifyjs.com/en/components/navigation-drawers/#api
<template>
<v-navigation-drawer
app
floating
>
<v-list nav rounded>
<v-list-item link>
<v-list-item-icon>
<v-icon>mdi-heart</v-icon>
</v-list-item-icon>
<v-list-item-title>Heart</v-list-item-title>
</v-list-item>
</v-list>
</v-navigation-drawer>
</template>
<script>
export default {
name: "AppNavigation",
data: () => ({
})
}
</script>
<style scoped>
</style>
Expected behavior
When I reduce the browser width, it should show the v-list icons like the mini variant, or expand on hover.
Actual behavior
The navigation drawer disappears completely by design but not sure how to stop this in the correct way.
Ideas
There is the permanent flag but how would I detect the screen size has changed? I could do a combination of permanent and mini.sync
you can access vuetify's built in breakpoints through $vuetify.breakpoint.<breakpoint> so for the drawer you can have this binding: :mini-variant="$vuetify.breakpoint.mdAndDown".
condition returns true for screen width below 1264 px and mini-variant comes to play and it returns false above 1264 px so you can have your normal drawer.
check the demo below and run it in full screen mode and resize the window to see the effect.
Vue.config.productionTip = false;
new Vue({
el: '#app',
vuetify: new Vuetify(),
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-navigation-drawer app color="indigo" floating permanent :mini-variant="$vuetify.breakpoint.mdAndDown">
<v-list nav rounded>
<v-list-item link>
<v-list-item-icon>
<v-icon>mdi-heart</v-icon>
</v-list-item-icon>
<v-list-item-title>Heart</v-list-item-title>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-app>
</div>

Vuetify How add <br> to v-text-field error-messages

I want to display new line, I use tag but not work.
The original idea was to new a component, and then customize error-messages to div, But it’s too much trouble, so come to ask if there is an easy way
Vue.use(Vuetify);
var vm = new Vue({
el: "#app",
methods: {
},
data: {
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.3/vue.js"></script>
<script src="https://unpkg.com/vuetify#0.14.8/dist/vuetify.min.js"></script>
<link rel=stylesheet type="text/css" href="https://unpkg.com/vuetify#0.14.8/dist/vuetify.min.css">
<div id="app">
<v-app dark>
<v-text-field
label="Field"
error-messages="aaa<br>bbb"
></v-text-field>
</v-app>
</div>
This is a possible solution.
https://jsfiddle.net/ue9rqcwk/
HTML:
<div id="app">
<v-app dark>
<v-text-field
class="multiline"
label="Field"
error-messages="aaa
bbb"
></v-text-field>
</v-app>
</div>
css:
.multiline {
white-space: pre-line;
}
EDIT: Corrected URL

Unknown custom element in Vuetify

I am new to Vuetify and vue. I am using vue and vuetify but due some reason I am not able open my page.The error I am getting when I run my project:
[Vue warn]: Unknown custom element: - did you register the
component correctly? For recursive components, make sure to provide
the "name" option.
found in
---> at resources/js/components/appContainer.vue
My code:
appContainer.vue
<template>
<v-app id="inspire">
<v-navigation-drawer
v-model="drawer"
app
>
<v-list dense>
<v-list-item link>
<v-list-item-action>
<v-icon>mdi-home</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Home</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item link>
<v-list-item-action>
<v-icon>mdi-contact-mail</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Contact</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-app-bar
app
color="indigo"
dark
>
<v-app-bar-nav-icon #click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-app-bar>
<v-content>
<v-container
class="fill-height"
fluid
>
<v-row
align="center"
justify="center"
>
<v-col class="text-center">
<v-tooltip left>
<template v-slot:activator="{ on }">
<v-btn
:href="source"
icon
large
target="_blank"
v-on="on"
>
<v-icon large>mdi-code-tags</v-icon>
</v-btn>
</template>
<span>Source</span>
</v-tooltip>
</v-col>
</v-row>
</v-container>
</v-content>
<v-footer
color="indigo"
app
>
<span class="white--text">© 2019</span>
</v-footer>
</v-app>
</template>
<script>
export default {
props: {
source: String,
},
data: () => ({
drawer: null,
}),
}
</script>
app.js
require('./bootstrap');
window.Vue = require('vue');
import Vue from 'vue'
import Vuetify from './plugins/vuetify'
Vue.use(Vuetify);
Vue.component('app-container', require('./components/appContainer.vue').default);
const app = new Vue({
Vuetify,
Vue,
el: '#app',
});
spa.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#5.x/css/materialdesignicons.min.css" rel="stylesheet">
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
<app-container></app-container>
</div>
</body>
</html>
vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
Vue.use(Vuetify)
const opts = {}
export default new Vuetify(opts)
Seems like you haven't given an export name for your app-container element. Try the below.
appContainer.vue
<template>
...
</template>
<script>
export default {
name: 'app-container'
props: {
source: String,
},
data: () => ({
drawer: null,
}),
}
</script>
Try to change the drawer from null to false:
data: () => ({
drawer: false,
}),
Please make your component name camelcase.
Like Vue.component('appContainer',require('./components/apContainer.vue').default);

Change default font color for navigation-drawer and toolbar

I would like to define the default font-color for the navigation-drawer and toolbar.
I looked at changing colors through theming: https://vuetifyjs.com/en/customization/theme
Aswell as overriding scss defaults: https://vuetifyjs.com/en/customization/sass-variables
But nowhere can i find changing the needed setting.
Playground: codepen io/timar/pen/WNvxOYB
The Vuetify CSS has multiple color classes for background as well as text. The format for the text color classes are in the format of: .[color]--text. There is also various flavoring for lighten, darken and accent in the format of: .text--lighten-2, for example. The naming of colors and such can be found at the Vuetify Colors page.
What I have shown below, essentially forking the codepen in the OP, illustrates a method, customColor, to return a CSS class to set the text color based on the item.title value that is called on v-list-item-title.
Vue.config.productionTip = false;
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
items: [
{ title: 'Dashboard', icon: 'mdi-view-dashboard' },
{ title: 'Photos', icon: 'mdi-image' },
{ title: 'About', icon: 'mdi-help-box' },
],
right: null,
}
},
methods: {
customColor(text) {
return (text === 'Photos') ? 'green--text' : '';
}
}
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.1.14/dist/vuetify.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-app id="inspire">
<v-card
height="400"
width="256"
class="mx-auto"
>
<v-navigation-drawer permanent>
<v-list-item>
<v-list-item-content>
<v-list-item-title class="title">
Application
</v-list-item-title>
<v-list-item-subtitle>
subtext
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-divider></v-divider>
<v-list
dense
nav
>
<v-list-item
v-for="item in items"
:key="item.title"
link
>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title
:class="customColor(item.title)"
>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-card>
</v-app>
</div>

Cannot read property 't' of undefined using Vuetify and Laravel

Getting this error when attempting to use a Vuetify component out of the box. Perhaps just my lack of understanding how to implement Vuetify components in Laravel.
Laravel v5.8.35, Vue v2.6.10, Vuetify v2.0.18.
error:
[Vue warn]: Error in render: "TypeError: Cannot read property 't' of
undefined"
found in
---> < VSelect >
< Test > at resources/js/components/Test.vue
< Root >
app.js
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
import Vuetify from 'vuetify';
Vue.use(Vuetify);
Vue.component('test', require('./components/Test.vue').default);
const app = new Vue({
el: '#app',
});
layouts/vue.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Vue Examples</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
</head>
<body>
<div id="app">
#yield("content")
</div>
<script src="{{ asset('/js/app.js') }}"></script>
</body>
</html>
test.blade.php
#extends('layouts.vue')
#section('content')
<test></test>
#endsection
components/Test.vue
<template>
<v-container fluid>
<v-row align="center">
<v-col class="d-flex" cols="12" sm="6">
<v-select
:items="items"
label="Standard"
></v-select>
</v-col>
<v-col class="d-flex" cols="12" sm="6">
<v-select
:items="items"
filled
label="Filled style"
></v-select>
</v-col>
<v-col class="d-flex" cols="12" sm="6">
<v-select
:items="items"
label="Outlined style"
outlined
></v-select>
</v-col>
<v-col class="d-flex" cols="12" sm="6">
<v-select
:items="items"
label="Solo field"
solo
></v-select>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
data: () => ({
items: ['Foo', 'Bar', 'Fizz', 'Buzz'],
}),
}
</script>
As you can see, the vue file is exactly the source from Vuetify for the v-select component. Components that don't include this works:
export default {
data: () => ({
All other components (e.g. ExampleComponent) work fine.
You need to create an instance of Vuetify. e.g.:
new Vue({
el: '#app',
vuetify: new Vuetify()
})
This is documented here, though they do hide it quite a long way down the page.

Resources