How to create Nested menus on Vuetify? - html

I'm currently usinfg Vuetify 1.5.18 and having some issues trying to create a nested menu usint the toolbar component and list-group.
The menu is working but when I click to expand it closes.
Here's the CodePen: https://codepen.io/fabiozanchi/pen/dybBmKj
And here the following code:
HTML
<div id="app">
<v-app id="inspire">
<v-toolbar>
<v-toolbar-title>Title</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items class="hidden-sm-and-down">
<v-btn flat>Link One</v-btn>
<v-btn flat>Link Two</v-btn>
<v-btn flat>Link Three</v-btn>
<v-menu open-on-hover bottom offset-y>
<template v-slot:activator="{ on }">
<v-btn
color="primary"
dark
v-on="on"
>
Dropdown
</v-btn>
</template>
<v-list>
<v-list-group
v-for="item in items"
:key="item.title"
v-model="item.active"
:prepend-icon="item.action"
no-action
>
<template v-slot:activator>
<v-list-tile>
<v-list-tile-content>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</template>
<v-list-tile
v-for="subItem in item.items"
:key="subItem.title"
#click=""
>
<v-list-tile-content>
<v-list-tile-title>{{ subItem.title }}</v-list-tile-title>
</v-list-tile-content>
<v-list-tile-action>
<v-icon>{{ subItem.action }}</v-icon>
</v-list-tile-action>
</v-list-tile>
</v-list-group>
</v-list>
</v-menu>
</v-toolbar-items>
</v-toolbar>
</v-app>
</div>
JavaScript
new Vue({
el: '#app',
data: () => ({
items: [
{
action: 'local_activity',
title: 'Attractions',
items: [
{ title: 'List Item' }
]
},
{
action: 'restaurant',
title: 'Dining',
active: true,
items: [
{ title: 'Breakfast & brunch' },
{ title: 'New American' },
{ title: 'Sushi' }
]
},
{
action: 'school',
title: 'Education',
items: [
{ title: 'List Item' }
]
},
{
action: 'directions_run',
title: 'Family',
items: [
{ title: 'List Item' }
]
},
{
action: 'healing',
title: 'Health',
items: [
{ title: 'List Item' }
]
},
{
action: 'content_cut',
title: 'Office',
items: [
{ title: 'List Item' }
]
},
{
action: 'local_offer',
title: 'Promotions',
items: [
{ title: 'List Item' }
]
}
]
})
})

Fixed. Working adding :close-on-content-click="false" on the v-menu:
<v-menu
v-model="menu"
:close-on-content-click="false"
:nudge-width="200"
offset-x
>
Codepen updated: https://codepen.io/fabiozanchi/pen/dybBmKj

