1/* 2===== 3functions/detections: 4 5file_buttons() 6file_upload_delete() 7file_upload_reset() 8file_upload_set() 9form_submit() -- includes recaptcha validation 10generate_password() 11hide_featured_img() 12htmlentities 13js_back() 14local_storage_debug() 15move_form_labels() 16optimage() 17password_chars_showhide() 18pcp() -- password confirm password form submit 19prevent_double_click() 20slider() 21spinner_load() 22spinner_show() 23scrollto() 24tabs() 25validate_ajax() 26wrappers_inner() 27wrappers_outer() 28===== 29*/ 30 31// GLOBALS =============================================================== 32if (typeof $jsphp_vars['current_rel_uri'] != 'undefined') { 33 $current_rel_uri = $jsphp_vars['current_rel_uri']; 34} 35// /GLOBALS =============================================================== 36 37// TRIGGER VARS ========================================================== 38// $enable_recaptcha = false; 39$enable_recaptcha = true; 40 41// also set in shortcodes-form-2.php [form2] 42// $recaptcha_v = 2; 43$recaptcha_v = 3; 44 45// $recaptcha_bot_level = 0.2; 46$recaptcha_bot_level = 0.3; 47// $recaptcha_bot_level = 0.4; 48// /TRIGGER VARS ========================================================== 49 50// MISC =================================================================== 51/** 52 * htmlentities 53 * modded from https://ourcodeworld.com/articles/read/188/encode-and-decode-html-entities-using-pure-javascript 54 * by DP 55 */ 56window.htmlentities = { 57 /** 58 * Converts a string to its html characters completely. 59 * 60 * @param {String} str String with unescaped HTML characters 61 **/ 62 encode : function(str) { 63 var buf = []; 64 65 for (var i=str.length-1;i>=0;i--) { 66 buf.unshift(['&#', str[i].charCodeAt(), ';'].join('')); 67 } 68 69 return buf.join(''); 70 }, 71 /** 72 * Converts an html characterSet into its original character. 73 * 74 * @param {String} str htmlSet entities 75 **/ 76 decode : function(str) { 77 return str.replace(/&#(\d+);/g, function(match, dec) { 78 return String.fromCharCode(dec); 79 }); 80 } 81};// /window.htmlentities = { 82 83/** 84 * js_back() 85 * a simple back button 86 * 87 */ 88jQuery(document).ready(function($) { 89 $(document).on('click','.js-back',function($e){ 90 $e.preventDefault(); 91 js_back(); 92 }); 93}); 94function js_back() { 95 history.back(); 96} 97 98/** 99 * local_storage_debug() 100 * print to console all localStorage key/values 101 * 102 */ 103function local_storage_debug() { 104 for (var $k in localStorage) { 105 if (typeof localStorage[$k] === 'function') {continue;} 106 console.log($k, ' = ', localStorage[$k]); 107 }// /for (var $k in localStorage) { 108}// /function local_storage_debug() { 109 110/** 111 * scrollto() 112 * scroll to anchor 113 * on page load, select change and link click 114 */ 115jQuery(document).ready(function($) { 116 $('a[href^="#"]').on('click',function ($e) { 117 //use like: <a href="#fred">Fred</a> <a name="fred" id="fred"></a> 118 $e.preventDefault(); 119 if (typeof $(this).attr('fancybox-inline') != 'undefined') {return false;} 120 scrollto($(this).hash); 121 }); 122 $('select').change(function($e){ 123 if($(this).val().charAt(0) == '#') { 124 $e.preventDefault(); 125 scrollto($(this).val()); 126 } 127 }); 128 $(window).ready(function(){ 129 if (location.hash) {scrollto(location.hash);} 130 }); 131});// /jQuery(document).ready(function($) { 132function scrollto(hash) { 133 jQuery(document).ready(function($) { 134 // console.log('hash:',hash); 135 if (typeof(hash) == 'undefined' || hash == '') {return false;} 136 var $target = $(hash); 137 if (typeof $target.offset() == 'undefined') {return false;} 138 $('html, body').stop().animate({ 139 'scrollTop': parseInt($target.offset().top)-0//130 140 }, 900, 'swing'); 141 });// /jQuery(document).ready(function($) { 142}// /function scrollto (hash) { 143 144/** 145 * slider() 146 * slide rotator 147 * modded from hp-darrel.js upcoming events rotator 148 * 149 * @param string $slider REQUIRED 150 * @param int data-timer -- in milliseconds 151 * @param int data-timer_resume -- milliseconds 152 * 153 * @since 2021-02 - TW 154 * 155 * use like, (in WP use group and/or columns for div's): 156 * <div class="slider"> 157 * <div class="slide">$content</div> 158 * <div class="slide">$content</div> 159 * </div> 160 * 161 * css like: 162.slider { 163border: solid 10px red; 164} 165.slide { 166 opacity: 0; 167 transition: 0.5s opacity; 168border: solid 10px green; 169} 170.slide:not(:first-of-type) { 171 position: absolute; 172 top: 0; 173 left: 0; 174} 175.slide .wp-block-column { 176border: solid 10px yellow; 177} 178.slide.slide-current { 179 opacity: 1;
180} 181.slider-nav-container { 182 display: flex; 183 justify-content: flex-start; 184border: solid 10px blue; 185} 186.slide-nav { 187 width: 20px; 188 height: 20px; 189 margin-right: 10px; 190 background-color: rgba(0,0,0,1); 191 border-radius: 20px; 192 cursor: pointer; 193 transition: 0.5s all; 194} 195.slide-nav.slide-nav-current { 196 background-color: rgba(255,255,255,1); 197} 198 */ 199jQuery(document).ready(function($) { 200 $('.slider').each(function($k,$v){ 201 slider($(this)); 202 }); 203});// /jQuery(document).ready(function($) { 204function slider($obj) { 205 jQuery(document).ready(function($) { 206 //console.log('$obj:',$obj); 207 //console.log('$obj.find(\'.slide\'):',$obj.find('.slide')); 208 209 var $timer = 4000; 210 if (typeof $obj.attr('data-timer') != 'undefined') {$timer = parseInt($obj.attr('data-timer'));} 211 //console.log('$timer:',$timer); 212 213 var $timer_resume = 10000; 214 if (typeof $obj.attr('data-timer_resume') != 'undefined') {$timer_resume = parseInt($obj.attr('data-timer_resume'));} 215 //console.log('$timer_resume:',$timer_resume); 216 217 var $slides_count = $obj.find('.slide').length; 218 var $slide_current = $slides_count; 219 if ($slides_count > 0) { 220 if ($slides_count > 1) { 221 // add the nav 222 $obj.append('<div class="slider-nav-container"></div>'); 223 for(var $n = 1; $n <= $slides_count; $n++) { 224 $obj.find('.slider-nav-container').append('<div class="slide-nav" data-num="'+$n+'"></div>'); 225 } 226 227 // start the timer 228 var $slidetimer = setInterval(function(){slide_display()},$timer); 229 }// /if ($slides_count > 1) { 230 231 // now show the first slide 232 slide_display(); 233 }// /if ($slides_count > 0) { 234 235 $obj.find('.slide-nav').on('click',function(){ 236 // stop the timer 237 clearInterval($slidetimer); 238 $slidetimer = null; 239 240 // restart the timer after x seconds 241 setTimeout(function(){ 242 $slidetimer = setInterval(function(){slide_display()},$timer); 243 },$timer_resume); 244 245 // set the clicked slide to current 246 $slide_current = ($(this).attr('data-num')-1); 247 slide_display(); 248 249 });// /$('.slide-nav').on('click',function(){ 250 251 function slide_display() { 252 //console.log('$obj:',$obj); 253 $obj.find('.slide').removeClass('slide-current'); 254 $slide_current = ($slide_current%$slides_count)+1;//console.log('$slide_current:',$slide_current); 255 $obj.find('.slide:nth-of-type('+$slide_current+')').addClass('slide-current'); 256 257 $obj.find('.slide-nav').removeClass('slide-nav-current'); 258 $obj.find('.slide-nav:nth-of-type('+$slide_current+')').addClass('slide-nav-current'); 259 }// /function slide_display() { 260 });// /jQuery(document).ready(function($) { 261}// /function slider() { 262 263/** 264 * spinner_load() 265 * DOM insert modal background with a css animated div, hidden by default 266 * see also ../css/style-custom.css spinner 267 */ 268spinner_load(); 269function spinner_load() { 270 jQuery(document).ready(function($) { 271 var popup = '<div class="hp-spinnerpopup" style="display:none;position:fixed;top:0px;left:0px;z-index:20000;width:100%;height:100%;background-color: rgba(0,0,0,0.5);"><div id="loader"></div></i></div>'; 272 273 $('body').append(popup); 274 275 var $viewport_height = parseInt($(window).height());//console.log($viewport_height); 276 $('.hp-spinnerpopup').css('padding-top',(($viewport_height/2)-60)+'px'); 277 278 $('body').on('click','.show_spinner',function($e){spinner_show();}); 279 280 window.default_alert = window.alert;// hold original alert obj 281 window.alert = function() { 282 $('.hp-spinnerpopup').hide(); 283 default_alert(arguments[0]); 284 return; 285 } 286 });// /jQuery(document).ready(function($) { 287}// /function spinner_load() { 288 289/** 290 * spinner_show() 291 * show/hide from spinner_load() above 292 * 293 * can also instead simply use the show() hide() in a page 294 * to progammatically determine when to show/hide, 295 * such as on an ajax send/return 296 * 297 * @param int $length -- length in milliseconds before hiding the spinner popup 298 */ 299function spinner_show($length) { 300 jQuery(document).ready(function($) { 301 //console.log('$length:',$length); 302 if ( 303 typeof $length == 'undefined' 304 || $length == '' 305 || $length == 0 306 || !$length 307 ) { 308 $length = 10000; 309 } 310 $('.hp-spinnerpopup').show(); 311 window.setTimeout(function(){ 312 $('.hp-spinnerpopup').hide(); 313 },$length); 314 });// /jQuery(document).ready(function($) { 315}// /function spinner_show() { 316 317/** 318 * tabs() 319 * HTML like: 320<div class="tabs"> 321 322<div class="tabs-nav"> 323<div class="active" data-tab="tab-name1">Name 1</div> 324<div data-tab="tab-name2">Name 2</div> 325</div><!-- class="tabs-nav"--> 326 327<div class="tab active" id="tab-name1"> 328<content here> 329</div><!-- class="tab"--> 330 331<div class="tab" id="tab-name2"> 332<content here> 333</div><!-- class="tab"--> 334 335</div><!-- class="tabs"--> 336 337 * CSS like: 338.tabs { 339} 340.tabs-nav { 341 position: relative; 342 z-index: 10000; 343 border-bottom: solid 1px #000; 344} 345.tabs-nav div {
346 display: inline-block; 347 padding: 3px 3px 3px 3px; 348 color: #ccc; 349 border-style: solid; 350 border-width: 1px 0px 0px 1px; 351 border-color: #000000; 352 cursor: pointer; 353} 354.tabs-nav div:last-child { 355 border-right-width: 1px; 356} 357.tabs-nav div.active{ 358 color: #000; 359} 360.tab { 361 display: none; 362} 363.tab.active { 364 display: block; 365} 366 */ 367function tabs() { 368 jQuery(document).ready(function($) { 369 $('.tabs-nav div').click(function($e){ 370 $e.preventDefault(); 371 372 var $tabs = $(this).closest('.tabs'); 373 var $tabs_nav = $(this).closest('.tabs-nav'); 374 var $target = $(this).attr('data-tab'); 375 376 $tabs_nav.find('div').removeClass('active'); 377 $(this).addClass('active'); 378 379 $tabs.find('.tab').hide(); 380 $('#'+$target).show(); 381 });// /$('.tabs-nav div').click(function($e){ 382 });// /jQuery(document).ready(function($) { 383}// /function tabs() { 384tabs(); 385// /MISC =================================================================== 386 387// FORMS =================================================================== 388/* 389NOTE: 2020-06-12 390some of the below have been rebuilt and may not function correctly, test before deployment!!!!! 391*/ 392 393// move labels ============================================= 394/** 395 * move_form_labels() 396 * move form labels inside of form elements: text, textarea 397 * see also see also style-custom.css label {} for the inital hide of labels 398 * 399 * must be in separate function if form is inserted in the dom via ajax or other mechanism, 400 * ex: see /admintools-3/api.js at3_form_print() 401 */ 402move_form_labels(); 403function move_form_labels() { 404 jQuery(document).ready(function($) { 405 // if element is pre-populated, add .label-pos-focused to the container 406 407 // move selected form element labels ========== 408 // see ../php/shortcodes-form.php [password],[text],[textarea] 409 var $container = $('.input-password-container,.input-text-container,.input-textarea-container'); 410 $container.addClass('label-pos'); 411 412 var $elements = 'input[type=password],input[type=text],textarea'; 413 // console.log('$elements:',$elements); 414 415 // $container.find('input[type=text]').blur();// removes autofocus if set 416 if ($container.find('input[type=text]').prop('autofocus')) { 417 $container.find('input[type=text]').blur(); 418 } 419 420 $container.each(function($k,$v){ 421 // console.log('$v:',$v); 422 // console.log('$(this)',$(this)); 423 var $_this = $(this); 424 var $val = $_this.find($elements).val(); 425 // console.log('$val:',$val.length); 426 if (typeof $val !== 'undefined' && $val.length > 0) {$_this.addClass('label-pos-focused');} 427 // console.log('$_this.attr(\'class\')',$_this.attr('class')); 428 429 // show the labels, see also style-custom.css label {} 430 $_this.find('label').show(); 431 432 $_this.find($elements).on('focus',function(){ 433 $_this.addClass('label-pos-focused'); 434 }); 435 $_this.find('label').on('click',function(){ 436 $_this.addClass('label-pos-focused'); 437 $_this.find($elements).focus(); 438 }); 439 $_this.find($elements).on('blur',function(){ 440 if ($(this).val() == '') { 441 $_this.removeClass('label-pos-focused'); 442 } 443 }); 444 });// /$container.each(function($k,$v){ 445 // /move selected form element labels ========== 446 447 // refocus on the last autofocus ========== 448 /* 449 NOTE: DO NOT HAVE CONSOLE OPEN OR THIS WILL NOT FOCUS!!!!! 450 Also, a timeout will NOT steal focus from the console, so don't try it 451 */ 452 $.each($('input[type=text]'),function($k,$v){ 453 if ($(this).prop('autofocus')) { 454 $(this).focus(); 455 } 456 });// /$.each($('input[type=text]'),function($k,$v){ 457 // /refocus on the last autofocus ========== 458 459 // suspenders/belt -- make sure labels are shown in case dom inserted 460 setTimeout(function(){ 461 $('label').show(); 462 },1600); 463 464 });// /jQuery(document).ready(function($) { 465}// /function move_form_labels() { 466// /move labels ============================================= 467 468// validate on submit ============================================ 469/** 470 * form_submit() 471 * validate forms on submit IF the form has data-validate="true" 472 * 473 * if data-validate == to an existing function, that function will be called, ex: 474 * [form2 name="password_confirm_password" validate="pcp"] will call this function: pcp() 475 * modded from: https://www.labnol.org/code/20181-call-javascript-function-by-name 476 * 477 * for recaptcha v2 (invisible): 478 * if a form has attr('data-recaptcha') == true 479 * and attr('data-rsk') != 'undefined', i.e. has the public key
480 * supposedly on initial fail, should pop a visual puzzle?? doesn't seem to be a way to test... 481 * on recaptcha fail, redirects to wp page /bot/ 482 * 483 * for recaptcha v3: 484 * if a form has attr('data-recaptcha') == true 485 * and attr('data-rsk') != 'undefined', i.e. has the public key 486 * on recaptcha fail, redirects to wp page /bot/ 487 * 488 * see ../php/shortcodes-form-2.php [form2] 489 */ 490jQuery(document).ready(function($) { 491 $('form').on('submit',function($e){ 492 493 // call a specific submit function: 494 if ( 495 typeof $(this).attr('data-validate') !== 'undefined' 496 && typeof window[$(this).attr('data-validate')] === 'function'// $(this).attr('data-validate') == 'pcp' 497 ) { 498 window[$(this).attr('data-validate')]($e,$(this));//pcp($e,$(this)); 499 } 500 501 // use the generic submit function 502 else { 503 form_submit($e,$(this)); 504 } 505 });// /$('form').on('submit',function($e){ 506 function form_submit($e,$obj) { 507 if ( 508 typeof $obj.attr('data-validate') === 'undefined' 509 || $obj.attr('data-validate') !== 'true' 510 ) {return;} 511 512 /* 513 stop the submit 514 to resubmit after tests, 515 unbind the submit button from the submit action like: 516 $obj.unbind('submit').submit(); 517 */ 518 $e.preventDefault(); 519 520 var $validated = true; 521 522 // see ../../assets/js/validate.js for validate functions 523 $obj.find(':input').each(function($k,$v){ 524 //console.log('$(this):',$(this)); 525 var $validate_type = ''; 526 if (typeof $(this).attr('data-validate') != 'undefined') {$validate_type = $(this).attr('data-validate');} 527 //console.log('$validate_type:',$validate_type); 528 var $msg = ''; 529 if (typeof $(this).attr('data-validate-msg') != 'undefined') {$msg = $(this).attr('data-validate-msg');} 530 //console.log($msg); 531 532 if ($validate_type == 'blank' && !check_blank($(this),$msg)) {$validated = false;return false;} 533 if ($validate_type == 'blank-no-email' && !check_blank_no_email($(this),$msg)) {$validated = false;return false;} 534 if ($validate_type == 'checkbox' && !check_checkbox($(this),$msg)) {$validated = false;return false;}
535 if ($validate_type == 'email' && !check_email($(this),$msg)) {$validated = false;return false;} 536 if ($validate_type == 'radio' && !check_radio_grp($(this),$msg)) {$validated = false;return false;} 537 if ($validate_type == 'select' && !check_select($(this),$msg)) {$validated = false;return false;} 538 539 // see ../php/shortcodes-form-2.php > [password_confirm_password2] 540 if ($validate_type == 'pcp-add' && $(this).hasClass('password')) { 541 // NOTE: $(this).hasClass('password') skips .password_confirm in the loop 542 var $pw = $(this); 543 var $pwc = $obj.find('.password_confirm');//alert($pwc); 544 if(!check_blank($pw,'Please fill out the "'+$pw.attr('title')+'" field')) {$validated = false;return false;} 545 if(!check_blank($pwc,'Please fill out the "'+$pwc.attr('title')+'" field')) {$validated = false;return false;} 546 if(!check_match_a_b($pw,$pwc,$msg)) {$validated = false;return false;} 547 if(!check_min_max($pw,$pw.attr('data-minlength'),$pw.attr('data-maxlength'))) {$validated = false;return false;} 548 }// /if ($validate_type == 'pcp-add' && $(this).hasClass('password')) { 549 550 });// /$(this).find(':input').each(function($k,$v){ 551 //if (!check_blank($('#form_id #field_id'))) {return false;}// an example of checking a specific field instead of using the above loop 552 553 // recaptcha test MUST be LAST!!!!! 554 // NOTE: $enable_recaptcha var at the top simply stops the redirect to the bot page, it does NOT stop the recaptcha test 555 if ( 556 typeof $obj.attr('data-recaptcha') != 'undefined' 557 && $obj.attr('data-recaptcha') == true 558 && typeof $obj.attr('data-rsk') != 'undefined' 559 && $validated 560 ) { 561 // console.log('$obj.attr(\'id\')',$obj.attr('id')); 562 // console.log('$obj.attr(\'data-recaptcha\'):',$obj.attr('data-recaptcha')); 563 // console.log('$obj.attr(\'data-rsk\'):',$obj.attr('data-rsk')); 564 var $site_key = $obj.attr('data-rsk'); 565 var $rsk = $site_key; 566 567 // $recaptcha_v set at the top of this file 568 // for $jsphp_vars see ../../functions.php 569 if ($recaptcha_v == 2) { 570 /* 571 see shortcodes-form-2.php form2_func() 572 sets the inital recaptcha invisible widget up in an obj for use in grecaptcha.execute() below 573 mulitple recaptcha widgets per page allowed this way 574 */ 575 // var $rvu = $jsphp_vars['parent_theme_file_uri']+'/assets/php/recaptcha/recaptcha_v2_validate.php';//'/wp-content/themes/'.HP_THEME_FOLDER.'/assets/php/recaptcha/recaptcha_v3_validate.php'; 576 var $rvu = $jsphp_vars['stylesheet_directory_uri']+'/assets/php/recaptcha/recaptcha_v2_validate.php';//'/wp-content/themes/'.HP_THEME_FOLDER.'/assets/php/recaptcha/recaptcha_v3_validate.php'; 577 // /* 578 grecaptcha.ready(function() { 579 // alert($recaptcha_widget[$obj.attr('id')]); 580 grecaptcha.execute($recaptcha_widget[$obj.attr('id')]).then(function($token) { 581 var $url = $rvu; 582 // why use $.ajax instead of $.post??? Seems setting async to false gives a more accurate score??? 583 $.ajax({
584 async: true,//false, 585 type: 'POST', 586 url: $url, 587 data: {'token':$token}, 588 success: function($data){ 589 $data = JSON.parse($data); 590 // console.log($data); 591 592 // always show this in console, helps with troubleshooting 593 console.log('v2 $data[\'score\']:',$data['score']); 594 595 // fail -- don't test score, just $data['success'] true|false 596 // $enable_recaptcha set at the top of this file 597 if ( 598 $enable_recaptcha 599 && ( 600 typeof $data['success'] == 'undefined' 601 || !$data['success'] 602 // || typeof $data['score'] == 'undefined' 603 // || $data['score'] < $recaptcha_bot_level 604 ) 605 ) { 606 // pops visual recaptcha??? no way to test it seems... 607 window.location.replace('/bot/'); 608 return false; 609 } 610 // pass -- submit form 611 else {$obj.unbind('submit').submit();} 612 }, 613 dataType: 'json' 614 }); 615 616 }); 617 }); 618 // */ 619 }// /if ($recaptcha_v == 2) { 620 if ($recaptcha_v == 3) { 621 // var $rvu = $jsphp_vars['parent_theme_file_uri']+'/assets/php/recaptcha/recaptcha_v3_validate.php';//'/wp-content/themes/'.HP_THEME_FOLDER.'/assets/php/recaptcha/recaptcha_v3_validate.php'; 622 var $rvu = $jsphp_vars['stylesheet_directory_uri']+'/assets/php/recaptcha/recaptcha_v3_validate.php';//'/wp-content/themes/'.HP_THEME_FOLDER.'/assets/php/recaptcha/recaptcha_v3_validate.php'; 623 grecaptcha.ready(function() { 624 grecaptcha.execute($rsk, {action:'shortcode_form'}).then(function(token) { 625 var $url = $rvu; 626 // why use $.ajax instead of $.post??? Seems setting async to false gives a more accurate score??? 627 $.ajax({
628 async: true,//false, 629 type: 'POST', 630 url: $url, 631 data: {'token':token}, 632 success: function($data){ 633 $data = JSON.parse($data);//console.log($data); 634 635 // always show this in console, helps with troubleshooting 636 console.log('v3 $data[\'score\']:',$data['score']); 637 638 // $enable_recaptcha set at the top of this file 639 if ($enable_recaptcha) { 640 if (typeof $data['success'] == 'undefined') { 641 window.location.replace('/bot/?msg=success-undefined'); 642 return false; 643 } 644 if (!$data['success']) { 645 window.location.replace('/bot/?msg=success-false'); 646 return false; 647 } 648 if (typeof $data['score'] == 'undefined') { 649 window.location.replace('/bot/?msg=score-undefined'); 650 return false; 651 } 652 if($data['score'] < $recaptcha_bot_level) { 653 window.location.replace('/bot/?msg=score-small&size='+$data['score']); 654 return false; 655 } 656 657 // pass -- submit the form 658 $obj.unbind('submit').submit(); 659 }// /if ($enable_recaptcha) { 660 if (!$enable_recaptcha) {// submit the form regardless, see top of this file 661 $obj.unbind('submit').submit(); 662 }// /if (!$enable_recaptcha) { 663 }, 664 dataType: 'json' 665 }); 666 });// /grecaptcha.execute( 667 });// /grecaptcha.ready(function() { 668 }// /if ($recaptcha_v == 3) { 669 }// /if (typeof $obj.attr('data-recaptcha') != 'undefined' 670 671 else if ($validated) {$obj.unbind('submit').submit();} 672 }// /function form_submit() { 673 674 /** 675 * pcp() 676 * password confirm password form submit 677 * see ../php/shortcodes-form-2.php > [password_confirm_password2] 678 * 679 * html MUST be like: 680 * <input type="password" class="password" 681 * <input type="password" class="password"_confirm" 682 */ 683 function pcp($e,$obj) { 684 //alert($e);$e.preventDefault();return false; 685 var $pw = $obj.find('input.password'); 686 var $pwc = $obj.find('input.password_confirm'); 687 688 var $msg = ''; 689 if (typeof $pw.attr('data-validate-msg') != 'undefined') {$msg = $pw.attr('data-validate-msg');} 690 //console.log($msg); 691 if(!check_blank($pw,'Please fill out the "'+$pw.attr('title')+'" field')) {$e.preventDefault();return false;} 692 if(!check_blank($pwc,'Please fill out the "'+$pwc.attr('title')+'" field')) {$e.preventDefault();return false;} 693 if(!check_match_a_b($pw,$pwc,$msg)) {$e.preventDefault();return false;} 694 if(!check_min_max($pw,$pw.attr('data-minlength'),$pw.attr('data-maxlength'))) {$e.preventDefault();return false;} 695 }// /function form_submit_pcp() { 696});// /jQuery(document).ready(function($) { 697// /validate on submit ============================================ 698 699// ajax validate ============================================ 700/** 701 * validate_ajax() 702 * see ../php/shortcodes-form-2.php [text2] 703 * 704 * NOTE: blur initially gets hit for all text fields to handle the moving of the label 705 * into the field, see move_form_labels() above 706 */ 707jQuery(document).ready(function($) { 708 $('input').on('blur',function(){ 709 if (typeof $(this).attr('data-validate-ajax') !== 'undefined') { 710 validate_ajax($(this)); 711 } 712 }); 713});// /jQuery(document).ready(function($) { 714function validate_ajax($obj) { 715 jQuery(document).ready(function($) { 716 //var $obj = $(obj);console.log('$obj:',$obj); 717 718 // if empty, stop -- will be hit on page load all the time by move_form_labels() 719 if (typeof $obj.val() == 'undefined' || $obj.val() == '') {return false;} 720 721 // if no string to test with, stop 722 if (typeof $obj.attr('data-validate-ajax') == 'undefined' || $obj.attr('data-validate-ajax') == '') {return false;} 723 724 var $args = {}; 725 parse_str($obj.attr('data-validate-ajax'),$args); 726 if (typeof $args['process'] == 'undefined' || $args['process'] == '') {$args['process'] = 'unique_db';} 727 $args['v'] = $obj.val(); 728 $args['ajax_return'] = true; 729 730 var $url = './';// see db.php 731 if (typeof $args['url'] != 'undefined' && $args['url'] != '') {$url = $args['url'];} 732 733 //console.log('$url:',$url); 734 //console.log('$args:',$args); 735 $.post($url,$args).done(function($data) { 736 //console.log('validate_ajax $data:',$data); 737 //console.log('$obj.attr(\'data-validate-ajax-exist\'):',$obj.attr('data-validate-ajax-exist')); 738 /* 739 if a value is returned, it means that the value exists already in the db 740 $exist = check db to see if returned value is to be tested as existing or not existing 741 */ 742 var $exist = JSON.parse($obj.attr('data-validate-ajax-exist').toLowerCase());// cast "true"|"false" to bool true|false 743 if (!$exist && $data.hasOwnProperty('check_v')) { 744 alert('The value you entered "'+$obj.val()+'" is not available. Please try again.'); 745 $obj.val(''); 746 $obj.focus(); 747 } 748 if ($exist && !$data.hasOwnProperty('check_v')) { 749 alert('The value you entered "'+$obj.val()+'" is not on file. Please try again.'); 750 $obj.val(''); 751 $obj.focus(); 752 } 753 },'json'); 754 });// /jQuery(document).ready(function($) { 755}// /function validate_ajax(obj) { 756// /ajax validate ============================================ 757 758// file upload ============================================== 759/** 760 * file uploader 761 * upload both to specific server location or email attachement 762 * drag and drop interface 763 * 764 * see ../php/shortcodes-form-2.php [file2] 765 */ 766jQuery(document).ready(function($) { 767 if (typeof $('.file-uploader-container') != 'undefined') {
768 $('.file-uploader-container').each(function($k,$v){ 769 $obj = $(this); 770 var $id = $obj.attr('data-id');//console.log('$id:',$id); 771 var $data_id = $obj.attr('data-id');//console.log('$data_id:',$data_id); 772 var $imgsrc = $obj.find('img').attr('src');//console.log('$imgsrc:',$imgsrc); 773 var $init_string = $('#'+$data_id+'-file-upload-display-name').html();//console.log('$init_string:',$init_string); 774 775 // show initial image 776 if (!empty($imgsrc)) { 777 $id.show(); 778 }// /if (!empty($imgsrc)) { 779 780 // drop on file input 781 $('#'+$data_id).on('dragover',false).on('drop',function($e){ 782 var $files = $e.originalEvent.dataTransfer.files;//console.log($files); 783 file_upload_set($files,$data_id); 784 }); 785 786 $('#'+$data_id+'-div .file-upload-reset').on('click',function($e){ 787 file_upload_reset($e,$data_id,$init_string,$imgsrc); 788 }); 789 790 $obj.find('.bn_delete').on('click',function($e){ 791 file_upload_delete($e,$data_id,$itempath,$copypath) 792 }); 793 });// /$('.file-uploader-container').each(function($k,$v){ 794 }// /if (typeof $('.file-uploader-container') != 'undefined') { 795});// /jQuery(document).ready(function($) { 796 797/** 798 * file_upload_set() 799 * 800 */ 801function file_upload_set($files,$data_id) { 802 //console.log('$files:',$files); 803 //console.log('$data_id:',$data_id); 804 jQuery(document).ready(function($) { 805 var $name = $files[0]['name'];//console.log($name); 806 $('#'+$data_id+'-file-upload-display-name').show().html($name); 807 //for(var $n = 0; $n < $files.length; $n++) {console.log($n+':'+$files[$n].name);} 808 809 // image upload ===== 810 if ( 811 typeof $files[0]['type'] != 'undefined' 812 && $files[0]['type'].search(/image/i) > -1 813 ) { 814 var reader = new FileReader(); 815 reader.onload = function ($e) { 816 $('#'+$data_id+'-file-upload-img-container').show(); 817 $('#'+$data_id+'-file-upload-img-container img').attr('src',$e.target.result); 818 } 819 //reader.readAsDataURL(e.target.files[0]); 820 reader.readAsDataURL($files[0]); 821 } 822 // /image upload ===== 823 824 $('#'+$data_id+'-div .file-upload-reset').show(); 825 });// /jQuery(document).ready(function($) { 826}// /function file_upload_set() { 827 828/** 829 * file_upload_reset() 830 * 831 */ 832function file_upload_reset($e,$data_id,$init_string,$imgsrc) { 833 jQuery(document).ready(function($) { 834 $e.preventDefault(); 835 $('#'+$data_id+'-file-upload-display-name').html($init_string); 836 $('#'+$data_id).val('');// this is the ONLY value that can be set with js for an input[type="file"] 837 $('#'+$data_id+'-file-upload-img-container img').attr('src',$imgsrc); 838 $('#'+$data_id+'-div .file-upload-reset').hide(); 839 });// /jQuery(document).ready(function($) { 840}// /function file_upload_reset() { 841 842/** 843 * file_upload_delete() 844 * 845 */ 846function file_upload_delete($e,$data_id,$itempath,$copypath) { 847 jQuery(document).ready(function($) { 848 //var $_this = $(this); 849 var $_this = $e.target; 850 $e.preventDefault(); 851 if (confirm('Are you SURE you want to delete this???')) { 852 $imgsrc = ''; 853 $url = './';// see shared.php 854 $postdata = { 855 'process':'delete_collateral', 856 'item':$itempath, 857 'copypath':$copypath, 858 'ajax':true, 859 }; 860 //console.log('$postdata:',$postdata); 861 862 $.post($url,$postdata).done(function($data) { 863 console.log($data); 864 if ( 865 $data.hasOwnProperty('deleted') 866 && $data['deleted'] == true 867 ) { 868 $('#'+$data_id+'-div .file-upload-reset').click(); 869 $_this.hide(); 870 } 871 else { 872 alert('There was a problem with your request.'); 873 } 874 },'json').fail(function(xhr,status,error){ 875 console.log('xhr:',xhr); 876 console.log('status:',status); 877 console.log('error:',error); 878 }); 879 }// /if (confirm 880 });// /jQuery(document).ready(function($) { 881}// /function file_upload_delete() { 882// /file upload ============================================== 883 884// generate password ======================================== 885/** 886 * generate_password() 887 * 888 */ 889jQuery(document).ready(function($) { 890 $('.gen-pswd').on('click',function($e){ 891 $e.preventDefault(); 892 generate_password($e,$(this)); 893 }); 894});// /jQuery(document).ready(function($) { 895function generate_password($e,$obj) { 896 jQuery(document).ready(function($) { 897 var $id = $obj.attr('data-id').replace('.','\\\.');// in case of id like: tablename.colname 898 var $url = './'; 899 var $args = { 900 'process':'ajax_pswd_gen',// in shared.php 901 'length':9, 902 'strength':10, 903 } 904 $.post($url,$args).done(function($data) { 905 //console.log('$data:',$data); 906 //console.log('$id:',$id); 907 if ($data.hasOwnProperty('pswd')) { 908 var $css_hide = { 909 'color':'rgba(0,0,0,0)', 910 'transition':'color 200ms', 911 }; 912 var $css_show = { 913 'color':'rgba(0,0,0,1)', 914 }; 915 916 var $newpswdmsg = '<div><i>Randomly generated password:</i></div><p><strong style="display:none;">'+$data['pswd']+'</strong></p>'; 917 $('#'+$id+'-gen-result').html($newpswdmsg); 918 $('#'+$id+'').val($data['pswd']).css($css_hide); 919 $('#'+$id+'_confirm').val($data['pswd']).css($css_hide); 920 $('#'+$id+'').focus(); 921 $('#'+$id+'_confirm').focus(); 922 $('#'+$id+'-gen-result strong').fadeIn('fast',function(){ 923 $('#'+$id+'').css($css_show); 924 $('#'+$id+'_confirm').css($css_show); 925 }); 926 } 927 },'json');// /$.post( 928 });// /jQuery(document).ready(function($) { 929}// /function generate_password() { 930 931// optimize images ======================================== 932/** 933 * optimage() 934 * 935 */ 936document.addEventListener('DOMContentLoaded', (event) => { 937 //console.log('DOM fully loaded and parsed'); 938 window.onresize = optimage; 939 optimage(); 940}); 941 942// optimize images ======================================== 943/** 944 * optimage() 945 * 946 */ 947document.addEventListener('DOMContentLoaded', (event) => { 948 //console.log('DOM fully loaded and parsed'); 949 window.onresize = optimage; 950 optimage(); 951}); 952 953function optimage() { 954 var optimages = document.querySelectorAll('.optimage img')
955 optimages.forEach(function(optimg) { 956 if (optimg.hasAttribute('srcset')) { 957 var srcset; 958 if (optimg.hasAttribute('srcset2')) { 959 srcset = optimg.getAttribute('srcset2'); 960 } else { 961 srcset = optimg.getAttribute('srcset'); 962 optimg.setAttribute('srcset2', srcset); 963 optimg.srcset = ""; 964 } 965 var sources = srcset.split(', ').map(e => e.split(' ')); 966 sources.forEach(function (source, index) { 967 sources[index][1] = Number(sources[index][1].substring(0, sources[index][1].length - 1)) 968 }) 969 sources.sort(function (a, b) { 970 return b[1] - a[1] 971 }); 972 var containerw = optimg.closest('.optimage').offsetWidth; 973 var containerh = optimg.closest('.optimage').offsetHeight; 974 var optimgwidth = optimg.getAttribute('width'); 975 var optimgheight = optimg.getAttribute('height'); 976 var optimgratio = optimgheight / optimgwidth; 977 var zoomlevel = 0 978 979 while (sources[zoomlevel][1] > containerw && optimgratio * sources[zoomlevel][1] > containerh) { 980 //console.log(zoomlevel, containerw, sources[zoomlevel][1]); 981 if (zoomlevel === sources.length - 1) break; 982 if (containerw < sources[zoomlevel + 1][1] && containerh < sources[zoomlevel + 1][1] * optimgratio) { 983 zoomlevel = zoomlevel + 1; 984 } else { 985 break 986 } 987 } 988 //console.log(containerw + ": " + sources[zoomlevel]); 989 zoomlevel = Math.max(0, Math.min(zoomlevel, sources.length - 1)) 990 if (optimg.src !== sources[zoomlevel][0]) optimg.src = sources[zoomlevel][0]; 991 } 992 }) 993} 994 995 996 997// /generate password ======================================== 998 999/** 1000 * password_chars_showhide() 1001 * show/hide the characters in a password input 1002 */ 1003jQuery(document).ready(function($) { 1004 $(document).on('click','.show-pswd',function($e){ 1005 $e.preventDefault(); 1006 password_chars_showhide($(this)); 1007 }); 1008});// /jQuery(document).ready(function($) { 1009function password_chars_showhide($obj) { 1010 $obj.toggleClass('active'); 1011 var $pswd_field = $obj.closest('.pswd-container').find('.password'); 1012 if ($pswd_field.attr('type') === 'password') { 1013 $pswd_field.attr('type','text'); 1014 } 1015 else { 1016 $pswd_field.attr('type','password'); 1017 } 1018 $pswd_field.focus(); 1019} 1020 1021// prevent form submission double-clicking =============================== 1022/** 1023 * prevent_double_click() 1024 * stop accidental or purposeful multiple clicks on submit buttons and other form submission types 1025 * 1026 * NOTE: DO NOT DISABLE THE SUBMIT BUTTON, 1027 * will break submissions that require the name of the submit button!!!!! 1028 * Instead, set a data-disabled attr. 1029 */ 1030jQuery(document).ready(function($) { 1031 $("form").each(function($k,$v) { 1032 $_this = $(this); 1033 prevent_double_click($k,$v,$_this); 1034 });// /$("form").each(function($k,$v) { 1035});// /jQuery(document).ready(function($) { 1036function prevent_double_click($k,$v,$_this) { 1037 jQuery(document).ready(function($) { 1038 1039 // enter key 1040 $_this.keypress(function($e){ 1041 if($e.which == 13) { 1042 // sets the data-disabled attr on the form itself. 1043 if ($_this.attr('data-disabled')) { 1044 $e.preventDefault(); 1045 return false; 1046 } 1047 $_this.attr('data-disabled','disabled'); 1048 setTimeout(function(){$_this.removeAttr('data-disabled');},1000); 1049 console.log('form submitted'); 1050 }// /if($e.which == 13) { 1051 });// /$_this.keypress(function($e){ 1052 1053 // submit buttons 1054 $_this.submit(function($e){ 1055 // assume regular input submit button 1056 var $submit = $_this.find('input[type="submit"]'); 1057 1058 // if running from an html 5 button instead: 1059 if ($submit.length === 0) {$submit = $_this.find('button[type="submit"]');} 1060 1061 if ($submit.attr('data-disabled')) { 1062 $e.preventDefault(); 1063 return false; 1064 } 1065 $submit.attr('data-disabled','disabled'); 1066 setTimeout(function(){$submit.removeAttr('data-disabled');},1000); 1067 1068 console.log('form submitted'); 1069 });// /$_this.submit(function($e){ 1070 });// /jQuery(document).ready(function($) { 1071}// /function prevent_double_click() { 1072// /prevent form submission double-clicking =============================== 1073 1074// /FORMS =================================================================== 1075 1076 1077// WORDPRESS additions/overwrites ========================================== 1078// NOTE: these additions are a moving target, so try not to rely on them 1079 1080/** 1081 * hide_featured_img() 1082 * if an image/cover is in the page with a class of "featured" remove any featured image that may be set 1083 * either manually or via shortcode [featured_image] 1084 * mainly useful for [featured_image use_default_img="true"], see shortcodes php for settings 1085 */ 1086hide_featured_img(); 1087function hide_featured_img() { 1088 jQuery(document).ready(function($) { 1089 if ( 1090 $('.wp-block-cover.featured').length 1091 || $('.wp-block-image.featured').length 1092 ) { 1093 $('.wp-block-post-featured-image').hide(); 1094 } 1095 });// /jQuery(document).ready(function($) { 1096}// /function hide_featured_img() { 1097 1098/** 1099 * remove empty p tags 1100 */ 1101jQuery(document).ready(function($) { 1102 $('p:empty').remove(); 1103});// /jQuery(document).ready(function($) { 1104 1105/** 1106 * file_buttons() 1107 * add classes for file buttons 1108 */ 1109file_buttons(); 1110function file_buttons() { 1111 jQuery(document).ready(function($) {
1112 $('a.wp-block-file__button').each(function($k,$v){ 1113 //console.log('$(this).attr(\'href\'):',$(this).attr('href')); 1114 if (stripos($(this).attr('href'),'.xls') !== false) { 1115 $(this).addClass('xls'); 1116 $(this).text('Excel'); 1117 } 1118 if (stripos($(this).attr('href'),'.pdf') !== false) { 1119 $(this).addClass('pdf'); 1120 $(this).text('PDF'); 1121 } 1122 if (stripos($(this).attr('href'),'.doc') !== false) { 1123 $(this).addClass('doc'); 1124 $(this).text('Doc'); 1125 } 1126 });// /$('.wp-block-file__button').each(function($k,$v){ 1127 // NOTE: initially hidden in ../css/style.css 1128 // $('a.wp-block-file__button').attr('style','display:inline-block !important'); 1129 });// /jQuery(document).ready(function($) { 1130}// /function file_buttons() { 1131 1132/** 1133* wrappers_inner() 1134* add inner div wrappers to select elements 1135*/ 1136jQuery(document).ready(function($) { 1137 wrappers_inner(); 1138});// /jQuery(document).ready(function($) { 1139function wrappers_inner() { 1140 jQuery(document).ready(function($) { 1141 // $('.wp-block-column').wrapInner('<div class="wp-block-column-inner"></div>'); 1142 });// /jQuery(document).ready(function($) { 1143}// /function wrappers_inner() { 1144 1145/** 1146* wrappers_outer() 1147* add outer div wrappers to select elements 1148* 1149*/ 1150jQuery(document).ready(function($) { 1151 wrappers_outer(); 1152});// /jQuery(document).ready(function($) { 1153function wrappers_outer() { 1154 jQuery(document).ready(function($) { 1155 });// /jQuery(document).ready(function($) { 1156}// /function wrappers_outer() { 1157// /WORDPRESS additions/overwrites ==========================================
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.