1/** 2 * COMMON JAVASCRIPT 3 * Behaviour as expected 4 */ 5function _msg(key, alt, replacements) { 6 let string = ''; 7 string = 8 (typeof msg == 'undefined' || typeof msg[key] == 'undefined') 9 ? string = alt 10 : msg[key]; 11 12 if (!replacements) return string; 13 14 if ('object' === typeof replacements && !Array.isArray(replacements)) { 15 Object.keys(replacements).forEach(key => { 16 string = string.replaceAll(key, replacements[key]); 17 }); 18 } 19 20 return string; 21} 22 23function numberPadLeft(number, n, str) { 24 return Array(n - String(number).length + 1).join(str || '0') + number; 25} 26 27const PRISTINE_JS = { 28 BASIC_CONFIG: { 29 classTo: 'input-group', // class of the parent element where the error/success class is added 30 errorClass: 'input-group__input--error', 31 successClass: 'has-success', 32 errorTextParent: 'input-group', // class of the parent element where error text element is appended 33 errorTextTag: 'p', // type of element to create for the error text 34 errorTextClass: 'input-group__validation input-group__input--error' // class of the error text element 35 }, 36 CUSTOM_VALIDATORS: { 37 valid_url : (value, element) => { 38 // only for non required elements 39 if (!value) { 40 return true; 41 } 42 43 const urlPattern = new RegExp('^((ft|htt)ps?:\\/\\/)?'+ // protocol 44 '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name and extension 45 '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address 46 '(\\:\\d+)?'+ // port 47 '(\\/[-a-z\\d%@_.~+&:]*)*'+ // path 48 '(\\?[;&a-z\\d%@_.,~+&:=-]*)?'+ // query string 49 '(\\#[-a-z\\d_]*)?$','i'); // fragment locator 50 51 return urlPattern.test(value.trim()); 52 53 } 54 55 } 56} 57 58 59/** 60 get url param 61 optional url 62 example getAllUrlParams().eventId will return data or undefined if not found 63*/ 64function getAllUrlParams(url) { 65 // get query string from url (optional) or window 66 var queryString = url ? url.split("?")[1] : window.location.search.slice(1); 67 68 // we'll store the parameters here 69 var obj = {}; 70 71 // if query string exists 72 if (queryString) { 73 // stuff after # is not part of query string, so get rid of it 74 queryString = queryString.split("#")[0]; 75 76 // split our query string into its component parts 77 var arr = queryString.split("&"); 78 79 for (var i = 0; i < arr.length; i++) { 80 // separate the keys and the values 81 var a = arr[i].split("="); 82 83 // set parameter name and value (use 'true' if empty) 84 var paramName = a[0]; 85 var paramValue = typeof a[1] === "undefined" ? true : a[1]; 86 87 // (optional) keep case consistent 88 paramName = paramName.toLowerCase(); 89 if (typeof paramValue === "string") paramValue = paramValue.toLowerCase(); 90 91 // if the paramName ends with square brackets, e.g. colors[] or colors[2] 92 if (paramName.match(/\[(\d+)?\]$/)) { 93 // create key if it doesn't exist 94 var key = paramName.replace(/\[(\d+)?\]/, ""); 95 if (!obj[key]) obj[key] = []; 96 97 // if it's an indexed array e.g. colors[2] 98 if (paramName.match(/\[\d+\]$/)) { 99 // get the index value and add the entry at the appropriate position 100 var index = /\[(\d+)\]/.exec(paramName)[1]; 101 obj[key][index] = paramValue; 102 } else { 103 // otherwise add the value to the end of the array 104 obj[key].push(paramValue); 105 } 106 } else { 107 // we're dealing with a string 108 if (!obj[paramName]) { 109 // if it doesn't exist, create property 110 obj[paramName] = paramValue; 111 } else if (obj[paramName] && typeof obj[paramName] === "string") { 112 // if property does exist and it's a string, convert it to an array 113 obj[paramName] = [obj[paramName]]; 114 obj[paramName].push(paramValue); 115 } else { 116 // otherwise add the property 117 obj[paramName].push(paramValue); 118 } 119 } 120 } 121 } 122 123 return obj; 124} 125 126/** 127 * Method to remove params from current URL and updates navigator bar 128 * 129 * @param {array | string } params Params to be removed from URL 130 * @param {boolean} removeAllParams remove all parameters in url 131 */ 132function removeUrlParams(params = [], removeAllParams = false) { 133 134 const url = new URL(window.location.href); 135 const currentParams = new URLSearchParams(url.searchParams.toString()); 136 137 // lets remove all params 138 if (removeAllParams) { 139 const newUrl = url.origin + url.pathname; 140 history.replaceState('', '', newUrl); 141 return; 142 } 143 // if no params or empty array 144 if (!params || !params.length) { 145 return; 146 } 147 148 // manages a string 149 if (typeof(params) === 'string') {
150 currentParams.delete(params); 151 } 152 153 // manages an array 154 if (Array.isArray(params)) { 155 params.forEach(param => { 156 currentParams.delete(param); 157 }); 158 } 159 160 // update current URL in navigator 161 const newParams = Array.from(currentParams).length ? '?' + currentParams.toString() : ''; 162 const newUrl = url.origin + url.pathname + newParams; 163 history.replaceState('', '', newUrl); 164 165} 166 167/** 168 * Set default width to 100% to ckeditor table 169 * @param CKEDITOR 170 */ 171function setDefaultCkEditorTableWidth(CKEDITOR) { 172 CKEDITOR.on('dialogDefinition', function( ev ) { 173 174 const diagName = ev.data.name; 175 const diagDefn = ev.data.definition; 176 177 if(diagName === 'table') { 178 const infoTab = diagDefn.getContents('info'); 179 180 const width = infoTab.get('txtWidth'); 181 width['default'] = "100%"; 182 } 183 }); 184} 185 186// method to check if url has param to call google analytics 187function ga_analytics_from_component(eventTracker, data = null) { 188 189 console.log("llego", eventTracker, data); 190 if (data && eventTracker) { 191 SYM.TRACKER.trackEventObj(eventTracker, data); 192 } 193 194 } 195 196var JSON = JSON || {}; // make JSON object available if no native support 197 198var SYM = window.SYM || {}; // initialize namespace: SYM 199 200SYM = $.extend(SYM, function() { // declare namespace SYM 201 202 var ajax_load = false; 203 var ajax_load_offset = -6; 204 205 const plupload_input_file_default_selector = '.input_file'; 206 const plupload_pick_file_default_selector = '.btn_pickfiles'; 207 const plupload_default_options = { 208 runtimes : 'html5,flash,silverlight,html4,gears,browserplus', 209 browse_button : 'pickfiles', 210 container : 'container', 211 max_file_size : '100mb', 212 chunk_size: '2mb', 213 url : '/file_manager/plupload_receiver', 214 flash_swf_url : '/js/plupload/js/plupload.flash.swf', 215 silverlight_xap_url : '/js/plupload/js/plupload.silverlight.xap' 216 }; 217 218 return { 219 220 uploader: null, // plupload 221 uploader_autostart: true, // plupload 222 uploader_id: null, // plupload 223 224 uploader_alt: null, 225 uploader_alt_autostart: true, 226 uploader_alt_id: null, 227 228 uploader_multi: null, 229 uploader_multi_autostart: true, 230 uploader_multi_id: null, 231 232 timer_session: null, // keep the session alive 233 debugc: (typeof _IS_LOCAL !== 'undefined' && _IS_LOCAL) ? true : false, //enable or disable debugging 234 235 // AJAX progress bar 236 bind_ajax_progress_bar: function() { 237 if (typeof SYMJS != 'undefined' && typeof SYMJS.blocks_init != 'undefined') return; 238 if($('#template').hasClass('emagister')) { 239 ajax_load_offset = 0; 240 } 241 $(document).ajaxSend(function() { 242 if(!$('#ajax_load').length) { 243 $('<div></div>').attr('id', 'ajax_load').append( 244 $('<img>').attr('src', '/imgs/common/ajax_load.gif') 245 ).appendTo($('body').css('cursor', 'progress')).animate({ 246 top: ajax_load_offset 247 }, 900); 248 } 249 ajax_load = $('#ajax_load'); 250 //Hide element at 10 seconds without ajax response 251 setTimeout(function() { 252 if(ajax_load.length) { 253 $('body').trigger('ajaxStop'); 254 } 255 }, 10000); 256 }).ajaxStop(function() { 257 setTimeout(function() { 258 $('body').css('cursor', 'default'); 259 if(ajax_load.length) { 260 ajax_load.animate({ 261 top: -40 262 }, 700, function() { 263 ajax_load.remove(); 264 }); 265 } 266 }, 900); 267 }); 268 }, 269 270 // do not show progress bar while async requesting 271 unbind_ajax_progress_bar: function() { 272 $('body').unbind('ajaxSend ajaxStop'); 273 }, 274 275 // maintain session alive #WATCHDOG DEPRECATED? 276 keep_session: function() { 277 if (_IS_LOGGED) { 278 clearInterval(this.timer_session); 279 this.timer_session = setInterval(function() { 280 SYM.unbind_ajax_progress_bar(); 281 $.get(noCache('/login/renew_session'), function() { 282 SYM.bind_ajax_progress_bar(); 283 }); 284 }, 1800000); // 30 min. 285 } 286 }, 287 288 // go to proper partner login page 289 go_to_partner_login: function(partner_code, encoded_redirect) { 290 switch (partner_code) { 291 case 'um': case 'ull': 292 case 'demoupf': case 'upf': 293 case 'demoupc': case 'upc': case 'upc-pruebas' : 294 window.open(_SERVERURI + 'login/cas_' + partner_code + '/login?uri=' + _SERVERURI); 295 break; 296 case 'unizar': case 'demo-unizar':
297 window.open(_SERVERURI + 'login/cas_' + partner_code + '/login'); 298 break; 299 case 'usal': case 'uma': 300 window.open(_SERVERURI + 'login/papipoa'); 301 break; 302 case 'demo-unex': 303 break; 304 case 'unex': case 'urjc': case 'urjc-verano': 305 window.open(_SERVERURI + 'login/ldap'); 306 break; 307 case 'madrimasd': 308 window.open(_SERVERURI + 'login/sym_sso/madrimasd/' + encoded_redirect); 309 break; 310 case 'demomadrimasd': 311 window.open(_SERVERURI + 'login/sym_sso/demomadrimasd/' + encoded_redirect); 312 break; 313 default: 314 msgbox_close('all'); 315 msgbox_infotop(msg.COMING_SOON); 316 } 317 }, 318 319 get_partner_login: function(partner_code) { 320 switch (partner_code) { 321 case 'um': case 'ull': 322 case 'unizar': case 'demo-unizar': 323 case 'demoupf': case 'upf': 324 case 'demoupc': case 'upc': case 'upc-pruebas' : 325 url = _SERVERURI + 'login/cas_' + partner_code + '/login?uri=' + _SERVERURI; 326 break; 327 case 'usal': case 'uma': 328 url = _SERVERURI + 'login/papipoa'; 329 break; 330 case 'demo-unex': 331 url = false; 332 break; 333 case 'unex': case 'urjc': case 'urjc-verano': 334 url = _SERVERURI + 'login/ldap'; 335 break; 336 case 'madrimasd': 337 url = _SERVERURI + 'login/sym_sso/madrimasd'; 338 break; 339 case 'demomadrimasd': 340 url = _SERVERURI + 'login/sym_sso/demomadrimasd'; 341 break; 342 default: 343 url = false; 344 } 345 return url; 346 }, 347 348 // fill integer with zeros on the left 349 zero_fill: function(number, width) { 350 width -= number.toString().length; 351 if(width > 0) { 352 return new Array(width + (/\./.test(number) ? 2 : 1)).join('0') + number; 353 } 354 return number; 355 }, 356 357 // NOTE: it requires script "http://www.google.com/recaptcha/api/js/recaptcha_ajax.js?1" in order to work! 358 create_captcha: function() { 359 Recaptcha.create(_CAPTCHA_KEY, 'captcha', 360 { 361 theme : 'white', 362 lang : _LANGUAGE 363 }); 364 }, 365 366 // automatically set tooltips if any 367 activate_tooltips: function(selector) { 368 if ($(selector+'img.tooltip_trigger').length) { // user 369 if (!$('#tooltip_div').length) { 370 //create tooltip div 371 $('<div></div>').attr('id', 'tooltip_div').appendTo($('body')); 372 } 373 //activate tooltip 374 $(selector+'img.tooltip_trigger').tooltip({ 375 tip: '#tooltip_div', 376 direction: 'down', 377 bounce: true, 378 position: 'bottom center', 379 onBeforeShow: function (event) { 380 // Transform # symbol into line breaks in tooltip texts 381 if ($(event.srcElement).hasClass('line-break-tooltip')) { 382 $('#tooltip_div').html($('#tooltip_div').html().replace(/#/g, '<br/>')); 383 } 384 } 385 }); 386 } else if ($('a.tooltip_trigger').length) { // event_detail 387 if (!$('#tooltip_div').length) { 388 //create tooltip div 389 $('<div></div>').attr('id', 'tooltip_div').appendTo($('body')); 390 } 391 //activate tooltip 392 $('a.tooltip_trigger').tooltip({ 393 tip: '#tooltip_div', 394 direction: 'down', 395 bounce: true, 396 position: 'bottom center' 397 }).dynamic({ 398 bottom: { 399 direction: 'down' 400 }, 401 top: { 402 direction: 'up' 403 } 404 }); 405 } 406 }, 407 408 /** 409 * Generate a plupload uploader 410 * 411 * Include the following scripts AFTER jquery 412 * - /js/plupload/js/plupload.browserplus.js 413 * - /js/plupload/js/plupload.full.js 414 * 415 * Copy the same HTML markup from one of the example uploaders like event_detail/upload 416 * 417 * You will get an extra INPUT called UPLOAD which will have the path to the uploaded file (obfuscated, see Utils Helper) 418 * It uses YAV validation to make this INPUT REQUIRED 419 * Use SYM.reset_plupload_input() to reset the input after a succesful post or any other case you may need to 420 */ 421 pluploader_init: function(properties, callback) { 422 423 const debug = false; 424 const file_selector = plupload_input_file_default_selector; 425 const pick_files_selector = plupload_pick_file_default_selector; 426 427 if (!$(file_selector).length) { 428 if ('function' === typeof callback) callback('No files found'); 429 return null; 430 } 431 432 if (SYM.uploader != null) { 433 try { 434 SYM.uploader.destroy(); 435 if (debug) console.log('uploader destroyed', SYM.uploader); 436 SYM.uploader = null;
437 if (debug) console.log('uploader should be null by now', SYM.uploader); 438 } catch (e) { 439 console.error(e); 440 if ('function' === typeof callback) callback(e); 441 } 442 if (debug) console.log('pluploader_init_multi destroyed'); 443 $(file_selector).off(); 444 if ($(pick_files_selector).length) { 445 $(pick_files_selector).each((i, o) => { 446 const clone = $(o).clone(); 447 $(o).replaceWith(clone); 448 }); 449 } 450 if (debug) console.log('input files and button pickfiles events unbinded', file_selector, pick_files_selector); 451 } 452 453 $(file_selector).focus(function(){ 454 $('#pickfiles').focus(); 455 }); 456 457 if(typeof properties.autostart != 'undefined') { 458 SYM.uploader_autostart = properties.autostart; 459 delete properties.autostart; 460 } 461 462 properties = $.extend({}, plupload_default_options, properties); 463 464 try { 465 SYM.uploader = new plupload.Uploader(properties); 466 SYM.uploader.init(); 467 } catch (err) { 468 console.error(err); 469 if ('function' === typeof callback) callback(err); 470 return; 471 } 472 473 SYM.uploader.bind('FilesAdded', function(up, files) { 474 // clean previous errors 475 SYM.reset_plupload_input(); 476 $('#filelist .error').remove(); 477 // Limit to 1 file, the last added 478 var file_ext = ''; 479 if (SYM.uploader.files.length > 1) { 480 // keep in the array just the last file 481 SYM.uploader.files.splice(0,1); 482 SYM.uploader.stop(); 483 } 484 $(file_selector).val(files[0].name + ' (' + plupload.formatSize(files[0].size)+ ') '); 485 // Catch the file extension. If there is none, file_ext will be null. If there is one, it will be on the position 1 of an array. 486 file_ext = files[0].name.match(/\.([\w\d]+)$/); 487 // Forbidden extensions 488 var extensions = ['', 'exe', 'com', 'pif', 'src', 'dot', 'vbs', 'php', 'sh']; 489 // Tweak the value of the variable for easier comparison 490 if (file_ext == null) { 491 file_ext = ''; 492 } else file_ext = file_ext[1]; 493 // If the extension is not found, upload 494 if (extensions.indexOf(file_ext) == -1) { 495 if(SYM.uploader_autostart) { 496 SYM.uploader.start(); 497 } 498 } else { 499 $('#filelist').append('<p class="error">'+msg['INVALID_EXTENSION']+'</p>'); 500 } 501 up.refresh();
501 // Reposition Flash/Silverlight 502 503 SYM.uploader.trigger('FilesQueued'); 504 }); 505 506 SYM.uploader.bind('UploadProgress', function(up, file) { 507 $("#bar").css("display", "block"); 508 $("#bar").css("width", file.percent + "%"); 509 $("#percent").html(file.percent + "%"); 510 }); 511 512 SYM.uploader.bind('Error', function(up, err) { 513 var code_to_msg = ''; 514 switch(err.code) { 515 case -600: 516 code_to_msg = 'FILE_TOO_BIG'; 517 break; 518 case -601: 519 code_to_msg = 'INVALID_EXTENSION'; 520 break; 521 default: 522 code_to_msg = 'UPLOAD_BASE_ERROR'; 523 break; 524 } 525 SYM.reset_plupload_input(); 526 $('#filelist .error').remove(); 527 $('#filelist').append('<p class="error">'+msg[code_to_msg]+'</p>'); 528 529 up.refresh(); // Reposition Flash/Silverlight 530 }); 531 532 SYM.uploader.bind('FileUploaded', function(up, file, response) { 533 var data = JSON.parse(response.response); 534 $('#upload').val(data.MSG).trigger('change'); 535 }); 536 537 if ('function' === typeof callback) callback(null, SYM.uploader); 538 }, 539 540 pluploader_init_alt: function(properties, callback) { 541 const debug = false; 542 543 let suffix = 544 'undefined' != typeof properties.alternative 545 ? properties.alternative 546 : 'alt'; 547 548 const file_selector = plupload_input_file_default_selector + '_' + suffix; 549 const pick_files_selector = '#pickfiles_' + suffix; 550 const uploader_identifier = 'uploader_' + suffix; 551 552 if(!$(file_selector).length){ 553 if ('function' === typeof callback) callback('No files found'); 554 return null; 555 } 556 557 if (!SYM.uploader_alt) { 558 SYM.uploader_alt = {}; 559 } 560 561 if (SYM.uploader_alt[uploader_identifier]) { 562 try { 563 SYM.uploader_alt[uploader_identifier].destroy(); 564 if (debug) console.log('uploader destroyed', SYM.uploader_alt[uploader_identifier]); 565 SYM.uploader_alt[uploader_identifier] = null; 566 if (debug) console.log('uploader should be null by now', SYM.uploader_alt[uploader_identifier]); 567 } catch (e) { 568 console.error(e); 569 if ('function' === typeof callback) callback(e); 570 } 571 if (debug) console.log('pluploader_init_multi destroyed'); 572 $(file_selector).off(); 573 if ($(pick_files_selector).length) { 574 $(pick_files_selector).each((i, o) => { 575 const clone = $(o).clone(); 576 $(o).replaceWith(clone); 577 }); 578 } 579 if (debug) console.log('input files and button pickfiles events unbinded', file_selector, pick_files_selector); 580 } 581 582 $(file_selector).focus(function(){ 583 $(pick_files_selector).focus(); 584 }); 585 586 if(typeof properties.autostart != 'undefined') { 587 SYM.uploader_alt_autostart = properties.autostart; 588 delete properties.autostart; 589 } 590 591 properties = $.extend({}, plupload_default_options, { 592 browse_button : 'pickfiles_'+suffix, 593 container : 'container_'+suffix, 594 }, properties); 595 596 try { 597 SYM.uploader_alt[uploader_identifier] = new plupload.Uploader(properties); 598 SYM.uploader_alt[uploader_identifier].init(); 599 } catch (err) { 600 console.error(err); 601 if ('function' === typeof callback) callback(err); 602 return; 603 } 604 605 SYM.uploader_alt[uploader_identifier].bind('FilesAdded', function(up, files) { 606 // clean previous errors 607 SYM.reset_plupload_alt_input({alternative: suffix}); 608 $('#filelist_'+suffix+' .error').remove(); 609 // Limit to 1 file, the last added 610 var file_ext = ''; 611 if (SYM.uploader_alt[uploader_identifier].files.length > 1) { 612 // keep in the array just the last file 613 SYM.uploader_alt[uploader_identifier].files.splice(0,1); 614 SYM.uploader_alt[uploader_identifier].stop(); 615 } 616 $(file_selector).val(files[0].name + ' (' + plupload.formatSize(files[0].size)+ ') '); 617 // Catch the file extension. If there is none, file_ext will be null. If there is one, it will be on the position 1 of an array. 618 file_ext = files[0].name.match(/\.([\w\d]+)$/); 619 // Forbidden extensions 620 var extensions = ['', 'exe', 'com', 'pif', 'src', 'dot', 'vbs', 'php', 'sh']; 621 // Tweak the value of the variable for easier comparison 622 if (file_ext == null) { 623 file_ext = ''; 624 } else file_ext = file_ext[1]; 625 // If the extension is not found, upload 626 if (extensions.indexOf(file_ext) == -1) { 627 if(SYM.uploader_alt_autostart) { 628 SYM.uploader_alt[uploader_identifier].start(); 629 } 630 } else { 631 $('#filelist_'+suffix).append('<p class="error">'+msg['INVALID_EXTENSION']+'</p>'); 632 } 633 up.refresh();
633 // Reposition Flash/Silverlight 634 635 SYM.uploader_alt[uploader_identifier].trigger('FilesQueued'); 636 }); 637 638 SYM.uploader_alt[uploader_identifier].bind('UploadProgress', function(up, file) { 639 $("#bar_"+suffix).css("display", "block"); 640 $("#bar_"+suffix).css("width", file.percent + "%"); 641 $("#percent_"+suffix).html(file.percent + "%"); 642 }); 643 644 SYM.uploader_alt[uploader_identifier].bind('Error', function(up, err) { 645 var code_to_msg = ''; 646 switch(err.code) { 647 case -600: 648 code_to_msg = 'FILE_TOO_BIG'; 649 break; 650 case -601: 651 code_to_msg = 'INVALID_EXTENSION'; 652 break; 653 default: 654 code_to_msg = 'UPLOAD_BASE_ERROR'; 655 break; 656 } 657 SYM.reset_plupload_alt_input({alternative: suffix}); 658 $('#filelist_'+suffix+' .error').remove(); 659 $('#filelist_'+suffix).append('<p class="error">'+msg[code_to_msg]+'</p>'); 660 661 up.refresh(); // Reposition Flash/Silverlight 662 }); 663 664 SYM.uploader_alt[uploader_identifier].bind('FileUploaded', function(up, file, response) { 665 var data = JSON.parse(response.response); 666 $('#filelist_' + suffix + ' .error').remove(); 667 if (data.STAT == 'OK') { 668 $('#upload_' + suffix).val(data.MSG); 669 $('#field_' + suffix + '_file').val(data.MSG); 670 } else { 671 $('#upload_' + suffix).val(''); 672 $('#field_' + suffix + '_file').val(''); 673 674 $("#bar_" + suffix).css('width', '0%'); 675 $("#percent_" + suffix).html(''); 676 $('#filelist_' + suffix).append('<p class="error">' + data.MSG + '</p>'); // plain English 677 } 678 }); 679 680 if ('function' === typeof callback) { 681 callback(null, SYM.uploader_alt[uploader_identifier]); 682 } 683 }, 684 685 pluploader_init_multi: function(properties, callback) { 686 const debug = false; 687 const file_selector = '.input_file'; 688 const pick_files_selector = plupload_pick_file_default_selector; 689 690 if (!$(file_selector).length) { 691 // Nothing to do. 692 return; 693 } 694 695 const first_uploader_id = $(file_selector).eq(0).data('field'); 696 if (debug) console.log('Initialize pluploader_init_multi = ', first_uploader_id); 697 698 if (SYM.uploader_multi != null) { 699 try { 700 SYM.uploader_multi.destroy(); 701 if (debug) console.log('uploader destroyed', SYM.uploader_multi); 702 SYM.uploader_multi = null; 703 if (debug) console.log('uploader should be null by now', SYM.uploader_multi); 704 } catch (e) { console.log(e); } 705 if (debug) console.log('pluploader_init_multi destroyed'); 706 $(file_selector).off(); 707 if ($(pick_files_selector).length) { 708 $(pick_files_selector).each((i, o) => { 709 const clone = $(o).clone(); 710 $(o).replaceWith(clone); 711 }); 712 } 713 if (debug) console.log('input files and button pickfiles events unbinded', file_selector, pick_files_selector); 714 } 715 716 // prepare buttons for picking up files 717 $(file_selector) 718 .off('focus') 719 .on('focus', function(){ 720 if (debug) console.log('Focus = ', $(this)); 721 $('#pickfiles_'+$(this).data('field')).focus(); 722 }); 723 724 $(pick_files_selector) 725 .off('mouseenter') 726 .on('mouseenter', function(){ 727 SYM.uploader_multi_id = $(this).data('field'); 728 if (debug) console.log('Set uploader = ' + SYM.uploader_multi_id); 729 }) 730 .off('click') 731 .on('click', function(ev){ 732 ev.preventDefault(); 733 ev.stopPropagation(); 734 735 const current_uploader_id = $(this).data('field'); 736 737 if(current_uploader_id != first_uploader_id){ 738 const first_pick_file_selector = '#pickfiles_' + first_uploader_id; 739 $(first_pick_file_selector)[0].click(); 740 if (debug) console.log('Click to (' + current_uploader_id + ') = ' + '#pickfiles_' + first_uploader_id + ' / ' + first_uploader_id); 741 return false; 742 } 743 744 return false; 745 }); 746 747 // IE Flash fix 748 if ($('.reg_form_table td.uploader').length) { 749 $('.reg_form_table td.uploader') 750 .off('hover') 751 .hover(function(){ 752 SYM.uploader_multi_id = $(this).find(pick_files_selector).attr('data-field'); 753 if (debug) console.log('Set uploader flashfix = ' + SYM.uploader_multi_id); 754 }); 755 } 756 757 // prepare uploader instance 758 properties = $.extend({}, plupload_default_options, { 759 browse_button : 'pickfiles_'+first_uploader_id, 760 container : 'container_'+first_uploader_id, 761 multi_selection: false 762 }, properties); 763 764 try { 765 SYM.uploader_multi = new plupload.Uploader(properties); 766 SYM.uploader_multi.init(); 767 } catch (e) { 768 console.error(e); 769 } 770 771 SYM.uploader_multi.bind('Error', function(up, err) { 772 var code_to_msg = ''; 773 switch(err.code) { 774 case -600: 775 code_to_msg = 'FILE_TOO_BIG'; 776 break; 777 case -601: 778 code_to_msg = 'INVALID_EXTENSION'; 779 break; 780 default: 781 code_to_msg = 'UPLOAD_BASE_ERROR'; 782 break; 783 } 784 $('#container_' + SYM.uploader_multi_id).find('.error').remove(); 785 $('#container_' + SYM.uploader_multi_id).append('<p class="error">'+msg[code_to_msg]+'</p>'); 786 787 up.refresh();
787 // Reposition Flash/Silverlight 788 }); 789 790 SYM.uploader_multi.bind('FilesAdded', function(up, files) { 791 // IE fails to set up 792 SYM.uploader_multi_id = SYM.uploader_multi_id || $(file_selector).eq(0).data('field'); 793 if (debug) console.log('FilesAdded to = ' + SYM.uploader_multi_id); 794 // reset previous error message 795 $('#container_' + SYM.uploader_multi_id).find('.error').remove(); 796 // keep this file 797 var last_file = files[files.length-1]; 798 last_file.field_id = SYM.uploader_multi_id; 799 // check for forbidden extensions 800 var extensions = ['', 'exe', 'com', 'pif', 'src', 'dot', 'vbs', 'php', 'sh']; 801 var file_ext = last_file.name.match(/\.([\w\d]+)$/); 802 if (file_ext == null) { 803 file_ext = ''; 804 } else { 805 file_ext = file_ext[1]; 806 } 807 if (extensions.indexOf(file_ext) == -1) { 808 // remove previous file (omitting last one) 809 var indexes_to_remove = []; 810 $.each(SYM.uploader_multi.files, function(i, file) { 811 if(last_file.id != file.id) { 812 if(file.field_id == SYM.uploader_multi_id) { 813 indexes_to_remove.push(i); 814 } 815 } 816 }); 817 $.each(indexes_to_remove, function(i, the_index) { 818 SYM.uploader_multi.files.splice(the_index, 1); 819 }); 820 $('#field_' + SYM.uploader_multi_id).val(last_file.name); 821 // reset progress bar and uploaded file for this new file 822 $('#container_' + SYM.uploader_multi_id).find('.bar').css('width','0%'); 823 $('#field_' + SYM.uploader_multi_id + '_file').val(''); 824 }else{ 825 $('#container_' + SYM.uploader_multi_id).append('<p class="error">'+msg['INVALID_EXTENSION']+'</p>'); 826 up.files.pop(); 827 } 828 829 up.refresh();
829 // Reposition Flash/Silverlight 830 831 SYM.uploader_multi.trigger('FilesQueued'); 832 }); 833 834 SYM.uploader_multi.bind('UploadProgress', function(up, file) { 835 if (debug) console.log('UploadProgress to = ' + '#container_' + file.field_id, up, file); 836 $('#container_' + file.field_id).find('.bar').css('width', file.percent + '%'); 837 }); 838 839 SYM.uploader_multi.bind('FileUploaded', function(up, file, response) { 840 // /_files/plupload/deobfuscateString(data.MSG) 841 var data = JSON.parse(response.response); 842 843 if (debug) console.log('FileUploaded to = ', up, file, response); 844 845 if(data.STAT == 'OK') { 846 $('#field_' + file.field_id + '_file').val(data.MSG); 847 } else { 848 $('#field_' + file.field_id).val(''); 849 $('#container_' + file.field_id).find('.bar').css('width','0%'); 850 $('#container_' + file.field_id).append('<p class="error">'+data.MSG+'</p>'); // plain English 851 } 852 }); 853 854 if (debug) console.log('Uploader queue must exist by now', SYM.uploader_multi._queue); 855 856 if (typeof callback == 'function') { 857 callback(null, SYM.uploader_multi); 858 } 859 }, 860 861 reset_plupload_input: function() { 862 $(plupload_input_file_default_selector).val(''); 863 $("#bar").css("width", "0%"); 864 $("#percent").html(""); 865 $('#upload').val(''); 866 }, 867 868 reset_plupload_alt_input: function(properties) { 869 let suffix = 870 'undefined' !== typeof properties.alternative 871 ? properties.alternative 872 : "alt"; 873 874 const file_selector = plupload_input_file_default_selector + '_' + suffix; 875 876 $(file_selector).val(''); 877 $("#bar_"+suffix).css("width", "0%"); 878 $("#percent_"+suffix).html(""); 879 $('#upload_'+suffix).val(''); 880 }, 881 882 multilang_warning_effects: function() { 883 if ($('#multilang_warning_overlay').length) { 884 var availableWidth = parseInt(($(window).width() - $('#user_content').width()) / 2)-45; 885 var maxWidth = $('#multilang_warning_overlay').width(); 886 var minWidth = 160; 887 while (maxWidth > availableWidth) maxWidth--; 888 if (maxWidth < minWidth) maxWidth = minWidth; 889 $('#multilang_warning_overlay').css('width', maxWidth+'px'); 890 891 var min = 10; 892 var war = $('#multilang_warning_overlay').height(); 893 var max = $('#right_column').height()-(war+min+20); 894 895 $(window).scroll(function(e){ 896 var scrollto = window.pageYOffset + min; 897 max = $('#right_column').height()-(war+min+20); // refresh max because right_column is mutable 898 if (scrollto > max) scrollto = max; 899 if (scrollto < min) scrollto = min; 900 $('#multilang_warning_overlay').animate({marginTop: scrollto+'px'}, {duration: 500, queue: false}); 901 }); 902 $('#multilang_overlay_close').click(function(){ 903 $(window).unbind('scroll'); // unbind 904 $('#multilang_warning_overlay').remove(); 905 }); 906 } 907 }, 908 909 // Enable multilang button "Copy Original Content" 910 i18n_reset: function(table){ 911 msgbox_confirm(msg.YOU_SURE, msg.LOOSE_TRANSLATION, function(result){ 912 if (result == true){ 913 var ref_id = 0; 914 var refresh_function = ''; 915 // delete translation 916 switch(table){ 917 case 'events.id.welcome_msg': 918 case 'events.id.sponsors': 919 case 'events.id.speakers': 920 case 'events.id.program': 921 case 'events.id.place_detail': 922 case 'events.id.title,description': 923 ref_id = $('#event_id').val(); 924 refresh_function = 'location.reload();'; 925 break; 926 case 'event_schedule_i18n': 927 ref_id = $('#dateid').val(); 928 refresh_function = 'create_agenda();$("button.cancel").click();'; 929 break; 930 case 'event_videos_i18n': 931 ref_id = $('#video_id').val(); 932 refresh_function = 'show_videos(1);$("#form_add_video li.edit_buttons button.cancel").click();'; 933 break; 934 case 'event_sponsors_i18n': 935 ref_id = $('#patro_id').val(); 936 refresh_function = 'reload_patros();$("#cancel_update_patro").click();'; 937 break; 938 case 'event_speakers_i18n': 939 ref_id = $('#speaker_id').val(); 940 refresh_function = 'reload_speakers();$("#cancel_update_speaker").click();'; 941 break; 942 case 'event_sections_i18n': 943 ref_id = section_id; 944 refresh_function = 'get_sections();cancel_edition();'; 945 break; 946 case 'event_news_i18n': 947 ref_id = SYM.I18N.new_id; 948 refresh_function = 'reload_news();'; 949 break; 950 case 'event_metadata_i18n': 951 ref_id = $('#eventid').val(); 952 refresh_function = 'location.reload();'; 953 break; 954 case 'event_dates_i18n': 955 ref_id = $('#date_id').val(); 956 refresh_function = 'get_dates(1);$(".button_wrapper button.cancel").click();'; 957 break; 958 case 'papers_categories_i18n': 959 ref_id = $('#inp_identifier').val(); 960 refresh_function = 'SYM.PAPERS_CATEGORIES.load_categories(1);$("#frm_papers_categories button.btn_cancel").click();'; 961 break; 962 case 'events.id.lopd_template': 963 ref_id = $('#event_id').val(); 964 refresh_function = 'SYM.EVENT_ATTENDING_CONFIG.load_lopd();'; 965 break; 966 } 967 if(ref_id){ 968 $.post(noCache('/user_events/reset_translation'), { 969 table: table, 970 lang_key: _LANGUAGE, 971 ref_id: ref_id 972 }, function(response){ 973 if(response.stat == 'OK'){ 974 // refresh contents 975 eval(refresh_function); 976 } 977 }); 978 } 979 } 980 }); 981 }, 982 983 check_dirty_form: function () { 984 if (typeof CKEDITOR != "undefined") { 985 var dirty = false;
986 $.each(CKEDITOR.instances, function(){dirty = (dirty || this.checkDirty())}); 987 } 988 if (($('#drtyfrm').length && $('#drtyfrm').val() == 'true') || dirty) { 989 return msg['DIRTY_FORM']; 990 } 991 return false; 992 }, 993 994 // Add this method on document ready in order to show a warning if any form input is dirty before unload 995 dirty_forms_warning_setup: function(parent) { 996 // console.log('setup'); 997 if (typeof parent == "undefined") { 998 parent = 'body'; 999 } 1000 1001 $(window).bind("beforeunload",function(event){ 1002 SYM.check_dirty_form(); 1003 }); 1004 1005 $('select, input', parent).change(function(){ 1006 // console.log('change'); 1007 if (!$('#drtyfrm').length) { 1008 $(parent).append('<input type="hidden" id="drtyfrm" value="true" />'); 1009 } 1010 }); 1011 1012 $('input, textarea', parent).keyup(function(){ 1013 // console.log('keyup'); 1014 if (!$('#drtyfrm').length) { 1015 $(parent).append('<input type="hidden" id="drtyfrm" value="true" />'); 1016 } 1017 }); 1018 1019 }, 1020 1021 // Manually mark a form as dirty 1022 dirty_forms_manual_marker: function(selector) { 1023 if (!$('#drtyfrm').length) { 1024 $(selector).append('<input type="hidden" id="drtyfrm" value="true" />'); 1025 } 1026 }, 1027 1028 // Add this method on every form callback to clean the previously set flag 1029 dirty_forms_cleanup: function() { 1030 $('#drtyfrm').remove(); 1031 if (typeof CKEDITOR != "undefined") { 1032 $.each(CKEDITOR.instances, function(){this.resetDirty()}); 1033 } 1034 }, 1035 1036 /** 1037 * Formats a JavaScript Date object into a string to use with our datepicker 1038 * @param {JavaScript.Date} date The date object to be processed 1039 * @param {string} dateformat The format of the date string, for example: yyyy-MM-dd or MM/dd/yyyy-MM-dd 1040 * @return {string} The string to use as the value of the input, for example: 2013-10-18 1041 */ 1042 format_date: function(date, dateformat) { 1043 if (typeof dateformat == 'undefined') { 1044 dateformat = (typeof msg.yavdateformat != 'undefined')?msg.yavdateformat:''; 1045 } 1046 1047 dateformat = dateformat.replace('dd', ('00'+date.getDate()).slice(-2)); 1048 dateformat = dateformat.replace('MM', ('00'+(date.getMonth()+1)).slice(-2)); 1049 dateformat = dateformat.replace('yyyy', date.getFullYear()); 1050 dateformat = dateformat.replace('HH', ('00'+date.getHours()).slice(-2)); 1051 dateformat = dateformat.replace('ii', ('00'+date.getMinutes()).slice(-2));
1052 dateformat = dateformat.replace('ss', ('00'+date.getSeconds()).slice(-2)); 1053 1054 return dateformat; 1055 }, 1056 1057 /** 1058 * Builds a JavaScript Date object parsing a string 1059 * @param {string} date The date to be parsed 1060 * @param {string} dateformat A template to parse the date, for example: yyyy-MM-dd HH:ii:ss 1061 * @param {string} gmt The timezone the date is at, only numeric. For example: +0000 (GMT+0) or +0200 (GMT+2) 1062 * @return {JavaScript.Date} The date object translated to the browser timezone 1063 */ 1064 build_date: function(date, dateformat, gmt) { 1065 if (typeof dateformat == 'undefined') { 1066 dateformat = (typeof msg.yavdateformat != 'undefined')?msg.yavdateformat:''; 1067 } 1068 1069 if (date == null || date.length == 0) return new Date(0); 1070 1071 var seconds, minutes, hours, day, month, year; 1072 day = date.substr(dateformat.indexOf('dd'),2); 1073 month = date.substr(dateformat.indexOf('MM'),2); 1074 year = date.substr(dateformat.indexOf('yyyy'),4); 1075 1076 if (dateformat.indexOf('H')>=0) { 1077 hours = date.substr(dateformat.indexOf('HH'),2); 1078 } else hours = 0; 1079 if (dateformat.indexOf('i')>=0) { 1080 minutes = date.substr(dateformat.indexOf('ii'),2); 1081 } else minutes = 0; 1082 if (dateformat.indexOf('s')>=0) { 1083 seconds = date.substr(dateformat.indexOf('ss'),2); 1084 } else seconds = 0; 1085 1086 month = month-1; 1087 if (month < 10) month = '0'+month; 1088 1089 if (typeof gmt == 'undefined') { 1090 gmt = '+0000'; 1091 } 1092 var new_date = new Date(year, month, day, hours, minutes, seconds), 1093 date_str = new_date.toDateString()+' '+new_date.toTimeString().substr(0,8); 1094 return new Date(date_str+' '+gmt); 1095 }, 1096 1097 download_file: function(url, filename) { 1098 if (typeof filename == 'undefined') { 1099 filename = url.substr(url.lastIndexOf('/')+1); 1100 } 1101 var anchor = document.createElement('a'); 1102 anchor.setAttribute('href', url); 1103 anchor.setAttribute('download', filename); 1104 1105 var ev = document.createEvent("MouseEvents"); 1106 ev.initMouseEvent("click", true, false, self, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 1107 anchor.dispatchEvent(ev); 1108 }, 1109 1110 compare_timezone_offsets: function() { 1111 if (typeof _TZ_OFFSET != 'undefined' && _TZ_OFFSET != -1) { 1112 var d = new Date(); 1113 return (_TZ_OFFSET != (d.getTimezoneOffset()*60)); 1114 } 1115 return false; 1116 }, 1117 1118 printpdf_task: function(local_url, local_params, print_folder, print_file, success, failure) { 1119 var request_params = local_params || {}; 1120 $.post(noCache(local_url), request_params, 1121 function(response) { 1122 if (response.stat == 'OK') { 1123 var request_folder = print_folder || response.path; 1124 var request_file = print_file || response.filename; 1125 /* var remainingIntervalRetries = 15; */ 1126 var retryTimeout = 2000; 1127 var interval = setInterval(function(){ 1128 console.log({file_path:request_folder+request_file}); 1129 $.post(noCache('/user_events/pdfprinter_file_status'), 1130 { 1131 file_path:request_folder+request_file 1132 }, 1133 function(response){ 1134 console.log(response); 1135 if (response.status) { 1136 clearInterval(interval); 1137 SYM.download_file('/user_events/pdfprinter_file_download/'+request_folder.replace(/\//g,'@')+request_file, request_file); 1138 if (typeof success == 'function') success(); 1139 } 1140 } 1141 ); 1142 /* // Stop the retries on timeout. 1143 if (--remainingIntervalRetries <= 0) { 1144 clearInterval(interval); 1145 msgbox_alert(_msg('SERVER_ERROR', 'Error en el servidor')); 1146 } */ 1147 }, retryTimeout); 1148 } else { 1149 if (typeof failure == 'function') failure(); 1150 } 1151 } 1152 ); 1153 }, 1154 1155 remove_errors: function(){ 1156 $('p.error').remove(); 1157 }, 1158 1159 add_errors: function(msg, dom_element){ 1160 $('<p></p>').addClass('error').text(msg).insertAfter(dom_element); 1161 }, 1162 1163 validateEmail(email) { 1164 var re = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; 1165 return re.test(String(email).toLowerCase()); 1166 }, 1167 1168 validateURL(url) { 1169 var re = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/i; 1170 return re.test(url); 1171 }, 1172 1173 fetchFile(url, data, filename, onError, onSuccess) { 1174 const p = Object.assign({}, data); 1175 const formData = new FormData(); 1176 const noCacheUrl = noCache(url); 1177 for (let i in p) { 1178 if (p.hasOwnProperty(i)) { 1179 formData.append(i, p[i]); 1180 } 1181 } 1182 const params = { 1183 method: 'POST', 1184 body: formData 1185 }; 1186 console.log('fetchFile', params, JSON.stringify(Object.fromEntries(formData))); 1187 fetch(noCacheUrl, params).then(function (response) { 1188 console.log('fetchFileResponse', response); 1189 if (response.ok) { 1190 // Check response type 1191 // if json, check controlled error response 1192 if (response.headers.get('Content-Type') == 'application/json') { 1193 response.json().then(json => { 1194 if (json.stat !== 'OK') { 1195 if (typeof onError == 'function') { 1196 onError(json.msg) 1197 } 1198 } 1199 }).catch(function (err) { 1200 console.error('Reading json error', err); 1201 // Check errors on request 1202 if (typeof onError == 'function') { 1203 onError(err.message); 1204 } 1205 }); 1206 } else { 1207 // if blob, check file download 1208 response.blob().then((blob) => { 1209 const headerContentDisposition = response.headers.get('Content-Disposition'); 1210 const serverFilename = headerContentDisposition.match(/filename="(.+)"/)[1]; 1211 const theFilename = filename || serverFilename; 1212 SYM.onDownloadBlob(blob, theFilename); 1213 if (typeof onSuccess == 'function') { 1214 onSuccess(blob, theFilename); 1215 } 1216 }).catch(function (err) { 1217 console.error('Getting blob error', err); 1218 // Check errors on request 1219 if (typeof onError == 'function') { 1220 onError(err.message); 1221 } 1222 }); 1223 } 1224 } else { 1225 if (typeof onError == 'function') { 1226 onError(response.statusText); 1227 } 1228 } 1229 }).catch(function (err) { 1230 console.error('fetchFileError', err); 1231 // Check errors on request 1232 if (typeof onError == 'function') { 1233 onError(err.message); 1234 } 1235 }); 1236 }, 1237 1238 fetchFileGet(url, filename, onError, onSuccess) { 1239 const noCacheUrl = noCache(url); 1240 console.log('fetchFileGet', noCacheUrl); 1241 fetch(noCacheUrl).then(function (response) { 1242 console.log('fetchFileResponse', response); 1243 if (response.ok) { 1244 // Check response type 1245 // if json, check controlled error response 1246 if (response.headers.get('Content-Type') == 'application/json') { 1247 response.json().then(json => { 1248 if (json.stat !== 'OK') { 1249 if (typeof onError == 'function') { 1250 onError(json.msg) 1251 } 1252 } 1253 }).catch(function (err) { 1254 console.error('Reading json error', err); 1255 // Check errors on request 1256 if (typeof onError == 'function') { 1257 onError(err.message); 1258 } 1259 }); 1260 } else { 1261 // if blob, check file download 1262 response.blob().then((blob) => { 1263 const headerContentDisposition = response.headers.get('Content-Disposition'); 1264 const serverFilename = headerContentDisposition.match(/filename="(.+)"/)[1]; 1265 const theFilename = filename || serverFilename; 1266 SYM.onDownloadBlob(blob, theFilename); 1267 if (typeof onSuccess == 'function') { 1268 onSuccess(blob, theFilename); 1269 } 1270 }).catch(function (err) { 1271 console.error('Getting blob error', err); 1272 // Check errors on request 1273 if (typeof onError == 'function') { 1274 onError(err.message); 1275 } 1276 }); 1277 } 1278 } else { 1279 if (typeof onError == 'function') { 1280 onError(response.statusText); 1281 } 1282 } 1283 }).catch(function (err) { 1284 console.error('fetchFileError', err); 1285 // Check errors on request 1286 if (typeof onError == 'function') { 1287 onError(err.message); 1288 } 1289 }); 1290 }, 1291 1292 onDownloadBlob: function (blob, filename) { 1293 // Create blob to link and download. 1294 const finalFilename = filename; 1295 const objURL = window.URL.createObjectURL(blob); 1296 let link = document.createElement('a'); 1297 link.href = objURL; 1298 link.download = finalFilename; 1299 link.click(); 1300 } 1301 1302 }; 1303 1304}()); 1305 1306SYM.FORM = window.SYM.FORM || {}; 1307SYM.FORM = $.extend(SYM.FORM, function ($) { 1308 var METHODS = { 1309 private: { 1310 /** 1311 * initInputCounter 1312 * - Requires the $dom object to have the following data attributes: 1313 * - data-text-count: Type of element to be counted [chars|words] (words by default)
1314 * - data-text-count-for: Input to check the length of 1315 * - data-max: Maximum number of 'type' to count 1316 * - data-text: Some text to add after the number of remaining items 1317 * @param {Object} $dom - The jQuery object of the dom holding the counter 1318 */ 1319 initInputCounter: function ($dom) { 1320 var type = $dom.attr('data-text-count'); 1321 var input = '#' + $dom.attr('data-text-count-for'); 1322 var max = $dom.attr('data-max'); 1323 var text = $dom.attr('data-text'); 1324 $(input).on('keyup', function (ev) { 1325 var count = type == 'chars' ? $(this).val().length : 1326 /* type == 'words' */$(this).val().split(' ') 1327 .filter(function (n) { return n != '' }) 1328 .length; 1329 var remaining = (max - count); 1330 $dom.html(remaining + ' ' + text); 1331 $dom.toggleClass('input-group__subtext--warning', remaining < 0); 1332 }); 1333 $(input).trigger('keyup'); 1334 } 1335 }, 1336 public: { 1337 initInputCounter: function ($selector) { 1338 var $selection = $selector || '.text-count-input'; 1339 $($selection).each(function (index, object) { METHODS.private.initInputCounter($(object)); }); 1340 } 1341 } 1342 }; 1343 return METHODS.public; 1344}(jQuery)); 1345 1346// Solves the Cache problem using AJAX calls 1347 1348function noCache(uri) { 1349 return uri.concat(/\?/.test(uri) ? '&' : '?', 'noCache=', (new Date).getTime(), '.', Math.random() * 1234567); 1350} 1351 1352// String to JSON object 1353 1354function evalJson(src) { 1355 var pattern = /^\(.+\)$/gi; // Add parentheses if needed 1356 if (pattern.test(src) == false) { 1357 src = '(' + src + ')'; 1358 } 1359 1360 var data = ''; 1361 if (typeof JSON == 'object' && JSON.parse) { 1362 try { 1363 data = JSON.parse(src); 1364 } 1365 catch (e) { 1366 try { 1367 data = eval(src); 1368 } 1369 catch (e) { 1370 data = src; 1371 } 1372 } 1373 1374 } 1375 else { 1376 data = eval(src); 1377 } 1378 1379 if (typeof data == 'object') { 1380 return data 1381 } 1382 else { 1383 return { 1384 stat: 'ERROR', 1385 msg: 'ERROR' 1386 }; 1387 } 1388} 1389 1390// implement JSON.stringify serialization 1391JSON.stringify = JSON.stringify || function (obj) { 1392 var t = typeof (obj); 1393 if (t != "object" || obj === null) { 1394 // simple data type 1395 if (t == "string") obj = '"'+obj+'"'; 1396 return String(obj); 1397 } else { 1398 // recurse array or object 1399 var n, v, json = [], arr = (obj && obj.constructor == Array); 1400 for (n in obj) { 1401 v = obj[n]; t = typeof(v); 1402 if (t == "string") v = '"'+v+'"'; 1403 else if (t == "object" && v !== null) v = JSON.stringify(v); 1404 json.push((arr ? "" : '"' + n + '":') + String(v)); 1405 } 1406 return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}"); 1407 } 1408}; 1409// implement JSON.parse de-serialization 1410JSON.parse = JSON.parse || function (str) { 1411 if (str === "") str = '""'; 1412 eval("var p=" + str + ";"); 1413 return p; 1414}; 1415 1416// Function to delay keyup event, to wait for the last one 1417var delay = (function() { 1418 var timer = 0; 1419 return function(callback, ms) { 1420 clearTimeout (timer); 1421 timer = setTimeout(callback, ms); 1422 }; 1423})(); 1424 1425function htmlentities(string, quote_style) { 1426 // Convert all applicable characters to HTML entities 1427 // 1428 // version: 1004.2314 1429 // discuss at: http://phpjs.org/functions/htmlentities // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1430 // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1431 // + improved by: nobbler 1432 // + tweaked by: Jack 1433 // + bugfixed by: Onno Marsman // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1434 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 1435 // + input by: Ratheous 1436 // - depends on: get_html_translation_table 1437 // * example 1: htmlentities('Kevin & van Zonneveld'); // * returns 1: 'Kevin & van Zonneveld' 1438 // * example 2: htmlentities("foo'bar","ENT_QUOTES"); 1439 // * returns 2: 'foo'bar' 1440 var hash_map = {}, 1441 symbol = '', 1442 tmp_str = '', 1443 entity = ''; 1444 tmp_str = string.toString(); 1445 if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) { 1446 return false; 1447 } 1448 hash_map["'"] = '''; 1449 for (symbol in hash_map) { 1450 entity = hash_map[symbol]; 1451 tmp_str = tmp_str.split(symbol).join(entity); 1452 } 1453 return tmp_str; 1454} 1455 1456function base64_encode(data) { 1457 var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
1457+/="; 1458 var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, 1459 ac = 0, 1460 enc = "", 1461 tmp_arr = []; 1462 if (!data) { 1463 return data 1464 } 1465 do { 1466 o1 = data.charCodeAt(i++); 1467 o2 = data.charCodeAt(i++); 1468 o3 = data.charCodeAt(i++); 1469 bits = o1 << 16 | o2 << 8 | o3; 1470 h1 = bits >> 18 & 0x3f; 1471 h2 = bits >> 12 & 0x3f; 1472 h3 = bits >> 6 & 0x3f; 1473 h4 = bits & 0x3f; 1474 tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4) 1475 } while (i < data.length); 1476 enc = tmp_arr.join(''); 1477 switch (data.length % 3) { 1478 case 1: 1479 enc = enc.slice(0, -2) + '=='; 1480 break; 1481 case 2: 1482 enc = enc.slice(0, -1) + '='; 1483 break 1484 } 1485 return enc 1486} 1487 1488function base64_decode(input) { 1489 var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 1490 1491 var output = ""; 1492 var chr1, chr2, chr3 = ""; 1493 var enc1, enc2, enc3, enc4 = ""; 1494 var i = 0; 1495 1496 // remove all characters that are not A-Z, a-z, 0-9, +, /, or = 1497 var base64test = /[^A-Za-z0-9\+\/\=]/g; 1498 if (base64test.exec(input)) { 1499 alert("There were invalid base64 characters in the input text.\n" + 1500 "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" + 1501 "Expect errors in decoding."); 1502 } 1503 input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 1504 1505 do { 1506 enc1 = b64.indexOf(input.charAt(i++)); 1507 enc2 = b64.indexOf(input.charAt(i++)); 1508 enc3 = b64.indexOf(input.charAt(i++)); 1509 enc4 = b64.indexOf(input.charAt(i++)); 1510 1511 chr1 = (enc1 << 2) | (enc2 >> 4); 1512 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 1513 chr3 = ((enc3 & 3) << 6) | enc4; 1514 1515 output = output + String.fromCharCode(chr1); 1516 1517 if (enc3 != 64) { 1518 output = output + String.fromCharCode(chr2); 1519 } 1520 if (enc4 != 64) { 1521 output = output + String.fromCharCode(chr3); 1522 } 1523 1524 chr1 = chr2 = chr3 = ""; 1525 enc1 = enc2 = enc3 = enc4 = ""; 1526 1527 } while (i < input.length); 1528 1529 return unescape(output); 1530} 1531 1532function get_html_translation_table(table, quote_style) { 1533 // http://kevin.vanzonneveld.net 1534 // + original by: Philip Peterson 1535 // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1536 // + bugfixed by: noname 1537 // + bugfixed by: Alex 1538 // + bugfixed by: Marco 1539 // + bugfixed by: madipta 1540 // + improved by: KELAN 1541 // + improved by: Brett Zamir (http://brett-zamir.me) 1542 // + bugfixed by: Brett Zamir (http://brett-zamir.me) 1543 // + input by: Frank Forte 1544 // + bugfixed by: T.Wild 1545 // + input by: Ratheous 1546 // % note: It has been decided that we're not going to add global 1547 // % note: dependencies to php.js, meaning the constants are not 1548 // % note: real constants, but strings instead. Integers are also supported if someone 1549 // % note: chooses to create the constants themselves. 1550 // * example 1: get_html_translation_table('HTML_SPECIALCHARS'); 1551 // * returns 1: {'"': '"', '&': '&', '<': '<', '>': '>'} 1552 var entities = {}, 1553 hash_map = {}, 1554 decimal = 0, 1555 symbol = ''; 1556 var constMappingTable = {}, 1557 constMappingQuoteStyle = {}; 1558 var useTable = {}, 1559 useQuoteStyle = {}; 1560 1561 // Translate arguments 1562 constMappingTable[0] = 'HTML_SPECIALCHARS'; 1563 constMappingTable[1] = 'HTML_ENTITIES'; 1564 constMappingQuoteStyle[0] = 'ENT_NOQUOTES'; 1565 constMappingQuoteStyle[2] = 'ENT_COMPAT'; 1566 constMappingQuoteStyle[3] = 'ENT_QUOTES'; 1567 1568 useTable = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS'; 1569 useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT'; 1570 1571 if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') { 1572 throw new Error("Table: " + useTable + ' not supported'); 1573 // return false; 1574 } 1575 1576 entities['38'] = '&'; 1577 if (useTable === 'HTML_ENTITIES') { 1578 entities['160'] = ' '; 1579 entities['161'] = '¡'; 1580 entities['162'] = '¢'; 1581 entities['163'] = '£'; 1582 entities['164'] = '¤'; 1583 entities['165'] = '¥'; 1584 entities['166'] = '¦'; 1585 entities['167'] = '§'; 1586 entities['168'] = '¨'; 1587 entities['169'] = '©'; 1588 entities['170'] = 'ª'; 1589 entities['171'] = '«'; 1590 entities['172'] = '¬'; 1591 entities['173'] = '­'; 1592 entities['174'] = '®'; 1593 entities['175'] = '¯';
1594 entities['176'] = '°'; 1595 entities['177'] = '±'; 1596 entities['178'] = '²'; 1597 entities['179'] = '³'; 1598 entities['180'] = '´'; 1599 entities['181'] = 'µ'; 1600 entities['182'] = '¶'; 1601 entities['183'] = '·'; 1602 entities['184'] = '¸'; 1603 entities['185'] = '¹'; 1604 entities['186'] = 'º'; 1605 entities['187'] = '»'; 1606 entities['188'] = '¼'; 1607 entities['189'] = '½'; 1608 entities['190'] = '¾'; 1609 entities['191'] = '¿'; 1610 entities['192'] = 'À'; 1611 entities['193'] = 'Á'; 1612 entities['194'] = 'Â'; 1613 entities['195'] = 'Ã'; 1614 entities['196'] = 'Ä'; 1615 entities['197'] = 'Å'; 1616 entities['198'] = 'Æ'; 1617 entities['199'] = 'Ç'; 1618 entities['200'] = 'È'; 1619 entities['201'] = 'É'; 1620 entities['202'] = 'Ê'; 1621 entities['203'] = 'Ë'; 1622 entities['204'] = 'Ì'; 1623 entities['205'] = 'Í'; 1624 entities['206'] = 'Î'; 1625 entities['207'] = 'Ï'; 1626 entities['208'] = 'Ð'; 1627 entities['209'] = 'Ñ'; 1628 entities['210'] = 'Ò'; 1629 entities['211'] = 'Ó'; 1630 entities['212'] = 'Ô'; 1631 entities['213'] = 'Õ'; 1632 entities['214'] = 'Ö'; 1633 entities['215'] = '×'; 1634 entities['216'] = 'Ø'; 1635 entities['217'] = 'Ù'; 1636 entities['218'] = 'Ú'; 1637 entities['219'] = 'Û'; 1638 entities['220'] = 'Ü'; 1639 entities['221'] = 'Ý'; 1640 entities['222'] = 'Þ'; 1641 entities['223'] = 'ß'; 1642 entities['224'] = 'à'; 1643 entities['225'] = 'á'; 1644 entities['226'] = 'â'; 1645 entities['227'] = 'ã'; 1646 entities['228'] = 'ä'; 1647 entities['229'] = 'å'; 1648 entities['230'] = 'æ'; 1649 entities['231'] = 'ç'; 1650 entities['232'] = 'è'; 1651 entities['233'] = 'é'; 1652 entities['234'] = 'ê'; 1653 entities['235'] = 'ë'; 1654 entities['236'] = 'ì'; 1655 entities['237'] = 'í'; 1656 entities['238'] = 'î'; 1657 entities['239'] = 'ï'; 1658 entities['240'] = 'ð'; 1659 entities['241'] = 'ñ'; 1660 entities['242'] = 'ò'; 1661 entities['243'] = 'ó'; 1662 entities['244'] = 'ô'; 1663 entities['245'] = 'õ'; 1664 entities['246'] = 'ö'; 1665 entities['247'] = '÷'; 1666 entities['248'] = 'ø'; 1667 entities['249'] = 'ù'; 1668 entities['250'] = 'ú'; 1669 entities['251'] = 'û'; 1670 entities['252'] = 'ü'; 1671 entities['253'] = 'ý'; 1672 entities['254'] = 'þ'; 1673 entities['255'] = 'ÿ'; 1674 } 1675 1676 if (useQuoteStyle !== 'ENT_NOQUOTES') { 1677 entities['34'] = '"'; 1678 }
1679 if (useQuoteStyle === 'ENT_QUOTES') { 1680 entities['39'] = '''; 1681 } 1682 entities['60'] = '<'; 1683 entities['62'] = '>'; 1684 1685 1686 // ascii decimals to real symbols 1687 for (decimal in entities) { 1688 symbol = String.fromCharCode(decimal); 1689 hash_map[symbol] = entities[decimal]; 1690 } 1691 1692 return hash_map; 1693} 1694 1695empty = function(mixed_var) { 1696 // !No description available for empty. @php.js developers: Please update the function summary text file. 1697 // 1698 // version: 1006.1915 1699 // discuss at: http://phpjs.org/functions/empty // + original by: Philippe Baumann 1700 // + input by: Onno Marsman 1701 // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1702 // + input by: LH 1703 // + improved by: Onno Marsman // + improved by: Francesco 1704 // + improved by: Marc Jansen 1705 // + input by: Stoyan Kyosev (http://www.svest.org/) 1706 // * example 1: empty(null); 1707 // * returns 1: true // * example 2: empty(undefined); 1708 // * returns 2: true 1709 // * example 3: empty([]); 1710 // * returns 3: true 1711 // * example 4: empty({}); // * returns 4: true 1712 // * example 5: empty({'aFunc' : function () { alert('humpty'); } }); 1713 // * returns 5: false 1714 var key; 1715 if (mixed_var === "" || mixed_var === 0 || mixed_var === "0" || mixed_var === null || mixed_var === false || typeof mixed_var === 'undefined') { 1716 return true; 1717 } 1718 if (typeof mixed_var == 'object') { 1719 for (key in mixed_var) { 1720 return false; 1721 } 1722 return true; 1723 } 1724 1725 return false; 1726} 1727 1728// Encode UTF8 1729 1730function encode_utf8(s) { 1731 return unescape(encodeURIComponent(s)); 1732} 1733// Decode UTF8 1734 1735function decode_utf8(s) { 1736 return decodeURIComponent(escape(s)); 1737} 1738 1739 1740function enable_tab_height() { 1741 if ($('.tabs', '#right_column').length) { 1742 $('.tabs a', '#right_column').hover(function() { 1743 $('.tabs a.current', '#right_column').css('height', 23); 1744 $(this).css('height', 25); 1745 }, function() { 1746 $(this).css('height', 23); 1747 $('.tabs a.current', '#right_column').css('height', 25); 1748 }); 1749 1750 } 1751} 1752 1753// eliminar duplicados en un array 1754 1755function array_unique(vals) { 1756 var uniques = []; 1757 for (var i = vals.length; i--;) { 1758 var val = vals[i]; 1759 if ($.inArray(val, uniques) === -1) { 1760 uniques.unshift(val); 1761 } 1762 } 1763 return uniques; 1764} 1765 1766//PASS ALL OPTIONS OF A SELECT TO AN ARRAY 1767 1768function optionsToArray(id) { 1769 var result = new Array(); 1770 var i = 0; 1771 $.each($('#' + id + ' option'), function() { 1772 result[i] = $(this).val(); 1773 i++; 1774 }); 1775 return result; 1776} 1777 1778// validate an email using RFC 1779/** 1780 * Validate email applies compliance RFC 5322 1781 * Permits some especial chars 1782 * refers to documentation for more info https://datatracker.ietf.org/doc/html/rfc5322#section-3.4 1783 * @param string email to check 1784 * @returns bool 1785 */ 1786 function validate_email_rfc(email) { 1787 var regexp = /^(?=.{1,64}@)(\w{1,}[!#\$\%\&\'\*\+\-\/=\?\.\^_`\{\|\}~]{0,1})+\w+@((?=.{1,255}\.)((?:[A-Za-z0-9]+(?:(?:[A-Za-z0-9\-]*[A-Za-z0-9])?)\.)+[A-Za-z]{2,})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|)]))$/i; 1788 return regexp.test(email); 1789}; 1790 1791/*************** YAV DEFAULT CUSTOM RULES **************/ 1792//comprobar que un ckeditor no está vacÃÂo 1793//elimina espacios, saltos de lÃÂnea, etc, antes de validar 1794 1795function ckeditor_required(return_value) { 1796 var ckeditor_value = CKEDITOR.instances[return_value.id].getData(); 1797 if (!$('#ckeditor_aux_div').length) { 1798 $('<div></div>').attr('id', 'ckeditor_aux_div').css('display', 'hidden').appendTo('body'); 1799 } 1800 var aux_div = $('#ckeditor_aux_div'); 1801 aux_div.hide().html(ckeditor_value); 1802 if ($.trim(aux_div.text()).replace(/^\s+/g, '').replace(/\s+$/g, '').length || aux_div.find('img').length) { 1803 return null; 1804 } else { 1805 return return_value; 1806 } 1807} 1808 1809function ckeditor_max_word_count(return_value) { 1810 var ckeditor_value = CKEDITOR.instances[return_value.id].getData(); 1811 var word_count = parseInt($('#'+return_value.id).attr('data-word-limit')); 1812 1813 // Word count is disabled 1814 if (word_count <= 0) return null; 1815 1816 ckeditor_value = ckeditor_value.replace(/<(?:.|\n)*?>/gm, '').replace(/ /gm, ' ').replace(/\s+/gm, ' ').trim(); 1817 word_count = word_count - ckeditor_value.split(' ').length; 1818 1819 if (word_count >= 0) { 1820 return null; 1821 } else { 1822 return return_value; 1823 } 1824} 1825 1826 1827//Validate dates + times 1828 1829function time_travel(return_value) { 1830 var timeTravel = true; 1831 var date_ini_val = $('#date_ini').val(); 1832 var time_ini_val = ($('#init_hour').val() < 10 ? '0' + $('#init_hour').val():$('#init_hour').val()) + $('#
1832init_minute').val(); 1833 var date_end_val = $('#date_end').val(); 1834 var time_end_val = ($('#end_hour').val() < 10 ? '0' + $('#end_hour').val():$('#end_hour').val()) + $('#end_minute').val(); 1835 if(date_ini_val.length >= 10 && date_end_val.length >= 10) { 1836 timeTravel = false; 1837 var date_ini_eng = date_ini_val.match(/(\d{1,2})\/(\d{2})\/(\d{4})/); 1838 var date_ini_esp = date_ini_val.match(/(\d{1,2})\-(\d{2})\-(\d{4})/); 1839 var date_end_eng = date_end_val.match(/(\d{1,2})\/(\d{2})\/(\d{4})/); 1840 var date_end_esp = date_end_val.match(/(\d{1,2})\-(\d{2})\-(\d{4})/); 1841 if(date_ini_eng && date_end_eng) { 1842 timeTravel = parseInt(date_ini_eng[3] + date_ini_eng[1] + date_ini_eng[2] + time_ini_val, 10) > parseInt(date_end_eng[3] + date_end_eng[1] + date_end_eng[2] + time_end_val, 10); 1843 } else if(date_ini_esp && date_end_esp) { 1844 timeTravel = parseInt(date_ini_esp[3] + date_ini_esp[2] + date_ini_esp[1] + time_ini_val, 10) > parseInt(date_end_esp[3] + date_end_esp[2] + date_end_esp[1] + time_end_val, 10); 1845 } else { 1846 timeTravel = true; 1847 } 1848 } 1849 return timeTravel == true ? return_value : null; 1850} 1851 1852 1853//Validate dates 1854 1855function date_travel(return_value) { 1856 var timeTravel = true; 1857 var date_ini_val = $('#date_ini').val(); 1858 var date_end_val = $('#date_end').val(); 1859 var valid_dates = true; 1860 if((!date_ini_val.length || !date_end_val.length) || (date_ini_val.length > 9 && date_end_val.length > 9)) { 1861 timeTravel = false; 1862 //date ini validation 1863 if(date_ini_val.length) { 1864 var date_ini_eng = date_ini_val.match(/(\d{1,2})\/(\d{2})\/(\d{4})/); //english 1865 var date_ini_esp = date_ini_val.match(/(\d{1,2})\-(\d{2})\-(\d{4})/); //spanish 1866 if(!date_ini_eng && !date_ini_esp) { 1867 timeTravel = true; 1868 valid_dates = false; 1869 } 1870 1871 } 1872 //date end validation 1873 if(date_end_val.length && valid_dates) { 1874 var date_end_eng = date_end_val.match(/(\d{1,2})\/(\d{2})\/(\d{4})/); //english 1875 var date_end_esp = date_end_val.match(/(\d{1,2})\-(\d{2})\-(\d{4})/); //spanish 1876 if(!date_end_eng && !date_end_esp) { 1877 timeTravel = true; 1878 valid_dates = false; 1879 } 1880 } 1881 //date ini & date end validation 1882 if(date_ini_val.length && date_end_val.length && valid_dates) { 1883 if(date_ini_eng && date_end_eng) { 1884 timeTravel = parseInt(date_ini_eng[3] + date_ini_eng[1] + date_ini_eng[2], 10) > parseInt(date_end_eng[3] + date_end_eng[1] + date_end_eng[2], 10); 1885 } else if(date_ini_esp && date_end_esp) { 1886 timeTravel = parseInt(date_ini_esp[3] + date_ini_esp[2] + date_ini_esp[1], 10) > parseInt(date_end_esp[3] + date_end_esp[2] + date_end_esp[1], 10); 1887 } else { 1888 timeTravel = true; 1889 valid_dates = false; 1890 } 1891 } 1892 if(!valid_dates) { 1893 return_value.msg = msg.WHEN_TIP; 1894 } 1895 } 1896 return timeTravel == true ? return_value : null; 1897} 1898 1899var valid_url = function(return_value){ 1900 if($("#" + return_value.id).val() == '') { // permitir no requerido 1901 return null; 1902 } 1903 else if (/([-a-zA-Z0-9@:%_\+.~#?&//=]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))/gi.test( $("#" + return_value.id).val() )){ 1904 return null; 1905 }else{ 1906 return return_value; 1907 } 1908} 1909 1910var integer_no_zero = function(return_value){ 1911 if($("#" + return_value.id).val() == '') { // permitir no requerido 1912 return null; 1913 } 1914 else if (/[1-9][0-9]*/.test( $("#" + return_value.id).val() )){ 1915 return null; 1916 }else{ 1917 return return_value; 1918 } 1919} 1920 1921var required_one = function(return_value) { 1922 var parent = $('#'+return_value.id).parent(), 1923 radios = $('input[type="radio"],input[type="checkbox"]', parent), 1924 one_checked = false, 1925 find_attempts = 3; 1926 while (radios.length == 1 && find_attempts > 0) { 1927 find_attempts--; 1928 parent = $(parent).parent(); 1929 radios = $('input[type="radio"],input[type="checkbox"]', parent); 1930 } 1931 for (var i = 0; i < radios.length; i++) { 1932 one_checked = (one_checked || $(radios[i]).is(':checked')); 1933 if(i > 0){ 1934 $(radios[i]).removeClass('required_one'); // avoid multiple error messages 1935 } 1936 } 1937 if (one_checked || ! $('#'+return_value.id).hasClass('required_one')) { 1938 return null; 1939 } else { 1940 return return_value; 1941 } 1942} 1943 1944/** 1945 * The field is required if the author base form required fields are filled. 1946 * If everything goes right the method will return null (no error). 1947 * @version 1.0 1948 * @param return_value string This string defines the error. 1949 * @author <[email protected]> 1950 * @return string|null 1951 */ 1952var required_if_valid_author_insert = function (return_value) { 1953 var field = $('#' + return_value.id); 1954 var authorBlock = field.parents('.author_form').first(); 1955 var authorName = authorBlock.find('.author_name_input'); 1956 var authorEmail = authorBlock.find('.author_email_input'); 1957 var validAuthorInsert = ( 1958 (authorName && authorName.val() && authorName.val() !== '') || 1959 (authorEmail && authorEmail.val() && authorEmail.val() !== '') 1960 ); 1961 1962 if ( ! field || ! field.val() || field.val() == '') { 1963 if (validAuthorInsert) { 1964 return return_value; 1965 } 1966 } 1967 1968 return null; 1969} 1970 1971/** 1972 * The field is required if the author base form required fields are filled. 1973 * If everything goes right the method will return null (no error). 1974 * @version 1.0 1975 * @param return_value string This string defines the error. 1976 * @author <[email protected]> 1977 * @return string|null 1978 */ 1979var required_one_if_valid_author_insert = function (return_value) { 1980 var field = $('#' + return_value.id); 1981 var authorBlock = field.parents('.author_form').first(); 1982 var authorName = authorBlock.find('.author_name_input'); 1983 var authorEmail = authorBlock.find('.author_email_input'); 1984 var validAuthorInsert = ( 1985 (authorName && authorName.val() && authorName.val() !== '') || 1986 (authorEmail && authorEmail.val() && authorEmail.val() !== '') 1987 ); 1988 1989 var parent = field.parent(), 1990 radios = $('input[type="radio"],input[type="checkbox"]', parent), 1991 one_checked = false;
1992 for (var i = 0; i < radios.length; i++) { 1993 one_checked = (one_checked || $(radios[i]).is(':checked')); 1994 if (i > 0) { 1995 $(radios[i]).removeClass('required_one_if_valid_author_insert'); // avoid multiple error messages 1996 } 1997 } 1998 1999 if (one_checked || ! field.hasClass('required_one_if_valid_author_insert')) { 2000 return null; 2001 } else { 2002 return (validAuthorInsert) ? return_value : null; 2003 } 2004} 2005 2006/** 2007 * Validate email applies compliance RFC 5322 2008 * Permits some especial chars 2009 * refers to documentation for more info https://datatracker.ietf.org/doc/html/rfc5322#section-3.4 2010 * @param {*} return_value 2011 * @returns 2012 */ 2013var email_rfc = function (return_value) { 2014 var field = $("#" + return_value.id); 2015 2016 if (field.val() == "") { 2017 return null; 2018 } 2019 2020 return validate_email_rfc(field.val()) ? null : return_value; 2021}; 2022 2023/** 2024 * Rule for YAV to validate only alphanumeric characters 2025 * @param return_value 2026 * @returns {*|null} 2027 */ 2028const only_alphanumeric = function (return_value) { 2029 var field = $("#" + return_value.id); 2030 if (field.val() == "") { 2031 return null; 2032 } 2033 const currentValue = field.val(); 2034 // pattern to validate 2035 var wl_pattern = /(<[^>]+>|=|"|<|>)+/i; 2036 var result = currentValue.match(wl_pattern); 2037 return result ? return_value : null; 2038}; 2039 2040const valid_uri = (returnValue) => { 2041 const urlPattern = new RegExp('^((ft|htt)ps?:\\/\\/)?'+ // protocol 2042 '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name and extension 2043 '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address 2044 '(\\:\\d+)?'+ // port 2045 '(\\/[-a-z\\d%@_.~+&:]*)*'+ // path 2046 '(\\?[;&a-z\\d%@_.,~+&:=-]*)?'+ // query string 2047 '(\\#[-a-z\\d_]*)?$','i'); // fragment locator 2048 const currentElement = document.getElementById(returnValue.id); 2049 const currentValue = currentElement.value || ''; 2050 if (currentValue.trim() === '') { // permitir no requerido 2051 return null; 2052 } 2053 2054 return !urlPattern.test(currentValue.trim()) ? returnValue : null; 2055} 2056 2057const yav_valid_cif_nif_nie = function (returnValue) { 2058 const $field = $('#' + returnValue.id); 2059 if (!$field.length || $field.val() == "") return null; 2060 2061 return valida_nif_cif_nie($field.val()) < 0 ? returnValue : null; 2062} 2063 2064// YAV CUSTOM RULES // 2065$.yav_customfunctions = { 2066 "ckeditor_required": ckeditor_required, 2067 "time_travel": time_travel, 2068 "date_travel": date_travel, 2069 "valid_url": valid_url, 2070 "integer_no_zero": integer_no_zero, 2071 "required_one": required_one, 2072 "email_rfc": email_rfc, 2073 "valid_cif_nif_nie": yav_valid_cif_nif_nie , 2074 "only_alphanumeric": only_alphanumeric, 2075}; 2076$.yav_default = { 2077 hideTitle: false, 2078 rulesOnSubmit: true 2079}; 2080$.yav_default.library = { 2081 ISFOCUSSET: true 2082}; 2083// END YAV CUSTOM RULES // 2084 2085//js log configuration 2086if(/[#,&,\?]debug=true/.test(document.location.href)){ 2087 document.writeln("<script type='text/javascript' src='https://getfirebug.com/firebug-lite.js#enableTrace=true'></script>"); 2088}else if (SYM.debugc || _ENVIRONMENT == 'testing') { 2089 if (typeof console == 'undefined') { 2090 document.writeln("<script type='text/javascript' src='https://getfirebug.com/firebug-lite.js#enableTrace=true'></script>"); 2091 } 2092}else { 2093 try { 2094 console_disable = function(){ 2095 return false; 2096 } 2097 window['console'] = { 2098 log: console_disable, 2099 info: console_disable, 2100 debug: console_disable, 2101 error: console_disable, 2102 warn: console_disable 2103 } 2104 } 2105 catch (e) {} 2106} 2107//end js log configuration 2108 2109//Make unique space cleaned tags 2110function generate_tags(tag_aux_arr) 2111{ 2112 tag_arr = []; 2113 $.each(array_unique(tag_aux_arr), function() { 2114 var str_val = $.trim(this.toString()); 2115 if(str_val.length) { 2116 tag_arr.push(str_val) 2117 } 2118 }); 2119 return tag_arr; 2120} 2121 2122/** 2123 * Links two datepickers, forcing the second to have at least the same day as the first 2124 * @param String class_identifier The class identifying both datepickers 2125 * @param String date_ini_id The id of the date ini datepicker 2126 */ 2127function datepicker_range_pair(class_identifier, date_ini_id) { 2128 $.datepicker.setDefaults(msg.datepicker); 2129 var date_ini_full_id = '#'+date_ini_id, 2130 dates = $(class_identifier).datepicker({ 2131 onSelect: function( selectedDate ) { 2132 if (this.id == date_ini_id) { // If Im date ini and have been changed 2133 var option = "minDate", 2134 instance = $( this ).data( "datepicker" ), 2135 date = $.datepicker.parseDate( 2136 instance.settings.dateFormat || 2137 $.datepicker._defaults.dateFormat, 2138 selectedDate, instance.settings ); 2139 2140 dates.not( this ).datepicker( "option", option, date ); // Set the minDate of my pair 2141 if ($.datepicker.parseDate( msg.datepicker.dateFormat , selectedDate) > $.datepicker.parseDate( msg.datepicker.dateFormat ,dates.not( this ).val())) 2142 // If date_ini > date_end, set the new date_end at date_ini, as it's its minimum 2143 dates.not( this ).val(selectedDate); 2144 } 2145 }, 2146 beforeShow: function( input, instance ) { 2147 // hack for calendar position in modals jQuery.ui.1.13.2 with jQuery 3.6.2 requires ui.position 2148 // Dirty hack, only works this way 2149 var calendar = instance.dpDiv; 2150 setTimeout(function() { 2151 calendar.position({ 2152 my: 'left top', 2153 at: 'left bottom', 2154 collision: 'none', 2155 of: input 2156 }); 2157 }, 1); 2158 2159 if (this.id != date_ini_id && $(date_ini_full_id).val().length > 0) { // If Im date end, and date ini has a value 2160 $(this).datepicker("option", "minDate", $.datepicker.parseDate( msg.datepicker.dateFormat ,dates.not( this ).val())); 2161 } 2162 } 2163 }); 2164} 2165 2166/** 2167 * Scrolls to an element. Useful to show errors. 2168 * @param String identifier Valid jQuery selector. 2169 */ 2170function scroll_to_el(identifier, speed, margin) { 2171 if (typeof speed == 'undefined') speed = 750; 2172 if (typeof margin == 'undefined') margin = 0; 2173 $('html,body').animate({ 2174 scrollTop: $(identifier).offset().top + margin 2175 }, speed); 2176} 2177 2178/* 2179FUNCIONES AUXILIARES 2180str_replace -> Emula el str_replace de PHP 2181valida_nif_cif_nie -> Valida un documento NIF, CIF o NIE 2182*/ 2183function str_replace(search, replace, subject) { 2184 var f = search, r = replace, s = subject; 2185 var ra = r instanceof Array, sa = s instanceof Array, f = [].concat(f), r = [].concat(r), i = (s = [].concat(s)).length; 2186 while (j = 0, i--) { 2187 if (s[i]) { 2188 while (s[i] = s[i].split(f[j]).join(ra ? r[j] || "" : r[0]), ++j in f){}; 2189 } 2190 }; 2191 return sa ? s : s[0]; 2192} 2193//Retorna: 1 = NIF ok, 2 = CIF ok, 3 = NIE ok, -1 = NIF error, -2 = CIF error, -3 = NIE error, 0 = ??? error 2194function valida_nif_cif_nie(a) 2195{ 2196 var temp=a.toUpperCase(); 2197 var cadenadni="TRWAGMYFPDXBNJZSQVHLCKE"; 2198 2199 if (temp!==''){ 2200 //si no tiene un formato valido devuelve error 2201 if ((!/^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$/.test(temp) && !/^[T]{1}[A-Z0-9]{8}$/.test(temp)) && !/^[0-9]{8}[A-Z]{1}$/.test(temp)) 2202 { 2203 return 0; 2204 } 2205 2206 //comprobacion de NIFs estandar 2207 if (/^[0-9]{8}[A-Z]{1}$/.test(temp)) 2208 { 2209 posicion = a.substring(8,0) % 23; 2210 letra = cadenadni.charAt(posicion); 2211 var letradni=temp.charAt(8); 2212 if (letra == letradni) 2213 { 2214 return 1; 2215 } 2216 else 2217 {
2218 return -1; 2219 } 2220 } 2221 2222 //algoritmo para comprobacion de codigos tipo CIF 2223 suma = parseInt(a[2])+parseInt(a[4])+parseInt(a[6]); 2224 for (i = 1; i < 8; i += 2) 2225 { 2226 temp1 = 2 * parseInt(a[i]); 2227 temp1 += ''; 2228 temp1 = temp1.substring(0,1); 2229 temp2 = 2 * parseInt(a[i]); 2230 temp2 += ''; 2231 temp2 = temp2.substring(1,2); 2232 if (temp2 == '') 2233 { 2234 temp2 = '0'; 2235 } 2236 2237 suma += (parseInt(temp1) + parseInt(temp2)); 2238 } 2239 suma += ''; 2240 n = 10 - parseInt(suma.substring(suma.length-1, suma.length)); 2241 2242 //comprobacion de NIFs especiales (se calculan como CIFs) 2243 if (/^[KLM]{1}/.test(temp)) 2244 { 2245 if (a[8] == String.fromCharCode(64 + n)) 2246 { 2247 return 1; 2248 } 2249 else 2250 { 2251 return -1; 2252 } 2253 } 2254 2255 //comprobacion de CIFs 2256 if (/^[ABCDEFGHJNPQRSUVW]{1}/.test(temp)) 2257 { 2258 temp = n + ''; 2259 if (a[8] == String.fromCharCode(64 + n) || a[8] == parseInt(temp.substring(temp.length-1, temp.length))) 2260 { 2261 return 2; 2262 } 2263 else 2264 { 2265 return -2; 2266 } 2267 } 2268 2269 //comprobacion de NIEs 2270 //T 2271 if (/^[T]{1}/.test(temp)) 2272 { 2273 if (a[8] == /^[T]{1}[A-Z0-9]{8}$/.test(temp)) 2274 { 2275 return 3; 2276 } 2277 else 2278 { 2279 return -3; 2280 } 2281 } 2282 2283 //XYZ 2284 if (/^[XYZ]{1}/.test(temp)) 2285 { 2286 pos = str_replace(['X', 'Y', 'Z'], ['0','1','2'], temp).substring(0, 8) % 23; 2287 if (a[8] == cadenadni.substring(pos, pos + 1)) 2288 { 2289 return 3; 2290 } 2291 else 2292 { 2293 return -3; 2294 } 2295 } 2296 } 2297 return 0; 2298} 2299 2300// indexOf for IE 2301if (!Array.prototype.indexOf) 2302{ 2303 Array.prototype.indexOf = function(elt /*, from*/) 2304 { 2305 var len = this.length >>> 0; 2306 2307 var from = Number(arguments[1]) || 0; 2308 from = (from < 0) 2309 ? Math.ceil(from) 2310 : Math.floor(from); 2311 if (from < 0) 2312 from += len; 2313 2314 for (; from < len; from++) 2315 { 2316 if (from in this && 2317 this[from] === elt) 2318 return from; 2319 } 2320 return -1; 2321 }; 2322} 2323 2324jQuery.fn.whenPresent = function(successCallback, failedCallback) { 2325 var selector = this.selector, 2326 interval = 100, 2327 timeout = 20, 2328 checkExist = setInterval(function() { 2329 if ($(selector).length || timeout < 0) { 2330 var callback = (timeout > 0) ? successCallback : failedCallback; 2331 if (typeof callback == 'function') { 2332 callback(); 2333 } 2334 clearInterval(checkExist); 2335 } else { 2336 timeout--; 2337 } 2338 }, interval); 2339 return this; 2340}; 2341 2342jQuery.fn.scrollTo = function(speed) { 2343 var selector = this.selector; 2344 if (typeof speed == 'undefined') speed = 750; 2345 $('html,body').animate({ 2346 scrollTop: $(selector).offset().top 2347 }, speed); 2348}; 2349 2350 2351SYM.TRACKER = $.extend({}, (($) => { 2352 const CONST = { 2353 ga4Events: { 2354 symposium_webinars_banner_show: { 2355 event: "Campaings", 2356 name: "Webinars Banner", 2357 parameters: { title: "Show" } 2358 }, 2359 2360 symposium_webinars_banner_more_info: { 2361 event: "Campaings", 2362 name: "Webinars Banner", 2363 parameters: { title: "More Info" } 2364 }, 2365 2366 symposium_webinars_banner_close: { 2367 event: "Campaings", 2368 name: "Webinars Banner", 2369 parameters: { title: "Close" } 2370 }, 2371 2372 symposium_webinars_overlay_show: { 2373 event: "Campaings", 2374 name: "Webinars Overlay", 2375 parameters: { title: "Show" } 2376 }, 2377 2378 symposium_webinars_overlay_close: { 2379 event: "Campaings", 2380 name: "Webinars Overlay", 2381 parameters: { title: "Close" } 2382 }, 2383 2384 symposium_webinars_overlay_more_info: { 2385 event: "Campaings", 2386 name: "Webinars Overlay", 2387 parameters: { title: "More Info" } 2388 }, 2389 2390 symposium_webinars_overlay_close_forever: { 2391 event: "AB_Testing", 2392 name: "MyEvents", 2393 parameters: { title: "Close Forever" } 2394 }, 2395 2396 symposium_AB_Testing_myevents_click_on_arrow: { 2397 event: "AB_Testing", 2398 name: "MyEvents", 2399 parameters: { title: "Toggle by click on arrow" } 2400 }, 2401 2402 symposium_AB_Testing_myevents_click_on_title: { 2403 event: "AB_Testing", 2404 name: "MyEvents", 2405 parameters: { title: "Toggle by click on title" } 2406 }, 2407 2408 symposium_from_vue_widget_event_click: { 2409 event: "VUE_event_click", 2410 name: "MyEvents", 2411 parameters: { title: "Click on vue widget event" } 2412 }, 2413 2414 symposium_from_vue_widget_news_click: { 2415 event: "VUE_news_click", 2416 name: "MyEvents", 2417 parameters: { title: "Click on vue widget news" } 2418 }, 2419 2420 symposium_maps_display: { 2421 event: "Maps", 2422 name: "Display", 2423 parameters: { title: "New event step 1" } 2424 }, 2425 2426 symposium_maps_display_directory_map: { 2427 event: "Maps", 2428 name: "Display", 2429 parameters: { title: "Directory Map" } 2430 }, 2431 2432 symposium_maps_display_event_places: { 2433 event: "Maps", 2434 name: "Display", 2435 parameters: { title: "Event_places" } 2436 }, 2437 2438 symposium_maps_display_event_map: { 2439 event: "Maps", 2440 name: "Display", 2441 parameters: { title: "Event map" } 2442 }, 2443 2444 symposium_maps_preload_preload_map: { 2445 event: "Maps", 2446 name: "Preload", 2447 parameters: { title: "Map preloaded" } 2448 }, 2449 2450 symposium_widget_maps_display_event: { 2451 event: "Maps", 2452 name: "Preload", 2453 parameters: { title: "widget_map_event" } 2454 }, 2455 2456 } 2457 2458 }; 2459 2460 const METHODS = { 2461 2462 private: { 2463 trackGoogleAnalytics4Event: (event, extraParams = null) => { 2464 const addCID = ['VUE_event_click', 'VUE_news_click']; 2465 const currentEvent = CONST.ga4Events[event]; 2466 // remove cid param 2467 if (addCID.includes(currentEvent.event)) { 2468 currentEvent.parameters.id = getAllUrlParams().cid; 2469 currentEvent.event = "SymWidgetComponent_eventClicked" 2470 removeUrlParams('cid'); 2471 } 2472 2473 // gtag not found due cookieconsent 2474 if (typeof gtag === 'undefined') { 2475 return; 2476 } 2477 2478 if (extraParams) { 2479 currentEvent.params = { ...currentEvent.params, ...extraParams }; 2480 } 2481 2482 gtag('event', currentEvent.event, currentEvent.parameters); 2483 2484 }, 2485 }, 2486 public: { 2487 trackEvent: (event, extraParams = null) => { 2488 console.log('track', event); 2489 if (CONST.ga4Events[event]) { 2490 METHODS.private.trackGoogleAnalytics4Event(event, extraParams); 2491 } else { 2492 console.log('cant track event'); 2493 } 2494 } 2495 } 2496 } 2497 2498 return METHODS.public; 2499 2500})(jQuery)); 2501 2502 2503// Once document is loaded... 2504$.fn.ready(function() { 2505 //Configuration for AJAX calls 2506 SYM.bind_ajax_progress_bar(); 2507 2508 // get rid of those system borders being generated for A tags // 2509 if (typeof $.browser != 'undefined' && $.browser.msie) { 2510 $('a').focus(function() { 2511 $(this).attr('hideFocus', 'true'); 2512 }); 2513 } 2514 2515 // prevent session lost 2516 if(typeof _IS_PARTNER_SITE != 'undefined') { // EE no ofrece gestión de usuarios 2517 if(_IS_PARTNER_SITE){ 2518 SYM.keep_session(); 2519 } 2520 } 2521 2522 //ELLIPSIS 2523 if ($('.ellipsis').length) { 2524 if ($.fn.ellipsis) { 2525 $('.ellipsis').ellipsis(true); 2526 } 2527 } 2528 2529 enable_tab_height(); 2530 2531 // Always stick the footer to the bottom of the page 2532 if ($("div.sticky").length > 0) { 2533 setTimeout(function() { 2534 if (typeof $.fn.stickyFooter == 'function') { 2535 $("div.sticky").stickyFooter(); 2536 } else { 2537 console.error('stickyFooter was not found'); 2538 } 2539 }, 1500); 2540 } 2541 2542 //Symposium by emagister link 2543 $('.sym_info', '#body_footer').css('cursor', 'pointer').click(function() { 2544 document.location.href = $(this).children('a').attr('href'); 2545 }); 2546 2547 // show tooltips 2548 SYM.activate_tooltips(''); 2549 2550 // activate multilang warning movement 2551 SYM.multilang_warning_effects(); 2552 2553 // extend jQuery load 2554 if (typeof $.fn._load == 'undefined') { // Don't do this twice 2555 (function($) { 2556 $.fn._load = $.fn.load; 2557 $.fn.extend({ 2558 load: function(url, args, callback) { 2559 if (typeof SYMJS != 'undefined' && typeof SYMJS.blocks_init != 'undefined') return $(this)._load(url, args, callback); 2560 // Backwards compatibility for the jquery load function 2561 if ($.isFunction(url)) return $(this)._load(url, args, callback); 2562 if (!this.length) return this; 2563 2564 // append ajax loader 2565 this.html('<div class="ajax_load_points"></div>'); 2566 2567 return $(this)._load(url, args, callback); 2568 } 2569 }); 2570 })(jQuery); 2571 } 2572 2573 // Migration warning 2574 var migrationwarning = false;
2575 if (migrationwarning && typeof msgbox_infotop != 'undefined') { 2576 if (typeof localStorage != 'undefined') { 2577 var lastShow = new Date(localStorage.getItem('_MaintenanceWarning')), 2578 now = new Date(), 2579 diff = now.getTime() - lastShow.getTime(), 2580 hours = diff / (1000*60*60); 2581 2582 if (hours < 1) { 2583 console.log('hours = '+hours); 2584 return; 2585 } 2586 2587 localStorage.setItem('_MaintenanceWarning', now.toISOString()); 2588 } 2589 var text = { 2590 'es' : 'La plataforma de eventos estará en mantenimiento el miércoles 19 de Octubre de 5:00 am a 9:00 am. Disculpen las molestias.', 2591 'en' : 'The events platform will be in maintenance mode on wednesday 19th of October from 5:00 am to 9:00 am. We apologize for any inconvenience.', 2592 'ca' : "La plataforma d'esdeveniments estaràen manteniment el dimecres 19 d'octubre de 05:00 a.m. a 09:00 a.m. Disculpeu les molèsteis." 2593 }, 2594 lang = _LANGUAGE; 2595 if (typeof text[_LANGUAGE] == 'undefined') lang = 'es'; 2596 msgbox_infotop(text[lang], 'migration-warning'); 2597 setTimeout(function(){ 2598 msgbox_close($('#migration-warning')); 2599 }, 10000); 2600 } 2601 2602 // Include js-dropdown functionality 2603 $('body').delegate('.js-dropdown .js-dropdown-trigger', 'mouseenter', function (ev) { 2604 ev.preventDefault(); 2605 var $body = $('body'); 2606 var $trigger = $(this); 2607 var $parent = $trigger.parents('.js-dropdown'); 2608 var $drop = $parent.find('.js-dropdown-drop'); 2609 var direction = null; 2610 if ($drop.length) { 2611 $drop.detach(); 2612 $drop.hide(); 2613 $body.append($drop); 2614 direction = $drop.data('direction') || 'bottom'; 2615 $drop.addClass(direction); 2616 $trigger[0]._js_drop = $drop; 2617 $trigger[0]._js_drop_direction = direction; 2618 } else { 2619 $drop = $trigger[0]._js_drop; 2620 } 2621 direction = $trigger[0]._js_drop_direction; 2622 $drop.css({'position': 'absolute'}); 2623 $drop.show(); 2624 var left = 0; 2625 var top = 0; 2626 switch (direction) { 2627 case 'left': 2628 left = $trigger.offset().left 2629 - $drop.width() 2630 - parseInt($drop.css('padding-left')) 2631 - parseInt($drop.css('padding-right')) 2632 - parseInt($drop.css('border-left')) 2633 - parseInt($drop.css('border-right')) 2634 - 18; 2635 top = $trigger.offset().top - ($drop.height() / 2); 2636 break; 2637 case 'right': 2638 left = $trigger.offset().left 2639 + $trigger.width() 2640 + parseInt($trigger.css('padding-right')) 2641 + parseInt($trigger.css('padding-left')) 2642 + 18; 2643 top = $trigger.offset().top - ($drop.height() / 2); 2644 break; 2645 case 'bottom': 2646 left = $trigger.offset().left - ($drop[0].clientWidth / 2) + ($trigger[0].clientWidth / 2); 2647 top = $trigger.offset().top + $trigger[0].clientHeight + 18; 2648 break; 2649 case 'top': 2650 left = $trigger.offset().left - ($drop[0].clientWidth / 2) + ($trigger[0].clientWidth / 2); 2651 top = $trigger.offset().top - $drop.height() - parseInt($drop.css('padding-top')) - parseInt($drop.css('padding-bottom')) - 18; 2652 break; 2653 } 2654 $drop.css({ 'left': left, 'top': top }); 2655 return false; 2656 }); 2657 $('body').delegate('.js-dropdown .js-dropdown-trigger', 'mouseleave', function (ev) { 2658 ev.preventDefault(); 2659 var $trigger = $(this); 2660 if ($trigger[0]._js_drop) { 2661 $trigger[0]._js_drop.hide(); 2662 } 2663 return false; 2664 }); 2665 2666 // Closes sidebar menu when clicks out 2667 var $sideMenu = $('#event-menu-collapse'); 2668 if ($sideMenu.length) { 2669 var $closeSideMenu = $sideMenu.find('.close-menu'); 2670 $sideMenu.find('a:not(.dropdown-toggle):not(.close-menu)').click(() => { 2671 $closeSideMenu.click(); 2672 }); 2673 } 2674 2675 // Symposium Banner fadeout 2676 $('.symposiumBanner__close').on('click', function (ev) { 2677 ev.preventDefault(); 2678 ev.stopPropagation(); 2679 var $trigger = $(this); 2680 var $banner = $trigger.parents('.symposiumBanner'); 2681 var $bannerIdentifier = $banner.data('banner-identifier'); 2682 var $bannerReopen = $banner.data('banner-reopen'); 2683 if ($bannerIdentifier) { 2684 $banner.slideUp('slow'); 2685 // Check if the banner is ment to open every time (we dont need to keep track of it) 2686 if (!$bannerReopen || $bannerReopen != 'reopen') { 2687 var now = new Date(); 2688 localStorage.setItem('banner-'+$bannerIdentifier, now); 2689 // Add statistics 2690 SYM.TRACKER.trackEvent("symposium_webinars_banner_close"); 2691 } 2692 } 2693 }); 2694 // Symposium Banner more information click 2695 $(".symposiumBanner__action-link").on('click', 'a', (ev) => { 2696 // Add statistics 2697 SYM.TRACKER.trackEvent("symposium_webinars_banner_more_info"); 2698 }); 2699 // Symposium Banner fade in 2700 $('.symposiumBanner').each(function (i, o) { 2701 var $banner = $(o); 2702 var $bannerIdentifier = $banner.data('banner-identifier'); 2703 if ($bannerIdentifier) { 2704 var now = new Date(); 2705 // Search banner in localstorage 2706 // If no data or the date is older than 8 hours, open the banner 2707 var date = localStorage.getItem('banner-'+$bannerIdentifier); 2708 var show = false;
2709 if (date) { 2710 date = new Date(date); 2711 var diff = (now.getTime() - date.getTime()) / 1000 / 3600; 2712 if (diff > 8) { 2713 show = true; 2714 } 2715 } else { 2716 show = true; 2717 } 2718 if (show) { 2719 $banner.slideDown('slow'); 2720 if ($bannerIdentifier == "zoom-support-banner") { 2721 SYM.TRACKER.trackEvent("symposium_webinars_banner_show"); 2722 } 2723 } 2724 } 2725 }); 2726 2727 // Symposium login modal 2728 if (SYM.LOGIN) { 2729 SYM.LOGIN.tryLoginModal(); 2730 } else { 2731 let loginTryies = 0; 2732 let loadLoginWidgetScript = function () { 2733 $.getScript("/js/widgets/login_panel.js") 2734 .done(function () { 2735 SYM.LOGIN.tryLoginModal(); 2736 }) 2737 .fail(function () { 2738 loginTryies++; 2739 if (loginTryies < 5) loadLoginWidgetScript(); 2740 }); 2741 } 2742 loadLoginWidgetScript(); 2743 } 2744 2745}); 2746 2747// Splash screen 2748/*$(window).load(function() { 2749 $('.loading_splash').fadeOut('slow', function() { 2750 $(this).remove(); 2751 }); 2752}); 2753*/ 2754 2755if ( !jQuery.browser ) { 2756 var uaMatch = function( ua ) { 2757 ua = ua.toLowerCase(); 2758 2759 var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || 2760 /(webkit)[ \/]([\w.]+)/.exec( ua ) || 2761 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || 2762 /(msie) ([\w.]+)/.exec( ua ) || 2763 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || 2764 []; 2765 2766 return { 2767 browser: match[ 1 ] || "", 2768 version: match[ 2 ] || "0" 2769 }; 2770 }; 2771 2772 matched = uaMatch( navigator.userAgent ); 2773 browser = {}; 2774 2775 if ( matched.browser ) { 2776 browser[ matched.browser ] = true; 2777 browser.version = matched.version; 2778 } 2779 2780 // Chrome is Webkit, but Webkit is also Safari. 2781 if ( browser.chrome ) { 2782 browser.webkit = true; 2783 } else if ( browser.webkit ) { 2784 browser.safari = true; 2785 } 2786 2787 jQuery.browser = browser; 2788} 2789 2790SYM.VAL = { 2791 current: null, 2792 validate: function(selector, elementsSelector) { 2793 SYM.VAL.current = $(selector); 2794 var valid = true; 2795 $('.symValError', selector).remove(); 2796 if (typeof elementsSelector == 'undefined') elementsSelector = '.symValInp:visible'; 2797 $(elementsSelector, selector).each(function(c,el){ 2798 if (valid) { 2799 var fn = $(el).attr('data-val-fn'), 2800 params = $(el).attr('data-val-params'); 2801 if (params != null && params.length) params = JSON.parse(params); 2802 switch ($(el).attr('type')) { 2803 case 'checkbox': 2804 case 'radio': 2805 var result = SYM.VAL.fn[fn]($(el).attr('data-val-group'), params); 2806 break; 2807 default: 2808 var result = SYM.VAL.fn[fn]($(el).val(), params); 2809 break; 2810 } 2811 if (!result) { 2812 var error = $(el).attr('data-val-error'); 2813 if (error == null || error.length == 0) { 2814 error = msg.REQUIRED_FIELD; 2815 } 2816 var error_container = $(el).attr('data-val-error-container'); 2817 if (error_container == null || error_container.length == 0) { 2818 $('<p class="error symValError"> ' + error + ' </p>').insertAfter(el); 2819 } else { 2820 $(error_container).append($('<p class="error symValError"> ' + error + ' </p>')); 2821 } 2822 } 2823 valid = valid && result; 2824 } 2825 }); 2826 return valid; 2827 }, 2828 fn: { 2829 email: function(value) { 2830 var reg = new RegExp(/^([a-z0-9_\.\-\+]+\@[\da-z\.-]+\.[a-z\.]{2,})$/i); 2831 console.log('email', reg.test(value), value); 2832 return reg.test(value); 2833 }, 2834 email_rfc: function(value) { 2835 return validate_email_rfc(value); 2836 }, 2837 required: function(value) { 2838 console.log('required', value); 2839 return value != null && (typeof value != 'undefined') && value.length > 0; 2840 }, 2841 regex: function(value, params) { 2842 var reg = new RegExp(params.reg); 2843 console.log('regex', reg.test(value), value); 2844 return reg.test(value); 2845 }, 2846 require_at_least: function(group, params) { 2847 var selected = $('input[data-val-group=' + group + ']:checked', SYM.VAL.current).length, 2848 min = (typeof params == 'object' && typeof params.min != 'undefined') ? params.min : 0, 2849 max = (typeof params == 'object' && typeof params.max != 'undefined') ? params.max : 99999; 2850 console.log('require_at_least', min, selected, max); 2851 return (selected >= min && selected <= max); 2852 } 2853 } 2854}; 2855 2856jQuery.fn.fadeThenSlideToggle = function (speed, easing, callback) { 2857 if (this.is(":hidden")) { 2858 return this.slideDown(speed, easing).fadeTo(speed, 1, easing, callback); 2859 } else {
2860 return this.fadeTo(speed, 0, easing).slideUp(speed, easing, callback); 2861 } 2862}; 2863 2864jQuery.fn.toClipboard = function () { 2865 var element = this[0]; 2866 var selection = window.getSelection(); 2867 var range = document.createRange(); 2868 range.selectNodeContents(element); 2869 selection.removeAllRanges(); 2870 selection.addRange(range); 2871 try { 2872 var successful = document.execCommand('copy'); 2873 selection.removeAllRanges(); 2874 return successful; 2875 } catch (err) { 2876 return false; 2877 } 2878} 2879 2880SYM.CLIPBOARD = { 2881 // copy text from DOM element via unsecure mode (non https) 2882 unsecuredCopyToClipboard: (text) => { 2883 const textArea = document.createElement("textarea"); 2884 textArea.value = text; 2885 document.body.appendChild(textArea); 2886 textArea.select(); 2887 try { 2888 document.execCommand('copy'); 2889 } catch (err) { 2890 console.error('Unable to copy to clipboard', err); 2891 } 2892 document.body.removeChild(textArea); 2893 }, 2894 2895 copyTextToClipboard: async (text) => { 2896 // call right method depending on secure context 2897 (window.isSecureContext && navigator.clipboard) ? 2898 await navigator.clipboard.writeText(text) : 2899 SYM.CLIPBOARD.unsecuredCopyToClipboard(text); 2900 }, 2901 2902 // copy code to clipboard 2903 copyToClipboard: async (htmlElement) => { 2904 const content = htmlElement.value || ''; 2905 2906 SYM.CLIPBOARD.copyTextToClipboard(text); 2907 2908 htmlElement.value = htmlElement.dataset.copyText; 2909 setTimeout(() => (htmlElement.value = content), 2000); 2910 }, 2911} 2912 2913SYM.SERVICES = $.extend({}, (function ($) { 2914 var BASIC_SERVICES = { 2915 get: function (url, params, cb) { 2916 $.getJSON(url, params, function (response) { 2917 var data = null; 2918 var error = null; 2919 if (response && response.stat == 'OK') { 2920 data = response.data; 2921 } else if (response && response.stat == 'WARNING') { 2922 data = response; 2923 } else if (typeof response.msg !== 'undefined') { 2924 if (typeof msg[response.msg] !== 'undefined') { 2925 error = msg[response.msg]; 2926 } else { 2927 error = response.msg; 2928 } 2929 } else if (typeof _msg == 'function' && _msg(response.msg)) { 2930 error = _msg(response.msg); 2931 } else { 2932 error = msg.SERVER_ERROR; 2933 } 2934 if (error && typeof response.errors !== 'undefined') { 2935 data = response.errors; 2936 } 2937 if (typeof cb == 'function') { 2938 return cb(error, data); 2939 } 2940 }).fail(function (jqXHR, textStatus, errorThrown) { 2941 if (typeof cb == 'function') { 2942 return cb( 2943 errorThrown, 2944 { 2945 jqXHR: jqXHR, 2946 textStatus: textStatus, 2947 errorThrown: errorThrown, 2948 requestId: jqXHR.getResponseHeader('x-symposium-unique-request-id') 2949 } 2950 ); 2951 } 2952 }); 2953 }, 2954 post: function (url, params, cb) { 2955 $.post(url, params, function (response) { 2956 var data = null; 2957 var error = null; 2958 if (response && response.stat == 'OK') { 2959 data = response.data; 2960 } else if (response && response.stat == 'WARNING') { 2961 data = response; 2962 } else if (typeof response.msg !== 'undefined') { 2963 if (typeof msg[response.msg] !== 'undefined') { 2964 error = msg[response.msg]; 2965 } else { 2966 error = response.msg; 2967 } 2968 } else if (typeof _msg == 'function' && _msg(response.msg)) { 2969 error = _msg(response.msg); 2970 } else { 2971 error = msg.SERVER_ERROR; 2972 } 2973 if (error && typeof response.errors !== "undefined") { 2974 data = response.errors; 2975 } 2976 if (typeof cb == 'function') { 2977 return cb(error, data); 2978 } 2979 }, 'json').fail(function (jqXHR, textStatus, errorThrown) { 2980 if (typeof cb == 'function') { 2981 return cb( 2982 errorThrown, 2983 { 2984 jqXHR: jqXHR, 2985 textStatus: textStatus, 2986 errorThrown: errorThrown, 2987 requestId: jqXHR.getResponseHeader('x-symposium-unique-request-id') 2988 } 2989 ); 2990 } 2991 }); 2992 }, 2993 put: function(url, data, callback, type) { 2994 2995 if ( $.isFunction(data) ){ 2996 type = type || callback, 2997 callback = data, 2998 data = {} 2999 } 3000 3001 return $.ajax({ 3002 url: url, 3003 type: 'PUT', 3004 success: callback, 3005 data: data, 3006 contentType: type 3007 }); 3008 }, 3009 delete: function(url, data, callback, type) { 3010 3011 if ( $.isFunction(data) ){ 3012 type = type || callback, 3013 callback = data, 3014 data = {} 3015 } 3016 return $.ajax({ 3017 url: url, 3018 type: 'DELETE', 3019 success: callback, 3020 data: data, 3021 contentType: type 3022 }); 3023 }, 3024 3025 // fetch implementation 3026 fetch: { 3027 3028 _common: { 3029 isJson: (res) => res.headers.get('Content-Type').match(/^application\/json/), 3030 getJsonResponse: (res, success, reject) => { 3031 res.json().then(success).catch(err => { 3032 console.error('Reading json error', err); 3033 reject(err.message); 3034 }); 3035 }, 3036 downloadFile: (res, success, reject) => { 3037 res.blob().then(blob => { 3038 const headerContentDisposition = res.headers.get('Content-Disposition'); 3039 if (!headerContentDisposition) return reject('SERVER_ERROR'); 3040 const serverFilename = headerContentDisposition.match(/filename="(.+)"/)[1]; 3041 const theFilename = serverFilename || 'file'; 3042 SYM.onDownloadBlob(blob, theFilename); 3043 success({ 3044 blob: blob, 3045 filename: theFilename 3046 }); 3047 }).catch(err => { 3048 console.error('Error in blob', err); 3049 return reject(err); 3050 }); 3051 },
3052 getUrlObject: function (url, base) { 3053 try { 3054 return new URL(url, base); 3055 } catch (err) { 3056 if (!base) { 3057 return this.getUrlObject(url, window.location.origin); 3058 } 3059 } 3060 }, 3061 default: (url, config, success, reject) => { 3062 fetch(url, config) 3063 .then((res) => { 3064 if (!res.ok) { 3065 return reject({ 3066 status: res.status, 3067 statusText: res.statusText, 3068 supportHeader: res.headers.get('x-symposium-server-error') 3069 }); 3070 } 3071 if (SYM.SERVICES.fetch._common.isJson(res)) { 3072 SYM.SERVICES.fetch._common.getJsonResponse(res, success, reject); 3073 } else { 3074 SYM.SERVICES.fetch._common.downloadFile(res, success, reject); 3075 } 3076 }) 3077 .catch(err => { 3078 console.error(err); 3079 reject(err.message) 3080 }); 3081 }, 3082 defaultError: function (res, reject) { 3083 console.error('default error', res); 3084 const baseError = { 3085 status: res.status, 3086 statusText: res.statusText, 3087 supportHeader: res.headers.get('x-symposium-server-error') 3088 }; 3089 res.json().then((json) => { 3090 let statusText = json.scalar || res.statusText; 3091 const error = json?.error || ''; 3092 const msg = json?.msg || ''; 3093 return reject(Object.assign({}, baseError, { statusText: statusText, error, msg })); 3094 }).catch(err => { 3095 console.error(err); 3096 return reject(baseError); 3097 }); 3098 }, 3099 defaultSuccess: function (res, success, reject) { 3100 if (SYM.SERVICES.fetch._common.isJson(res)) { 3101 SYM.SERVICES.fetch._common.getJsonResponse(res, success, reject); 3102 } else { 3103 SYM.SERVICES.fetch._common.downloadFile(res, success, reject); 3104 } 3105 }, 3106 default: (url, config, success, reject) => { 3107 fetch(url, config) 3108 .then((res) => { 3109 if (!res.ok) { 3110 SYM.SERVICES.fetch._common.defaultError(res, reject); 3111 } else { 3112 SYM.SERVICES.fetch._common.defaultSuccess(res, success, reject); 3113 } 3114 }) 3115 .catch(err => { 3116 console.error(err); 3117 reject(err.message) 3118 }); 3119 }, 3120 }, 3121 3122 get: function (url, qs_params) { 3123 const urlObject = this._common.getUrlObject(url); 3124 if (qs_params) urlObject.search = new URLSearchParams(qs_params).toString(); 3125 const config = {method: 'GET'}; 3126 const defaultRun = this._common.default; 3127 return new Promise((success, reject) => { 3128 defaultRun(urlObject, config, success, reject); 3129 }); 3130 }, 3131 3132 delete: function (url, qs_params) { 3133 const urlObject = this._common.getUrlObject(url); 3134 if (qs_params) urlObject.search = new URLSearchParams(qs_params).toString(); 3135 const config = {method: 'DELETE'}; 3136 const defaultRun = this._common.default; 3137 return new Promise((success, reject) => { 3138 defaultRun(urlObject, config, success, reject); 3139 }); 3140 }, 3141 3142 post: function (url, params, qs_params, json='json') { 3143 const urlObject = this._common.getUrlObject(url); 3144 let config = { method: 'POST' }; 3145 if (qs_params) urlObject.search = new URLSearchParams(qs_params).toString(); 3146 if (params && json) { 3147 config = Object.assign({}, config, { 3148 headers: { "Content-Type": "application/json" }, 3149 body: JSON.stringify(params) 3150 }); 3151 } else if (params) { 3152 config = Object.assign({}, config, { 3153 headers: { "Content-Type": "application/x-www-form-urlencoded" }, 3154 body: new URLSearchParams(params) 3155 }); 3156 } 3157 const defaultRun = this._common.default; 3158 return new Promise((success, reject) => { 3159 defaultRun(urlObject, config, success, reject); 3160 }); 3161 }, 3162 3163 put: function (url, params, qs_params, json='json') { 3164 const urlObject = this._common.getUrlObject(url); 3165 let config = { method: 'PUT' }; 3166 if (qs_params) urlObject.search = new URLSearchParams(qs_params).toString(); 3167 if (params && json) { 3168 config = Object.assign({}, config, { 3169 headers: { "Content-Type": "application/json" }, 3170 body: JSON.stringify(params) 3171 }); 3172 } else if (params) { 3173 config = Object.assign({}, config, { body: params }); 3174 } 3175 const defaultRun = this._common.default; 3176 return new Promise((success, reject) => { 3177 defaultRun(urlObject, config, success, reject); 3178 }); 3179 }, 3180 3181 } 3182 3183 } 3184 return BASIC_SERVICES; 3185})(jQuery)); 3186 3187SYM.EXPORT_FORMAT = $.extend({}, (function ($) { 3188 3189 const DOM = { 3190 MODAL: { 3191 SELECTOR: '.div_export_formats' 3192 }, 3193 }; 3194 3195 const METHODS = { 3196 private: { 3197 openModal: function (selector, type = '', modalOptions = null, success, reject) { 3198 const $modalTemplate = $(selector); 3199 if ($modalTemplate.length) { 3200 // This can be done without detaching the modal and using $modal.html() as parameter to msgbox. 3201 // Is done this way to keep the styles of the main class, using the same object as is done in other views. 3202 $('body').append($modalTemplate.detach()); 3203 $modal = msgbox($modalTemplate, type, modalOptions); 3204 if ($modal) { 3205 METHODS.private.initModalHandlers($modal, success, reject); 3206 } else { 3207 reject(); 3208 } 3209 } 3210 }, 3211 initModalHandlers: function ($modal, success, reject) { 3212 3213 $('a', $modal).off('click').on('click', function(ev){ 3214 ev.preventDefault(); 3215 ev.stopPropagation(); 3216 3217 const $target = $(ev.target); 3218 const data = $target.data(); 3219 const format = data?.format || 'excel'; 3220 3221 success(format); 3222 msgbox_close($modal); 3223 3224 return false;
3225 }); 3226 3227 $('.close', $modal).off('click').on('click', function (ev) { 3228 ev.preventDefault(); 3229 ev.stopPropagation(); 3230 reject(); 3231 msgbox_close($modal); 3232 return false; 3233 }); 3234 3235 } 3236 }, 3237 public: { 3238 select: function (modalType='', modalOptions=null) { 3239 return new Promise((success, reject) => { 3240 METHODS.private.openModal(DOM.MODAL.SELECTOR, modalType, modalOptions, success, reject); 3241 }); 3242 } 3243 } 3244 }; 3245 3246 return METHODS.public; 3247 3248})(jQuery));
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.