Merge pull request #2533 from jlmitch5/schDatePicker

use bootstrap date picker and fix for locales
This commit is contained in:
jlmitch5 2016-06-21 13:51:47 -04:00 committed by GitHub
commit 41baa7d28d
8 changed files with 161 additions and 113 deletions

View File

@ -1,13 +1,13 @@
/***************************************************************************
* angular-scheruler.js
*
*
* Copyright (c) 2014 Ansible, Inc.
*
* Maintainers:
*
* Chris Houseknecht
* @chouseknecht
* chouse@ansible.com
* chouse@ansible.com
*
*/
@ -23,7 +23,7 @@ angular.module('underscore',[])
angular.module('AngularScheduler', ['underscore'])
.constant('AngularScheduler.partials', '/lib/')
.constant('AngularScheduler.useTimezone', false)
.constant('AngularScheduler.showUTCField', false)
@ -96,6 +96,11 @@ angular.module('AngularScheduler', ['underscore'])
}
};
// change the utc time with the new start date
scope.$watch('schedulerStartDt', function() {
scope.scheduleTimeChange(scope.processSchedulerEndDt);
});
scope.resetError = function(variable) {
scope[variable] = false;
};
@ -193,24 +198,24 @@ angular.module('AngularScheduler', ['underscore'])
}
return CreateObject(scope, requireFutureStartTime);
};
}])
/**
Return an AngularScheduler object we can use to get the RRule result from user input, check if
user input is valid, reset the form, etc. All the things we need to access and manipulate the
scheduler widget
user input is valid, reset the form, etc. All the things we need to access and manipulate the
scheduler widget
*/
.factory('CreateObject', ['AngularScheduler.useTimezone', '$filter', 'GetRule', 'Inject', 'InjectDetail', 'SetDefaults', '$timezones', 'SetRule', 'InRange',
function(useTimezone, $filter, GetRule, Inject, InjectDetail, SetDefaults, $timezones, SetRule, InRange) {
return function(scope, requireFutureST) {
var fn = function() {
this.scope = scope;
this.useTimezone = useTimezone;
this.requireFutureStartTime = requireFutureST;
// Evaluate user intput and build options for passing to rrule
this.getOptions = function() {
var options = {};
@ -223,9 +228,9 @@ angular.module('AngularScheduler', ['underscore'])
if (this.scope.schedulerEnd.value === 'on') {
options.endDate = scope.schedulerEndDt.replace(/(\d{2})\/(\d{2})\/(\d{4})/, function(match, p1, p2, p3) {
return p3 + '-' + p1 + '-' + p2;
}) + 'T' +
$filter('schZeroPad')(this.scope.schedulerEndHour,2) + ':' +
$filter('schZeroPad')(this.scope.schedulerEndMinute,2) + ':' +
}) + 'T' +
$filter('schZeroPad')(this.scope.schedulerEndHour,2) + ':' +
$filter('schZeroPad')(this.scope.schedulerEndMinute,2) + ':' +
$filter('schZeroPad')(this.scope.schedulerEndSecond,2)+ 'Z';
}
if (this.scope.schedulerFrequency.value === 'weekly') {
@ -264,7 +269,7 @@ angular.module('AngularScheduler', ['underscore'])
this.scope.scheduler_occurrenceCount_error = false;
this.scope.scheduler_monthDay_error = false;
this.scope.scheduler_yearlyMonthDay_error = false;
if (this.scope.scheduler_form && this.scope.scheduler_form.schedulerEndDt) {
this.scope.scheduler_form.schedulerEndDt.$setValidity('custom-error', true);
this.scope.scheduler_form.schedulerEndDt.$setPristine();
@ -319,7 +324,7 @@ angular.module('AngularScheduler', ['underscore'])
this.scope.scheduler_occurrenceCount_error = true;
validity = false;
}
if (this.scope.schedulerFrequency.value === 'weekly' && this.scope.weekDays.length === 0) {
this.scope.scheduler_weekDays_error = true;
validity = false;
@ -367,7 +372,7 @@ angular.module('AngularScheduler', ['underscore'])
$filter('schZeroPad')(now.getHours(),2) + ':' +
$filter('schZeroPad')(now.getMinutes(),2) + ':' +
$filter('schZeroPad')(now.getSeconds(),2) + '.000Z';
adjNow = $timezones.toUTC(dateStr, this.scope.schedulerTimeZone.name); //Adjust to the selected TZ
adjNow = $timezones.toUTC(dateStr, this.scope.schedulerTimeZone.name); //Adjust to the selected TZ
timeNow = adjNow.getTime();
}
else {
@ -434,7 +439,7 @@ angular.module('AngularScheduler', ['underscore'])
this.scope.schedulerName = name;
};
// Read in the HTML partial, compile and inject it into the DOM.
// Read in the HTML partial, compile and inject it into the DOM.
// Pass in the target element's id attribute value or an angular.element()
// object.
this.inject = function(element, showButtons) {
@ -491,7 +496,7 @@ angular.module('AngularScheduler', ['underscore'])
.factory('Inject', ['AngularScheduler.partials', '$compile', '$http', '$log', function(scheduler_partial, $compile, $http) {
return function(params) {
var scope = params.scope,
target = params.target,
buttons = params.buttons;
@ -521,7 +526,7 @@ angular.module('AngularScheduler', ['underscore'])
.factory('InjectDetail', ['AngularScheduler.partials', '$compile', '$http', '$log', function(scheduler_partial, $compile, $http) {
return function(params) {
var scope = params.scope,
target = params.target,
showRRule = params.showRRule;
@ -551,11 +556,11 @@ angular.module('AngularScheduler', ['underscore'])
.factory('GetRule', ['$log', function($log) {
return function(params) {
// Convert user inputs to an rrule. Returns rrule object using https://github.com/jkbr/rrule
// **list of 'valid values' found below in LoadLookupValues
// **list of 'valid values' found below in LoadLookupValues
var startDate = params.startDate, // date object or string in yyyy-MM-ddTHH:mm:ss.sssZ format
frequency = params.frequency, // string, optional, valid value from frequencyOptions
interval = params.interval, // integer, optional
interval = params.interval, // integer, optional
occurrenceCount = params.occurrenceCount, //integer, optional
endDate = params.endDate, // date object or string in yyyy-MM-dd format, optional
// ignored if occurrenceCount provided
@ -564,7 +569,7 @@ angular.module('AngularScheduler', ['underscore'])
weekDays = params.weekDays, // integer, optional, valid value from weekdays
setOccurrence = params.setOccurrence, // integer, optional, valid value from occurrences
options = {}, i;
if (angular.isDate(startDate)) {
options.dtstart = startDate;
}
@ -580,7 +585,7 @@ angular.module('AngularScheduler', ['underscore'])
if (frequency && frequency !== 'none') {
options.freq = RRule[frequency.toUpperCase()];
options.interval = interval;
if (weekDays && typeof weekDays === 'string') {
options.byweekday = RRule[weekDays.toUpperCase()];
}
@ -636,7 +641,7 @@ angular.module('AngularScheduler', ['underscore'])
return function(rule, scope) {
var set, result = '', i,
setStartDate = false;
// Search the set of RRule keys for a particular key, returning its value
function getValue(set, key) {
var pair = _.find(set, function(x) {
@ -837,7 +842,7 @@ angular.module('AngularScheduler', ['underscore'])
}
}
}
function isValid() {
// Check what was put into scope vars, and see if anything is
// missing or not quite right.
@ -923,7 +928,7 @@ angular.module('AngularScheduler', ['underscore'])
.factory('LoadLookupValues', [ function() {
return function(scope) {
scope.frequencyOptions = [
{ name: 'None (run once)', value: 'none', intervalLabel: '' },
{ name: 'Minute', value: 'minutely', intervalLabel: 'minutes' },
@ -978,7 +983,7 @@ angular.module('AngularScheduler', ['underscore'])
};
}])
// $filter('schZeroPad')(n, pad) -- or -- {{ n | afZeroPad:pad }}
.filter('schZeroPad', [ function() {
return function (n, pad) {
@ -1034,7 +1039,7 @@ angular.module('AngularScheduler', ['underscore'])
};
}])
// Custom directives
// Custom directives
.directive('schSpinner', ['$filter', function($filter) {
return {
require: 'ngModel',
@ -1072,7 +1077,7 @@ angular.module('AngularScheduler', ['underscore'])
}
}
});
$(element).on("click", function () {
$(element).select();
});

View File

@ -42,26 +42,9 @@
(mm/dd/yyyy)
</span>
</label>
<div class="input-group Form-inputGroup">
<input type="text"
class="form-control input-sm
Form-textInput"
name="schedulerStartDt"
id="schedulerStartDt"
ng-model="schedulerStartDt"
sch-date-picker
placeholder="mm/dd/yyyy"
required
ng-change="scheduleTimeChange()" >
<span class="input-group-btn">
<button
class="btn btn-default btn-sm
Form-inputButton Form-lookupButton"
type="button"
ng-click="showCalendar('schedulerStartDt')">
<i class="fa fa-calendar"></i>
</button>
</span>
<div class="input-group Form-inputGroup SchedulerForm-inputGroup--date">
<scheduler-date-picker date="schedulerStartDt">
</scheduler-date-picker>
</div>
<div class="error"
ng-show="scheduler_form_schedulerStartDt_error"
@ -508,26 +491,9 @@
(mm/dd/yyyy)
</span>
</label>
<div class="input-group Form-inputGroup">
<input type="text"
name="schedulerEndDt"
id="schedulerEndDt"
class="form-control input-sm
Form-textInput"
ng-model="$parent.schedulerEndDt"
sch-date-picker
data-min-today="true"
placeholder="mm/dd/yyyy"
ng-change="$parent.resetError('scheduler_endDt_error')">
<span class="input-group-btn">
<button class="btn btn-default btn-sm
Form-inputButton Form-lookupButton"
type="button"
ng-click="showCalendar('schedulerEndDt')"
>
<i class="fa fa-calendar"></i>
</button>
</span>
<div class="input-group Form-inputGroup SchedulerForm-inputGroup--date">
<scheduler-date-picker date="$parent.schedulerEndDt">
</scheduler-date-picker>
</div>
<div class="error"
ng-show="$parent.scheduler_endDt_error">

View File

@ -8,12 +8,14 @@ import controller from './scheduler.controller';
import addController from './schedulerAdd.controller';
import editController from './schedulerEdit.controller';
import {templateUrl} from '../shared/template-url/template-url.factory';
import schedulerDatePicker from './schedulerDatePicker.directive';
export default
angular.module('scheduler', [])
.controller('schedulerController', controller)
.controller('schedulerAddController', addController)
.controller('schedulerEditController', editController)
.directive('schedulerDatePicker', schedulerDatePicker)
.run(['$stateExtender', function($stateExtender) {
$stateExtender.addState({
name: 'jobTemplateSchedules',

View File

@ -23,11 +23,7 @@ export default [
ClearScope();
$scope.schedulerStartDT = 'test';
var base, id, url,parentObject, title;
$scope.schedulerStartDT = 'test';
base = $location.path().replace(/^\//, '').split('/')[0];
if (base === 'management_jobs') {

View File

@ -0,0 +1,92 @@
/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/* jshint unused: vars */
export default
[ 'moment',
'templateUrl',
function(moment, templateUrl) {
return {
restrict: 'E',
scope: {
date: '=',
minDate: '=',
autoUpdate: '=?',
inputClass: '&'
},
templateUrl: templateUrl('system-tracking/date-picker/date-picker'),
link: function(scope, element, attrs) {
// We need to make sure this _never_ recurses, which sometimes happens
// with two-way binding.
var mustUpdateValue = true;
scope.autoUpdate = scope.autoUpdate === false ? false : true;
// convert the passed current date into the correct moment locale
scope.$watch('date', function(newValue) {
if (newValue) {
mustUpdateValue = false;
scope.dateValueMoment = moment(newValue, ['MM/DD/YYYY'], moment.locale());
scope.dateValue = scope.dateValueMoment.format('L');
}
}, true);
// as the date picker value changes, convert back to
// the english date to pass back into the scheduler lib
scope.$watch('dateValue', function(newValue) {
scope.dateValueMoment = moment(newValue, ['L'], moment.locale());
scope.date = scope.dateValueMoment.locale('en').format('L');
mustUpdateValue = true;
});
var localeData =
moment.localeData();
var dateFormat = momentFormatToDPFormat(localeData._longDateFormat.L);
var localeKey = momentLocaleToDPLocale(moment.locale());
element.find(".DatePicker").addClass("input-prepend date");
element.find(".DatePicker").find(".DatePicker-icon").addClass("add-on");
$(".date").systemTrackingDP({
autoclose: true,
language: localeKey,
format: dateFormat
});
function momentLocaleToDPLocale(localeKey) {
var parts = localeKey.split('-');
if (parts.length === 2) {
var lastPart = parts[1].toUpperCase();
return [parts[0], lastPart].join('-');
} else {
return localeKey;
}
}
function momentFormatToDPFormat(momentFormat) {
var resultFormat = momentFormat;
function lowerCase(str) {
return str.toLowerCase();
}
resultFormat = resultFormat.replace(/D{1,2}/, lowerCase);
if (/MMM/.test(resultFormat)) {
resultFormat = resultFormat.replace('MMM', 'M');
} else {
resultFormat = resultFormat.replace(/M{1,2}/, 'm');
}
resultFormat = resultFormat.replace(/Y{2,4}/, lowerCase);
return resultFormat;
}
}
};
}
];

View File

@ -0,0 +1,9 @@
<div class="DatePicker">
<button class="DatePicker-icon"><i class="fa fa-calendar"></i></button>
<input
class="DatePicker-input"
type="text"
readonly
ng-model="dateValue"
ng-class="inputClass()">
</div>

View File

@ -6,6 +6,18 @@
padding-right: 0px;
}
.SchedulerForm-inputGroup--date {
width: 100%;
}
#SchedulerFormTarget .DatePicker {
max-height: 31px;
}
#SchedulerFormTarget .DatePicker-icon {
padding-top: 4px;
}
@media (min-width: 901px) {
.SchedulerForm-formGroup {
flex: 0 0 auto;

View File

@ -42,26 +42,9 @@
(mm/dd/yyyy)
</span>
</label>
<div class="input-group Form-inputGroup">
<input type="text"
class="form-control input-sm
Form-textInput"
name="schedulerStartDt"
id="schedulerStartDt"
ng-model="schedulerStartDt"
sch-date-picker
placeholder="mm/dd/yyyy"
required
ng-change="scheduleTimeChange(processSchedulerEndDt)" >
<span class="input-group-btn">
<button
class="btn btn-default btn-sm
Form-inputButton Form-lookupButton"
type="button"
ng-click="showCalendar('schedulerStartDt')">
<i class="fa fa-calendar"></i>
</button>
</span>
<div class="input-group Form-inputGroup SchedulerForm-inputGroup--date">
<scheduler-date-picker date="schedulerStartDt">
</scheduler-date-picker>
</div>
<div class="error"
ng-show="scheduler_form_schedulerStartDt_error"
@ -490,26 +473,9 @@
(mm/dd/yyyy)
</span>
</label>
<div class="input-group Form-inputGroup">
<input type="text"
name="schedulerEndDt"
id="schedulerEndDt"
class="form-control input-sm
Form-textInput"
ng-model="$parent.schedulerEndDt"
sch-date-picker
data-min-today="true"
placeholder="mm/dd/yyyy"
ng-change="$parent.resetError('scheduler_endDt_error')">
<span class="input-group-btn">
<button class="btn btn-default btn-sm
Form-inputButton Form-lookupButton"
type="button"
ng-click="showCalendar('schedulerEndDt')"
>
<i class="fa fa-calendar"></i>
</button>
</span>
<div class="input-group Form-inputGroup SchedulerForm-inputGroup--date">
<scheduler-date-picker date="$parent.schedulerEndDt">
</scheduler-date-picker>
</div>
<div class="error"
ng-show="$parent.scheduler_endDt_error">