(js) Improve sgToggleGrid directive with ngModel

This allows a form to be set as "dirty" when a grid element is toggled.
pull/207/head
Francis Lachapelle 2016-05-06 16:49:47 -04:00
parent 8789db67b3
commit 68799755be
3 changed files with 69 additions and 61 deletions

View File

@ -295,7 +295,8 @@
<label class="pseudo-input-label"><var:string label:value="Week days to display"/></label> <label class="pseudo-input-label"><var:string label:value="Week days to display"/></label>
<md-grid-list md-cols="7" md-row-height="2em" md-gutter="0.5em" <md-grid-list md-cols="7" md-row-height="2em" md-gutter="0.5em"
flex="50" flex-sm="80" flex-xs="100" flex="50" flex-sm="80" flex-xs="100"
sg-toggle-grid="app.preferences.defaults.SOGoCalendarWeekdays"> ng-model="app.preferences.defaults.SOGoCalendarWeekdays"
sg-toggle-grid="sg-toggle-grid">
<var:foreach list="shortWeekDaysList" item="item"> <var:foreach list="shortWeekDaysList" item="item">
<md-grid-tile var:value="valueForWeekDay"><var:string value="item"/></md-grid-tile> <md-grid-tile var:value="valueForWeekDay"><var:string value="item"/></md-grid-tile>
</var:foreach> </var:foreach>

View File

@ -28,7 +28,8 @@
<label class="pseudo-input-label"><var:string label:value="On"/></label> <label class="pseudo-input-label"><var:string label:value="On"/></label>
<md-grid-list md-cols="7" md-row-height="2em" md-gutter="0.5em" <md-grid-list md-cols="7" md-row-height="2em" md-gutter="0.5em"
flex="50" flex-sm="80" flex-xs="100" flex="50" flex-sm="80" flex-xs="100"
sg-toggle-grid="editor.component.repeat.days" ng-model="editor.component.repeat.days"
sg-toggle-grid="sg-toggle-grid"
sg-toggle-grid-attr="day"> sg-toggle-grid-attr="day">
<var:foreach list="shortWeekDaysList" item="item"> <var:foreach list="shortWeekDaysList" item="item">
<md-grid-tile var:value="valueForWeekDay"><var:string value="labelForWeekDay"/></md-grid-tile> <md-grid-tile var:value="valueForWeekDay"><var:string value="labelForWeekDay"/></md-grid-tile>
@ -53,7 +54,8 @@
<div layout="row" layout-align="start center"> <div layout="row" layout-align="start center">
<md-grid-list md-cols="7" md-row-height="2em" md-gutter="0.5em" <md-grid-list md-cols="7" md-row-height="2em" md-gutter="0.5em"
flex="50" flex-sm="80" flex-xs="100" flex="50" flex-sm="80" flex-xs="100"
sg-toggle-grid="editor.component.repeat.monthdays"> ng-model="editor.component.repeat.monthdays"
sg-toggle-grid="sg-toggle-grid">
<md-grid-tile value="1">1</md-grid-tile> <md-grid-tile value="1">1</md-grid-tile>
<md-grid-tile value="2">2</md-grid-tile> <md-grid-tile value="2">2</md-grid-tile>
<md-grid-tile value="3">3</md-grid-tile> <md-grid-tile value="3">3</md-grid-tile>
@ -121,7 +123,8 @@
<div layout="row" layout-align="start center"> <div layout="row" layout-align="start center">
<md-grid-list md-cols="6" md-row-height="2em" md-gutter="0.5em" <md-grid-list md-cols="6" md-row-height="2em" md-gutter="0.5em"
flex="50" flex-sm="80" flex-xs="100" flex="50" flex-sm="80" flex-xs="100"
sg-toggle-grid="editor.component.repeat.months"> ng-model="editor.component.repeat.months"
sg-toggle-grid="sg-toggle-grid">
<var:foreach list="yearlyMonthList" item="item"> <var:foreach list="yearlyMonthList" item="item">
<md-grid-tile var:value="valueForYearlyMonth"><var:string value="item"/></md-grid-tile> <md-grid-tile var:value="valueForYearlyMonth"><var:string value="item"/></md-grid-tile>
</var:foreach> </var:foreach>

View File

