Open a router-view in a new tab? - vue.js

we are starting a new vuejs SPA application, the thing is that the client is asking to do something like a tabbed navigation.
i mean, each option of the menu, will open in a new closable tab, i was looking for this in here, but each solution that i find, is with all the tabs open from the start, the idea is to do it dynamic.
i've tried to persuade the client from this option, but i didn't have any luck with that, they are migrating the application from a MDI windows app, and somehow want to keep some functionalities.
is there any way to accomplish this task?
regards

1) Store an object array that will be looped through to create tabs. When a tab is opened, add to the list, when a tab is closed, delete the tab from the list
tabs: [ { text: 'tab 1', 'route': 'routeName' },
{ text: 'tab 1', 'route': 'routeName' },
{ text: 'tab 1', 'route': 'routeName' }]
2) Create a router-view under the rendered tabs that will show the route when a tab is clicked
<b-tab v-for="tab in tabs"
#click="navigate(tab.route)>
{{ tab.text }}
<v-tab>
<div>
<router-view>
</router-view>
</div>

Related

Vuetify bottom navigation not removing active state on route change after hard refresh

In my app I have a bottom navigation component set up as such:
<v-bottom-navigation
v-else
background-color="overlay"
grow
app
color="primary"
>
<v-btn
v-for="(route, key) in routes"
ref="link"
:key="'route' + key"
:to="route.to"
min-width="48"
class="px-0"
>
<span v-if="$vuetify.breakpoint.smAndUp">{{ route.name }}</span>
<v-icon>{{ route.icon }}</v-icon>
</v-btn>
</v-bottom-navigation>
This works well, I can use it to navigate around my app as intended. When clicking one of the buttons on the bottom navigation, the button state updates as it should to show that it is active (primary color).
My routes are defined as follows:
routes: [
{ icon: mdiViewDashboard, name: 'Dashboard', to: '/dashboard' },
{ icon: mdiCart, name: 'Orders', to: '/orders' },
{ icon: mdiDolly, name: 'Receiving', to: '/receiving' },
{ icon: mdiClipboardText, name: 'Tasks', to: '/tasks' },
{ icon: mdiTruck, name: 'Deliveries', to: '/deliveries' },
],
I have an additional route /settings which is not part of this main navigation, but defined on the header bar of my application as such:
<v-btn
aria-label="Settings"
icon
to="/settings"
>
<v-icon>{{ mdiCog }}</v-icon>
</v-btn>
Since the settings button/router link is not part of the bottom navigation, when I click on the settings button, it disables the active state on the buttons in the bottom navigation, as it should since it is not part of the bottom navigation.
Here is where the odd behavior occurs:
If I am in one of the routes defined on the bottom navigation, and hard refresh the page I refresh to the proper location. From here, if I click the settings button, the router displays the settings as it should, but the active state on the bottom navigation of the stale state still shows. This only occurs on a hard refresh, if I select a bottom navigation route, and then go to settings, it removes the active state from the bottom navigation button.
In my research I thought it may be an issue with the exact property for the router links, but it seems to make no different.
Additionally, I set a breakpoint to display the bottom navigation on small and below, if I stretch the window to hide the bottom navigation, then shrink it to re-show, when the component is shown again, it has the proper state.
Reloading the page isn't the only way to reproduce the bug. The buttons in the navigation group appear to be toggleable both by VItemGroup logic and VBtn's routable mixin. You can replicate the problem by clicking any nav button two times and routing to /settings after that. If you inspect the element in that state, the active class v-btn--active is duplicated 3 times. Routing to another page removes only the exact matches of v-btn--active v-btn--active, leaving the third one on the element.
Clearly, this is not an intended behavior.
But the workaround is quite simple. Setting every button's active-class prop to anything but 'v-btn--active' will do the trick.
So, for example:
<v-btn
v-for="(route, key) in routes"
ref="link"
:key="'route' + key"
:to="route.to"
min-width="48"
class="px-0"
active-class=""
>
<span v-if="$vuetify.breakpoint.smAndUp">{{ route.name }} </span>
<v-icon>{{ route.icon }}</v-icon>
</v-btn>

Is there a way to bind click events to buttons in schemas?

Is there a way to make my schema accept click events for buttons, or do click events have to be binded manually?
For example, is there a way to do something like
schema: [
{
type: 'button',
name: 'sample-button',
label: 'Here is a button',
click: myClickFunction(),
}
]
or do I have to manually set a FormulateInput element and put this in my template
<FormulateInput
type="button"
name="Here is a button"
#click="myClickFunction()"
/>

Use Font Awesome icons in CoreUI sidebar

