| 1 |
// noinspection JSUnresolvedReference,JSValidateTypes |
| 2 |
|
| 3 |
;(function ($) { |
| 4 |
'use strict'; |
| 5 |
|
| 6 |
/** |
| 7 |
* Initialize the King Addons Select2 wrapper |
| 8 |
* @param {string|HTMLElement|jQuery} selector - The element(s) to attach Select2 to |
| 9 |
*/ |
| 10 |
const initTargetRuleSelect2 = (selector) => { |
| 11 |
$(selector).kngselect2({ |
| 12 |
placeholder: kngRules.search, |
| 13 |
ajax: { |
| 14 |
url: ajaxurl, |
| 15 |
dataType: 'json', |
| 16 |
method: 'post', |
| 17 |
delay: 250, |
| 18 |
data: (params) => ({ |
| 19 |
q: params.term, |
| 20 |
page: params.page, |
| 21 |
action: 'king_addons_el_hf_get_posts_by_query', |
| 22 |
nonce: kngRules.ajax_nonce, |
| 23 |
}), |
| 24 |
processResults: (data) => ({ |
| 25 |
results: data, |
| 26 |
}), |
| 27 |
cache: true, |
| 28 |
}, |
| 29 |
minimumInputLength: 2, |
| 30 |
}); |
| 31 |
}; |
| 32 |
|
| 33 |
/** |
| 34 |
* Update the hidden input field that stores rule data |
| 35 |
* @param {jQuery} wrapper - The wrapper element containing rule fields |
| 36 |
*/ |
| 37 |
const updateTargetRuleInput = (wrapper) => { |
| 38 |
const ruleInput = wrapper.find('.king-addons-el-hf-target_rule-input'); |
| 39 |
const newValues = []; |
| 40 |
|
| 41 |
wrapper.find('.king-addons-el-hf-target-rule-condition').each(function () { |
| 42 |
const $this = $(this); |
| 43 |
const ruleConditionVal = $this.find('select.target_rule-condition').val(); |
| 44 |
const specificPageVal = $this.find('select.target_rule-specific-page').val(); |
| 45 |
|
| 46 |
if (ruleConditionVal !== '') { |
| 47 |
newValues.push({ |
| 48 |
type: ruleConditionVal, |
| 49 |
specific: specificPageVal, |
| 50 |
}); |
| 51 |
} |
| 52 |
}); |
| 53 |
|
| 54 |
ruleInput.val(JSON.stringify(newValues)); |
| 55 |
}; |
| 56 |
|
| 57 |
/** |
| 58 |
* Update close button visibility |
| 59 |
* @param {jQuery} wrapper - The wrapper element containing rule fields |
| 60 |
*/ |
| 61 |
const updateCloseButton = (wrapper) => { |
| 62 |
const parentWrapper = wrapper.closest('.king-addons-el-hf-target-rule-wrapper'); |
| 63 |
const type = parentWrapper.attr('data-type'); |
| 64 |
const rules = wrapper.find('.king-addons-el-hf-target-rule-condition'); |
| 65 |
|
| 66 |
let showClose = false; |
| 67 |
if (type === 'display') { |
| 68 |
showClose = rules.length > 1; |
| 69 |
} else { |
| 70 |
// For exclude or other types |
| 71 |
showClose = true; |
| 72 |
} |
| 73 |
|
| 74 |
rules.each(function () { |
| 75 |
const deleteBtn = $(this).find('.target_rule-condition-delete'); |
| 76 |
if (showClose) { |
| 77 |
deleteBtn.removeClass('king-addons-el-hf-hidden'); |
| 78 |
} else { |
| 79 |
deleteBtn.addClass('king-addons-el-hf-hidden'); |
| 80 |
} |
| 81 |
}); |
| 82 |
}; |
| 83 |
|
| 84 |
/** |
| 85 |
* Show/hide the exclusion rule block |
| 86 |
* @param {boolean} [forceShow=false] - Force show the block |
| 87 |
* @param {boolean} [forceHide=false] - Force hide the block |
| 88 |
*/ |
| 89 |
const updateExclusionButton = (forceShow = false, forceHide = false) => { |
| 90 |
const displayOn = $('.king-addons-el-hf-target-rule-display-on-wrap'); |
| 91 |
const excludeOn = $('.king-addons-el-hf-target-rule-exclude-on-wrap'); |
| 92 |
|
| 93 |
const excludeFieldWrap = excludeOn.closest('tr'); |
| 94 |
const addExcludeBlock = displayOn.find('.target_rule-add-exclusion-rule'); |
| 95 |
const excludeConditions = excludeOn.find('.king-addons-el-hf-target-rule-condition'); |
| 96 |
const firstConditionVal = excludeConditions.first().find('select.target_rule-condition').val() || ''; |
| 97 |
|
| 98 |
if (forceHide) { |
| 99 |
// Hide entire block and show "Add Exclusion" button |
| 100 |
excludeFieldWrap.addClass('king-addons-el-hf-hidden'); |
| 101 |
addExcludeBlock.removeClass('king-addons-el-hf-hidden'); |
| 102 |
} else if (forceShow) { |
| 103 |
// Show entire block and hide "Add Exclusion" button |
| 104 |
excludeFieldWrap.removeClass('king-addons-el-hf-hidden'); |
| 105 |
addExcludeBlock.addClass('king-addons-el-hf-hidden'); |
| 106 |
} else { |
| 107 |
// Decide based on the first condition |
| 108 |
if (excludeConditions.length === 1 && firstConditionVal === '') { |
| 109 |
excludeFieldWrap.addClass('king-addons-el-hf-hidden'); |
| 110 |
addExcludeBlock.removeClass('king-addons-el-hf-hidden'); |
| 111 |
} else { |
| 112 |
excludeFieldWrap.removeClass('king-addons-el-hf-hidden'); |
| 113 |
addExcludeBlock.addClass('king-addons-el-hf-hidden'); |
| 114 |
} |
| 115 |
} |
| 116 |
}; |
| 117 |
|
| 118 |
$(document).ready(() => { |
| 119 |
|
| 120 |
const selectorWrapper = $('.king-addons-el-hf-target-rule-selector-wrapper'); |
| 121 |
|
| 122 |
// Show/hide the specific page select if the condition is "specifics" |
| 123 |
$('.king-addons-el-hf-target-rule-condition').each(function () { |
| 124 |
const $this = $(this); |
| 125 |
const conditionVal = $this.find('select.target_rule-condition').val(); |
| 126 |
const specificPageWrap = $this.next('.target_rule-specific-page-wrap'); |
| 127 |
|
| 128 |
if (conditionVal === 'specifics') { |
| 129 |
specificPageWrap.slideDown(300); |
| 130 |
} |
| 131 |
}); |
| 132 |
|
| 133 |
// Initialize all existing Select2 fields |
| 134 |
$('select.target-rule-select2').each((i, el) => { |
| 135 |
initTargetRuleSelect2(el); |
| 136 |
}); |
| 137 |
|
| 138 |
// Update close button visibility in each wrapper |
| 139 |
selectorWrapper.each(function () { |
| 140 |
updateCloseButton($(this)); |
| 141 |
}); |
| 142 |
|
| 143 |
// Initial check for exclusion button |
| 144 |
updateExclusionButton(); |
| 145 |
|
| 146 |
/** |
| 147 |
* Handle changes to the condition dropdown |
| 148 |
*/ |
| 149 |
$(document).on( |
| 150 |
'change', |
| 151 |
'.king-addons-el-hf-target-rule-condition select.target_rule-condition', |
| 152 |
function () { |
| 153 |
const $this = $(this); |
| 154 |
const thisVal = $this.val(); |
| 155 |
const fieldWrap = $this.closest('.king-addons-el-hf-target-rule-wrapper'); |
| 156 |
const nextSpecificPageWrap = $this |
| 157 |
.closest('.king-addons-el-hf-target-rule-condition') |
| 158 |
.next('.target_rule-specific-page-wrap'); |
| 159 |
|
| 160 |
if (thisVal === 'specifics') { |
| 161 |
nextSpecificPageWrap.slideDown(300); |
| 162 |
} else { |
| 163 |
nextSpecificPageWrap.slideUp(300); |
| 164 |
} |
| 165 |
|
| 166 |
updateTargetRuleInput(fieldWrap); |
| 167 |
} |
| 168 |
); |
| 169 |
|
| 170 |
/** |
| 171 |
* Handle changes in the Select2 dropdowns |
| 172 |
*/ |
| 173 |
selectorWrapper.on( |
| 174 |
'change', |
| 175 |
'.target-rule-select2', |
| 176 |
function () { |
| 177 |
const fieldWrap = $(this).closest('.king-addons-el-hf-target-rule-wrapper'); |
| 178 |
updateTargetRuleInput(fieldWrap); |
| 179 |
} |
| 180 |
); |
| 181 |
|
| 182 |
/** |
| 183 |
* Add new rule condition |
| 184 |
*/ |
| 185 |
selectorWrapper.on( |
| 186 |
'click', |
| 187 |
'.target_rule-add-rule-wrap a', |
| 188 |
function (e) { |
| 189 |
e.preventDefault(); |
| 190 |
e.stopPropagation(); |
| 191 |
|
| 192 |
const $this = $(this); |
| 193 |
const id = parseInt($this.attr('data-rule-id'), 10); |
| 194 |
const newId = id + 1; |
| 195 |
const type = $this.attr('data-rule-type'); |
| 196 |
const ruleWrap = $this |
| 197 |
.closest('.king-addons-el-hf-target-rule-selector-wrapper') |
| 198 |
.find('.target_rule-builder-wrap'); |
| 199 |
const template = wp.template(`king-addons-el-hf-target-rule-${type}-condition`); |
| 200 |
const fieldWrap = $this.closest('.king-addons-el-hf-target-rule-wrapper'); |
| 201 |
|
| 202 |
// Append new template block |
| 203 |
ruleWrap.append(template({ id: newId, type })); |
| 204 |
|
| 205 |
// Re-initialize Select2 on the newly added field |
| 206 |
initTargetRuleSelect2(`.king-addons-el-hf-target-rule-${type}-on .target-rule-select2`); |
| 207 |
|
| 208 |
// Update data-rule-id for next addition |
| 209 |
$this.attr('data-rule-id', newId); |
| 210 |
|
| 211 |
updateCloseButton(fieldWrap); |
| 212 |
} |
| 213 |
); |
| 214 |
|
| 215 |
/** |
| 216 |
* Delete a rule condition |
| 217 |
*/ |
| 218 |
selectorWrapper.on( |
| 219 |
'click', |
| 220 |
'.target_rule-condition-delete', |
| 221 |
function () { |
| 222 |
const $this = $(this); |
| 223 |
const ruleCondition = $this.closest('.king-addons-el-hf-target-rule-condition'); |
| 224 |
const fieldWrap = $this.closest('.king-addons-el-hf-target-rule-wrapper'); |
| 225 |
const dataType = fieldWrap.attr('data-type'); |
| 226 |
|
| 227 |
// If exclusion type and only one condition, reset instead of removing |
| 228 |
if (dataType === 'exclude') { |
| 229 |
const allConditions = fieldWrap.find('.target_rule-condition'); |
| 230 |
if (allConditions.length === 1) { |
| 231 |
allConditions.val(''); |
| 232 |
fieldWrap.find('.target_rule-specific-page').val(''); |
| 233 |
allConditions.trigger('change'); |
| 234 |
updateExclusionButton(false, true); |
| 235 |
} else { |
| 236 |
// Remove the entire condition block and its sibling |
| 237 |
ruleCondition.next('.target_rule-specific-page-wrap').remove(); |
| 238 |
ruleCondition.remove(); |
| 239 |
} |
| 240 |
} else { |
| 241 |
// For display or others, simply remove |
| 242 |
ruleCondition.next('.target_rule-specific-page-wrap').remove(); |
| 243 |
ruleCondition.remove(); |
| 244 |
} |
| 245 |
|
| 246 |
// Re-index the rule conditions |
| 247 |
let count = 0; |
| 248 |
fieldWrap.find('.king-addons-el-hf-target-rule-condition').each(function (i) { |
| 249 |
const condition = $(this); |
| 250 |
const oldRuleId = condition.attr('data-rule'); |
| 251 |
const selectLocation = condition.find('.target_rule-condition'); |
| 252 |
const locationName = selectLocation.attr('name'); |
| 253 |
|
| 254 |
condition.attr('data-rule', i); |
| 255 |
selectLocation.attr('name', locationName.replace(`[${oldRuleId}]`, `[${i}]`)); |
| 256 |
|
| 257 |
condition |
| 258 |
.removeClass(`king-addons-el-hf-target-rule-${oldRuleId}`) |
| 259 |
.addClass(`king-addons-el-hf-target-rule-${i}`); |
| 260 |
|
| 261 |
count = i; |
| 262 |
}); |
| 263 |
|
| 264 |
// Update the data-rule-id for the "Add" button |
| 265 |
fieldWrap.find('.target_rule-add-rule-wrap a').attr('data-rule-id', count); |
| 266 |
|
| 267 |
updateCloseButton(fieldWrap); |
| 268 |
updateTargetRuleInput(fieldWrap); |
| 269 |
} |
| 270 |
); |
| 271 |
|
| 272 |
/** |
| 273 |
* Add an exclusion rule block |
| 274 |
*/ |
| 275 |
selectorWrapper.on( |
| 276 |
'click', |
| 277 |
'.target_rule-add-exclusion-rule a', |
| 278 |
function (e) { |
| 279 |
e.preventDefault(); |
| 280 |
e.stopPropagation(); |
| 281 |
updateExclusionButton(true); |
| 282 |
} |
| 283 |
); |
| 284 |
}); |
| 285 |
}(jQuery, window)); |