Date picker on Service Portal - sideBySide
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-15-2017 03:08 PM
On the Service Portal the date time picker is very nice but our users have told us that when they use the arrows to increase the hours they sometimes don't notice that the date changed and this causes problems.
The Options - Bootstrap 3 Datepicker tell me we can show both date and times side by side but now the question is, how can I enable this behavior in the Portal?
- Labels:
-
Service Portal
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-25-2017 07:14 AM
How can you get the value of the selected datetime in ng-model angular?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-19-2018 01:48 AM
Hey,
I managed to achieve this view with dynamic CSS, I know it's not best practice but I couldn't affect the view with the .datetimepicker({
sideBySide: true});, I tried putting it on each class that was relevant to this specific HTML block.
This is what I put in my SC Catalog Item client controller:
$timeout( function(){
//Date time picker CSS to be side by side
$('.bootstrap-datetimepicker-widget').each(function( ) {
$(this).css('width','32em');
$(this).css('padding','4px');
$(this).css('margin','2px 0');
});
$('.bootstrap-datetimepicker-widget .list-unstyled ').each(function( ) {
$(this).css('display','flex');
});
$('li.picker-switch').each(function( ) {
$(this).css('display','none');
});
$('.bootstrap-datetimepicker-widget ul.list-unstyled li.collapse').each(function( ) {
$(this).css('display','inline-block');
$(this).css('width','50%');
});
$('.timepicker').each(function( ) {
$(this).css('padding','0 10%');
});
}, 0 );
I tested it on chrome and IE, also with 14'' and 21'' screens and it looked fine:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-19-2018 02:03 AM
Hi Alex,
Another alternative is to create a custom AngularJS directive and include it as a UI script dependency:
angular.module('sn.$sp').directive('spDatePickerCustom', function(spConf, $rootScope, $document, spAriaUtil, i18n, spDatePickerUtil) {
var dateFormat = g_user_date_format || spConf.SYS_DATE_FORMAT;
var dateTimeFormat = g_user_date_time_format || spConf.SYS_TIME_FORMAT;
if ($rootScope.user && $rootScope.user.date_format)
dateFormat = $rootScope.user.date_format;
if ($rootScope.user && $rootScope.user.date_time_format)
dateTimeFormat = $rootScope.user.date_time_format;
return {
template: '<div ng-class="{\'input-group\': !snDisabled, \'has-error\': field.isInvalid}" style="width: 100%;">' +
'<input id="sp_formfield_{{::field.name}}" type="text" name="{{field.name}}" class="form-control" placeholder="{{field.placeholder}}" title="{{g_accessibility ? translations[\'Enter date in format\']: \'\'}}{{g_accessibility ? format : \'\'}}" tooltip-top="true" tooltip-enable="{{g_accessibility}}" ng-model="formattedDate" ng-model-options="{updateOn: \'blur\', getterSetter: true}" ng-readonly="snDisabled" />' +
'<span class="input-group-btn" ng-hide="snDisabled">' +
'<input type="hidden" class="datepickerinput" ng-model="formattedDate" ng-readonly="true" />' +
'<button class="btn btn-default" type="button" tabindex="-1" aria-hidden="true">' +
'<glyph sn-char="calendar" />' +
'</button>' +
'</span>' +
'<span ng-if="field.isInvalid" class="sp-date-format-info" style="display:table-row;" aria-hidden="true">{{translations[\'Enter date in format\']}} {{format}}</span>' +
'</div>',
restrict: 'E',
replace: true,
require: '?ngModel',
scope: {
field: '=',
snDisabled: '=',
snIncludeTime: '=',
sideBySide: '=',
snChange: '&'
},
link: function(scope, element, attrs, ngModel) {
scope.g_accessibility = spAriaUtil.isAccessibilityEnabled();
var includeTime = scope.snIncludeTime;
var sideBySide = scope.sideBySide;
var format;
format = includeTime ? dateTimeFormat.trim() : dateFormat.trim();
format = format.replace(/y/g, 'Y').replace(/d/g, 'D').replace(/a/g, 'A');
scope.format = format;
var dp = element.find('.input-group-btn').datetimepicker({
keepInvalid: true,
pickTime: includeTime,
format: format,
sideBySide: sideBySide,
locale: g_lang,
language: g_lang
}).on('dp.change', onDpChange);
function validate(formattedDate) {
scope.field.isInvalid = false;
return spDatePickerUtil.validate(dp, format, formattedDate, function(error) {
if (error) {
spAriaUtil.sendLiveMessage(scope.translations["Entered date not valid. Enter date in format"] + " " + format);
scope.field.isInvalid = true;
}
});
}
function closeOnTouch(evt) {
if (!jQuery.contains(dp.data('DateTimePicker').widget[0], evt.target)) {
dp.data('DateTimePicker').hide();
}
}
function bindTouchClose() {
$document.on('touchstart', closeOnTouch);
}
function unBindTouchClose() {
$document.off('touchstart', closeOnTouch);
}
dp.on('dp.show', bindTouchClose).on('dp.hide', unBindTouchClose);
function onDpChange(e) {
scope.formattedDate(e.date.format(format));
if (!scope.$root.$$phase)
scope.$apply();
}
if (ngModel) {
ngModel.$parsers.push(validate);
ngModel.$render = function() {
validate(ngModel.$viewValue);
};
scope.formattedDate = function(formattedValue) {
if (angular.isDefined(formattedValue)) {
ngModel.$setViewValue(formattedValue);
if (scope.snChange) scope.snChange({
newValue: formattedValue
});
}
return ngModel.$viewValue;
};
} else {
scope.formattedDate = function(formattedValue) {
if (angular.isDefined(formattedValue)) {
scope.field.value = validate(formattedValue);
if (scope.snChange) scope.snChange({
newValue: formattedValue
});
}
return scope.field.value;
};
scope.$watch('field.value', function(newValue, oldValue) {
if (newValue != oldValue)
validate(newValue);
});
}
scope.$on('$destroy', function() {
dp.off('dp.change', onDpChange);
unBindTouchClose();
});
scope.translations = [];
i18n.getMessages(["Enter date in format", "Use format", "Entered date not valid. Enter date in format"], function(msgs) {
scope.translations = msgs;
});
}
}
});
This new directive can be used like this:
<sp-date-picker-custom sn-include-time="true"
field="{'name':'date'}"
ng-model="date1"
side-by-side="false">
</sp-date-picker-custom>
<sp-date-picker-custom sn-include-time="true"
field="{'name':'date'}"
ng-model="date2"
side-by-side="true">
</sp-date-picker-custom>

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-22-2019 10:12 AM
This worked well. I can't seem to get the datepicker to be required however. Any advice?
<sp-date-picker-custom name="board_ex_date" id="board_ex_date" sn-include-time="false"
field="{'name':'board_ex_date'}"
side-by-side="true"
ng-model="c.board_ex_date"
ng-required="true">
</sp-date-picker-custom>

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-27-2020 04:05 PM