Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angularjs bootstrap collapse horizontally

How can I make angular bootstrap collapse, collapsing horizontally? Something like here?

like image 658
Tino Avatar asked Mar 26 '14 08:03

Tino


1 Answers

You are going to need to either modify the collapse directive or create a new directive based on that to handle collapsing the width only. I would suggest the latter unless you want all of the collapse directives in your app to collapse horizontally.

Please see the Plunk here demonstrating the use of a collapse-with directive based on the bootstrap collapse directive.

On top of changing the directive you will need to add new classes to handle the transition and set a width for the element you want to collapse (you could also change the directive to collapse to and from 100% width, not sure on your use case but hopefully you get the idea):

.well {
  width: 400px;  
}

.collapsing-width {
  position: relative;
  overflow: hidden;
  -webkit-transition: width 0.35s ease;
    -moz-transition: width 0.35s ease;
    -o-transition: width 0.35s ease;
    transition: width 0.35s ease;
}

And the directive just requires a few changes to the expand, expandDone, collapse and collapseDone functions and adding/removing the css class above as follows:

.directive('collapseWidth', ['$transition', function ($transition, $timeout) {

    return {
      link: function (scope, element, attrs) {

        var initialAnimSkip = true;
        var currentTransition;

        function doTransition(change) {
          var newTransition = $transition(element, change);
          if (currentTransition) {
            currentTransition.cancel();
          }
          currentTransition = newTransition;
          newTransition.then(newTransitionDone, newTransitionDone);
          return newTransition;

          function newTransitionDone() {
            // Make sure it's this transition, otherwise, leave it alone.
            if (currentTransition === newTransition) {
              currentTransition = undefined;
            }
          }
        }

        function expand() {
          if (initialAnimSkip) {
            initialAnimSkip = false;
            expandDone();
          } else {
            element.removeClass('collapse').addClass('collapsing-width');
            doTransition({ width: element[0].scrollWidth + 'px' }).then(expandDone);
          }
        }

        function expandDone() {
          element.removeClass('collapsing-width');
          element.addClass('collapse in');
          element.css({width: 'auto'});
        }

        function collapse() {
          if (initialAnimSkip) {
            initialAnimSkip = false;
            collapseDone();
            element.css({width: 0});
          } else {
            // CSS transitions don't work with height: auto, so we have to manually change the height to a specific value
            element.css({ width: element[0].scrollWidth + 'px' });
            //trigger reflow so a browser realizes that height was updated from auto to a specific value
            var x = element[0].offsetHeight;

            element.removeClass('collapse in').addClass('collapsing-width');

            doTransition({ width: 0 }).then(collapseDone);
          }
        }

        function collapseDone() {
          element.removeClass('collapsing-width');
          element.addClass('collapse');
        }

        scope.$watch(attrs.collapseWidth, function (shouldCollapse) {
          if (shouldCollapse) {
            collapse();
          } else {
            expand();
          }
        });
      }
    };
}]);

You may need to tweak the css a little to ensure the spacing and margins are consistent with your use cases but hopefully that helps.

like image 56
adamK Avatar answered Oct 06 '22 23:10

adamK