jquerysassaccordiontimeline

jQuery accordion with animated timeline


I am working on an jQuery accordion with an animated timeline. It is almost done, but I am stuck with the line / animation on the last element. You can view a working example on: https://tjobtjob.nl/goldstine-sales-en-acquisitie-medewerker/. Please scroll down to the part called 'Sollicitatieprocedure', almost at the bottom.

It works well for all the steps, except for the last one. The last step also shows a line, but I want this line to disappear, so that the last element only has a colored dot.

This is my jQuery code:

jQuery.fn.simpleAccordion = function (options){
    options = $.extend ({start: 0, activeClass: 'active'}, options || {});

    return this.each (
        function(){
            var $this = $(this);
            var headers = $this.children('dt');

            headers.next().hide();
            headers.eq(options.start).addClass(options.activeClass).next().show();

            headers.bind ('click',
                function(){
                    var $this = $(this);

                    $this.addClass(options.activeClass)
                    .next().slideDown();

                    $this.siblings('.' + options.activeClass)
                    .removeClass(options.activeClass) 
                    .next().slideUp();
                }
            );
        }
    );
}
$('dl.stappen').simpleAccordion();

And this is the (s)CSS part:

dl.stappen{
    width: calc(100% - 45px);
    display: inline-block;
    margin: 50px 0 0;
    padding-left: 45px;
    position: relative;

    dt{
        font-weight: 500;
        font-size: 21px;
        margin-top: 15px;
        margin-bottom: 5px;
        cursor: pointer;
        position: relative;

        &:first-of-type{
            margin-top: 0;
        }
        .round{
            position: absolute;
            left: -45px;
            top: 50%;
            transform: translateY(-50%);
            width: 12px;
            height: 12px;
            background: #eee;
            border: 3px solid #dcae23;
            border-radius: 10px;
            z-index: 100;
        }
    }
    dd{
        font-size: 17px;
        line-height: 26px;
        position: relative;

        p{
            margin-bottom: 15px;

            &:last-child{
                margin-bottom: 0;
            }
        }
    }
    &:before{
        background: #dcae23;
        height: calc(100% - 24px);
        width: 3px;
        position: absolute;
        content: "";
        left: 8px;
        top: 8px;
    }
}

Thanks for helping!

Update: put it in a pen: https://codepen.io/bureaukamp/pen/ZEGoaQa


Solution

  • To do it in a better way & simple, the HTML structure needs to be updated a bit. Here I have wrapped each accordion item in a .item div.

    In the below, I have updated html, css & js to make it work at any dynamic variation of the content.

    jQuery.fn.simpleAccordion = function(options) {
      options = $.extend({
        start: 0,
        activeClass: "active",
        itemClass: "item"
      }, options || {});
    
      function updateView(activeItem) {
        var otherItems = activeItem.siblings();
        otherItems
          .removeClass(options.activeClass)
          .children('dd').slideUp();
    
        activeItem
          .addClass(options.activeClass)
          .children('dd').slideDown();
    
      }
    
      return this.each(function() {
        var $this = $(this);
    
        var itemSelector = "." + options.itemClass;
        var items = $(itemSelector, $this);
        updateView(items.eq(options.start));
    
        $this.on('click', itemSelector + '>dt', function() {
          var activeItem = $(this).closest(itemSelector);
          if (activeItem.hasClass(options.activeClass)) return;
          updateView(activeItem);
        });
    
      });
    };
    
    $("dl.stappen").simpleAccordion();
    dl.stappen {
      display: block;
      margin: 50px 0 0;
    }
    
    dl.stappen .item {
      padding-left: 45px;
      position: relative;
    }
    
    dl.stappen .item:before {
      background: black;
      width: 3px;
      bottom: -10px;
      position: absolute;
      content: "";
      left: 8px;
      top: 8px;
    }
    
    dl.stappen .item:last-of-type:before {
      display: none;
    }
    
    dl.stappen .item dt {
      font-weight: 500;
      font-size: 21px;
      margin-top: 15px;
      margin-bottom: 5px;
      cursor: pointer;
      position: relative;
    }
    
    dl.stappen .item dt:first-of-type {
      margin-top: 0;
    }
    
    dl.stappen .item dt .round {
      position: absolute;
      left: -45px;
      top: 50%;
      transform: translateY(-50%);
      width: 12px;
      height: 12px;
      background: #eee;
      border: 3px solid black;
      border-radius: 10px;
      z-index: 100;
    }
    
    dl.stappen .item dd {
      font-size: 17px;
      line-height: 26px;
      position: relative;
      margin-left: 40px;
    }
    
    dl.stappen .item dd p {
      margin-bottom: 15px;
    }
    
    dl.stappen .item dd p:last-child {
      margin-bottom: 0;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <dl class="stappen">
      <div class="item">
        <dt>
          <div class="round"></div>
          Step one
        </dt>
        <dd>
          Step one description. Step one description. Step one description. Step one description. Step one description. Step one description.
        </dd>
      </div>
      <div class="item">
        <dt>
          <div class="round"></div>
          Step two
        </dt>
        <dd>
          Step two description. Step two description. Step two description. Step two description. Step two description.
        </dd>
      </div>
      <div class="item">
        <dt>
          <div class="round"></div>
          Step three
        </dt>
        <dd>
          Step three description. Step three description. Step three description. Step three description. Step three description. Step three description.description.
        </dd>
      </div>
    </dl>