EricWVGG / AngularSlideables

A "pure" Angular implementation of jQuery-style toggleSlide().
MIT License
151 stars 43 forks source link

Only show one open slideable at a time #16

Open helsont opened 9 years ago

helsont commented 9 years ago

Hi,

I hacked together this code to only show one slideable at time. I tried calling 'click' on the element that i needed, but that didn't work. So, in my hurry, I resorted to not-so-great programming, but it works and I hope it helps someone (or someone can help me improve this!).

var objects = [];
angular.module('angularSlideables', [])
.directive('slideable', function () {
    return {
        restrict:'C',
        compile: function (element, attr) {
            // wrap tag

            var contents = element.html();
            element.html('<div class="slideable_content" style="margin:0 !important; padding:0 !important" >' + contents + '</div>');

            return function postLink(scope, element, attrs) {
                // default properties
                attrs.duration = (!attrs.duration) ? '1s' : attrs.duration;
                attrs.easing = (!attrs.easing) ? 'ease-in-out' : attrs.easing;
                element.css({
                    'overflow': 'hidden',
                    'height': '0px',
                    'transitionProperty': 'height',
                    'transitionDuration': attrs.duration,
                    'transitionTimingFunction': attrs.easing
                });
            };
        }
    };
})
.directive('slideToggle', function() {

    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var target, content;

            var holder = {
                element: element, 
                attrs: attrs
            };
            objects.push(holder);

            attrs.expanded = false;

            element.bind('click', function() {
                for(var i = 0; i < objects.length; i ++) {
                    if (objects[i].element != element && objects[i].attrs.expanded) {
                        // Because the click does not fire...
                        // objects[i].element[0].click();
                        var ptarget = document.querySelector(objects[i].attrs.slideToggle);
                        var pcontent = ptarget.querySelector('.slideable_content');

                        if(!objects[i].attrs.expanded) {
                            pcontent.style.border = '1px solid rgba(0,0,0,0)';
                            var y = pcontent.clientHeight;
                            pcontent.style.border = 0;
                            ptarget.style.height = y + 'px';
                        } else {
                            ptarget.style.height = '0px';
                        }
                        objects[i].attrs.expanded = !objects[i].attrs.expanded;
                    }
                }

                if (!target) target = document.querySelector(attrs.slideToggle);
                if (!content) content = target.querySelector('.slideable_content');

                if(!attrs.expanded) {
                    content.style.border = '1px solid rgba(0,0,0,0)';
                    var y = content.clientHeight;
                    content.style.border = 0;
                    target.style.height = y + 'px';
                } else {
                    target.style.height = '0px';
                }
                attrs.expanded = !attrs.expanded;
            });
        }
    }
});
JayWIlsonJr commented 8 years ago

Thank you for sharing your solution. I am pressed for time, and this worked exactly the way I wanted!

EricHerlitz commented 7 years ago

Awesome, well done @helsont