You can also do this thing in v-list-group as (:close-on-content-click="true") by default in my case I solved it by this adding (#click.stop).
<v-list-group
#click.stop
v-for="item in items"
:key="item.title"
v-model="item.active"
:prepend-icon="item.action"
no-action
>

Related

Vuetify <v-data-table> custom <th> header

I am using Vuetify <v-data-table>.
How to add button on table header <th>?
This code is what I have tried so far.
<v-data-table v-model="selected" :headers="headers" :items="desserts">
<template slot="items" slot-scope="row">
<th><button>button</button></th>
</template>
</v-data-table>
<script>
export default {
data:() =>({
headers: [
{
text: 'Dessert (100g serving)',
align: 'start',
sortable: true,
value: 'name',
},
{ text: 'Calories', value: 'calories' },
{ text: 'Fat (g)', value: 'fat' },
{ text: 'Carbs (g)', value: 'carbs' },
{ text: 'Protein (g)', value: 'protein' },
{ text: 'Iron (%)', value: 'iron' },
],
});
</script>
Please help.
You can use the header.<fieldname> slot template.
For example, to target the first column, name:
<v-data-table v-model="selected" :headers="headers" :items="desserts">
<template v-slot:header.name="{ header }">
{{ header.text }}
<v-btn>Button</v-btn>
</template>
</v-data-table>

How can I drag items from list in component to list inside another component using Vue draggable?

I am trying to move items from one list to another using vue draggable, but the lists are inside of a component and I can't get it to work. The items are able to move inside a list but not from a list to another.
I have got a Board component containing all the lists and a List component containing the draggable items.
This is the board component:
<template>
<div class="board">
<BoardMenu :users="this.users" :name="this.name"> </BoardMenu>
<div class="boardContent">
<Backlog></Backlog>
<div class="lists">
<List
class="list"
v-for="list in lists"
:key="list.id"
:id="list.id"
:items="list.items"
></List>
</div>
</div>
</div>
</template>
<script>
import BoardMenu from "./BoardMenu";
import Backlog from "./Backlog";
import List from "./List";
export default {
name: "UserIcon",
props: {
id: Number
},
components: {
BoardMenu,
Backlog,
List
},
data() {
return {
name: "BOARDNAME",
users: [{ name: "Bram Coenders" }, { name: "Jasper van der Zwaan" }],
lists: [
{
id: 1,
items: [
{
type: "story",
id: 1,
listId: 1
},
{
id: 2,
listId: 1
},
]
},
{ id: 2, items: [] }
],
backlog: { id: 2 }
};
},
};
</script>
And this is the List component:
<template>
<div class="list">
<div class="list-header">
<h2 id="list-name">{{ name }}</h2>
<p id="list-description">{{ description }}</p>
</div>
<draggable
v-model="items"
:list="this.id"
class="list-list"
>
<div :id="item.id" class="list-item" v-for="item in items" :key="item.id">
<div v-if="item.type == 'story'">
<Story class="story" :id="item.id"></Story>
</div>
<div v-else>
<Task class="task" :id="item.id"></Task>
</div>
</div>
</draggable>
</div>
</template>
<script>
import draggable from "vuedraggable";
import Story from "./Story.vue";
import Task from "./Task.vue";
export default {
name: "List",
components: {
Story,
Task,
draggable
},
props: {
items: []
},
data() {
return {
name: "To do",
description: "this sprint."
};
},
methods :{
newItem: function(){
console.log("test")
}
}
};
</script>
Add :options='{group: "items"}' to your draggable component or you can just try to add the attribute group="items" (if you're using Vue 2.2+)

ES6: How to filter a state array using a map

I have the following state array called structure:
var structure = [
{ id: 0, label: "Dashboard", link: "/test/dashboard", icon: <HomeIcon /> },
{
id: 1,
label: "Test1",
link: "/test1",
icon: <InboxIcon />,
},
{
id: 2,
label: "Test2",
link: "/test2",
icon: <PresentToAllIcon />,
},
{ id: 3, type: "divider" },
{
id: 4,
label: "Test3",
link: "/test3",
icon: <ListAltIcon />,
children: [
{
label: "Test4",
link: "/test4",
icon: <LanguageIcon />,
},
{
label: "Test5",
link: "/test5",
icon: <ListIcon />,
},
],
},
{
id: 5,
label: "Test6",
link: "/test6",
icon: <DescriptionIcon />,
},
{
id: 6,
label: "Test7",
link: "/test7",
icon: <AccountBalanceWallet />,
children: [
{
label: "Test8",
link: "/test8",
icon: <FaceIcon />,
},
{
label: "Test9",
link: "/test9",
icon: <TransferWithinAStationIcon />,
},
{
label: "Test10",
link: "/test10",
icon: (
<Avatar alt="Test" src={testlogo} className={classes.small} />
),
},
{
label: "Test11",
link: "/test11",
icon: <PeopleAlt />,
},
],
},
{
id: 7,
label: "Test12",
link: "/test12",
icon: <EditIcon />,
},
];
I want to filter it using another array, the modules array looks like this:
["Miscellaneous","Test Converter"]
What I've done so far is this
modules.forEach((modulesMap) => {
structureNew = structure.filter(
(structureFiltered) => structureFiltered.label == modulesMap
);
});
Anyone has an idea how to do this properly? The problem I'm encountering with my code is it overrides or replaces the current variable structureNew
I would like it to get appended into a state array as well so it would look kind of similar to structure
Try this one, i just made some small change in your code
var structure = [
{ id: 0, label: "Dashboard", link: "/cpex/dashboard", icon: '<HomeIcon />' },
{
id: 1,
label: "Inward",
link: "/cpex/inward",
icon: '<InboxIcon />',
},
{
id: 2,
label: "Outward",
link: "/cpex/outward",
icon: '<PresentToAllIcon />',
},
{ id: 3, type: "divider" },
{
id: 4,
label: "Proof List",
link: "/cpex/prooflist",
icon: '<ListAltIcon />',
children: [
{
label: "Proof Web",
link: "/cpex/prooflist/web",
icon: '<LanguageIcon />',
},
{
label: "Proof Others",
link: "/cpex/prooflist/others",
icon: '<ListIcon />',
},
],
},
{
id: 5,
label: "Miscellaneous",
link: "/cpex/misc",
icon: '<DescriptionIcon />',
},
{
id: 6,
label: "RPS",
link: "/cpex/rps",
icon: '<AccountBalanceWallet />',
children: [
{
label: "Client Maintenance",
link: "/cpex/rps/clientmaintenance",
icon: '<FaceIcon />',
},
{
label: "Process SFTP",
link: "/cpex/rps/sftp",
icon: '<TransferWithinAStationIcon />',
},
{
label: "Process PESONet",
link: "/cpex/rps/pesonet",
icon: (
'<Avatar alt="Pesonet" src={pesonetlogo} className={classes.small} />'
),
},
{
label: "Override Enrollment",
link: "/cpex/rps/overrideenrollment",
icon: '<PeopleAlt />',
},
],
},
{
id: 7,
label: "Message Converter",
link: "/cpex/message",
icon: '<EditIcon />',
},
];
var modules=["Miscellaneous","Message Converter"]
var structureNew=[]
modules.forEach((modulesMap,i) => {
let arrs = structure.filter(
(structureFiltered) => structureFiltered.label == modulesMap
);
structureNew= structureNew.concat(...arrs)
});
console.log('RESULT:'+JSON.stringify(structureNew))
debugger

extjs dynamic button in panel

Have this code
Ext.define('C.YmkDetPanel', {
extend: 'Ext.Panel',
xtype: 'YmkDetPanel',
conttroller: 'ccc',
viewModel: {
type: 'ymkDetModel'
},
bind: {
html: '<div> {zzz} </div> <div id = "button"> </div>'
},
listeners: {
painted: function ( ) {
new Ext.Button({
renderTo: 'button',
scope: this,
text: 'Click Me',
listeners:
{
tap: function() {
alert(this.up());
}
}
});
}
},
initComponent: function() {
this.callParent(arguments);
}
});
I see created button.
But on click this.up() is null. THIS is the button.
How to access to C.YmkDetPanel from button? in Painted event THIS is "Ext.dom.Element"
Use a container and nest the 2 items separately, fiddle:
Ext.define('C.YmkDetPanel', {
extend: 'Ext.Panel',
xtype: 'YmkDetPanel',
viewModel: {
data: {
zzz: 'foo'
}
},
items: [{
xtype: 'component',
bind: '{zzz}'
}, {
xtype: 'button',
text: 'Click me'
}]
});
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.Viewport.add({
xtype: 'YmkDetPanel'
});
}
});

