Skip to content

AngularJS: Example Deckster Directives

baileyreed39 edited this page Aug 12, 2016 · 8 revisions

Angular Directives for Deckster

A custom Angular directive will allow you to insert one piece of HTML into another via an HTML tag or attribute. See here for an explanation of Angular directives. This definition defines a custom directive called 'decksterDeck' and attaches it to a module called 'app,' which should be the module in your app where you wish to place the Deckster deck.

Deckster Deck

angular.module('app').directive('decksterDeck', function ($parse, $timeout) {

Then, within this function, you might want to define your defaults for Gridster, the jQuery plug-in that Deckster is based on. These defaults can be overridden as you configure each deck.

        var defaults = {
            gridsterOpts: {
                max_cols: 4, // max columns
                widget_margins: [10, 10], // x, y margins between each card
                widget_base_dimensions: ['auto', 250], // x, y dimensions of rows and columns. 'auto' will set width to be responsive to page size
                responsive_breakpoint: 850 // responsiveness of when cards change position when one card is dragged
            }
        };

Then define the directive itself:

        return {
            restrict: 'EA', // restricts directive to be usable via element tag and attribute
            replace: true, // 
            scope: { // sets two-way binding between parent and isolated scope
                deck: '=',
                initialized: '='
            },

Preferably put this template into a separate HTML file and refer to using templateUrl instead of template.

            template: '<div class="deckster-deck-wrapper"><div class="deckster-deck" deck-options="deck"><deckster-card ng-repeat="cardOpts in deck.cards" card-options="cardOpts"></deckster-card></div></div>',

These controller functions will properly set up your Deckster deck:

            controller: function($scope) {
                $scope.deckInitialized = false;

                $scope.$on('deckster:resize', function () {
                    if ($scope.deckster) {
                        $timeout(function () {
                            $scope.deckster.$gridster.recalculate_faux_grid();
                        });
                    }
                });

                this.addCard = function (card, callback) {
                    $scope.deckster.addCard(card, function (card) {
                        if (callback) callback(card);
                    });
                };

                this.init = function (element, opts) {
                    $scope.deckster = $(element).deckster(opts).data('deckster');
                    $scope.deckInitialized = true;
                };
            },
            link: function (scope, element, attrs, ctrl) {
                var deckOptions = $.extend(true, {}, defaults, scope.deck);
                var $deckEl = $(element).find('.deckster-deck');

                scope.$watch('initialized', function(init) {
                    if (init && !scope.deckInitialized) {
                        ctrl.init($deckEl, deckOptions);
                    }
                });

                scope.$on('$destroy', function() {
                    scope.deckster.destroy();
                    scope.deckInitialized = false;
                });
            }
        };
})

Deckster Card

    .directive('decksterCard', function ($parse, $q, $http, $timeout) {


        return {
            restrict: 'E',
            require: ['^decksterDeck', 'decksterCard'],
            controller: function ($scope, $compile) {
                // Default leftControlsHtml function
                this.getLeftControlsContent = function (card, cb) {
                    $timeout(function() {
                        cb($compile('<div></div>')($scope));
                    });
                };

                // Default rightControlsHtml function
                this.getRightControlsContent = function (card, cb) {
                    $timeout(function() {
                        cb($compile('<div></div>')($scope));
                    });
                };

                // Default centerControlsHtml function
                this.getCenterControlsContent = function (card, cb) {
                    $timeout(function() {
                        cb($compile('<div></div>')($scope));
                    });
                };

                this.onReload = function (card) {
                    console.log('card reloaded', card);
                };

                this.onResize = function (card) {
                    console.log('card resized', card);
                };

                this.onExpand = function (card)  {
                    console.log('card expanded', card);
                };

                this.scrollToCard = function () {
                    $scope.card.scrollToCard();
                };

                this.toggleCard = function () {
                    // $scope.card.hidden ? $scope.card.showCard() : $scope.card.hideCard();
                };

                this.setUpCard = function (cardOpts) {
                    if(!cardOpts.summaryViewType && !cardOpts.detailsViewType) {
                        cardOpts.summaryContentHtml = cardOpts.summaryContentHtml || this.getSummaryContent;
                        cardOpts.detailsContentHtml = cardOpts.detailsContentHtml || this.getDetailsContent;
                        cardOpts.onResize = cardOpts.onResize || this.onResize;
                        cardOpts.onReload = cardOpts.onReload || this.onReload;
                    }

                    cardOpts.showFooter = false;
                    cardOpts.leftControlsHtml = this.getLeftControlsContent;
                    cardOpts.rightControlsHtml = this.getRightControlsContent;
                    cardOpts.centerControlsHtml = this.getCenterControlsContent;

                    $scope.$on('deckster-card:scrollto-' + cardOpts.id, this.scrollToCard);
                    $scope.$on('deckster-card:toggle-' + cardOpts.id, this.toggleCard);

                    return cardOpts;
                };

            },
            link: function (scope, element, attrs, ctrls) {
                var deckCtrl = ctrls[0];
                var cardCtrl = ctrls[1];

                var cardOpts = $parse(attrs.cardOptions || {})(scope);

                scope.$watch('deckInitialized', function (initialized) {
                    if (initialized) {
                        deckCtrl.addCard(cardCtrl.setUpCard(cardOpts), function (card) {
                            scope.card = card;

                            // When the deck is resize resize this card as well
                            scope.$on('deckster:resize', function () {
                                // TODO code to resize cards
                            });

                            scope.$on('deckster:redraw', function () {
                                $timeout(function () {
                                    // TODO code to redraw cards
                                });
                            });
                        });
                    }
                });
            }
        };
    })

<deckster-popout></deckster-popout>

    .directive('decksterPopout', ['$injector', '$compile', '$http', 'Deckster', function($injector, $compile, $http, Deckster) {
        return {
            restrict: 'E',
            link: function(scope, element) {
                var cardId, section;

                var $routeParams = $injector.get('$routeParams');
                cardId = $routeParams.id;
                section = $routeParams.section;


                var getSummaryTemplate = function(cardConfig, cb) {
                    // Not using the cardConfig here but you could use it to make request
                    $http.get('partials/testSummaryCard.html').success(function(html) {
                        if (cb) cb($compile(html)(scope));
                    });
                };

                var getDetailsTemplate = function(cardConfig, cb) {
                    // Not using the cardConfig here but you could use it to make request
                    $http.get('partials/testDetailsCard.html').success(function (html) {
                        if (cb) cb($compile(html)(scope));
                    });
                };

                // Get card config from server or angular constants using cardId
                var cardConfig =  {
                    title: 'Photos',
                    id: 'photoCard',
                    summaryContentHtml: getSummaryTemplate,
                    detailsContentHtml: getDetailsTemplate,
                    position: {
                        size_x: 1,
                        size_y: 1,
                        col: 1,
                        row: 1
                    }
                };

                Deckster.generatePopout(element, cardConfig, section);
            }
        };
    }]);

Clone this wiki locally