PluginProbe
ShiftController Employee Shift Scheduling / 4.9.95
ShiftController Employee Shift Scheduling v4.9.95
4.9.97 4.9.96 4.9.95 4.9.74 4.9.75 4.9.76 4.9.77 4.9.78 4.9.84 4.9.85 4.9.87 4.9.91 4.9.92 trunk 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.2.4 All 38 releases
shiftcontroller / hc3 / assets / js / hc2.js

hc2.js in ShiftController Employee Shift Scheduling 4.9.95, at hc3/assets/js/hc2.js

621 lines 13.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 var hcapp = {};
2
3 document.addEventListener('DOMContentLoaded', function()
4 {
5 if( ! hcapp.hasOwnProperty('app') ){
6 hcapp['app'] = 'hc3';
7 }
8 });
9
10 function hc2MakeAjaxHref( href )
11 {
12 href += ( href.split('?')[1] ? '&':'?' ) + 'hcj=' + hcapp['app'];
13 console.log( href );
14 return href;
15 }
16
17 function hc2_set_loader( $el )
18 {
19 var loader = '<div class="hc-loader"></div';
20 var shader = '<div class="hc-loader-shader"></div';
21 $el.css('position', 'relative');
22 $el.append( shader );
23 $el.append( loader );
24 }
25
26 function hc2_unset_loader( $el )
27 {
28 $el.find('[class="hc-loader-shader"]').remove();
29 $el.find('[class="hc-loader"]').remove();
30 }
31
32 jQuery(document).on( 'click', '.hcj2-ajax-loader', function(event)
33 {
34 var $this = jQuery(this);
35
36 hc2_set_loader( $this );
37 var href = hc2MakeAjaxHref( $this.attr('href') );
38
39 jQuery.ajax({
40 type: 'GET',
41 url: href,
42 // dataType: "json",
43 success: function( data, textStatus ){
44 $this.replaceWith( data );
45 }
46 })
47 .fail( function(jqXHR, textStatus, errorThrown){
48 hc2_unset_loader( $this );
49 alert( 'Ajax Error' );
50 console.log( 'Ajax Error: ' + errorThrown + "\n" + "status: " + textStatus + "\n" + "response: " + jqXHR.responseText );
51 })
52 ;
53
54 return false;
55 });
56
57 jQuery(document).on( 'click', '.hcj2-confirm', function(event)
58 {
59 if( window.confirm("Are you sure?") ){
60 return true;
61 }
62 else {
63 event.preventDefault();
64 event.stopPropagation();
65 return false;
66 }
67 });
68
69 jQuery(document).on( 'submit', '.hcj2-alert-dismisser', function(e)
70 {
71 jQuery(this).closest('.hcj2-alert').hide();
72 return false;
73 });
74
75 document.addEventListener('DOMContentLoaded', function()
76 {
77 /* auto dismiss alerts */
78 jQuery('.hcj2-auto-dismiss').delay(3000).slideUp(200, function(){
79 // jQuery('.hcj2-auto-dismiss .alert').alert('close');
80 });
81
82 var timeRangeInputs = jQuery( '.hcj-timerange-input' );
83 timeRangeInputs.each( function(index){
84 var this_input = new hcapp.html.timeRangeInput( jQuery(this) );
85 this_input.init();
86 this_input.render();
87 });
88 });
89
90 var hc2 = {};
91
92 var hc2_spinner = '<span class="hc-m0 hc-p0 hc-fs5 hc-spin hc-inline-block">&#9788;</span>';
93 var hc2_absolute_spinner = '<div class="hc-fs5 hc-spin hc-inline-block hc-m0 hc-p0" style="position: absolute; top: 45%;"><span class="hc-m0 hc-p0">&#9788;</span></div>';
94 var hc2_full_spinner = '<div class="hcj2-full-spinner hc-bg-silver hc-muted-2 hc-align-center" style="z-index: 1000; width: 100%; height: 100%; position: absolute; top: 0; left: 0;">' + hc2_absolute_spinner + '</div>';
95
96 // html
97 hcapp.html = {};
98
99 hcapp.html.timeRangeInput = function( $el )
100 {
101 var self = this;
102 self.input_value = [0, 0];
103
104 var $container = $el.find('.hcj-display:first');
105 var $hidden = $el.find('input[type=hidden]');
106 var $input_start = jQuery('<select>', {
107 class: 'hc-field hc-block',
108 });
109 var $input_end = jQuery('<select>', {
110 class: 'hc-field hc-block',
111 });
112
113 var $allday_input = $el.find(':checkbox');
114
115 if( $allday_input.length ){
116 $allday_input.on('change', function(e){
117 var is_all_day = jQuery(this)[0].checked;
118 if( is_all_day ){
119 $container.hide();
120 }
121 else {
122 $container.show();
123 }
124 $hidden.val( self.get_value() );
125 $hidden.trigger('change');
126 });
127 }
128
129 this.init = function()
130 {
131 // parse default value
132 var this_value = $hidden.val();
133 self.default_duration = 5 * 60;
134 self.input_value = [];
135
136 if( this_value.length ){
137 var this_times = this_value.split('-');
138 for( var jj = 0; jj < this_times.length; jj++ ){
139 self.input_value.push( parseInt(this_times[jj]) );
140 }
141
142 if( 2 == this_times.length ){
143 self.default_duration = parseInt(this_times[1]) - parseInt(this_times[0]);
144 }
145 }
146 else {
147 var time_format = $el.data('time-format');
148 var time_unit = 1 * 60;
149 var end_day = 24 * 60 * 60;
150 var start_from = 0;
151
152 for( var ts = start_from; ts <= end_day; ts += time_unit ){
153 if( ! time_format.hasOwnProperty(ts) ){
154 continue;
155 }
156
157 self.input_value.push( parseInt(ts) );
158 break;
159 }
160 }
161 }
162
163 this.get_value = function()
164 {
165 var times = [];
166 var is_all_day = $allday_input.length ? $allday_input[0].checked : false;
167
168 if( is_all_day ){
169 times.push( 0 );
170 times.push( 24*60*60 );
171 }
172 else {
173 times.push( $input_start.val() );
174 times.push( $input_end.val() );
175 }
176
177 var out = times.join('-');
178 return out;
179 }
180
181 this.render = function()
182 {
183 var time_unit = 1 * 60;
184 var end_day = 24 * 60 * 60;
185 var time_format = $el.data('time-format');
186
187 // start
188 var start_from = 0;
189
190 $input_start.empty();
191 for( var ts = start_from; ts <= end_day; ts += time_unit ){
192 if( ! time_format.hasOwnProperty(ts) ){
193 continue;
194 }
195
196 $input_start.append(
197 jQuery('<option>', {
198 value: ts,
199 text : time_format[ts]
200 })
201 );
202 }
203
204 // update end depending on start
205 $input_start.on('change', function(e){
206 $input_end.trigger('listen');
207 });
208
209 $input_end.on('listen', function(e){
210 var start = parseInt( $input_start.val() );
211
212 var current_end = self.input_value[1] ? self.input_value[1] : $input_end.val();
213 current_end = start + self.default_duration;
214 current_end = parseInt( current_end );
215
216 var current_end_exists = false;
217
218 var end_from = start + time_unit;
219 var end_to = start + end_day;
220 var last_seen_end = 0;
221
222 $input_end.empty();
223 for( var ts = end_from; ts <= end_to; ts += time_unit ){
224 var ts_key = ( ts > end_day ) ? ts % end_day : ts;
225
226 if( ! time_format.hasOwnProperty(ts_key) ){
227 continue;
228 }
229
230 if( (! last_seen_end) && (ts > end_from) ){
231 last_seen_end = ts;
232 }
233
234 if( ts == current_end ){
235 current_end_exists = true;
236 }
237
238 var ts_view = time_format[ts_key];
239 if( ts > end_day ){
240 var ts_view = ' > ' + ts_view;
241 }
242
243 $input_end.append(
244 jQuery('<option>', {
245 value: ts,
246 text : ts_view
247 })
248 );
249 }
250
251 if( ! current_end_exists ){
252 current_end = last_seen_end;
253 }
254
255 $input_end.val(current_end);
256 self.input_value[1] = current_end;
257 return false;
258 });
259
260 $input_start.val( self.input_value[0] );
261 $input_end.val( self.input_value[1] );
262
263 // end
264 $input_end.trigger('listen');
265
266 // update hidden value
267 $input_start.on('change', function(e){
268 $hidden.val( self.get_value() );
269 $hidden.trigger('change');
270 });
271
272 $input_end.on('change', function(e){
273 $hidden.val( self.get_value() );
274 $hidden.trigger('change');
275 });
276
277 // display
278 var out = new hcapp.html.List_Inline()
279 .set_mobile(true)
280 .set_gutter(2)
281 .add( $input_start )
282 .add( '-' )
283 .add( $input_end )
284 ;
285 out = out.render();
286
287 $container
288 .empty()
289 .append( out )
290 ;
291
292 $hidden.val( self.get_value() );
293 $hidden.trigger('change');
294 }
295 }
296
297 hcapp.html.List_Inline = function()
298 {
299 var self = this;
300
301 self.items = [];
302 self.gutter = 2;
303 self.is_mobile = false;
304
305 this.add = function( item )
306 {
307 self.items.push( item );
308 return this;
309 }
310
311 this.set_gutter = function( gutter )
312 {
313 self.gutter = gutter;
314 return this;
315 }
316
317 this.set_mobile = function( mobile )
318 {
319 self.mobile = mobile;
320 return this;
321 }
322
323 this.render = function()
324 {
325 var $out = jQuery('<div>');
326
327 for( var ii = 0; ii < self.items.length; ii++ ){
328 var $out_item = jQuery('<div>')
329 .addClass('hc-valign-middle')
330 ;
331
332 if( self.mobile ){
333 $out_item.addClass('hc-inline-block');
334 }
335 else {
336 $out_item.addClass('hc-lg-inline-block');
337 }
338
339 if( self.gutter && ii < (self.items.length - 1) ){
340 $out_item.addClass( 'hc-mr' + self.gutter );
341 if( ! self.mobile ){
342 $out_item
343 .addClass( 'hc-xs-mr0' )
344 .addClass( 'hc-xs-mb' + self.gutter )
345 ;
346 }
347 }
348
349 $out_item.append( self.items[ii] );
350 $out.append( $out_item );
351 }
352
353 return $out;
354 }
355 }
356
357 hcapp.html.List = function()
358 {
359 var self = this;
360
361 self.items = [];
362 self.gutter = 2;
363
364 this.add = function( item )
365 {
366 self.items.push( item );
367 return this;
368 }
369
370 this.set_gutter = function( gutter )
371 {
372 self.gutter = gutter;
373 return this;
374 }
375
376 this.render = function()
377 {
378 var $out = jQuery('<div>');
379
380 for( var ii = 0; ii < self.items.length; ii++ ){
381 var $out_item = jQuery('<div>')
382 .addClass('hc-block')
383 ;
384
385 if( self.gutter && ii ){
386 $out_item
387 .addClass( 'hc-mt' + self.gutter )
388 ;
389 }
390
391 $out_item.append( self.items[ii] );
392 $out.append( $out_item );
393 }
394
395 return $out;
396 }
397 }
398
399 hcapp.html.Month_Calendar = function()
400 {
401 var self = this;
402 self.dates = [];
403 self.lang = [];
404
405 self._selected_date = null;
406 self._cells = {};
407
408 var $this = jQuery({});
409 this.on = function( e, callback ){
410 $this.on( e, callback );
411 }
412 this.trigger = function( e, params ){
413 $this.trigger( e, params );
414 }
415
416 this.get_selected_date = function()
417 {
418 if( ! (self._selected_date == null) ){
419 return self._selected_date;
420 }
421
422 var this_date = null
423 for( var ii = 0; ii < self.dates.length; ii++ ){
424 if( this_date ){
425 break;
426 }
427 for( var jj = 0; jj < self.dates[ii].length; jj++ ){
428 var this_date = self.dates[ii][jj];
429 if( this_date ){
430 break;
431 }
432 }
433 }
434
435 self._selected_date = this_date;
436 return self._selected_date;
437 }
438
439 this.select_date = function( date )
440 {
441 self._selected_date = date;
442 self.trigger('select-date', date);
443 return this;
444 }
445
446 this.set_dates = function( dates )
447 {
448 self.dates = dates;
449 return this;
450 }
451
452 this.render = function()
453 {
454 // alert('render cal' + self.dates.length);
455 var $out = jQuery('<div>', {
456 class: 'hc-block',
457 });
458
459 var out = new hcapp.html.List()
460 .set_gutter(0)
461 ;
462
463 // labels
464 if( self.lang && self.lang.length ){
465 var label_row = new hcapp.html.Grid()
466 .set_gutter(0)
467 ;
468 for( var jj = 0; jj < 7; jj++ ){
469 var $this_cell = jQuery('<div>', {
470 class: 'hc-align-center hc-nowrap hc-fs1',
471 })
472 .append( self.lang[jj] )
473 .attr('title', self.lang[jj])
474 ;
475 label_row.add( $this_cell, '1-7', '1-7' );
476 }
477 out.add( label_row.render() );
478 }
479
480 if( ! self.dates ){
481 self.dates = [];
482 }
483 for( var ii = 0; ii < self.dates.length; ii++ ){
484 var row = new hcapp.html.Grid()
485 .set_gutter(0)
486 ;
487
488 for( var jj = 0; jj < self.dates[ii].length; jj++ ){
489 var this_date = self.dates[ii][jj];
490
491 var $this_cell = jQuery('<div>', {
492 class: 'hc-align-center hc-nowrap',
493 });
494
495 self.trigger( 'render-date', {date: this_date, cell: $this_cell} );
496
497 row.add( $this_cell, '1-7', '1-7' );
498 self._cells[ this_date ] = $this_cell;
499 }
500
501 out.add( row.render() );
502 }
503
504 return out.render();
505 }
506
507 this.get_date_cell = function( date )
508 {
509 return self._cells[date];
510 }
511 }
512
513 hcapp.html.Grid = function()
514 {
515 this.items = [];
516 this.gutter = 2;
517
518 this.add = function( item, width, mobile_width )
519 {
520 if( ! mobile_width ){
521 mobile_width = 12;
522 }
523 this.items.push( {'item': item, 'width': width, 'mobile_width': mobile_width} );
524 return this;
525 }
526
527 this.set_gutter = function( gutter )
528 {
529 this.gutter = gutter;
530 return this;
531 }
532
533 this.render = function()
534 {
535 var rows = [];
536
537 var full_width = 12;
538 var current_row = [];
539 var taken_width = 0;
540
541 for( var ii = 0; ii < this.items.length; ii++ ){
542 var this_width = this.items[ii].width;
543 // this_width = 0;
544
545 if( (taken_width + this_width) > full_width ){
546 rows.push( current_row );
547 taken_width = 0;
548 current_row = [];
549 }
550
551 current_row.push( this.items[ii] );
552 taken_width += this_width;
553 }
554
555 if( current_row.length ){
556 rows.push( current_row );
557 taken_width = 0;
558 current_row = [];
559 }
560
561 var $out = jQuery('<div>', {
562 })
563 ;
564
565 for( var ii = 0; ii < rows.length; ii++ ){
566 var $out_row = jQuery('<div>', {
567 class: 'hc-clearfix',
568 });
569
570 if( this.gutter ){
571 $out_row.addClass( 'hc-mxn' + this.gutter );
572
573 if( (rows.length > 1) && (ii != (rows.length - 1)) ){
574 $out_row.addClass( 'hc-mb' + this.gutter );
575 }
576 }
577
578 for( var jj = 0; jj < rows[ii].length; jj++ ){
579 var this_width = rows[ii][jj].width;
580 var this_mobile_width = rows[ii][jj].mobile_width;
581
582 var cell_classes = [];
583
584 if( this_mobile_width != 12 ){
585 cell_classes.push( 'hc-xs-col' );
586 cell_classes.push( 'hc-xs-col-' + this_mobile_width );
587 }
588
589 cell_classes.push( 'hc-col' );
590 cell_classes.push( 'hc-col-' + this_width );
591 if( this.gutter ){
592 cell_classes.push( 'hc-xs-mb' + this.gutter );
593 }
594
595 var $out_cell = jQuery('<div>');
596 for( var kk = 0; kk < cell_classes.length; kk++ ){
597 $out_cell.addClass( cell_classes[kk] );
598 }
599
600 var this_item = rows[ii][jj].item;
601 if( ! Array.isArray(this_item) ){
602 this_item = [this_item];
603 }
604
605 for( var kk = 0; kk < this_item.length; kk++ ){
606 $out_cell.append( this_item[kk] );
607 }
608
609 if( this.gutter ){
610 $out_cell.addClass( 'hc-px' + this.gutter );
611 }
612
613 $out_row.append( $out_cell );
614 }
615
616 $out.append( $out_row );
617 }
618 return $out;
619 }
620 }
621