1/* 2 CMS Javascript Editing Tools [2018-10-10] 3 - the intention is to consolidate CMS Javascript files as follows: 4 - Any variables you need from $ACS[] or $params to be set in page using set_php_vars(); 5 - N.B. to set HTMLEditor to show by default see showEditorFields below 6 - N.B. to configure HTMLEditor toolbar see ckCMS.js 7 - N.B. See [https://vm7.ehaus2.co.uk/ifrro/page/member-details/] for working example 8 9*/ 10/* ******************************************************************************/ 11// /<![CDATA[ 12 $(document).ready(function(){ 13 14 // POPOVER (tooltips) 15 $(".icon-info-sign,.fa-info-circle").popover({ 16 placement:'top', 17 trigger: 'hover', 18 html: true 19 }); 20 21 /* DATEPICKERS */ 22 $(".datepicker").each(function(){ 23 var $this = $(this); 24 //console.log($this.data('date-format')); 25 $this.datepicker({ 26 format: ($this.data('date-format')) ? $this.data('date-format') : 'dd MM yyyy' 27 }); 28 }); 29 30 // TOGGLE TABS 31 if($('#common').length){ 32 33 var dbm = $("body").data("dbm") ; 34 var ref_no = $("body").data("user-ref") ; 35 36 $('a[data-toggle="tab"]').on('show.bs.tab', function(event) 37 { 38 //console.log(event); 39 var _tab_id = event.relatedTarget.href.split('#')[1]; 40 var _form_id = $("#"+_tab_id).children("form").attr('id'); 41 42 if(_form_id !== undefined) 43 { 44 if(!validate(_form_id)) 45 { 46 event.preventDefault(); 47 } 48 else 49 { 50 $("#idx").val('N'); 51 var _pairs = $("#common").serialize(); 52 PrepareSave(_form_id); 53 //destroyEditor(); 54 form_submit('#'+_form_id, _pairs); 55 get_data(ref_no, dbm); 56 } 57 } 58 59 }); 60 } 61 62 // ACS forms feedback 63 $('.invalid-feedback').each(function() { 64 65 $feedback = $(this); 66 //console.log($feedback.html()); 67 if ($feedback.html().match(/[a-z]/i)) { 68 //$feedback.siblings('input').addClass("is-invalid"); 69 } 70 71 }); 72 // ==== 73 74 // ACS Login 75 $('#btn-login').on('click',function() 76 { 77 var _form_id = $(this).closest('form').attr('id'); 78 $('#'+_form_id).submit(); return false; 79 80 }); 81 // ==== 82 83 // ACS Login 84 $('#btn-register').on('click',function() 85 { 86 var _form_id = $(this).closest('form').attr('id'); 87 $('#'+_form_id).submit(); return false; 88 89 }); 90 // ==== 91 92 // show/hide password 93 $('.fa-password').on('click',function() { 94 $(this).toggleClass("fa-eye-slash"); 95 var x = $(this).parents('.input-group').find('input'); 96 if (x.attr('type') === "password") { 97 x.attr('type', 'text'); 98 } else { 99 x.attr('type', 'password'); 100 } 101 }); 102 103 // REQUEST NEW PASSWORD 104 $('.new-password').on('click', function(event) 105 { 106 event.preventDefault(); 107 var _form_id = $(this).closest('form').attr('id'); 108 $('#'+_form_id).submit(); return false; 109 110 }); 111 112 // CHANGE PASSWORD BUTTON 113 $('.change-password').on('click', function(event) 114 { 115 event.preventDefault(); 116 if ($(this).hasClass('disabled')) { 117 return true; 118 } 119 120 var data = get_form( ['#password-form'] ); 121 //console.log(data); 122 123 $('#responsemsg').html('').hide(); 124 $('#errormsg').html('').hide(); 125 $('#loading').show(); 126 127 var callback = function(response){ 128 form_submit_results(response); 129 }; 130 var url = "lib/acs/acs-proxy.php"; 131 ajax_search(url, data, callback); 132 133 134 }); 135 136 // FORGOT PASSWORD 137 $('.forgot').on('click', function(event) 138 { 139 event.preventDefault(); 140 var eml = '?eml=' + $('#login-username').val(); 141 var rurl = give_me_a_baseref() + 'page/acs-new-password/' + eml; 142 window.location = rurl; 143 return false; 144 145 }); 146 147 if (document.URL.includes("acs-new-password") ) { 148 149 $('#login-username').val( getParameterByName('eml') ); 150 } 151 152 153 /* DROPDWON SELECT BOXES 154 <input type="hidden" data-select="field" name="fv_<?php echo $field;?>" id="fv_<?php echo $field;?>" value=""> 155 <input type="hidden" data-select="code" name="fv_<?php echo $field;?>_code" id="fv_<?php echo $field;?>_code" value="" > 156 <select class="md-form form-control auto-select" data-select-id="mdb"> 157 <?php require('include/Options_Country.inc'); ?> 158 </select> 159 */ 160 $('.auto-select').on('click', function(event) 161 { 162 163 var code = $(this).val(); 164 var name = $(this).find('option:selected').attr('id');
165 $(this).siblings('input:hidden').each(function(){ 166 167 if( $(this).data('select') == 'field' ){ 168 $(this).val(name); 169 }else if( $(this).data('select') == 'code' ){ 170 $(this).val(code); 171 } 172 173 }); 174 175 }); 176 177 }); // END Document Ready 178 179// ]]> 180 181 182/* ******************************************************************************/ 183 function form_submit(frm, pairs, response_handler, redirect_url){ 184 185 //console.log('form_submit:: frm:[' + frm + '] ' + 'pairs:[' + pairs + '] ' + 'redirect_url:[' + redirect_url + '] ' + 'response_handler:[' + response_handler + '] '); 186 var params = ""; 187 188 if (frm.indexOf("#") < 0) { frm = '#' + frm; } 189 if(frm != '' && !empty($(frm))){ 190 191 $(':input', frm).each(function(){ 192 //console.log('id: [' + $(this).attr('id') + '] val: [' + $(this).val() + ']' + '] name: [' + $(this).attr('name') + ']'); 193 var inputID = $(this).attr('id'); 194 var inputName = $(this).attr('name'); 195 var inputRel = $(this).attr('rel'); 196 var inputVal = $(this).val(); 197 198 if(!empty(inputName)){ 199 200 inputName = inputName.toLowerCase(); 201 if(!empty(inputRel)){ 202 203 params = params + inputName + "|" + inputRel + "=" + encodeURIComponent(inputVal) + "&" ; 204 205 } else { 206 //we have no rel meaning its a normal text field 207 params = params + inputName + "=" + encodeURIComponent(inputVal) + "&" ; 208 } 209 //console.log('form_submit: inputID:[ ' + inputID + '] inputName:[' + inputName + '] inputRel:[ ' + inputRel + ' ] inputVal:[ ' + inputVal + ' ]'); 210 211 }else{ 212 //console.log('form_submit: inputName: [' + typeof inputName + ']'); 213 //console.log('form_submit: inputID:[ ' + inputID + '] inputName:[' + inputName + '] inputRel:[ ' + inputRel + ' ] inputVal:[ ' + inputVal + ' ]'); 214 215 } 216 217 }); 218 219 //remove the trailing & 220 params = params.substring(0,params.length -1); 221 222 if(pairs != "") { 223 params = params + "&" + pairs; 224 } 225 226 }else{ 227 //console.log('form_submit:: pairs: [' + pairs + ']'); 228 params = pairs; 229 } 230 231 //console.log('form_submit:: params: [' + params + ']'); 232 if(!params){ 233 alert('You need to submit some params!'); 234 return false; 235 } 236 237 238 //console.log('form_submit:: params: [' + params + ']'); 239 240 $('#messages').addClass('alert alert-info').show(); 241 $('#responsemsg').html('').hide(); 242 $('#errormsg').html('').hide(); 243 $('#loading').show(); 244 $('#message').html('<img src="' + give_me_a_baseref() + 'img/nicerloading.gif" id="loading" /> Please wait').show(); 245 246 if(empty(response_handler)){ 247 response_handler = form_submit_results; 248 } 249 250 var callback = function(response){ 251 response_handler(response, redirect_url, params); 252 }; 253 254 ajax_search('', params, callback); 255 256 257 } 258 259/* ******************************************************************************/ 260 function form_submit_results(json, redirect_url){ 261 262 $('#loading').hide(); 263 //console.log('form_submit_results: ', json.response); 264 265 var $logfile = !empty(json.response.logfile) ? json.response.logfile : ''; 266 267 if(json.response.error_code == 0 || json.response.error_code == ''){ 268 269 //console.log("submitForm: success:: " + json.response.error_code); 270 //$('#'+json.response.div).html(json.response.text).fadeIn("slow"); 271 $('#messages').removeClass().addClass('alert alert-success'); 272 $('#message').html('<span class="icon-ok"></span> ' + json.response.error_msg); 273 $('html, body').animate({scrollTop: 0}, 900, 'swing'); 274 275 var $div = (json.response.div) ? json.response.div : 'responsemsg' ; 276 if(json.response.text != "" ){ 277 278 $('#'+$div).html(json.response.text).fadeIn("slow"); 279 280 } 281 282 if(!empty(redirect_url)){ 283 284 //console.log('redirect new:' + redirect_url); 285 setTimeout(function(){ redirect(redirect_url) }, 1000); 286 287 } 288 if( !empty($logfile) ) { 289 290 $('#responsemsg').append(' <a href="#" onclick="openWindow(\'../logprocess.php?log=' + $logfile + '\', \'Log process\', 675, 700);">View log</a>'); 291 $('.subnav-container').css('background-color', '#fbeed5'); 292 293 } 294 295 }else{ 296 297 //alert('something is wrong!'); 298 $('#messages').removeClass().addClass('alert alert-danger'); 299 $('#message').html('<span class="icon-remove"></span> Process was not completed.'); 300 $('#errormsg').html(json.response.error_msg).fadeIn("slow"); 301 302 } 303 304 } 305 306/*******************************************************************************/ 307/* 308 DEFAULTS: POST to "lib/acs/acs-proxy.php" expecting 'xml' response 309 310 @load_url: e.g. 'include/xmla-elastic.php' - give_me_a_baseref() will add root 311 @params: e.g. &name=value pairs 312 @callback: name of function to handle the Ajax success / fail response 313 @data_type: [xml|json] defaults to 'xml' for [db.server|db.client|xml.proxy.php] else 'json' 314 @action: [POST|GET] defaults to POST 315 316 e.g. function form_submit(frm, data, query){ 317 318 // handle the frm/data/query stuff 319 320 // set up the response handler 321 var callback = function(response){ 322 form_submit_results(response); 323 }; 324 325 // call the ajax_search function[ ajax_search(url["lib/acs/acs-proxy.php"], $data, callback); ], sends response to callback function 326 ajax_search(url, data, callback); 327 328 } 329 330*/ 331 function ajax_search(load_url, params, callback, data_type, action){ 332 // assume params already serialized [&name=value etc.] 333 // requires jQuery Ajax Queue v0.1.1 | (c) 2013 Corey Frang | Licensed MIT */ see next 334 335 //console.log('ajax_search', data_type ); 336 /**/ 337 var $dtype = data_type || ''; // N.B. try to make callbacks XML/JSON agnostic see form_subscribe_response() below 338 var $ax = action || 'POST'; // N.B. xmla-elastic.php doesn't accept POSTs - only GET 339 //console.log("ajax_search:" + $dtype + " - ax: " + $ax); 340 341 if( load_url.match('db.server') || load_url.match('db.client') || load_url.match('xml.proxy') ){ 342 343 if(empty($dtype)){ // i.e. if not set in function call params 344 $dtype = 'xml'; 345 } 346 347 } else { 348 349 if(empty($dtype)){ // i.e. if not set in function call params 350 $dtype = 'json'; 351 } 352 } 353 354 $.ajaxQueue({ 355 type: $ax, // POST by default unless set via function call params 356 url: give_me_a_baseref() + ((load_url) ? load_url : "lib/acs/acs-proxy.php"), 357 dataType: $dtype, 358 data: params, 359 success: function(response){ 360 callback(response); 361 }, 362 error: function(xhr, opts, err) { 363 console.log(err); 364 console.log(xhr); 365 $('#messages').removeClass().addClass('alert alert-error').show(); 366 $('#message').html('<span class="icon-remove"></span> Error processing AJAX request (Switch off debug and check console log)').show(); 367 } 368 369 370 }); 371 } 372/* ******************************************************************************/ 373/*! jQuery Ajax Queue v0.1.1 | (c) 2013 Corey Frang | Licensed MIT */ 374(function(e){var r=e({});e.ajaxQueue=function(n){function t(r){u=e.ajax(n).done(a.resolve).fail(a.reject).then(r,r)}var u,a=e.Deferred(),i=a.promise();
374return r.queue(t),i.abort=function(o){if(u)return u.abort(o);var c=r.queue(),f=e.inArray(t,c);return f>-1&&c.splice(f,1),a.rejectWith(n.context||n,[i,o,""]),i},i}})(jQuery); 375/* ******************************************************************************/ 376/* 377 Call one of the new PHP scripts directly - e.g. elastic-indexer.php 378 379*/ 380 function runScript(script_path, params, rid){ 381 382 $('#messages').addClass('alert alert-info').show(); 383 $('#responsemsg').html('').hide(); 384 $('#errormsg').html('').hide(); 385 $('#loading').show(); 386 $('#message').html('<img src="../img/nicerloading.gif" id="loading" /> Please wait').show(); 387 388 //alert(setflag); 389 $.ajaxQueue({ 390 type: "POST", 391 url: script_path, 392 data: params, 393 success: function(xml){ 394 395 $('#loading').hide(); 396 397 var errCode = $("errorcode", xml).text(); 398 var errMsg = $("errormsg", xml).text().replace(/~~/g,' '); 399 var response = $("responsetext", xml).text().replace(/~~/g,' '); 400 var refno = $("ref_no", xml).text(); 401 var rID = $("rid", xml).text(); 402 var title = $("ctitle",xml).text(); 403 var logfile = $("logfile",xml).text(); 404 var msg = $("msg",xml).text(); 405 406 407 if(errCode == '0'){ 408 $('#messages').removeClass().addClass('alert alert-success'); 409 $('#message').html('<span class="icon-ok"></span> Process complete. '); 410 $('#responsemsg').html(response).fadeIn("slow"); 411 412 if(response != "" && rID == "") { 413 $('#responsemsg').html(response).fadeIn("slow"); 414 } else { 415 $("#"+rID).html(response); 416 } 417 if(logfile != '') { 418 $('#responsemsg').append(' <a href="#" onclick="openWindow(\'../logprocess.php?log=' + logfile + '\', \'Log process\', 675, 700);">View log</a>'); 419 $('.subnav-container').css('background-color', '#fbeed5'); 420 } 421 422 }else{ 423 424 $('#messages').removeClass().addClass('alert alert-danger'); 425 $('#message').html('<span class="icon-remove"></span> Process was not completed.'); 426 $('#errormsg').html(errMsg).fadeIn("slow"); 427 $('#responsemsg').html(msg).fadeIn("slow"); 428 429 if(logfile != '') { 430 $('#responsemsg').append(' <a href="#" onclick="openWindow(\'../logprocess.php?log=' + logfile + '\', \'Log process\', 675, 700);">View log</a>'); 431 $('.subnav-container').css('background-color', '#fbeed5'); 432 } 433 434 } 435 436 } 437 }); 438 } 439/* ******************************************************************************/ 440 function get_data(refno, dbm, qs){ 441 442 if(typeof qs == 'undefined'){ qs = '';} 443 var params = "ax=getdata&k=" + refno + "&rid=return&dbm=" + dbm + qs; 444 445 $.ajaxQueue({ 446 type: "POST", 447 url: give_me_a_baseref() + "/lib/acs/acs-proxy.php", 448 dataType: "json", 449 data: params, 450 success: function(json){ 451 452 $('#loading').hide(); 453 454 var errCode = json.response.error_code; 455 var errMsg = json.response.error_msg; 456 var response = json.response.text; 457 var rID = json.response.div; 458 var $data = json.response.data; 459 //console.log('get_data', $data); 460 461 if( typeof $data != 'undefined' && typeof json.response.data.record.acs_address != 'undefined'){ 462 // prefer to keep ACS address field as textarea except for SmartCart Checkout. 463 var lines = (json.response.data.record.acs_address['@cdata']).split("\n"); 464 json.response.data.record.acs_address_line1 = lines.join(", "); 465 466 } 467 468 //console.log(json.response.data); 469 470 if(errCode == 0){ 471 472 //console.log($data); 473 PopulateXML($data); 474 475 } else { 476 477 $('#messages').removeClass().addClass('alert alert-danger').show(); 478 $('#message').html('<span class="icon-remove"></span> Error retrieving data').show(); 479 $('#errormsg').html(errMsg).show(); 480 481 } 482 }, 483 error: function($data){ 484 485 console.log($data); 486 console.error('Error processing ajax request. getData() function.'); 487 $('#messages').removeClass().addClass('alert alert-danger').show(); 488 $('#message').html('<span class="icon-remove"></span> Error processing AJAX request').show(); 489 490 } 491 }); 492 } 493/* ******************************************************************************/ 494 function PrepareSave(_form_id){ 495 496 //console.log('PrepareSave: ', _form_id); 497 498 $(':input',"#"+_form_id).each(function(){ 499 var input_id = $(this).attr('id'); 500 var input_val = $(this).val(); 501 //console.log('PrepareSave:' + input_id); 502 //console.log('before: ', input_val); 503 // Save funny characters as numeric character entities (msp:) 504 input_val = htmlEntity(input_val); 505 //console.log('after: ', input_val); 506 $(this).val(input_val); 507 508 // Save ckEditor content back into textareas 509 var ckeditor = $('#cke_'+input_id); 510 //console.log(ckeditor) 511 if(window.CKEDITOR){ 512 if(CKEDITOR.instances[input_id]){ 513 //alert("i have an instance"); 514 var ckinstance = true; 515 } 516 if(ckinstance){ 517 var data = CKEDITOR.instances[input_id].getData(); 518 var ckdisplay = ckeditor.css('display'); 519 if(ckdisplay != 'none'){ 520 //when we click hide editor it does this all for us already no need to repeat it. 521 data = data.replace('<br type="_moz" />', ''); 522 data = data.replace('[[','<'); 523 data = data.replace(']]','>'); 524 $('#'+input_id).val(data); 525 //console.log('PrepareSave:' + input_id); 526 //console.log('writing: [' + data + '] to ' + input_id ); 527 }else{ 528 data = data.replace('[[','<'); 529 data = data.replace(']]','>'); 530 $('#'+input_id).val(data); 531 } 532 } 533 } 534 }); 535 536 if( typeof CKEDITOR !== 'undefined') { destroyEditor(); } 537 538 } 539
540/* ****************************************************************************************/ 541/* 542 This function will now populate any form input tag with values from the XML supplied 543 e.g. <input type="text" id="fv_grandtotal" value="" rel="node:content"> 544 use the rel="content/items" to specify path to XML element 545 use the id="fv_os_order_item_status_2" to specify XML tag name and index if the xml repeats 546 _sel and _dta boxes must refer to hidden inputs [ see working examples ] 547 .. and be amazed at how neat it is :)!! 548 549*/ 550 function PopulateXML(data) { 551 552 //console.log('PopulateXML'); 553 //console.log(data); 554 //console.log( "PopulateXML(): data: " + data.record.acs_session_id ); 555 556 var fv = {}; 557 var showEditorFields = new Array('fv_message_body_dta', 'fv_cms_text_dta', 'fv_cms_image_thumb_dta','fv_cms_image_full_dta', 'fv_cms_stay_informed_dta', 'fv_cms_notes_dta'); 558 var modalFields = new Array('fv_contributors'); 559 560 // Now go thru the form elements that will need populating 561 $('.acs-form input, .acs-form select, .acs-form textarea').each(function(){ 562 563 var _id = $(this).attr('id'); 564 var _name = $(this).attr('name'); 565 var _rel = $(this).attr('rel'); 566 567 //console.log(_id + '/' + _name + '/' + _rel + '/' ); 568 569 if(_id !== undefined) 570 { 571 _id = _id.toLowerCase(); 572 //console.log('populate:id: ' + _id + ': [' + getElementValue(_id, data, _rel) + ']'); 573 if(_id.indexOf('_sel') != -1){ 574 //console.log(_id); 575 if(getElementValue(_id, data, _rel)){ 576 $(this).attr('data', getElementValue(_id, data, _rel)); 577 } 578 } 579 if(_id.indexOf('_dta') != -1){ 580 //console.log('dta:'+_id); 581 //data = _id.substr(0,_id.indexOf('_dta')); 582 if(getElementValue(_id, data, _rel)){ 583 //console.log('array:'+fv[data]); 584 //console.log(getElementValue(_id, data, _rel)); 585 $(this).html(getElementValue(_id, data, _rel)); 586 } 587 } 588 // end of the drop down 589 if(getElementValue(_id, data, _rel)){ 590 591 592 if( $.inArray(_id, modalFields) !== -1 ) { 593 var $field = _id.replace(/^fv_/, '', _id); 594 //console.log('populate:field: ' + $field + ' id:' + _id); 595 $c = $(data).find($field).html(); 596 $(this).val($c); 597 populate_modal($(data).find($field)); 598 599 }else{ 600 //console.log('populate:id: ' + _id + ': [' + getElementValue(_id, data, _rel) + ']'); 601 //console.log( $(this) ); 602 $(this).val(getElementValue(_id, data, _rel)); 603 $(this).prev().addClass('active'); 604 //console.log( 'eek:' + $(this).val() ); 605 } 606 607 608 }else if(_id.indexOf("_flag") != -1){ 609 610 //console.log("PopulateXML:" + _id); 611 //console.log(data); 612 $(this).val("N"); 613 614 } 615 // ToggleEditor on: consult list of Fields that require to be always showing. 616 if( $.inArray(_id, showEditorFields) !== -1 ) { 617 id = _id.replace(/_dta$/, ''); 618 //console.log('Show:' + id); 619 showEditor(id); 620 } 621 } 622 }); 623 624 activateSelectTags(); 625 626 } 627 628/* ****************************************************************************************/ 629/* 630 Handles _sel and _dta form tags which modify hidden inputs of the same name (minus the tail _sel/_dta) 631 - e.g. <input type="hidden" name="fv_os_item_status_1" id="fv_os_item_status_1" value="Cancelled" rel="node:content/items"> 632 <input type="hidden" name="fv_os_item_status_code_1" id="fv_os_item_status_code_1" value="CANCELLED" rel="node:content/items"> 633 <select class="autoSelector" data="CANCELLED" id="fv_os_item_status_code_1_sel" name="fv_os_item_status_code_1_sel" rel="fv_os_item_status_1"> 634 .. 635 </select> 636 637 Also handles ordinary fv_field_name form elements 638 And repeating elements e.g. item_1 / item_2 / etc. 639 640*/ 641 function getElementValue(id, data, rel){ 642 643 // Set up the keys we need 644 var fv_name = id; 645 646 //console.log( 'oof: ' + arr_get(data, 'record.acs_address.@cdata') ); 647 //console.log('getEV' + id + rel); 648 649 // remove _sel and _dta from textareas and drop-down boxes 650 if(id.indexOf('_sel') != -1){ 651 fv_name = id.replace(/_sel$/, '', id); 652 } 653 if(id.indexOf('_dta') != -1){ 654 fv_name = id.replace(/_dta$/, '', id); 655 } 656 657 // remove prefix fv_ + [ AND NO _sel / _dta ] 658 field_name = fv_name.replace(/^fv_/, '', fv_name); 659 660 // test for _1 / _2 / _3 etc and set idx number (for child arrays) 661 var reg = new RegExp(/_\d{1,2}/); 662 var $matches = (fv_name.match(reg)) ? fv_name.match(reg) : ''; 663 if ( $matches.length > 0 ){ 664 var rep = $matches[0]; 665 var idx = $matches[0].replace(/[_]+/, '') - 1; 666 var field_name = field_name.replace(rep, ''); 667 } else { 668 var idx = ''; 669 } 670 671 672 // try to find the rel attr values which contain node info e.g rel=node:content/items@t
672ype:html 673 var nodes = ''; 674 var info = {}; 675 if(empty(rel)){ 676 rel = $("input,textarea[name='"+fv_name+"']").attr('rel'); 677 } 678 679 //console.log(rel); 680 //console.log('idx [' + idx + '] ' + 'fv_name [' + fv_name + '] ' + 'field_name [' + field_name + '] ' + 'rel [' + rel + '] '); 681 //console.log(data); 682 683 if(!empty(rel)){ 684 var parts = rel.split(/@/); 685 $.each(parts, function(index, item) { 686 info[ item.split(/:/)[0] ] = item.split(/:/)[1] 687 }); 688 } 689 //console.log(info); 690 var ret_str = ''; 691 var path = ''; 692 693 if( !empty(info['node']) ){ 694 path = 'record.' + info['node'] + '.' + idx + '.' + field_name + '.' + info['type']; 695 } else { 696 path = 'record.' + '.' + field_name + '.' + idx + '.' + info['type']; 697 } 698 path = path.replace(/undefined/, '').replace(/\//, '.').replace(/[\.]+/g, '.').replace(/html/, '@cdata').replace(/\.$/, ''); 699 //console.log('path:' + path); 700 701 ret_str = arr_get(data, path); 702 703 var html = ret_str; 704 705 706 if(!empty(html)){ 707 /* EEK! jquery shortens '<p></p>' to '<p/>' - CKEditor disapproves of this and fucks up the HTML! ACTUALLY ALL EMPTY TAGS e.g. <cmsection></cmsection> => <cmsection/> 708 See: http://stackoverflow.com/questions/348736/is-writing-self-closing-tags-for-elements-not-traditionally-empty-bad-practice 709 */ 710 711 // pipe separated field data will come back as an array! 712 if ( Object.toType(html) == 'array' ){ 713 714 html = html.join('|'); 715 //console.log(path);console.log(html); 716 717 } 718 719 // @cdata nodes come back as an object for some reason! 720 if( Object.toType(html) == 'object' ) { 721 722 html = arr_get(html, '@cdata'); 723 //console.log(path);console.log(html); 724 725 } 726 727 //console.log("getElementValue(): html: " + fv_name + " [" + html + "] - " + Object.toType(html)); 728 729 // treat everything as text [amazingly elastic interpreted acs_last_logged_out as long which carried over into javascript - breaking string handling!] 730 if( Object.toType(html) == 'number' ) { 731 732 html = html.toString(); 733 734 } 735 736 // do some tidying - mainly for ckEditor - N.B. .replace only works on Typeof = string 737 if( Object.toType(html) == 'string' ) { 738 739 html = html.replace(/<p\/>/g, '<p></p>'); 740 html = html.replace(/<i\/>/g, '<i></i>'); 741 html = html.replace(/<i ([\s\S]+?)\/>/g, "<i $1><\/i>"); 742 html = html.replace(/<p ([\s\S]+?)\/>/g, "<p $1><\/p>"); 743 html = html.replace(/<span ([\s\S]+?)\/>/g, "<span $1><\/span>"); 744 html = html.replace(/<textarea ([\s\S]+?)\/>/g, "<textarea $1><\/textarea>"); 745 746 // carriage returns stored in elastic as \n but browsers use \r\n :) 747 html = html.replace(/\r?\n/g, "\r\n"); 748 749 //console.log('eek ['+html+"]\r\n"); 750 /* EEK! am i the only one? - a lone '%' will - of course - break decodeURIComponent!!! */ 751 html = html.replace(/%(?![0-9a-fA-F]{2})/, '%25'); 752 //console.log('['+id+']'+' val: [' + html +']'); 753 } 754 755 // OK this converts numerical char entities back into user friendly stuff. See PrepareSave() (msp:) 756 html = decodeHtml(html); 757 } 758 759 if (html){ 760 761 return html; 762 763 /* NOTE!! 764 765 We should move all CMS save_data and get_data to use admin.tools and acs-proxy.php 766 - this uses JSON as a transport method :) 767 - funny characters will be converted on save [See: PrepareSave.htmlEntity()] and stored in XML as numeric character entities 768 - acs-proxy.php update_record uses xml2array() class which escapes all ampersands to & 769 - elasticSearchCGI.php converts & to & [see: output_XML2()] 770 - PopulateXML() also converts numeric entities to ordinary characters [see: getElementValue.decodeHtml()] 771 772 N.B. Data is stored directly into the elastic index, in most cases without using the DOM, so no &'s 773 774 So, we should NOT need to use decodeURIComponent(ret_str); anywhere! 775 776 */ 777 778 779 } else { 780 return false; 781 } 782 783 } 784 785// *****************************************************************************/ 786 function get_form(frms){ 787 788 var id, i, len = frms.length; 789 var data = {}; 790 var form_id = frms.attr('id'); 791 //console.log('get_form: ', form_id); 792 793 PrepareSave(form_id); 794 795 for (i=0; i<len; ++i) { 796 797 id = frms[i]; 798 $(':input', id).each(function(){ 799 //console.log('id: [' + $(this).attr('id') + '] val: [' + $(this).val() + ']' + '] name: [' + $(this).attr('name') + ']'); 800 var input_id = $(this).attr('id'); 801 var input_name = $(this).attr('name'); 802 var input_rel = $(this).attr('rel'); 803 var input_val = $(this).val(); 804 var input_key = ''; 805 806 if(!empty(input_rel)){ 807 808 input_key = input_name + "|" + input_rel; 809 810 } else { 811 812 input_key = input_name; 813 } 814 815 data[input_key] = input_val; 816 817 }); 818 819 } 820 821 return data; 822 823 } 824/* ******************************************************************************/ 825 Object.toType = function(obj) { 826 return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase(); 827 } 828/* ******************************************************************************/ 829/* ******************************************************************************/ 830/* ******************************************************************************/ 831 function MakeExact(str){ 832 833 var ret = ''; 834 var nreg = /(&.{1,5};|@#.{1,5};|\W|\s+)/ig; 835 836 837 if(!empty(str)){ 838 ret = str.replace(nreg, '').substr(0,120).toUpperCase(); 839 } 840 841 return ret; 842 843 } 844
845/* ******************************************************************************/ 846 function isNumber(n) { 847 //should return true if n is a number 848 return !isNaN(parseFloat(n)) && isFinite(n); 849 } 850 851/* ******************************************************************************/ 852 function toTitleCase(str){ 853 return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}); 854 } 855 856/* ******************************************************************************/ 857 function roundNumber(num, dec) { 858 var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec); 859 result = result.toFixed(dec); 860 return result; 861 } 862 863/* ******************************************************************************/ 864 function decodeHtml(html) { 865 var txt = document.createElement("textarea"); 866 txt.innerHTML = html; 867 return txt.value; 868 } 869 870/* ******************************************************************************/ 871 function redirect(url){ 872 873 //console.log('redirecting:' + url); 874 window.location = url ; 875 return false; 876 877 } 878
879/* ******************************************************************************/ 880 function give_me_a_baseref() { 881 882 //Is the location path a script? 883 var _isScript = (location.pathname.split('/')[1]).match(/\./); 884 _isScript = !(_isScript == null); 885 var _barePath = (location.pathname.toString() == "/"); 886 var _protocol = location.protocol; 887 888 return ((location.pathname.split('/')[1] == 'pid')||(location.pathname.split('/')[1] == 'page')||(location.pathname.split('/')[1] == 'book')||(_isScript)||(_barePath) ? '//' + location.hostname + '/' :'//' + location.hostname +'/' + location.pathname.split('/')[1] + '/'); 889 890 } 891 892/* ******************************************************************************/ 893 function getParameterByName(name) { 894 895 name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); 896 var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), 897 results = regex.exec(location.search); 898 return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); 899 900 } 901/* ******************************************************************************/ 902 function parse_str(str) { 903 904 var query = {}; 905 var pairs = (str[0] === '?' ? str.substr(1) : str).split('&'); 906 for (var i = 0; i < pairs.length; i++) { 907 var pair = pairs[i].split('='); 908 query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || ''); 909 } 910 return query; 911 } 912/* ****************************************************************************************/ 913// Magic returns values from the XML Obj from a string e.g. arr_get(data, 'CONTENT.ITEMS.OS_ITEM_STATUS_CODE[2]') 914 arr_get = function(o, s) { 915 916 s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties 917 s = s.replace(/^\./, ''); // strip a leading dot 918 var a = s.split('.'); 919 for (var i = 0, n = a.length; i < n; ++i) { 920 var k = a[i]; 921 //console.log( "k: " + Object.toType(k) + " o: " + Object.toType(o) ); 922 if( Object.toType(o) == 'string' ){ 923 console.log('arr_get: Type error. [e.g. Form specifies type:HTML, but data is missing @cdata node]'); 924 console.log(s); 925 console.log(o); 926 return; 927 } 928 if (k in o) { 929 o = o[k]; 930 } else { 931 return; 932 } 933 } 934 return o; 935 } 936/* *****************************************************************************/ 937 function htmlEntity(txt, tags) { 938 // Set tags to 1 for '<' instead of '<' and & instead of '&' 939 // Set tags to 2 for for '<' instead of '<' 940 if(!tags){ tags == 0}; 941 var aa = txt; 942 //console.log('htmlEntity: [' + typeof txt + ']'); 943 if(typeof txt !== 'object'){ 944 var bb = ''; 945 for (var i = 0; i < aa.length; i++) { 946 bb += hEnt(aa.charAt(i),tags); 947 } 948 //console.log('bb1: ' + bb); 949 bb = bb.replace(/&/ig, '&'); 950 bb = bb.replace(/(&)(\w)/ig, '&$2'); 951 bb = bb.replace(/(&)(\s)/, '&$2'); 952 bb = bb.replace(/(&$)/, '&'); 953 //console.log('bb2: ' + bb); 954 return bb; 955 } 956 } 957 958 function hEnt(d, tags) { 959 960 //* HTML entity */ 961 if (tags == 2) { 962 if (d == '<'){return '<'}; 963 if (d == '>'){return '>'}; 964 } 965 if (tags == 1) { 966 if (d == '<'){ return '<'} ; 967 if (d == '>'){return '>'}; 968 if (d == '&'){return '&'}; 969 } 970 if (d == '\''){ return '''} ; 971 if (d.charCodeAt(0) > 127) { 972 return '&#' + d.charCodeAt(0) + ';'; 973 } 974 return d; 975 976 } 977 978/* ******************************************************************************/ 979 function empty( val ) { 980 981 // test results 982 //--------------- 983 // [] true, empty array 984 // {} true, empty object 985 // null true 986 // undefined true 987 // "" true, empty string 988 // '' true, empty string 989 // 0 false, number 990 // true false, boolean 991 // false false, boolean 992 // Date false 993 // function false 994 995 if (val === undefined ) 996 return true; 997 998 if (typeof (val) == 'function' || typeof (val) == 'number' || typeof (val) == 'boolean' || Object.prototype.toString.call(val) === '[object Date]') 999 return false; 1000 1001 if (val == null || val.length === 0) // null or 0 length array 1002 return true; 1003 1004 if (typeof (val) == "object") { 1005 // empty object 1006 1007 var r = true; 1008 1009 for (var f in val) 1010 r = false; 1011 1012 return r; 1013 } 1014 1015 return false; 1016 } 1017 1018/* ******************************************************************************/ 1019 function padz(n, totalDigits) { 1020 n = n.toString(); 1021 var pd = ''; 1022 if (totalDigits > n.length) 1023 { 1024 for (i=0; i < (totalDigits-n.length); i++) 1025 { 1026 pd += '0'; 1027 } 1028 } 1029 return pd + n.toString(); 1030 } 1031
1032/* ******************************************************************************/ 1033 function trunc(str){ 1034 var n = ""; 1035 1036 if(typeof str != 'undefined'){ 1037 1038 n = str.indexOf("|") 1039 if(n > 0) { 1040 str = str.slice(0, n); 1041 } 1042 n = str.indexOf("(") 1043 if(n > 0) { 1044 str = str.slice(0, n); 1045 } 1046 n = str.indexOf("[") 1047 if(n > 0) { 1048 str = str.slice(0, n); 1049 } 1050 1051 } else { 1052 1053 str = ''; 1054 1055 } 1056 1057 return str; 1058 } 1059 1060/******************************************************************************/ 1061 function trim(str){ 1062 1063 //str = str.replace(/^\s+|\s+$/g, ""); // whitespace 1064 //console.log("trim in ["+ str+ "]"); 1065 str = str.replace(/(^[\s,:;\._-]+)|([\s,:;\._-]+$)/g, ""); // commas etc 1066 //console.log("trim out ["+ str+ "]"); 1067 return str 1068 1069 } 1070/******************************************************************************/ 1071/* 1072*/ 1073 function validate_form(frm){ 1074 1075 //console.log('validate_form: ', frm ); 1076 1077 var valid_form = true; 1078 1079 $('.validate').each(function(){ 1080 1081 var input = $(this); 1082 var input_id = input.attr('id') || 'undefined'; 1083 var input_name = input.attr('name'); 1084 var input_type = input.attr('type'); 1085 var input_val = input.val(); 1086 1087 /* 1088 console.log( 1089 "input_id: ["+input_id+"] " + 1090 "input_name: ["+input_name+"] " + 1091 "input_type: ["+input_type+"] " + 1092 "input_val: ["+input_val+"] " 1093 ); 1094 */ 1095 1096 valid_form = validate_this(input); 1097 1098 if(valid_form === false){ 1099 1100 $('#'+input_id).focus(); 1101 return valid_form; 1102 1103 } 1104 1105 1106 1107 }); 1108 1109 return valid_form; 1110 1111 } 1112 1113/******************************************************************************/ 1114/* 1115 1116 @input [class="validate" type="" value="" name="" id="" data-required="[true|false]" data-valid="[Y|N]" etc. 1117 Typical HTML: Please set type / name=fv_ / id 1118 1119 <?php $field_label = "Title"; $field_name = "ctitle"; $placeholder="placeholder_text" ?> 1120 <div class="md-form"> 1121 <label for="<?php echo $field_name; ?>"><span class="fas fa-info-circle" data-content="" title="<?php echo $field_label; ?>"></span><?php echo $field_label; ?>:</label> 1122 <input class="form-control validate mb-0" type="text" name="fv_<?php echo $field_name; ?>" id="<?php echo $field_name; ?>" placeholder="<?php echo $placeholder;?>" value="" data-required="true" data-valid="N" data-maxlength="" data-pattern=""> 1123 <div class="invalid-feedback"></div> 1124 </div> 1125 1126 N.B. if data-required="true" then set data-valid="N" to initialise the test. 1127 N.B. if data-required="false" then set data-valid="" to skip the test. 1128 1129*/ 1130 function validate_this(input){ 1131 1132 //console.log('acs.tools.js::validate_this'); 1133 //console.log('validate_this:', input ); 1134 1135 var $data = {}; 1136 var input_id = input.attr('id') || 'undefined'; 1137 var input_name = input.attr('name'); 1138 var input_type = input.attr('type'); 1139 var input_val = input.val(); 1140 var valid_input = true; 1141 1142 if(typeof input_name !== 'undefined'){ 1143 1144 /* 1145 console.log( 1146 "input_id: ["+input_id+"] " + 1147 "input_name: ["+input_name+"] " + 1148 "input_type: ["+input_type+"] " + 1149 "input_val: ["+input_val+"] " 1150 ); 1151 */ 1152 1153 var key = input_name.toLowerCase(); 1154 var checked = input.is(":checked"); 1155 $data[key] = { 1156 1157 'type': input.attr('type'), 1158 'name': input.attr('name'), 1159 'id': input.attr('id'), 1160 'checked': checked, 1161 'val': input.val() 1162 1163 }; 1164 1165 // PATTERN 1166 if( $data[key]['type'] == 'text' && !empty(input.data('pattern')) ){ 1167 1168 // You have to specify type & name in the form otherwise they are undefined 1169 /* N.B. 'g' flag can cause odd results so best specify full ^pattern$ */ 1170 //console.log('pattern: ', input.data('pattern')); 1171 $ptrn = new RegExp("" + input.data('pattern') + "", ""); 1172 $txt = $data[key]['val']; 1173 //console.log('testing: ', $ptrn.test($txt)); 1174 1175 if( $ptrn.test($txt) !== true){ 1176 // negative pattern - we've matched an unwanted character; 1177 //console.log('invalid reason: [pattern]', $ptrn); 1178 input.removeClass('is-valid valid').addClass('is-invalid'); 1179 $("#"+input_id).attr('data-valid', 'N'); 1180 valid_input = false; 1181 return valid_input; 1182 1183 } else { 1184 //console.log('yay: ', $ptrn); 1185 input.removeClass('is-invalid').addClass('is-valid'); 1186 $("#"+input_id).attr('data-valid', 'Y'); 1187 1188 } 1189 1190 } 1191 1192 1193 // Check for data-MAXLENGTH: 1194 if( !empty(input.data('maxlength')) && input_val.length > input.data('maxlength') ){ 1195 1196 if(!empty(input.data('maxlength'))){ 1197 1198 if( input_val.length > input.data('maxlength') ){ 1199 1200 //console.log('invalid reason: [maxlength]', input_val.length + ' / ' + input.data('maxlength')); 1201 input.removeClass('is-valid valid').addClass('is-invalid'); 1202 //input.siblings('div').html('Maximum number of characters is ' + input.data('maxlength')); 1203 $("#"+input_id).attr('data-valid', 'N'); 1204 valid_input = false; 1205 return valid_input; 1206 1207 } else { 1208 1209 input.removeClass('is-invalid').addClass('is-valid'); 1210 $("#"+input_id).attr('data-valid', 'Y'); 1211 1212 } 1213 } 1214 1215 } 1216 1217 // SPECIAL FIELD TYPE:TEXT - ISBN
1218 if( $data[key]['type'] == 'text' && input_id.match(/barcode/gi ) ){ 1219 1220 if( !valid_isbn(input_val) ){ 1221 1222 console.log('invalid reason: [ISBN] [' + input_val + ']' + '[' + input_id + ']'); 1223 input.removeClass('is-valid valid').addClass('is-invalid'); 1224 $("#"+input_id).siblings('div').html('Not a valid ISBN.'); 1225 $("#"+input_id).attr('data-valid', 'N'); 1226 valid_input = false; 1227 return valid_input; 1228 1229 }else{ 1230 1231 //console.log('good email.'); 1232 input.removeClass('is-invalid').addClass('is-valid'); 1233 $("#"+input_id).attr('data-valid', 'Y'); 1234 1235 } 1236 1237 } 1238 1239 // EMAILS: 1240 if( $data[key]['type'] == 'email' ){ 1241 1242 if( !valid_email(input_val) ){ 1243 1244 //console.log('invalid reason: [email] [' + input_val + ']' + '[' + input_id + ']'); 1245 input.removeClass('is-valid valid').addClass('is-invalid'); 1246 $("#"+input_id).siblings('div').html('You need to enter a valid email address so we can contact you.'); 1247 $("#"+input_id).attr('data-valid', 'N'); 1248 valid_input = false; 1249 return valid_input; 1250 1251 }else{ 1252 1253 //console.log('good email.'); 1254 input.removeClass('is-invalid').addClass('is-valid'); 1255 $("#"+input_id).attr('data-valid', 'Y'); 1256 1257 } 1258 1259 } 1260 1261 // CHECKBOXES: 1262 if( $data[key]['type'] == 'checkbox' ){ 1263 1264 $x = ($data[key]['checked']) ? 'Y' : 'N'; 1265 //console.log('checkbox: [' + input_id + '] ' + $x); 1266 input.val($x); 1267 1268 } 1269 1270 // SELECT / OPTION DROPDOWNS +/- REQUIRED 1271 if( $data[key]['type'] === 'select' && input.data('required') == true ){ 1272 1273 //console.log('select: ', input_id); 1274 // You have to specify type & name in the form otherwise they are undefined 1275 if( empty($data[key]['val']) ){ 1276 1277 //console.log('invalid [' + input_id + '] reason: [select required]'); 1278 input.removeClass('is-valid valid').addClass('is-invalid'); 1279 $("#"+input_id).attr('data-valid', 'N'); 1280 valid_input = false; 1281 return valid_input; 1282 1283 } else { 1284 1285 input.removeClass('is-invalid').addClass('is-valid'); 1286 $("#"+input_id).attr('data-valid', 'Y'); 1287 1288 } 1289 1290 } 1291 1292 1293 // NUMERIC (e.g. Telephones) 1294 if( $data[key]['type'] == 'tel' ){ 1295 1296 // See https://regexlib.com:: it is not perfect... 1297 $ptrn = new RegExp(/((\+?44\s?\(0\)\s?\d{2,4})|(\+44\s?(01|02|03|07|08)\d{2,3})|(\+44\s?(1|2|3|7|8)\d{2,3})|(\(\+44\)\s?\d{3,4})|(\(\d{5}\))|((01|02|03|07|08)\d{1,3})|(\d{5}))(\s|-|.)(((\d{3,4})(\s|-)(\d{3,4}))|((\d{6,7})))/); 1298 if( $ptrn.test($data[key]['val']) === true){ 1299 1300 //console.log('tel:valid'); 1301 input.removeClass('is-invalid').addClass('is-valid'); 1302 $("#"+input_id).attr('data-valid', 'Y'); 1303 1304 }else{ 1305 1306 if( empty($data[key]['val']) && input.data('required') == false ){ 1307 1308 //console.log('tel:valid'); 1309 input.removeClass('is-invalid').addClass('is-valid'); 1310 $("#"+input_id).attr('data-valid', 'Y'); 1311 1312 }else{ 1313 1314 console.log('tel:invalid'); 1315 input.removeClass('is-valid valid').addClass('is-invalid'); 1316 if( empty($("#"+input_id).siblings('div').html()) ){ 1317 $("#"+input_id).siblings('div').html('You need to enter a valid telephone number so we can contact you.'); 1318 } 1319 $("#"+input_id).attr('data-valid', 'N'); 1320 valid_input = false; 1321 return valid_input; 1322 1323 } 1324 1325 } 1326 1327 1328 } 1329 1330 // REQUIRED Fields Check for any field with data attribute='REQUIRED' that is empty 1331 if( input.data('required') == true ){ 1332 1333 //console.log('required: ', input_id + ": " + input.data('required') ); 1334 1335 if( empty($data[key]['val']) ){ 1336 1337 //console.log('invalid reason: [required field] ' + key); 1338 $("#"+input_id).removeClass('is-valid valid').addClass('is-invalid'); 1339 $("#"+input_id).siblings('div').html('Field cannot be empty'); 1340 $("#"+input_id).attr('data-valid', 'N'); 1341 valid_input = false; 1342 return valid_input; 1343 1344 } else { 1345 1346 $("#"+input_id).removeClass('is-invalid').addClass('is-valid'); 1347 $("#"+input_id).attr('data-valid', 'Y'); 1348 1349 } 1350 1351 }else{ 1352 1353 $("#"+input_id).removeClass('is-invalid').addClass('is-valid'); 1354 $("#"+input_id).attr('data-valid', 'Y'); 1355 1356 } 1357 1358 // HIDDEN INPUTS 1359 if( $data[key]['type'] != 'hidden' ){ 1360 // purpose is to 'refresh' input boxes after autofill (Chrome) & is quite absurd! 1361 $("#"+input_id).val( $("#"+input_id).val() + '' ); 1362 } 1363 1364 1365 $('textarea').each(function(index){ 1366 $(this).addClass( 'chrome-crap'); 1367 1368 }); 1369 1370 } 1371 1372 //console.log('validate_this:' + input_name + '[' + input_id +']') 1373 return valid_input; 1374 1375 } 1376/******************************************************************************/ 1377 function valid_email(email) { 1378 var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 1379 return re.test(email); 1380 } 1381/*******************************************************************************/ 1382 var valid_isbn = function(str) 1383 { 1384 1385 var sum, 1386 weight, 1387 digit, 1388 check, 1389 i; 1390 1391 str = str.replace(/[^0-9X]/gi, ''); 1392 1393 if (str.length != 10 && str.length != 13) { 1394 return false; 1395 } 1396 1397 if (str.length == 13) { 1398 sum = 0; 1399 for (i = 0; i < 12; i++) { 1400 digit = parseInt(str[i]); 1401 if (i % 2 == 1) { 1402 sum += 3*digit; 1403 } else { 1404 sum += digit; 1405 } 1406 } 1407 check = (10 - (sum % 10)) % 10; 1408 return (check == str[str.length-1]); 1409 } 1410 1411 if (str.length == 10) { 1412 weight = 10; 1413 sum = 0; 1414 for (i = 0; i < 9; i++) { 1415 digit = parseInt(str[i]); 1416 sum += weight*digit; 1417 weight--; 1418 } 1419 check = (11 - (sum % 11)) % 11 1420 if (check == 10) { 1421 check = 'X'; 1422 } 1423 return (check == str[str.length-1].toUpperCase()); 1424 } 1425 } 1426/******************************************************************************/ 1427 function valid_date(d) { 1428 1429 $dte = new Date(d); 1430 //console.log('dte: ' + $dte); 1431 return $dte instanceof Date && !isNaN($dte); 1432 1433 } 1434/*******************************************************************************/ 1435/* COOKIES */ 1436/*******************************************************************************/ 1437/* 1438 e.g. Cookie.set('test', 'Jim', {path: '/', days: 10}); 1439 e.g. Cookie.get('test'): 1440 e.g. Cookie.delete('test'); 1441 1442 domain left blank (which = current host without subdomain). 1443 1444 Also: 1445 Cookie.getJSON = name => JSON.parse(Cookie.get(name)) 1446 Cookie.setJSON = (name, value, opts) => Cookie.set(name, JSON.stringify(value), opts); 1447 1448*/ 1449if( typeof Cookie === 'undefined' ){ // see ehaus.functions.js 1450 1451 const Cookie = { 1452 get: name => { 1453 let c = document.cookie.match(`(?:(?:^|.*; *)${name} *= *([^;]*).*$)|^.*$`)[1] 1454 console.log('acs.tools:Cookie.get::', name + '[' + c + ']'); 1455 if (c) return decodeURIComponent(c) 1456 }, 1457 set: (name, value, opts = {}) => { 1458 1459 console.log('acs.tools:Cookie.set::', name + '[' + value + ']'); 1460 /*If options contains days then we're configuring max-age*/ 1461 if(!opts.days){ opts['days'] = 7; }
1461 // or leave days blank to set Expires:Session 1462 if (opts.days) { 1463 opts['max-age'] = opts.days * 60 * 60 * 24; 1464 delete opts.days 1465 } 1466 1467 /* Set some other defaults */ 1468 if(!opts.path){ opts['path'] = '/'; } 1469 if(!opts.SameSite){ opts['SameSite'] = 'Strict'; } 1470 if(!opts.Secure){ opts['Secure'] = 1; } 1471 1472 /*Configuring options to cookie standard by reducing each property*/ 1473 opts = Object.entries(opts).reduce( 1474 (accumulatedStr, [k, v]) => `${accumulatedStr}; ${k}=${v}`, '' 1475 ) 1476 1477 /*Finally, creating the key*/ 1478 document.cookie = name + '=' + encodeURIComponent(value) + opts 1479 }, 1480 delete: (name, opts) => Cookie.set(name, '', {'days': -1}) 1481 // path & domain must match cookie being deleted 1482 } 1483} 1484/******************************************************************************/ 1485 function display_date_time(action, mod){ 1486 1487 // Set up a dateArray() 1488 var months = "Zero,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec" 1489 var dateArray = new Array(); 1490 dateArray = months.split(","); 1491 var dateHash = new Array(); 1492 for (var n=0; n<dateArray.length; n++) { 1493 dateHash[padz(n, 2)] = dateArray[n]; 1494 } 1495 1496 //console.log(dateHash); 1497 1498 var date = new Date(); 1499 1500 if(!empty(mod)){ 1501 date = date.addDays(mod); 1502 } 1503 var day = date.getDate(); 1504 var month = date.getMonth() + 1; 1505 var year = date.getFullYear() 1506 var hh = date.getHours(); 1507 var mm = date.getMinutes(); 1508 var ss = date.getSeconds(); 1509 1510 //alert(month); 1511 1512 if(action == 'pretty') { 1513 1514 return padz(day, 2) + '/' + padz(month, 2) + '/' + year; 1515 1516 } else if (action == 'vpretty') { 1517 1518 return padz(day, 2) + ' ' + dateHash[padz(month, 2)] + ' ' + year; 1519 1520 } else if (action == 'time') { 1521 1522 return padz(hh, 2) + ':' + padz(mm, 2) + ':' + padz(ss, 2); 1523 1524 } else if (action == 'date') { 1525 1526 return year + '-' + month + '-' + padz(day, 2) ; 1527 1528 } else if (action == 'datetime') { 1529 1530 return year + '-' + month + '-' + padz(day, 2) + 'T' + padz(hh, 2) + ':' + padz(mm, 2) + ':' + padz(ss, 2); 1531 1532 } else if (action == 'yyyymmdd') { 1533 1534 return year + padz(month, 2) + padz(day, 2); 1535 1536 } else { 1537 1538 return year + padz(month, 2) + padz(day, 2); 1539 1540 } 1541 1542 } 1543 1544/* ******************************************************************************/ 1545 1546 Date.prototype.addDays = function(days) { 1547 var date = new Date(this.valueOf()); 1548 date.setDate(date.getDate() + days); 1549 return date; 1550 } 1551 1552/* ******************************************************************************/ 1553 function ResetFlag(refno, field, node){ 1554 1555 /*var setflag = val; // better to get it from the image then you can change it back :) 1556 e.g. for an ehaus node set field = 'ehaus.fv_field_name' OR set node = 'ehaus' otherwise set it to '' 1557 see admin.acs.edit.js for a cooler way to do this :) 1558 1559 */ 1560 if( field.indexOf('.') ){ 1561 // this results in undefined!! ToDO: fix! 1562 //node = field.split('.', 2)[0]; 1563 //field= field.split('.', 2)[1]; 1564 } 1565 1566 node = (node) ? ('|node:' + node) : ''; 1567 1568 var setflag = $('#' + field + '_' + refno).attr('src'); 1569 setflag = setflag.replace('../images/',''); 1570 setflag = setflag.replace('.png',''); 1571 setflag = (setflag == 'Y')?'N':'Y';// alert('['+setflag+']'); 1572 1573 var dbm = get_dbm(); 1574 1575 //alert(setflag); 1576 $.ajaxQueue({ 1577 type: "POST", 1578 url: give_me_a_baseref() + "lib/acs/acs-proxy.php", 1579 dataType: "json", 1580 data: "dbm=" + dbm + "&ax=update&xml=save&k="+refno +"&fv_"+field+node+"="+setflag+"", 1581 success: function(json){ 1582 1583 console.log(json.response); 1584 var errCode = json.response.error_code; 1585 var errMsg = json.response.error_msg; 1586 //var fValue = $('responsetext', xml).text(); //same thing.. 1587 if(errCode == '0'){ 1588 $('#' + field + '_' + refno).attr('src', '../images/'+setflag+'.png'); 1589 1590 }else{ 1591 console.log('eeror: ResetFlag') 1592 //alert(errMsg); 1593 } 1594 1595 } 1596 }); 1597 } 1598 1599/* ******************************************************************************/
1600 function OrderStatusFlag(refno, field, node){ 1601 1602 //var setflag = val; // better to get it from the image then you can change it back :) 1603 var setflag = $('#' + field + '_' + refno).attr('src'); 1604 setflag = setflag.replace('../images/',''); 1605 setflag = setflag.replace('.png',''); 1606 setflag = (setflag == 'Y')?'N':'Y';// alert('['+setflag+']'); 1607 1608 //alert(setflag); 1609 $.ajaxQueue({ 1610 type: "POST", 1611 url: "../include/db.server.php", 1612 data: "admdb=" + admdb_dbm + "&ax=update-xml&fv_ref_no="+refno +"&fv_"+field+"|node:ehaus"+"="+setflag+"&idx=Y", 1613 success: function(xml){ 1614 1615 var errCode = $("errorcode", xml).text(); 1616 var errMsg = $("errormsg", xml).text(); 1617 //var fValue = $('responsetext', xml).text(); //same thing.. 1618 if(errCode == '0'){ 1619 $('#' + field + '_' + refno).attr('src', '../images/'+setflag+'.png'); 1620 1621 }else{ 1622 console.log('error: OrderStatusFlag'); 1623 //alert(errMsg); 1624 } 1625 1626 } 1627 }); 1628 } 1629 1630/* ******************************************************************************/ 1631/* DROPDWON SELECT BOXES 1632 <input type="hidden" class="" data-select="field" name="fv_<?php echo $field;?>" id="<?php echo $field;?>" value="" > 1633 <input type="hidden" data-select="code" name="fv_<?php echo $field;?>_code" id="<?php echo $field;?>_code" value="" > 1634 <select class="md-form md-form-compact form-control auto-select validate" type="select" name="" id="<?php echo $field;?>_code_sel" rel="fv_<?php echo $field;?>" data-valid='N' data-required=true data-maxlength=''> 1635 <?php require('include/Options_Country_Codes.inc'); ?> 1636 </select> 1637 1638 <!-- Form: CHECKBOX - --> 1639 <div class="form-check form-check-plain my-2">
1640 <?php $field = "ship_and_bill_flag"; $label = "Billing address is same as shipping";?> 1641 <input class="autoCheck form-check-input" type="checkbox" checked="checked" id="<?php echo $field; ?>" name="fv_<?php echo $field; ?>" value="Y" /> 1642 <label class="" for="<?php echo $field; ?>" id="<?php echo $field;?>_label"><?php echo $label;?>:</label> 1643 <div class="d-none control-messages"><div class="alert alert-error hidden"></div></div> 1644 </div> 1645 1646 */ 1647 function activateSelectTags() 1648 { 1649 1650 1651 // DROPDWON SELECT BOXES 1652 $('.auto-select').on('click keyup', function(event) 1653 { 1654 1655 var code = $(this).val(); 1656 var name = $(this).find('option:selected').attr('id') || $(this).find('option:selected').text(); 1657 //console.log($(this).attr('id'), 'code:' + code + " name: " + name); 1658 $(this).siblings('input:hidden').each(function(){ 1659 //console.log( $(this).attr('id'), $(this).data('select') + '[' + code + ']' ); 1660 if( $(this).data('select') == 'field' ){ 1661 $(this).val(name); 1662 }else if( $(this).data('select') == 'code' ){ 1663 $(this).val(code); 1664 } 1665 1666 }); 1667 1668 }); 1669 1670 1671 1672 // CHECKBOXES 1673 $('input.autoCheck').unbind('click'); 1674 1675 $('input.autoCheck').each(function () { 1676 var idCheck = $(this); 1677 var idValue = idCheck.attr("id").replace(/_chk$/,""); 1678 //console.log('autoCheck:' + idValue + '[' + idCheck.val() + ']'); 1679 //console.log('autoCheck:x:' + idCheck.prop('checked') + '[' + idCheck.attr('checked') + ']'); 1680 1681 if($('#' + idValue).val() == "Y"){ 1682 idCheck.prop('checked', true); 1683 }else{ 1684 idCheck.prop('checked', false); 1685 $('#' + idValue).val('N'); 1686 } 1687 }) 1688 1689 $('input.autoCheck').click(function () { 1690 1691 //console.log('who clicked me?'); 1692 var idCheck = $(this); 1693 var idValue = idCheck.attr("id").replace(/_chk/,""); 1694 if(idCheck.prop('checked')){ 1695 $('#' + idValue).val('Y'); 1696 }else{ 1697 $('#' + idValue).val('N'); 1698 } 1699 }) 1700 1701 } 1702 1703/* ******************************************************************************/
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.