close tab and activate previous


Topic: close tab and activate previous

MarcRohrer asked 3 years ago

Hi,

I have tabs with close buttons and want to activate the previous tab when tab to be deleted is active otherwise just close. Closing the current tab works fine, but not when some other tab is closed, as

element.firstElementChild.classList.contains('active') { element.previousElementSibling.firstElementChild.click() }

always is true. Even when

tab.addEventListener('click',closeTabListener,{capture: true})

capture is true.

How can I find out if it is not the current tab to be closed?

Thank you!

Marc


Michał Duszak staff answered 3 years ago

I guess you should delete an active class upon deleting a tab. Could you reproduce this behaviour in the snippet https://mdbootstrap.com/snippets/ so that I could see what exactly problem occurs right there?


MarcRohrer answered 3 years ago

I don't know what you bean by this! I prepared kind of a minimal example.

If you delete the currently selected tab, everything works fine. But the question is, how to delete a tab which is not current. By clicking on the close button the tab iss activated first and a check for the active class always returns true.

My code (easy, but still lengthy :-(

<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/3.6.0/mdb.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
    <link href="/static/css/betriebszeiten.css" rel="stylesheet">
    <link rel="icon" href="/static/img/betriebszeiten.svg">
    <body>
        <div class="container-fluid fixed-top" id="header">
            <ul class="nav nav-pills mb-3" id="applicationTabBar">
                <li class="nav-item" id="homeTabNavItem">
                    <a class="nav-link" id="homeTab" data-mdb-toggle="pill" href="#home">Tab 0<button type="button" class="btn-close opacity-0" id="homeCloseButton" disabled="disabled"></button>
                    </a>
                </li>
                <li class="nav-item" id="tab_1">
                    <a href="#pane_1" id="tab_element_1" tabid="1" class="nav-link" data-mdb-toggle="pill">Tab 1<button class="btn-close tabCloseButton" id="tab_close_1"></button>
                    </a>
                </li>
                <li class="nav-item" id="tab_4">
                    <a href="#pane_4" id="tab_element_4" tabid="4" class="nav-link" data-mdb-toggle="pill">Tab 2<button class="btn-close tabCloseButton" id="tab_close_4"></button>
                    </a>
                </li>
                <li class="nav-item" id="tab_5">
                    <a href="#pane_5" id="tab_element_5" tabid="5" class="nav-link active" data-mdb-toggle="pill">Tab 3<button class="btn-close tabCloseButton" id="tab_close_5"></button>
                    </a>
                </li>
            </ul>
        </div>
        <div class="container-fluid overflow-auto" id="appArea">
            <div class="tab-content overflow-auto" id="applicationTabPane">
                <div class="tab-pane show overflow-auto" id="home" role="tabpanel">
                    <h1>Pane 0</h1>
                </div>
                <div class="tab-pane show overflow-auto" id="pane_1" role="tabpanel">
                    <h1>Pane 1</h1>
                </div>
                <div class="tab-pane show overflow-auto" id="pane_4" role="tabpanel">
                    <h1>Pane 2</h1>
                </div>
                <div class="tab-pane show active overflow-auto" id="pane_5" role="tabpanel">
                    <h1>Pane 3</h1>
                </div>
            </div>
        </div>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/3.6.0/mdb.min.js"></script>
        <script>
            function closeTabListener(event)
            {
                const e = event.srcElement.parentElement.parentElement
                e.firstElementChild.classList.contains('active')
                {
                    e.previousElementSibling.firstElementChild.click()
                }
                document.getElementById(e.id).remove()
                document.getElementById(e.id.replace('tab','pane')).remove()
            }

            let element
            element = document.getElementById('homeCloseButton')
            element.addEventListener('click',closeTabListener,{capture: true})
            element = document.getElementById('tab_close_1')
            element.addEventListener('click',closeTabListener,{capture: true})
            element = document.getElementById('tab_close_4')
            element.addEventListener('click',closeTabListener,{capture: true})
            element = document.getElementById('tab_close_5')
            element.addEventListener('click',closeTabListener,{capture: true})
        </script>
    </body>
</head>


Michał Duszak staff answered 3 years ago

Hello. Thank you for submitting the code, now I can see what's going on there! First of all, this code needed a complete refactor. You need to store the information about the previous tab somewhere, and handle it as an instance, or, at least, an element. Fortunately, MDB provides hide.mdb.tab event. Then you can provide a condition upon closing a tab - whether to choose previously opened tab, or go to the home tab. I prepared a small refactor for you with working code - it begins with Home Tab opened. If you close not current Tab - the current Tab stays active. When you close a current Tab - it goes to the previously opened Tab . https://mdbootstrap.com/snippets/standard/m-duszak/3300996#js-tab-view


MarcRohrer answered 3 years ago

perfect, thank you!
Dynamic tabbing would be agreat extension to the standard mdb!
Very rarely available :-(


MarcRohrer answered 3 years ago

unfortunately in the refactor my already working code went out the window :-(
i.e got replaced by switchToHomeTab()
if the current tab is to be removed the previous in the tabbar should be selected of course

But anyhow, the code does not work with my dynamically created tabs.
None of the callbacks are actually called...
When creating a tab dynamically, what further actions have to be taken to register it with mdb?


Michał Duszak staff answered 3 years ago

Try to run

setListenersOnTabs();
setListenersOnCloseButtons();

right after you dynamically add a new Tab. Did it work for you?


MarcRohrer answered 3 years ago

unfortunately not.

It only works for the tab that is there when the page is loaded. I generate the html for the tab from javascript. Do I also have to call a function, that generates the mdb instance for that tab?

I logged it out. The lister is created every time a new tab is inserted as you say. But not called when I switch between dynamically created tabs. Only when switching to the tab, that is there, when I load the page is loaded, hidden on the dynamically generated tab is called, but not when switching back to the generated tab.

Side question: why is this necessary? document.addEventListener('hidden.mdb.tab'... installes a handler for the document and should work for everything in it, right? Actually, I think, this is not good, as there is multiple handlers! One should suffice!

With Materialize I had this working in a day :-(


Michał Duszak staff commented 3 years ago

You can reset listeners - remove and then add. So that when you add anything dynamically, everything will get it's own listener. According to document.addEventListener... you don't have to listen to the whole document. You can listen to the list of tabs - it just seeks if any tab was chosen, and saves information about that.

https://mdbootstrap.com/snippets/standard/m-duszak/3303304#js-tab-view


MarcRohrer answered 3 years ago

This is VERY disappointing!

I mean, it kinda works in your example, but this is obviously to usable in an application. So I copy it onto my system and start experimenting.

I remove all but the first tab as and it already doesn't work anymore. Clicking on a newly added button there is an exception in selector-engine.js

Not to talk about integrating it in my own program, where still the hidden.mdb.tab listeners are not called, even when I previously remove the existing listeners as you suggested. I suspect there is a functionality, I know nothing about...

Suspecting, it might have something to do with the way you added the elements, I copied your function to add tabs, but then I also get an exception in the selector engine, but on a different line.

Could you please provide me with information, how to resolve this issue. I don't understand, what the problem is! Thank you.


Michał Duszak staff answered 3 years ago

Hello, let's reference a new snippet. I did a little refactor so that it will be easier for you to migrate it into your project.

Clicking on a newly added button there is an exception in selector-engine.js

This was happening because of the href attribute of newly created Tab. Previously I left a placeholder there - it was referencing a non-existent element. In the 9th line i created something like newTab.innerHTML = <a href="#pane_4" ... .... Now every dynamically created Tab will be referencing this pane. So you need to decide what content will be referenced by new Tabs. I semi-handled it, as there is a counter variable added. Each Tab gets new ID, which you can use to create new pane with the same ID for the reference. To dynamically use incrementing ID in Tab's href attribute, simply set it in the 9th line to <a href=#pane_${counter}. If href selector will point to non-existent element - the selector-engine error will occur.

the hidden.mdb.tab listeners are not called

I checked on that, and it was because of Tabs being created dynamically. It would be too much of a struggle to get this event to work in this case, so I replaced it with a simple 'click' event.

Please see if this snippet works on your machine https://mdbootstrap.com/snippets/standard/m-duszak/3314210#js-tab-view

And tell me what further struggle do you occur transfering it into your project.

Keep Coding,

Michał Duszak


Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue
  • User: Free
  • Premium support: No
  • Technology: MDB Standard
  • MDB Version: MDB5 3.9.0
  • Device: PC
  • Browser: Chrome
  • OS: Windows
  • Provided sample code: No
  • Provided link: No