Topic: Nested accordion trigger event show and hide to its parents

Alan Schwertner free asked 2 weeks ago


Expected behavior

The event should be triggered only in the target collapse component, not in its parent elements.

Actual behavior

All *.mdb.collapse events (show, hide, shown, and hidden) are propagated up the DOM, even if no data-mdb-target is defined.

Resources (screenshots, code snippets etc.)

https://jsfiddle.net/8fj74mpu/25/

// Even when filtering by the event target, the invoked event cannot be isolated to the correct accordion; it always propagates up the DOM.


$('.accordion-collapse').on('show.mdb.collapse', function (e) {
   if (e.target === this) {
      console.log('show: ', $(e.currentTarget).attr('id'));
   } 
});

DOM:


<!-- Nested accordion example -->
<div class="accordion" id="level_1">
  <div class="accordion-item">
    <h2 class="accordion-header" id="level_1_menu_1">
      <button
        data-mdb-collapse-init
        class="accordion-button collapsed"
        type="button"
        data-mdb-target="#level_1_collapse_1"
      >
        Menu #1
      </button>
    </h2>
    <div id="level_1_collapse_1" class="accordion-collapse collapse">
      <div class="accordion-body">

        <!-- Nest another accordion -->
        <div class="accordion" id="level_2">
          <div class="accordion-item">
            <h2 class="accordion-header" id="level_2_menu_1">
              <button
                data-mdb-collapse-init
                class="accordion-button collapsed"
                type="button"
                data-mdb-target="#level_2_collapse_1"
              >
                Submenu #1.1
              </button>
            </h2>
            <div id="level_2_collapse_1" class="accordion-collapse collapse">
              <div class="accordion-body">Content 1.1</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Kamila Pieńkowska staff answered 1 week ago


You may consider using existing treeview plugin: https://mdbootstrap.com/docs/standard/plugins/tree-view/


Alan Schwertner free answered 1 week ago


Thank you, Kamila.

I'm working on a multilevel tree menu, and I need to monitor both show and hide events because a menu can be opened or closed dynamically, even without a click. For example, an action like "reveal in menu" might need to open one accordion and close others.

I've reviewed the source code but haven't been able to figure out how the event-handler.js works internally.

Temporarily, I'm using this (not very elegant) solution, but it achieves the desired result since events on parent elements are propagated almost simultaneously:


const isolateCollapseEvent = {
    target: null,
    time: null,
    setTarget(target) {
        // Keep the first target
        if (!this.time || Date.now() - this.time > 50) {
            this.target = target;
            this.time = Date.now();
        }
    },
    getTarget() {
        return this.target;
    }
};

$('#tree-menu .accordion-collapse').on('show.mdb.collapse', (e) => {
    // Keep the first target because all events are captured almost simultaneously
    isolateCollapseEvent.setTarget(e.currentTarget);

    // Filter other targets
    if (isolateCollapseEvent.getTarget() !== e.currentTarget) {
        return;
    }

    // Perform the task
});

Kamila Pieńkowska staff answered 2 weeks ago


Use this as your listener:

   document.querySelectorAll('.accordion-button').forEach((btn) => {
    btn.addEventListener(
      'click',
      (e) => {
        console.log('capture click on:', e.currentTarget.dataset.mdbTarget);
      },
      true
    );
  });


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

  • ForumUser: Free
  • Premium support: No
  • Technology: MDB Standard
  • MDB Version: MDB5 9.1.0
  • Device: all
  • Browser: all
  • OS: all
  • Provided sample code: No
  • Provided link: Yes