Home » Jquery » javascript – Collapse list menu alterations

javascript – Collapse list menu alterations

Posted by: admin February 22, 2020 Leave a comment

Questions:

I have a Rails app with bootstrap, and I’m using the following code in order to show the categories, subcategories and so on in a list collapse menu. As you can see I’m lopping through all of them in groups of three in order to show them in three different <div class="col-sm-4"> columns.

Everything shows just fine, but I would like to make a few alterations regrading the behavior and I don’t know how to implement them.

  1. When I click on a category the list collapses but with it all other three columns collapse too. How can I change this to collapse only the column I click on?

  2. When I click on a category the previously opened category doesn’t close down as it’s suppose to do. How can I make the previously opened category close down when a new one is clicked?

This is how the collapse list menu looks like, along with both the issues that I’m talking about:enter image description here

<% @categories.in_groups_of(3) do |category| %>
<div class="row">
  <% category.each do |subcategory| %>
    <div class="col-sm-4">
      <% if subcategory.present? %>
        <ul class="cl-start-wrap">
          <li class="cl-item">
            <div class="cl-label-wrap">
              <span class="cl-label-title"><%= subcategory.name %></span>
              <span class="cl-label-icon"></span>
            </div>
            <% unless subcategory.children.empty? %>
              <% subcategory.children.sort_by(&:name).each do |sub_1| %>
                <ul>
                  <li class="cl-item">
                    <div class="cl-label-wrap">
                      <span class="cl-label-title"><%= sub_1.name %></span>
                      <span class="cl-label-icon"></span>
                    </div>
                    <% unless sub_1.children.empty? %>
                      <% sub_1.children.sort_by(&:name).each do |sub_2| %>
                        <ul>
                          <li class="cl-item">
                            <div class="cl-label-wrap">
                              <span class="cl-label-title"><%= sub_2.name %></span>
                              <span class="cl-label-icon"></span>
                            </div>
                          </li>
                          <% unless sub_2.children.empty? %>
                            <% sub_2.children.sort_by(&:name).each do |sub_3| %>
                              <ul>
                                <li class="cl-item">
                                  <div class="cl-label-wrap">
                                    <span class="cl-label-title"><%= sub_3.name %></span>
                                    <span class="cl-label-icon"></span>
                                  </div>
                                </li>
                              </ul>
                            <% end %>
                          <% end %>
                        </ul>
                      <% end %>
                    <% end %>
                  </li>
                </ul>
              <% end %>
            <% end %>
          </li>
        </ul>
      <% end %>
    </div>
<% end %>
</div>
<% end %>
</div>

Styling:

$li-padding: 7px;
$li-padding-tools: 10px;
$cascade-padding: 25px;
$bg-level-1: #fafafa;
$bg-level-2: #ffffff;
$bg-level-3: #ffffff;
$color-tools: #9e9e9e;
$blue-color: #586181;
$arrow-color: #dadada;
$toggle-width: 1.5em;

.cl-start-wrap {
  list-style: none;
  padding: 0;
  margin: 0px;
  ul {
    list-style: none;
    padding: 0;
    margin: 0;
  }
  > li {
    > .cl-label-wrap {
      padding: $li-padding 0 $li-padding $cascade-padding*0;
      margin: 10px 0;
      background: $bg-level-1;
      &:hover {
        background: darken($bg-level-1, 5%);
      }
    }
   > ul > li {
      > .cl-label-wrap {
        padding: $li-padding 0 $li-padding $cascade-padding*1;
        background: $bg-level-2;
        &:hover {
          background: darken($bg-level-2, 5%);
        }
      }
      > ul > li {
        > .cl-label-wrap {
          padding: $li-padding 0 $li-padding $cascade-padding*2;
          background: $bg-level-3;
          &:hover {
            background: darken($bg-level-3, 5%);
          }
        }
      }
    }
  }
}

.cl-item {
  > ul {

  }
  > .cl-label-wrap {
    .cl-label-title {
      cursor: pointer;
      color: $blue-color;
      font-weight: bolder;
    }
    .cl-label-icon {
      cursor: pointer;
      text-align: center;
      &:before {
        cursor: pointer;
        display: inline-block;
        font: normal normal normal 14px/1 FontAwesome;
        font-size: inherit;
        text-rendering: auto;
        -webkit-font-smoothing: antialiased;
      }
    }
    .cl-label-tools {
      a {
        color: $color-tools;
        &:hover {
          color: darken($color-tools, 10%);
        }
      }
    }
  }
}
.cl-item:not(.cl-item-open) {
  > ul {
    display: none;
  }
  > .cl-label-wrap {
    .cl-label-icon {
      &:before {
        font-family: "Font Awesome 5 Free";
        color: $arrow-color;
        position: relative;
        content: "\f0da";
        font-weight: 900;
        font-size: 12px;
      }
    }
  }
}
.cl-item.cl-item-open {
  > .cl-label-wrap {
    .cl-label-icon {
      &:before {
        font-family: "Font Awesome 5 Free";
        color: $arrow-color;
        position: relative;
        content: "\f0d7";
        font-weight: 900;
        font-size: 12px;
      }
    }
  }
}
.cl-item.cl-item-no-sub {
  > .cl-label-wrap {
    .cl-label-title {
      cursor: default;
    }
    .cl-label-icon {
      &:before {
        content: "";
      }
    }
  }
}

// Label-Flexbox
.cl-label-wrap {
  display: table-cell;
  -ms-display: flex;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: flex-start;
  align-content: stretch;
  align-items: flex-start;
  .cl-label-title {
    order: 1;
    flex: 1 1 auto;
    align-self: auto;
  }
  .cl-label-icon {
    order: 0;
    flex: 0 1 $toggle-width;
    align-self: auto;
  }
  .cl-label-tools {
    order: 2;
    flex: 0 1 auto;
    align-self: auto;
    white-space: nowrap;
    padding: 0 $li-padding-tools;
  }
}

Javascript:

$('.cl-item:not(.cl-item-no-sub) > .cl-label-wrap .cl-label-title, .cl-item:not(.cl-item-no-sub) > .cl-label-wrap .cl-label-icon').click(function() {
        let parent = $(this).parent().parent();
        parent.siblings().removeClass("cl-item-open");
        parent.toggleClass('cl-item-open');
    }
);


$('.cl-item').each(function(){
    console.log ($(this).find('> ul').length);
    if ( $(this).find('> ul').length === 0 ) {
        $(this).addClass('cl-item-no-sub');
    }
})
How to&Answer: