PluginProbe
Filter Everything — WordPress & WooCommerce Filters / 1.9.7
Filter Everything — WordPress & WooCommerce Filters v1.9.7
1.9.7 1.9.6 1.9.5 1.9.4 1.9.3 1.9.2.2 1.9.2.1 trunk 1.2.1 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.4.1 1.4.4 1.4.5 1.4.8 1.4.9 1.5.0 1.5.1 1.6.0 1.6.1 1.6.2 All 52 releases
← All changes | assets/js/wpc-filter-set-admin.js +1016 -135 1.5.11.9.7 View file →
@@ -1,10 +1,14 @@
1 1 /*!
2 - * Filter Everything set admin 1.5.1
2 + * Filter Everything set admin 1.9.7
3 3 */
4 4 (function($) {
5 5 "use strict";
6 6 let filtersFormValid = false;
7 + let postTypesTaxList = wpcSetVars.postTypesTaxList;
8 + let numFieldNoTaxes = wpcSetVars.numFieldNoTaxes;
9 + let numFieldAttrs = wpcSetVars.numFieldAttrs;
10 + let isLimitFilterSet = wpcSetVars.isLimitFilterSet;
7 11
8 12 function validateFiltersForm( $el )
9 13 {
10 14 let $spinner = $('#publishing-action .spinner');
@@ -9,8 +13,25 @@
9 13 {
10 14 let $spinner = $('#publishing-action .spinner');
11 15 let requestParams = {};
12 16
17 + const keepFields = [
18 + '_wpnonce',
19 + '_flrt_nonce',
20 + '_wp_http_referer',
21 + 'user_ID',
22 + 'action',
23 + 'originalaction',
24 + 'post_author',
25 + 'post_type',
26 + 'original_post_status',
27 + 'post_ID',
28 + 'post_title',
29 + 'save',
30 + 'post_status',
31 + 'wpc_filter_set_json_data',
32 + ];
33 +
13 34 $spinner.addClass( 'is-active' );
14 35 /**
15 36 * @todo checkboxes does not validates correctly because they send the same value !!! IMPORTANT
16 37 * independently from checked status
@@ -15,9 +36,9 @@
15 36 * @todo checkboxes does not validates correctly because they send the same value !!! IMPORTANT
16 37 * independently from checked status
17 38 */
18 39
19 - requestParams.validateData = wpcSerialize( $el );
40 + requestParams.validateData = JSON.stringify(wpcSerialize( $el ));
20 41
21 42 wp.ajax.post( 'wpc-validate-filters', requestParams )
22 43 .always( function() {
23 44 $spinner.removeClass( 'is-active' );
@@ -23,9 +44,29 @@
23 44 $spinner.removeClass( 'is-active' );
24 45 })
25 46 .done( function( response ) {
26 47 filtersFormValid = true;
48 +
49 + const wpcHiddenInput = document.createElement('input');
50 + wpcHiddenInput.type = 'hidden';
51 + wpcHiddenInput.name = 'wpc_filter_set_json_data';
52 + wpcHiddenInput.value = JSON.stringify(wpcSerialize( $el ));
53 + $el.append(wpcHiddenInput);
54 +
55 + // Find the elements that need to be "disabled"
56 + const $toDisable = $el.find('[name]').not(keepFields.map(n => `[name="${n}"]`).join(','));
57 +
58 + // Save name and remove before submit
59 + $toDisable.each(function() {
60 + $(this).attr('data-name', $(this).attr('name')).removeAttr('name');
61 + });
62 +
27 63 $el.submit();
64 +
65 + // Restore name after submit
66 + $toDisable.each(function() {
67 + $(this).attr('name', $(this).attr('data-name')).removeAttr('data-name');
68 + });
28 69 })
29 70 .fail( function( response ) {
30 71
31 72 let notices = [];
@@ -146,8 +187,13 @@
146 187 }
147 188 });
148 189 }
149 190
191 + /**
192 + * Creates array with taxonomies that do not belong to the Post type
193 + * selected in Filter Set
194 + * @returns {[]|*[]}
195 + */
150 196 function getForbiddenTaxes()
151 197 {
152 198 if( typeof wpcSetVars.postTypesTaxList !== 'undefined'){
153 199 let postType = $('#wpc_set_fields-post_type').val();
@@ -175,18 +221,26 @@
175 221
176 222 return [];
177 223 }
178 224
225 + /**
226 + * Retrieves already selected filter entities to disable double using of them
227 + * @param $inputs - select tags, where we collect used entities. Usually .wpc-field-entity
228 + * @param excludeInput
229 + * @returns {boolean|[]}
230 + */
179 231 function getUsedEntities( $inputs, excludeInput )
180 232 {
181 233 let usedEntities = [];
182 234 let currentVal = '';
183 - let doNotInclude = ['post_meta', 'post_meta_num', 'post_meta_exists'];
235 + // Pass through these entities
236 + let doNotInclude = ['post_meta', 'post_meta_num', 'post_meta_exists', 'tax_numeric', 'post_meta_date'];
184 237
185 - if( $inputs.length > 0 ){
186 - $inputs.each(function(){
238 + if ( $inputs.length > 0 ) {
239 + $inputs.each( function(){
187 240 currentVal = $(this).val();
188 241
242 + // Continue
189 243 if( $(this).attr('id') == excludeInput.attr('id') ){
190 244 return;
191 245 }
192 246
@@ -192,9 +246,11 @@
192 246
193 247 if( doNotInclude.includes( currentVal ) ){
194 248 return;
195 249 }
196 - usedEntities.push( $(this).val() );
250 + if( currentVal ) {
251 + usedEntities.push( currentVal );
252 + }
197 253 });
198 254
199 255 return usedEntities;
200 256 }
@@ -200,22 +256,34 @@
200 256 }
201 257 return false;
202 258 }
203 259
204 - function setAvailableEntities( $el, noChange )
205 - {
206 - let currentVal = '';
207 - let exclude = getUsedEntities( $('.wpc-field-entity'), $el );
208 - let forbiddenTaxes = getForbiddenTaxes();
260 + /**
261 + * Pass through new filter entity options and set as disabled already used taxonomies
262 + * @param $theSelect - the select element with options to set. Usually it is .wpc-field-entity
263 + * @param dropdownClass - class of the select element where we have to set option status
264 + * @param noChange
265 + * @returns {boolean}
266 + */
267 + function setAvailableEntities( $theSelect, noChange )
268 + { // .wpc-field-entity
269 + let currentVal = '';
270 + let selectClass = $theSelect.attr('class');
271 + const excludeRaw = getUsedEntities( $( '.'+selectClass ), $theSelect );
272 + const exclude = Array.isArray(excludeRaw) ? excludeRaw : [];
273 + let forbiddenTaxes = getForbiddenTaxes(); //
209 274
210 - $el.find('option').each( function (){
275 + $theSelect.find('option').each( function (){
211 276 currentVal = $(this).val();
212 277
213 - if( currentVal === 'post_meta_exists' && ( wpcSetVars.filtersPro < 1) ){
278 + if( currentVal === 'post_meta_exists' && ( wpcSetVars.filtersPro < 1 ) ) {
214 279 return;
215 280 }
281 + if( currentVal === 'tax_numeric' && ( wpcSetVars.filtersPro < 1 ) ) {
282 + return;
283 + }
216 284
217 - if( exclude.includes( currentVal ) || forbiddenTaxes.includes(currentVal) ){
285 + if( exclude.includes( currentVal ) || forbiddenTaxes.includes( currentVal ) ){
218 286 $(this).attr( 'disabled', 'disabled' );
219 287 }else{
220 288 $(this).removeAttr( 'disabled' );
221 289 }
@@ -221,11 +289,12 @@
221 289 }
222 290 } );
223 291
224 292 // If currently selected option is disabled, make first available option selected.
225 - let disabled = $el.find('option:selected').attr('disabled');
293 + let disabled = $theSelect.find('option:selected').attr('disabled');
294 + // if noChange === false this works
226 295 if( disabled === 'disabled' && ! noChange ){
227 - $el.find('option:not([disabled]):first').prop('selected', true)
296 + $theSelect.find('option:not([disabled]):first').prop('selected', true)
228 297 .trigger('change');
229 298 }
230 299
231 300 return true;
@@ -230,17 +299,43 @@
230 299
231 300 return true;
232 301 }
233 302
234 - function passNewEntities(select)
303 + function handleShowTerms( select )
235 304 {
305 + let currentVal = select.val();
306 + let currentFid = select.parents('.wpc-filter-item').data('fid');
307 + currentVal = wpcShortenEname( currentVal );
308 +
309 + let $formTable = $( "#wpc-filter-id-"+currentFid+" .wpc-form-fields-table" );
310 + if ( wpcSetVars.swatchesTaxonomies.includes( currentVal ) ){
311 + $formTable.addClass("taxonomy-has-swatches");
312 + } else {
313 + $formTable.removeClass("taxonomy-has-swatches");
314 + }
315 +
316 + if ( wpcSetVars.brandEntities.includes( currentVal ) ){
317 + $formTable.addClass("wpc-filter-has-brands");
318 + } else {
319 + $formTable.removeClass("wpc-filter-has-brands");
320 + }
321 +
322 + if ( wpcSetVars.ratingTaxonomies.includes( currentVal ) ){
323 + $formTable.addClass("selected-and-above-show");
324 + } else {
325 + $formTable.removeClass("selected-and-above-show");
326 + }
327 + }
328 +
329 + function passNewEntities( select )
330 + {
236 331 let time = 0;
237 332
238 - $('.wpc-new-filter-item .wpc-field-entity').each(function (){
239 - let select = $(this);
333 + $('.wpc-new-filter-item .wpc-field-entity').each( function () {
334 + let select = $(this);
240 335 let noChange = false;
241 -
242 - if( $(this).attr('id') == select.attr('id') ){
336 + // Do not change current select tag
337 + if( $(this).attr('id') == select.attr('id') ) {
243 338 noChange = true;
244 339 }
245 340
246 341 setTimeout( function(){ setAvailableEntities( select, noChange ); }, time);
@@ -247,12 +342,27 @@
247 342 time += 100;
248 343 });
249 344 }
250 345
346 + $.fn.getCursorPosition = function() {
347 + var input = this.get(0);
348 + if (!input) return; // No (input) element found
349 + if ('selectionStart' in input) {
350 + // Standard-compliant browsers
351 + return input.selectionStart;
352 + } else if (document.selection) {
353 + // IE
354 + input.focus();
355 + var sel = document.selection.createRange();
356 + var selLen = document.selection.createRange().text.length;
357 + sel.moveStart('character', -input.value.length);
358 + return sel.text.length - selLen;
359 + }
360 + }
361 +
251 362 $(document).ready(function (){
252 363
253 364 $('form#post').on('submit', function(e){
254 -
255 365 // Clear all errors
256 366 removeElement( $('.wpc-field-notice') );
257 367
258 368 // Clear Notice
@@ -267,10 +377,12 @@
267 377 validateFiltersForm($(this));
268 378 }
269 379 });
270 380
381 +
271 382 $('.wpc-add-filter').on('click', function (e){
272 383 e.preventDefault();
384 +
273 385 let html = $('#wpc-new-filter').html();
274 386 let $el = $(html);
275 387 let search = 'wpc_new_id';
276 388 let replace = uniqId('filter_');
@@ -276,22 +388,27 @@
276 388 let replace = uniqId('filter_');
277 389 let replaceAttr = function(i, value){
278 390 return value.replace( search, replace );
279 391 }
280 - let applyButtonPosition = $("#wpc_set_fields-apply_button_menu_order").val();
392 +
281 393 let filtersListContainer = $('#wpc-filters-list');
282 - let filtersLength = filtersListContainer.find(".wpc-filter-item").length.toString();
283 - let applyButtonItem = $("#wpc-filter-id-apply-button");
284 394
285 395 $el.find('[id*="' + search + '"]').attr('id', replaceAttr);
286 396 $el.find('[for*="' + search + '"]').attr('for', replaceAttr);
287 397 $el.find('[name*="' + search + '"]').attr('name', replaceAttr);
398 + $el.find('[class*="' + search + '"]').attr('class', replaceAttr);
288 399 $el.data('fid', replace);
289 400 $el.attr('id', 'wpc-filter-id-'+replace);
290 401
291 - if( applyButtonPosition === filtersLength || applyButtonPosition === '-1' ){
292 - applyButtonItem.before($el);
293 - }else{
402 + let latestElem = $(".wpc-filter-item").last();
403 + if ( latestElem.hasClass('wpc-filter-not-listed') ) {
404 + let prevLatestElem = latestElem.prev('.wpc-filter-item');
405 + if ( prevLatestElem.hasClass('wpc-filter-not-listed') ) {
406 + prevLatestElem.before($el);
407 + } else {
408 + latestElem.before($el);
409 + }
410 + } else {
294 411 filtersListContainer.append($el);
295 412 }
296 413
297 414 let select = $el.find('.wpc-field-entity');
@@ -304,8 +421,9 @@
304 421
305 422 // Make already used entities unavailable to selection
306 423 setAvailableEntities( select );
307 424 handleHierarchyField( select );
425 + handleShowTerms( select );
308 426 // handleUsedForVariationsField( select );
309 427
310 428 $el.find('.wpc-field-exclude').select2({
311 429 width: '100%',
@@ -312,9 +430,9 @@
312 430 placeholder: wpcSetVars.excludePlaceholder,
313 431 });
314 432
315 433 // Fire this event to load exclude terms for first filter
316 - if( $('.wpc-filter-item').length === 1 ){
434 + if( $(".wpc-filter-item:not(.wpc-filter-not-listed)").length === 1 ){
317 435 select.trigger('change');
318 436 }
319 437
320 438 $('.wpc-help-tip').tipTip({
@@ -329,8 +447,12 @@
329 447 openFilter($el);
330 448
331 449 renderMenuOrder();
332 450 handleNoFiltersMessage();
451 +
452 + // Update Parent filter dropdown
453 + wpcAddNewFilterToParentList();
454 +
333 455 /**
334 456 * @todo There is problem with down arrow when we adding new filter !!! IMPORTANT
335 457 */
336 458
@@ -335,9 +457,9 @@
335 457 */
336 458
337 459 });
338 460
339 - $('.wpc-form-fields-table:not(.wpc-filter-post_meta_num) .wpc-field-exclude, .wpc-form-fields-table:not(.wpc-filter-post_meta_exists) .wpc-field-exclude').select2({
461 + $('.wpc-form-fields-table:not(.wpc-filter-tax_numeric) .wpc-field-exclude, .wpc-form-fields-table:not(.wpc-filter-post_meta_num) .wpc-field-exclude, .wpc-form-fields-table:not(.wpc-filter-post_meta_exists) .wpc-field-exclude').select2({
340 462 width: '100%',
341 463 placeholder: wpcSetVars.excludePlaceholder
342 464 });
343 465
@@ -371,8 +493,16 @@
371 493 .next('.wpc-filter-field-td')
372 494 .find('.wpc-filter-delete-wrapper').css('visibility', 'hidden');
373 495 });
374 496
497 + $('body').on('click', '.wpc-advice-head', function(e){
498 + // let body = $(this).next('.wpc-advice-body');
499 + $(this).toggleClass('wpc-opened');
500 + // body.slideToggle(200)
501 + // body.toggle(200)
502 + // body.toggleClass('wpc-opened');
503 + });
504 +
375 505 $('body').on('click', '.wpc-title-action', function(e){
376 506 let head = $(this).parent('.wpc-filter-head'),
377 507 body = head.next('.wpc-filter-body');
378 508 head.toggleClass('wpc-opened');
@@ -403,28 +533,47 @@
403 533 $(this).parents('.wpc-filter-body').find('.wpc-filter-additional-fields').slideToggle(200)
404 534 .toggleClass('wpc-additional-opened');
405 535 });
406 536
537 + $('body').on('change', 'select.wpc-field-ename', function(e){
538 + let time = 0;
539 + // let fid = $(this).parents('.wpc-filter-item').data('fid');
540 +
541 + $( $('.wpc-new-filter-item select.wpc-field-ename').get().reverse() ).each( function () {
542 + let eNameSelect = $(this);
543 +
544 + setTimeout( function(){ setAvailableEntities( eNameSelect, false ); }, time);
545 + time += 100;
546 + });
547 + });
548 +
407 549 $('body').on('change', '.wpc-field-entity', function(e){
408 - let select = $(this);
550 + let thisSelect = $(this);
551 + let theTitle = '';
409 552
410 553 // Set available entities again
411 - passNewEntities(select);
412 - syncEntityWithPrefix(select);
413 - handleMetaKeyField(select);
414 - handleLogicField(select);
415 - setEntityTableClass(select);
416 - syncEntityWithView(select);
417 - syncEntityWithSortTerms(select);
554 + passNewEntities(thisSelect);
555 + syncEntityWithPrefix(thisSelect);
556 + handleMetaKeyField(thisSelect);
557 + handleLogicField(thisSelect);
558 + setEntityTableClass(thisSelect);
559 + syncEntityWithView(thisSelect);
560 + syncEntityWithSortTerms(thisSelect);
418 561
419 - handleHierarchyField(select);
562 + handleHierarchyField(thisSelect);
563 + handleShowTerms( thisSelect );
420 564 // handleUsedForVariationsField(select);
421 565
422 566 // Load terms for exclude
423 567 let entity = $(this).val();
424 - let fid = $(this).parents('.wpc-filter-item').data('fid');
568 + let fid = $(this).parents('.wpc-filter-item').data('fid');
425 569
426 - if( entity === 'post_meta' || entity === 'post_meta_num' || entity === 'post_meta_exists' ){
570 + if ( entity === 'tax_numeric' ) {
571 + $('#wpc_filter_fields-'+fid+'-e_name').trigger('change');
572 + }
573 +
574 + // replace with includes
575 + if ( [ 'tax_numeric', 'post_meta', 'post_meta_num', 'post_meta_exists', 'post_date', 'post_meta_date' ].includes(entity) ) {
427 576 let target = $('#wpc_filter_fields-'+fid+'-exclude');
428 577 target.select2({
429 578 disabled: true,
430 579 width: '100%'
@@ -433,10 +582,25 @@
433 582 loadExcludeItems(entity, fid);
434 583 }
435 584
436 585 let entityLabel = $(this).find('option:selected').text();
437 - let target = $(this).parents('.wpc-filter-item').find('.wpc-filter-head li.wpc-filter-entity');
586 + let target = $(this).parents('.wpc-filter-item').find('.wpc-filter-head li.wpc-filter-entity');
438 587 target.text(entityLabel);
588 +
589 + theTitle = $("#wpc_filter_fields-"+fid+"-label").val();
590 +
591 + if( ! theTitle ){
592 + theTitle = wpcSetVars.newFilter;
593 + }
594 +
595 + $(".wpc-field-parent-filter option[value='"+fid+"'").each(function (index, element){
596 + $(this).text( theTitle + " (" +wpcShortenEname( entity )+ ")" );
597 + if( entity === 'post_meta_num' || entity === 'tax_numeric' || entity === 'taxonomy_product_visibility' ){
598 + $(this).attr('disabled', 'disabled');
599 + }else{
600 + $(this).removeAttr('disabled');
601 + }
602 + });
439 603 });
440 604
441 605 // Try to prepend slug if it already exists
442 606 $('body').on('input change', '.wpc-field-ename', function(){
@@ -445,13 +609,17 @@
445 609 let entity = $('#wpc_filter_fields-'+fid+'-entity').val();
446 610 let val = '';
447 611 let slugs = wpcSetVars.filterSlugs;
448 612
449 - if( entity === 'post_meta_num' ){
613 + if ( entity === 'post_meta_num' ) {
450 614 val = 'post_meta_num_' + ename;
451 - }else if( entity === 'post_meta_exists' ){
615 + } else if ( entity === 'tax_numeric' ) {
616 + val = 'tax_numeric_' + ename;
617 + } else if ( entity === 'post_meta_exists' ) {
452 618 val = 'post_meta_exists_' + ename;
453 - }else{
619 + } else if ( entity === 'post_meta_date' ) {
620 + val = 'post_meta_date_' + ename;
621 + }else {
454 622 val = 'post_meta_' + ename;
455 623 }
456 624
457 625 if( typeof slugs[val] !== 'undefined' ){
@@ -457,10 +625,10 @@
457 625 if( typeof slugs[val] !== 'undefined' ){
458 626 $('#wpc_filter_fields-'+fid+'-slug').val( slugs[val] )
459 627 .trigger('input');
460 628
461 - // Do not load exclude terms for Post Meta Num and Post Meta Exists
462 - if( entity !== 'post_meta_num' ){
629 + // Do not load exclude terms for Post Meta Num and Tax Numeric
630 + if( entity !== 'post_meta_num' && entity !== 'tax_numeric'){
463 631 loadExcludeItems(entity, fid, ename);
464 632 }
465 633
466 634 }else{
@@ -487,31 +655,86 @@
487 655 let target = $("#wpc-filter-id-apply-button").find('.wpc-button-reset');
488 656 cpaLiveWrite( $(this), target );
489 657 });
490 658
491 - $('body').on('input', '.wpc-field-slug', function (){
659 + $('body').on('input keydown', '#wpc_set_fields-search_field_placeholder', function (){
660 + let target = $("#wpc-filter-id-search-field").find('.wpc-text-input-search');
661 + target.attr('placeholder', $(this).val());
662 + });
663 +
664 + $('body').on('input keydown', '#wpc_set_fields-search_field_label', function (){
665 + let target = $("#wpc-filter-id-search-field").find('.wpc-filter-label');
666 + cpaLiveWrite( $(this), target );
667 + // target.attr('placeholder', $(this).val());
668 + });
669 +
670 + $('body').on('input keydown', '.wpc-field-slug', function (){
492 671 let target = $(this).parents('.wpc-filter-item').find('.wpc-filter-head li.wpc-filter-slug');
493 672 cpaLiveWrite( $(this), target );
494 673 });
495 674
496 - $('body').on('input', '.wpc-field-label', function (){
675 + $('body').on('input keydown', '.wpc-field-label', function (){
497 676 let target = $(this).parents('.wpc-filter-item').find('.wpc-filter-head li.wpc-filter-label');
498 677 cpaLiveWrite( $(this), target );
678 +
679 + let fid = $(this).parents(".wpc-filter-item").data('fid');
680 + let eName = $("#wpc_filter_fields-"+fid+"-entity").val();
681 + eName = wpcShortenEname( eName );
682 + let theTitle = $(this).val();
683 +
684 + $(".wpc-field-parent-filter option[value='"+fid+"'").each(function (index, element){
685 + $(this).text( theTitle + " (" + eName + ")" );
686 + });
499 687 });
500 688
689 + $('body').on('change', '.wpc-field-show-range-list', function (){
690 + let rangeListButtonChecked = $(this).prop( "checked" );
691 + if( rangeListButtonChecked ){
692 + $(".wpc-view-range").addClass('wpc-view-range-list');
693 + }else{
694 + $(".wpc-view-range").removeClass('wpc-view-range-list');
695 + }
696 + });
697 +
501 698 $('body').on('change', '.wpc-field-view', function(){
502 - let optionName = $(this).find('option:selected').text();
503 - let optionVal = $(this).find('option:selected').val();
504 - let $divFilterItem = $(this).parents('.wpc-filter-item');
505 - let target = $divFilterItem.find('.wpc-filter-head li.wpc-filter-view');
506 - let allowedViews = ['checkboxes', 'radio', 'labels'];
507 - target.text(optionName);
699 + const $this = $(this);
700 + const $option = $this.find('option:selected');
701 + const optionName = $option.text();
702 + const optionVal = $option.val();
703 + const $divFilterItem = $this.parents('.wpc-filter-item');
508 704
509 - if( allowedViews.includes(optionVal) ){
510 - $divFilterItem.find('.wpc-field-search-tr').show();
511 - }else{
512 - $divFilterItem.find('.wpc-field-search-tr').hide();
705 + // Update View Label in Header
706 + $divFilterItem.find('.wpc-filter-head li.wpc-filter-view').text(optionName);
707 +
708 + // Handle visibility of Search and More/Less fields
709 + const allowedViews = ['checkboxes', 'radio', 'labels'];
710 + const showExtraFields = allowedViews.includes(optionVal);
711 + $divFilterItem.find('.wpc-field-search-tr, .wpc-field-more-less-tr').toggle(showExtraFields);
712 +
713 + // Handle CSS classes for the fields table
714 + const $fieldsTable = $divFilterItem.find('.wpc-form-fields-table');
715 + const classesToRemove = 'wpc-view-checkboxes wpc-view-dropdown wpc-view-rating wpc-view-range selected-and-above-show';
716 +
717 + // Map option values to their specific CSS classes
718 + const viewClasses = {
719 + 'checkboxes': 'wpc-view-checkboxes',
720 + 'rating': 'wpc-view-rating',
721 + 'range': 'wpc-view-range',
722 + 'dropdown': 'wpc-view-dropdown'
723 + };
724 +
725 + // Reset classes first
726 + $fieldsTable.removeClass(classesToRemove);
727 +
728 + // Add specific class if exists in map
729 + if (viewClasses[optionVal]) {
730 + $fieldsTable.addClass(viewClasses[optionVal]);
513 731 }
732 +
733 + // Handle special case for 'rating'
734 + if (optionVal === 'rating') {
735 + $fieldsTable.addClass('selected-and-above-show');
736 + }
514 737 });
515 738
516 739 $( '.wpc-filter-set-wrapper .wpc-filters-list' ).sortable({
517 740 items: "> div.wpc-filter-item",
@@ -524,13 +747,12 @@
524 747 update: function( event, ui ) {
525 748 renderMenuOrder();
526 749 },
527 750 start: function ( event, ui ){
528 - var height, $this = $(this), // .wpc-filters-list
529 - head = ui.item.children('.wpc-filter-head'),
751 + let head = ui.item.children('.wpc-filter-head'),
530 752 inside = ui.item.children('.wpc-filter-body');
531 753
532 - if (inside.hasClass('wpc-opened') ) {
754 + if ( inside.hasClass('wpc-opened') ) {
533 755 inside.removeClass('wpc-opened')
534 756 .hide();
535 757 head.removeClass('wpc-opened');
536 758 $(this).sortable('refreshPositions');
@@ -570,8 +792,12 @@
570 792 }
571 793 })
572 794 }
573 795
796 + // Remove current filter from Parent filters list
797 + let dataFid = $(this).parents('.wpc-filter-item').data('fid');
798 + wpcDeleteFilterFromParentList( dataFid );
799 +
574 800 wp.ajax.post( 'wpc-delete-filter', requestParams )
575 801 .always( function() {
576 802 $spinner.removeClass( 'is-active' );
577 803 })
@@ -599,19 +825,29 @@
599 825 if( typeof response !== 'undefined'){
600 826 addFieldError( 'wpc-filter-delete-wrapper-'+response.fid, response.message );
601 827 }
602 828 });
603 -
604 829 });
605 830
606 831 // Get set location fields
832 + let selected_link = $('#wpc_set_fields-post_type option:selected').data('link');
833 + if(selected_link != ''){
834 + $('.wpc-location-preview-not-pro').removeClass('display-none');
835 + }
836 +
607 837 $('body').on('change', '#wpc_set_fields-post_type', function (){
608 838
609 - $("#wpc-filters-list").attr('data-posttype', $(this).val() );
839 + let postType = $(this).val();
840 + $("#wpc-filters-list").attr('data-posttype', postType );
841 + let link = $('option:selected', this).data('link');
842 + $('.wpc-location-preview-not-pro').attr('href', link);
610 843
611 - if( wpcSetVars.filtersPro < 1){
612 - return true;
844 + if(link != ''){
845 + $('.wpc-location-preview-not-pro').removeClass('display-none');
846 + }else{
847 + $('.wpc-location-preview-not-pro').addClass('display-none');
613 848 }
849 +
614 850 setAvailableEntities( $('.wpc-new-filter-item .wpc-field-entity') );
615 851
616 852 removeElement( $('.wpc-field-notice') );
617 853
@@ -619,8 +855,24 @@
619 855 let selected = $('#wpc_set_fields-wp_page_type').val();
620 856 if( typeof selected !== 'undefined' /*&& selected === 'common:common'*/ ){
621 857 wpcGetLocationTerms( selected );
622 858 }
859 +
860 + let selectEntity = $("select.wpc-field-entity");
861 +
862 + const postMetaValues = ['post_meta', 'post_meta_num', 'post_meta_exists', 'post_meta_date'];
863 +
864 + // Change options in all select.wpc-field-ename
865 + let eNameSelect = $("select.wpc-field-ename");
866 + if(postMetaValues.includes(selectEntity.val())){
867 + handleMetaKeyField(selectEntity);
868 + return;
869 + }
870 +
871 + if( eNameSelect.length > 0 ) {
872 + fillTaxNumSelect( eNameSelect, postType );
873 + }
874 +
623 875 });
624 876
625 877 // Filtered WP_Query location
626 878 $('body').on('change', '#wpc_set_fields-wp_page_type', function(){
@@ -631,10 +883,8 @@
631 883 $('body').on('change', '#wpc_set_fields-apply_button_page_type', function(){
632 884 wpcGetApplyLocationTerms( $(this).val() );
633 885 });
634 886
635 - makeNoticesDismissible();
636 -
637 887 $('body').on('change', '#wpc_set_fields-post_name', function (e){
638 888 let filterPagelink = $('option:selected', this).data('link');
639 889
640 890 if( typeof filterPagelink !== 'undefined'){
@@ -641,8 +891,75 @@
641 891 wpcGetWpQueries( filterPagelink );
642 892 }
643 893 });
644 894
895 + $('body').on( 'change', '.wpc-date-format', function (e){
896 + let otherFieldName = $(this).attr('name');
897 + let $customField = $( '.wpc-date-custom-format[name="'+otherFieldName+'"]' );
898 + if ( $(this).attr('value') === 'other' ) {
899 + $customField.removeAttr('disabled');
900 + } else {
901 + $customField.val( $(this).val() );
902 + $customField.attr('disabled', 'disabled');
903 + }
904 + });
905 +
906 + $('body').on('change', '.wpc-date-type', function (e){
907 +
908 + let dataFid = $(this).parents('.wpc-filter-item').data('fid');
909 +
910 + let $spinner = $( '.wpc_filter_fields-'+dataFid+'-date_format-wrap' ).children( '.spinner' );
911 + $spinner.addClass( 'is-active' );
912 +
913 + // Set up AJAX request
914 + let requestParams = {};
915 + //requestParams._wpnonce = $("#wpc_set_nonce").val();
916 + requestParams.setId = $("#post_ID").val();
917 + requestParams.dateType = $("#wpc_filter_fields-"+dataFid+"-date_type").val();
918 + requestParams.fid = dataFid;
919 +
920 + wp.ajax.post( 'wpc_get_date_formats', requestParams )
921 + .always( function() {
922 + $spinner.removeClass( 'is-active' );
923 + })
924 + .done( function( response ) {
925 + if ( typeof response.html !== 'undefined' ) {
926 + let setDefault = true;
927 + let radioList = $(response.html).find('ul');
928 +
929 + $.each( radioList.find('input.wpc-date-format'), function( key, value ){
930 + let theOption = $(this);
931 + if( theOption.is(':checked') ){
932 + setDefault = false;
933 + return;
934 + }
935 + });
936 +
937 + if( setDefault === true ) {
938 + radioList.find('input.wpc-date-format:first').attr('checked', 'checked');
939 + }
940 +
941 + $( '.wpc_filter_fields-'+dataFid+'-date_format-wrap ul' ).replaceWith(radioList);
942 + }
943 + })
944 + .fail( function(response) {
945 + // {"success":false}
946 + });
947 + });
948 +
949 + $('body').on('change', '.wpc-field-parent-filter', function (){
950 + let parentNo = ['no', '-1'];
951 + let parentVal = $(this).val();
952 + let fid = $(this).parents('.wpc-filter-item').data('fid');
953 + let hideTr = $("#wpc-filter-id-"+fid+" .wpc-field-hide-until-parent-tr");
954 +
955 + if( parentNo.includes(parentVal) ){
956 + hideTr.removeClass('wpc-opened');
957 + }else{
958 + hideTr.addClass('wpc-opened');
959 + }
960 + });
961 +
645 962 $('body').on('click', '#wpc_set_fields-use_apply_button', function (){
646 963 let applyButtonChecked = $(this).prop( "checked" );
647 964
648 965 if( applyButtonChecked ){
@@ -656,33 +973,322 @@
656 973 $(".wpc-field-apply-button-text-tr").removeClass('wpc-opened');
657 974 $(".wpc-field-apply-button-page-type-tr").removeClass('wpc-opened');
658 975 $(".wpc-field-reset-button-text-tr").removeClass('wpc-opened');
659 976
660 - if( $(".wpc-filter-item:not(#wpc-filter-id-apply-button)").length < 1 ){
977 + if( $(".wpc-filter-item:visible").length < 1 ){
661 978 $('.wpc-no-filters').show();
662 979 }
663 980 }
664 981 });
665 982
983 + $('body').on('click', '#wpc_set_fields-horizontal_view', function (){
984 + let applyButtonChecked = $(this).prop( "checked" );
985 + $("#wpc_set_fields-horizontal_view_priority").val('filter_set');
986 + if( applyButtonChecked ){
987 + $(".wpc-field-horizontal-view-column-tr").addClass('wpc-opened');
988 + }else{
989 + $(".wpc-field-horizontal-view-column-tr").removeClass('wpc-opened');
990 + }
991 + });
992 +
993 + $('body').on('click', '#wpc_set_fields-use_search_field', function (){
994 + let searchFieldChecked = $(this).prop( "checked" );
995 +
996 + if( searchFieldChecked ){
997 + $("#wpc-filter-id-search-field").addClass('wpc-opened');
998 +
999 + $(".wpc-search-field-placeholder-tr").addClass('wpc-opened');
1000 + $(".wpc-search-field-label-tr").addClass('wpc-opened');
1001 +
1002 + $('.wpc-no-filters').hide();
1003 + }else{
1004 + $("#wpc-filter-id-search-field").removeClass('wpc-opened');
1005 +
1006 + $(".wpc-search-field-placeholder-tr").removeClass('wpc-opened');
1007 + $(".wpc-search-field-label-tr").removeClass('wpc-opened');
1008 +
1009 + if( $(".wpc-filter-item:visible").length < 1 ){
1010 + $('.wpc-no-filters').show();
1011 + }
1012 + }
1013 + });
1014 +
1015 + $('body').on('focus keypress blur', '.wpc-field-min-num-label, .wpc-field-max-num-label', function (e){
1016 + let wpcPosition = $(this).getCursorPosition();
1017 + $(this).data('caret', wpcPosition);
1018 + });
1019 +
1020 + $('body').on('click', '.wpc-variable-inserter', function (e){
1021 + let wrapper = $(this).parents('.wpc-filter-field-min-max-labels-wrap');
1022 + $.each( wrapper.find('input[type="text"]'), function( i, field ){
1023 + let inputField = $( field );
1024 + let valueVar = '{value}';
1025 + let caretPos = inputField.data('caret');
1026 +
1027 + if( caretPos === 0 ){
1028 + valueVar = valueVar+' ';
1029 + }else if( caretPos === inputField.val().length ){
1030 + valueVar = ' '+valueVar;
1031 + }else{
1032 + // Undefined or position in the end
1033 + valueVar = ' '+valueVar+' ';
1034 + }
1035 +
1036 + insertAtCaret( inputField, valueVar, caretPos );
1037 + } );
1038 +
1039 + });
1040 +
1041 +
666 1042 let filterPagelink = $('option:selected', $('#wpc_set_fields-post_name')).data('link');
1043 + $('.wpc-location-preview').addClass('display-none');
667 1044
668 1045 if( typeof filterPagelink !== 'undefined' && filterPagelink ){
1046 + $('.wpc-location-preview').removeClass('display-none');
669 1047 wpcGetWpQueries( filterPagelink );
670 1048 }
671 1049
672 - // Set correct position of the Apply button
673 - let applyButtonPosition = $("#wpc_set_fields-apply_button_menu_order").val();
674 - if( applyButtonPosition === '-1' ){
675 - let filtersLength = $('#wpc-filters-list').find(".wpc-filter-item").length.toString();
676 - $("#wpc_set_fields-apply_button_menu_order").val(filtersLength);
1050 + let notProFilterPagelink = $('option:selected', $('#wpc_set_fields-post_type')).data('link');
1051 + if( typeof notProFilterPagelink !== 'undefined' && notProFilterPagelink ){
1052 + $('.wpc-location-preview-not-pro').attr('href', notProFilterPagelink);
1053 + $('.wpc-location-preview-not-pro').removeClass('display-none');
677 1054 }
1055 + });
1056 + $('body').on('click', '.wpc-field-show-range-list-input', function (e){
1057 + e.preventDefault();
1058 + let $prevRow = $(this).prev('.range-list-value');
1059 + const $currentRangeValues = $(this)
1060 + .parent()
1061 + .find('.range-list-value');
1062 + if($('.wpc-range-list-value-error-button').length > 0){
1063 + $('.wpc-range-list-value-error-button').remove();
1064 + }
1065 + if($prevRow.length > 0 && $prevRow.find('.wpc-range-list-min-value').val() === '' && $prevRow.find('.wpc-range-list-max-value').val() === ''){
1066 + let error_html = `<div class="wpc-range-list-value-error-button"><span>${wpcSetVars.rangeListTexts.error}</span></div>`;
1067 + $(this).after(error_html);
1068 + return false;
1069 + }
678 1070
1071 + const name = $(this).attr('name');
1072 +
1073 +
1074 + let lastRangeListNumber = 1;
1075 +
1076 + if ($currentRangeValues.length) {
1077 + lastRangeListNumber =
1078 + Math.max(
1079 + ...$currentRangeValues.map(function () {
1080 + return Number($(this).data('list-number')) || 0;
1081 + }).get()
1082 + ) + 1;
1083 + }
1084 +
1085 + let html = `<div class="range-list-value" data-list-number="${lastRangeListNumber}">
1086 + <div class="wpc-range-list-inputs">
1087 + <div><input type="number" class="wpc-range-list-min-value" name="${name}[${lastRangeListNumber}][range_list_min_val]" placeholder="${wpcSetVars.rangeListTexts.min_value}"></div>
1088 + <div><input type="number" class="wpc-range-list-max-value" name="${name}[${lastRangeListNumber}][range_list_max_val]" placeholder="${wpcSetVars.rangeListTexts.max_value}"></div>
1089 + <div><input type="text" class="wpc-range-list-range-text" name="${name}[${lastRangeListNumber}][range_list_range_text]" placeholder="${wpcSetVars.rangeListTexts.label}"></div>
1090 + <div><button class="button remove-range-list-value">${wpcSetVars.rangeListValueToRemove}</button></div>
1091 + </div>
1092 + </div>`;
1093 + $(this).before(html);
1094 + if(wpcSetVars.limitForRangeList <= $(this).parent().find('.range-list-value').length){
1095 + $(this).prop('disabled', true);
1096 + return false;
1097 + }
1098 +
1099 + changeRangeListInputStatus();
679 1100 });
680 1101
1102 + $(document).on('keyup change mouseup', '.wpc-range-list-min-value, .wpc-range-list-max-value', function (e){
1103 + let $currentRow = $(this).parents('.range-list-value');
1104 + let $rangeListMin = $currentRow.find('.wpc-range-list-min-value');
1105 + let $rangeListMax = $currentRow.find('.wpc-range-list-max-value');
1106 + let rangeListTextVal = '';
1107 +
1108 + let $prevRow = $currentRow.prev('.range-list-value');
1109 + let rangeMinVal = $rangeListMin.val();
1110 + let rangeMaxVal = $rangeListMax.val();
1111 +
1112 +
1113 + if ($rangeListMin.val() === '') {
1114 + rangeMinVal = wpcSetVars.rangeListTexts.up_to;
1115 + }
1116 +
1117 +
1118 + if ($rangeListMax.val() === '') {
1119 + rangeMaxVal = wpcSetVars.rangeListTexts.and_up;
1120 + }
1121 +
1122 + if ($prevRow.length > 0) {
1123 + if ($prevRow.find('.wpc-range-list-max-value').val() !== '' && $prevRow.find('.wpc-range-list-max-value').val() !== 0) {
1124 + if(typeof $rangeListMin.val() !== 'undefined'){
1125 + rangeMinVal = $prevRow.find('.wpc-range-list-max-value').val();
1126 + if (e.type === 'change' && $rangeListMin.val() === '' && parseFloat(rangeMinVal) <= parseFloat($rangeListMax.val())) {
1127 + $rangeListMin.val(rangeMinVal);
1128 + }
1129 + }
1130 +
1131 + }
1132 + }
1133 +
1134 + if($rangeListMin.val() !== '') {
1135 + rangeMinVal = $rangeListMin.val();
1136 + }
1137 +
1138 + if($rangeListMin.val() === '' && parseFloat(rangeMinVal) >= parseFloat($rangeListMax.val())){
1139 + rangeMinVal = wpcSetVars.rangeListTexts.up_to;
1140 + }
1141 +
1142 + if(typeof rangeMinVal === 'undefined'){
1143 + rangeMinVal = wpcSetVars.rangeListTexts.up_to;
1144 + }
1145 +
1146 + rangeListTextVal += rangeMinVal + ' - ' + rangeMaxVal;
1147 + if($rangeListMin.val() === '' && $rangeListMax.val() === '' ) {
1148 + rangeListTextVal = '';
1149 + }else{
1150 + if($currentRow.find('.wpc-range-list-value-error').length > 0){
1151 + $currentRow.find('.wpc-range-list-value-error').remove();
1152 + }
1153 + }
1154 +
1155 + if($('.wpc-range-list-value-error-button').length > 0){
1156 + $('.wpc-range-list-value-error-button').remove();
1157 + }
1158 +
1159 + if(e.type === 'change'){
1160 + if ($rangeListMin.val() != '' && $rangeListMax.val() != '' && parseFloat($rangeListMin.val()) >= parseFloat($rangeListMax.val())) {
1161 + let html_val_error = `<div class="wpc-range-list-value-error"><span>${wpcSetVars.rangeListTexts.value_error}</span></div>`;
1162 + $currentRow.append(html_val_error);
1163 + }
1164 + }
1165 + $currentRow.find('.wpc-range-list-range-text').val(rangeListTextVal);
1166 + });
1167 +
1168 + $(document).on('click', '.remove-range-list-value', function (e){
1169 + e.preventDefault();
1170 + $(this).parents('.range-list-value').remove();
1171 + if($('.range-list-value').length < wpcSetVars.limitForRangeList && $('.wpc-field-show-range-list-input').is(':disabled')){
1172 + $('.wpc-field-show-range-list-input').removeAttr('disabled');
1173 + }
1174 + if($('.wpc-range-list-value-error-button').length > 0){
1175 + $('.wpc-range-list-value-error-button').remove();
1176 + }
1177 + changeRangeListInputStatus();
1178 + });
1179 +
1180 + function changeRangeListInputStatus(){
1181 + let $rangeListValues = $('.wpc-field-show-range-list-input-tr').find('.range-list-value');
1182 + $rangeListValues.removeClass('wpc-is-first-range-list-value wpc-is-last-range-list-value');
1183 + $rangeListValues.first().addClass('wpc-is-first-range-list-value');
1184 + $rangeListValues.last().addClass('wpc-is-last-range-list-value');
1185 + /* if(!$rangeListValues.last().hasClass('wpc-is-first-range-list-value')){
1186 + $rangeListValues.last().addClass('wpc-is-last-range-list-value');
1187 + }*/
1188 + }
1189 +
1190 + function wpcShortenEname( eName ){
1191 + let shortenName = eName;
1192 +
1193 + if( eName.includes( 'taxonomy_' ) ){
1194 + if( eName.slice(0, 9) === 'taxonomy_' ){
1195 + shortenName = eName.slice(9);
1196 + }
1197 + }else if( eName.includes( 'author_' ) ){
1198 + if( eName.slice(0, 7) === 'author_' ){
1199 + shortenName = eName.slice(7);
1200 + }
1201 + }
1202 +
1203 + return shortenName;
1204 + }
1205 +
1206 + function wpcAddNewFilterToParentList(){
1207 + let allIds = {};
1208 + let theFid = 0;
1209 + let theTitle = ''
1210 + let theEname = '';
1211 + let theNoVal = false;
1212 + let possibleOption = false;
1213 + let newOption = false;
1214 +
1215 + $(".wpc-filter-item:not(.wpc-filter-not-listed)").each( function ( index, elem ){
1216 + theFid = $(this).data('fid');
1217 + theTitle = $("#wpc_filter_fields-"+theFid+"-label").val();
1218 +
1219 + if( ! theTitle ){
1220 + theTitle = wpcSetVars.newFilter;
1221 + }
1222 +
1223 + theEname = $("#wpc_filter_fields-"+theFid+"-entity").val();
1224 + // theEname = wpcShortenEname(theEname);
1225 +
1226 + allIds[theFid] = { 'id' : theFid.toString(), 'title': theTitle, 'ename': theEname};
1227 + } );
1228 +
1229 + // In case if there is only single filter in Set
1230 + if( Object.keys(allIds).length < 2 ){
1231 + //console.log('Less than 2');
1232 + return;
1233 + }
1234 +
1235 + // If there are 2 or more filters
1236 + $.each( allIds, function ( index, elem ){
1237 +
1238 + theNoVal = $( "#wpc_filter_fields-"+elem['id']+"-parent_filter > option[value='no']");
1239 + if( theNoVal.length > 0 ){
1240 + theNoVal.val( '-1' );
1241 + theNoVal.text( wpcSetVars.selectFilter );
1242 + }
1243 +
1244 + $.each( allIds, function ( inindex, inelem ){
1245 + if( elem['id'] === inindex ){
1246 + return;
1247 + }
1248 +
1249 + possibleOption = $( "#wpc_filter_fields-"+elem['id']+"-parent_filter > option[value='"+inindex+"']");
1250 + if( possibleOption.length < 1 ){
1251 + newOption = $('<option>', {
1252 + value: inindex,
1253 + text: inelem['title']+" ("+wpcShortenEname( inelem['ename'] )+")"
1254 + });
1255 +
1256 + if( inelem['ename'] === 'post_meta_num' || inelem['ename'] === 'tax_numeric' ){
1257 + newOption.attr("disabled", "disabled");
1258 + }
1259 +
1260 + $( "#wpc_filter_fields-"+elem['id']+"-parent_filter").append( newOption );
1261 + }
1262 + });
1263 + });
1264 + }
1265 +
1266 + function wpcDeleteFilterFromParentList( filterId )
1267 + {
1268 + let theOption = false;
1269 +
1270 + $(".wpc-field-parent-filter option[value='"+filterId+"'").each(function (index, element){
1271 + theOption = $(this);
1272 + let theSelect = theOption.parents("select");
1273 +
1274 + if( theOption.is(':selected') ){
1275 + theSelect.val( theSelect.find("option:first").val() );
1276 + }
1277 +
1278 + theOption.remove();
1279 +
1280 + if( theSelect.find("option").length === 1 ){
1281 + theOption = theSelect.find("option:first");
1282 + theOption.val('no');
1283 + theOption.text(wpcSetVars.addFilter);
1284 + theSelect.val('no');
1285 + }
1286 +
1287 + });
1288 + }
1289 +
681 1290 function wpcGetWpQueries( filterPagelink ){
682 - if( wpcSetVars.filtersPro < 1){
683 - return true;
684 - }
685 1291
686 1292 if( filterPagelink === '' ){
687 1293 return true;
688 1294 }
@@ -701,9 +1307,14 @@
701 1307 requestParams.postType = postType;
702 1308 requestParams.postId = $("#post_ID").val();
703 1309 requestParams.action = 'wpc_get_wp_queries';
704 1310
1311 + let chooseButtonLink = new URL(filterPagelink);
705 1312
1313 + chooseButtonLink.searchParams.set('flrt_get_html_selector', '1');
1314 + chooseButtonLink.searchParams.set('flrt_set_id', requestParams.postId);
1315 +
1316 +
706 1317 $.ajax({
707 1318 'method': 'POST',
708 1319 'data': requestParams,
709 1320 'url': filterPagelink,
@@ -710,8 +1321,9 @@
710 1321 'dataType': 'html',
711 1322 beforeSend: function () {
712 1323 $spinner.addClass( 'is-active' );
713 1324 $(".wpc-location-preview").attr('href', filterPagelink);
1325 + $("#wpc-choose-selector-button").attr('href', chooseButtonLink.href);
714 1326 },
715 1327 complete: function () {
716 1328 $spinner.removeClass( 'is-active' );
717 1329 },
@@ -782,8 +1394,27 @@
782 1394 requestParams.wpPageType = selected;
783 1395 requestParams.postType = postType;
784 1396 requestParams.postId = $("#post_ID").val();
785 1397
1398 + const isFreeVersion = Number(wpcSetVars.filtersPro) < 1;
1399 + const $addFilterDiv = $('.wpc-add-filter-div');
1400 + const $submitButton = $('#publishing-action input[type=submit]');
1401 + const $publishingActionDiv = $('#publishing-action');
1402 + const applyFreeFiltersUiState = (isLimited, isLoading) => {
1403 + if (!isFreeVersion) return;
1404 +
1405 + $addFilterDiv.toggleClass('wpc_under_limit_filter_set', Boolean(isLimited));
1406 + $publishingActionDiv.toggleClass('wpc_under_limit_filter_set_publish', Boolean(isLimited));
1407 +
1408 + if (isLoading) {
1409 + $submitButton.addClass('disabled').prop('disabled', true);
1410 + } else {
1411 + $submitButton.removeClass('disabled').prop('disabled', false);
1412 + }
1413 + };
1414 +
1415 + applyFreeFiltersUiState(isLimitFilterSet, true);
1416 +
786 1417 wp.ajax.post( 'wpc-get-set-location-terms', requestParams )
787 1418 .always( function() {
788 1419 $spinner.removeClass( 'is-active' );
789 1420 })
@@ -791,8 +1422,11 @@
791 1422 //
792 1423 let locationTermsSelect = $(response.html).find('#wpc_set_fields-post_name');
793 1424 $( '#wpc_set_fields-post_name' ).replaceWith(locationTermsSelect);
794 1425
1426 + isLimitFilterSet = response.isLimitFilterSet;
1427 + applyFreeFiltersUiState(isLimitFilterSet, false);
1428 +
795 1429 let filterPagelink = $('option:selected', $('#wpc_set_fields-post_name') ).data('link');
796 1430 if( typeof filterPagelink !== 'undefined'){
797 1431 wpcGetWpQueries( filterPagelink );
798 1432 }
@@ -807,13 +1441,12 @@
807 1441 }
808 1442
809 1443 function cpaLiveWrite( readFrom, writeTo ) {
810 1444 let cpaText;
811 -
812 - readFrom.on('input', function() {
813 - cpaText = $(this).val();
1445 + // readFrom.on('input', function() {
1446 + cpaText = readFrom.val(); //$(this).val();
814 1447 writeTo.text(cpaText);
815 - });
1448 + // });
816 1449 }
817 1450
818 1451 /**
819 1452 * Calculates correct menu order in accordance with filter position in list
@@ -821,19 +1454,21 @@
821 1454 function renderMenuOrder()
822 1455 {
823 1456 $(".wpc-filter-item").each( function ( index, element ) {
824 1457 var num = index + 1;
825 - $(element).find('.wpc-menu-order-field').attr('value', num );
826 - // $(element).find('.wpc-filter-sortable-handle').text(num);
1458 + $(element).find('.wpc-menu-order-field').attr( 'value', num );
1459 + $(element).find('.wpc-filter-order').attr( 'title', num );
827 1460 });
828 1461 }
829 1462
830 1463 function handleNoFiltersMessage()
831 1464 {
832 - if( $(".wpc-filter-item:not(#wpc-filter-id-apply-button)").length > 0 ){
1465 + if( $(".wpc-filter-item:not(.wpc-filter-not-listed)").length > 0 ){
833 1466 $('.wpc-no-filters').hide();
834 1467 }else{
835 - $('.wpc-no-filters').show();
1468 + if ( $(".wpc-filter-not-listed").hasClass('wpc-opened') === false ){
1469 + $('.wpc-no-filters').show();
1470 + }
836 1471 }
837 1472 }
838 1473
839 1474 function setEntityTableClass( entitySelect )
@@ -886,18 +1521,29 @@
886 1521
887 1522 function syncEntityWithView( entitySelect ){
888 1523 let val = entitySelect.val();
889 1524 let fid = entitySelect.parents('.wpc-filter-item').data('fid');
890 -
891 - if( val === 'post_meta_num' ) {
892 - $('#wpc_filter_fields-'+fid+'-view option:not([value="range"])').attr('disabled', 'disabled');
893 - $('#wpc_filter_fields-'+fid+'-view option[value="range"]').removeAttr('disabled')
1525 + if( val === 'post_meta_num' || val === 'tax_numeric' ) {
1526 + $('#wpc_filter_fields-' + fid + '-view option:not([value="range"])').attr('disabled', 'disabled');
1527 + $('#wpc_filter_fields-' + fid + '-view option[value="range"]').removeAttr('disabled').prop('selected', true);
1528 + $('#wpc_filter_fields-' + fid + '-view').trigger('change');
1529 + } else if ( val === 'taxonomy_product_visibility' ) {
1530 + $('#wpc_filter_fields-' + fid + '-view option[value="rating"]').removeAttr('disabled')
894 1531 .prop('selected', true);
895 -
1532 + $('.wpc-form-fields-table').addClass('wpc-view-rating');
1533 + }
1534 + else if ( val === 'post_date' || val === 'post_meta_date' ) {
1535 + $('#wpc_filter_fields-' + fid + '-view option:not([value="date"])').attr('disabled', 'disabled');
1536 + $('#wpc_filter_fields-' + fid + '-view option[value="date"]').removeAttr('disabled')
1537 + .prop('selected', true);
1538 + $('#wpc_filter_fields-' + fid + '-view').trigger('change');
896 1539 }else{
897 1540 $('#wpc_filter_fields-'+fid+'-view option').removeAttr('disabled')
898 1541 $('#wpc_filter_fields-'+fid+'-view option:not([disabled]):first').prop('selected', true);
899 1542 $('#wpc_filter_fields-'+fid+'-view option[value="range"]').attr('disabled', 'disabled');
1543 + $('#wpc_filter_fields-'+fid+'-view option[value="rating"]').attr('disabled', 'disabled');
1544 + $('#wpc_filter_fields-'+fid+'-view option[value="date"]').attr('disabled', 'disabled');
1545 + $('#wpc_filter_fields-'+fid+'-view').trigger('change');
900 1546 }
901 1547 }
902 1548
903 1549
@@ -905,18 +1551,20 @@
905 1551 {
906 1552 let val = entitySelect.val();
907 1553 let fid = entitySelect.parents('.wpc-filter-item').data('fid');
908 1554
909 - if( val === 'author_author' || val === 'post_meta_exists' ) {
910 - $('#wpc_filter_fields-' + fid + '-logic option[value="and"]').attr('disabled', 'disabled');
911 - $('#wpc_filter_fields-' + fid + '-logic option[value="or"]').prop('selected', true);
912 -
913 - }else if( val === 'post_meta_num' ){
914 - $('#wpc_filter_fields-' + fid + '-logic option[value="or"]').attr('disabled', 'disabled');
915 - $('#wpc_filter_fields-' + fid + '-logic option[value="and"]').prop('selected', true);
916 - }else{
917 - $('#wpc_filter_fields-'+fid+'-logic option[value="and"]').removeAttr('disabled');
918 - $('#wpc_filter_fields-'+fid+'-logic option[value="or"]').removeAttr('disabled');
1555 + if ( val === 'author_author' || val === 'post_meta_exists' || val === 'taxonomy_product_visibility' ) {
1556 + $( '#wpc_filter_fields-' + fid + '-logic option[value="and"]' ).attr( 'disabled', 'disabled' );
1557 + $( '#wpc_filter_fields-'+fid+'-logic option[value="or"]' ).removeAttr( 'disabled' );
1558 + $( '#wpc_filter_fields-' + fid + '-logic option[value="or"]' ).prop( 'selected', true );
1559 + } else if ( val === 'post_meta_num' || val === 'tax_numeric' || val === 'post_date' || val === 'post_meta_date' ) {
1560 + // If filter is numeric logic can be AND only
1561 + $( '#wpc_filter_fields-' + fid + '-logic option[value="or"]' ).attr( 'disabled', 'disabled' );
1562 + $( '#wpc_filter_fields-' + fid + '-logic option[value="and"]' ).removeAttr( 'disabled');
1563 + $( '#wpc_filter_fields-' + fid + '-logic option[value="and"]' ).prop( 'selected', true );
1564 + } else {
1565 + $( '#wpc_filter_fields-'+fid+'-logic option[value="and"]' ).removeAttr( 'disabled' );
1566 + $( '#wpc_filter_fields-'+fid+'-logic option[value="or"]' ).removeAttr( 'disabled' );
919 1567 }
920 1568
921 1569 return true;
922 1570 }
@@ -923,10 +1571,9 @@
923 1571
924 1572 function handleHierarchyField( entitySelect )
925 1573 {
926 1574 let val = entitySelect.val();
927 - let fid = entitySelect.parents('.wpc-filter-item').data('fid');
928 - let posttype = $("#wpc-filters-list").attr('data-posttype');
1575 + let $divFilterItem = entitySelect.parents('.wpc-filter-item');
929 1576
930 1577 if( val.indexOf('taxonomy') !== -1 ){
931 1578 $.each( wpcSetVars.postTypesTaxList, function ( pType, taxesArray ){
932 1579 $.each( taxesArray, function ( index, theTax ){
@@ -931,15 +1578,17 @@
931 1578 $.each( wpcSetVars.postTypesTaxList, function ( pType, taxesArray ){
932 1579 $.each( taxesArray, function ( index, theTax ){
933 1580 if( theTax['name'] === val ){
934 1581 if( theTax['hierarchical'] ){
935 - $("#wpc-filter-id-"+fid+" .wpc-field-hierarchy-tr").show();
1582 + $divFilterItem.find('.wpc-form-fields-table').addClass('taxonomy-hierarchical');
936 1583 }else{
937 - $("#wpc-filter-id-"+fid+" .wpc-field-hierarchy-tr").hide();
1584 + $divFilterItem.find('.wpc-form-fields-table').removeClass('taxonomy-hierarchical');
938 1585 }
939 1586 }
940 1587 });
941 1588 });
1589 + } else {
1590 + $divFilterItem.find('.wpc-form-fields-table').removeClass('taxonomy-hierarchical');
942 1591 }
943 1592 }
944 1593
945 1594 function handleMetaKeyField( entitySelect )
@@ -945,18 +1594,241 @@
945 1594 function handleMetaKeyField( entitySelect )
946 1595 {
947 1596 let val = entitySelect.val();
948 1597 let fid = entitySelect.parents('.wpc-filter-item').data('fid');
1598 + let postType = $("#wpc_set_fields-post_type").val();
949 1599
950 - if( val === 'post_meta' || val === 'post_meta_num' || val === 'post_meta_exists' ){
951 - $('#wpc_filter_fields-'+fid+'-e_name').val('')
952 - .removeAttr('readonly')
953 - .parents('.wpc-field-ename-tr').show();
954 - }else{
955 - $('#wpc_filter_fields-'+fid+'-e_name').parents('.wpc-field-ename-tr').hide();
1600 + if ( val === 'post_meta' || val === 'post_meta_num' || val === 'post_meta_exists' || val === 'post_meta_date' ) {
1601 + let eNameTag = $('#wpc_filter_fields-'+fid+'-e_name');
1602 + if ( eNameTag.prop("tagName").toLowerCase() === 'select' && eNameTag.is('[readonly]')) {
1603 + let eNameInput = $('<input>');
1604 +
1605 + eNameInput.attr( 'class', eNameTag.attr('class') )
1606 + .attr( 'type', 'text' )
1607 + .attr( 'name', eNameTag.attr('name') )
1608 + .attr( 'id', eNameTag.attr('id') );
1609 +
1610 + eNameTag.val('');
1611 + eNameTag.removeAttr('readonly');
1612 + eNameTag.replaceWith(eNameInput);
1613 +
1614 + eNameInput.parents('.wpc-field-ename-tr').show();
1615 + } else {
1616 + if (eNameTag.length > 0 && eNameTag.hasClass('select2-hidden-accessible')) {
1617 + eNameTag.select2('destroy');
1618 + eNameTag.empty();
1619 + eNameTag.off();
1620 + }
1621 + let eNameSelect = $('<select>');
1622 + eNameSelect
1623 + .attr('class', eNameTag.attr('class'))
1624 + .attr('name', eNameTag.attr('name'))
1625 + .attr('id', eNameTag.attr('id'));
1626 +
1627 + eNameTag.val('');
1628 + eNameTag.replaceWith(eNameSelect);
1629 +
1630 + const defaultCustomMetaKeys = wpcSetVars.defaultCustomMetaKeys;
1631 +
1632 + const ptItems = defaultCustomMetaKeys?.[postType]?.[val];
1633 + const allItems = defaultCustomMetaKeys?.['all_post_types']?.[val];
1634 +
1635 + const getItems = (items) => {
1636 + if (items && typeof items === 'object') {
1637 + Object.entries(items).forEach(function ([key, value]) {
1638 + items[key] = value;
1639 + });
1640 + return items;
1641 + }
1642 + return [];
1643 + }
1644 +
1645 + let tItems = [];
1646 +
1647 + tItems = getItems(ptItems);
1648 + if (tItems.length > 0) {
1649 + tItems.push(getItems(allItems));
1650 + }
1651 +
1652 + const prefillItems = Object.entries(tItems).map(([key, value]) => ({
1653 + id: key,
1654 + text: value
1655 + }));
1656 +
1657 + let minimumInputLength = 1;
1658 + if(prefillItems.length > 0){
1659 + minimumInputLength = 0;
1660 + }
1661 +
1662 + eNameSelect.select2({
1663 + width: '100%',
1664 + ajax: {
1665 + url: ajaxurl,
1666 + dataType: 'json',
1667 + data: function (params) {
1668 + return {
1669 + action: 'wpc_search_meta_keys',
1670 + _flrt_nonce: $('#wpc_set_nonce').val(),
1671 + post_type: postType,
1672 + post_meta_type: val,
1673 + q: params.term || ''
1674 + };
1675 + },
1676 + transport: function (params, success, failure) {
1677 + let dots = 0;
1678 + let animatedDotInterval;
1679 + const startAnimation = (el)=> {
1680 + if (!animatedDotInterval) { // Prevent multiple intervals
1681 + animatedDotInterval = setInterval(function() {
1682 + if (dots < 3) {
1683 + el.append('.');
1684 + dots++;
1685 + } else {
1686 + el.text(''); // Clear dots
1687 + dots = 0;
1688 + }
1689 + }, 400); // Interval in milliseconds
1690 + }
1691 + }
1692 + if($('.loading-dots-search').length > 0){
1693 + startAnimation($('.loading-dots-search'));
1694 + }
1695 +
1696 + let term = (params.data && (params.data.q || params.data.term)) || '';
1697 +
1698 + if (!term && prefillItems.length > 0) {
1699 + success({ items: prefillItems });
1700 + return {
1701 + abort: function () {}
1702 + };
1703 + }
1704 +
1705 +
1706 + let delayTime = term ? 0 : 1000;
1707 + let doRequest = function () {
1708 + let $request = $.ajax(params);
1709 + $request.then(success);
1710 + $request.fail(failure);
1711 + return $request;
1712 + };
1713 + if (delayTime > 0) {
1714 + let timeout = setTimeout(doRequest, delayTime);
1715 + return {
1716 + abort: function () { clearTimeout(timeout); }
1717 + };
1718 + }
1719 + return doRequest();
1720 + },
1721 + processResults: function (data, params) {
1722 + let items = (data && data.items) ? data.items : [];
1723 + if (!params || !params.term || !params.q) {
1724 + if (!items.length && prefillItems.length) {
1725 + return { results: prefillItems };
1726 + }
1727 + }
1728 +
1729 + if (items.length > 0) {
1730 + items.forEach((el, index) => {
1731 + if(el.text !== '' && el.text !== el.id && !el.text.startsWith(el.id)){
1732 + el.text = el.id + '<span class="wpc-select2-dots">:</span><span class="wpc-select2-info">' + el.text + '</span>';
1733 + } else if (el.text !== '' && el.text !== el.id && el.text.startsWith(el.id)) {
1734 + }else{
1735 + el.text = el.id;
1736 + }
1737 + items[index] = el;
1738 + });
1739 + }
1740 +
1741 + return { results: items };
1742 + },
1743 + cache: false
1744 +
1745 + },
1746 + placeholder: wpcSetVars.selectMetaKeyPlaceholder,
1747 + allowClear: true,
1748 + minimumInputLength: minimumInputLength,
1749 + templateSelection: function (data, container) {
1750 + if (data.id === '' || !data.id) {
1751 + return wpcSetVars.selectMetaKeyPlaceholder;
1752 + }
1753 + return data.id;
1754 + },
1755 + escapeMarkup: function (markup) { return markup; },
1756 + language: {
1757 + searching: function () {
1758 + return $('<span>' + wpcSetVars.metaKeySearchText +'</span><span class="loading-dots-search"></span>')
1759 +
1760 + },
1761 + errorLoading: function () {
1762 + return $('<span>' + wpcSetVars.metaKeySearchText + '</span><span class="loading-dots-search"></span>')
1763 + }
1764 + },
1765 + });
1766 +
1767 + eNameSelect.parents('.wpc-field-ename-tr').show();
1768 + }
1769 +
1770 + $('#wpc-filter-id-'+fid+' .wpc-field-ename-tr p.wpc-field-description').text( numFieldAttrs['post_meta_num']['description'] );
1771 + $('#wpc-filter-id-'+fid+' .wpc-field-ename-tr label.wpc-filter-label span.wpc-label-text').text( numFieldAttrs['post_meta_num']['label'] );
1772 + $('#wpc-filter-id-'+fid+' .wpc-field-ename-tr p.description').css('visibility', 'visible');
1773 +
1774 + } else if ( val === 'tax_numeric' ) {
1775 + let eNameTag = $('#wpc_filter_fields-'+fid+'-e_name');
1776 + if (eNameTag.length > 0 && eNameTag.hasClass('select2-hidden-accessible')) {
1777 + eNameTag.select2('destroy');
1778 + eNameTag.empty();
1779 + eNameTag.off();
1780 + }
1781 +
1782 + let postType = $("#wpc_set_fields-post_type").val();
1783 + let tagName = eNameTag.prop("tagName").toLowerCase();
1784 +
1785 + if ( tagName === 'input') {
1786 + let eNameSelect = $('<select>');
1787 +
1788 + eNameSelect.attr( 'class', eNameTag.attr('class') )
1789 + .attr( 'name', eNameTag.attr('name') )
1790 + .attr( 'id', eNameTag.attr('id') );
1791 +
1792 + eNameTag.removeAttr( 'readonly' );
1793 + eNameTag.replaceWith( eNameSelect );
1794 + //@todo - if already existing tax_numeric slug presents, it should be inserted as usual
1795 + //@todo - if filter by this tax numeric entity exists, it should be deactivated in the Tax num dropdown
1796 + fillTaxNumSelect( eNameSelect, postType );
1797 + eNameSelect.parents('.wpc-field-ename-tr').show();
1798 + } else {
1799 + fillTaxNumSelect( eNameTag, postType );
1800 + eNameTag.parents('.wpc-field-ename-tr').show();
1801 + }
1802 +
1803 + $('#wpc-filter-id-'+fid+' .wpc-field-ename-tr p.wpc-field-description').text( numFieldAttrs['tax_numeric']['description'] );
1804 + $('#wpc-filter-id-'+fid+' .wpc-field-ename-tr label.wpc-filter-label span.wpc-label-text').text( numFieldAttrs['tax_numeric']['label'] );
1805 + $('#wpc-filter-id-'+fid+' .wpc-field-ename-tr p.description').css('visibility', 'hidden');
1806 +
1807 + } else {
1808 + let eNameTag = $('#wpc_filter_fields-'+fid+'-e_name');
1809 + if ( eNameTag.prop("tagName").toLowerCase() === 'select') {
1810 +
1811 + if (eNameTag.length > 0 && eNameTag.hasClass('select2-hidden-accessible')) {
1812 + eNameTag.select2('destroy');
1813 + eNameTag.empty();
1814 + eNameTag.off();
1815 + }
1816 +
1817 + let eNameInput = $('<input>');
1818 + eNameInput.attr( 'class', eNameTag.attr('class') )
1819 + .attr( 'type', 'text' )
1820 + .attr( 'name', eNameTag.attr('name') )
1821 + .attr( 'id', eNameTag.attr('id') )
1822 + .attr( 'value', '');
1823 +
1824 + eNameTag.replaceWith(eNameInput);
1825 + $('#wpc_filter_fields-'+fid+'-e_name').parents('.wpc-field-ename-tr').hide();
1826 + }
956 1827 }
957 1828
958 - if( val === 'post_meta_num' ){
1829 + // Numeric values can not be in URL path
1830 + if( val === 'post_meta_num' || val === 'tax_numeric' || val === 'post_date' || val === 'post_meta_date' ){
959 1831 $('#wpc_filter_fields-'+fid+'-in_path').prop( "checked", false );
960 1832 // $('#wpc_filter_fields-'+fid+'-show_chips').prop( "checked", false );
961 1833 }else{
962 1834 $('#wpc_filter_fields-'+fid+'-in_path').prop( "checked", true );
@@ -965,10 +1837,8 @@
965 1837 }
966 1838
967 1839 function loadExcludeItems( entity, fid, ename )
968 1840 {
969 - // let val = entitySelect.val();
970 - // let fid = entitySelect.parents('.wpc-filter-item').data('fid');
971 1841 removeElement( $('.wpc-field-notice') );
972 1842 let requestParams = {};
973 1843 let target = $('#wpc_filter_fields-'+fid+'-exclude');
974 1844 requestParams._wpnonce = $("#wpc_set_nonce").val();
@@ -1006,36 +1876,18 @@
1006 1876 });
1007 1877
1008 1878 }
1009 1879
1010 - function makeNoticesDismissible() {
1011 - $( '.wpc-error.is-dismissible' ).each( function() {
1012 - var $el = $( this ),
1013 - $button = $el.find('.notice-dismiss');
1014 - // Ensure plain text.
1015 - $button.on( 'click', function( event ) {
1016 - event.preventDefault();
1017 - $el.fadeTo( 100, 0, function() {
1018 - $el.slideUp( 100, function() {
1019 - $el.remove();
1020 - });
1021 - });
1022 - });
1023 -
1024 - $el.append( $button );
1025 - });
1026 - }
1027 -
1028 1880 function wpcSerialize( $el ){
1029 1881
1030 - var obj = {};
1031 - var inputs = $el.find('select, textarea, input').serializeArray();
1882 + let obj = {};
1883 + let inputs = $el.find('select, textarea, input').serializeArray();
1032 1884
1033 - for( var i = 0; i < inputs.length; i++ ) {
1885 + for( let i = 0; i < inputs.length; i++ ) {
1034 1886 wpcBuildObject( obj, inputs[i].name, inputs[i].value );
1035 1887 }
1036 1888 return obj;
1037 - };
1889 + }
1038 1890
1039 1891 function wpcBuildObject( obj, name, value ){
1040 1892 name = name.replace('[]', '[%%index%%]');
1041 1893
@@ -1074,9 +1926,38 @@
1074 1926 function wpcIsObject( a ){
1075 1927 return ( typeof a === 'object' );
1076 1928 }
1077 1929
1930 + /**
1931 + * Fills Tax Num Select with options
1932 + * @param $el (object) The select element
1933 + * @param postType Post type selected to filter
1934 + */
1935 + function fillTaxNumSelect( $el, postType ) {
1936 + $el.find('option')
1937 + .remove()
1938 + .end();
1939 +
1940 + if ( postType in postTypesTaxList ) {
1941 + $( postTypesTaxList[ postType ] ).each( function() {
1942 + $el.append( $("<option>").attr('value', this.name ).text( this.label ) );
1943 + });
1944 + } else {
1945 + $el.append( $("<option>").attr('value', -1 ).text( numFieldNoTaxes ) );
1946 + }
1947 + }
1948 +
1078 1949 })(jQuery);
1950 +
1951 +function insertAtCaret( target, text, caretPos )
1952 +{
1953 + let textAreaTxt = target.val();
1954 + let result = textAreaTxt.substring(0, caretPos) + text + textAreaTxt.substring(caretPos);
1955 + result = result.replace(/ +(?= )/g,'');
1956 + target.val(result);
1957 +
1958 + return true;
1959 +}
1079 1960
1080 1961 // Important!!!
1081 1962 // When field Filter by is selected, it is required to make AJAX request to find the same
1082 1963 // entity in filters already. And if it is exists, to predefine field "slug" defined in previous