@ -7,41 +7,56 @@
* sgToggleGrid - Convert the tiles of a grid to toggle buttons * sgToggleGrid - Convert the tiles of a grid to toggle buttons
* @memberof SOGo.Common * @memberof SOGo.Common
* @restrict attribute * @restrict attribute
* @param {object} sgToggleGrid - the model of the source objects
* @param {string} [sgToggleGridAttr] - the attribute that specifies if an object is enabled (toggled) * @param {string} [sgToggleGridAttr] - the attribute that specifies if an object is enabled (toggled)
* @ngInject * @ngInject
* @example: * @example:
<md-grid-list md-cols="7" md-row-height="1:1" <md-grid-list md-cols="7" md-row-height="1:1"
sg-toggle-grid="editor.event.repeat.days" ng-model="editor.event.repeat.days"
sg-toggle-grid-attr="day">..</md-grid-list> sg-toggle-grid sg-toggle-grid-attr="day">..</md-grid-list>
*/ */
sgToggleGrid.$inject = ['$parse']; sgToggleGrid.$inject = ['$parse', '$mdUtil'];
function sgToggleGrid($parse) { function sgToggleGrid($parse, $mdUtil) {
return { return {
restrict: 'A', restrict: 'A',
link: link require: '?ngModel',
compile: compile
}; };
function link(scope, iElement, attrs, ctrl) { function compile(tElement, tAttrs) {
var tiles = iElement.find('md-grid-tile'), return function postLink(scope, element, attr, ngModelCtrl) {
tile, var tiles = tElement.find('md-grid-tile'),
i, tile,
modelDays, i,
modelAttr, modelDays,
ensureInitRunsOnce, modelAttr,
toggleClass; toggleClass;
ensureInitRunsOnce = scope.$watch(function() { ngModelCtrl = ngModelCtrl || $mdUtil.fakeNgModel();
// Parse attribute until it returns a valid object ngModelCtrl.$render = render;
return $parse(attrs.sgToggleGrid)(scope);
}, function(days) { toggleClass = function() {
if (angular.isDefined(days)) { // Toggle class on click event and call toggle function
var flattenedDays = days; var tile = angular.element(this),
modelDays = days; day = tile.attr('value');
if (attrs.sgToggleGridAttr) { tile.toggleClass('sg-active');
modelAttr = attrs.sgToggleGridAttr; toggle(day);
flattenedDays = _.map(days, attrs.sgToggleGridAttr); };
for (i = 0; i < tiles.length; i++) {
tile = angular.element(tiles[i]);
tile.addClass('sg-icon-button');
tile.find('figure').addClass('md-icon');
tile.on('click', toggleClass);
}
function render() {
console.debug(ngModelCtrl.$viewValue);
var flattenedDays = ngModelCtrl.$viewValue;
modelDays = ngModelCtrl.$viewValue;
if (tAttrs.sgToggleGridAttr) {
modelAttr = tAttrs.sgToggleGridAttr;
flattenedDays = _.map(ngModelCtrl.$viewValue, tAttrs.sgToggleGridAttr);
} }
_.forEach(tiles, function(o) { _.forEach(tiles, function(o) {
var tile = angular.element(o); var tile = angular.element(o);
@ -49,44 +64,33 @@
tile.addClass('sg-active'); tile.addClass('sg-active');
} }
}); });
ensureInitRunsOnce();
} }
});
toggleClass = function() { function toggle(day) {
// Toggle class on click event and call toggle function var i = _.findIndex(modelDays, function(o) {
var tile = angular.element(this), if (modelAttr)
day = tile.attr('value'); return o[modelAttr] == day;
tile.toggleClass('sg-active'); else
toggle(day); return o == day;
}; });
if (i < 0) {
for (i = 0; i < tiles.length; i++) { if (modelAttr) {
tile = angular.element(tiles[i]); var o = {};
tile.addClass('sg-icon-button'); o[modelAttr] = day;
tile.find('figure').addClass('md-icon'); modelDays.push(o);
tile.on('click', toggleClass); }
} else
modelDays.push(day);
function toggle(day) {
var i = _.findIndex(modelDays, function(o) {
if (modelAttr)
return o[modelAttr] == day;
else
return o == day;
});
if (i < 0) {
if (modelAttr) {
var o = {};
o[modelAttr] = day;
modelDays.push(o);
} }
else else
modelDays.push(day); modelDays.splice(i, 1);
scope.$apply(function() {
ngModelCtrl.$setViewValue(modelDays);
ngModelCtrl.$setDirty();
});
} }
else };
modelDays.splice(i, 1);
}
} }
} }