I'm trying to replace the default CoreUI icons from the admin panel template sidebar with a Font Awesome icons.
I've installed Font-Awesome successfully using the latest official installation instructions of FontAwesome for vue and can display the icons just fine using the <font-awesome-icon icon="tasks" /> syntax. But I can't get the same icon to show up in the CoreUI Sidebar component.
Here is my _nav.js:
export default [
{
_name: 'CSidebarNav',
_children: [
{
_name: 'CSidebarNavItem',
name: 'Dashboard',
to: '/dashboard',
icon: 'cil-speedometer'
},
{
_name: 'CSidebarNavItem',
name: 'Account',
to: '/account',
icon: 'cil-bank'
},
{
_name: 'CSidebarNavItem',
name: 'Projects',
to: '/projects',
fontIcon: 'fas fa-tasks'
}
]
}
]
So far I tried fontIcon: 'fas fa-tasks', icon: 'fas fa-tasks', icon: 'faTasks', etc. but nothing works.
As you can see below, the "tasks" icon show up in the card body (using <font-awesome-icon icon="tasks" />), but not in the sidebar for the Project item.
This link suggest using fontIcon api instead of Icon, however this requires the CSS versions of icons to be imported, which I can't find using the recommended Font Awesome installation guide.
At this point how could I either import the CSS icons so it works with the CSidebarNavItem component, or is there a way to reference a Font Awesome icon directly ?
This is fontawesome icon portal https://fontawesome.com/v4.7/icon/address-book . Here icon name has address-book. You can't access directly address-book name in coreui template.
you should use this fa key
fa fa-address-book
sample code,
{
name: 'Address',
url: '/address',
icon: 'fa fa-address-book',
},
You need to pass children CSidebarNavItem for custom content (component supports only CIcon component configuration by default)
<CSidebarNavItem>
<CLink
class="c-sidebar-nav-link"
to="/home/test02"
:exact="true"
activeClassName="c-active"
>
<FontAwesomeIcon class="c-sidebar-nav-icon" icon="faCoffee" />
Test02
</CLink>
</CSidebarNavItem>
You have sidebar rendered through CRenderFunction which docs are available here:
https://coreui.io/vue/docs/components/render-function.html
Also CSidebarNavItem and CIconcomponents are documented on this site
just add core ui and font Awesome css classes together in i tag
{
_tag: 'CSidebarNavItem',
name: 'Category',
to: '/category',
icon: <i class="fad fa-acorn c-sidebar-nav-icon"></i>,
},

How can I get CKEditor 5 "Link" dialog box to pin to custom DOM element instead of 'document.body'

I'm building a Vue.js web application. I'm using CKEditor in a form that is placed inside a modal window. By design, the user's focus is "trapped" in the modal. In CKEditor, when user clicks the "Link" icon in toolbar, the editor opens a dialog box and attaches the new DOM element to 'document.body'. With respect to the DOM, the "Link" dialog is now outside of trapped focus. The user cannot click or tab his way to the "Link" dialog input.
I dug into the ckeditor5-ui source and found relevant code in balloonpanelview.js. I've unsuccessfully tried to configure CKEditor based on https://ckeditor.com/docs/ckeditor5/latest/api/module_utils_dom_position-Options.html
In my Vue.js component, I have:
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
...
data: () => ({
editor: ClassicEditor,
editorConfig: {
toolbar: ['bold', 'italic', 'bulletedList', 'numberedList', 'link'],
},
...
})
...
I want the CKEditor "Link" dialog DOM element to be attached to a DOM element id that I specify.
In Vuetify dialog component is required to disable retain-focus
<v-dialog :retain-focus="false" />
There may be much time since you opened the issue. However... This issue was happening to me too. This is happening because Bootstrap modal trap the focus in the active modal. If you're using bootstrap-vue, do this.
In your <b-modal> add the prop no-enforce-focus.
no-enforce-focus is reactive. To properly apply this workaround you can use this prop with a variable, that detects when your CKeditor have focus. If have focus, disable the enforce focus. If doesn't have, restore it. You can apply it by the following way:
<template>
<b-modal
...
:no-enforce-focus="editorFocus">
<ckeditor
...
#focus="toggleEditorFocus(true)"
#blur="toggleEditorFocus(false)"
/>
</b-modal>
</template>
<script>
export default {
...
data () {
return {
editorFocus: false
}
},
methods: {
toggleEditorFocus (val = !this.editorFocus) {
setTimeout(() => {
this.editorFocus = val
}, 10)
}
}
}
</script>
I know the setTimeout is a tricky method, but at least is working now for me.

Triggering an action of a different page using NavigatorIOS Buttons

I'm making an app with two Buttons in the Navigator in the Homepage. I have also used React Native Side Menu. (https://github.com/react-native-fellowship/react-native-side-menu)
From the left button of the NavigatorIOS, I want to trigger the toggle() method of the Side Menu. How am I to accomplish this?
<NavigatorIOS
style={styles.navigationContainer}
ref="nav"
initialRoute={{
title: "Home",
component: Home,
ref:'home',
rightButtonTitle: 'Items',
leftButtonTitle: 'Menu',
onLeftButtonPress: () => {
//menuActions.toggle(); HERE IS THE PROBLEM
},
onRightButtonPress: () => {
this.refs.nav.navigator.push({
title: "Items",
component: Items
});
}
}} />
The code and the elements for the Sidemenu is in the Home file. How to access this from this code, which is in the index.ios.js?
Thanks in advance.
I'm afraid that's not enough to make a conclusion. First of all, I need to see, how you compose your components. menuActions are available only for children components thru the context. Based on this code fragment I can't see how you make do it.
My suggestions:
- Check if you NavigatorIOS component is a children of your SideMenu component
- If you don't want to use NavigatorIOS as a children of a SideMenu, you may need something like a global store (you can use redux, for example) which will reflect a state of the SideMenu. Subscribing to this store from the right place (in any children of SideMenu), you'll be able to trigger menuActions from the place it'll be accessible.