1// Pass the id of the initial select2 tag that is used 2// to create the select2 3function select2_has_error(el, color='#A94442'){ 4 var tag = $(el).select(); 5 if ( tag ) { 6 var link_bound = tag[0].previousElementSibling.childNodes[0]; 7 $(link_bound).css('border-color', color); 8 } 9} 10 11function select2_no_error(el){ 12 select2_has_error(el, ''); 13} 14 15// Toggle password visibility input by id 16// 17function toggle_on(password){ 18 password.type = "text"; 19} 20function toggle_off(password){ 21 //Add timer hide if copy is needed 22 setTimeout(function(){ 23 password.type = "password"; 24 }, 2000); 25} 26 27Number.prototype.length_between = function(a, b, inclusive) { 28 var min = Math.min(a, b), 29 max = Math.max(a, b), 30 len = this.toString().length; 31 return inclusive ? len >= min && len <= max : len > min && len < max; 32} 33 34function urlEncode(s){ 35 return encodeURIComponent( s ).replace( /\%20/g, '+' ).replace( /!/g, '%21' ).replace( /'/g, '%27' ).replace( /\(/g, '%28' ).replace( /\)/g, '%29' ).replace( /\*/g, '%2A' ).replace( /\~/g, '%7E' ); 36} 37 38function urlDecode(s){ 39 return decodeURIComponent( s.replace( /\+/g, '%20' ).replace( /\%21/g, '!' ).replace( /\%27/g, "'" ).replace( /\%28/g, '(' ).replace( /\%29/g, ')' ).replace( /\%2A/g, '*' ).replace( /\%7E/g, '~' ) ); 40} 41 42function urlEncode2 (str) { 43 return encodeURIComponent(str). 44 // Note that although RFC3986 reserves "!", RFC5987 does not, 45 // so we do not need to escape it 46 replace(/['()]/g, escape). // i.e., %27 %28 %29 47 replace(/\*/g, '%2A'). 48 // The following are not required for percent-encoding per RFC5987, 49 // so we can allow for a little better readability over the wire: |`^ 50 replace(/%(?:7C|60|5E)/g, unescape); 51} 52 53// adds '!' to encodeURIComponent 54~function () { 55 var orig = window.encodeURIComponent; 56 window.encodeURIComponent = function (str) { 57 // calls the original function, and adds your 58 // functionality to it 59 return orig.call(window, str).replace(/!/g, '%21').replace(/\*/g,'%2A').replace(/\$/g,'%24'); 60 }; 61}(); 62 63function escapeHtml(text) { 64 return text 65 .replace(/&/g, "&") 66 .replace(/</g, "<") 67 .replace(/>/g, ">") 68 .replace(/"/g, """) 69 .replace(/'/g, "'"); 70} 71 72function IsAlphaNumeric(input) { 73 var regex = /[^a-zA-Z0-9]/; 74 return regex.test(input); 75} 76 77function IsEmail(emails) 78{ 79 var res = emails.split(","); 80 for(i = 0; i < res.length; i++) 81 if(!validateEmail(res[i])) return false; 82 return true; 83} 84 85function dt_sleep(milliseconds) { 86 var start = new Date().getTime(); 87 for (var i = 0; i < 1e7; i++) { 88 if ((new Date().getTime() - start) > milliseconds){ 89 break; 90 } 91 } 92} 93 94function validateEmail(email){ 95 var regex = /^([a-zA-Z0-9_\.\-\+\&])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,10})+$/; 96 return regex.test(email); 97} 98function IsPhoneNumber(num) { 99 var regex = /^[0-9-+]+$/; 100 if (num.length < 10){ return false; } 101 return regex.test(num); 102} 103function isMacAddress(mac){ 104 var regex = /^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$/; 105 return regex.test(mac); 106} 107function isNumber(num){ 108 num = num.replace(",",""); 109 return !isNaN(num); 110} 111function IsPassword(input){ 112 var regex = /^.*[a-zA-Z0-9\@\^\~\+=\\\*\(\)\{<\}\$\!%\#\?&\|>\[\}\-\/\.\,\;\:_]{6,}$/; 113 return regex.test(input); 114} 115function IsTime(input,format){ 116 var regex = /^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/; 117 if (format=="hh:mm"){ 118 regex = /^([0-1][0-9]|2[0-3]):([0-5][0-9])$/; 119 } 120 return regex.test(input); 121} 122function isDate(input,format){ 123 var regex= ""; 124 if (format===undefined || format=="yyyy-mm-dd"){ 125 regex = /^\d{4}[\-\/\s]?((((0[13578])|(1[02]))[\-\/\s]?(([0-2][0-9])|(3[01])))|(((0[469])|(11))[\-\/\s]?(([0-2][0-9])|(30)))|(02[\-\/\s]?[0-2][0-9]))$/; 126 } 127 return regex.test(input); 128} 129function IsValidIP(input){ 130 if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(input)){ 131 return true; 132 } else { 133 return false;
134 } 135} 136function IsIDnumber(input){ 137 var regex = /(((\d{2}((0[13578]|1[02])(0[1-9]|[12]\d|3[01])|(0[13456789]|1[012])(0[1-9]|[12]\d|30)|02(0[1-9]|1\d|2[0-8])))|([02468][048]|[13579][26])0229))(( |-)(\d{4})( |-)(\d{3})|(\d{7}))$/; 138 return regex.test(input); 139} 140 141function isValidGPS(input){ 142 var regex = /([+-]?\d+\.?\d+)\s*,\s*([+-]?\d+\.?\d+)/; 143 return regex.test(input.trim()); 144} 145 146function isValidURL(input) { 147 var regex = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/; 148 return regex.test(input.trim()); 149} 150 151function isValidDomain(input) { 152 var regex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/; 153 return regex.test(input.trim()); 154} 155 156/* 157function ValidateIPAddress($checkipaddress) { 158 var IpAddReg = /^([1-9][0-9]{0,1}|1[0-9]{2}|2[0-4][0-9]|25[0-4])\.([1-9][0-9]{0,1}|1[0-9]{2}|2[0-4][0-9]|25[0-4])\.([1-9][0-9]{0,1}|1[0-9]{2}|2[0-4][0-9]|25[0-4])\.([1-9][0-9]{0,1}|1[0-9]{2}|2[0-4][0-9]|25[0-4])$/; 159 return IpAddReg.test( $checkipaddress ); 160}; 161*/ 162
163function Ucfirst(string) 164{ 165 return string.charAt(0).toUpperCase() + string.slice(1); 166} 167 168var ordinalize = function(n) { 169 var s=["th","st","nd","rd"], 170 v=n%100; 171 return n+(s[(v-20)%10]||s[v]||s[0]); 172} 173 174function today(){ 175 var d = new Date(); 176 var month = d.getMonth()+1; 177 var day = d.getDate(); 178 var output = d.getFullYear() + '-' + 179 ((''+month).length<2 ? '0' : '') + month + '-' + 180 ((''+day).length<2 ? '0' : '') + day; 181 return(output); 182} 183 184function formatNum(nStr) 185{ 186 return accounting.formatMoney(nStr, '', 2, ",", "."); 187/* 188 nStr += ''; 189 x = nStr.split('.'); 190 x1 = x[0]; 191 x2 = x.length > 1 ? '.' + x[1] : ''; 192 var rgx = /(\d+)(\d{3})/; 193 while (rgx.test(x1)) { 194 x1 = x1.replace(rgx, '$1' + ',' + '$2'); 195 } 196 return x1 + x2; 197*/ 198} 199 200function removeNL(s) { 201 r = ""; 202 for (i=0; i < s.length; i++) { 203 if (s.charAt(i) != '\n' && 204 s.charAt(i) != '\r' && 205 s.charAt(i) != '\t') { 206 r += s.charAt(i); 207 } else { 208 r += ' '; 209 } 210 } 211 return r; 212} 213 214function amount(amt, label) { 215 return amt.toFixed(2); 216} 217 218function formatMoney(n, c, d, t){ 219 var c = isNaN(c = Math.abs(c)) ? 2 : c, 220 d = d == undefined ? "." : d, 221 t = t == undefined ? "," : t, 222 s = n < 0 ? "-" : "", 223 i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", 224 j = (j = i.length) > 3 ? j % 3 : 0; 225 return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ""); 226}; 227 228function bytes(bytes, label) { 229 if (bytes == 0) return ; 230 var s = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']; 231 var e = Math.floor(Math.log(bytes)/Math.log(1024)); 232 var value = ((bytes/Math.pow(1024, Math.floor(e))).toFixed(1)); 233 e = (e<0) ? (-e) : e; 234 if (label) value += ' ' + s[e]; 235 return value; 236} 237function speed(bytes, label) { 238 if (bytes == 0) return ; 239 var s = ['b/s', 'Kb/s', 'Mb/s', 'Gb/s', 'Tb/s', 'Pb/s']; 240 var e = Math.floor(Math.log(bytes)/Math.log(1024)); 241 var value = ((bytes/Math.pow(1024, Math.floor(e))).toFixed(1)); 242 e = (e<0) ? (-e) : e; 243 if (label) value += ' ' + s[e]; 244 return value; 245} 246function data_speed(bytes, label) { 247 if (bytes == 0) return ; 248 var s = ['b/s', 'Kb/s', 'Mb/s', 'Gb/s', 'Tb/s', 'Pb/s']; 249 var e = Math.floor(Math.log(bytes)/Math.log(1024)); 250 var value = ((bytes/Math.pow(1024, Math.floor(e))).toFixed(1)); 251 e = (e<0) ? (-e) : e; 252 if (label) value += ' ' + s[e]; 253 return value; 254} 255 256function speed_1000(bytes, label) { 257 if (bytes == 0) return 0; 258 if (bytes < 0){bytes = bytes * -1;} 259 var s = ['b/s', 'Kb/s', 'Mb/s', 'Gb/s', 'Tb/s', 'Pb/s']; 260 var e = Math.floor(Math.log(bytes)/Math.log(1000)); 261 var value = ((bytes/Math.pow(1000, Math.floor(e))).toFixed(1)); 262 e = (e<0) ? (-e) : e; 263 if (label) value += ' ' + s[e]; 264 return value; 265} 266 267function sec_to_time(secs){ 268// var ts = (new Date).clearTime().addSeconds(secs).toString('H:mm:ss'); 269// return ts; 270 271 var sec_num = parseInt(secs, 10); // don't forget the second param 272 var hours = Math.floor(sec_num / 3600); 273 var minutes = Math.floor((sec_num - (hours * 3600)) / 60); 274 var seconds = sec_num - (hours * 3600) - (minutes * 60); 275 276 if (hours < 10) {hours = "0"+hours;} 277 if (minutes < 10) {minutes = "0"+minutes;} 278 if (seconds < 10) {seconds = "0"+seconds;} 279 var time = hours+':'+minutes+':'+seconds; 280 return time; 281} 282 283function sec_to_time_days(secs){ 284// var ts = (new Date).clearTime().addSeconds(secs).toString('H:mm:ss'); 285// return ts; 286 287 var sec_num = parseInt(secs, 10); // don't forget the second param 288 var days = Math.floor(sec_num / 86400); 289 var hours = Math.floor(sec_num / 3600); 290 var minutes = Math.floor((sec_num - (hours * 3600)) / 60); 291 var seconds = sec_num - (hours * 3600) - (minutes * 60); 292 293 if (hours > 23) {hours = hours - (Math.floor(hours / 24)*24);} 294 if (hours < 10) {hours = "0"+hours;} 295 if (minutes < 10) {minutes = "0"+minutes;} 296 if (seconds < 10) {seconds = "0"+seconds;} 297 var time = days+' days '+hours+':'+minutes+':'+seconds; 298 return time; 299} 300 301function nl2br (str, is_xhtml) { 302 var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>'; 303 return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2'); 304} 305 306String.prototype.toUpperCaseFirstChar = function() { 307 return this.substr( 0, 1 ).toUpperCase() + this.substr( 1 ); 308} 309 310function guid() { 311 function s4() { 312 return Math.floor((1 + Math.random()) * 0x10000) 313 .toString(16) 314 .substring(1); 315 } 316 return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); 317} 318 319/* 320$.noty.defaults = { 321 layout: 'top', 322 theme: 'bootstrapTheme', // or 'relax' 323 type: 'alert', 324 text: '', // can be html or string 325 dismissQueue: true, // If you want to use queue feature set this true 326 template: '<div class="noty_message"><span class="noty_text"></span><div class="noty_close"></div></div>', 327 animation: { 328 open: {height: 'toggle'}, // or Animate.css class names like: 'animated bounceInLeft' 329 close: {height: 'toggle'}, // or Animate.css class names like: 'animated bounceOutLeft' 330 easing: 'swing', 331 speed: 500 // opening & closing animation speed 332 }, 333 timeout: false, // delay for closing event. Set false for sticky notifications 334 force: false, // adds notification to the beginning of queue when set to true 335 modal: false, 336 maxVisible: 5, // you can set max visible notification for dismissQueue true option, 337 killer: false, // for close all notifications before show 338 closeWith: ['click'], // ['click', 'button', 'hover', 'backdrop'] // backdrop click will close all notifications 339 callback: { 340 onShow: function() {}, 341 afterShow: function() {}, 342 onClose: function() {}, 343 afterClose: function() {}, 344 onCloseClick: function() {}, 345 },
346 buttons: false // an array of buttons 347}; 348*/ 349 350 351function show_notify(message_text,message_type,message_position,message_duration,message_container){ 352 if (message_position === undefined ){ message_position = 'topRight';} 353 if (message_type === undefined ){ message_type = 'alert';} 354 if (message_duration === undefined ){ message_duration = 7500;} 355 if (message_container === undefined ){ message_container = null;} 356 357 358 new Noty({ 359 text: message_text, 360 type: message_type, 361 theme: 'bootstrap-v3', 362 timeout: message_duration, 363 layout: message_position, 364 progressBar: true, 365 container: message_container 366 }).show(); 367 368/* 369 new Noty({ 370 text: message_text, 371 layout: message_position, 372 theme: 'bootstrapTheme', 373 type: message_type, 374 dismissQueue: true, // If you want to use queue feature set this true 375 template: '<div class="noty_message"><span class="noty_text"></span><div class="noty_close"></div></div>', 376 animation: { 377 open: {height: 'toggle'}, 378 close: {height: 'toggle'}, 379 easing: 'swing', 380 speed: 500 // opening & closing animation speed 381 }, 382 timeout: message_duration, // delay for closing event. Set false for sticky notifications 383 force: false, // adds notification to the beginning of queue when set to true 384 modal: false, 385 maxVisible: 5, // you can set max visible notification for dismissQueue true option 386 closeWith: ['click'], // ['click', 'button', 'hover'] 387 callback: { 388 onShow: function() {}, 389 afterShow: function() {}, 390 onClose: function() {}, 391 afterClose: function() {} 392 },
393 buttons: false // an array of buttons 394 }).show(); 395*/ 396} 397 398function confirm_notify(message_text,message_type,message_position,message_duration){ 399 if (message_position === undefined ){ message_position = 'topRight';} 400 if (message_type === undefined ){ message_type = 'alert';} 401 if (message_duration === undefined ){ message_duration = 10000;} 402 403 new Noty({ 404 text: message_text, 405 type: message_type, 406 timeout: false, 407 closeWith: ['click'], 408 }).show(); 409 410/* 411 new Noty({ 412 text: message_text, 413 layout: message_position, 414 theme: 'bootstrapTheme', 415 type: message_type, 416 dismissQueue: true, // If you want to use queue feature set this true 417 template: '<div class="noty_message"><span class="noty_text"></span><div class="noty_close"></div></div>', 418 animation: { 419 open: {height: 'toggle'}, 420 close: {height: 'toggle'}, 421 easing: 'swing', 422 speed: 500 // opening & closing animation speed 423 }, 424 timeout: false, // delay for closing event. Set false for sticky notifications 425 force: false, // adds notification to the beginning of queue when set to true 426 modal: true, 427 maxVisible: 5, // you can set max visible notification for dismissQueue true option 428 closeWith: ['click'], // ['click', 'button', 'hover'] 429 callback: { 430 onShow: function() {}, 431 afterShow: function() {}, 432 onClose: function() {}, 433 afterClose: function() {} 434 }, 435 buttons: [ 436 {addClass: 'btn btn-default btn-sm', text: 'Ok', onClick: function($noty) { 437 $noty.close(); 438 } 439 } 440 ] 441 }).show(); 442*/ 443} 444 445var graph_fonts = "Helvetica,Arial,Sans-Serif "; 446var graph_font_size = "normal 11px "; 447var graph_title_size = "normal 12px "; 448var graph_legend_size = "12px "; 449 450var red_to_green = [ 451 '#00ff00', 452 '#33ff00', 453 '#66ff00', 454 '#99ff00', 455 '#ccff00', 456 '#ffff00', 457 '#ffcc00', 458 '#ff9900', 459 '#ff6600', 460 '#ff3300', 461 '#ff0000', 462] 463var graph_colors = [ 464 '#ff0000', 465 '#2f7ed8', 466 '#8bbc21', 467 '#910000', 468 '#1aadce', 469 '#492970', 470 '#f28f43', 471 '#77a1e5', 472 '#c42525', 473 '#89A54E', 474 '#4572A7', 475 '#80699B', 476 '#AA4643', 477 '#ccc', 478 '#888', 479 '#a6c96a', 480 '#3D96AE', 481 '#DB843D', 482 '#92A8CD', 483 '#A47D7C', 484 '#B5CA92', 485 '#a6cee3', 486 '#1f78b4', 487 '#8bbc21', 488 '#b2df8a', 489 '#33a02c', 490 '#fb9a99', 491 '#e31a1c', 492 '#fdbf6f', 493 '#ff7f00', 494 '#cab2d6', 495 '#6a3d9a', 496 '#ffff99', 497 '#b15928' 498]; 499 500var graph_colors_workflow = [ 501 '#2f7ed8', 502 '#8bbc21', 503 '#1aadce', 504 '#492970', 505 '#f28f43', 506 '#77a1e5', 507 '#c42525', 508 '#89A54E', 509 '#4572A7', 510 '#80699B', 511 '#AA4643', 512 '#ccc', 513 '#888', 514 '#a6c96a', 515 '#3D96AE', 516 '#DB843D', 517 '#92A8CD', 518 '#A47D7C', 519 '#B5CA92', 520 '#a6cee3', 521 '#1f78b4', 522 '#8bbc21', 523 '#b2df8a', 524 '#33a02c', 525 '#fb9a99', 526 '#e31a1c', 527 '#fdbf6f', 528 '#ff7f00', 529 '#cab2d6', 530 '#6a3d9a', 531 '#ffff99', 532 '#b15928', 533 '#ff0000', 534 '#910000' 535]; 536 537var phone_colors = [ 538 '#80699B', 539 '#89A54E' 540]; 541 542var data_colors = [ 543 '#6BB848', 544 '#75CC58' 545]; 546 547var traffic_colors = [ 548// '#87CEFA', 549 '#4682B4', 550 '#9ABD93', 551// '#CD748F' 552]; 553 554 555(function($) { 556 $.fn.spin = function(opts, color) { 557 var presets = { 558 "tiny": { lines: 8, length: 2, width: 2, radius: 3 }, 559 "small": { lines: 8, length: 4, width: 3, radius: 5 }, 560 "large": { lines: 10, length: 8, width: 4, radius: 8 } 561 }; 562 if (Spinner) { 563 return this.each(function() { 564 var $this = $(this), 565 data = $this.data(); 566 567 if (data.spinner) { 568 data.spinner.stop(); 569 delete data.spinner; 570 } 571 if (opts !== false) { 572 if (typeof opts === "string") { 573 if (opts in presets) { 574 opts = presets[opts]; 575 } else { 576 opts = {}; 577 } 578 if (color) { 579 opts.color = color; 580 } 581 } 582 data.spinner = new Spinner($.extend({color: $this.css('color')}, opts)).spin(this); 583 } 584 }); 585 } else { 586 throw "Spinner class not available."; 587 } 588 }; 589 $.customerSelect = function(selector,placeholder,list,prepaid) { 590 var placeholder = (typeof placeholder !== 'undefined' && placeholder.length > 0 ? placeholder : 'Select a customer'); 591 var prepaid = (typeof prepaid !== 'undefined' && prepaid > 0 ? 1 : 0); 592 return $(selector).select2({ 593 'minimumResultsForSearch': 5, 594 'placeholder' : placeholder, 595 'allowClear' : true, 596 'ajax' : { 597 'url' : datatill.url('customers/ajax_search'), 598 'dataType' : 'JSON', 599 'quietMillis' : 250, 600 'data' : function(term,page) { 601 return { 602 'query' : term, 603 'page' : page, 604 'prepaid' : (prepaid >0 ? 1 : 0), 605 606 }; 607 }, 608 'results' : function(data, page) { 609 var more = (page * 30) < data.total_rows; 610 return { 611 results : data.items, 612 'text': function(item) { 613 return item.title; 614 }, 615 'more': more, 616 }; 617 }, 618 'cache' : true 619 }, 620 'initSelection' : function(el,callback) { 621 var id = $(el).val(); 622 623 $.ajax({ 624 'dataType' : 'JSON', 625 'data' : { 626 id : id 627 }, 628 'url' : datatill.url('customers/ajax_get'), 629 'quietMillis' : 250, 630 'success' : function(data,xhr) { 631 callback({ 632 id : data.id, 633 text : data.accounting_code+'-'+data.customer_title 634 }); 635 }, 636 'error' : function(xhr) { 637 638 } 639 640 }); 641 } 642 }); 643 }; 644 $.customerMultiSelect = function(selector,placeholder) { 645 var placeholder = (typeof placeholder !== 'undefined' && placeholder.length > 0 ? placeholder : 'Select customers'); 646 return $(selector).select2({ 647 'minimumResultsForSearch': 5, 648 'multiple' : true, 649 'placeholder' : placeholder, 650 'allowClear' : true, 651 'ajax' : { 652 'url' : datatill.url('customers/ajax_search'), 653 'dataType' : 'JSON', 654 'quietMillis' : 250, 655 'data' : function(term,page) { 656 return { 657 'query' : term, 658 'page' : page 659 }; 660 }, 661 'results' : function(data, page) { 662 var more = (page * 30) < data.total_rows; 663 return { 664 results : data.items, 665 'text': function(item) { 666 return item.title; 667 }, 668 'more': more, 669 }; 670 }, 671 'cache' : true 672 }, 673 'initSelection' : function(el,callback) { 674 var id = $(el).val(); 675 676 $.ajax({ 677 'dataType' : 'JSON', 678 'data' : { 679 id : id 680 }, 681 'url' : datatill.url('customers/ajax_get'), 682 'quietMillis' : 250, 683 'success' : function(data,xhr) { 684 callback({ 685 id : data.id, 686 text : data.accounting_code+'-'+data.customer_title 687 }); 688 }, 689 'error' : function(xhr) { 690 691 } 692 693 }); 694 } 695 }); 696 }; 697 $.customerDebtorsSelect = function(selector,placeholder,list) { 698 var placeholder = (typeof placeholder !== 'undefined' && placeholder.length > 0 ? placeholder : 'Select a customer'); 699 700 return $(selector).select2({ 701 'minimumResultsForSearch': 5, 702 'placeholder' : placeholder, 703 'allowClear' : true, 704 'ajax' : { 705 'url' : datatill.url('customers/ajax_debtors_search'), 706 'dataType' : 'JSON', 707 'quietMillis' : 250, 708 'data' : function(term,page) { 709 return { 710 'query' : term, 711 'page' : page, 712 713 }; 714 }, 715 'results' : function(data, page) { 716 var more = (page * 30) < data.total_rows; 717 return { 718 results : data.items, 719 'text': function(item) { 720 return item.title; 721 }, 722 'more': more, 723 }; 724 }, 725 'cache' : true 726 }, 727 'initSelection' : function(el,callback) { 728 var id = $(el).val(); 729 730 $.ajax({ 731 'dataType' : 'JSON', 732 'data' : { 733 id : id 734 }, 735 'url' : datatill.url('customers/ajax_get'), 736 'quietMillis' : 250, 737 'success' : function(data,xhr) { 738 callback({ 739 id : data.id, 740 text : data.accounting_code+'-'+data.customer_title 741 }); 742 }, 743 'error' : function(xhr) { 744 745 } 746 747 }); 748 } 749 }); 750 }; 751 $.resellerCustomerSelect = function(selector,placeholder) { 752 var placeholder = (typeof placeholder !== 'undefined' && placeholder.length > 0 ? placeholder : 'Select a customer'); 753 return $(selector).select2({ 754 'minimumResultsForSearch': 5, 755 'placeholder' : placeholder, 756 'allowClear' : true, 757 'ajax' : { 758 'url' : datatill.url('customers/ajax_reseller_customer_search'), 759 'dataType' : 'JSON', 760 'quietMillis' : 250, 761 'data' : function(term,page) { 762 return { 763 'query' : term, 764 'page' : page 765 }; 766 }, 767 'results' : function(data, page) { 768 var more = (page * 30) < data.total_rows; 769 return { 770 results : data.items, 771 'text': function(item) { 772 return item.title; 773 }, 774 'more': more, 775 }; 776 }, 777 'cache' : true 778 }, 779 'initSelection' : function(el,callback) { 780 var id = $(el).val(); 781 $.ajax({ 782 'dataType' : 'JSON', 783 'data' : { 784 id : id 785 }, 786 'url' : datatill.url('customers/ajax_resellers_get'), 787 'quietMillis' : 250, 788 'success' : function(data,xhr) { 789 callback({ 790 id : data.id, 791 text : data.accounting_code+'-'+data.customer_title 792 }); 793 }, 794 'error' : function(xhr) { 795 796 } 797 798 }); 799 } 800 }); 801 }; 802 $.resellerCustomerMultiSelect = function(selector,placeholder) { 803 var placeholder = (typeof placeholder !== 'undefined' && placeholder.length > 0 ? placeholder : 'Select customers'); 804 return $(selector).select2({ 805 'minimumResultsForSearch': 5, 806 'placeholder' : placeholder, 807 'multiple' : true, 808 'allowClear' : true, 809 'ajax' : { 810 'url' : datatill.url('customers/ajax_reseller_customer_search'), 811 'dataType' : 'JSON', 812 'quietMillis' : 250, 813 'data' : function(term,page) { 814 return { 815 'query' : term, 816 'page' : page 817 }; 818 }, 819 'results' : function(data, page) { 820 var more = (page * 30) < data.total_rows; 821 return { 822 results : data.items, 823 'text': function(item) { 824 return item.title; 825 }, 826 'more': more, 827 }; 828 }, 829 'cache' : true 830 }, 831 'initSelection' : function(el,callback) { 832 var id = $(el).val(); 833 $.ajax({ 834 'dataType' : 'JSON', 835 'data' : { 836 id : id 837 }, 838 'url' : datatill.url('customers/ajax_resellers_get'), 839 'quietMillis' : 250, 840 'success' : function(data,xhr) { 841 callback({ 842 id : data.id, 843 text : data.accounting_code+'-'+data.customer_title 844 }); 845 }, 846 'error' : function(xhr) { 847 848 } 849 850 }); 851 } 852 }); 853 }; 854 $.subaccountsCustomerSelect = function(selector,placeholder) { 855 var placeholder = (typeof placeholder !== 'undefined' && placeholder.length > 0 ? placeholder : 'Select a customer'); 856 return $(selector).select2({ 857 'minimumResultsForSearch': 5, 858 'placeholder' : placeholder, 859 'allowClear' : true, 860 'ajax' : { 861 'url' : datatill.url('customers/ajax_subaccounts_customer_search'), 862 'dataType' : 'JSON', 863 'quietMillis' : 250, 864 'data' : function(term,page) { 865 return {
866 'id' : $('#id').val(), 867 'query' : term, 868 'page' : page 869 }; 870 }, 871 'results' : function(data, page) { 872 var more = (page * 30) < data.total_rows; 873 return { 874 results : data.items, 875 'text': function(item) { 876 return item.title; 877 }, 878 'more': more, 879 }; 880 }, 881 'cache' : true 882 }, 883 'initSelection' : function(el,callback) { 884 var id = $(el).val(); 885 $.ajax({ 886 'dataType' : 'JSON', 887 'data' : { 888 id : id 889 }, 890 'url' : datatill.url('customers/ajax_subaccounts_get'), 891 'quietMillis' : 250, 892 'success' : function(data,xhr) { 893 callback({ 894 id : data.id, 895 text : data.accounting_code+'-'+data.customer_title 896 }); 897 }, 898 'error' : function(xhr) { 899 900 } 901 902 }); 903 } 904 }); 905 }; 906 $.radiusSelect = function(selector,account_type,result_type,customer_id,parent_only,include_prepaid,include_expired,include_lte,include_mikrotik,placeholder,multiple) { 907 var placeholder = (typeof placeholder !== 'undefined' && placeholder.length > 0 ? placeholder : 'Select a data account'); 908 var result_type = (typeof result_type !== 'undefined' && result_type.length > 0 ? result_type : 'radius'); 909 var multiple = (typeof multiple !== 'undefined' && multiple > 0 ? true : false); 910 911// var parent_only = (typeof parent_only !== 'undefined' && parent_only.length > 0 ? parent_only : 0); 912 // var include_prepaid = (typeof include_prepaid !== 'undefined' && include_prepaid.length > 0 ? include_prepaid : 0); 913 return $(selector).select2({ 914 'minimumResultsForSearch': 5, 915 'placeholder' : placeholder, 916 'allowClear' : true, 917 'multiple': multiple, 918 'ajax' : { 919 'url' : datatill.url('radius/ajax_search'), 920 'dataType' : 'JSON', 921 'quietMillis' : 250, 922 'data' : function(term,page) { 923 return { 924 'query' : term, 925 'page' : page, 926 'account_type' : account_type, 927 'result_type' : result_type, 928 'parent_only' : parent_only, 929 'include_prepaid' : include_prepaid, 930 'include_expired' : include_expired, 931 'customer_id' : customer_id, 932 'include_lte' : (include_lte>0 ? 1 : 0), 933 'include_mikrotik' : (include_mikrotik>0 ? 1 : 0) 934 }; 935 }, 936 'results' : function(data, page) { 937 var more = (page * 30) < data.total_rows; 938 return { 939 results : data.items, 940 'text': function(item) { 941 return item.title; 942 }, 943 'more': more, 944 }; 945 }, 946 'cache' : true 947 }, 948 'initSelection' : function(el,callback) { 949 var id = $(el).val(); 950 951 $.ajax({ 952 'dataType' : 'JSON', 953 'data' : { 954 id : id 955 }, 956 'url' : datatill.url('radius/ajax_get'), 957 'quietMillis' : 250, 958 'success' : function(data,xhr) { 959 if (result_type == 'customer'){ 960 callback({ 961 id : data.id, 962 text : (data.alias>'' ? data.alias+ ' ('+data.username+')' : data.username)+' - '+data.customer_title 963 }); 964 } else { 965 callback({ 966 id : data.id, 967 text : (data.alias>'' ? data.alias+ ' ('+data.username+')' : data.username) 968 }); 969 } 970 }, 971 'error' : function(xhr) { 972 973 } 974 975 }); 976 } 977 }); 978 }; 979 $.customerPortaSelect = function(selector,placeholder,list,prepaid) { 980 var placeholder = (typeof placeholder !== 'undefined' && placeholder.length > 0 ? placeholder : 'Select a customer'); 981 var prepaid = (typeof prepaid !== 'undefined' && prepaid > 0 ? 1 : 0); 982 return $(selector).select2({ 983 'minimumResultsForSearch': 5, 984 'placeholder' : placeholder, 985 'allowClear' : true, 986 'ajax' : { 987 'url' : datatill.url('customers/ajax_porta_search'), 988 'dataType' : 'JSON', 989 'quietMillis' : 250, 990 'data' : function(term,page) { 991 return { 992 'query' : term, 993 'page' : page, 994 'prepaid' : (prepaid >0 ? 1 : 0), 995 996 }; 997 }, 998 'results' : function(data, page) { 999 var more = (page * 30) < data.total_rows; 1000 return { 1001 results : data.items, 1002 'text': function(item) { 1003 return item.title; 1004 }, 1005 'more': more, 1006 }; 1007 }, 1008 'cache' : true 1009 }, 1010 'initSelection' : function(el,callback) { 1011 var id = $(el).val(); 1012 1013 $.ajax({ 1014 'dataType' : 'JSON', 1015 'data' : { 1016 id : id 1017 }, 1018 'url' : datatill.url('customers/ajax_get'), 1019 'quietMillis' : 250, 1020 'success' : function(data,xhr) { 1021 callback({ 1022 id : data.id, 1023 text : data.accounting_code+'-'+data.customer_title 1024 }); 1025 }, 1026 'error' : function(xhr) { 1027 1028 } 1029 1030 }); 1031 } 1032 }); 1033 }; 1034 1035 1036 $.toDecimal = function(number,negative,decimals,debug){ 1037 1038 decimals= isNaN(decimals) ? 2 : decimals < 0 ? 2 : decimals; 1039 number=$.trim(number+''); 1040 number=number.replace(/\s/g,'').replace(/,/g,'.').replace(/(\.)([0-9]*)((\.)([0-9]*))/g,'$1$2').replace(/[^\-\.0-9]/,''); 1041 //if(!negative) number=number.replace('-',0); 1042 1043 if(number.indexOf('-')>0) number='0'; 1044 number=+number; 1045 var a = Math.pow(10,decimals),b = Math.pow(10,decimals+1),c=b/a; 1046 1047 return isNaN(number)? (+0).toFixed(decimals) : (Math.round(Math.round(number*b)/c)/a).toFixed(decimals); 1048 }; 1049 /** 1050 * Calls a bootbox modal for you to load your form into via JSON AJAX Request 1051 * Requires: data.title for header & data.message 1052 * @param {[object]} args 1053 * @param args.url Url to GET form and POST/PUT data 1054 * @param args.params Extra params for GET/PUT/POST besides form 1055 * @param args.successCallback Custom Callback for clicking the submit button. handling form etc 1056 * @param args.title An Optional Title for your modal 1057 * @param args.message A Custom Message for your modal 1058 * @usage var popup = new $.Crud({ url: datatill.url(), params: {} }).create() 1059 */ 1060 $.Crud = function(args){ 1061 1062 var args = $.extend({ 1063 url :'', 1064 params : {}, 1065 onHidden : null, 1066 successCallback : null, 1067 title : '', 1068 message : '' 1069 }
1069,args); 1070 1071 this.args = args; 1072 this.success = false; 1073 this.id = null; 1074 this.dialog = null; 1075 }; 1076 1077 $.Crud.prototype = { 1078 create : function(args){ 1079 var args = $.extend(true,{},{ 1080 buttons : 1081 { 1082 success : { 1083 label : 'Create', 1084 className : 'btn btn-success btn-save', 1085 } 1086 } 1087 },args); 1088 1089 1090 var form = this.fetchForm(args); 1091 }, 1092 read : function(args) { 1093 // Todo 1094 }, 1095 update : function(args){ 1096 var args = $.extend(true,{},{ 1097 buttons : 1098 { 1099 success : { 1100 label : 'Update', 1101 className : 'btn btn-success btn-save', 1102 } 1103 } 1104 },args); 1105 var form = this.fetchForm(args); 1106 }, 1107 delete : function(args) { 1108 var self = this; 1109 1110 var dialog = self.createDialog({ 1111 title : (!self.args.title.length ? 'Please confirm before proceeding.' : self.title), 1112 message : (!self.args.message.length ? 'Are you sure you want to delete this item ?' : self.message), 1113 buttons : { 1114 success : { 1115 label : 'Delete', 1116 className : 'btn btn-danger btn-save', 1117 callback : function(ev) { 1118 var form = $(ev.delegateTarget).find('.modal-content > .modal-body'); 1119 $.post(self.args.url,self.args.params,function(data){ 1120 if(typeof data.success !== 'undefined' && data.success > 0) { 1121 self.showSuccess(form,'Item successfully deleted'); 1122 self.success = data.success; 1123 self.id = data.success; 1124 return true; 1125 } else { 1126 self.success = false; 1127 bootbox.alert('An Error has occured trying to delete this item'); 1128 } 1129 }); 1130 return false; 1131 } 1132 }, 1133 danger : { 1134 label : 'Cancel', 1135 className : 'btn btn-primary pull-left', 1136 callback : function(ev) { 1137 return true; 1138 } 1139 } 1140 } 1141 }); 1142 }, 1143 fetchForm : function(args) { 1144 var self = this; 1145 if(typeof self.args.message !== 'undefined' && self.args.message.length) { 1146 var args = $.extend({ 1147 title : (typeof self.args.title !== 'undefined' && self.args.title.length > 0 ? self.args.title : data.title ), 1148 message : self.args.message 1149 },args); 1150 return self.createDialog(args); 1151 } 1152 var xhr = $.ajax({ 1153 url : self.args.url, 1154 data : self.args.params, 1155 method : 'GET', 1156 contentType : 'JSON', 1157 success : function(data,xhr) { 1158 self.createDialog({ 1159 title : (typeof self.args.title !== 'undefined' && self.args.title.length > 0 ? self.args.title : data.title ), 1160 message : data.message || '', 1161 buttons : args.buttons 1162 }); 1163 } 1164 }); 1165 }, 1166 postForm : function(form){ 1167 $('.btn-save').button('loading'); 1168 var self = this; 1169 var data = form.serializeArray(); 1170 if(typeof self.args.params !== 'undefined' && self.args.params !== null) { 1171 data.push(self.args.params); 1172 } 1173 var xhr = $.ajax({ 1174 url : self.args.url, 1175 data : data, 1176 method : 'POST', 1177 dataType : 'JSON', 1178 success : function(data,xhr) { 1179 $('.btn-save').button('reset'); 1180 if($.isPlainObject(data.errors) && !$.isEmptyObject(data.errors)) { 1181 self.showErrors(form,data.errors); 1182 self.success = false;
1183 } else if(data.success > 0) { 1184 // TODO showSuccess 1185 self.hideErrors(form); 1186 var msg = (typeof data.message !== 'undefined' && data.message !== null ? data.message : 'Your action was successfull'); 1187 self.showSuccess(form,msg); 1188 self.success = data.success; 1189 self.id = data.success; 1190 } 1191 }, 1192 error : function(xhr) { 1193 $('.btn-save').button('reset'); 1194 bootbox.alert('A problem has occured with your request, Please try again later.',function(resp){ 1195 bootbox.hideAll(); 1196 }); 1197 } 1198 }); 1199 }, 1200 createDialog : function(args) { 1201 var self = this; 1202 1203 var args = $.extend(true,{},{ 1204 title : '', 1205 message : '', 1206 buttons : { 1207 success : { 1208 label : 'Save', 1209 className : 'btn btn-success btn-save', 1210 callback : function(ev){ 1211 var form = $(ev.delegateTarget).find('form'); 1212 if(form.length > 0) { 1213 self.hideErrors(form); 1214 self.postForm(form); 1215 } 1216 return false; 1217 } 1218 }, 1219 danger : { 1220 label : 'Close', 1221 className : 'btn btn-danger pull-left', 1222 callback : function(ev) { 1223 return true; 1224 } 1225 } 1226 } 1227 },args); 1228 1229 // https://github.com/select2/select2/issues/1436 1230 $.fn.modal.Constructor.prototype.enforceFocus = function() {}; 1231 // Fetch our Dialog for display 1232 var dialog = bootbox.dialog(args); 1233 dialog.on('hidden.bs.modal',function(e){ 1234 // Remove all old select2 dom content 1235 $(e.currentTarget).find('.select-2').select2('destroy'); 1236 if(e.target == this) { 1237 1238 if($.isFunction(self.args.onHidden) && self.args.onHidden !== null) { 1239 return self.args.onHidden(e,self); 1240 } 1241 } 1242 }); 1243 // Anything we should do once hidden ? 1244 }, 1245 showSuccess : function(form,msg) { 1246 if (typeof do_background_tickets == 'function') { do_background_tickets();} 1247// var alert = ['<div class="alert fade in alert-success form-success">',msg,' <br/>This Screen will automatically close in <b class="timer">3</b> seconds.</div>'].join(''); 1248 this.success = true; 1249 form.closest('.modal').modal('hide'); // IRIRIR 1250/* 1251 form.prepend(alert); 1252 var timeout = 2000; 1253 var timer = setInterval(function(){ 1254 form.find('.alert.form-success > .timer').text((timeout/1000)); 1255 timeout = timeout-1000; 1256 if(timeout<0) { 1257 clearInterval(timer); 1258 timer=null; 1259 form.closest('.modal').modal('hide'); 1260 return false; 1261 } 1262 },1000); 1263*/ 1264 1265 }, 1266 showErrors : function(form,errors) { 1267 var rows = [],formErrors=form.find('.alert-danger.form-errors'); 1268 $.each(errors,function(i,val){ 1269 rows.push('<li>'+val+'</li>'); 1270 }); 1271 formErrors.find('ul').html(rows.join('')); 1272 formErrors.show(330); 1273 this.success = false; 1274 return false; 1275 }, 1276 hideErrors : function(form) { 1277 var formErrors = form.find('.alert-danger.form-errors'); 1278 formErrors.hide(330).find('ul').html(''); 1279 this.success = true; 1280 return true; 1281 } 1282 }; 1283 window.datatill = $.extend(window.datatill || {},{ 1284 init:function(){ 1285 $('body').off('click.datatillInit'); 1286 $('body').on('click.datatillInit','[data-dismiss=popup-destroy]',function(e){ 1287 e.preventDefault(); 1288 var popup=$(this).closest('.popup'),api=popup.data('popup'); 1289 if(api)api.destroy=true; 1290 popup.popup('hide'); 1291 }); 1292 $('body').on('click.datatillInit','[data-dismiss=popup]',function(e){ 1293 e.preventDefault(); 1294 $(this).closest('.popup').popup('hide'); 1295 }); 1296 $('body').on('click.datatillInit','[data-toggle=popup-fullscreen]',function(e){ 1297 e.preventDefault(); 1298 var popup=$(this).closest('.popup'); 1299 popup.toggleClass('fullscreen'); 1300 $(window).resize(); 1301 }); 1302 } 1303 }); 1304})(jQuery); 1305 1306 1307if (typeof(bootbox) != "undefined") { 1308 bootbox.setDefaults({ 1309 show: true, 1310 backdrop: true, 1311 closeButton: true, 1312 animate: false, 1313 className: "my-modal" 1314 }); 1315} 1316 1317 1318if (typeof($.fn.dataTable) != "undefined") { 1319 if (typeof($.fn.dataTable.defaults) != "undefined") { 1320 $.extend($.fn.dataTable.defaults, {
1321 "fnInitComplete": function(oSettings, json) { 1322 $(".dataTables_length select").select2({ 1323 minimumResultsForSearch: -1, 1324 dropdownAutoWidth : true 1325 }); 1326 }, 1327 }); 1328 } 1329 if (typeof($.fn.dataTableExt.oApi) != "undefined") { 1330 $.extend($.fn.dataTableExt.oApi, { 1331 "fnMultiFilter": function(oSettings, oData) { 1332 for ( var key in oData ) 1333 { 1334 if ( oData.hasOwnProperty(key) ) 1335 { 1336 for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ ) 1337 { 1338 if( oSettings.aoColumns[i].idx == key ) 1339 { 1340 oSettings.aoPreSearchCols[ i ].sSearch = oData[key]; 1341 break; 1342 } 1343 } 1344 } 1345 } 1346 this.oApi._fnReDraw( oSettings ); 1347 }, 1348 }); 1349 } 1350} 1351 1352function initialize_gallery(){ 1353 $('a.DTgallery').featherlightGallery({ 1354 previousIcon: '◀', /* Code that is used as previous icon */ 1355 nextIcon: '▶', /* Code that is used as next icon */ 1356 galleryFadeIn: 100, /* fadeIn speed when slide is loaded */ 1357 galleryFadeOut: 300 /* fadeOut speed before slide is loaded */ 1358 }); 1359} 1360 1361function b64Encode(str) { 1362 if (typeof str != 'string') throw new TypeError('Passed parameter is not a string'); 1363 const output = str.replace( 1364 /[\u0080-\u07ff]/g, // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz 1365 function(c) { 1366 var cc = c.charCodeAt(0); 1367 return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); } 1368 ).replace( 1369 /[\u0800-\uffff]/g, // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz 1370 function(c) { 1371 var cc = c.charCodeAt(0); 1372 return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); } 1373 ); 1374 return btoa(output); 1375} 1376 1377function b64Decode(str) { 1378 if (typeof str != 'string') throw new TypeError('Passed parameter is not a string'); 1379 var base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; 1380 if (base64regex.test(str)) { str = atob(str); } // only does a decode if the string is a valid Base64 encoded 1381 // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char! 1382 const output = str.replace( 1383 /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, // 3-byte chars 1384 function(c) { // (note parentheses for precedence) 1385 var cc = ((c.charCodeAt(0)&0x0f)<<12) | ((c.charCodeAt(1)&0x3f)<<6) | ( c.charCodeAt(2)&0x3f); 1386 return String.fromCharCode(cc); } 1387 ).replace( 1388 /[\u00c0-\u00df][\u0080-\u00bf]/g, // 2-byte chars 1389 function(c) { // (note parentheses for precedence) 1390 var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f; 1391 return String.fromCharCode(cc); } 1392 ); 1393 return output; 1394} 1395 1396var file_uploads_in_progress = [] ; 1397function get_new_upload_id(){ 1398 var upload_id = Math.random(); 1399 return upload_id; 1400} 1401 1402function begin_upload(upload_id) { 1403 1404 var upload = { 1405 id : upload_id, 1406 complete : false 1407 }; 1408 file_uploads_in_progress.push(upload); 1409 return upload_id; 1410} 1411 1412function complete_upload(upload_id) { 1413 var len = file_uploads_in_progress.length; 1414 for (var i=0; i<len;i++){ 1415 if (file_uploads_in_progress[i].id == upload_id){ 1416 file_uploads_in_progress[i].complete = true; 1417 break; 1418 } 1419 } 1420} 1421 1422function uploads_complete(){ 1423 var len = file_uploads_in_progress.length; 1424 for (var i=0; i<len;i++){ 1425 if (file_uploads_in_progress[i].complete == false){ 1426 return false; 1427 } 1428 } 1429 return true; 1430} 1431 1432 1433// MAR-19 1434function check_refer_a_friend_item(message, selector){ 1435 $(selector).hide(); 1436 var theOption = []; 1437 $('#table_lines tr').each(function(i){ 1438 if( $(this).css('display') !== 'none') { 1439 var id_split = $(this).attr('id').split('_'); 1440 theOption.push($('#item_type_' + id_split[1] + ' option:selected').val()); 1441 } 1442 }); 1443 if ( theOption.indexOf('BANDWIDTH') == -1 ) { 1444 $(selector).html(message).show(); 1445 return; 1446 } 1447 return 1; 1448} 1449 1450function generate_label(label_list_color,label_list_name){ 1451 return "<button type='button' class='label label-default nopointevent' style='border-color:"+label_list_color+"; margin-bottom:2px; border-left: 15px solid "+label_list_color+"; '>"+label_list_name+"</button> "; 1452} 1453 1454// Format a number with thousand markers and fixed decimals 1455function formatNumber(number, dec_f, dec_m, thou_m) { 1456 var dec_f = isNaN(dec_f = Math.abs(dec_f)) ? 2 : dec_f, 1457 dec_m = dec_m == undefined ? "." : dec_m, 1458 thou_m = thou_m == undefined ? "," : thou_m, 1459 neg = number < 0 ? "-" : "", 1460 actual = String(parseInt(number = Math.abs(Number(number) || 0).toFixed(dec_f))), 1461 split = (split = actual.length) > 3 ? split % 3 : 0; 1462 1463 return neg + (split ? actual.substr(0, split) + thou_m : "") + 1464 actual.substr(split).replace(/(\d{3})(?=\d)/g, "$1" + thou_m) + 1465 (dec_f ? dec_m + Math.abs(number - actual).toFixed(dec_f).slice(2) : ""); 1466}; 1467 1468// Pass a decimal representation to have it converted to D:HH:MM:SS 1469function convertNumberToTimeDHMS(value) { 1470 var days = Math.floor(value/1440); 1471 var sub_days = Boolean(days) ? value - (1440*days) : value; 1472 var show_hours = Boolean(days) ? 1 : 0; 1473 var hours = Math.floor(sub_days/60); 1474 var hour_ = (String(hours).length == 1) ? '0'+hours : hours; 1475 var sub_hour = Boolean(hours) ? sub_days - (60*hours) : sub_days; 1476 var minutes = Math.floor(sub_hour); 1477 var seconds = Math.round((sub_hour % 1)*100)/100; 1478 var min = ((String(minutes).length == 1) ? '0'+minutes : minutes) 1479 var sec_ = parseInt(seconds*60); 1480 var sec = (String(sec_).length == 1) ? '0'+sec_ : sec_; 1481 return ((Boolean(days)) ? days + ':' : '' ) + ((Boolean(hours) || Boolean(show_hours)) ? hour_ + ':' : '' ) + min + ':' + sec; 1482} 1483 1484// Pass a decimal representation to have it converted to MM:SS 1485function convertNumberToTimeMS(value) { 1486 var minutes = Math.floor(value / 60); 1487 var seconds = Math.round((value % 60) * 100) / 100; 1488 var min = ((String(minutes).length === 1) ? '0' + minutes : minutes); 1489 var sec_ = parseInt(seconds); 1490 var sec = (String(sec_).length == 1) ? '0' + sec_ : sec_; 1491 return min + ':' + sec; 1492} 1493 1494/** 1495 * `DTSUPPORT ONLY` will be sections in the system 1496 * that allow only the namesake user additional functionality; 1497 * debugging, insights, raw data, testing ... 1498 */ 1499function dtsupportInsertMarker() { 1500 $(".dtsupport_only").each(function(){ 1501 $(this).before("<hr>
1501").prepend($('<div>').text("DTSUPPORT ONLY")); 1502 }); 1503} 1504 1505var customjs_version=15;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.