})
// Display a date widget.
- // example: <input crm-ui-date="myobj.datefield" />
- // example: <input crm-ui-date="myobj.datefield" crm-ui-date-format="yy-mm-dd" />
- // WISHLIST: use ngModel
+ // example: <input crm-ui-date ng-model="myobj.datefield" />
+ // example: <input crm-ui-date ng-model="myobj.datefield" crm-ui-date-format="yy-mm-dd" />
.directive('crmUiDate', function ($parse, $timeout) {
return {
restrict: 'AE',
+ require: 'ngModel',
scope: {
- crmUiDate: '@', // expression, model binding
crmUiDateFormat: '@' // expression, date format (default: "yy-mm-dd")
},
- link: function (scope, element, attrs) {
+ link: function (scope, element, attrs, ngModel) {
var fmt = attrs.crmUiDateFormat ? $parse(attrs.crmUiDateFormat)() : "yy-mm-dd";
- var model = $parse(attrs.crmUiDate);
element.addClass('dateplugin');
$(element).datepicker({
dateFormat: fmt
});
- var updateChildren = (function() {
- element.off('change', updateParent);
- $(element).datepicker('setDate', model(scope.$parent));
- element.on('change', updateParent);
- });
+ ngModel.$render = function $render() {
+ $(element).datepicker('setDate', ngModel.$viewValue);
+ };
var updateParent = (function() {
$timeout(function () {
- model.assign(scope.$parent, $(element).val());
+ ngModel.$setViewValue(element.val());
});
});
- updateChildren();
- scope.$parent.$watch(attrs.crmUiDate, updateChildren);
element.on('change', updateParent);
}
};
})
// Display a date-time widget.
- // example: <div crm-ui-date-time="myobj.mydatetimefield"></div>
- // WISHLIST: use ngModel
+ // example: <div crm-ui-date-time ng-model="myobj.mydatetimefield"></div>
.directive('crmUiDateTime', function ($parse) {
return {
restrict: 'AE',
+ require: 'ngModel',
scope: {
- crmUiDateTime: '@'
+ ngRequired: '@'
},
- template: '<input crm-ui-date="dtparts.date" placeholder="{{dateLabel}}"/> <input crm-ui-time="dtparts.time" placeholder="{{timeLabel}}"/>',
- link: function (scope, element, attrs) {
- var model = $parse(attrs.crmUiDateTime);
+ templateUrl: '~/crmUi/datetime.html',
+ link: function (scope, element, attrs, ngModel) {
+ var ts = scope.ts = CRM.ts(null);
scope.dateLabel = ts('Date');
scope.timeLabel = ts('Time');
+ element.addClass('crm-ui-datetime');
- var updateChildren = (function () {
- var value = model(scope.$parent);
- if (value) {
- var dtparts = value.split(/ /);
+ ngModel.$render = function $render() {
+ if (!_.isEmpty(ngModel.$viewValue)) {
+ var dtparts = ngModel.$viewValue.split(/ /);
scope.dtparts = {date: dtparts[0], time: dtparts[1]};
}
else {
scope.dtparts = {date: '', time: ''};
}
- });
- var updateParent = (function () {
- model.assign(scope.$parent, scope.dtparts.date + " " + scope.dtparts.time);
- });
+ };
+
+ function updateParent() {
+ var incompleteDateTime = _.isEmpty(scope.dtparts.date) ^ _.isEmpty(scope.dtparts.time);
+ ngModel.$setValidity('incompleteDateTime', !incompleteDateTime);
+
+ if (_.isEmpty(scope.dtparts.date) && _.isEmpty(scope.dtparts.time)) {
+ ngModel.$setViewValue(' ');
+ }
+ else {
+ //ngModel.$setViewValue(scope.dtparts.date + ' ' + scope.dtparts.time);
+ ngModel.$setViewValue((scope.dtparts.date ? scope.dtparts.date : '') + ' ' + (scope.dtparts.time ? scope.dtparts.time : ''));
+ }
+ }
- updateChildren();
- scope.$parent.$watch(attrs.crmUiDateTime, updateChildren);
scope.$watch('dtparts.date', updateParent);
scope.$watch('dtparts.time', updateParent);
+
+ function updateRequired() {
+ scope.required = scope.$parent.$eval(attrs.ngRequired);
+ }
+
+ if (attrs.ngRequired) {
+ updateRequired();
+ scope.$parent.$watch(attrs.ngRequired, updateRequired);
+ }
+
+ scope.reset = function reset() {
+ scope.dtparts = {date: '', time: ''};
+ ngModel.$setViewValue('');
+ };
}
};
})
})
// Display a time-entry field.
- // example: <input crm-ui-time="myobj.mytimefield" />
- // WISHLIST: use ngModel
+ // example: <input crm-ui-time ng-model="myobj.mytimefield" />
.directive('crmUiTime', function ($parse, $timeout) {
return {
restrict: 'AE',
+ require: 'ngModel',
scope: {
- crmUiTime: '@'
},
- link: function (scope, element, attrs) {
- var model = $parse(attrs.crmUiTime);
-
+ link: function (scope, element, attrs, ngModel) {
element.addClass('crm-form-text six');
- $(element).timeEntry({show24Hours: true});
+ element.timeEntry({show24Hours: true});
+
+ ngModel.$render = function $render() {
+ element.timeEntry('setTime', ngModel.$viewValue);
+ };
- var updateChildren = (function() {
- element.off('change', updateParent);
- $(element).timeEntry('setTime', model(scope.$parent));
- element.on('change', updateParent);
- });
var updateParent = (function () {
$timeout(function () {
- model.assign(scope.$parent, element.val());
+ ngModel.$setViewValue(element.val());
});
});
-
- updateChildren();
- scope.$parent.$watch(attrs.crmUiTime, updateChildren);
element.on('change', updateParent);
}
};
});
// Represent a datetime field as if it were a radio ('schedule.mode') and a datetime ('schedule.datetime').
- // example: <div crm-mailing-radio-date="mySchedule" crm-model="mailing.scheduled_date">...</div>
- // FIXME: use ngModel instead of adhoc crmModel
+ // example: <div crm-mailing-radio-date="mySchedule" ng-model="mailing.scheduled_date">...</div>
angular.module('crmMailing').directive('crmMailingRadioDate', function ($parse) {
return {
- link: function ($scope, element, attrs) {
- var schedModel = $parse(attrs.crmModel);
+ require: 'ngModel',
+ link: function ($scope, element, attrs, ngModel) {
var schedule = $scope[attrs.crmMailingRadioDate] = {
mode: 'now',
datetime: ''
};
- var updateChildren = (function () {
- var sched = schedModel($scope);
- if (sched) {
+
+ ngModel.$render = function $render() {
+ var sched = ngModel.$viewValue;
+ if (!_.isEmpty(sched)) {
schedule.mode = 'at';
schedule.datetime = sched;
}
else {
schedule.mode = 'now';
}
- });
+ };
+
var updateParent = (function () {
switch (schedule.mode) {
case 'now':
- schedModel.assign($scope, null);
+ ngModel.$setViewValue(null);
break;
case 'at':
- schedModel.assign($scope, schedule.datetime);
+ ngModel.$setViewValue(schedule.datetime);
break;
default:
throw 'Unrecognized schedule mode: ' + schedule.mode;
}
});
- $scope.$watch(attrs.crmModel, updateChildren);
$scope.$watch(attrs.crmMailingRadioDate + '.mode', updateParent);
$scope.$watch(attrs.crmMailingRadioDate + '.datetime', function (newValue, oldValue) {
// automatically switch mode based on datetime entry
if (oldValue != newValue) {
- if (!newValue || newValue == " ") {
+ if (_.isEmpty(newValue) || newValue == " ") {
schedule.mode = 'now';
}
else {