lib/client lib/kolab_client_task.php lib/locale public_html/js public_html/skins
Aleksander Machniak
machniak at kolabsys.com
Tue Apr 15 10:39:15 CEST 2014
lib/client/kolab_client_task_settings.php | 2
lib/client/kolab_client_task_sharedfolder.php | 11
lib/kolab_client_task.php | 14
lib/locale/en_US.php | 32
public_html/js/jquery.datetimepicker.js | 1287 ++++++++++++++++++++
public_html/js/kolab_admin.js | 346 +++++
public_html/skins/default/jquery.datetimepicker.css | 304 ++++
public_html/skins/default/style.css | 42
public_html/skins/default/templates/main.html | 2
9 files changed, 2029 insertions(+), 11 deletions(-)
New commits:
commit 932aac40676bfff20032145437f7c99819d82e4a
Author: Aleksander Machniak <machniak at kolabsys.com>
Date: Tue Apr 15 10:37:41 2014 +0200
Added IMAP ACL field widget (Request #1752)
TODO: user autocompletion, default rights, add acl field for shared folders
diff --git a/lib/client/kolab_client_task_settings.php b/lib/client/kolab_client_task_settings.php
index 56feb97..2731120 100644
--- a/lib/client/kolab_client_task_settings.php
+++ b/lib/client/kolab_client_task_settings.php
@@ -33,7 +33,7 @@ class kolab_client_task_settings extends kolab_client_task
protected $form_element_types = array(
'text', 'select', 'multiselect', 'list', 'list-autocomplete', 'checkbox', 'password', 'ldap_url',
- 'text-quota', 'aci',
+ 'text-quota', 'aci', 'imap_acl',
);
diff --git a/lib/client/kolab_client_task_sharedfolder.php b/lib/client/kolab_client_task_sharedfolder.php
index 441e11a..e2d4d18 100644
--- a/lib/client/kolab_client_task_sharedfolder.php
+++ b/lib/client/kolab_client_task_sharedfolder.php
@@ -68,13 +68,10 @@ class kolab_client_task_sharedfolder extends kolab_client_task
*/
public function action_info()
{
- $id = $this->get_input('id', 'POST');
- $result = $this->api_get('sharedfolder.info', array('id' => $id));
- $sharedfolder = $result->get();
-
- //console("action_info()", $sharedfolder);
-
- $output = $this->sharedfolder_form(null, $sharedfolder);
+ $id = $this->get_input('id', 'POST');
+ $result = $this->api_get('sharedfolder.info', array('id' => $id));
+ $data = $result->get();
+ $output = $this->sharedfolder_form(null, $data);
$this->output->set_object('taskcontent', $output);
}
diff --git a/lib/kolab_client_task.php b/lib/kolab_client_task.php
index 8d95fba..370ad64 100644
--- a/lib/kolab_client_task.php
+++ b/lib/kolab_client_task.php
@@ -897,6 +897,20 @@ class kolab_client_task
);
break;
+ case 'imap_acl':
+ $result['type'] = kolab_form::INPUT_TEXTAREA;
+ $result['data-type'] = 'acl';
+
+ $this->output->add_translation('aci.new', 'aci.edit', 'aci.remove',
+ 'button.ok', 'button.cancel',
+ 'acl.read', 'acl.write', 'acl.append', 'acl.post', 'acl.all', 'acl.custom',
+ 'acl.l', 'acl.r', 'acl.s', 'acl.w', 'acl.i', 'acl.p', 'acl.k', 'acl.a',
+ 'acl.x', 'acl.t', 'acl.n', 'acl.e', 'acl.d', 'acl.anyone', 'acl.anonymous',
+ 'acl.identifier', 'acl.rights', 'acl.expire', 'acl.user',
+ 'acl.error.invaliddate', 'acl.error.nouser', 'acl.error.subjectexists', 'acl.error.norights'
+ );
+ break;
+
default:
$result['type'] = kolab_form::INPUT_TEXT;
diff --git a/lib/locale/en_US.php b/lib/locale/en_US.php
index bc74504..e36977d 100644
--- a/lib/locale/en_US.php
+++ b/lib/locale/en_US.php
@@ -56,6 +56,37 @@ $LANG['aci.thisentry'] = 'This entry';
$LANG['aci.selected'] = 'all selected';
$LANG['aci.other'] = 'all except selected';
+$LANG['acl.read'] = 'read';
+$LANG['acl.write'] = 'write';
+$LANG['acl.post'] = 'post';
+$LANG['acl.append'] = 'append';
+$LANG['acl.all'] = 'all';
+$LANG['acl.custom'] = 'custom...';
+$LANG['acl.l'] = 'Lookup';
+$LANG['acl.r'] = 'Read messages';
+$LANG['acl.s'] = 'Keep Seen state';
+$LANG['acl.w'] = 'Write flags';
+$LANG['acl.i'] = 'Insert (Copy into)';
+$LANG['acl.p'] = 'Post';
+$LANG['acl.c'] = 'Create subfolders';
+$LANG['acl.k'] = 'Create subfolders';
+$LANG['acl.d'] = 'Delete messages';
+$LANG['acl.t'] = 'Delete messages';
+$LANG['acl.e'] = 'Expunge';
+$LANG['acl.x'] = 'Delete folder';
+$LANG['acl.a'] = 'Administer';
+$LANG['acl.n'] = 'Annotate messages';
+$LANG['acl.identifier'] = 'Identifier';
+$LANG['acl.rights'] = 'Access Rights';
+$LANG['acl.expire'] = 'Expires On';
+$LANG['acl.user'] = 'User...';
+$LANG['acl.anyone'] = 'All users (anyone)';
+$LANG['acl.anonymous'] = 'Guests (anonymous)';
+$LANG['acl.error.invaliddate'] = 'Invalid date format!';
+$LANG['acl.error.norights'] = 'No access rights specified!';
+$LANG['acl.error.subjectexists'] = 'Access rights for specified identifier already exist!';
+$LANG['acl.error.nouser'] = 'User identifier not specified!';
+
$LANG['add'] = 'Add';
$LANG['api.notypeid'] = 'No object type ID specified!';
@@ -254,6 +285,7 @@ $LANG['servererror'] = 'Server Error!';
$LANG['session.expired'] = 'Session has expired. Login again, please';
+$LANG['sharedfolder.acl'] = 'IMAP Access Rights';
$LANG['sharedfolder.add'] = 'Add Shared Folder';
$LANG['sharedfolder.add.success'] = 'Shared folder created successfully.';
$LANG['sharedfolder.alias'] = 'Secondary Email Address(es)';
diff --git a/public_html/js/jquery.datetimepicker.js b/public_html/js/jquery.datetimepicker.js
new file mode 100644
index 0000000..bf64572
--- /dev/null
+++ b/public_html/js/jquery.datetimepicker.js
@@ -0,0 +1,1287 @@
+/**
+ * @preserve jQuery DateTimePicker plugin v2.2.5
+ * @homepage http://xdsoft.net/jqplugins/datetimepicker/
+ * (c) 2014, Chupurnov Valeriy.
+ */
+(function( $ ) {
+ 'use strict'
+ var default_options = {
+ i18n:{
+ ru:{ // Russian
+ months:[
+ 'ЯнваÑÑ','ФевÑалÑ','ÐаÑÑ','ÐпÑелÑ','Ðай','ÐÑнÑ','ÐÑлÑ','ÐвгÑÑÑ','СенÑÑбÑÑ','ÐкÑÑбÑÑ','ÐоÑбÑÑ','ÐекабÑÑ'
+ ],
+ dayOfWeek:[
+ "ÐÑк", "Ðн", "ÐÑ", "СÑ", "ЧÑ", "ÐÑ", "Сб"
+ ]
+ },
+ en:{ // English
+ months: [
+ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
+ ],
+ dayOfWeek: [
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ ]
+ },
+ de:{ // German
+ months:[
+ 'Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'
+ ],
+ dayOfWeek:[
+ "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"
+ ]
+ },
+ nl:{ // Dutch
+ months:[
+ "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"
+ ],
+ dayOfWeek:[
+ "zo", "ma", "di", "wo", "do", "vr", "za"
+ ]
+ },
+ tr:{ // Turkish
+ months:[
+ "Ocak", "Åubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "AÄustos", "Eylül", "Ekim", "Kasım", "Aralık"
+ ],
+ dayOfWeek:[
+ "Paz", "Pts", "Sal", "Ãar", "Per", "Cum", "Cts"
+ ]
+ },
+ fr:{ //French
+ months:[
+ "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"
+ ],
+ dayOfWeek:[
+ "Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"
+ ]
+ },
+ es:{ // Spanish
+ months: [
+ "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
+ ],
+ dayOfWeek: [
+ "Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"
+ ]
+ },
+ th:{ // Thai
+ months:[
+ 'มà¸à¸£à¸²à¸à¸¡','à¸à¸¸à¸¡à¸ าà¸à¸±à¸à¸à¹','มีà¸à¸²à¸à¸¡','à¹à¸¡à¸©à¸²à¸¢à¸','à¸à¸¤à¸©à¸ าà¸à¸¡','มิà¸à¸¸à¸à¸²à¸¢à¸','à¸à¸£à¸à¸à¸²à¸à¸¡','สิà¸à¸«à¸²à¸à¸¡','à¸à¸±à¸à¸¢à¸²à¸¢à¸','à¸à¸¸à¸¥à¸²à¸à¸¡','à¸à¸¤à¸¨à¸à¸´à¸à¸²à¸¢à¸','à¸à¸±à¸à¸§à¸²à¸à¸¡'
+ ],
+ dayOfWeek:[
+ 'à¸à¸².','à¸.','à¸.','à¸.','à¸à¸¤.','ศ.','ส.'
+ ]
+ },
+ pl:{ // Polish
+ months: [
+ "styczeÅ", "luty", "marzec", "kwiecieÅ", "maj", "czerwiec", "lipiec", "sierpieÅ", "wrzesieÅ", "październik", "listopad", "grudzieÅ"
+ ],
+ dayOfWeek: [
+ "nd", "pn", "wt", "År", "cz", "pt", "sb"
+ ]
+ },
+ pt:{ // Portuguese
+ months: [
+ "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
+ ],
+ dayOfWeek: [
+ "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"
+ ]
+ },
+ ch:{ // Simplified Chinese
+ months: [
+ "ä¸æ","äºæ","ä¸æ","åæ","äºæ","å
æ","ä¸æ","å
«æ","ä¹æ","åæ","åä¸æ","åäºæ"
+ ],
+ dayOfWeek: [
+ "æ¥", "ä¸","äº","ä¸","å","äº","å
"
+ ]
+ },
+ se:{ // Swedish
+ months: [
+ "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September","Oktober", "November", "December"
+ ],
+ dayOfWeek: [
+ "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
+ ]
+ },
+ kr:{ // Korean
+ months: [
+ "1ì", "2ì", "3ì", "4ì", "5ì", "6ì", "7ì", "8ì", "9ì", "10ì", "11ì", "12ì"
+ ],
+ dayOfWeek: [
+ "ì¼", "ì", "í", "ì", "목", "ê¸", "í "
+ ]
+ },
+ it:{ // Italian
+ months: [
+ "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"
+ ],
+ dayOfWeek: [
+ "Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"
+ ]
+ },
+ da:{ // Dansk
+ months: [
+ "January", "Februar", "Marts", "April", "Maj", "Juni", "July", "August", "September", "Oktober", "November", "December"
+ ],
+ dayOfWeek: [
+ "Søn", "Man", "Tir", "ons", "Tor", "Fre", "lør"
+ ]
+ },
+ ja:{ // Japanese
+ months: [
+ "1æ", "2æ", "3æ", "4æ", "5æ", "6æ", "7æ", "8æ", "9æ", "10æ", "11æ", "12æ"
+ ],
+ dayOfWeek: [
+ "æ¥", "æ", "ç«", "æ°´", "æ¨", "é", "å"
+ ]
+ }
+ },
+ value:'',
+ lang: 'en',
+
+ format: 'Y/m/d H:i',
+ formatTime: 'H:i',
+ formatDate: 'Y/m/d',
+
+ startDate: false, // new Date(), '1986/12/08', '-1970/01/05','-1970/01/05',
+
+ //fromUnixtime: false,
+
+ step:60,
+
+ closeOnDateSelect:false,
+ closeOnWithoutClick:true,
+
+ timepicker:true,
+ datepicker:true,
+
+ minDate:false,
+ maxDate:false,
+ minTime:false,
+ maxTime:false,
+
+ allowTimes:[],
+ opened:false,
+ initTime:true,
+ inline:false,
+
+ onSelectDate:function() {},
+ onSelectTime:function() {},
+ onChangeMonth:function() {},
+ onChangeDateTime:function() {},
+ onShow:function() {},
+ onClose:function() {},
+ onGenerate:function() {},
+
+ withoutCopyright:true,
+
+ inverseButton:false,
+ hours12:false,
+ next: 'xdsoft_next',
+ prev : 'xdsoft_prev',
+ dayOfWeekStart:0,
+
+ timeHeightInTimePicker:25,
+ timepickerScrollbar:true,
+
+ todayButton:true, // 2.1.0
+ defaultSelect:true, // 2.1.0
+
+ scrollMonth:true,
+ scrollTime:true,
+ scrollInput:true,
+
+ lazyInit:false,
+
+ mask:false,
+ validateOnBlur:true,
+ allowBlank:true,
+
+ yearStart:1950,
+ yearEnd:2050,
+
+ style:'',
+ id:'',
+
+ roundTime:'round', // ceil, floor
+ className:'',
+
+ weekends : [],
+ yearOffset:0
+ };
+
+ // fix for ie8
+ if ( !Array.prototype.indexOf ) {
+ Array.prototype.indexOf = function(obj, start) {
+ for (var i = (start || 0), j = this.length; i < j; i++) {
+ if (this[i] === obj) { return i; }
+ }
+ return -1;
+ }
+ };
+
+ $.fn.xdsoftScroller = function( _percent ) {
+ return this.each(function() {
+ var timeboxparent = $(this);
+ if( !$(this).hasClass('xdsoft_scroller_box') ) {
+ var pointerEventToXY = function( e ) {
+ var out = {x:0, y:0};
+ if( e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend' || e.type == 'touchcancel' ) {
+ var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
+ out.x = touch.pageX;
+ out.y = touch.pageY;
+ }else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove' || e.type == 'mouseover'|| e.type=='mouseout' || e.type=='mouseenter' || e.type=='mouseleave') {
+ out.x = e.pageX;
+ out.y = e.pageY;
+ }
+ return out;
+ },
+ move = 0,
+ timebox = timeboxparent.children().eq(0),
+ parentHeight = timeboxparent[0].clientHeight,
+ height = timebox[0].offsetHeight,
+ scrollbar = $('<div class="xdsoft_scrollbar"></div>'),
+ scroller = $('<div class="xdsoft_scroller"></div>'),
+ maximumOffset = 100,
+ start = false;
+
+ scrollbar.append(scroller);
+
+ timeboxparent.addClass('xdsoft_scroller_box').append(scrollbar);
+ scroller.on('mousedown.xdsoft_scroller',function ( event ) {
+ if( !parentHeight )
+ timeboxparent.trigger('resize_scroll.xdsoft_scroller',[_percent]);
+ var pageY = event.pageY,
+ top = parseInt(scroller.css('margin-top')),
+ h1 = scrollbar[0].offsetHeight;
+ $(document.body).addClass('xdsoft_noselect');
+ $([document.body,window]).on('mouseup.xdsoft_scroller',function arguments_callee() {
+ $([document.body,window]).off('mouseup.xdsoft_scroller',arguments_callee)
+ .off('mousemove.xdsoft_scroller',move)
+ .removeClass('xdsoft_noselect');
+ });
+ $(document.body).on('mousemove.xdsoft_scroller',move = function(event) {
+ var offset = event.pageY-pageY+top;
+ if( offset<0 )
+ offset = 0;
+ if( offset+scroller[0].offsetHeight>h1 )
+ offset = h1-scroller[0].offsetHeight;
+ timeboxparent.trigger('scroll_element.xdsoft_scroller',[maximumOffset?offset/maximumOffset:0]);
+ });
+ });
+
+ timeboxparent
+ .on('scroll_element.xdsoft_scroller',function( event,percent ) {
+ if( !parentHeight )
+ timeboxparent.trigger('resize_scroll.xdsoft_scroller',[percent,true]);
+ percent = percent>1?1:(percent<0||isNaN(percent))?0:percent;
+ scroller.css('margin-top',maximumOffset*percent);
+ timebox.css('marginTop',-parseInt((height-parentHeight)*percent))
+ })
+ .on('resize_scroll.xdsoft_scroller',function( event,_percent,noTriggerScroll ) {
+ parentHeight = timeboxparent[0].clientHeight;
+ height = timebox[0].offsetHeight;
+ var percent = parentHeight/height,
+ sh = percent*scrollbar[0].offsetHeight;
+ if( percent>1 )
+ scroller.hide();
+ else{
+ scroller.show();
+ scroller.css('height',parseInt(sh>10?sh:10));
+ maximumOffset = scrollbar[0].offsetHeight-scroller[0].offsetHeight;
+ if( noTriggerScroll!==true )
+ timeboxparent.trigger('scroll_element.xdsoft_scroller',[_percent?_percent:Math.abs(parseInt(timebox.css('marginTop')))/(height-parentHeight)]);
+ }
+ });
+ timeboxparent.mousewheel&&timeboxparent.mousewheel(function(event, delta, deltaX, deltaY) {
+ var top = Math.abs(parseInt(timebox.css('marginTop')));
+ timeboxparent.trigger('scroll_element.xdsoft_scroller',[(top-delta*20)/(height-parentHeight)]);
+ event.stopPropagation();
+ return false;
+ });
+ timeboxparent.on('touchstart',function( event ) {
+ start = pointerEventToXY(event);
+ });
+ timeboxparent.on('touchmove',function( event ) {
+ if( start ) {
+ var coord = pointerEventToXY(event), top = Math.abs(parseInt(timebox.css('marginTop')));
+ timeboxparent.trigger('scroll_element.xdsoft_scroller',[(top-(coord.y-start.y))/(height-parentHeight)]);
+ event.stopPropagation();
+ event.preventDefault();
+ };
+ });
+ timeboxparent.on('touchend touchcancel',function( event ) {
+ start = false;
+ });
+ }
+ timeboxparent.trigger('resize_scroll.xdsoft_scroller',[_percent]);
+ });
+ };
+ $.fn.datetimepicker = function( opt ) {
+ var KEY0 = 48,
+ KEY9 = 57,
+ _KEY0 = 96,
+ _KEY9 = 105,
+ CTRLKEY = 17,
+ DEL = 46,
+ ENTER = 13,
+ ESC = 27,
+ BACKSPACE = 8,
+ ARROWLEFT = 37,
+ ARROWUP = 38,
+ ARROWRIGHT = 39,
+ ARROWDOWN = 40,
+ TAB = 9,
+ F5 = 116,
+ AKEY = 65,
+ CKEY = 67,
+ VKEY = 86,
+ ZKEY = 90,
+ YKEY = 89,
+ ctrlDown = false,
+ options = ($.isPlainObject(opt)||!opt)?$.extend(true,{},default_options,opt):$.extend({},default_options),
+
+ lazyInitTimer = 0,
+
+ lazyInit = function( input ){
+ input
+ .on('open.xdsoft focusin.xdsoft mousedown.xdsoft',function initOnActionCallback(event) {
+ if( input.is(':disabled')||input.is(':hidden')||!input.is(':visible')||input.data( 'xdsoft_datetimepicker') )
+ return;
+
+ clearTimeout(lazyInitTimer);
+
+ lazyInitTimer = setTimeout(function() {
+
+ if( !input.data( 'xdsoft_datetimepicker') )
+ createDateTimePicker(input);
+
+ input
+ .off('open.xdsoft focusin.xdsoft mousedown.xdsoft',initOnActionCallback)
+ .trigger('open.xdsoft');
+ },100);
+
+ });
+ },
+
+ createDateTimePicker = function( input ) {
+
+ var datetimepicker = $('<div '+(options.id?'id="'+options.id+'"':'')+' '+(options.style?'style="'+options.style+'"':'')+' class="xdsoft_datetimepicker xdsoft_noselect '+options.className+'"></div>'),
+ xdsoft_copyright = $('<div class="xdsoft_copyright"><a target="_blank" href="http://xdsoft.net/jqplugins/datetimepicker/">xdsoft.net</a></div>'),
+ datepicker = $('<div class="xdsoft_datepicker active"></div>'),
+ mounth_picker = $('<div class="xdsoft_mounthpicker"><button type="button" class="xdsoft_prev"></button><button type="button" class="xdsoft_today_button"></button><div class="xdsoft_label xdsoft_month"><span></span></div><div class="xdsoft_label xdsoft_year"><span></span></div><button type="button" class="xdsoft_next"></button></div>'),
+ calendar = $('<div class="xdsoft_calendar"></div>'),
+ timepicker = $('<div class="xdsoft_timepicker active"><button type="button" class="xdsoft_prev"></button><div class="xdsoft_time_box"></div><button type="button" class="xdsoft_next"></button></div>'),
+ timeboxparent = timepicker.find('.xdsoft_time_box').eq(0),
+ timebox = $('<div class="xdsoft_time_variant"></div>'),
+ scrollbar = $('<div class="xdsoft_scrollbar"></div>'),
+ scroller = $('<div class="xdsoft_scroller"></div>'),
+ monthselect =$('<div class="xdsoft_select xdsoft_monthselect"><div></div></div>'),
+ yearselect =$('<div class="xdsoft_select xdsoft_yearselect"><div></div></div>');
+
+ //constructor lego
+ mounth_picker
+ .find('.xdsoft_month span')
+ .after(monthselect);
+ mounth_picker
+ .find('.xdsoft_year span')
+ .after(yearselect);
+
+ mounth_picker
+ .find('.xdsoft_month,.xdsoft_year')
+ .on('mousedown.xdsoft',function(event) {
+ mounth_picker
+ .find('.xdsoft_select')
+ .hide();
+
+ var select = $(this).find('.xdsoft_select').eq(0),
+ val = 0,
+ top = 0;
+
+ if( _xdsoft_datetime.currentTime )
+ val = _xdsoft_datetime.currentTime[$(this).hasClass('xdsoft_month')?'getMonth':'getFullYear']();
+
+ select.show();
+
+ for(var items = select.find('div.xdsoft_option'),i = 0;i<items.length;i++) {
+ if( items.eq(i).data('value')==val ) {
+ break;
+ }else top+=items[0].offsetHeight;
+ }
+
+ select.xdsoftScroller(top/(select.children()[0].offsetHeight-(select[0].clientHeight)));
+ event.stopPropagation();
+
+ return false;
+ });
+
+ mounth_picker
+ .find('.xdsoft_select')
+ .xdsoftScroller()
+ .on('mousedown.xdsoft',function( event ) {
+ event.stopPropagation();
+ event.preventDefault();
+ })
+ .on('mousedown.xdsoft','.xdsoft_option',function( event ) {
+ if( _xdsoft_datetime&&_xdsoft_datetime.currentTime )
+ _xdsoft_datetime.currentTime[$(this).parent().parent().hasClass('xdsoft_monthselect')?'setMonth':'setFullYear']($(this).data('value'));
+
+ $(this).parent().parent().hide();
+
+ datetimepicker.trigger('xchange.xdsoft');
+ options.onChangeMonth&&options.onChangeMonth.call&&options.onChangeMonth.call(datetimepicker,_xdsoft_datetime.currentTime,datetimepicker.data('input'));
+ });
+
+
+ // set options
+ datetimepicker.setOptions = function( _options ) {
+ options = $.extend(true,{},options,_options);
+
+ if( _options.allowTimes && $.isArray(_options.allowTimes) && _options.allowTimes.length ){
+ options['allowTimes'] = $.extend(true,[],_options.allowTimes);
+ }
+
+ if( _options.weekends && $.isArray(_options.weekends) && _options.weekends.length ){
+ options['weekends'] = $.extend(true,[],_options.weekends);
+ }
+
+ if( (options.open||options.opened)&&(!options.inline) ) {
+ input.trigger('open.xdsoft');
+ }
+
+ if( options.inline ) {
+ datetimepicker.addClass('xdsoft_inline');
+ input.after(datetimepicker).hide();
+ datetimepicker.trigger('afterOpen.xdsoft');
+ }
+
+ if( options.inverseButton ) {
+ options.next = 'xdsoft_prev';
+ options.prev = 'xdsoft_next';
+ }
+
+ if( options.datepicker )
+ datepicker.addClass('active');
+ else
+ datepicker.removeClass('active');
+
+ if( options.timepicker )
+ timepicker.addClass('active');
+ else
+ timepicker.removeClass('active');
+
+ if( options.value ){
+ input&&input.val&&input.val(options.value);
+ _xdsoft_datetime.setCurrentTime(options.value);
+ }
+
+ if( isNaN(options.dayOfWeekStart)||parseInt(options.dayOfWeekStart)<0||parseInt(options.dayOfWeekStart)>6 )
+ options.dayOfWeekStart = 0;
+ else
+ options.dayOfWeekStart = parseInt(options.dayOfWeekStart);
+
+ if( !options.timepickerScrollbar )
+ scrollbar.hide();
+
+ if( options.minDate && /^-(.*)$/.test(options.minDate) ){
+ options.minDate = _xdsoft_datetime.strToDateTime(options.minDate).dateFormat( options.formatDate );
+ }
+
+ if( options.maxDate && /^\+(.*)$/.test(options.maxDate) ) {
+ options.maxDate = _xdsoft_datetime.strToDateTime(options.maxDate).dateFormat( options.formatDate );
+ }
+
+ mounth_picker
+ .find('.xdsoft_today_button')
+ .css('visibility',!options.todayButton?'hidden':'visible');
+
+ if( options.mask ) {
+ var e,
+ getCaretPos = function ( input ) {
+ try{
+ if ( document.selection && document.selection.createRange ) {
+ var range = document.selection.createRange();
+ return range.getBookmark().charCodeAt(2) - 2;
+ }else
+ if ( input.setSelectionRange )
+ return input.selectionStart;
+ }catch(e) {
+ return 0;
+ }
+ },
+ setCaretPos = function ( node,pos ) {
+ var node = (typeof node == "string" || node instanceof String) ? document.getElementById(node) : node;
+ if(!node) {
+ return false;
+ }else if(node.createTextRange) {
+ var textRange = node.createTextRange();
+ textRange.collapse(true);
+ textRange.moveEnd(pos);
+ textRange.moveStart(pos);
+ textRange.select();
+ return true;
+ }else if(node.setSelectionRange) {
+ node.setSelectionRange(pos,pos);
+ return true;
+ }
+ return false;
+ },
+ isValidValue = function ( mask,value ) {
+ var reg = mask
+ .replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g,'\\$1')
+ .replace(/_/g,'{digit+}')
+ .replace(/([0-9]{1})/g,'{digit$1}')
+ .replace(/\{digit([0-9]{1})\}/g,'[0-$1_]{1}')
+ .replace(/\{digit[\+]\}/g,'[0-9_]{1}');
+ return RegExp(reg).test(value);
+ };
+ input.off('keydown.xdsoft');
+ switch(true) {
+ case ( options.mask===true ):
+
+ options.mask = options.format
+ .replace(/Y/g,'9999')
+ .replace(/F/g,'9999')
+ .replace(/m/g,'19')
+ .replace(/d/g,'39')
+ .replace(/H/g,'29')
+ .replace(/i/g,'59')
+ .replace(/s/g,'59');
+
+ case ( $.type(options.mask) == 'string' ):
+
+ if( !isValidValue( options.mask,input.val() ) )
+ input.val(options.mask.replace(/[0-9]/g,'_'));
+
+ input.on('keydown.xdsoft',function( event ) {
+ var val = this.value,
+ key = event.which;
+
+ switch(true) {
+ case (( key>=KEY0&&key<=KEY9 )||( key>=_KEY0&&key<=_KEY9 ))||(key==BACKSPACE||key==DEL):
+ var pos = getCaretPos(this),
+ digit = ( key!=BACKSPACE&&key!=DEL )?String.fromCharCode((_KEY0 <= key && key <= _KEY9)? key-KEY0 : key):'_';
+
+ if( (key==BACKSPACE||key==DEL)&&pos ) {
+ pos--;
+ digit='_';
+ }
+
+ while( /[^0-9_]/.test(options.mask.substr(pos,1))&&pos<options.mask.length&&pos>0 )
+ pos+=( key==BACKSPACE||key==DEL )?-1:1;
+
+ val = val.substr(0,pos)+digit+val.substr(pos+1);
+ if( $.trim(val)=='' ){
+ val = options.mask.replace(/[0-9]/g,'_');
+ }else{
+ if( pos==options.mask.length )
+ break;
+ }
+
+ pos+=(key==BACKSPACE||key==DEL)?0:1;
+ while( /[^0-9_]/.test(options.mask.substr(pos,1))&&pos<options.mask.length&&pos>0 )
+ pos+=(key==BACKSPACE||key==DEL)?-1:1;
+
+ if( isValidValue( options.mask,val ) ) {
+ this.value = val;
+ setCaretPos(this,pos);
+ }else if( $.trim(val)=='' )
+ this.value = options.mask.replace(/[0-9]/g,'_');
+ else{
+ input.trigger('error_input.xdsoft');
+ }
+ break;
+ case ( !!~([AKEY,CKEY,VKEY,ZKEY,YKEY].indexOf(key))&&ctrlDown ):
+ case !!~([ESC,ARROWUP,ARROWDOWN,ARROWLEFT,ARROWRIGHT,F5,CTRLKEY,TAB,ENTER].indexOf(key)):
+ return true;
+ }
+ event.preventDefault();
+ return false;
+ });
+ break;
+ }
+ }
+ if( options.validateOnBlur ) {
+ input
+ .off('blur.xdsoft')
+ .on('blur.xdsoft', function() {
+ if( options.allowBlank && !$.trim($(this).val()).length ) {
+ $(this).val(null);
+ datetimepicker.data('xdsoft_datetime').empty();
+ }else if( !Date.parseDate( $(this).val(), options.format ) ) {
+ $(this).val((_xdsoft_datetime.now()).dateFormat( options.format ));
+ datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val());
+ }
+ else{
+ datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val());
+ }
+ datetimepicker.trigger('changedatetime.xdsoft');
+ });
+ }
+ options.dayOfWeekStartPrev = (options.dayOfWeekStart==0)?6:options.dayOfWeekStart-1;
+ datetimepicker
+ .trigger('xchange.xdsoft');
+ };
+
+ datetimepicker
+ .data('options',options)
+ .on('mousedown.xdsoft',function( event ) {
+ event.stopPropagation();
+ event.preventDefault();
+ yearselect.hide();
+ monthselect.hide();
+ return false;
+ });
+
+ var scroll_element = timepicker.find('.xdsoft_time_box');
+ scroll_element.append(timebox);
+ scroll_element.xdsoftScroller();
+ datetimepicker.on('afterOpen.xdsoft',function() {
+ scroll_element.xdsoftScroller();
+ });
+
+ datetimepicker
+ .append(datepicker)
+ .append(timepicker);
+
+ if( options.withoutCopyright!==true )
+ datetimepicker
+ .append(xdsoft_copyright);
+
+ datepicker
+ .append(mounth_picker)
+ .append(calendar);
+
+ $('body').append(datetimepicker);
+
+ var _xdsoft_datetime = new function() {
+ var _this = this;
+ _this.now = function() {
+ var d = new Date();
+ if( options.yearOffset )
+ d.setFullYear(d.getFullYear()+options.yearOffset);
+ return d;
+ };
+
+ _this.currentTime = this.now();
+ _this.isValidDate = function (d) {
+ if ( Object.prototype.toString.call(d) !== "[object Date]" )
+ return false;
+ return !isNaN(d.getTime());
+ };
+
+ _this.setCurrentTime = function( dTime) {
+ _this.currentTime = (typeof dTime == 'string')? _this.strToDateTime(dTime) : _this.isValidDate(dTime) ? dTime: _this.now();
+ datetimepicker.trigger('xchange.xdsoft');
+ };
+
+ _this.empty = function() {
+ _this.currentTime = null;
+ };
+
+ _this.getCurrentTime = function( dTime) {
+ return _this.currentTime;
+ };
+
+ _this.nextMonth = function() {
+ var month = _this.currentTime.getMonth()+1;
+ if( month==12 ) {
+ _this.currentTime.setFullYear(_this.currentTime.getFullYear()+1);
+ month = 0;
+ }
+ _this.currentTime.setDate(
+ Math.min(
+ Date.daysInMonth[month],
+ _this.currentTime.getDate()
+ )
+ )
+ _this.currentTime.setMonth(month);
+ options.onChangeMonth&&options.onChangeMonth.call&&options.onChangeMonth.call(datetimepicker,_xdsoft_datetime.currentTime,datetimepicker.data('input'));
+ datetimepicker.trigger('xchange.xdsoft');
+ return month;
+ };
+
+ _this.prevMonth = function() {
+ var month = _this.currentTime.getMonth()-1;
+ if( month==-1 ) {
+ _this.currentTime.setFullYear(_this.currentTime.getFullYear()-1);
+ month = 11;
+ }
+ _this.currentTime.setDate(
+ Math.min(
+ Date.daysInMonth[month],
+ _this.currentTime.getDate()
+ )
+ )
+ _this.currentTime.setMonth(month);
+ options.onChangeMonth&&options.onChangeMonth.call&&options.onChangeMonth.call(datetimepicker,_xdsoft_datetime.currentTime,datetimepicker.data('input'));
+ datetimepicker.trigger('xchange.xdsoft');
+ return month;
+ };
+
+ _this.strToDateTime = function( sDateTime ) {
+ var tmpDate = [],timeOffset,currentTime;
+
+ if( ( tmpDate = /^(\+|\-)(.*)$/.exec(sDateTime) ) && ( tmpDate[2]=Date.parseDate(tmpDate[2], options.formatDate) ) ) {
+ timeOffset = tmpDate[2].getTime()-1*(tmpDate[2].getTimezoneOffset())*60000;
+ currentTime = new Date((_xdsoft_datetime.now()).getTime()+parseInt(tmpDate[1]+'1')*timeOffset);
+ }else
+ currentTime = sDateTime?Date.parseDate(sDateTime, options.format):_this.now();
+
+ if( !_this.isValidDate(currentTime) )
+ currentTime = _this.now();
+
+ return currentTime;
+ };
+
+ _this.strtodate = function( sDate ) {
+ var currentTime = sDate?Date.parseDate(sDate, options.formatDate):_this.now();
+ if( !_this.isValidDate(currentTime) )
+ currentTime = _this.now();
+ return currentTime;
+ };
+
+ _this.strtotime = function( sTime ) {
+ var currentTime = sTime?Date.parseDate(sTime, options.formatTime):_this.now();
+ if( !_this.isValidDate(currentTime) )
+ currentTime = _this.now();
+ return currentTime;
+ };
+
+ _this.str = function() {
+ return _this.currentTime.dateFormat(options.format);
+ };
+ };
+ mounth_picker
+ .find('.xdsoft_today_button')
+ .on('mousedown.xdsoft',function() {
+ datetimepicker.data('changed',true);
+ _xdsoft_datetime.setCurrentTime(0);
+ datetimepicker.trigger('afterOpen.xdsoft');
+ }).on('dblclick.xdsoft',function(){
+ input.val( _xdsoft_datetime.str() );
+ datetimepicker.trigger('close.xdsoft');
+ });
+ mounth_picker
+ .find('.xdsoft_prev,.xdsoft_next')
+ .on('mousedown.xdsoft',function() {
+ var $this = $(this),
+ timer = 0,
+ stop = false;
+
+ (function arguments_callee1(v) {
+ var month = _xdsoft_datetime.currentTime.getMonth();
+ if( $this.hasClass( options.next ) ) {
+ _xdsoft_datetime.nextMonth();
+ }else if( $this.hasClass( options.prev ) ) {
+ _xdsoft_datetime.prevMonth();
+ }
+ !stop&&(timer = setTimeout(arguments_callee1,v?v:100));
+ })(500);
+
+ $([document.body,window]).on('mouseup.xdsoft',function arguments_callee2() {
+ clearTimeout(timer);
+ stop = true;
+ $([document.body,window]).off('mouseup.xdsoft',arguments_callee2);
+ });
+ });
+
+ timepicker
+ .find('.xdsoft_prev,.xdsoft_next')
+ .on('mousedown.xdsoft',function() {
+ var $this = $(this),
+ timer = 0,
+ stop = false,
+ period = 110;
+ (function arguments_callee4(v) {
+ var pheight = timeboxparent[0].clientHeight,
+ height = timebox[0].offsetHeight,
+ top = Math.abs(parseInt(timebox.css('marginTop')));
+ if( $this.hasClass(options.next) && (height-pheight)- options.timeHeightInTimePicker>=top ) {
+ timebox.css('marginTop','-'+(top+options.timeHeightInTimePicker)+'px')
+ }else if( $this.hasClass(options.prev) && top-options.timeHeightInTimePicker>=0 ) {
+ timebox.css('marginTop','-'+(top-options.timeHeightInTimePicker)+'px')
+ }
+ timeboxparent.trigger('scroll_element.xdsoft_scroller',[Math.abs(parseInt(timebox.css('marginTop'))/(height-pheight))]);
+ period= ( period>10 )?10:period-10;
+ !stop&&(timer = setTimeout(arguments_callee4,v?v:period));
+ })(500);
+ $([document.body,window]).on('mouseup.xdsoft',function arguments_callee5() {
+ clearTimeout(timer);
+ stop = true;
+ $([document.body,window])
+ .off('mouseup.xdsoft',arguments_callee5);
+ });
+ });
+
+ var xchangeTimer = 0;
+ // base handler - generating a calendar and timepicker
+ datetimepicker
+ .on('xchange.xdsoft',function( event ) {
+ clearTimeout(xchangeTimer);
+ xchangeTimer = setTimeout(function(){
+ var table = '',
+ start = new Date(_xdsoft_datetime.currentTime.getFullYear(),_xdsoft_datetime.currentTime.getMonth(),1, 12, 0, 0),
+ i = 0,
+ today = _xdsoft_datetime.now();
+
+ while( start.getDay()!=options.dayOfWeekStart )
+ start.setDate(start.getDate()-1);
+
+ //generate calendar
+ table+='<table><thead><tr>';
+
+ // days
+ for(var j = 0; j<7; j++) {
+ table+='<th>'+options.i18n[options.lang].dayOfWeek[(j+options.dayOfWeekStart)>6?0:j+options.dayOfWeekStart]+'</th>';
+ }
+
+ table+='</tr></thead>';
+ table+='<tbody><tr>';
+ var maxDate = false, minDate = false;
+
+ if( options.maxDate!==false ) {
+ maxDate = _xdsoft_datetime.strtodate(options.maxDate);
+ maxDate = new Date(maxDate.getFullYear(),maxDate.getMonth(),maxDate.getDate(),23,59,59,999);
+ }
+
+ if( options.minDate!==false ) {
+ minDate = _xdsoft_datetime.strtodate(options.minDate);
+ minDate = new Date(minDate.getFullYear(),minDate.getMonth(),minDate.getDate());
+ }
+
+ var d,y,m,classes = [];
+
+ while( i<_xdsoft_datetime.currentTime.getDaysInMonth()||start.getDay()!=options.dayOfWeekStart||_xdsoft_datetime.currentTime.getMonth()==start.getMonth() ) {
+ classes = [];
+ i++;
+
+ d = start.getDate(); y = start.getFullYear(); m = start.getMonth();
+
+ classes.push('xdsoft_date');
+
+ if( ( maxDate!==false && start > maxDate )||( minDate!==false && start < minDate ) ){
+ classes.push('xdsoft_disabled');
+ }
+
+ if( _xdsoft_datetime.currentTime.getMonth()!=m ){
+ classes.push('xdsoft_other_month');
+ }
+
+ if( (options.defaultSelect||datetimepicker.data('changed')) && _xdsoft_datetime.currentTime.dateFormat('d.m.Y')==start.dateFormat('d.m.Y') ) {
+ classes.push('xdsoft_current');
+ }
+
+ if( today.dateFormat('d.m.Y')==start.dateFormat('d.m.Y') ) {
+ classes.push('xdsoft_today');
+ }
+
+ if( start.getDay()==0||start.getDay()==6||~options.weekends.indexOf(start.dateFormat('d.m.Y')) ) {
+ classes.push('xdsoft_weekend');
+ }
+
+ table+='<td data-date="'+d+'" data-month="'+m+'" data-year="'+y+'"'+' class="xdsoft_date xdsoft_day_of_week'+start.getDay()+' '+ classes.join(' ')+'">'+
+ '<div>'+d+'</div>'+
+ '</td>';
+
+ if( start.getDay()==options.dayOfWeekStartPrev ) {
+ table+='</tr>';
+ }
+
+ start.setDate(d+1);
+ }
+ table+='</tbody></table>';
+
+ calendar.html(table);
+
+ mounth_picker.find('.xdsoft_label span').eq(0).text(options.i18n[options.lang].months[_xdsoft_datetime.currentTime.getMonth()]);
+ mounth_picker.find('.xdsoft_label span').eq(1).text(_xdsoft_datetime.currentTime.getFullYear());
+
+ // generate timebox
+ var time = '',
+ h = '',
+ m ='',
+ line_time = function line_time( h,m ) {
+ var now = _xdsoft_datetime.now();
+ now.setHours(h);
+ h = parseInt(now.getHours());
+ now.setMinutes(m);
+ m = parseInt(now.getMinutes());
+
+ classes = [];
+ if( (options.maxTime!==false&&_xdsoft_datetime.strtotime(options.maxTime).getTime()<now.getTime())||(options.minTime!==false&&_xdsoft_datetime.strtotime(options.minTime).getTime()>now.getTime()))
+ classes.push('xdsoft_disabled');
+ if( (options.initTime||options.defaultSelect||datetimepicker.data('changed')) && parseInt(_xdsoft_datetime.currentTime.getHours())==parseInt(h)&&(options.step>59||Math[options.roundTime](_xdsoft_datetime.currentTime.getMinutes()/options.step)*options.step==parseInt(m))) {
+ if( options.defaultSelect||datetimepicker.data('changed')) {
+ classes.push('xdsoft_current');
+ } else if( options.initTime ) {
+ classes.push('xdsoft_init_time');
+ }
+ }
+ if( parseInt(today.getHours())==parseInt(h)&&parseInt(today.getMinutes())==parseInt(m))
+ classes.push('xdsoft_today');
+ time+= '<div class="xdsoft_time '+classes.join(' ')+'" data-hour="'+h+'" data-minute="'+m+'">'+now.dateFormat(options.formatTime)+'</div>';
+ };
+
+ if( !options.allowTimes || !$.isArray(options.allowTimes) || !options.allowTimes.length ) {
+ for( var i=0,j=0;i<(options.hours12?12:24);i++ ) {
+ for( j=0;j<60;j+=options.step ) {
+ h = (i<10?'0':'')+i;
+ m = (j<10?'0':'')+j;
+ line_time( h,m );
+ }
+ }
+ }else{
+ for( var i=0;i<options.allowTimes.length;i++ ) {
+ h = _xdsoft_datetime.strtotime(options.allowTimes[i]).getHours();
+ m = _xdsoft_datetime.strtotime(options.allowTimes[i]).getMinutes();
+ line_time( h,m );
+ }
+ }
+
+ timebox.html(time);
+
+ var opt = '',
+ i = 0;
+
+ for( i = parseInt(options.yearStart,10)+options.yearOffset;i<= parseInt(options.yearEnd,10)+options.yearOffset;i++ ) {
+ opt+='<div class="xdsoft_option '+(_xdsoft_datetime.currentTime.getFullYear()==i?'xdsoft_current':'')+'" data-value="'+i+'">'+i+'</div>';
+ }
+ yearselect.children().eq(0)
+ .html(opt);
+
+ for( i = 0,opt = '';i<= 11;i++ ) {
+ opt+='<div class="xdsoft_option '+(_xdsoft_datetime.currentTime.getMonth()==i?'xdsoft_current':'')+'" data-value="'+i+'">'+options.i18n[options.lang].months[i]+'</div>';
+ }
+ monthselect.children().eq(0).html(opt);
+ $(this).trigger('generate.xdsoft');
+ },10);
+ event.stopPropagation();
+ })
+ .on('afterOpen.xdsoft',function() {
+ if( options.timepicker ) {
+ var classType;
+ if( timebox.find('.xdsoft_current').length ) {
+ classType = '.xdsoft_current';
+ } else if( timebox.find('.xdsoft_init_time').length ) {
+ classType = '.xdsoft_init_time';
+ }
+
+ if( classType ) {
+ var pheight = timeboxparent[0].clientHeight,
+ height = timebox[0].offsetHeight,
+ top = timebox.find(classType).index()*options.timeHeightInTimePicker+1;
+ if( (height-pheight)<top )
+ top = height-pheight;
+ timebox.css('marginTop','-'+parseInt(top)+'px');
+ timeboxparent.trigger('scroll_element.xdsoft_scroller',[parseInt(top)/(height-pheight)]);
+ }
+ }
+ });
+
+ var timerclick = 0;
+
+ calendar
+ .on('click.xdsoft', 'td', function (xdevent) {
+ xdevent.stopPropagation(); // Prevents closing of Pop-ups, Modals and Flyouts in Bootstrap
+ timerclick++;
+ var $this = $(this),
+ currentTime = _xdsoft_datetime.currentTime;
+ if( $this.hasClass('xdsoft_disabled') )
+ return false;
+
+ currentTime.setDate( $this.data('date') );
+ currentTime.setMonth( $this.data('month') );
+ currentTime.setFullYear( $this.data('year') );
+
+ datetimepicker.trigger('select.xdsoft',[currentTime]);
+
+ input.val( _xdsoft_datetime.str() );
+ if( (timerclick>1||(options.closeOnDateSelect===true||( options.closeOnDateSelect===0&&!options.timepicker )))&&!options.inline ) {
+ datetimepicker.trigger('close.xdsoft');
+ }
+
+ if( options.onSelectDate && options.onSelectDate.call ) {
+ options.onSelectDate.call(datetimepicker,_xdsoft_datetime.currentTime,datetimepicker.data('input'));
+ }
+
+ datetimepicker.data('changed',true);
+ datetimepicker.trigger('xchange.xdsoft');
+ datetimepicker.trigger('changedatetime.xdsoft');
+ setTimeout(function(){
+ timerclick = 0;
+ },200);
+ });
+
+ timebox
+ .on('click.xdsoft', 'div', function (xdevent) {
+ xdevent.stopPropagation(); // NAJ: Prevents closing of Pop-ups, Modals and Flyouts
+ var $this = $(this),
+ currentTime = _xdsoft_datetime.currentTime;
+ if( $this.hasClass('xdsoft_disabled') )
+ return false;
+ currentTime.setHours($this.data('hour'));
+ currentTime.setMinutes($this.data('minute'));
+ datetimepicker.trigger('select.xdsoft',[currentTime]);
+
+ datetimepicker.data('input').val( _xdsoft_datetime.str() );
+
+ !options.inline&&datetimepicker.trigger('close.xdsoft');
+
+ if( options.onSelectTime&&options.onSelectTime.call ) {
+ options.onSelectTime.call(datetimepicker,_xdsoft_datetime.currentTime,datetimepicker.data('input'));
+ }
+ datetimepicker.data('changed',true);
+ datetimepicker.trigger('xchange.xdsoft');
+ datetimepicker.trigger('changedatetime.xdsoft');
+ });
+
+ datetimepicker.mousewheel&&datepicker.mousewheel(function(event, delta, deltaX, deltaY) {
+ if( !options.scrollMonth )
+ return true;
+ if( delta<0 )
+ _xdsoft_datetime.nextMonth();
+ else
+ _xdsoft_datetime.prevMonth();
+ return false;
+ });
+
+ datetimepicker.mousewheel&&timeboxparent.unmousewheel().mousewheel(function(event, delta, deltaX, deltaY) {
+ if( !options.scrollTime )
+ return true;
+ var pheight = timeboxparent[0].clientHeight,
+ height = timebox[0].offsetHeight,
+ top = Math.abs(parseInt(timebox.css('marginTop'))),
+ fl = true;
+ if( delta<0 && (height-pheight)-options.timeHeightInTimePicker>=top ) {
+ timebox.css('marginTop','-'+(top+options.timeHeightInTimePicker)+'px');
+ fl = false;
+ }else if( delta>0&&top-options.timeHeightInTimePicker>=0 ) {
+ timebox.css('marginTop','-'+(top-options.timeHeightInTimePicker)+'px');
+ fl = false;
+ }
+ timeboxparent.trigger('scroll_element.xdsoft_scroller',[Math.abs(parseInt(timebox.css('marginTop'))/(height-pheight))]);
+ event.stopPropagation();
+ return fl;
+ });
+
+ datetimepicker
+ .on('changedatetime.xdsoft',function() {
+ if( options.onChangeDateTime&&options.onChangeDateTime.call ) {
+ var $input = datetimepicker.data('input');
+ options.onChangeDateTime.call(datetimepicker, _xdsoft_datetime.currentTime, $input);
+ $input.trigger('change');
+ }
+ })
+ .on('generate.xdsoft',function() {
+ if( options.onGenerate&&options.onGenerate.call )
+ options.onGenerate.call(datetimepicker,_xdsoft_datetime.currentTime,datetimepicker.data('input'));
+ });
+
+ var current_time_index = 0;
+ input.mousewheel&&input.mousewheel(function( event, delta, deltaX, deltaY ) {
+ if( !options.scrollInput )
+ return true;
+ if( !options.datepicker && options.timepicker ) {
+ current_time_index = timebox.find('.xdsoft_current').length?timebox.find('.xdsoft_current').eq(0).index():0;
+ if( current_time_index+delta>=0&¤t_time_index+delta<timebox.children().length )
+ current_time_index+=delta;
+ timebox.children().eq(current_time_index).length&&timebox.children().eq(current_time_index).trigger('mousedown');
+ return false;
+ }else if( options.datepicker && !options.timepicker ) {
+ datepicker.trigger( event, [delta, deltaX, deltaY]);
+ input.val&&input.val( _xdsoft_datetime.str() );
+ datetimepicker.trigger('changedatetime.xdsoft');
+ return false;
+ }
+ });
+ var setPos = function() {
+ var offset = datetimepicker.data('input').offset(), top = offset.top+datetimepicker.data('input')[0].offsetHeight-1, left = offset.left;
+ if( top+datetimepicker[0].offsetHeight>$(window).height()+$(window).scrollTop() )
+ top = offset.top-datetimepicker[0].offsetHeight+1;
+ if (top < 0)
+ top = 0;
+ if( left+datetimepicker[0].offsetWidth>$(window).width() )
+ left = offset.left-datetimepicker[0].offsetWidth+datetimepicker.data('input')[0].offsetWidth;
+ datetimepicker.css({
+ left:left,
+ top:top
+ });
+ };
+ datetimepicker
+ .on('open.xdsoft', function() {
+ var onShow = true;
+ if( options.onShow&&options.onShow.call) {
+ onShow = options.onShow.call(datetimepicker,_xdsoft_datetime.currentTime,datetimepicker.data('input'));
+ }
+ if( onShow!==false ) {
+ datetimepicker.show();
+ datetimepicker.trigger('afterOpen.xdsoft');
+ setPos();
+ $(window)
+ .off('resize.xdsoft',setPos)
+ .on('resize.xdsoft',setPos);
+
+ if( options.closeOnWithoutClick ) {
+ $([document.body,window]).on('mousedown.xdsoft',function arguments_callee6() {
+ datetimepicker.trigger('close.xdsoft');
+ $([document.body,window]).off('mousedown.xdsoft',arguments_callee6);
+ });
+ }
+ }
+ })
+ .on('close.xdsoft', function( event ) {
+ var onClose = true;
+ if( options.onClose&&options.onClose.call ) {
+ onClose=options.onClose.call(datetimepicker,_xdsoft_datetime.currentTime,datetimepicker.data('input'));
+ }
+ if( onClose!==false&&!options.opened&&!options.inline ) {
+ datetimepicker.hide();
+ }
+ event.stopPropagation();
+ })
+ .data('input',input);
+
+ var timer = 0,
+ timer1 = 0;
+
+ datetimepicker.data('xdsoft_datetime',_xdsoft_datetime);
+ datetimepicker.setOptions(options);
+
+ function getCurrentValue(){
+ var ct = options.value?options.value:(input&&input.val&&input.val())?input.val():'';
+
+ if( ct && _xdsoft_datetime.isValidDate(ct = Date.parseDate(ct, options.format)) ) {
+ datetimepicker.data('changed',true);
+ }else
+ ct = '';
+
+ if( !ct && options.startDate!==false ){
+ ct = _xdsoft_datetime.strToDateTime(options.startDate);
+ }
+
+ return ct?ct:0;
+ }
+
+ _xdsoft_datetime.setCurrentTime( getCurrentValue() );
+
+ datetimepicker.trigger('afterOpen.xdsoft');
+
+ input
+ .data( 'xdsoft_datetimepicker',datetimepicker )
+ .on('open.xdsoft focusin.xdsoft mousedown.xdsoft',function(event) {
+ if( input.is(':disabled')||input.is(':hidden')||!input.is(':visible') )
+ return;
+ clearTimeout(timer);
+ timer = setTimeout(function() {
+ if( input.is(':disabled')||input.is(':hidden')||!input.is(':visible') )
+ return;
+ _xdsoft_datetime.setCurrentTime(getCurrentValue());
+
+ datetimepicker.trigger('open.xdsoft');
+ },100);
+ })
+ .on('keydown.xdsoft',function( event ) {
+ var val = this.value,
+ key = event.which;
+ switch(true) {
+ case !!~([ENTER].indexOf(key)):
+ var elementSelector = $("input:visible,textarea:visible");
+ datetimepicker.trigger('close.xdsoft');
+ elementSelector.eq(elementSelector.index(this) + 1).focus();
+ return false;
+ case !!~[TAB].indexOf(key):
+ datetimepicker.trigger('close.xdsoft');
+ return true;
+ }
+ });
+ },
+ destroyDateTimePicker = function( input ) {
+ var datetimepicker = input.data('xdsoft_datetimepicker');
+ if( datetimepicker ) {
+ datetimepicker.data('xdsoft_datetime',null);
+ datetimepicker.remove();
+ input
+ .data( 'xdsoft_datetimepicker',null )
+ .off( 'open.xdsoft focusin.xdsoft focusout.xdsoft mousedown.xdsoft blur.xdsoft keydown.xdsoft' );
+ $(window).off('resize.xdsoft');
+ $([window,document.body]).off('mousedown.xdsoft');
+ input.unmousewheel&&input.unmousewheel();
+ }
+ };
+ $(document)
+ .off('keydown.xdsoftctrl keyup.xdsoftctrl')
+ .on('keydown.xdsoftctrl',function(e) {
+ if ( e.keyCode == CTRLKEY )
+ ctrlDown = true;
+ })
+ .on('keyup.xdsoftctrl',function(e) {
+ if ( e.keyCode == CTRLKEY )
+ ctrlDown = false;
+ });
+ return this.each(function() {
+ var datetimepicker;
+ if( datetimepicker = $(this).data('xdsoft_datetimepicker') ) {
+ if( $.type(opt) === 'string' ) {
+ switch(opt) {
+ case 'show':
+ $(this).select().focus();
+ datetimepicker.trigger( 'open.xdsoft' );
+ break;
+ case 'hide':
+ datetimepicker.trigger('close.xdsoft');
+ break;
+ case 'destroy':
+ destroyDateTimePicker($(this));
+ break;
+ case 'reset':
+ this.value = this.defaultValue;
+ if(!this.value || !datetimepicker.data('xdsoft_datetime').isValidDate(Date.parseDate(this.value, options.format)))
+ datetimepicker.data('changed',false);
+ datetimepicker.data('xdsoft_datetime').setCurrentTime(this.value);
+ break;
+ }
+ }else{
+ datetimepicker
+ .setOptions(opt);
+ }
+ return 0;
+ }else
+ if( ($.type(opt) !== 'string') ){
+ if( !options.lazyInit||options.open||options.inline ){
+ createDateTimePicker($(this));
+ }else
+ lazyInit($(this));
+ }
+ });
+ };
+})( jQuery );
+
+//http://www.xaprb.com/blog/2005/12/12/javascript-closures-for-runtime-efficiency/
+/*
+ * Copyright (C) 2004 Baron Schwartz <baron at sequent dot org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, version 2.1.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+Date.parseFunctions={count:0};Date.parseRegexes=[];Date.formatFunctions={count:0};Date.prototype.dateFormat=function(b){if(b=="unixtime"){return parseInt(this.getTime()/1000);}if(Date.formatFunctions[b]==null){Date.createNewFormat(b);}var a=Date.formatFunctions[b];return this[a]();};Date.createNewFormat=function(format){var funcName="format"+Date.formatFunctions.count++;Date.formatFunctions[format]=funcName;var code="Date.prototype."+funcName+" = function() {return ";var special=false;var ch="";for(var i=0;i<format.length;++i){ch=format.charAt(i);if(!special&&ch=="\\"){special=true;}else{if(special){special=false;code+="'"+String.escape(ch)+"' + ";}else{code+=Date.getFormatCode(ch);}}}eval(code.substring(0,code.length-3)+";}");};Date.getFormatCode=function(a){switch(a){case"d":return"String.leftPad(this.getDate(), 2, '0') + ";case"D":return"Date.dayNames[this.getDay()].substring(0, 3) + ";case"j":return"this.getDate() + ";case"l":return"Date.dayNames[this.getDay()] + ";case"
S":return"this.getSuffix() + ";case"w":return"this.getDay() + ";case"z":return"this.getDayOfYear() + ";case"W":return"this.getWeekOfYear() + ";case"F":return"Date.monthNames[this.getMonth()] + ";case"m":return"String.leftPad(this.getMonth() + 1, 2, '0') + ";case"M":return"Date.monthNames[this.getMonth()].substring(0, 3) + ";case"n":return"(this.getMonth() + 1) + ";case"t":return"this.getDaysInMonth() + ";case"L":return"(this.isLeapYear() ? 1 : 0) + ";case"Y":return"this.getFullYear() + ";case"y":return"('' + this.getFullYear()).substring(2, 4) + ";case"a":return"(this.getHours() < 12 ? 'am' : 'pm') + ";case"A":return"(this.getHours() < 12 ? 'AM' : 'PM') + ";case"g":return"((this.getHours() %12) ? this.getHours() % 12 : 12) + ";case"G":return"this.getHours() + ";case"h":return"String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + ";case"H":return"String.leftPad(this.getHours(), 2, '0') + ";case"i":return"String.leftPad(this.getMinutes(), 2, '0') + ";case
"s":return"String.leftPad(this.getSeconds(), 2, '0') + ";case"O":return"this.getGMTOffset() + ";case"T":return"this.getTimezone() + ";case"Z":return"(this.getTimezoneOffset() * -60) + ";default:return"'"+String.escape(a)+"' + ";}};Date.parseDate=function(a,c){if(c=="unixtime"){return new Date(!isNaN(parseInt(a))?parseInt(a)*1000:0);}if(Date.parseFunctions[c]==null){Date.createParser(c);}var b=Date.parseFunctions[c];return Date[b](a);};Date.createParser=function(format){var funcName="parse"+Date.parseFunctions.count++;var regexNum=Date.parseRegexes.length;var currentGroup=1;Date.parseFunctions[format]=funcName;var code="Date."+funcName+" = function(input) {\nvar y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, z = -1;\nvar d = new Date();\ny = d.getFullYear();\nm = d.getMonth();\nd = d.getDate();\nvar results = input.match(Date.parseRegexes["+regexNum+"]);\nif (results && results.length > 0) {";var regex="";var special=false;var ch="";for(var i=0;i<format.length;++i){ch=format
.charAt(i);if(!special&&ch=="\\"){special=true;}else{if(special){special=false;regex+=String.escape(ch);}else{obj=Date.formatCodeToRegex(ch,currentGroup);currentGroup+=obj.g;regex+=obj.s;if(obj.g&&obj.c){code+=obj.c;}}}}code+="if (y > 0 && z > 0){\nvar doyDate = new Date(y,0);\ndoyDate.setDate(z);\nm = doyDate.getMonth();\nd = doyDate.getDate();\n}";code+="if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n{return new Date(y, m, d, h, i, s);}\nelse if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n{return new Date(y, m, d, h, i);}\nelse if (y > 0 && m >= 0 && d > 0 && h >= 0)\n{return new Date(y, m, d, h);}\nelse if (y > 0 && m >= 0 && d > 0)\n{return new Date(y, m, d);}\nelse if (y > 0 && m >= 0)\n{return new Date(y, m);}\nelse if (y > 0)\n{return new Date(y);}\n}return null;}";Date.parseRegexes[regexNum]=new RegExp("^"+regex+"$");eval(code);};Date.formatCodeToRegex=function(b,a){switch(b){case"D":return{g:0,c:null,s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"};case"j":cas
e"d":return{g:1,c:"d = parseInt(results["+a+"], 10);\n",s:"(\\d{1,2})"};case"l":return{g:0,c:null,s:"(?:"+Date.dayNames.join("|")+")"};case"S":return{g:0,c:null,s:"(?:st|nd|rd|th)"};case"w":return{g:0,c:null,s:"\\d"};case"z":return{g:1,c:"z = parseInt(results["+a+"], 10);\n",s:"(\\d{1,3})"};case"W":return{g:0,c:null,s:"(?:\\d{2})"};case"F":return{g:1,c:"m = parseInt(Date.monthNumbers[results["+a+"].substring(0, 3)], 10);\n",s:"("+Date.monthNames.join("|")+")"};case"M":return{g:1,c:"m = parseInt(Date.monthNumbers[results["+a+"]], 10);\n",s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"};case"n":case"m":return{g:1,c:"m = parseInt(results["+a+"], 10) - 1;\n",s:"(\\d{1,2})"};case"t":return{g:0,c:null,s:"\\d{1,2}"};case"L":return{g:0,c:null,s:"(?:1|0)"};case"Y":return{g:1,c:"y = parseInt(results["+a+"], 10);\n",s:"(\\d{4})"};case"y":return{g:1,c:"var ty = parseInt(results["+a+"], 10);\ny = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",s:"(\\d{1,2})"};case"a":return{g:1,c:"if
(results["+a+"] == 'am') {\nif (h == 12) { h = 0; }\n} else { if (h < 12) { h += 12; }}",s:"(am|pm)"};case"A":return{g:1,c:"if (results["+a+"] == 'AM') {\nif (h == 12) { h = 0; }\n} else { if (h < 12) { h += 12; }}",s:"(AM|PM)"};case"g":case"G":case"h":case"H":return{g:1,c:"h = parseInt(results["+a+"], 10);\n",s:"(\\d{1,2})"};case"i":return{g:1,c:"i = parseInt(results["+a+"], 10);\n",s:"(\\d{2})"};case"s":return{g:1,c:"s = parseInt(results["+a+"], 10);\n",s:"(\\d{2})"};case"O":return{g:0,c:null,s:"[+-]\\d{4}"};case"T":return{g:0,c:null,s:"[A-Z]{3}"};case"Z":return{g:0,c:null,s:"[+-]\\d{1,5}"};default:return{g:0,c:null,s:String.escape(b)};}};Date.prototype.getTimezone=function(){return this.toString().replace(/^.*? ([A-Z]{3}) [0-9]{4}.*$/,"$1").replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/,"$1$2$3");};Date.prototype.getGMTOffset=function(){return(this.getTimezoneOffset()>0?"-":"+")+String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset())/60),2,"0")+String.
leftPad(Math.abs(this.getTimezoneOffset())%60,2,"0");};Date.prototype.getDayOfYear=function(){var a=0;Date.daysInMonth[1]=this.isLeapYear()?29:28;for(var b=0;b<this.getMonth();++b){a+=Date.daysInMonth[b];}return a+this.getDate();};Date.prototype.getWeekOfYear=function(){var b=this.getDayOfYear()+(4-this.getDay());var a=new Date(this.getFullYear(),0,1);var c=(7-a.getDay()+4);return String.leftPad(Math.ceil((b-c)/7)+1,2,"0");};Date.prototype.isLeapYear=function(){var a=this.getFullYear();return((a&3)==0&&(a%100||(a%400==0&&a)));};Date.prototype.getFirstDayOfMonth=function(){var a=(this.getDay()-(this.getDate()-1))%7;return(a<0)?(a+7):a;};Date.prototype.getLastDayOfMonth=function(){var a=(this.getDay()+(Date.daysInMonth[this.getMonth()]-this.getDate()))%7;return(a<0)?(a+7):a;};Date.prototype.getDaysInMonth=function(){Date.daysInMonth[1]=this.isLeapYear()?29:28;return Date.daysInMonth[this.getMonth()];};Date.prototype.getSuffix=function(){switch(this.getDate()){case 1:case 21:ca
se 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};String.escape=function(a){return a.replace(/('|\\)/g,"\\$1");};String.leftPad=function(d,b,c){var a=new String(d);if(c==null){c=" ";}while(a.length<b){a=c+a;}return a;};Date.daysInMonth=[31,28,31,30,31,30,31,31,30,31,30,31];Date.monthNames=["January","February","March","April","May","June","July","August","September","October","November","December"];Date.dayNames=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];Date.y2kYear=50;Date.monthNumbers={Jan:0,Feb:1,Mar:2,Apr:3,May:4,Jun:5,Jul:6,Aug:7,Sep:8,Oct:9,Nov:10,Dec:11};Date.patterns={ISO8601LongPattern:"Y-m-d H:i:s",ISO8601ShortPattern:"Y-m-d",ShortDatePattern:"n/j/Y",LongDatePattern:"l, F d, Y",FullDateTimePattern:"l, F d, Y g:i:s A",MonthDayPattern:"F d",ShortTimePattern:"g:i A",LongTimePattern:"g:i:s A",SortableDateTimePattern:"Y-m-d\\TH:i:s",UniversalSortableDateTimePattern:"Y-m-d H:i:sO",YearMonthPattern:"F
, Y"};
+/*
+ * Copyright (c) 2013 Brandon Aaron (http://brandonaaron.net)
+ *
+ * Licensed under the MIT License (LICENSE.txt).
+ *
+ * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
+ * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
+ * Thanks to: Seamus Leahy for adding deltaX and deltaY
+ *
+ * Version: 3.1.3
+ *
+ * Requires: 1.2.2+
+ */
+(function(factory) {if(typeof define==='function'&&define.amd) {define(['jquery'],factory)}else if(typeof exports==='object') {module.exports=factory}else{factory(jQuery)}}(function($) {var toFix=['wheel','mousewheel','DOMMouseScroll','MozMousePixelScroll'];var toBind='onwheel'in document||document.documentMode>=9?['wheel']:['mousewheel','DomMouseScroll','MozMousePixelScroll'];var lowestDelta,lowestDeltaXY;if($.event.fixHooks) {for(var i=toFix.length;i;) {$.event.fixHooks[toFix[--i]]=$.event.mouseHooks}}$.event.special.mousewheel={setup:function() {if(this.addEventListener) {for(var i=toBind.length;i;) {this.addEventListener(toBind[--i],handler,false)}}else{this.onmousewheel=handler}},teardown:function() {if(this.removeEventListener) {for(var i=toBind.length;i;) {this.removeEventListener(toBind[--i],handler,false)}}else{this.onmousewheel=null}}};$.fn.extend({mousewheel:function(fn) {return fn?this.bind("mousewheel",fn):this.trigger("mousewheel")},unmousewheel:function(fn) {r
eturn this.unbind("mousewheel",fn)}});function handler(event) {var orgEvent=event||window.event,args=[].slice.call(arguments,1),delta=0,deltaX=0,deltaY=0,absDelta=0,absDeltaXY=0,fn;event=$.event.fix(orgEvent);event.type="mousewheel";if(orgEvent.wheelDelta) {delta=orgEvent.wheelDelta}if(orgEvent.detail) {delta=orgEvent.detail*-1}if(orgEvent.deltaY) {deltaY=orgEvent.deltaY*-1;delta=deltaY}if(orgEvent.deltaX) {deltaX=orgEvent.deltaX;delta=deltaX*-1}if(orgEvent.wheelDeltaY!==undefined) {deltaY=orgEvent.wheelDeltaY}if(orgEvent.wheelDeltaX!==undefined) {deltaX=orgEvent.wheelDeltaX*-1}absDelta=Math.abs(delta);if(!lowestDelta||absDelta<lowestDelta) {lowestDelta=absDelta}absDeltaXY=Math.max(Math.abs(deltaY),Math.abs(deltaX));if(!lowestDeltaXY||absDeltaXY<lowestDeltaXY) {lowestDeltaXY=absDeltaXY}fn=delta>0?'floor':'ceil';delta=Math[fn](delta/lowestDelta);deltaX=Math[fn](deltaX/lowestDeltaXY);deltaY=Math[fn](deltaY/lowestDeltaXY);args.unshift(event,delta,deltaX,deltaY);return($.event.d
ispatch||$.event.handle).apply(this,args)}}));
diff --git a/public_html/js/kolab_admin.js b/public_html/js/kolab_admin.js
index 44c3227..1a192e5 100644
--- a/public_html/js/kolab_admin.js
+++ b/public_html/js/kolab_admin.js
@@ -722,6 +722,7 @@ function kolab_admin()
aci_fields = $('textarea[data-type="aci"]', form);
this.aci = {};
+ this.acl = {};
this.trigger_event('form-load', id);
// replace some textarea fields with pretty/smart input lists
@@ -733,6 +734,9 @@ function kolab_admin()
// create LDAP URL fields
$('input[data-type="ldap_url"]:not(:disabled):not([readonly])', form)
.each(function() { kadm.form_url_element_wrapper(this); });
+ // create IMAP ACL fields
+ $('textarea[data-type="acl"]', form)
+ .each(function() { kadm.form_acl_element_wrapper(this); });
// create ACI fields
aci_fields.each(function() { kadm.form_aci_element_wrapper(this); });
if (aci_fields.length)
@@ -777,6 +781,11 @@ function kolab_admin()
data.json = kadm.form_url_element_submit(this.name, data.json, form);
});
+ // IMAP ACL fields
+ $('textarea[data-type="acl"]:not(:disabled):not([readonly])', form).each(function() {
+ data.json = kadm.form_acl_element_submit(this.name, data.json, form);
+ });
+
// ACI fields
$('textarea[data-type="aci"]:not(:disabled):not([readonly])', form).each(function() {
data.json = kadm.form_aci_element_submit(this.name, data.json, form);
@@ -1725,6 +1734,247 @@ function kolab_admin()
}
};
+ // Replaces form element with IMAP ACL element
+ this.form_acl_element_wrapper = function(form_element)
+ {
+ var i, e = $(form_element),
+ form = form_element.form,
+ name = form_element.name,
+ div = $('<div class="acl"></div>'),
+ select = $('<select multiple="multiple" size="8"></select>'),
+ table = $('<table class="acltable"><tr><td class="list"></td><td class="buttons"></td></tr></table>'),
+ buttons = [
+ $('<input type="button" />').attr({value: this.t('aci.new')}),
+ $('<input type="button" />').attr({value: this.t('aci.edit'), disabled: true}),
+ $('<input type="button" />').attr({value: this.t('aci.remove'), disabled: true})
+ ],
+ acl = this.parse_acl(e.val()) || [];
+
+ this.acl[name] = acl;
+ e.hide();
+
+ // this.log(e.val());
+ // this.log(acl);
+
+ $.each(acl, function(i, entry) {
+ $('<option></option>').val(i).text(entry.subject).appendTo(select)
+ .on('dblclick', function () { self.form_acl_dialog(name, this.value); });
+ });
+
+ select.attr('id', 'acl'+name).on('change', function() {
+ var selected = $(this).val() || [];
+
+ buttons[1].prop('disabled', selected.length != 1);
+ buttons[2].prop('disabled', selected.length == 0);
+ });
+
+ // click on 'new' and 'edit' button
+ buttons[0].on('click', function() { self.form_acl_dialog(name); });
+ buttons[1].on('click', function() {
+ var selected = select.val();
+ self.form_acl_dialog(name, selected && selected.length ? selected[0] : null);
+ });
+
+ // click on 'remove' button
+ buttons[2].on('click', function() {
+ $.each(select.val() || [], function(i, v) {
+ self.acl[name][v] = null;
+ $('option[value="' + v + '"]', select).remove();
+ });
+ buttons[1].prop('disabled', true);
+ buttons[2].prop('disabled', true);
+ });
+
+ $('.buttons', table).append(buttons);
+ $('.list', table).append(select);
+ div.append(table)
+
+ $(form_element).parent().append(div);
+ };
+
+ // updates form data with IMAP ACL (on form submit)
+ this.form_acl_element_submit = function(name, data, form)
+ {
+ data[name] = this.build_acl(this.acl[name]);
+
+ return data;
+ };
+
+ // display IMAP ACL dialog
+ this.form_acl_dialog = function(name, id)
+ {
+ var acl = id ? this.acl[name][id] : {};
+
+ this.acl_dialog_acl = acl;
+ this.acl_dialog_name = name;
+ this.acl_dialog_id = id;
+
+ this.modal_dialog(this.form_acl_dialog_content(acl), this.form_acl_dialog_buttons());
+
+ window.setTimeout(function() { $('#acl-subject').focus(); }, 100);
+ };
+
+ // return IMAP ACL dialog buttons
+ this.form_acl_dialog_buttons = function()
+ {
+ var buttons = {
+ 'button.ok': function() {
+ if (self.form_acl_dialog_submit()) {
+ this.hide();
+ $('#acl-dialog').remove();
+ }
+ },
+ 'button.cancel': function() {
+ this.hide();
+ $('#acl-dialog').remove();
+ },
+ };
+
+ return buttons;
+ };
+
+ // build and return IMAP ACL dialog content
+ this.form_acl_dialog_content = function(acl)
+ {
+ var dialog = $('<div id="acl-dialog"><form id="acl-form"><table class="form">'
+ + '<tr><td class="label"></td><td class="value"></td></tr>'
+ + '<tr><td class="label"></td><td class="value"></td></tr>'
+ + '<tr><td class="label"></td><td class="value"></td></tr>'
+ + '</table></form></div>'),
+ rows = $('tr', dialog),
+ rights_div = $('<div>'),
+ spans = [$('<span>'), $('<span>')],
+ subject_select = $('<select id="acl-subject"></select>')
+ .on('change', function() {
+ subject_input[$(this).val() == 'user' ? 'show' : 'hide']();
+ }),
+ subject_input = $('<input id="acl-subject-user" type="text" size="30" />'),
+ select = $('<select id="acl-type"></select>')
+ .on('change', function() {
+ rights_div[$(this).val() == 'custom' ? 'show' : 'hide']();
+ }),
+ epoch_input = $('<input id="acl-epoch" type="text" size="13" />'),
+ subjects = 'user,anyone,anonymous'.split(','),
+ options = 'all,read,write,post,append,custom'.split(','),
+ rights = 'l,r,s,w,i,p,k,x,t,n,e,a'.split(',');
+
+ $.each(subjects, function() {
+ $('<option></option>').text(self.t('acl.'+this)).val(this).appendTo(subject_select);
+ });
+
+ $.each(options, function() {
+ $('<option></option>').text(self.t('acl.'+this)).val(this).appendTo(select);
+ });
+
+ $.each(rights, function(i, v) {
+ $('<label>')
+ .append($('<input type="checkbox" />').val(v))
+ .append($('<span>').text(self.t('acl.'+v)))
+ .appendTo(spans[i > 5 ? 1 : 0]);
+ });
+
+ $('td.label', rows[0]).text(this.t('acl.identifier'));
+ $('td.value', rows[0]).append(subject_select).append(subject_input);
+ $('td.label', rows[1]).text(this.t('acl.rights'));
+ $('td.value', rows[1]).append(select).append(rights_div.append(spans));
+ $('td.label', rows[2]).text(this.t('acl.expire'));
+ $('td.value', rows[2]).append(epoch_input);
+
+ dialog.hide().appendTo('body');
+
+ this.trigger_event('form-load', 'acl-form');
+
+ // reset form elements
+ subject_select.val(acl.subject).change();
+ subject_input.val(subject_select.val() == 'user' ? acl.subject : '');
+ epoch_input.val(this.unix_to_date(acl.epoch, true));
+ epoch_input.datetimepicker({
+ lang: 'en',
+ format: 'Y-m-d H:i'
+ });
+
+ var v = $.inArray(acl.rights, options) != -1 ? acl.rights : 'custom';
+ select.val(v).change();
+ $.each(rights, function() {
+ $('input[value="' + this + '"]', rights_div).prop('checked', v == 'custom' && acl.rights && acl.rights.indexOf(this) > -1);
+ });
+
+ return dialog.show();
+ };
+
+ // submits IMAP ACL dialog, updates acl definition in form
+ this.form_acl_dialog_submit = function()
+ {
+ var acl, exists, subject = $('#acl-subject').val(),
+ user_input = $('#acl-subject-user'),
+ user = $.trim(user_input.val()),
+ rights = $('#acl-type').val(),
+ epoch = $.trim($('#acl-epoch').val()),
+ acl_list = $('#acl' + this.acl_dialog_name);
+
+ // sanity checks
+ if (subject == 'user') {
+ subject = user;
+ if (!subject) {
+ alert(this.t('acl.error.nouser'));
+ user_input.focus();
+ return false;
+ }
+ }
+
+ $.each(this.acl[self.acl_dialog_name] || [], function(i, v) {
+ if (v && v.subject == subject && (!self.acl_dialog_id || self.acl_dialog_id != i)) {
+ exists = true;
+ return false;
+ }
+ });
+
+ if (exists) {
+ alert(this.t('acl.error.subjectexists'));
+ return false;
+ }
+
+ if (rights == 'custom') {
+ rights = '';
+ $('#acl-form input:checked').each(function() { rights += this.value; });
+
+ if (!rights) {
+ alert(this.t('acl.error.norights'));
+ return false;
+ }
+ }
+
+ if (epoch) {
+ if (epoch.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2})$/))
+ epoch = Date.UTC(RegExp.$1, RegExp.$2 - 1, RegExp.$3, RegExp.$4, RegExp.$5) / 1000;
+ else if (epoch.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/))
+ epoch = Date.UTC(RegExp.$1, RegExp.$2 - 1, RegExp.$3, 23, 59) / 1000;
+ else {
+ alert(this.t('acl.error.invaliddate'));
+ return false;
+ }
+ }
+
+ acl = {subject: subject, rights: rights, epoch: epoch};
+
+ // this.log(acl);
+ // this.log(this.build_acl([acl]));
+
+ if (this.acl_dialog_id) {
+ this.acl[this.acl_dialog_name][this.acl_dialog_id] = acl;
+ $('option[value="' + this.acl_dialog_id + '"]', acl_list).text(acl.subject);
+ }
+ else {
+ this.acl[this.acl_dialog_name].push(acl);
+ $('<option></option>').val(this.acl[this.acl_dialog_name].length-1)
+ .text(acl.subject)
+ .appendTo(acl_list)
+ .on('dblclick', function () { self.form_acl_dialog(self.acl_dialog_name, this.value); });
+ }
+
+ return true;
+ };
+
// Replaces form element with LDAP URL element
this.form_url_element_wrapper = function(form_element)
{
@@ -2751,7 +3001,6 @@ function kolab_admin()
var aci = [];
$.each((aci_str || '').split(/\r?\n/), function(i, str) {
-
var s, target, permission,
or_rx = /\s*\|\|\s*/,
entry = {targets: [], perms: []};
@@ -2864,6 +3113,48 @@ function kolab_admin()
return result;
};
+ // convert ACL string into object
+ this.parse_acl = function(acl_str)
+ {
+ var acl = [];
+
+ $.each((acl_str || '').split(/\r?\n/), function(i, str) {
+ // Syntax subject, rights[, epoch]
+ var entry = self.explode_quoted_str(str, ',');
+
+ if (entry.length == 2 || entry.length == 3)
+ acl.push({subject: entry[0], rights: entry[1], epoch: entry[2] || 0});
+ });
+
+ return acl;
+ };
+
+ // convert IMAP ACL object into ACL array (of strings)
+ this.build_acl = function(acl)
+ {
+ var result = [];
+
+ $.each(acl, function(i, entry) {
+ // skip removed and invalid entries
+ if (!entry || !entry.subject || !entry.rights)
+ return;
+
+ var tokens = [], subject = entry.subject;
+
+ if (subject.indexOf(',') > -1 || subject.indexOf('"') > -1)
+ subject = subject.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
+
+ tokens.push(subject);
+ tokens.push(entry.rights);
+ if (entry.epoch)
+ tokens.push(entry.epoch);
+
+ result.push(tokens.join(', '));
+ });
+
+ return result;
+ };
+
// LDAP URL parser
this.parse_ldap_url = function(url)
{
@@ -3044,6 +3335,59 @@ function kolab_admin()
return { left:mX, top:mY };
};
+ this.explode_quoted_str = function(str, separator)
+ {
+ var i, c, q = false, p = 0, result = [], len = str.length;
+
+ for (i=0; i<len; i++) {
+ c = str.charAt(i);
+ if (c == '"' && str.charAt(i-1) != '\\')
+ q = q ? false : true;
+ else if (!q && c == separator) {
+ result.push(this.unescape_quoted_str(str.substr(p, i - p)));
+ p = i + 1;
+ }
+ }
+
+ result.push($.trim(p ? str.substr(p) : str));
+
+ return result;
+ };
+
+ this.unescape_quoted_str = function(str)
+ {
+ str = $.trim(str || '');
+
+ if (str.charAt(0) == '"')
+ str = str.replace(/^"/, '').replace(/"$/, '')
+ .replace(/\\(.?)/g, function(s, n1) {
+ switch (n1) {
+ case '\\':
+ return '\\';
+ return n1;
+ }
+ });
+
+ return str;
+ };
+
+ // convert unix timestamp to datetime string
+ this.unix_to_date = function(epoch, with_time)
+ {
+ if (!epoch)
+ return '';
+
+ var result, dt = new Date(epoch * 1000),
+ dts = dt.toISOString(),
+ parts = dts.split('T');
+
+ result = parts[0];
+
+ if (with_time)
+ result += ' ' + parts[1].split(':').slice(0,2).join(':');
+
+ return result;
+ };
};
/**
diff --git a/public_html/skins/default/jquery.datetimepicker.css b/public_html/skins/default/jquery.datetimepicker.css
new file mode 100644
index 0000000..dad45ed
--- /dev/null
+++ b/public_html/skins/default/jquery.datetimepicker.css
@@ -0,0 +1,304 @@
+.xdsoft_datetimepicker{
+ box-shadow: 0px 5px 15px -5px rgba(0, 0, 0, 0.506);
+ background: #FFFFFF;
+ border-bottom: 1px solid #BBBBBB;
+ border-left: 1px solid #CCCCCC;
+ border-right: 1px solid #CCCCCC;
+ border-top: 1px solid #CCCCCC;
+ color: #333333;
+ display: block;
+ font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;
+ padding: 8px;
+ padding-left: 0px;
+ padding-top: 2px;
+ position: absolute;
+ z-index: 9999;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ display:none;
+}
+
+.xdsoft_datetimepicker iframe {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 75px;
+ height: 210px;
+ background: transparent;
+ border:none;
+}
+/*For IE8 or lower*/
+.xdsoft_datetimepicker button {
+ border:none !important;
+}
+
+.xdsoft_noselect{
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -o-user-select: none;
+ user-select: none;
+}
+.xdsoft_noselect::selection { background: transparent; }
+.xdsoft_noselect::-moz-selection { background: transparent; }
+.xdsoft_datetimepicker.xdsoft_inline{
+ display: inline-block;
+ position: static;
+ box-shadow: none;
+}
+.xdsoft_datetimepicker *{
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding:0px;
+ margin:0px;
+}
+.xdsoft_datetimepicker .xdsoft_datepicker, .xdsoft_datetimepicker .xdsoft_timepicker{
+ display:none;
+}
+.xdsoft_datetimepicker .xdsoft_datepicker.active, .xdsoft_datetimepicker .xdsoft_timepicker.active{
+ display:block;
+}
+.xdsoft_datetimepicker .xdsoft_datepicker{
+ width: 224px;
+ float:left;
+ margin-left:8px;
+}
+.xdsoft_datetimepicker .xdsoft_timepicker{
+ width: 58px;
+ float:left;
+ text-align:center;
+ margin-left:8px;
+ margin-top:0px;
+}
+.xdsoft_datetimepicker .xdsoft_datepicker.active+.xdsoft_timepicker{
+ margin-top:8px;
+ margin-bottom:3px
+}
+.xdsoft_datetimepicker .xdsoft_mounthpicker{
+ position: relative;
+ text-align: center;
+}
+
+.xdsoft_datetimepicker .xdsoft_prev, .xdsoft_datetimepicker .xdsoft_next,.xdsoft_datetimepicker .xdsoft_today_button{
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAAAeCAYAAACsYQl4AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDozQjRCQjRGREU4MkNFMzExQjRDQkIyRDJDOTdBRUI1MCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCQjg0OUYyNTZDODAxMUUzQjMwM0IwMERBNUU0ODQ5NSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCQjg0OUYyNDZDODAxMUUzQjMwM0IwMERBNUU0ODQ5NSIgeG1wOkNyZWF0b3J
Ub29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkI5NzE3MjFBN0E2Q0UzMTFBQjJEQjgzMDk5RTNBNTdBIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjNCNEJCNEZERTgyQ0UzMTFCNENCQjJEMkM5N0FFQjUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+aQvATgAAAfVJREFUeNrsmr1OwzAQxzGtkPjYEAuvVGAvfQIGRKADE49gdLwDDwBiZ2RhQUKwICQkWLsgFiRQuIBTucFJ/XFp4+hO+quqnZ4uvzj2nV2RpukCW/22yAgYNINmc7du7DcghCjrkqgOKjF1znpt6rZ0AGWQj7TvCU8d9UM+QAGDrhdyc2Bnc1WVVPBev9V8lBnY+rDwncWZThG4xk4lmxtJy2AHgoY/FySgbSBPwPZ8mEXbQx3aDERb0EbYAYFC7pcAtAvkMWwC0D3NX58S9D/YnoGC7nPWr3Dg9JTbtuHhDShBT8D2CBSK/iIEvVXxpuxSgh7DdgwUTL4iA92zmJb6lKB/YTsECmV+IgK947AGDIqgQ/LojsO135Hn51l2cWlov0JdGNrPUceueXRwilSVgkUyom9Rd6gbLfYTDeO+1v6orn0InTogYDGUkYLO3/wc9BdqqTCKP1Tfi+oTIaCBIL2TES+GTyruT9S61p6BHam+99DFEAgLFklYsIBHwSI9QY80H5ta+1rB/6ovaKihBJeEJbgLbBlQgl+j3lDPqA2tfQV1j3pVn8s+oKHGTSVJ+FqDLeR5bCqJ2E/BCycsoLZETXaKGs7rhKVt+9HZScrZNMi88V8P7LlDbvOZYaJVpMMmBCT4n0o8dTBo
NgbdWPsRYACs3r7XyNfbnAAAAABJRU5ErkJggg==');
+}
+.xdsoft_datetimepicker .xdsoft_prev{
+ float: left;
+ background-position:-20px 0px;
+}
+.xdsoft_datetimepicker .xdsoft_today_button{
+ float: left;
+ background-position:-70px 0px;
+ margin-left:5px;
+}
+
+.xdsoft_datetimepicker .xdsoft_next{
+ float: right;
+ background-position:0px 0px;
+}
+.xdsoft_datetimepicker .xdsoft_next:active,.xdsoft_datetimepicker .xdsoft_prev:active{
+}
+.xdsoft_datetimepicker .xdsoft_next,.xdsoft_datetimepicker .xdsoft_prev ,.xdsoft_datetimepicker .xdsoft_today_button{
+ background-color: transparent;
+ background-repeat: no-repeat;
+ border: 0px none currentColor;
+ cursor: pointer;
+ display: block;
+ height: 30px;
+ opacity: 0.5;
+ outline: medium none currentColor;
+ overflow: hidden;
+ padding: 0px;
+ position: relative;
+ text-indent: 100%;
+ white-space: nowrap;
+ width: 20px;
+}
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_prev,
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_next{
+ float:none;
+ background-position:-40px -15px;
+ height: 15px;
+ width: 30px;
+ display: block;
+ margin-left:14px;
+ margin-top:7px;
+}
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_prev{
+ background-position:-40px 0px;
+ margin-bottom:7px;
+ margin-top:0px;
+}
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box{
+ height:151px;
+ overflow:hidden;
+ border-bottom:1px solid #DDDDDD;
+}
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div{
+ background: #F5F5F5;
+ border-top:1px solid #DDDDDD;
+ color: #666666;
+ font-size: 12px;
+ text-align: center;
+ border-collapse:collapse;
+ cursor:pointer;
+ border-bottom-width:0px;
+ height:25px;
+ line-height:25px;
+}
+
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div > div:first-child{
+ border-top-width:0px;
+}
+.xdsoft_datetimepicker .xdsoft_today_button:hover,
+.xdsoft_datetimepicker .xdsoft_next:hover,
+.xdsoft_datetimepicker .xdsoft_prev:hover {
+ opacity: 1;
+}
+.xdsoft_datetimepicker .xdsoft_label{
+ display: inline;
+ position: relative;
+ z-index: 9999;
+ margin: 0;
+ padding: 5px 3px;
+ font-size: 14px;
+ line-height: 20px;
+ font-weight: bold;
+ background-color: #fff;
+ float:left;
+ width:182px;
+ text-align:center;
+ cursor:pointer;
+}
+.xdsoft_datetimepicker .xdsoft_label:hover{
+ text-decoration:underline;
+}
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select{
+ border:1px solid #ccc;
+ position:absolute;
+ display:block;
+ right:0px;
+ top:30px;
+ z-index:101;
+ display:none;
+ background:#fff;
+ max-height:160px;
+ overflow-y:hidden;
+}
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select.xdsoft_monthselect{right:-7px;}
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select.xdsoft_yearselect{right:2px;}
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option:hover{
+ color: #fff;
+ background: #ff8000;
+}
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option{
+ padding:2px 10px 2px 5px;
+}
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option.xdsoft_current{
+ background: #33AAFF;
+ box-shadow: #178FE5 0px 1px 3px 0px inset;
+ color:#fff;
+ font-weight: 700;
+}
+.xdsoft_datetimepicker .xdsoft_month{
+ width:90px;
+ text-align:right;
+}
+.xdsoft_datetimepicker .xdsoft_calendar{
+ clear:both;
+}
+.xdsoft_datetimepicker .xdsoft_year{
+ width:56px;
+}
+.xdsoft_datetimepicker .xdsoft_calendar table{
+ border-collapse:collapse;
+ width:100%;
+
+}
+.xdsoft_datetimepicker .xdsoft_calendar td > div{
+ padding-right:5px;
+}
+.xdsoft_datetimepicker .xdsoft_calendar th{
+ height: 25px;
+}
+.xdsoft_datetimepicker .xdsoft_calendar td,.xdsoft_datetimepicker .xdsoft_calendar th{
+ width:14.2857142%;
+ text-align:center;
+ background: #F5F5F5;
+ border:1px solid #DDDDDD;
+ color: #666666;
+ font-size: 12px;
+ text-align: right;
+ padding:0px;
+ border-collapse:collapse;
+ cursor:pointer;
+ height: 25px;
+}
+.xdsoft_datetimepicker .xdsoft_calendar th{
+ background: #F1F1F1;
+}
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_today{
+ color:#33AAFF;
+}
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_default,
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_current,
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div.xdsoft_current{
+ background: #33AAFF;
+ box-shadow: #178FE5 0px 1px 3px 0px inset;
+ color:#fff;
+ font-weight: 700;
+}
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_other_month,
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_disabled,
+.xdsoft_datetimepicker .xdsoft_time_box >div >div.xdsoft_disabled{
+ opacity:0.5;
+}
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_other_month.xdsoft_disabled{
+ opacity:0.2;
+}
+.xdsoft_datetimepicker .xdsoft_calendar td:hover,
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div:hover{
+ color: #fff !important;
+ background: #ff8000 !important;
+ box-shadow: none !important;
+}
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_disabled:hover,
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div.xdsoft_disabled:hover{
+ color: inherit !important;
+ background: inherit !important;
+ box-shadow: inherit !important;
+}
+.xdsoft_datetimepicker .xdsoft_calendar th{
+ font-weight: 700;
+ text-align: center;
+ color: #999;
+ cursor:default;
+}
+.xdsoft_datetimepicker .xdsoft_copyright{ color:#ccc !important; font-size:10px;clear:both;float:none;margin-left:8px;}
+.xdsoft_datetimepicker .xdsoft_copyright a{ color:#eee !important;}
+.xdsoft_datetimepicker .xdsoft_copyright a:hover{ color:#aaa !important;}
+
+
+.xdsoft_time_box{
+ position:relative;
+ border:1px solid #ccc;
+}
+.xdsoft_scrollbar >.xdsoft_scroller{
+ background:#ccc !important;
+ height:20px;
+ border-radius:3px;
+}
+.xdsoft_scrollbar{
+ position:absolute;
+ width:7px;
+ width:7px;
+ right:0px;
+ top:0px;
+ bottom:0px;
+ cursor:pointer;
+}
+.xdsoft_scroller_box{
+position:relative;
+}
\ No newline at end of file
diff --git a/public_html/skins/default/style.css b/public_html/skins/default/style.css
index 6b9ffef..b634f20 100644
--- a/public_html/skins/default/style.css
+++ b/public_html/skins/default/style.css
@@ -605,6 +605,10 @@ a.button.delete {
background-position: -1px -1px;
}
+.xdsoft_datetimepicker {
+ border-radius: 4px;
+}
+
/********* Form smart inputs *********/
span.listarea {
@@ -946,13 +950,13 @@ fieldset.tabbed
#modal_bg {
background-color: #000;
- z-index: 10000;
+ z-index: 1000;
opacity: 0.2;
filter: alpha(opacity=20);
}
#modal_pixel {
- z-index: 10001;
+ z-index: 1001;
}
.modal {
@@ -1092,6 +1096,40 @@ fieldset.tabbed
margin-bottom: 10px;
}
+
+/**** IMAP ACL widget ********/
+
+#acl-dialog {
+ width: 550px;
+ background-color: #F0F0F0;
+ border: 1px solid #D0D0D0;
+ border-radius: 4px;
+ margin: 10px;
+ padding: 10px;
+}
+
+#acl-form td {
+ white-space: nowrap;
+ width: 1%;
+ min-width: 20px;
+}
+
+#acl-form label {
+ display: block;
+}
+
+#acl-form td.value div span {
+ display: inline-block;
+ vertical-align: top;
+ min-width: 200px;
+}
+
+#acl-form td.value div label input,
+#acl-form td.value div label span {
+ vertical-align: middle;
+}
+
+
/**** Login form elements ****/
#login_form {
diff --git a/public_html/skins/default/templates/main.html b/public_html/skins/default/templates/main.html
index 0de2e4f..108845c 100644
--- a/public_html/skins/default/templates/main.html
+++ b/public_html/skins/default/templates/main.html
@@ -4,8 +4,10 @@
<meta charset="utf-8" />
<title>{$pagetitle}</title>
<link rel="stylesheet" href="{$skin_path}style.css" />
+ <link rel="stylesheet" href="{$skin_path}jquery.datetimepicker.css" />
<link rel="shortcut icon" type="image/png" href="{$skin_path}images/favicon.png" />
<script src="js/jquery.min.js"></script>
+ <script src="js/jquery.datetimepicker.js"></script>
<script src="js/kolab_admin.js"></script>
<script src="{$skin_path}ui.js"></script>
</head>
More information about the commits
mailing list