question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Inertiajs workaround dropdown

See original GitHub issue

Hello,

I use this sidebar with inertiajs in a laravel project, if you tried using this, you’ll notice the active state in sidebar no longer works, and the dropdowns no longer / childs do not show.

My workaround this is as follows: for siderbar-menu props: :showChild="true"

this will show all dropdowns opened. So from here, its all dom manipulation

    beforeUpdate() {
        const parent_vsm_item = document.getElementsByClassName('vsm--item vsm--item_open')
        for(var i=0; i<parent_vsm_item.length; i++){
            // remove the arrow open
            const parent_vsm_item_arrow = parent_vsm_item[i].querySelector('.vsm--arrow_open')
            parent_vsm_item_arrow.classList.remove(this.parents_div.parent_highlight_vsm_arrow)

            // hide dropdown with display none
            const child_dropdown = parent_vsm_item[i].querySelector('.vsm--dropdown');
            child_dropdown.style.display = "none"

            // remove parent background hightlight
            parent_vsm_item[i].classList.remove(this.parents_div.parent_hightlight_vsm_item)
        }

        let open_parent = false

        this.menu.forEach((parent) => {
            if(parent.child != undefined) {
                parent.child.forEach((child_item) => {
                    if (child_item.to == document.URL) {
                        let [parent_id, child_id] = child_item.cid.split('-')
                        if(open_parent == false) {
                            this.parents_div.list[parent_id].classList.add(this.parents_div.parent_hightlight_vsm_item)
                            this.parents_div.list[parent_id].querySelector('.vsm--arrow').classList.add(this.parents_div.parent_highlight_vsm_arrow)
                            this.parents_div.list[parent_id].querySelector('.vsm--dropdown').style.display = 'block'
                            open_parent = true
                        }
                        parent.class = "vsm--item_open"
                        child_item.class = "vsm--link_active"
                    } else {
                        child_item.class = ""
                    }
                })
            } else {
                if (parent.to == document.URL) {
                    parent.class = "vsm--link_active"
                } else {
                    parent.class = ""
                }
            }
        })
    },
    .....
       methods: {
        inertia_navigate(event, item, node) {
            if(item.child instanceof Array) {
                if(!this.parents_div.list[item.id].classList.contains(this.parents_div.parent_hightlight_vsm_item)) {
                    this.parents_div.list[item.id].classList.add(this.parents_div.parent_hightlight_vsm_item)
                    this.parents_div.list[item.id].querySelector('.vsm--arrow').classList.add(this.parents_div.parent_highlight_vsm_arrow)
                    this.parents_div.list[item.id].querySelector('.vsm--dropdown').style.display = 'block'
                } else {
                    this.parents_div.list[item.id].classList.remove(this.parents_div.parent_hightlight_vsm_item)
                    this.parents_div.list[item.id].querySelector('.vsm--arrow').classList.remove(this.parents_div.parent_highlight_vsm_arrow)
                    this.parents_div.list[item.id].querySelector('.vsm--dropdown').style.display = 'none'
                }
            }
            // do not set `to` prop on dropdown parent, only set it on childs. Only childs should navigate
            if(item.to != undefined) {
                this.$inertia.visit(item.to)
            }
        },
    },
    computed: {
            parents_div: function () {
            return {
                list: document.querySelectorAll('.vsm--list > .vsm--item'),
                parent_hightlight_vsm_item: "vsm--item_open",
                parent_highlight_vsm_arrow: "vsm--arrow_open"
            }
        }
    }

I also use a menu.js which contains the menu items, where the childs also requires the parent id and child id. The child id is not used, but perhaps it will be useful later… The child id will contain the parent id so that you can easily get to the parent example:

        {
            id: 7,
            icon: 'icon-settings',
            title: 'Settings',
            class: "",
            child: [
                {
                    cid: "7-8",
                    to: route('admin.settings'),
                    title: 'General Settings',
                    class: "",
                    icon: 'icon-child',
                },
             ]
         },

I know this is just an ugly workaround hack, but I have no idea if its possible to control the dropdown in any other way, if its possible, please do share.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
yaminnccocommented, Dec 29, 2020

i released a new patch that should fix the active state on init, the only thing left is when the url change you need to manually call onRouteChange, with inertia something like this can work:

const customLink = (props, { slots }) => {
  const { item, ...attrs } = props
  const onRouteChange = inject('onRouteChange')
  return h(link, {
    ...attrs,
    onFinish: () => {
      onRouteChange()
    },
  }, slots.default)
}

and make sure to use persistent layouts to prevent the sidebar from re-rendring whenever a link is clicked

1reaction
yaminnccocommented, Dec 26, 2020

what problem did you face did you use the prop above? you need to make a custom link component and register it globaly

import { createApp, h } from 'vue'

const customLink = (props, { slots }) => {
  const { item, ...attrs } = props
  return h('inertia-link', { ...attrs }, slots.default())
}

const app = createApp(App)
app.component('custom-link', customLink)

then config the sidebar with the prop <sidebar-menu :link-component-name="'custom-link'"/>

Read more comments on GitHub >

github_iconTop Results From Across the Web

Search Dropdown Modal with a Headless UI -Laravel Tutorial
In this video, we are going to create a search dropdown modal with a headless UI.Laravel Inertiajs tutorial.Laravel Vuejs Tutorial.
Read more >
pingcrm/Dropdown.vue at master · inertiajs ...
A demo application to illustrate how Inertia.js works. - pingcrm/Dropdown.vue at master · inertiajs/pingcrm.
Read more >
If the value in one dropdown changed, how to reload ...
If the value in one dropdown changed, how to reload the values for the second dropdown? How to do Partial Reload in InertiaJs....
Read more >
Build Modern Laravel Apps Using Inertia.js: Active Links
Let's fix that by leveraging both the $page.url and $page.component properties that Inertia provides to us. View this lesson's source code.
Read more >
Forms
Forms. Submitting forms. While it's possible to make classic form submissions with Inertia, it's not recommended, as they cause full page reloads.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found