initial commit
[namibia] / public / js / admin.js
1 var updateAutoData = {};
2 var refreshAutoData = {};
3 var lastUpdatedId = false;
4 var postUpdateAction = [];
5 var postRefreshAction = [];
6 var postCollectAction = [];
7 var searchHandler = {};
8 var searchStack = {};
9 var mode = '';
10
11
12
13 function hasPlaceholderSupport() {
14         var input = document.createElement('input');
15         return ('placeholder' in input);
16 }
17
18 function generalNotice(header,body)
19 {
20         $('#modalGeneralNotice h3').html(header);
21         $('#modalGeneralNotice .modal-body').html(body);
22         $('#modalGeneralNotice').modal('show');
23 }
24
25 $('input:text,input:password,textarea').focus(function (){
26         if (!hasPlaceholderSupport())
27         {
28                 datepicker = false;
29                 if ($(this).hasClass('datepicker'))
30                 {
31                         datepicker = true;
32                         $(this).datepicker('remove');
33                 }
34                 $(this).val('');
35                 if (datepicker)
36                 {
37                         $(this).datepicker();
38                 }
39         }
40 });
41
42 $('input:text,input:password,textarea').blur(function (){
43         if (!hasPlaceholderSupport() && $(this).val() == '')
44         {
45                 datepicker = false;
46                 text = $(this).attr('placeholder');
47                 if ($(this).hasClass('datepicker'))
48                 {
49                         datepicker = true;
50                         $(this).datepicker('remove');
51                 }
52                 if (text)
53                 {
54                         $(this).val(text);
55                 }
56                 if (datepicker)
57                 {
58                         $(this).datepicker();
59                 }
60         }
61 });
62
63 $(document).ready(function() {
64         $.prettyLoader();
65         if (!hasPlaceholderSupport())
66         {
67                 $('input:text,input:password,textarea').each(function () {
68                         datepicker = false;
69                         text = $(this).attr('placeholder');
70                         if ($(this).hasClass('datepicker'))
71                         {
72                                 datepicker = true;
73                                 $(this).datepicker('remove');
74                         }
75                         if (text)
76                         {
77                                 $(this).val(text);
78                         }
79                         if (datepicker)
80                         {
81                                 $(this).datepicker();
82                         }
83                 });
84         }
85         $('.nav-vertical .nav-list:odd:not(:first)').slideToggle();
86         $('.nav-vertical .nav-header > span > i').toggleClass('icon-circle-arrow-down');
87         $('.nav-vertical .nav-list:even').click(function () {
88                 $(this).next().slideToggle();
89                 $(this).find("i").toggleClass('icon-circle-arrow-down');
90         });
91         //$("input:checkbox, input:radio").uniform();
92         $("[rel=tooltip]").tooltip({
93                 placement:"top",
94                 delay: 250
95         });
96         $(".alert").alert();
97         $(".popover").popover();
98         $(".datepicker").datepicker({
99                 dateFormat: 'yy-mm-dd'
100         });
101         setInterval('updateClock()', 1000);
102         jQuery.validator.messages.required = "";
103         jQuery.validator.messages.email = "";
104 });
105
106 $("#deleteForm").submit(function () {
107         $("[rel=tooltip]").tooltip('hide');
108         doUpdate('delete',
109                 $('#delete_namespace').val(),
110                 $('#delete_remove_action').val(),
111                 $('#delete_refresh_container').val(),
112                 $('#delete_refresh_action').val(),
113                 false, true);
114         return false;
115 });
116
117 function loadPage(page, options) {
118         $("[rel=tooltip]").tooltip('hide');
119         $('#adminMainContent').fadeTo(300, 0.5);
120         $('#adminMainContent').load(
121                 '/admin/' + page, options,
122                 function () {
123                         $('#adminMainContent').fadeTo(200, 1);
124                         $("[rel=tooltip]").tooltip({
125                                 placement:"top",
126                                 delay: 250
127                         });
128                         $(".alert").alert();
129                         $(".popover").popover();
130                         $(".datepicker").datepicker({
131                                 dateFormat: 'yy-mm-dd'
132                         });
133                 });
134 }
135
136 function pagerPage(section, action, pagenum) {
137         $("[rel=tooltip]").tooltip('hide');
138         $('#' + section).fadeTo(300, 0.5);
139         $('#' + section).load(
140                 '/' + theme + '/' + action,
141                 {
142                         pg_page: pagenum
143                 },
144                 function () {
145                         $('#' + section).fadeTo(200, 1);
146                 });
147 };
148
149 function pagerRecords(section, action, numrecords) {
150         $("[rel=tooltip]").tooltip('hide');
151         $('#' + section).fadeTo(300, 0.5);
152         $('#' + section).load(
153                 '/' + theme + '/' + action,
154                 {
155                         pg_records: numrecords,
156                         pg_page:1
157                 },
158                 function () {
159                         $('#' + section).fadeTo(200, 1);
160                 });
161 };
162
163 function search(namespace) {
164         prepend = namespace.replace('-', '_') + '_';
165         meta = searchHandler[namespace];
166         $("[rel=tooltip]").tooltip('hide');
167         $('#' + meta['container']).fadeTo(300, 0.5);
168         data = {};
169         data["x"] = "x";
170         inputs = $('input.' + namespace + ', select.' + namespace).toArray();
171         for (index in inputs) {
172                 item = inputs[index];
173                 if ($(item).attr('name') != undefined) {
174                         value = $(item).val();
175                         if (value.length) {
176                                 name = $(item).attr('name');
177                                 name = name.replace(prepend, '');
178                                 data[name] = value;
179                         }
180                 }
181         }
182         refreshContent(meta['container'], meta['action'], false, false, {
183                 pg_filter: data,
184                 pg_page:1
185         });
186 };
187
188 function order(namespace, field, direction) {
189         meta = searchHandler['srch-' + namespace];
190         $("[rel=tooltip]").tooltip('hide');
191         $('#' + meta['container']).fadeTo(300, 0.5);
192         data = {};
193         data[field] = direction;
194         refreshContent(meta['container'], meta['action'], false, false, {
195                 pg_order: data,
196                 pg_page:1
197         });
198 }
199
200 function flagItem(field, id, label, refreshContainer, refreshAction) {
201         $("[rel=tooltip]").tooltip('hide');
202         $('#' + refreshContainer).fadeTo(300, 0.5);
203         $.ajax({
204                 type: "POST",
205                 url: '/util/utility/set-data-flag',
206                 data: {
207                         fieldname: field,
208                         filter: id,
209                         filterlabel: label
210                 },
211                 success: function(data, textStatus, jqXHR) {
212                         $('#' + refreshContainer).fadeTo(300, 1);
213                         try {
214                                 response = typeof(data)=='string'
215                                 ? $.parseJSON(data)
216                                 : data;
217                         } catch (e) {
218                                 alert('Could not flag data entry!');
219                         }
220                         refreshContent(refreshContainer, refreshAction);
221                 },
222                 error: function(jqXHR, textStatus, errorThrown) {
223                         $('#' + refreshContainer).fadeTo(300, 1);
224                         alert('Oops: Could not flag data entry!');
225                 }
226         });
227
228 }
229
230 function collectData(dataAction, requestData) {
231         $("[rel=tooltip]").tooltip('hide');
232         if (!requestData) {
233                 requestData = {};
234         }
235         $.ajax({
236                 type: "POST",
237                 url: '/' + dataAction,
238                 data: requestData,
239                 success: function(data, textStatus, jqXHR) {
240                         try {
241                                 response = typeof(data)=='string'
242                                 ? $.parseJSON(data)
243                                 : data;
244                         } catch (e) {
245                                 alert('Oops, incorrect data format received from the server!');
246                         }
247                         while (postCollectAction.length) {
248                                 (postCollectAction.shift())(response['Data']);
249                         }
250                         return false;
251                 },
252                 error: function(jqXHR, textStatus, errorThrown) {
253                         alert('Oops: ' + errorThrown);
254                         return false;
255                 }
256         });
257 };
258
259 function refreshContent(section, action, titleId, title, data) {
260         $("[rel=tooltip]").tooltip('hide');
261         $('#' + section).fadeTo(300, 0.5);
262         if (!data) {
263                 data = {};
264         }
265         $('#' + section).load(
266                 '/' + action,
267                 data,
268                 function () {
269                         $('#' + section).fadeTo(200, 1);
270                         while (postRefreshAction.length) {
271                                 (postRefreshAction.shift())();
272                         }
273                 });
274         if (titleId) {
275                 $('#' + titleId).html(title);
276         }
277 };
278
279 function clearForm(namespace, modalElement) {
280         $("[rel=tooltip]").tooltip('hide');
281         $("[form-id=" + namespace + "]").each(function() {
282                 if (this.name) {
283                         if ($(this).is(':checkbox')) {
284                                 $(this).prop("checked", false);
285                         } else if ($(this).is('textarea')) {
286                                 $(this).val('');
287                                 $('.wysihtml5-sandbox').contents().find('body').html('');
288                         } else if ($(this).hasClass('data-dependant-chain') || $(this).hasClass('data-dependant-child')) {
289                                 meta = $(this).metadata({
290                                         type:'attr',
291                                         name:'data'
292                                 });
293                                 meta = $('#' + meta['parent']).metadata({
294                                         type:'attr',
295                                         name:'data'
296                                 });
297                                 $(this).html('<option value="">--- Select ' + meta['title'] + ' ---</option>');
298                         } else {
299                                 $(this).val('');
300                         }
301                 }
302         });
303         if (modalElement) {
304                 $('#' + modalElement).modal('toggle');
305         }
306         mode = 'create';
307 };
308
309 function populateForm(namespace, context, dataItem, modalElement) {
310         mode = 'populate';
311         $("[rel=tooltip]").tooltip('hide');
312         depParentValue = 0;
313         $('[id^=' + namespace + '_]').each(function (){
314                 field = $(this).attr('id');
315                 field = field.replace(namespace + '_', '');
316                 element = $(this);
317
318                 if (typeof(dataItem[field]) == "undefined")
319                 {
320                         bits = field.split("_");
321                         sub = bits[bits.length-1];
322                         bits = bits.splice(0, bits.length-1);
323                         dataValue = (dataItem[bits.join('_')])
324                         ? dataItem[bits.join('_')][sub]
325                         : "";
326                 }
327                 else
328                 {
329                         dataValue = dataItem[field];
330                 }
331                 if (typeof(dataValue) != "undefined")
332                 {
333                         if (element.is(':checkbox')) {
334                                 if ('1' == dataValue) {
335                                         element.prop("checked", true);
336                                 } else {
337                                         element.prop("checked", false);
338                                 }
339                         } else if (element.is('textarea')) {
340                                 element.val(dataValue);
341                                 $('.wysihtml5-sandbox').contents().find('body').html(dataValue);
342                         } else if (element.hasClass('data-dependant-chain') || element.hasClass('data-dependant-child')) {
343                                 meta = element.metadata({
344                                         type:'attr',
345                                         name:'data'
346                                 });
347                                 parentDataField = context + '_' + meta['parent'].replace(namespace + '_', '')
348                                 meta = $('#' + meta['parent']).metadata({
349                                         type:'attr',
350                                         name:'data'
351                                 });
352                                 element.load(
353                                         '/' + theme + '/' + 'list-dependancy-select',
354                                         {
355                                                 dep_filter:{
356                                                         item:meta['item'],
357                                                         field:meta['filterField'],
358                                                         value:dataItem[parentDataField],
359                                                         selected:dataValue
360                                                 }
361                                         }
362                                         );
363                         } else {
364                                 element.val(dataValue);
365                         }
366                 }
367         });
368
369         if (modalElement) {
370                 $('#' + modalElement).modal('toggle');
371         }
372         mode = 'update';
373 };
374
375 function collectFormData(selector) {
376         values = {};
377         $(selector).each(function() {
378                 if (this.name) {
379                         shortname = this.name;
380                         if ($(this).is(':checkbox'))
381                         {
382                                 values[$(this).val()] = $(this).is(':checked') ? 1 : 0;
383                         }
384                         else if ($(this).is(':radio'))
385                         {
386                                 values[shortname] = $('input[name=' + this.name + ']:checked').val();
387                         }
388                         else
389                         {
390                                 values[shortname] = $(this).val();
391                         }
392
393                 }
394         });
395         return values;
396 }
397
398 function doUpdate(namespace, datanamespace, updateAction, refreshContainer, refreshAction,
399         warningContainer, closeOnSave, redirect, addon) {
400         $("[rel='tooltip']").tooltip('hide');
401         if (refreshContainer) {
402                 $('#' + refreshContainer).fadeTo(300, 0.5);
403         }
404         $('.btn-save').button('loading');
405         values = {};
406         if (namespace) {
407                 values = collectFormData("[form-id='" + namespace + "']");
408         }
409         if (addon) {
410                 for (index in addon) {
411                         values[index] = addon[index];
412                 }
413         }
414         if (updateAutoData[updateAction]) {
415                 for (index in updateAutoData[updateAction]) {
416                         values[index] = updateAutoData[updateAction][index];
417                 }
418         }
419         if (datanamespace) {
420                 var postData = {};
421                 postData[datanamespace] = values;
422         } else {
423                 var postData = values;
424         }
425         $.ajax({
426                 type: "POST",
427                 url: '/' + updateAction,
428                 data: postData,
429                 success: function(data, textStatus, jqXHR) {
430                         response = data;
431                         if ('Success' == response['Status']) {
432                                 if ('RecordId' in response) {
433                                         lastUpdatedId = response['RecordId'];
434                                 } else {
435                                         lastUpdatedId = false;
436                                 }
437                                 if (warningContainer) {
438                                   flashPopover(
439               warningContainer.element,
440               (warningContainer.placement) ? warningContainer.placement : "right",
441               (warningContainer.title) ? warningContainer.title : "Oops",
442               response['Message'],
443               (warningContainer.length) ? warningContainer.length : 3000
444             );
445         } else {
446                                 }
447                                 if ((refreshContainer) && (refreshAction)) {
448                                         if (refreshAutoData[refreshContainer]) {
449                                                 refreshContent(refreshContainer, refreshAction, false, false, refreshAutoData[refreshContainer]);
450                                         } else {
451                                                 refreshContent(refreshContainer, refreshAction);
452                                         }
453                                 }
454                                 if (closeOnSave) {
455                                         if ('boolean' == typeof(closeOnSave)) {
456                                                 modalElement = '#modal' + ucfirst(namespace);
457                                         } else {
458                                                 modalElement = '#' + closeOnSave;
459                                         }
460                                         $(modalElement).modal('toggle');
461                                 }
462                                 while (postUpdateAction.length) {
463                                         (postUpdateAction.shift())(response);
464                                 }
465                                 if (redirect) {
466                                         $('.btn-save').button('complete');
467                                         window.location = redirect;
468                                 }
469                         } else if ('Error' == response['Status']) {
470               if (refreshContainer) {
471                 $('#' + refreshContainer).fadeTo(300, 1.0);
472               }
473                                 if (warningContainer) {
474                                   flashPopover(
475               warningContainer.element,
476               (warningContainer.placement) ? warningContainer.placement : "right",
477               (warningContainer.title) ? warningContainer.title : "Oops",
478               response['Message'],
479               (warningContainer.length) ? warningContainer.length : 3000
480             );
481                                 } else {
482                                         alert('Service Error: ' + response['Message']);
483                                 }
484                         } else {
485                                 alert(data);
486                         }
487                         $('.btn-save').button('complete');
488                         return false;
489                 },
490                 error: function(jqXHR, textStatus, errorThrown) {
491       if (refreshContainer) {
492         $('#' + refreshContainer).fadeTo(300, 1.0);
493       }
494                         $('.btn-save').button('complete');
495                         alert('Oops: ' + errorThrown);
496                         return false;
497                 }
498         });
499 }
500
501 function confirmDelete(namespace, removeAction, id, refreshContainer, refreshAction) {
502         $('#delete_id').val(id);
503         $('#delete_namespace').val(namespace);
504         $('#delete_remove_action').val(removeAction);
505         $('#delete_refresh_container').val(refreshContainer);
506         $('#delete_refresh_action').val(refreshAction);
507         $('#modalDelete').modal('toggle');
508 };
509
510 function flashPopover(element, placement, title, content, length) {
511   $('#' + element).popover({
512     "placement": placement,
513     "title": title,
514     "content": content,
515     "trigger": "manual"
516   });
517   $('#btnLogin').popover('show');
518   if (!length) {
519     length = 3000;
520   }
521   setTimeout(function () {
522     $('#' + element).popover('hide');
523   }, length);
524 }
525
526 /*
527  *      Function wrapping code.
528  *      fn - reference to function.
529  *      context - what you want "this" to be.
530  *      params - array of parameters to pass to function.
531  *      Example usage:
532  *       var sayStuff = function(str) { alert(str); };
533  *       var fun1 = wrapFunction(sayStuff, this, ["Hello, world!"]);
534  *       funqueue.push(fun1);
535  */
536 var wrapFunction = function(fn, context, params) {
537         return function() {
538                 fn.apply(context, params);
539         };
540 };
541
542 function resetSaveButton() {
543         $('.btn-save').button('complete');
544 };
545
546 function resetTooltips() {
547         $(".tooltip").remove();
548         $("[rel=tooltip]").tooltip({
549                 placement:"top",
550                 delay: 250
551         });
552         setTimeout(function() {
553                 $(".icon-fade").fadeTo(300, 0.35);
554         }, 200);
555 }
556
557 function populateSelect(target, instruction, data, selected) {
558         var opts = '<option value="">-- ' + instruction + ' --</option>';
559         for (var i in data) {
560                 var chosen = (selected == i) ? ' selected' : '';
561                 opts += '<option value="' + i + '"' + chosen + '>' + data[i] + '</option>';
562         }
563         $('#' + target).html(opts);
564 }
565
566 function ucfirst(string)
567 {
568         return string.charAt(0).toUpperCase() + string.slice(1);
569 };
570
571 function updateClock()
572 {
573         var currentTime = new Date ( );
574         var currentHours = currentTime.getHours ( );
575         var currentMinutes = currentTime.getMinutes ( );
576         var currentSeconds = currentTime.getSeconds ( );
577         currentMinutes = ( currentMinutes < 10 ? "0" : "" ) + currentMinutes;
578         currentSeconds = ( currentSeconds < 10 ? "0" : "" ) + currentSeconds;
579         currentHours = ( currentHours == 0 ) ? 12 : currentHours;
580         var currentTimeString = currentHours + ":" + currentMinutes + ":" + currentSeconds;
581         $("#clock").html(currentTimeString);
582         $("#clockmobi").html(currentTimeString);
583 }
584
585 function calculateTimeLeft(value)
586 {
587         var dateTime = value.split(' '),
588         date     = dateTime[0],
589         time     = dateTime[1],
590
591         dateParts = date.split('-').map(function(part){
592                 return parseInt(part, 10);
593         }),
594         timeParts = time.split(':').map(function(part){
595                 return parseInt(part, 10);
596         }),
597         expieDateTime = new Date(dateParts[0], dateParts[1]-1, dateParts[2], timeParts[0], timeParts[1], timeParts[2] ),
598         currentDateTime = new Date(),
599         difference = expieDateTime.getTime() - currentDateTime.getTime(),
600         daysDifference, hoursDifference, minutesDifference, secondsDifference;
601
602         daysDifference = Math.floor(difference/1000/60/60/24);
603         difference -= daysDifference*1000*60*60*24;
604         hoursDifference = Math.floor(difference/1000/60/60);
605         difference -= hoursDifference*1000*60*60;
606         minutesDifference = Math.floor(difference/1000/60);
607         difference -= minutesDifference*1000*60;
608         secondsDifference = Math.floor(difference/1000);
609
610   if (expieDateTime.getTime() < currentDateTime.getTime()) {
611     return '0m';
612   }
613
614         return daysDifference > 0
615          ? daysDifference + 'd, ' + hoursDifference + 'h, ' + minutesDifference + 'm'
616          : hoursDifference + 'h, ' + minutesDifference + 'm';
617         
618 }