Sencha Touch Horizontally Center Search Field in Navigation Bar

This question is pretty downright dumb and I might have stumbled upon a bug but I need to center my searchfield in my navigation bar in Sencha Touch and I just can't make it work. This is my code:
Ext.define('Myapp.view.MyNav', {
extend: 'Ext.navigation.View',
xtype: 'mynav',
requires: [
'Ext.field.Search', 'Ext.Button'
],
config: {
fullscreen: true,
navigationBar: {
items: [
{
xtype: 'searchfield',
placeHolder: 'Search...',
listeners: {
keyup: function(field) {
}
},
align: 'right'
}
]
},
items: [
{
title: 'MyNav',
xtype: 'list',
fullscreen: true,
grouped: true,
store: {
fields: ['name', 'html'],
sorters: 'name',
data: [
{name: 'Alfa', html: '<p>alfa</p>'},
{name: 'Beta', html: '<p>beta</p>'},
{name: 'Gamma', html: '<p>gamma</p>'},
{name: 'Mupp', html: '<p>mupp</p>'},
{name: 'Tupp', html: '<p>tupp</p>'}
],
grouper: {
groupFn: function(record) {
return record.get('name')[0];
},
indexBar: true
},
},
listeners: {
select: function(view, record) {
var test = Ext.create('Ext.Panel', { fullscreen: true,
title: record.get('name'),
layout: {
type:'vbox'
},
items: [
{
xtype: 'panel',
html: record.get('html')
}
]
});
var mainnav = Ext.ComponentQuery.query('bookmarksmainnav')[0];
mainnav.setActiveItem(test);
}
},
itemTpl: '{name}'
}
]
}
});
Focus on the actual navigation bar thing, the other stuff is just code pasted (and I modified it somewhat), I'm pretty sure this is a bug though.
Thanks in advance!
you can try using a toolbar docked in the bottom of the page with the search field centered, I don't know why but the navigation bar ignores the centered property.
Something like this:
config: {
fullscreen: true,
navigationBar: {
},
items: [
{
xtype: 'toolbar',
docked: 'bottom',
items: [
{
xtype: 'searchfield',
placeHolder: 'Search...',
listeners: {
keyup: function(field) {
}
},
centered: true
}
],
},
{
title: 'MyNav',
xtype: 'list',
If you need the search field on the top of the screen you could try hiding the navigation bar with hidden: true and changing the docked property in the toolbar.
Hope it helps!
A better answer (for me) that just centres whatever you have added to the navigation bar, is:
this.getNavigationBar().leftBox.setCentered(true);
You will probably want to manage the centred-ness of the navigation bar for each page, though.
I used
layout: {
align: 'center',
pack: 'center',
type: 'hbox'
}
This would be just under the docked: 'bottom', line is the example above.
Regards
Jacko
Whenever I find it difficult to center a desired field, I just add a spacer before and after, combined with a flex for the item I want to center, it never fails. In this case:
items: [
{
xtype: 'spacer',
},
{
xtype: 'searchfield',
placeHolder: 'Search...',
listeners: {
keyup: function(field) {
}
flex: 0.7
},
{
xtype: 'spacer',
},