(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>
<md-grid-list md-cols="7" md-row-height="2em" md-gutter="0.5em"
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">
<md-grid-tile var:value="valueForWeekDay"><var:string value="item"/></md-grid-tile>
</var:foreach>

View File

@ -28,7 +28,8 @@
<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"
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">
<var:foreach list="shortWeekDaysList" item="item">
<md-grid-tile var:value="valueForWeekDay"><var:string value="labelForWeekDay"/></md-grid-tile>
@ -53,7 +54,8 @@
<div layout="row" layout-align="start center">
<md-grid-list md-cols="7" md-row-height="2em" md-gutter="0.5em"
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="2">2</md-grid-tile>
<md-grid-tile value="3">3</md-grid-tile>
@ -121,7 +123,8 @@
<div layout="row" layout-align="start center">
<md-grid-list md-cols="6" md-row-height="2em" md-gutter="0.5em"
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">
<md-grid-tile var:value="valueForYearlyMonth"><var:string value="item"/></md-grid-tile>
</var:foreach>

View File

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