AdminLTE icon indicating copy to clipboard operation
AdminLTE copied to clipboard

[BUG] The opened Treeview menu won't collapse when the Treeview was initiated more than once

Open galihsetyo opened this issue 2 years ago • 12 comments

Hi guys, I run Adminlte with Laravel using Inertiajs with Vue (SPA). the app is loading the adminlte on the login page so after logging in and being redirected to the dashboard the treeview needs to be initiated. I initiate the treeview with this:

$('[data-widget="treeview"]').each(function () { adminlte.Treeview._jQueryInterface.call($(this), 'init') })

and then the treeview is working properly.

but, the problem is when I refresh the page on the dashboard, the treeview can open but won't collapse.

I think it's because the treeview init runs more than once, first when the page refreshed and then when my code initiates the treeview again. how to check whether the treeview was initiated or not?, so I can condition my code to only run when the treeview is not initiated yet, or is there any other solution with this?, sorry for my bad English, I appreciate the help.

galihsetyo avatar Mar 14 '22 18:03 galihsetyo

Hello good Morning,

I have the same problem

=(

airtonctj avatar Apr 14 '22 13:04 airtonctj

No solution for that?

tiagocarvalhomk avatar Apr 29 '22 13:04 tiagocarvalhomk

It does happen because it's being ran twice. I had to hack a little, in order to make it work.

I noticed that this portion isn't running sometimes - i guess that's because the menu isn't rendered when this setup runs (i'm using React) image

But you can avoid that, and init by yourself whenever you want (just make sure you are checking everytime wether or not you have done a init before) image

wchar-t avatar May 06 '22 00:05 wchar-t

Hi, thanks for the reply guys. Finally, I got it to work by doing this, first I make a variable to check if the treeview has been loaded with the load.lte.treeview event and then when document.readyState is complete I check for the variable whether it is still undefined or not, only if it is still undefined then I initiate the treeview

let treeView;

$(window).on('load.lte.treeview', function (e) {
    treeView = e;
});

var readyStateCheckInterval = setInterval(function() {
    if (document.readyState === "complete") {
        clearInterval(readyStateCheckInterval);

        if(treeView == undefined) {
            $('[data-widget="treeview"]').each(function() {
                adminlte.Treeview._jQueryInterface.call($(this), 'init');
            })
        }
    }
}, 10);

galihsetyo avatar May 25 '22 02:05 galihsetyo

Update: there is still a problem with the code above, so here is my solution, so I make a function to initiate the TreeView in app.js:

let treeViewInit = function(){
    $('[data-widget="treeview"]').each(function () {
        adminlte.Treeview._jQueryInterface.call(
            $(this),
            "init"
        );
    });
}

and run that function with the Lodash once function:

let treeViewInitOnce = _.once(treeViewInit);

after that, I make a global property to call that Lodash function:

createInertiaApp({
    resolve: name => import(`./Pages/${name}`),
    title: title => title ? `${title} - Walisongo` : 'Walisongo',
    setup({ el, App, props, plugin }) {
        const myApp = createApp({ render: () => h(App, props) })
            .use(plugin)
            .mixin({ methods: {} })

        myApp.config.globalProperties.$treeViewInitOnce = treeViewInitOnce;

        myApp.mount(el);

        return myApp;
    },
})

and then I use that in my component:

let _this = this;

let treeView;
$(window).on('load.lte.treeview', function (e) {
    treeView = e;
});

var readyStateCheckInterval = setInterval(function() {
    if (document.readyState === "complete") {
        clearInterval(readyStateCheckInterval);

        if(treeView == undefined) {
            _this.$treeViewInitOnce();
        }
    }
}, 10);

galihsetyo avatar May 27 '22 01:05 galihsetyo

Hello

Where did you put that code?

let treeViewInitOnce = _.once(treeViewInit);

tiagocarvalhomk avatar May 27 '22 08:05 tiagocarvalhomk

Probably that line that I don't where is to insert is making the difference because to me in some circunstances ( that I don't know what they are) the menu accordion don't close. If I click on some item that has subitems it expandes but when i try to close it doesn't collapse. If I refresh the page everything works normally.

tiagocarvalhomk avatar May 30 '22 08:05 tiagocarvalhomk

Hi guys, sorry for the late response, I've made a fix from the AdminLTE side, just waiting for the merge request approval. You can check my commit above for the solution

galihsetyo avatar Jun 25 '22 05:06 galihsetyo

with the fix above you can now initiate the Treeview just like this:

$('[data-widget="treeview"]').each(function () {
    adminlte.Treeview._jQueryInterface.call($(this), "init");
});

I'm using Vue so I added that code on mounted section in the component

galihsetyo avatar Jun 25 '22 05:06 galihsetyo

Hello sir, i have meet this problem too and i have read but still don't understand. Can I have your code? thank you

Kokleng-Dev avatar Jul 04 '22 05:07 Kokleng-Dev

faced same problem while working with laravel & Vue 3 with inertiajs. found a fix for this after working it on 3 days, please checkout.

Add below lines in

import { onMounted, onUnmounted } from "vue";

onMounted( () => {
    $('[data-widget = "treeview"]').Treeview('init');
    // $('#mainSidebar').Treeview('init');

    console.log('Main sidebar mounted.');
})

onUnmounted(() => {
    $(document).on('click','[data-widget="treeview"] .nav-link', function (e) {
        e.stopImmediatePropagation();
    });

    console.log('Treeview stopped.');
})

Hope this works for others too.

ImCreator2 avatar Nov 15 '22 15:11 ImCreator2

Para que no se ejecute 2 veces solo agregen una variable global por ejemplo en algun contexto o equivalente que en este caso es isPrueba y SetIsPrueba y cuando se cargue el componente solo cambian la variable a false y ya no se ejecutará dos veces y por ende ya no provocará el error. import $ from "jquery"; import * as Adminlte from "adminlte";

const {user,isPrueba,setIsPrueba} = useAuth(); useEffect(()=>{ if(isPrueba){ $('[data-widget="treeview"]').each(function(){ Adminlte.Treeview._jQueryInterface.call($(this),'init');
}); } setIsPrueba(false); },[]);

Th3Joel avatar Nov 08 '23 05:11 Th3Joel