├── .gitignore ├── README.md ├── bower.json ├── dist └── angular-responsive.js └── src └── angular-responsive.coffee /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Angular Responsive 2 | ================== 3 | 4 | **Angular Responsive** is a nifty, growing set of directives to help you build responsive apps. 5 | 6 | Installation 7 | ------------ 8 | Business as usual: `bower install cfts-angular-responsive --save` 9 | 10 | 11 | 12 | Setup 13 | ----- 14 | First, load `angular-responsive.js` into your HTML: 15 | 16 | 18 | 19 | Then, load into your modules: 20 | 21 | var myModule = angular.module("myModule", ['angular-responsive']); 22 | 23 | Now, you're ready to go. 24 | 25 | 26 | 27 | Directives 28 | ---------- 29 | 30 | | directive | description | example 31 | |---|---|---| 32 | |`responsive`|This is your main directive. Use this to start watching over changes in `window`'s size. This will update width and height values to the `Breakpoint` service. Because of it's nature, It should be used in ``, and **no more than once per app**. | `` 33 | |`minWidth`|Defines a minimum width in pixels for the element to be displayed. If `window`'s width is less than this value, the element will be hidden. You shouldn't need to use this. Instead, you're encouraged to do your hiding/showing via CSS, but there it is, en case you ever need it. | `
`| 34 | |`maxWidth`| Same as `minWidth`: Defines a maximum width in pixels for the element to be displayed. If `window`'s width is greater than this value, the element will be hidden. You shouldn't need to use this. | `
`| 35 | |`responsiveBooleans`|A-ha, now this might be useful. Defines and appends a set of variables to your scope, which evaluate to `true`or `false`, given a width-comparison rule for each one of them. Works just like **ngClass**. The variables can be later used in your controller as you wish. | `
`| 36 | |`responsiveClasses`|This is why I created this module. I needed to append/remove classes to a given element based on `window`'s width. And this is what this directive does. And works just like **ngClass**. | `
`| 37 | 38 | 39 | 40 | Afterword 41 | --------- 42 | I'd like to hear feedback on how you use **Angular Responsive** and how to improve it in any way, be it performance, new features, best practices or even documentation. So please, feel free to open an issue, pull-request or drop a line. Proposals to improve this little module will make me happy. 43 | 44 | Thanks! -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-responsive", 3 | "version": "0.1.0", 4 | "authors": [ 5 | "Armin Cifuentes (http://armincifuentes.cl)" 6 | ], 7 | "description": "Nifty directives to help you build responsive apps.", 8 | "main": "dist/angular-responsive.js", 9 | "dependencies": { 10 | "angular": "^1.2.x" 11 | }, 12 | "devDependencies": { 13 | "coffeescript": "~1.10.0" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/armincifuentes/angular-responsive.git" 18 | }, 19 | "keywords": [ 20 | "angular", 21 | "directive", 22 | "responsive", 23 | "layout" 24 | ], 25 | "license": "MIT", 26 | "ignore": [ 27 | "**/.*", 28 | "node_modules", 29 | "bower_components", 30 | "src/bower_components", 31 | "test", 32 | "tests" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /dist/angular-responsive.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var responsive; 4 | 5 | responsive = angular.module("angular-responsive", []); 6 | 7 | responsive.service("Breakpoint", function() { 8 | return { 9 | w: 0, 10 | h: 0 11 | }; 12 | }); 13 | 14 | responsive.directive("responsive", function($window, Breakpoint) { 15 | return { 16 | restrict: "A", 17 | link: function(scope, element, attrs) { 18 | var w; 19 | w = angular.element($window); 20 | Breakpoint.w = w.width(); 21 | Breakpoint.h = w.height(); 22 | return w.bind("resize", function() { 23 | Breakpoint.w = w.width(); 24 | Breakpoint.h = w.height(); 25 | return scope.$digest(); 26 | }); 27 | } 28 | }; 29 | }); 30 | 31 | responsive.directive("minWidth", function(Breakpoint) { 32 | return { 33 | restrict: "A", 34 | link: function(scope, element, attrs) { 35 | return scope.$watch(function() { 36 | return Breakpoint.w; 37 | }, function(newWidth) { 38 | if (newWidth < parseInt(attrs.minWidth)) { 39 | element.hide(); 40 | } 41 | if (newWidth > parseInt(attrs.minWidth)) { 42 | return element.show(); 43 | } 44 | }); 45 | } 46 | }; 47 | }); 48 | 49 | responsive.directive("maxWidth", function(Breakpoint) { 50 | return { 51 | restrict: "A", 52 | link: function(scope, element, attrs) { 53 | return scope.$watch(function() { 54 | return Breakpoint.w; 55 | }, function(newWidth) { 56 | if (newWidth > parseInt(attrs.maxWidth)) { 57 | element.hide(); 58 | } 59 | if (newWidth < parseInt(attrs.maxWidth)) { 60 | return element.show(); 61 | } 62 | }); 63 | } 64 | }; 65 | }); 66 | 67 | responsive.directive("responsiveBooleans", function(Breakpoint, $parse) { 68 | return { 69 | restrict: "A", 70 | link: function(scope, element, attrs) { 71 | var checkConditions, conditions, parseConditions; 72 | conditions = $parse(attrs.responsiveBooleans)(scope); 73 | parseConditions = function() { 74 | return angular.forEach(conditions, function(val, key, obj) { 75 | return conditions[key] = { 76 | operation: val[0], 77 | value: val.substring(1) 78 | }; 79 | }); 80 | }; 81 | checkConditions = function(value) { 82 | return angular.forEach(conditions, function(val, key) { 83 | switch (val.operation) { 84 | case '>': 85 | return scope[key] = value > val.value; 86 | case '<': 87 | return scope[key] = value < val.value; 88 | case '=': 89 | return scope[key] = value === val.value; 90 | } 91 | }); 92 | }; 93 | parseConditions(); 94 | return scope.$watch(function() { 95 | return Breakpoint.w; 96 | }, function(newWidth) { 97 | return checkConditions(newWidth); 98 | }); 99 | } 100 | }; 101 | }); 102 | 103 | responsive.directive("responsiveClasses", function(Breakpoint, $parse) { 104 | return { 105 | restrict: "A", 106 | link: function(scope, element, attrs) { 107 | var checkConditions, conditions, parseConditions; 108 | conditions = $parse(attrs.responsiveClasses)(scope); 109 | parseConditions = function() { 110 | return angular.forEach(conditions, function(val, key, obj) { 111 | return conditions[key] = { 112 | operation: val[0], 113 | value: val.substring(1) 114 | }; 115 | }); 116 | }; 117 | checkConditions = function(value) { 118 | return angular.forEach(conditions, function(val, key) { 119 | switch (val.operation) { 120 | case '>': 121 | if (value > val.value) { 122 | return element.addClass(key); 123 | } else { 124 | return element.removeClass(key); 125 | } 126 | break; 127 | case '<': 128 | if (value < val.value) { 129 | return element.addClass(key); 130 | } else { 131 | return element.removeClass(key); 132 | } 133 | break; 134 | case '=': 135 | if (value === val.value) { 136 | return element.addClass(key); 137 | } else { 138 | return element.removeClass(key); 139 | } 140 | } 141 | }); 142 | }; 143 | parseConditions(); 144 | return scope.$watch(function() { 145 | return Breakpoint.w; 146 | }, function(newWidth) { 147 | return checkConditions(newWidth); 148 | }); 149 | } 150 | }; 151 | }); 152 | 153 | }).call(this); 154 | -------------------------------------------------------------------------------- /src/angular-responsive.coffee: -------------------------------------------------------------------------------- 1 | responsive = angular.module "angular-responsive", [] 2 | 3 | responsive.service "Breakpoint", -> 4 | w: 0 5 | h: 0 6 | 7 | responsive.directive "responsive", ($window, Breakpoint)-> 8 | restrict: "A" 9 | link: (scope, element, attrs)-> 10 | 11 | w = angular.element($window) 12 | 13 | Breakpoint.w = w.width() 14 | Breakpoint.h = w.height() 15 | 16 | w.bind "resize", -> 17 | 18 | Breakpoint.w = w.width() 19 | Breakpoint.h = w.height() 20 | 21 | scope.$digest() 22 | 23 | responsive.directive "minWidth", (Breakpoint)-> 24 | restrict: "A" 25 | link: (scope, element, attrs)-> 26 | scope.$watch -> 27 | Breakpoint.w 28 | , (newWidth)-> 29 | element.hide() if newWidth < parseInt attrs.minWidth 30 | element.show() if newWidth > parseInt attrs.minWidth 31 | 32 | responsive.directive "maxWidth", (Breakpoint)-> 33 | restrict: "A" 34 | link: (scope, element, attrs)-> 35 | scope.$watch -> 36 | Breakpoint.w 37 | , (newWidth)-> 38 | element.hide() if newWidth > parseInt attrs.maxWidth 39 | element.show() if newWidth < parseInt attrs.maxWidth 40 | 41 | responsive.directive "responsiveBooleans", (Breakpoint, $parse)-> 42 | restrict: "A" 43 | link: (scope, element, attrs)-> 44 | 45 | conditions = $parse(attrs.responsiveBooleans)(scope) 46 | 47 | parseConditions = -> 48 | angular.forEach conditions, (val, key, obj)-> 49 | conditions[key] = 50 | operation: (val[0]) 51 | value: ( val.substring 1 ) 52 | 53 | checkConditions = (value)-> 54 | angular.forEach conditions, (val, key)-> 55 | switch val.operation 56 | when '>' then scope[key] = value > val.value 57 | when '<' then scope[key] = value < val.value 58 | when '=' then scope[key] = value == val.value 59 | 60 | parseConditions() 61 | 62 | scope.$watch -> 63 | Breakpoint.w 64 | , (newWidth)-> 65 | checkConditions newWidth 66 | 67 | responsive.directive "responsiveClasses", (Breakpoint, $parse)-> 68 | restrict: "A" 69 | link: (scope, element, attrs)-> 70 | 71 | conditions = $parse(attrs.responsiveClasses)(scope) 72 | 73 | parseConditions = -> 74 | angular.forEach conditions, (val, key, obj)-> 75 | conditions[key] = 76 | operation: (val[0]) 77 | value: ( val.substring 1 ) 78 | 79 | checkConditions = (value)-> 80 | angular.forEach conditions, (val, key)-> 81 | switch val.operation 82 | when '>' 83 | if value > val.value 84 | element.addClass key 85 | else element.removeClass key 86 | 87 | when '<' 88 | if value < val.value 89 | element.addClass key 90 | else element.removeClass key 91 | 92 | when '=' 93 | if value == val.value 94 | element.addClass key 95 | else element.removeClass key 96 | 97 | parseConditions() 98 | 99 | scope.$watch -> 100 | Breakpoint.w 101 | , (newWidth)-> 102 | checkConditions newWidth --------------------------------------------------------------------------------