-
Notifications
You must be signed in to change notification settings - Fork 3
AngularJS: Example Deckster Directives
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.
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. See Gridster Documentation for additional options.
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 for 'deck' and 'initialized' variables
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;
});
}
};
})The instantiation of the Deckster Deck directive should call the Deckster Card directive using ng-repeat.
angular.module('app').directive('decksterCard', function ($parse, $q, $http, $timeout) {
return {
restrict: 'E',
require: ['^decksterDeck', 'decksterCard'],
controller: function ($scope, $compile) {Within the controller, there are several default functions that you may define if you wish. None of these are completely necessary.
// Default summaryContentHtml function
this.getSummaryContent = function (card, cb) {
$timeout(function() {
cb($compile('<div></div>')($scope));
});
};
// Default detailsContentHtml function
this.getDetailsContent = function (card, cb) {
$timeout(function() {
cb($compile('<div></div>')($scope));
});
};
// 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 function will set up your defaults as well as create the card itself.
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;
};
},The link function will then set up the event listeners.
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
});
});
});
}
});
}
};
})This directive should configure the Deckster popout functionality, if you wish you use that.
angular.module('app').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);
}
};
}]);