Last active
August 29, 2015 13:57
-
-
Save consoledotblog/9486040 to your computer and use it in GitHub Desktop.
AngularJS - Responsive Transclusion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Simple directive template --> | |
<!-- This will always be hidden --> | |
<div class="sampleDirectiveTemplate" ng-if="false"> | |
<!-- ng-src will never be processed and the image won't download --> | |
<img ng-src="pic.png" /> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Directive template that assumes a shouldShow property is defined on the model --> | |
<!-- This will always be hidden if our directive code tells it to be --> | |
<div class="sampleDirectiveTemplate" ng-if="responsiveDirective.shouldShow"> | |
<!-- ng-src will not download unless shouldShow equates to false --> | |
<img ng-src="pic.png" /> | |
<!-- ng-transclude and any content meant to be transcluded will | |
not be processed if shouldShow equates to false --> | |
<div ng-transclude></div> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Mappings to the twitter bootstrap 3 breakpoints */ | |
var breakpoints = [ | |
{name: "xs", lowPixel: 0, highPixel: 767}, | |
{name: "sm", lowPixel: 768, highPixel: 991}, | |
{name: "md", lowPixel: 992, highPixel: 1199}, | |
{name: "lg", lowPixel: 1200, highPixel: Infinity} | |
]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Reading attributes from a directive */ | |
function controller($scope, $element, $attrs) { | |
... | |
var includedatArray = $attrs.includedat ? JSON.parse($attrs.includedat) : undefined; | |
var selectedBreakpoints = breakpoints.filter(function(breakpoint) { | |
return _.contains(includedatArray, breakpoint.name); | |
}); | |
... | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Reading css classes from a directive */ | |
function controller($scope, $element, $attrs) { | |
... | |
var classArray = $attrs.class.split(" "); | |
var selectedBreakpointsByClass = _.clone(breakpoints), | |
breakpointNamesToShow = _.chain(classArray) | |
.intersection(bootstrapVisibleClasses) | |
.map(function(visibleClass) { | |
return visibleClass.split("-")[1]; | |
}) | |
.value(), | |
breakpointNamesToHide = _.chain(classArray) | |
.intersection(bootstrapHiddenClasses) | |
.map(function(hiddenClass) { | |
return hiddenClass.split("-")[1]; | |
}) | |
.value(); | |
//hidden-xx > precendence than visible-xx in twbs. | |
//If there is a hidden class present, visible classes don't matter. | |
if(breakpointNamesToHide.length > 0) { | |
selectedBreakpointsByClass = _.filter(selectedBreakpointsByClass, function(bp) { | |
if(_.contains(breakpointNamesToHide, bp.name)) { | |
return false; //want to hide this one | |
} | |
return true; | |
}); | |
} | |
else if(breakpointNamesToShow.length > 0) { | |
selectedBreakpointsByClass = _.filter(selectedBreakpointsByClass, function(bp) { | |
if(_.contains(breakpointNamesToShow, bp.name)) { | |
return true; //want to show this one | |
} | |
return false; | |
}); | |
} | |
... | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Call a method 'handleResize' whenever the viewport size changes */ | |
angular.element(window).on('resize', handleResize); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Responsive directive */ | |
angular.module('myApp.responsiveDirective', []) | |
.directive('responsive', function($timeout) { | |
/** | |
* These match up with the twitter bootstrap 3 breakpoints | |
* @type {Array} | |
*/ | |
var breakpoints = [ | |
{name: "xs", lowPixel: 0, highPixel: 767}, | |
{name: "sm", lowPixel: 768, highPixel: 991}, | |
{name: "md", lowPixel: 992, highPixel: 1199}, | |
{name: "lg", lowPixel: 1200, highPixel: Infinity} | |
]; | |
var bootstrapVisibleClasses = ["visible-xs", "visible-sm", "visible-md", "visible-lg"], | |
bootstrapHiddenClasses = ["hidden-xs", "hidden-sm", "hidden-md", "hidden-lg"]; | |
function getSelectedBreakpointsByTWBSClasses(classArray) { | |
var selectedBreakpointsByClass = _.clone(breakpoints), | |
breakpointNamesToShow = _.chain(classArray) | |
.intersection(bootstrapVisibleClasses) | |
.map(function(visibleClass) { | |
return visibleClass.split("-")[1]; | |
}) | |
.value(), | |
breakpointNamesToHide = _.chain(classArray) | |
.intersection(bootstrapHiddenClasses) | |
.map(function(hiddenClass) { | |
return hiddenClass.split("-")[1]; | |
}) | |
.value(); | |
//hidden-xx > precendence than visible-xx in twbs. If there is a hidden class present, visible classes don't matter. | |
if(breakpointNamesToHide.length > 0) { | |
selectedBreakpointsByClass = _.filter(selectedBreakpointsByClass, function(bp) { | |
if(_.contains(breakpointNamesToHide, bp.name)) { | |
return false; //want to hide this one | |
} | |
return true; | |
}); | |
} | |
else if(breakpointNamesToShow.length > 0) { | |
selectedBreakpointsByClass = _.filter(selectedBreakpointsByClass, function(bp) { | |
if(_.contains(breakpointNamesToShow, bp.name)) { | |
return true; //want to show this one | |
} | |
return false; | |
}); | |
} | |
return selectedBreakpointsByClass; | |
} | |
function getSelectedBreakpointsByAttribute(includedatArray) { | |
var selectedBreakpoints = breakpoints.filter(function(breakpoint) { | |
return _.contains(includedatArray, breakpoint.name); | |
}); | |
return selectedBreakpoints; | |
} | |
/** | |
* | |
* If there is an includedat attribute, the directive will use that to determine where this directive's | |
* content appears at. | |
* If there is no attribute, the directive will look for twbs hidden/visible classes and use those | |
* to determine the inclusion of content. | |
* @param $scope | |
* @param $element | |
* @param $attrs | |
* @param $attrs.includedat {Array} Array of strings matching the twitter bootstrap breakpoint keys | |
*/ | |
function controller($scope, $element, $attrs) { | |
$scope.responsiveDirectiveModel = { | |
shouldShow: false | |
}; | |
var selectedBreakpoints, | |
includedatArray = $attrs.includedat ? JSON.parse($attrs.includedat) : undefined; | |
if(includedatArray) { | |
selectedBreakpoints = getSelectedBreakpointsByAttribute(includedatArray); | |
} else { | |
selectedBreakpoints = getSelectedBreakpointsByTWBSClasses($attrs.class.split(" ")); | |
} | |
/** | |
* Called everytime the window is resized. The current window width is checked against the breakpoints | |
* specified via the 'includedat' attribute on the directive. | |
*/ | |
function handleResize() { | |
console.log('shouldshow: ' + $scope.responsiveDirectiveModel.shouldShow); | |
var originalShouldShow = $scope.responsiveDirectiveModel.shouldShow, | |
newShouldShow; | |
//Check to see if any of the selected breakpoints contain the current width | |
var currentWidthMatchesASelectedBreakpoint = _.some(selectedBreakpoints, function(breakpoint) { | |
if((window.innerWidth >= breakpoint.lowPixel) && | |
(window.innerWidth <= breakpoint.highPixel)) { | |
return true; | |
} | |
}); | |
//Match occurs, so load up the templateid passed in through an attribute | |
if(currentWidthMatchesASelectedBreakpoint) { | |
newShouldShow = true; | |
} else { | |
newShouldShow = false; | |
} | |
if(originalShouldShow !== newShouldShow) { | |
$timeout(function() { | |
$scope.responsiveDirectiveModel.shouldShow = newShouldShow; | |
}); | |
} | |
} | |
angular.element(window).on('resize', handleResize); | |
//kick one check off right away | |
handleResize(); | |
} | |
return { | |
restrict: 'A', | |
templateUrl: 'directives/responsive/responsive.tpl.html', | |
replace: true, | |
transclude: true, | |
scope: true, | |
controller: controller | |
}; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Using the responsive directive with attributes --> | |
<div responsive includedat="['xs', 'lg']"> | |
<!-- This will only be shown and processed in extra small and large viewports --> | |
<img ng-src="pic.png" /> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- using the responsive directive with twos classes --> | |
<div responsive class="visible-xs visible-lg"> | |
<!-- This will only be shown and processed in extra small and large viewports --> | |
<img ng-src="pic.png" /> | |
</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment