1(function( $ ) { 2 'use strict'; 3 4 /** 5 * All of the code for your public-facing JavaScript source 6 * should reside in this file. 7 * 8 * Note: It has been assumed you will write jQuery code here, so the 9 * $ function reference has been prepared for usage within the scope 10 * of this function. 11 * 12 * This enables you to define handlers, for when the DOM is ready: 13 * 14 * $(function() { 15 * 16 * }); 17 * 18 * When the window is loaded: 19 * 20 * $( window ).load(function() { 21 * 22 * }); 23 * 24 * ...and/or other possibilities. 25 * 26 * Ideally, it is not considered best practise to attach more than a 27 * single DOM-ready or window-load handler for a particular page. 28 * Although scripts in the WordPress core, Plugins and Themes may be 29 * practising this, we should strive to set a better example in our own work. 30 */ 31 32 $(function () { 33 $('.wdk-click-load-animation').on('click', function () { 34 $(this).find('.fa-ajax-indicator').css('display', 'inline-block'); 35 36 if ($(this).closest('form').length) { 37 if (!$(this).closest('form')[0].checkValidity()) { 38 $(this).find('.fa-ajax-indicator').css('display', 'none'); 39 } 40 } 41 }); 42 43 $('.wdk-form-animation').on('submit', function () { 44 var form, indicator; 45 form = $(this); 46 indicator = form.find('.fa-ajax-indicator'); 47 indicator.css('display', 'inline-block'); 48 49 if(form[0].checkValidity()) 50 indicator.css('display', 'none'); 51 }); 52 53 54 $('.wdk-submit-loading').on('click', function () { 55 var form; 56 form = $(this).closest('form'); 57 58 if( $(this).hasClass('wdk_btn_load_indicator')) { 59 return false; 60 } 61 62 $(this).addClass('wdk_btn_load_indicator disabled'); 63 }); 64 65 $('.wdk-click-loading').on('click', function (e) { 66 67 if( $(this).hasClass('wdk_btn_load_indicator')) { 68 return false; 69 } 70 $(this).addClass('wdk_btn_load_indicator disabled'); 71 }); 72 73 const wdk_start_search = (form, formData = null) => { 74 var url,scrollTo, data = {}; 75 url = form.attr('action').replace(/#results/, ''); 76 if (url.indexOf('?') == -1) { 77 url += '?'; 78 } else { 79 url += '&'; 80 } 81 var str_parameters = ""; 82 83 if (formData) { 84 85 $.each(formData, function (name, value) { 86 if ( 87 value != '' && 88 name.indexOf('skip') == -1 89 ) { 90 if (str_parameters != "") { 91 str_parameters += "&"; 92 } 93 94 str_parameters += name + "=" + encodeURIComponent(value); 95 } 96 }); 97 98 } else { 99 $.each($("form.wdk-search-form:visible").serializeArray(), function (i, k) { 100 if (k.value != '' && k.name.indexOf('skip') == -1) { 101 if (str_parameters != "") { 102 str_parameters += "&"; 103 } 104 str_parameters += k.name + "=" + encodeURIComponent(k.value); 105 } 106 }); 107 108 $.each($("form.wdk-search-form.map").serializeArray(), function (i, k) { 109 if (k.value != '' && k.name.indexOf('skip') == -1) { 110 if (str_parameters != "") { 111 str_parameters += "&"; 112 } 113 str_parameters += k.name + "=" + encodeURIComponent(k.value); 114 } 115 }); 116 117 $.each($(".wdk-search-popup .toggle-btn:visible"), function (i, k) { 118 let el = $($(this).attr('data-wdk-target')); 119 if(el && el.length) { 120 $.each(el.find('.wdk-search-form').serializeArray(), function (i, k) { 121 if (k.value != '' && k.name.indexOf('skip') == -1) { 122 if (str_parameters != "") { 123 str_parameters += "&"; 124 } 125 str_parameters += k.name + "=" + encodeURIComponent(k.value); 126 } 127 }); 128 } 129 }); 130 } 131 /* view_type */ 132 if($('.wmvc-view-type .nav-link.active').length) { 133 str_parameters += "&wmvc_view_type="+$('.wmvc-view-type .nav-link.active').attr('data-id'); 134 } 135 136 /* order by */ 137 if($('.wdk-order').val() != '' && $('.wdk-order').val()) { 138 str_parameters += "&order_by="+$('.wdk-order').val(); 139 } 140 141 if ($('.wdk-search-form[data-scrollto]').length) 142 scrollTo = '#'+$('.wdk-search-form[data-scrollto]').attr('data-scrollto'); 143 144 145 146 var setCookie = (cname, cvalue, exdays) => { 147 var d = new Date(); 148 d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); 149 var expires = "expires="+d.toUTCString(); 150 document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; 151 }
152 setCookie('wdk_last_search', str_parameters); 153 154 return url+str_parameters+scrollTo; 155 } 156 157 /* set current page for search results if exists results widget and enabled in setttings*/ 158 $('form.wdk-search-form').each(function() { 159 var $form = $(this); 160 if ($('.wdk-listings-results').length && $('.wdk-listings-results#results').length && $form.attr('data-current-link')) { 161 $form.attr('action', $form.attr('data-current-link')); 162 } 163 }); 164 165 $("form.wdk-search-form").on('submit', function (e) { 166 e.preventDefault(); 167 var url = wdk_start_search($(this)); 168 $(this).closest('form').addClass('loading') 169 if (decodeURI(window.location.href) == decodeURI(url)) { 170 window.location.reload(); 171 } else { 172 window.location.href = url; 173 } 174 return false; 175 }); 176 177 $("form.wdk-search-form.auto_search").find('input, select').on('input', function (e) { 178 $("form.wdk-search-form").first().trigger('submit') 179 }); 180 181 $("form.wdk-search-form .wdk-search-start:not(.wdk-search-reset)").on('click', function (e) { 182 e.preventDefault(); 183 var url = wdk_start_search($(this).closest('form')); 184 $(this).closest('form').addClass('loading') 185 186 if($(this).closest('.ajax_results_enabled').length) { 187 if (typeof wdk_ajax_loading_listings == 'function') { 188 wdk_ajax_loading_listings(url); 189 } 190 } else if (decodeURI(window.location.href) == decodeURI(url)) { 191 window.location.reload(url); 192 } else { 193 window.location.href = url; 194 } 195 return false; 196 }) 197 198 $('.wdk-listings-results.ajax_results_enabled .wdk-pagination .page-numbers').on('click', function (e) { 199 e.preventDefault(); 200 if (typeof wdk_ajax_loading_listings == 'function') { 201 wdk_ajax_loading_listings($(this).attr('href')); 202 } 203 }) 204 205 /* elementor popup */ 206 jQuery( document ).on( 'elementor/popup/show', () => { 207 wdk_reset_form(); 208 } ); 209 210 const wdk_reset_form = () => { 211 $("form.wdk-search-form .wdk-search-reset").off().on('click', function (e) { 212 e.preventDefault(); 213 let this_form = jQuery(this).closest('form'); 214 jQuery('input:not([type="checkbox"]):not([name="element_id"]):not([type="radio"]):not([type="hidden"]),textarea,select').val(''); 215 jQuery('select').val(jQuery(this).find('option:first').val()) 216 jQuery('input[type="checkbox"]').prop('checked', false); 217 jQuery('input[type="radio"]').prop('checked', false); 218 jQuery('.wdk-field.LOCATION .wdk_dropdown_tree button:first-child').html(jQuery('.wdk-field.LOCATION .list_items li:first').text()); 219 jQuery('.wdk-field.CATEGORY .wdk_dropdown_tree button:first-child').html(jQuery('.wdk-field.CATEGORY .list_items li:first').text()); 220 jQuery('input[name="rectangle_ne"],input[name="rectangle_sw"] ').val(''); 221 222 // Reset Select2 fields with .select_ajax class 223 jQuery('.select_ajax').each(function() { 224 if (typeof jQuery(this).select2 === 'function') { 225 jQuery(this).val(null).trigger('change'); // Clear selection and notify Select2 226 } 227 }); 228 229 $('.wdk-slider-range-field').each(function () { 230 231 var instance = $(this).data('fieldSliderRange'); 232 233 if(instance) { 234 instance.reset(); 235 } 236 237 }); 238 239 // Remove all query params starting with 'search_' or 'field_' and hash '#results' from the URL on reset 240 if (window.history && window.history.replaceState) { 241 let url = window.location.href; 242 let parser = document.createElement('a'); 243 parser.href = url; 244 245 // Get query string and hash 246 let query = parser.search.replace(/^\?/, ''); 247 let hash = parser.hash; 248 249 // Split query into key-value pairs 250 let params = query ? query.split('&') : []; 251 let filteredParams = []; 252 253 // Remove params whose key starts with 'search_' or 'field_'
254 params.forEach(function(param) { 255 let key = param.split('=')[0]; 256 if (!(key.startsWith('search_') || key.startsWith('field_'))) { 257 filteredParams.push(param); 258 } 259 }); 260 261 // Rebuild the URL without the removed params and hash 262 let newQuery = filteredParams.length ? '?' + filteredParams.join('&') : ''; 263 let newUrl = parser.protocol + '//' + parser.host + parser.pathname + newQuery; 264 265 // Remove hash if it is '#results' 266 if (hash && hash !== '#results') { 267 newUrl += hash; 268 } 269 270 window.history.replaceState({}, document.title, newUrl); 271 } 272 273 if(this_form.hasClass('auto_search')) { 274 $("form.wdk-search-form").first().trigger('submit') 275 } 276 return false; 277 }) 278 }; 279 wdk_reset_form(); 280 281 /* date time fields init */ 282 if ($('.wdk-fielddate').length && typeof $.datepicker != 'undefined') { 283 284 $('.wdk-fielddate').each(function () { 285 let dateFormat = wdk_script_parameters.format_date_js; 286 var self = $(this); 287 288 if (self.attr('date-format')) 289 dateFormat = self.attr('date-format'); 290 291 self.datepicker({ dateFormat: dateFormat, onSelect: function() { 292 self.parent().find('.db-date').val(wdk_date_sql_normalize(self.datepicker("getDate"), self)).trigger('input'); 293 } 294 }).on( "change", function() { 295 if(self.val() == '') { 296 self.parent().find('.db-date').val(''); 297 } else { 298 self.parent().find('.db-date').val(wdk_date_sql_normalize(self.datepicker("getDate"), self)); 299 } 300 }); 301 302 if(self.parent().find('.db-date').val() == '' && false) { 303 self.parent().find('.db-date').val(wdk_date_notime_sql_normalize()); 304 } 305 }) 306 } ; 307 308 309 if ($('.wdk-fielddatetime').length && typeof $.datepicker != 'undefined') { 310 311 $('.wdk-fielddatetime').each(function () { 312 let dateFormat = wdk_script_parameters.format_datetime_js; 313 314 var self = $(this); 315 if (self.attr('date-format')) 316 dateFormat = self.attr('date-format'); 317 318 self.datepicker({ dateFormat: dateFormat, onSelect: function() { 319 var datetime = wdk_date_notime_sql_normalize(self.datepicker("getDate"), self); 320 if(self.parent().find('[name="hours_mask"]').val() !='') { 321 datetime += ' '+wdk_pad(self.parent().find('[name="hours_mask"]').val()); 322 } else { 323 datetime += ' 00'; 324 } 325 if(self.parent().find('[name="minutes_mask"]').val() !='') { 326 datetime += ':'+wdk_pad(self.parent().find('[name="minutes_mask"]').val()); 327 } else { 328 datetime += ':00'; 329 } 330 datetime += ':00'; 331 332 self.parent().find('.db-date').val(datetime).trigger('input'); 333 } 334 }).on( "change", function() { 335 336 var datetime = wdk_date_notime_sql_normalize(self.datepicker("getDate"), self); 337 if(self.parent().find('[name="hours_mask"]').val() !='') { 338 datetime += ' '+wdk_pad(self.parent().find('[name="hours_mask"]').val()); 339 } else { 340 datetime += ' 00'; 341 } 342 if(self.parent().find('[name="minutes_mask"]').val() !='') { 343 datetime += ':'+wdk_pad(self.parent().find('[name="minutes_mask"]').val()); 344 } else { 345 datetime += ':00'; 346 } 347 datetime += ':00'; 348 self.parent().find('.db-date').val(datetime); 349 }); 350 351 if(self.parent().find('.db-date').val() == '') { 352 self.parent().find('.db-date').val(wdk_date_sql_normalize()); 353 } 354 355 self.parent().find('[name="hours_mask"],[name="minutes_mask"]').on('input', function(){ 356 var datetime = wdk_date_notime_sql_normalize(self.datepicker("getDate"), self); 357 if(self.parent().find('[name="hours_mask"]').val() !='') { 358 datetime += ' '+wdk_pad(self.parent().find('[name="hours_mask"]').val()); 359 } else { 360 datetime += ' 00'; 361 } 362 if(self.parent().find('[name="minutes_mask"]').val() !='') { 363 datetime += ':'+wdk_pad(self.parent().find('[name="minutes_mask"]').val()); 364 } else { 365 datetime += ':00'; 366 } 367 datetime += ':00'; 368 self.parent().find('.db-date').val(datetime); 369 }); 370 }) 371 }; 372 373 if ($('.wdk-fielddate_from').length && $('.wdk-fielddate_to').length && typeof $.datepicker != 'undefined') { 374 var dateFormat, from, to;
375 const getDate = ( element ) => { 376 var date; 377 try { 378 date = $.datepicker.parseDate( dateFormat, element.value ); 379 } catch( error ) { 380 date = null; 381 } 382 return date; 383 } 384 385 dateFormat = wdk_script_parameters.format_date_js; 386 if ($('.wdk-fielddate_from').attr('date-format')) 387 dateFormat = $('.wdk-fielddate_from').attr('date-format'); 388 389 from = $('.wdk-fielddate_from') 390 .datepicker({ 391 dateFormat: dateFormat, 392 onSelect: function( selectedDate ) { 393 to.datepicker("option", "minDate", selectedDate ); 394 setTimeout(function(){ 395 to.datepicker('show'); 396 }, 16); 397 398 from.parent().find('.db-date').val(wdk_date_sql_normalize(from.datepicker("getDate"), from)); 399 wdk_date_add_hours(from); 400 } 401 }).on( "change", function() { 402 from.parent().find('.db-date').val(wdk_date_sql_normalize(from.datepicker("getDate"), from)).trigger('input'); 403 }); 404 405 to = $('.wdk-fielddate_to').datepicker({ 406 dateFormat: dateFormat 407 }) 408 .on( "change", function() { 409 from.datepicker( "option", "maxDate", getDate( this ) ); 410 to.parent().find('.db-date').val(wdk_date_sql_normalize(to.datepicker("getDate"), to)).trigger('input'); 411 wdk_date_add_hours(to); 412 }); 413 414 if(to.parent().find('.db-date').val() == '') { 415 to.parent().find('.db-date').val(wdk_date_sql_normalize()); 416 } 417 418 if(from.parent().find('.db-date').val() == '') { 419 from.parent().find('.db-date').val(wdk_date_sql_normalize()); 420 } 421 422 from.parent().find('[name="hours_mask"],[name="minutes_mask"]').on('input', function(){ 423 wdk_date_add_hours(from); 424 }); 425 426 to.parent().find('[name="hours_mask"],[name="minutes_mask"]').on('input', function(){ 427 wdk_date_add_hours(to); 428 }); 429 } 430 if(typeof $.fn.wdkSuggestion == 'function') { 431 432 if(typeof wdk_script_parameters.settings_wdk_field_search_suggestion_disable != 'undefined' && wdk_script_parameters.settings_wdk_field_search_suggestion_disable == 1) { 433 434 } else { 435 $('#wdk_field_search').wdkSuggestion({ 436 ajax_url: wdk_script_parameters.ajax_url, 437 ajax_param: { 438 "action": 'wdk_public_action', 439 "page": 'wdk_frontendajax', 440 "function": 'search_suggestion', 441 }, 442 debounce: 250, 443 min_chars: 3, 444 cache_ttl: 0, 445 strings: { 446 loading: wp.i18n.__('Searchingâ¦', 'wpdirectorykit'), 447 empty: wp.i18n.__('No results found', 'wpdirectorykit'), 448 error: wp.i18n.__('Search failed. Try again.', 'wpdirectorykit'), 449 results: wp.i18n.__('{count} suggestions available', 'wpdirectorykit'), 450 label: wp.i18n.__('Search suggestions', 'wpdirectorykit') 451 }, 452 language_id: '', 453 text_search: 'Search', 454 callback_selected: function(key) { 455 456 } 457 }); 458 } 459 460 } 461 462 $('.wdk-control[type="number"]').on('change',function(){ 463 let val = $(this).val(); 464 let step = 1; 465 if(val.length>=7){ 466 step = 10000; 467 } else if(val.length>=4) { 468 step = 10; 469 } 470 $(this).attr('step', step); 471 }) 472 473 474 if(typeof $.fn.fieldSliderRange == 'function' && typeof $.fn.ionRangeSlider == 'function') { 475 $('.wdk-slider-range-field').fieldSliderRange(); 476 } 477 478 wdk_result_listings_thumbnail_slider(); 479 480 /* if video exists on thumbnail css trick */ 481 $('.wdk-listing-card .wdk-thumbnail .wdk-image.media').find('iframe,video').css('padding-bottom', +($('.wdk-listing-card .wdk-thumbnail .wdk-over-image-bottom').outerHeight())+'px'); 482 483 484 if(typeof $.fn.WdkScrollMobileSwipe == 'function') { 485 $('.WdkScrollMobileSwipe_enable').WdkScrollMobileSwipe(); 486 $('.WdkScrollMobileSwipe_elementor_enable .elementor-container').WdkScrollMobileSwipe(); 487 } 488 489 if($('.wl-menu-toggle').length) { 490 $('.wdk-footer-menu .wdk_mobile_footer_menu_gumb-open').addClass('trigger') 491 $('.wdk-footer-menu .wdk_mobile_footer_menu_gumb-open').on('click', function(e){
492 e.preventDefault(); 493 $('.wl-menu-toggle').trigger('click'); 494 }); 495 } 496 497 498 /* Read More Button */ 499 jQuery('.wdk-field-value.TEXTAREA').each(function(){ 500 // Find the target div containing additional content 501 var moreContentDiv = $(this).find("[id*='more-']"); 502 // Hide the additional content initially 503 var additionalContent = moreContentDiv.nextUntil(":not(p)"); 504 additionalContent.hide(); 505 506 // Create a "Read More" button 507 var readMoreButtonWrapper = $("<div class='wdk-textarea-load-more-wrapper'><a class='wdk-textarea-load-more-button'></a></div>"), 508 readMoreButton = readMoreButtonWrapper.find('a').text(wdk_script_parameters.text.read_more || ''); 509 readMoreButton.on("click", function() { 510 // Toggle the visibility of the additional content 511 additionalContent.slideToggle(); 512 if (readMoreButton.text() === wdk_script_parameters.text.read_more) { 513 readMoreButton.text(wdk_script_parameters.text.read_less); 514 } else { 515 readMoreButton.text(wdk_script_parameters.text.read_more); 516 } 517 }); 518 519 // Replace the target div with the "Read More" button 520 moreContentDiv.before(readMoreButtonWrapper); 521 moreContentDiv.remove(); 522 }); 523 524 $('.wdk-language-switcher-drop .wdk-language-switcher-btn-toggle').on('click', function (e) { 525 e.preventDefault(); 526 $(this).closest('.wdk-language-switcher-drop').toggleClass('wdk-show'); 527 }); 528 // Add click event to each share link 529 document.querySelectorAll('.wdk-device-share-link').forEach(link => { 530 link.addEventListener('click', function(event) { 531 event.preventDefault(); 532 shareUrl(link.getAttribute('href')); 533 }); 534 }); 535 536 $('.wdk-search_sensitive_link').on('click',function(e) { 537 e.preventDefault(); 538 var href = $(this).attr('href'), 539 search_url = wdk_start_search($("form.wdk-search-form")); 540 541 if(search_url == href) { 542 window.location.href = href; 543 return; 544 } 545 546 // Parse the href to extract search_location and search_category 547 var urlParams = new URLSearchParams(href.split('?')[1]); 548 var searchLocation = urlParams.get('search_location'); 549 var searchCategory = urlParams.get('search_category'); 550 551 // Parse the search_url to update with new params 552 var searchParams = new URLSearchParams(search_url.split('?')[1]); 553 554 if (searchLocation) { 555 searchParams.set('search_location', searchLocation); 556 } 557 if (searchCategory) { 558 searchParams.set('search_category', searchCategory); 559 } 560 561 var updatedSearchUrl = search_url.split('?')[0] + '?' + searchParams.toString(); 562 window.location.href = updatedSearchUrl; 563 564 }) 565 resetSearchFields(); 566 567 if(typeof fpai_ajax_obj != 'undefined') { 568 const { __ } = wp.i18n; 569 jQuery('.wdk-ai-search').on('click', function(e) { 570 e.preventDefault(); 571 e.stopPropagation(); 572 var self = jQuery(this); 573 jQuery.confirm({ 574 backgroundDismiss: true, 575 closeIcon: true, 576 boxWidth: '400px', 577 useBootstrap: false, 578 title: __('Search with AI', 'wpdirectorykit'), 579 onOpenBefore: function () { 580 this.$el.addClass('wdk-ai-search-popup'); 581 jQuery('body').addClass('wdk-popup-open'); 582 }, 583 onClose: function () { 584 jQuery('body').removeClass('wdk-popup-open'); 585 }, 586 content: '' + 587 `<form action="" class=""> 588 <div class="form-alerts"> 589 </div> 590 <div class="form-group"> 591 <textarea 592 rows="6" 593 name="query" 594 class="form-control" 595 placeholder="${__("I'm searching for red apartment with balcony and pool near London...", 'wpdirectorykit')}" 596 ></textarea> 597 </div> 598 </form>`, 599 buttons: { 600 formSubmit: { 601 text: `⨠${__('Search with AI', 'wpdirectorykit')}`, 602 btnClass: 'wdk-ai-search', 603 action: function(e) { 604 const popup = this; 605 const jc = this.$content; 606 const query = jc.find('textarea[name="query"]').val(); 607 const $responseDiv = jc.find('.form-alerts'); 608 let $btn = jc.closest('.jconfirm').find('.wdk-ai-search'); 609 610 // Check if the query textarea in the first form is empty, if so add error class and do not proceed 611 var $aiQueryTextarea = jc.find('textarea[name="query"]'); 612 $aiQueryTextarea.off('focus.fpaiError').on('focus.fpaiError', function() { 613 $aiQueryTextarea.removeClass('fpai-error'); 614 }); 615 616 if (!query || query.trim() === "") { 617 $aiQueryTextarea.addClass('fpai-error'); 618 return false; // prevent the popup from closing and block further processing 619 } else { 620 $aiQueryTextarea.removeClass('fpai-error'); 621 } 622 623 $btn.prop('disabled', true).html(`ð¤ ${__('AI is working...', 'wpdirectorykit')} <div class="fpai-loading-spinner"></div>`); 624 $responseDiv.show().html(`${__('Processing... Please wait...', 'wpdirectorykit')} <div class="fpai-loading-spinner"></div>`).removeClass('fpai-success fpai-error'); 625 626 // Build "form_1" fields structure dynamically from wdk_script_parameters.fields_data 627 const formFieldsObj = {}; 628 if (Array.isArray(wdk_script_parameters.fields_data)) { 629 wdk_script_parameters.fields_data.forEach(field => { 630 // Construct the field key (e.g. "field_2") based on your data structure 631 const fieldKey = 'field_' + field.idfield; 632 // Only include fields if field.field_type is one of the allowed types. 633 const allowedTypes = ['INPUTBOX', 'NUMBER', 'DROPDOWN', 'DROPDOWNMULTIPLE', 'CHECKBOX']; 634 if (!allowedTypes.includes(field.field_type)) { 635 return;
635 // skip this field 636 } 637 638 let type = "text"; 639 if(field.field_type == 'NUMBER') 640 type = "number"; 641 642 if(field.field_type == 'CHECKBOX') 643 type = "checkbox"; 644 645 formFieldsObj[fieldKey] = { 646 // Optionally: default value or empty, since the user may fill via AI 647 value: field.value !== undefined ? field.value : "", 648 type: type, // fallback type "text" if not set 649 label: field.field_label || '',// fallback to title if label isn't present 650 placeholder: field.placeholder || '', // fallback to empty if not set 651 options: field.values_list || '', // fallback to empty if not set 652 }; 653 }); 654 } 655 656 // Use only the first 15 fields 657 let formFieldsObjLimited; 658 if ( 659 Array.isArray(wdk_script_parameters.wdk_ai_search_fields) && 660 wdk_script_parameters.wdk_ai_search_fields.length > 0 661 ) { 662 const allowedIds = wdk_script_parameters.wdk_ai_search_fields.map(String); 663 formFieldsObjLimited = Object.fromEntries( 664 Object.entries(formFieldsObj).filter(([key, field]) => { 665 const id = key.replace(/^field_/, ''); 666 return allowedIds.includes(id); 667 }) 668 ); 669 } else { 670 // fallback: limit to 12, as before 671 formFieldsObjLimited = Object.fromEntries( 672 Object.entries(formFieldsObj).slice(0, 12) 673 ); 674 } 675 676 677 // Prepend system/required fields if needed, demo here: 678 const form1 = { 679 field_search: { value: "", type: "text", label: "locations, country, city", placeholder: "",}, 680 address: { value: "", type: "text", label: "Address", placeholder: "Address" }, 681 ...formFieldsObjLimited 682 }; 683 684 // Additional forms if needed (leave as static if not dynamic) 685 const formsData = JSON.stringify({ 686 "form_1": form1, 687 }); 688 689 // Send data via fetch API using FormData for better handling 690 const formData = new FormData(); 691 formData.append('action', 'fpai_generate_form_data'); 692 formData.append('nonce', fpai_ajax_obj.nonce); 693 formData.append('ai_input', query); 694 formData.append('forms_data', formsData); 695 696 fetch(fpai_ajax_obj.ajax_url, { 697 method: 'POST', 698 body: formData 699 }) 700 .then(response => response.json()) 701 .then(data => { 702 if (data.success && data.data) { 703 $responseDiv.html(data.data.message || 'Form populated successfully').addClass('fpai-success'); 704 // Populate form fields 705 const formData = data.data.form_data; 706 707 const searchData = {}; 708 709 jQuery.each(formData, function (name, field) { 710 if ( 711 field && 712 typeof field === 'object' && 713 'value' in field && 714 field.value !== '' && 715 field.value !== null && 716 typeof field.value !== 'undefined' 717 ) { 718 searchData[name] = field.value; 719 } 720 }); 721 722 var url = wdk_start_search(self.closest('form'), searchData); 723 724 $(this).closest('form').addClass('loading') 725 726 if($(this).closest('.ajax_results_enabled').length) { 727 if (typeof wdk_ajax_loading_listings == 'function') { 728 wdk_ajax_loading_listings(url); 729 } 730 }
730 else if (decodeURI(window.location.href) == decodeURI(url)) { 731 window.location.reload(url); 732 } else { 733 window.location.href = url; 734 } 735 736 737 setTimeout(() => { 738 popup.close(); 739 }, 2000); 740 741 } else { 742 $responseDiv.html(data.data ? data.data.message : 'Error: Invalid response format').addClass('fpai-error'); 743 } 744 }) 745 .catch(error => { 746 $responseDiv.html(__('Error occurred while processing request', 'wpdirectorykit')).addClass('fpai-error'); 747 }) 748 .finally((data) => { 749 $btn.prop('disabled', false).html(`<span class="fpai-btn-icon">â¨</span> ${__('Populate form with AI', 'wpdirectorykit')}`); 750 751 }); 752 753 return false; 754 } 755 }, 756 /* 757 cancel: { 758 text: __('Close', 'wpdirectorykit'), 759 btnClass: 'wdk-ai-close', 760 action: function() { 761 //close 762 } 763 },*/ 764 765 }, 766 }); 767 return false; 768 }) 769 } 770 }); 771 772})(jQuery); 773 774 775 776var resetSearchFields = () => { 777 jQuery(".wdk-control[type='text']:not(.wdk-hidden)").each(function(){ 778 var $searchField = jQuery(this); 779 // Create reset button 780 var $resetButton = jQuery("<span>×</span>") 781 .css({ 782 cursor: "pointer", 783 display: "none", // Initially hidden 784 position: "absolute", 785 right: "10px", 786 top: "50%", 787 transform: "translateY(-50%)", 788 fontSize: "18px" 789 }); 790 791 /* Text Fields */ 792 793 // Wrap input field in a relative container 794 var $wrapper = jQuery("<div></div>") 795 .css({ position: "relative" }) 796 .insertBefore($searchField); 797 798 $wrapper.append($searchField).append($resetButton); 799 800 // Show/hide reset button based on input 801 $searchField.on("input", function () { 802 $resetButton.toggle(!!$searchField.val()); // Toggle visibility based on input 803 }); 804 805 // Clear field when reset button is clicked 806 $resetButton.on("click", function () { 807 $searchField.val("").trigger("input").focus(); // Reset field and trigger input event to hide button 808 }); 809 }); 810 /* Tree Fields */ 811 812 jQuery(`input[name="search_location"],input[name="search_category"]`).each(function(){ 813 814 var $searchField = jQuery(this); 815 var resetButton; 816 817 // Show/hide reset button based on input 818 $searchField.on("change", function () { 819 if (jQuery(this).val() !== "") { 820 // Wrap input field in a relative container 821 var $wrapper = $searchField.closest('.wdk-field-group').find('.wdk_dropdown_tree button:first-child') 822 .css({ position: "relative" }); 823 if (!resetButton) { 824 resetButton = jQuery("<span>×</span>") 825 .css({ 826 cursor: "pointer", 827 position: "absolute", 828 right: "10px", 829 top: "50%", 830 transform: "translateY(-50%)", 831 fontSize: "18px" 832 }) 833 .on("click", function (e) { 834 e.stopPropagation(); 835 e.preventDefault(); 836 837 $searchField.val("").trigger("input").focus(); 838 resetButton.remove(); 839 resetButton = null; 840 $searchField.closest('.wdk-field-group').find('.wdk_dropdown_tree button:first-child').html( $searchField.closest('.wdk-field-group').find('.list_items li:first').text()); 841 842 return false; 843 }); 844 $wrapper.append(resetButton); 845 } 846 } else if (resetButton) { 847 resetButton.remove(); 848 resetButton = null; 849 } 850 }); 851 852 });
853 854}; 855 856/* slider for result listings thumbnails */ 857if (typeof wdk_result_listings_thumbnail_slider != 'function') { 858 var wdk_result_listings_thumbnail_slider = ($wrapper = 'body') => { 859 if(typeof jQuery.fn.slick == 'function') { 860 jQuery('.wdk_js_gallery_slider_box', $wrapper).each(function(){ 861 var _this = jQuery(this); 862 863 if($wrapper == 'body') { 864 if(_this.closest('.wdk_results_listings_slider_ini').length){return true;} 865 } 866 867 if (_this.closest('.slick-slide').hasClass('slick-cloned')) { 868 return true; 869 } 870 871 // Check if the slider exists and is initialized 872 if (_this.find('.wdk_js_gallery_slider').length > 0 && _this.find('.wdk_js_gallery_slider').hasClass('slick-initialized')) { 873 _this.find('.wdk_js_gallery_slider').slick('unslick'); 874 } 875 876 877 _this.find('.wdk_js_gallery_slider').slick({ 878 dots: true, 879 infinite: true, 880 speed: 500, 881 fade: true, 882 arrows: true, 883 cssEase: 'linear', 884 nextArrow: _this.find('.wdk_js_gallery_slider-carousel_arrows .wdk-slider-next'), 885 prevArrow: _this.find('.wdk_js_gallery_slider-carousel_arrows .wdk-slider-prev'), 886 }); 887 }); 888 } 889 }; 890} 891/* 892 Fix for slick slider, event after init slick 893 894 @param object el slick object 895 @param function callback 896*/ 897 898if (typeof wdk_slick_slider_init != 'function') { 899var wdk_slick_slider_init = (el, callback) => { 900 try { 901 el.slick("slickGoTo", 0, true); 902 } 903 catch(error) { 904 setTimeout(wdk_slick_slider_init, 1000); 905 return; 906 } 907 908 if(callback) { 909 callback.call(); 910 } 911}; 912} 913if (typeof wdk_pad != 'function') { 914var wdk_pad = (num = '') => { 915 return ('00'+num).slice(-2); 916}; 917} 918 919if (typeof wdk_date_add_hours != 'function') { 920var wdk_date_add_hours = (selector = '') => { 921 if(typeof selector !='undefined' && selector.parent().find('[name="hours_mask"]').length) { 922 var datetime = wdk_date_notime_sql_normalize(selector.datepicker("getDate"), selector); 923 if(selector.parent().find('[name="hours_mask"]').val() !='') { 924 datetime += ' '+wdk_pad(selector.parent().find('[name="hours_mask"]').val()); 925 } else { 926 datetime += ' 00'; 927 } 928 if(selector.parent().find('[name="minutes_mask"]').val() !='') { 929 datetime += ':'+wdk_pad(selector.parent().find('[name="minutes_mask"]').val()); 930 } else { 931 datetime += ':00'; 932 } 933 datetime += ':00'; 934 selector.parent().find('.db-date').val(datetime); 935 } 936}; 937} 938/* 939 Convert date to sql format 940 941 @param string $date, string of date 942 943 @return string normalize date or Current date/time 944*/ 945if (typeof wdk_date_sql_normalize != 'function') { 946var wdk_date_sql_normalize = (date = '', datepicker_el = null) => { 947 if(date == '') { 948 var d = new Date(); 949 } else { 950 var d = new Date(date); 951 } 952 953 if(d == 'Invalid Date' && datepicker_el) { 954 var d = new Date(+(jQuery.datepicker.formatDate("@", datepicker_el.datepicker("getDate")))); 955 } 956 957 d = d.getUTCFullYear() + '-' + 958 wdk_pad(d.getMonth() + 1) + '-' + 959 wdk_pad(d.getDate()) + ' ' + 960 wdk_pad(d.getHours()) + ':' + 961 wdk_pad(d.getMinutes()) + ':' + 962 wdk_pad(d.getSeconds()); 963 return d; 964}; 965} 966 967if (typeof wdk_date_notime_sql_normalize != 'function') { 968var wdk_date_notime_sql_normalize = (date = '', datepicker_el = null) => { 969 if(date == '') { 970 var d = new Date(); 971 } else { 972 var d = new Date(date); 973 } 974 975 if(d == 'Invalid Date' && datepicker_el) { 976 var d = new Date(+(jQuery.datepicker.formatDate("@", datepicker_el.datepicker("getDate")))); 977 } 978 979 d = d.getUTCFullYear() + '-' + 980 wdk_pad(d.getMonth() + 1) + '-' + 981 wdk_pad(d.getDate()); 982 return d; 983}; 984} 985 986if (typeof wdk_generate_marker_ajax_popup != 'function') { 987var wdk_generate_marker_ajax_popup = (ajax_url, listing_post_id, lat, lng,innerMarker, wdk_jpopup_customOptions, auto = false, cluster
987s_enabled = true, custom_layout_id = '') => { 988 989 if(auto) { 990 var marker = L.marker( 991 [lat, lng], 992 {icon: L.divIcon({ 993 html: innerMarker, 994 className: 'open_steet_map_marker', 995 iconSize: 'auto', 996 }) 997 } 998 ); 999 } else { 1000 var marker = L.marker( 1001 [lat, lng], 1002 {icon: L.divIcon({ 1003 html: innerMarker, 1004 className: 'open_steet_map_marker', 1005 iconSize: [40, 60], 1006 popupAnchor: [-1, -35], 1007 iconAnchor: [23, 73], 1008 }) 1009 } 1010 ); 1011 } 1012 1013 var data = { 1014 "action": 'wdk_public_action', 1015 "page": 'wdk_frontendajax', 1016 "function": 'map_infowindow', 1017 "listing_post_id": listing_post_id, 1018 "custom_layout_id": custom_layout_id, 1019 }; 1020 1021 let favorite_init = false; 1022 let compare_init = false; 1023 marker.bindPopup(function () { 1024 var content = '<div class="infobox"><div class="map_infowindow"><div class="loading_content animated-background"><div class="box_line m170"></div><div class="box_line m20"></div><div class="box_line m20"></div><div class="box_line m20"></div><div class="box_line m20"></div><div class="box_line m20"></div></div></div></div>'; 1025 marker.getPopup().setContent(content); 1026 marker.getPopup().update(); 1027 jQuery.ajax({ 1028 url : ajax_url, 1029 type : "POST", 1030 data: data, 1031 success: function (data) { 1032 marker.getPopup().setContent(data.popup_content); 1033 marker.getPopup().update(); 1034 if (!favorite_init && typeof wdk_favorite == 'function') 1035 wdk_favorite('.infobox'); 1036 1037 favorite_init = false; 1038 1039 if (!compare_init && typeof wdk_init_compare_elem == 'function') 1040 wdk_init_compare_elem(); 1041 1042 compare_init = false; 1043 }, 1044 }); 1045 return content; 1046 }, wdk_jpopup_customOptions); 1047 1048 if (typeof wdk_favorite == 'function') 1049 marker.on('popupopen', function (popup) { 1050 if (!favorite_init) 1051 wdk_favorite('.infobox'); 1052 }); 1053 1054 if (typeof wdk_init_compare_elem == 'function') 1055 marker.on('popupopen', function (popup) { 1056 if (!compare_init) 1057 wdk_init_compare_elem(); 1058 }); 1059 1060 if (typeof wdk_favorite == 'function') 1061 marker.on('popupclose', function (popup) { 1062 marker.getPopup().setContent(jQuery('.leaflet-popup-content-wrapper .leaflet-popup-content').html()); 1063 marker.getPopup().update(); 1064 }); 1065 1066 if(clusters_enabled) { 1067 wdk_clusters.addLayer(marker); 1068 } else { 1069 wdk_map.addLayer(marker); 1070 } 1071 return marker; 1072} 1073} 1074 1075if (typeof wdk_generate_marker_basic_popup != 'function') { 1076var wdk_generate_marker_basic_popup = (lat, lng, innerMarker, wdk_jpopup_content, wdk_jpopup_customOptions) => { 1077 var marker = L.marker( 1078 [lat, lng], 1079 {icon: L.divIcon({ 1080 html: innerMarker, 1081 className: 'open_steet_map_marker', 1082 iconSize: [40, 60], 1083 popupAnchor: [-1, -35], 1084 iconAnchor: [23, 73], 1085 }) 1086 } 1087 ); 1088 1089 marker.bindPopup(wdk_jpopup_content, wdk_jpopup_customOptions); 1090 1091 return marker; 1092} 1093} 1094 1095if (typeof wdk_generate_marker_nopopup != 'function') { 1096var wdk_generate_marker_nopopup = (lat, lng,innerMarker) => { 1097 var marker = L.marker( 1098 [lat, lng], 1099 {icon: L.divIcon({ 1100 html: innerMarker, 1101 className: 'open_steet_map_marker', 1102 iconSize: [40, 60], 1103 popupAnchor: [-1, -35], 1104 iconAnchor: [23, 73], 1105 }) 1106 } 1107 ); 1108 1109 return marker; 1110} 1111} 1112 1113// Share URL function 1114var shareUrl = (url = window.location.href) => { 1115 // Check if the browser supports the Web Share API 1116 if (!navigator.share) { 1117 console.log("Web Share API not supported."); 1118 return; 1119 } 1120 1121 navigator.share({ 1122 url: url, // Share the current page URL 1123 }) 1124 .then(() => { 1125 console.log("Shared successfully!"); 1126 }) 1127 .catch((error) => { 1128 console.error("Sharing failed:", error); 1129 });
1130}; 1131
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.