Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core | list-item: accordion behaviour #2764

Closed
simolev opened this issue Jul 8, 2020 · 2 comments
Closed

Core | list-item: accordion behaviour #2764

simolev opened this issue Jul 8, 2020 · 2 comments

Comments

@simolev
Copy link

simolev commented Jul 8, 2020

Environment
Onsen UI Version: onsenui v2.10.10 - 2019-07-29
Platform: Cordova 9.0.0 -> Android, Browser

Shortcoming / missing feature
Accordion and file explorer are two particular cases of lists: the first puts an emphasis on other elements closing when one is opened, the second on (possibly deeply) nested lists with a clear visual indication of whether an element is or can be expanded. Both have many use cases and are very useful in a number of applications, but Onsen UI does not currently support either out of the box, therefore requiring custom code that is in my opinion just boilerplate. I believe a programmer nowadays can expect this functionality to be provided by a library, and not having to code a pretty standard component.

Feature request
Creation of a new component, or addition of an attribute that specifies what else should happen when an expandable is actioned. It should be possible to choose between different behaviours towards same-level or child expandables.
Easy way to have customizable symbols such as +/- toggle on item expansion/collapse. It should be possible to place the symbol anywhere within the list-item, regardless of div.left, div.center or div.right. This should not break with nested lists: currently the wrong chevron is shown in sub-lists.

Sample code
In order to illustrate the desired behaviour, I'm posting a snippet of how I added this functionality.
To see it work, you'll have to paste this elsewhere: unfortunately the playground does not allow saving and sharing a link.

Non-working demo link

  • HTML
<ons-list-item expandable class="list-item level-0">
  <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
  <div class="center">Russians</div>
  <div class="right"></div>
  <div class="expandable-content">
    <ons-list-item expandable class="list-item level-1">
      <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
      <div class="center">Lev Nikolayevich Tolstoy</div>
      <div class="right"></div>
      <div class="expandable-content">
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Anna Karenina</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">War and Peace</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Resurrection</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
      </div>
    </ons-list-item>
    <ons-list-item expandable class="list-item level-1">
      <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
      <div class="center">Fyodor Mikhailovich Dostoevsky</div>
      <div class="right"></div>
      <div class="expandable-content">
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Crime and Punishment</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">The Idiot</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">The Brothers Karamazov</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
      </div>
    </ons-list-item>
    <ons-list-item expandable class="list-item level-1">
      <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
      <div class="center">Alexander Sergeyevich Pushkin</div>
      <div class="right"></div>
      <div class="expandable-content">
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Eugene Onegin</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Boris Godunov</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">The Stone Guest</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
      </div>
    </ons-list-item>
  </div>
</ons-list-item>
<ons-list-item expandable class="list-item level-0">
  <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
  <div class="center">French</div>
  <div class="right"></div>
  <div class="expandable-content">
    <ons-list-item expandable class="list-item level-1">
      <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
      <div class="center">Honoré de Balzac</div>
      <div class="right"></div>
      <div class="expandable-content">
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Lost Illusions</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Le Père Goriot</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Splendors and Miseries of Courtesans</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
      </div>
    </ons-list-item>
    <ons-list-item expandable class="list-item level-1">
      <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
      <div class="center">Jules Verne</div>
      <div class="right"></div>
      <div class="expandable-content">
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Michael Strogoff</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Journey to the Center of the Earth</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Twenty Thousand Leagues under the Seas</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
      </div>
    </ons-list-item>
    <ons-list-item expandable class="list-item level-1">
      <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
      <div class="center">Victor Hugo</div>
      <div class="right"></div>
      <div class="expandable-content">
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Les Misérables</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Le roi s'amuse</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Notre-Dame de Paris</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
      </div>
    </ons-list-item>
  </div>
</ons-list-item>
<ons-list-item expandable class="list-item level-0">
  <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
  <div class="center">English</div>
  <div class="right"></div>
  <div class="expandable-content">
    <ons-list-item expandable class="list-item level-1">
      <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
      <div class="center">Mark Twain</div>
      <div class="right"></div>
      <div class="expandable-content">
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">The prince and the Pauper</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">The Adventures of Tom Sawyer</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">A Connecticut Yankee in King Arthur's Court</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
      </div>
    </ons-list-item>
    <ons-list-item expandable class="list-item level-1">
      <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
      <div class="center">William Shakespeare</div>
      <div class="right"></div>
      <div class="expandable-content">
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Hamlet</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Romeo and Juliet</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Titus Andronicus</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
      </div>
    </ons-list-item>
    <ons-list-item expandable class="list-item level-1">
      <div class="left"><ons-icon icon="md-plus"></ons-icon></div>
      <div class="center">Jane Austen</div>
      <div class="right"></div>
      <div class="expandable-content">
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Sense and Sensibility</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Pride and Prejudice</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
        <ons-list-item tappable class="list-item level-2">
          <div class="left"></div>
          <div class="center">Emma</div>
          <div class="right"><ons-icon icon="md-forward"></ons-icon></div></ons-list-item>
      </div>
    </ons-list-item>
  </div>
</ons-list-item>
  • JS
document.addEventListener('click', function (event) {
    if (event.target.closest('.level-2')) {return;}
    const elem = event.target.closest('.list-item');
    if (elem.classList.contains('expanded')) {
        elem.querySelector('.ons-icon').classList.add('zmdi-plus');
        elem.querySelector('.ons-icon').classList.remove('zmdi-minus');
        elem.querySelectorAll('.list-item .expanded').forEach(function(item) {
            item.hideExpansion();
            item.querySelector('.ons-icon').classList.add('zmdi-plus');
            item.querySelector('.ons-icon').classList.remove('zmdi-minus');
        });
    } else {
        elem.querySelector('.ons-icon').classList.remove('zmdi-plus');
        elem.querySelector('.ons-icon').classList.add('zmdi-minus');
        if (elem.classList.contains('level-0')) {
            document.querySelectorAll('.list-item.expanded').forEach(function(item) {
                item.hideExpansion();
                item.querySelector('.ons-icon').classList.add('zmdi-plus');
                item.querySelector('.ons-icon').classList.remove('zmdi-minus');
            });
        } else if (elem.classList.contains('level-1')) {
            elem.closest('.level-0').querySelectorAll('.level-1.expanded').forEach(function(item) {
                item.hideExpansion();
                item.querySelector('.ons-icon').classList.add('zmdi-plus');
                item.querySelector('.ons-icon').classList.remove('zmdi-minus');
            });
        }
    }
}, false);
@github-actions
Copy link

This issue is stale because it has been open for 60 days with no activity. If there is no activity in the next 7 days, the issue will be closed.

@github-actions github-actions bot added the stale label Dec 13, 2022
@github-actions
Copy link

This issue was closed because it has been inactive for 7 days since being marked as stale. Please open a new issue if you believe you are encountering a related problem.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Dec 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants