1(function($) { 2 'use strict'; 3 4 var instances_map = new Map(); 5 var max_visible_values = 3; 6 7 function ProductAttributesField($wrapper_element) { 8 this.$wrapper = $wrapper_element; 9 this.$loading_element = $wrapper_element.find('.cf7-pa-loading'); 10 this.$content_element = $wrapper_element.find('.cf7-pa-content'); 11 this.$options_list_element = $wrapper_element.find('.cf7-pa-options-list'); 12 this.$selected_list_element = $wrapper_element.find('.cf7-pa-selected-list'); 13 this.$hidden_input_element = $wrapper_element.find('.cf7-pa-hidden-input'); 14 this.$modal_element = $wrapper_element.find('.cf7-pa-modal-overlay'); 15 this.$search_options_input = $wrapper_element.find('.cf7-pa-search-options'); 16 this.$search_selected_input = $wrapper_element.find('.cf7-pa-search-selected'); 17 18 this.attributes_list = []; 19 this.selected_attributes_list = []; 20 this.current_attribute_data = null; 21 this.current_editing_index = -1; 22 this.expanded_items_set = new Set(); 23 this.modal_values_list = []; 24 this.modal_values_expanded = false; 25 26 var types_attribute = $wrapper_element.attr('data-types') || ''; 27 this.allowed_types_list = types_attribute ? types_attribute.split(',').map(function(type) { 28 return type.trim().toLowerCase(); 29 }).filter(function(type) { return type; }) : []; 30 31 this.is_multiselect_enabled = $wrapper_element.attr('data-multiselect') === 'true'; 32 33 var defaults_attribute = $wrapper_element.attr('data-defaults') || '[]'; 34 try { 35 this.default_values_list = JSON.parse(defaults_attribute); 36 } catch (parse_error) { 37 this.default_values_list = []; 38 } 39 40 this.initialize(); 41 } 42 43 ProductAttributesField.prototype.initialize = function() { 44 this.bind_event_handlers(); 45 this.load_attributes_data(); 46 }; 47 48 ProductAttributesField.prototype.bind_event_handlers = function() { 49 var self = this; 50 51 this.$options_list_element.on('click', '.cf7-pa-option-item', function(click_event) { 52 self.toggle_option_selection($(click_event.currentTarget)); 53 }); 54 55 this.$selected_list_element.on('click', '.cf7-pa-selected-item', function(click_event) { 56 if (!$(click_event.target).closest('.cf7-pa-item-remove').length) { 57 var item_index = $(click_event.currentTarget).data('index'); 58 self.open_values_modal(item_index); 59 } 60 }); 61 62 this.$selected_list_element.on('click', '.cf7-pa-item-remove', function(click_event) { 63 click_event.stopPropagation(); 64 self.remove_selected_attribute($(click_event.currentTarget).closest('.cf7-pa-selected-item')); 65 }); 66 67 this.$selected_list_element.on('click', '.cf7-pa-value-more', function(click_event) { 68 click_event.stopPropagation(); 69 var item_index = $(click_event.currentTarget).data('index'); 70 self.expanded_items_set.add(item_index); 71 self.render_selected_attributes_list(); 72 }); 73 74 this.$selected_list_element.on('click', '.cf7-pa-value-less', function(click_event) { 75 click_event.stopPropagation(); 76 var item_index = $(click_event.currentTarget).data('index'); 77 self.expanded_items_set.delete(item_index); 78 self.render_selected_attributes_list(); 79 }); 80 81 this.$search_options_input.on('input', function(input_event) { 82 self.filter_options_list($(input_event.target).val()); 83 }); 84 85 this.$search_selected_input.on('input', function(input_event) { 86 self.filter_selected_list($(input_event.target).val()); 87 }); 88 89 this.$wrapper.find('.cf7-pa-select-all-checkbox').on('change', function() { 90 var is_checked = $(this).is(':checked'); 91 if (is_checked) { 92 self.select_all_attributes(); 93 } else { 94 self.deselect_all_attributes(); 95 } 96 }); 97 98 this.$modal_element.on('click', '.cf7-pa-modal-close', function(click_event) { 99 click_event.preventDefault(); 100 self.close_values_modal(); 101 }); 102 103 this.$modal_element.on('click', '.cf7-pa-modal-cancel', function(click_event) { 104 click_event.preventDefault(); 105 self.close_values_modal(); 106 }); 107 108 this.$modal_element.on('click', '.cf7-pa-modal-save', function(click_event) { 109 click_event.preventDefault(); 110 self.save_attribute_values(); 111 }); 112 113 this.$modal_element.on('click', function(click_event) { 114 if ($(click_event.target).hasClass('cf7-pa-modal-overlay')) { 115 self.close_values_modal(); 116 } 117 }); 118 119 this.$modal_element.on('keypress', '.cf7-pa-single-mode input[name="value"]', function(keypress_event) { 120 if (keypress_event.which === 13) { 121 keypress_event.preventDefault(); 122 self.save_attribute_values(); 123 } 124 }); 125 126 this.$modal_element.on('keypress', '.cf7-pa-multi-mode input[name="value"]', function(keypress_event) { 127 if (keypress_event.which === 13) { 128 keypress_event.preventDefault(); 129 self.add_value_to_modal_list(); 130 } 131 }); 132 133 this.$modal_element.on('input', '.cf7-pa-multi-mode input[name="value"]', function() { 134 self.update_save_button_state(); 135 }); 136 137 this.$modal_element.on('click', '.cf7-pa-add-value-btn', function(click_event) { 138 click_event.preventDefault(); 139 self.add_value_to_modal_list(); 140 }); 141 142 this.$modal_element.on('click', '.cf7-pa-value-remove', function(click_event) { 143 click_event.preventDefault(); 144 var $value_item = $(click_event.currentTarget).closest('.cf7-pa-value-item'); 145 var value_text = $value_item.data('value'); 146 147 self.modal_values_list = self.modal_values_list.filter(function(item) { 148 return item.value !== value_text; 149 }); 150 151 self.render_modal_values_list(); 152 }); 153 154 this.$modal_element.on('click', '.cf7-pa-modal-value-more', function(click_event) { 155 click_event.preventDefault(); 156 self.modal_values_expanded = true; 157 self.render_modal_values_list(); 158 }); 159 160 this.$modal_element.on('click', '.cf7-pa-modal-value-less', function(click_event) { 161 click_event.preventDefault(); 162 self.modal_values_expanded = false;
163 self.render_modal_values_list(); 164 }); 165 }; 166 167 ProductAttributesField.prototype.load_attributes_data = function() { 168 var self = this; 169 170 this.$loading_element.show(); 171 this.$content_element.hide(); 172 173 if (typeof window.product_attributes !== 'undefined' && 174 Array.isArray(window.product_attributes) && 175 window.product_attributes.length > 0) { 176 this.attributes_list = this.normalize_attributes_data(window.product_attributes); 177 this.render_options_list(); 178 this.render_selected_attributes_list(); 179 this.update_select_all_checkbox(); 180 this.$loading_element.hide(); 181 this.$content_element.show(); 182 return; 183 } 184 185 $.ajax({ 186 url: cf7ProductAttributesConfig.ajaxurl, 187 type: 'POST', 188 data: { 189 action: 'cf7_get_product_attributes', 190 nonce: cf7ProductAttributesConfig.nonce 191 }, 192 success: function(ajax_response) { 193 if (ajax_response.success) { 194 var attributes_data = ajax_response.data?.attributes || ajax_response.data || []; 195 196 if (typeof attributes_data === 'string') { 197 try { 198 attributes_data = JSON.parse(attributes_data); 199 } catch (parse_error) {} 200 } 201 202 if (attributes_data && attributes_data.data && Array.isArray(attributes_data.data)) { 203 attributes_data = attributes_data.data; 204 } 205 206 if (Array.isArray(attributes_data) && attributes_data.length > 0) { 207 self.attributes_list = self.normalize_attributes_data(attributes_data); 208 self.render_options_list(); 209 self.render_selected_attributes_list(); 210 self.update_select_all_checkbox(); 211 self.$loading_element.hide(); 212 self.$content_element.show(); 213 } else { 214 self.show_error_message('No attributes found'); 215 } 216 } else { 217 self.show_error_message(ajax_response.data?.message || 'Failed to load'); 218 } 219 }, 220 error: function() { 221 self.show_error_message('Failed to load attributes'); 222 } 223 }); 224 }; 225 226 ProductAttributesField.prototype.normalize_attributes_data = function(raw_attributes_data) { 227 var self = this; 228 229 if (!Array.isArray(raw_attributes_data)) return []; 230 231 var normalized_attributes = raw_attributes_data.map(function(attribute_item) { 232 return { 233 id: attribute_item.id || attribute_item.attribute_id || '', 234 name: attribute_item.name || '', 235 display_name: attribute_item.name || attribute_item.display_name || attribute_item.label || '', 236 type: (attribute_item.data_type || attribute_item.type || 'text').trim().toLowerCase(), 237 options: attribute_item.options || [] 238 }; 239 }).filter(function(attribute_item) { 240 return attribute_item.id && attribute_item.display_name; 241 }); 242 243 if (self.allowed_types_list.length > 0) { 244 normalized_attributes = normalized_attributes.filter(function(attribute_item) { 245 return self.allowed_types_list.includes(attribute_item.type.toLowerCase().trim()); 246 }); 247 } 248 249 return normalized_attributes; 250 }; 251 252 ProductAttributesField.prototype.get_default_value_for_attribute = function(attribute_id, attribute_name) { 253 if (!this.default_values_list || this.default_values_list.length === 0) return null; 254 255 var matching_default = this.default_values_list.find(function(default_item) { 256 return default_item.attribute_id === attribute_id || 257 (default_item.attribute_name && attribute_name && 258 default_item.attribute_name.toLowerCase() === attribute_name.toLowerCase()); 259 }); 260 261 return matching_default ? matching_default.value : null; 262 }; 263 264 ProductAttributesField.prototype.render_options_list = function() { 265 var self = this; 266 267 this.$options_list_element.empty(); 268 269 this.attributes_list.forEach(function(attribute_item) { 270 var is_selected = self.selected_attributes_list.some(function(selected_item) { 271 return selected_item.id === attribute_item.id; 272 }); 273 274 var default_value = self.get_default_value_for_attribute(attribute_item.id, attribute_item.name); 275 var default_label_html = default_value ? 276 '<span class="cf7-pa-option-default" title="' + self.escape_attribute(default_value) + '">
276' + self.escape_html_string(default_value) + '</span>' : ''; 277 278 var selected_class = is_selected ? 'cf7-pa-option-selected' : ''; 279 280 var option_item_html = '<div class="cf7-pa-option-item ' + selected_class + '" ' + 281 'data-id="' + self.escape_html_string(attribute_item.id) + '" ' + 282 'data-name="' + self.escape_html_string(attribute_item.display_name) + '">' + 283 '<div class="cf7-pa-option-checkbox">' + 284 '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">' + 285 '<polyline points="20 6 9 17 4 12"></polyline></svg></div>' + 286 '<span class="cf7-pa-option-name" title="' + self.escape_attribute(attribute_item.display_name) + '">' + self.escape_html_string(attribute_item.display_name) + '</span>' + 287 default_label_html + '</div>'; 288 289 self.$options_list_element.append(option_item_html); 290 }); 291 }; 292 293 ProductAttributesField.prototype.toggle_option_selection = function($option_item_element) { 294 var self = this; 295 var attribute_id = $option_item_element.data('id'); 296 var is_currently_selected = $option_item_element.hasClass('cf7-pa-option-selected'); 297 298 if (is_currently_selected) { 299 this.selected_attributes_list = this.selected_attributes_list.filter(function(selected_item) { 300 return selected_item.id !== attribute_id; 301 }); 302 $option_item_element.removeClass('cf7-pa-option-selected'); 303 } else { 304 var attribute_data = this.attributes_list.find(function(attribute_item) { 305 return attribute_item.id === attribute_id; 306 }); 307 308 if (attribute_data) { 309 var default_value = this.get_default_value_for_attribute(attribute_data.id, attribute_data.name); 310 var initial_values = default_value ? [default_value] : []; 311 312 this.selected_attributes_list.push({ 313 id: attribute_data.id, 314 name: attribute_data.name, 315 display_name: attribute_data.display_name, 316 type: attribute_data.type, 317 values: initial_values 318 }); 319 $option_item_element.addClass('cf7-pa-option-selected'); 320 } 321 } 322 323 this.render_selected_attributes_list(); 324 this.update_hidden_input_value(); 325 this.update_select_all_checkbox(); 326 }; 327 328 ProductAttributesField.prototype.render_selected_attributes_list = function() { 329 var self = this; 330 331 this.$selected_list_element.empty(); 332 333 if (this.selected_attributes_list.length === 0) { 334 this.$selected_list_element.html('<div class="cf7-pa-empty-state"><span>No attributes selected</span></div>'); 335 return; 336 } 337 338 this.selected_attributes_list.forEach(function(attribute_item, item_index) { 339 var default_value = self.get_default_value_for_attribute(attribute_item.id, attribute_item.name); 340 var is_expanded = self.expanded_items_set.has(item_index); 341 var values_array = attribute_item.values || []; 342 var total_values_count = values_array.length; 343 var remaining_values_count = total_values_count - max_visible_values; 344 345 var values_html = ''; 346 347 if (total_values_count === 0) { 348 values_html = '<span class="cf7-pa-item-no-values">Click to add values</span>'; 349 } else { 350 var visible_values = is_expanded ? values_array : values_array.slice(0, max_visible_values); 351 352 values_html = visible_values.map(function(value_item) { 353 var is_default = value_item === default_value; 354 var default_class = is_default ? 'cf7-pa-value-default' : ''; 355 return '<span class="cf7-pa-item-value-tag ' + default_class + '" title="' + self.escape_attribute(value_item) + '">' +
356 self.escape_html_string(value_item) + '</span>'; 357 }).join(''); 358 359 if (remaining_values_count > 0 && !is_expanded) { 360 values_html += '<span class="cf7-pa-item-value-tag cf7-pa-value-more" data-index="' + 361 item_index + '">+' + remaining_values_count + '</span>'; 362 } 363 364 if (is_expanded && total_values_count > max_visible_values) { 365 values_html += '<span class="cf7-pa-item-value-tag cf7-pa-value-less" data-index="' + 366 item_index + '">Show less</span>'; 367 } 368 } 369 370 var expanded_class = is_expanded ? ' cf7-pa-values-expanded' : ''; 371 372 var selected_item_html = '<div class="cf7-pa-selected-item" data-index="' + item_index + '">' + 373 '<div class="cf7-pa-drag-handle"><span></span><span></span></div>' + 374 '<div class="cf7-pa-item-content">' + 375 '<div class="cf7-pa-item-name" title="' + self.escape_attribute(attribute_item.display_name) + '">' + self.escape_html_string(attribute_item.display_name) + '</div>' + 376 '<div class="cf7-pa-item-values' + expanded_class + '">' + values_html + '</div></div>' + 377 '<button type="button" class="cf7-pa-item-remove" title="Remove">' + 378 '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' + 379 '<line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></button></div>'; 380 381 self.$selected_list_element.append(selected_item_html); 382 }); 383 }; 384 385 ProductAttributesField.prototype.filter_options_list = function(search_query) { 386 var lower_query = search_query.toLowerCase(); 387 var visible_count = 0; 388 389 this.$options_list_element.find('.cf7-pa-option-item').each(function() { 390 var option_name = $(this).data('name').toLowerCase(); 391 var is_visible = option_name.includes(lower_query); 392 $(this).toggle(is_visible); 393 if (is_visible) visible_count++; 394 }); 395 396 this.$options_list_element.find('.cf7-pa-no-results').remove(); 397 if (visible_count === 0 && search_query.length > 0) { 398 this.$options_list_element.append('<div class="cf7-pa-no-results">No attributes found</div>'); 399 } 400 }; 401 402 ProductAttributesField.prototype.filter_selected_list = function(search_query) { 403 var lower_query = search_query.toLowerCase(); 404 var visible_count = 0; 405 406 this.$selected_list_element.find('.cf7-pa-selected-item').each(function() { 407 var item_name = $(this).find('.cf7-pa-item-name').text().toLowerCase(); 408 var is_visible = item_name.includes(lower_query); 409 $(this).toggle(is_visible); 410 if (is_visible) visible_count++; 411 }); 412 413 this.$selected_list_element.find('.cf7-pa-no-results').remove(); 414 if (visible_count === 0 && search_query.length > 0) { 415 this.$selected_list_element.append('<div class="cf7-pa-no-results">No attributes found</div>'); 416 } 417 }; 418 419 ProductAttributesField.prototype.select_all_attributes = function() { 420 var self = this; 421 422 this.attributes_list.forEach(function(attribute_item) { 423 var is_already_selected = self.selected_attributes_list.some(function(selected_item) { 424 return selected_item.id === attribute_item.id; 425 }); 426 427 if (!is_already_selected) { 428 var default_value = self.get_default_value_for_attribute(attribute_item.id, attribute_item.name); 429 var initial_values = default_value ? [default_value] : []; 430 431 self.selected_attributes_list.push({ 432 id: attribute_item.id, 433 name: attribute_item.name, 434 display_name: attribute_item.display_name, 435 type: attribute_item.type, 436 values: initial_values 437 }); 438 } 439 }); 440 441 this.render_options_list(); 442 this.render_selected_attributes_list(); 443 this.update_hidden_input_value(); 444 }; 445 446 ProductAttributesField.prototype.deselect_all_attributes = function() { 447 this.selected_attributes_list = []; 448 this.expanded_items_set.clear(); 449 450 this.render_options_list(); 451 this.render_selected_attributes_list(); 452 this.update_hidden_input_value(); 453 }; 454 455 ProductAttributesField.prototype.update_select_all_checkbox = function() { 456 var total_count = this.attributes_list.length; 457 var selected_count = this.selected_attributes_list.length; 458 var $checkbox = this.$wrapper.find('.cf7-pa-select-all-checkbox'); 459 460 if (selected_count === 0) { 461 $checkbox.prop('checked', false); 462 $checkbox.prop('indeterminate', false); 463 } else if (selected_count === total_count) { 464 $checkbox.prop('checked', true); 465 $checkbox.prop('indeterminate', false); 466 } else { 467 $checkbox.prop('checked', false); 468 $checkbox.prop('indeterminate', true); 469 } 470 }; 471 472 ProductAttributesField.prototype.remove_selected_attribute = function($selected_item_element) { 473 var item_index = $selected_item_element.data('index'); 474 var attribute_data = this.selected_attributes_list[item_index]; 475 476 if (attribute_data) { 477 this.$options_list_element.find('.cf7-pa-option-item[data-id="' + attribute_data.id + '"]') 478 .removeClass('cf7-pa-option-selected'); 479 } 480 481 this.selected_attributes_list.splice(item_index, 1); 482 this.render_selected_attributes_list(); 483 this.update_hidden_input_value(); 484 this.update_select_all_checkbox(); 485 }; 486 487 ProductAttributesField.prototype.open_values_modal = function(edit_index) { 488 var attribute_data = this.selected_attributes_list[edit_index]; 489 if (!attribute_data) return; 490 491 this.current_editing_index = edit_index; 492 this.current_attribute_data = attribute_data; 493 494 this.$modal_element.find('.cf7-pa-error-message').removeClass('visible'); 495 496 this.$modal_element.find('.cf7-pa-modal-attr-name') 497 .text(attribute_data.display_name) 498 .attr('title', attribute_data.display_name); 499 this.$modal_element.find('.cf7-pa-modal-attribute-name').hide(); 500 501 var existing_values = attribute_data.values || []; 502 var default_value = this.get_default_value_for_attribute(attribute_data.id, attribute_data.name); 503 504 if (this.is_multiselect_enabled) { 505 this.$modal_element.find('.cf7-pa-single-mode').hide(); 506 this.$modal_element.find('.cf7-pa-multi-mode').show(); 507 508 this.modal_values_list = []; 509 this.modal_values_expanded = false;
510 511 var self = this; 512 513 if (existing_values.length > 0) { 514 existing_values.forEach(function(value_item) { 515 var is_default = value_item === default_value; 516 self.modal_values_list.push({ value: value_item, is_default: is_default }); 517 }); 518 } else if (default_value) { 519 this.modal_values_list.push({ value: default_value, is_default: true }); 520 } 521 522 this.render_modal_values_list(); 523 524 var $multi_input_element = this.$modal_element.find('.cf7-pa-multi-mode input[name="value"]'); 525 $multi_input_element.val(''); 526 527 if (window.cf7_pa_multi_value) { 528 window.cf7_pa_multi_value.data = { value: '' }; 529 } 530 } else { 531 this.$modal_element.find('.cf7-pa-single-mode').show(); 532 this.$modal_element.find('.cf7-pa-multi-mode').hide(); 533 534 var existing_value = existing_values.length > 0 ? existing_values[0] : (default_value || ''); 535 var $single_input_element = this.$modal_element.find('.cf7-pa-single-mode input[name="value"]'); 536 $single_input_element.val(existing_value); 537 538 if (window.cf7_pa_single_value) { 539 window.cf7_pa_single_value.data = { value: existing_value }; 540 } 541 } 542 543 this.$modal_element.addClass('active'); 544 545 var self = this; 546 547 if (this.is_multiselect_enabled) { 548 setTimeout(function() { 549 self.$modal_element.find('.cf7-pa-multi-mode input[name="value"]').focus(); 550 }, 100); 551 } else { 552 setTimeout(function() { 553 self.$modal_element.find('.cf7-pa-single-mode input[name="value"]').focus(); 554 }, 100); 555 } 556 557 $('body').addClass('cf7-pa-modal-open'); 558 this.update_save_button_state(); 559 }; 560 561 ProductAttributesField.prototype.add_value_to_modal_list = function() { 562 var $input_element = this.$modal_element.find('.cf7-pa-multi-mode input[name="value"]'); 563 var input_value = ''; 564 565 if (window.cf7_pa_multi_value && window.cf7_pa_multi_value.data) { 566 input_value = (window.cf7_pa_multi_value.data.value || '').trim(); 567 } else { 568 input_value = $input_element.val().trim(); 569 } 570 571 if (!input_value) { 572 return; 573 } 574 575 this.modal_values_list.push({ value: input_value, is_default: false }); 576 this.render_modal_values_list(); 577 578 $input_element.val(''); 579 580 if (window.cf7_pa_multi_value) { 581 window.cf7_pa_multi_value.data = { value: '' }; 582 } 583 584 $input_element.focus(); 585 this.update_save_button_state(); 586 }; 587 588 ProductAttributesField.prototype.render_modal_values_list = function() { 589 var self = this; 590 var $values_list_element = this.$modal_element.find('.cf7-pa-values-list'); 591 $values_list_element.empty(); 592 593 var total_count = this.modal_values_list.length; 594 var remaining_count = total_count - max_visible_values; 595 var visible_values = this.modal_values_expanded 596 ? this.modal_values_list 597 : this.modal_values_list.slice(0, max_visible_values); 598 599 visible_values.forEach(function(item) { 600 var default_class = item.is_default ? 'cf7-pa-value-default' : ''; 601 602 var value_item_html = '<div class="cf7-pa-value-item ' + default_class + '" title="' + self.escape_attribute(item.value) + '">' + 603 '<span class="cf7-pa-value-text">' + self.escape_html_string(item.value) + '</span>' + 604 '<button type="button" class="cf7-pa-value-remove" title="Remove">' + 605 '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' + 606 '<line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></button></div>'; 607 608 var $value_item = $(value_item_html); 609 $value_item.data('value', item.value); 610 $values_list_element.append($value_item); 611 }); 612 613 if (remaining_count > 0 && !this.modal_values_expanded) { 614 var more_chip_html = '<div class="cf7-pa-value-item cf7-pa-modal-value-more">' + 615 '<span class="cf7-pa-value-text">+' + remaining_count + '</span></div>'; 616 $values_list_element.append(more_chip_html); 617 } 618 619 if (this.modal_values_expanded && total_count > max_visible_values) { 620 var less_chip_html = '<div class="cf7-pa-value-item cf7-pa-modal-value-less">' + 621 '<span class="cf7-pa-value-text">Show less</span></div>'; 622 $values_list_element.append(less_chip_html); 623 } 624 }; 625 626 ProductAttributesField.prototype.close_values_modal = function() { 627 this.$modal_element.removeClass('active'); 628 this.current_editing_index = -1; 629 $('body').removeClass('cf7-pa-modal-open'); 630 }; 631 632 ProductAttributesField.prototype.update_save_button_state = function() { 633 if (!this.is_multiselect_enabled) { 634 this.$modal_element.find('.cf7-pa-modal-save').prop('disabled', false); 635 return; 636 } 637 638 var $input_element = this.$modal_element.find('.cf7-pa-multi-mode input[name="value"]'); 639 var input_value = $input_element.val().trim(); 640 var has_unsaved_input = input_value.length > 0; 641 642 this.$modal_element.find('.cf7-pa-modal-save').prop('disabled', has_unsaved_input); 643 }; 644 645 ProductAttributesField.prototype.save_attribute_values = function() { 646 var values_array = []; 647 648 this.$modal_element.find('.cf7-pa-error-message').removeClass('visible'); 649 650 if (this.is_multiselect_enabled) { 651 values_array = this.modal_values_list.map(function(item) { 652 return item.value; 653 }); 654 655 if (values_array.length === 0) { 656 this.$modal_element.find('.cf7-pa-multi-error').addClass('visible'); 657 return; 658 } 659 } else { 660 var $input_element = this.$modal_element.find('.cf7-pa-single-mode input[name="value"]'); 661 var input_value = ''; 662 663 if (window.cf7_pa_single_value && window.cf7_pa_single_value.data) { 664 input_value = (window.cf7_pa_single_value.data.value || '').trim(); 665 } else { 666 input_value = $input_element.val().trim(); 667 } 668 669 if (!input_value) { 670 if (typeof window.handleValidate === 'function') {
671 var validations = $input_element.data('validations'); 672 window.handleValidate(validations, '', $input_element, true); 673 } 674 return; 675 } 676 677 values_array = [input_value]; 678 } 679 680 if (this.current_editing_index >= 0) { 681 this.selected_attributes_list[this.current_editing_index].values = values_array; 682 } 683 684 this.render_selected_attributes_list(); 685 this.render_options_list(); 686 this.update_hidden_input_value(); 687 this.close_values_modal(); 688 }; 689 690 ProductAttributesField.prototype.update_hidden_input_value = function() { 691 var serialized_data = this.selected_attributes_list.map(function(attribute_item) { 692 return { 693 attribute_id: attribute_item.id, 694 attribute_name: attribute_item.name, 695 display_name: attribute_item.display_name, 696 type: attribute_item.type, 697 values: attribute_item.values 698 }; 699 }); 700 701 this.$hidden_input_element.val(JSON.stringify(serialized_data)); 702 703 window.selected_product_attributes = serialized_data; 704 }; 705 706 ProductAttributesField.prototype.show_error_message = function(error_message) { 707 this.$loading_element.html( 708 '<div class="cf7-pa-error">' + 709 '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' + 710 '<circle cx="12" cy="12" r="10"></circle>' + 711 '<line x1="12" y1="8" x2="12" y2="12"></line>' + 712 '<line x1="12" y1="16" x2="12.01" y2="16"></line></svg>' + 713 '<span>' + error_message + '</span></div>' 714 ); 715 }; 716 717 ProductAttributesField.prototype.escape_html_string = function(text_content) { 718 var temp_div = document.createElement('div'); 719 temp_div.textContent = text_content; 720 return temp_div.innerHTML; 721 }; 722 723 ProductAttributesField.prototype.escape_attribute = function(text_content) { 724 if (!text_content) return ''; 725 return String(text_content) 726 .replace(/&/g, '&') 727 .replace(/"/g, '"') 728 .replace(/'/g, ''') 729 .replace(/</g, '<') 730 .replace(/>/g, '>'); 731 }; 732
733 function initialize_product_attributes_fields() { 734 $('.cf7-product-attributes-wrapper').each(function() { 735 var $wrapper_element = $(this); 736 if (!instances_map.has(this)) { 737 instances_map.set(this, new ProductAttributesField($wrapper_element)); 738 } 739 }); 740 } 741 742 $(document).ready(initialize_product_attributes_fields); 743 $(document).on('wpcf7initform', initialize_product_attributes_fields); 744 745})(jQuery);
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.