PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.5.23
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.5.23
2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 2.6.4 2.6.3 2.5.23 All 138 releases
metasync / schema-markup / js / schema-markup-admin.js

schema-markup-admin.js in Search Atlas SEO – OTTO AI SEO Automation for WordPress 2.5.23, at schema-markup/js/schema-markup-admin.js

686 lines 27.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Schema Markup Admin JavaScript
3 *
4 * @package MetaSync
5 * @subpackage Schema_Markup
6 */
7
8 jQuery(document).ready(function($) {
9 let schemaTypeCounter = 0;
10
11 // Initialize counter based on existing schema types
12 function initializeSchemaTypeCounter() {
13 const existingItems = $('.schema-type-item');
14 if (existingItems.length > 0) {
15 let maxIndex = -1;
16 existingItems.each(function() {
17 const index = parseInt($(this).attr('data-index'));
18 if (index > maxIndex) {
19 maxIndex = index;
20 }
21 });
22 schemaTypeCounter = maxIndex + 1;
23 }
24 }
25
26 // Initialize counter when document is ready
27 initializeSchemaTypeCounter();
28
29 // Function to check if a schema type already exists
30 function schemaTypeExists(schemaType) {
31 let exists = false;
32 $('.schema-type-item').each(function() {
33 const existingType = $(this).find('input[name*="[type]"]').val();
34 if (existingType === schemaType) {
35 exists = true;
36 return false; // break loop
37 }
38 });
39 return exists;
40 }
41
42 // Function to add a new schema type
43 function addSchemaType(schemaType) {
44 // Check if this schema type already exists
45 if (schemaTypeExists(schemaType)) {
46 return;
47 }
48
49 const index = schemaTypeCounter++;
50 const schemaTypeNames = {
51 'article': 'Article',
52 'FAQPage': 'FAQ',
53 'product': 'Product',
54 'recipe': 'Recipe'
55 };
56 const displayName = schemaTypeNames[schemaType] || schemaType;
57
58 const schemaTypeHtml = '<div class="schema-type-item" data-index="' + index + '" style="margin: 15px 0; padding: 15px; border: 1px solid #ddd; border-radius: 4px; background: #f9f9f9;">' +
59 '<div class="schema-type-header" style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">' +
60 '<h5 style="margin: 0; color: #333;">' +
61 '<span class="dashicons dashicons-tag" style="color: #0073aa;"></span> ' + displayName + ' Schema' +
62 '</h5>' +
63 '<button type="button" class="button button-link remove-schema-type" style="color: #dc3232; text-decoration: none;">' +
64 '<span class="dashicons dashicons-trash"></span> Remove' +
65 '</button>' +
66 '</div>' +
67 '<div class="schema-type-content">' +
68 '<input type="hidden" name="schema_markup[types][' + index + '][type]" value="' + schemaType + '">' +
69 '<div class="schema-fields-container">' +
70 '</div>' +
71 '</div>' +
72 '</div>';
73
74 // Remove no-schema-types message if it exists
75 $('.no-schema-types').remove();
76
77 // Add the new schema type
78 $('#schema-types-list').append(schemaTypeHtml);
79
80 // Load the fields for this schema type
81 loadSchemaFields(schemaType, index);
82 }
83
84 // Function to load schema fields via AJAX
85 function loadSchemaFields(schemaType, index) {
86 const postId = $('#post_ID').val() || 0;
87 $.ajax({
88 url: metasyncSchemaMarkup.ajaxurl,
89 type: 'POST',
90 data: {
91 action: 'metasync_get_schema_fields',
92 schema_type: schemaType,
93 index: index,
94 post_id: postId,
95 nonce: metasyncSchemaMarkup.schema_fields_nonce
96 },
97 success: function(response) {
98 if (response.success) {
99 $('.schema-type-item[data-index="' + index + '"] .schema-fields-container').html(response.data);
100 }
101 }
102 });
103 }
104
105 // Toggle schema fields based on enabled checkbox
106 $('input[name="schema_markup[enabled]"]').change(function() {
107 if ($(this).is(':checked')) {
108 $('.schema-types-container').show();
109 } else {
110 $('.schema-types-container').hide();
111 }
112 });
113
114 // Handle modal cancel button
115 $(document).on('click', '#cancel-schema-type', function() {
116 $('#schema-type-modal').remove();
117 });
118
119 // Handle modal add button
120 $(document).on('click', '#add-selected-schema-type', function() {
121 const selectedType = $('#new-schema-type-select').val();
122 const selectedOption = $('#new-schema-type-select option:selected');
123
124 if (!selectedType) {
125 alert('Please select a schema type.');
126 return;
127 }
128
129 // Check if the selected option is disabled
130 if (selectedOption.prop('disabled')) {
131 alert('This schema type has already been added. Please select a different schema type or remove the existing one first.');
132 return;
133 }
134
135 addSchemaType(selectedType);
136 $('#schema-type-modal').remove();
137 });
138
139 // Add new schema type
140 $(document).on('click', '#add_schema_type_button', function(e) {
141 e.preventDefault();
142
143 // Show schema type selection modal or dropdown
144 showSchemaTypeSelection();
145 });
146
147 // Remove schema type
148 $(document).on('click', '.remove-schema-type', function(e) {
149 e.preventDefault();
150
151 if (confirm('Are you sure you want to remove this schema type?')) {
152 $(this).closest('.schema-type-item').fadeOut(200, function() {
153 $(this).remove();
154 updateSchemaTypeIndices();
155 updateNoSchemaTypesMessage();
156 });
157 }
158 });
159
160 function showSchemaTypeSelection() {
161 const schemaTypes = [
162 { value: 'article', label: 'Article' },
163 { value: 'FAQPage', label: 'FAQ' },
164 { value: 'product', label: 'Product' },
165 { value: 'recipe', label: 'Recipe' }
166 ];
167
168 let optionsHtml = '<option value="">Select Schema Type</option>';
169 schemaTypes.forEach(function(type) {
170 const isAlreadyAdded = schemaTypeExists(type.value);
171 let label = type.label;
172 let disabledAttr = '';
173
174 if (isAlreadyAdded) {
175 label += ' - already added';
176 disabledAttr = ' disabled';
177 }
178
179 optionsHtml += '<option value="' + type.value + '"' + disabledAttr + '>' + label + '</option>';
180 });
181
182 const modalHtml = '<div id="schema-type-modal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 9999; display: flex; align-items: center; justify-content: center;">' +
183 '<div style="background: white; padding: 20px; border-radius: 4px; min-width: 300px;">' +
184 '<h3 style="margin-top: 0;">Add Schema Type</h3>' +
185 '<p>Select the schema type you want to add:</p>' +
186 '<select id="new-schema-type-select" style="width: 100%; margin-bottom: 15px;">' + optionsHtml + '</select>' +
187 '<div style="text-align: right;">' +
188 '<button type="button" class="button" id="cancel-schema-type">Cancel</button> ' +
189 '<button type="button" class="button button-primary" id="add-selected-schema-type">Add Schema Type</button>' +
190 '</div>' +
191 '</div>' +
192 '</div>';
193
194 $('body').append(modalHtml);
195 }
196
197
198 function updateSchemaTypeIndices() {
199 $('.schema-type-item').each(function(newIndex) {
200 $(this).attr('data-index', newIndex);
201 $(this).find('input[name*="[type]"]').attr('name', 'schema_markup[types][' + newIndex + '][type]');
202
203 // Update all field names
204 $(this).find('[name*="schema_markup[types]"]').each(function() {
205 const name = $(this).attr('name');
206 const newName = name.replace(/schema_markup\[types\]\[\d+\]/, 'schema_markup[types][' + newIndex + ']');
207 $(this).attr('name', newName);
208 });
209 });
210
211 // Update counter to be the next available index
212 schemaTypeCounter = $('.schema-type-item').length;
213 }
214
215 function updateNoSchemaTypesMessage() {
216 if ($('.schema-type-item').length === 0) {
217 $('#schema-types-list').html('<div class="no-schema-types" style="text-align: center; padding: 20px; background: #f9f9f9; border: 2px dashed #ddd; border-radius: 4px; color: #666;"><p style="margin: 0;">No schema types added yet. Click "Add Schema Type" to get started.</p></div>');
218 }
219 }
220
221 // Add ingredient
222 $(document).on('click', '.add-ingredient', function() {
223 const container = $(this).siblings('.ingredients-list');
224 const schemaTypeItem = $(this).closest('.schema-type-item');
225 const schemaIndex = schemaTypeItem.attr('data-index');
226
227 const newItem = '<div class="ingredient-item">' +
228 '<input type="text" name="schema_markup[types][' + schemaIndex + '][fields][ingredients][]" placeholder="Enter ingredient">' +
229 '<button type="button" class="remove-item">Remove</button>' +
230 '</div>';
231 container.append(newItem);
232 });
233
234 // Add instruction
235 $(document).on('click', '.add-instruction', function() {
236 const container = $(this).siblings('.instructions-list');
237 const schemaTypeItem = $(this).closest('.schema-type-item');
238 const schemaIndex = schemaTypeItem.attr('data-index');
239
240 const newItem = '<div class="instruction-item">' +
241 '<textarea name="schema_markup[types][' + schemaIndex + '][fields][instructions][]" placeholder="Enter instruction step"></textarea>' +
242 '<button type="button" class="remove-item">Remove</button>' +
243 '</div>';
244 container.append(newItem);
245 });
246
247 // Remove item
248 $(document).on('click', '.remove-item', function() {
249 $(this).parent().remove();
250 });
251
252 // Media uploader for organization logo
253 let mediaUploader;
254
255 $(document).on('click', '.upload-logo-button', function(e) {
256 e.preventDefault();
257 const targetIndex = $(this).data('target');
258
259 // If the media frame already exists, reopen it
260 if (mediaUploader) {
261 mediaUploader.open();
262 return;
263 }
264
265 // Create the media frame
266 mediaUploader = wp.media({
267 title: 'Choose Organization Logo',
268 button: {
269 text: 'Use this logo'
270 },
271 multiple: false,
272 library: {
273 type: 'image'
274 }
275 });
276
277 // When an image is selected, run a callback
278 mediaUploader.on('select', function() {
279 const attachment = mediaUploader.state().get('selection').first().toJSON();
280 $('#article_organization_logo_' + targetIndex).val(attachment.url);
281 $('#logo_preview_' + targetIndex + ' img').attr('src', attachment.url);
282 $('#logo_preview_' + targetIndex).show();
283 $('.remove-logo-button[data-target="' + targetIndex + '"]').show();
284 });
285
286 // Open the uploader dialog
287 mediaUploader.open();
288 });
289
290 // Remove logo
291 $(document).on('click', '.remove-logo-button', function(e) {
292 e.preventDefault();
293 const targetIndex = $(this).data('target');
294 $('#article_organization_logo_' + targetIndex).val('');
295 $('#logo_preview_' + targetIndex).hide();
296 $(this).hide();
297 });
298
299 // Add FAQ item
300 $(document).on('click', '.add-faq-item', function(e) {
301 e.preventDefault();
302 const container = $(this).siblings('.faq-items-list');
303 const count = container.find('.faq-item').length;
304 const schemaTypeItem = $(this).closest('.schema-type-item');
305 const schemaIndex = schemaTypeItem.attr('data-index');
306
307 const newItem = '<div class="faq-item" style="margin: 15px 0; padding: 15px; border: 1px solid #ddd; border-radius: 4px; background: #f9f9f9;">' +
308 '<div class="schema-field">' +
309 '<label>Question ' + (count + 1) + ':</label>' +
310 '<input type="text" name="schema_markup[types][' + schemaIndex + '][fields][faq_items][' + count + '][question]" value="" placeholder="Enter your question" style="width: 100%; margin-bottom: 10px;">' +
311 '</div>' +
312 '<div class="schema-field">' +
313 '<label>Answer ' + (count + 1) + ':</label>' +
314 '<textarea name="schema_markup[types][' + schemaIndex + '][fields][faq_items][' + count + '][answer]" placeholder="Enter your answer" style="width: 100%; height: 80px; margin-bottom: 10px;"></textarea>' +
315 '</div>' +
316 '<button type="button" class="button remove-faq-item" style="background: #dc3232; color: white; border-color: #dc3232;">Remove Question</button>' +
317 '</div>';
318 container.append(newItem);
319 });
320
321 // Remove FAQ item
322 $(document).on('click', '.remove-faq-item', function(e) {
323 e.preventDefault();
324 const container = $(this).closest('.faq-items-list');
325 $(this).closest('.faq-item').fadeOut(200, function() {
326 $(this).remove();
327 // Update question numbers
328 container.find('.faq-item').each(function(index) {
329 $(this).find('label').first().text('Question ' + (index + 1) + ':');
330 $(this).find('label').last().text('Answer ' + (index + 1) + ':');
331 });
332 });
333 });
334
335 // Function to display validation errors
336 function displayValidationErrors(errors) {
337 let errorHtml = '<div style="background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; border-radius: 4px;">';
338 errorHtml += '<h3 style="margin: 0 0 15px 0; color: #856404; font-size: 16px;">';
339 errorHtml += '<span class="dashicons dashicons-warning" style="color: #ffc107; vertical-align: middle;"></span> ';
340 errorHtml += 'Validation Issues Detected';
341 errorHtml += '</h3>';
342 errorHtml += '<p style="margin: 0 0 10px 0; color: #856404;">Schema preview is not possible because the following issues are present:</p>';
343 errorHtml += '<ul style="margin: 0; padding-left: 20px; color: #856404;">';
344
345 // Group errors by schema type
346 const errorsByType = {};
347 errors.forEach(function(error) {
348 if (!errorsByType[error.schema_type]) {
349 errorsByType[error.schema_type] = [];
350 }
351 errorsByType[error.schema_type].push(error);
352 });
353
354 // Display errors grouped by schema type
355 for (const schemaType in errorsByType) {
356 errorHtml += '<li style="margin-bottom: 8px;"><strong>' + schemaType + ' Schema:</strong><ul style="margin-top: 5px;">';
357 errorsByType[schemaType].forEach(function(error) {
358 errorHtml += '<li>' + error.message + '</li>';
359 });
360 errorHtml += '</ul></li>';
361 }
362
363 errorHtml += '</ul>';
364 errorHtml += '</div>';
365
366 // Display in preview area
367 $('#schema-json-preview').html(errorHtml);
368 $('#schema-preview-output').slideDown();
369 $('#copy_schema_button').hide(); // Hide copy button for errors
370 }
371
372 // Preview Schema
373 $(document).on('click', '#preview_schema_button', function(e) {
374 e.preventDefault();
375
376 const button = $(this);
377 const originalText = button.html();
378 button.prop('disabled', true).html('<span class="dashicons dashicons-update dashicons-spin"></span> Generating Preview...');
379
380 // Collect form data
381 const formData = {
382 action: 'metasync_preview_schema',
383 nonce: metasyncSchemaMarkup.preview_schema_nonce,
384 post_id: $('#post_ID').val(),
385 schema_enabled: $('input[name="schema_markup[enabled]"]').is(':checked') ? 1 : 0,
386 schema_types: []
387 };
388
389 // Collect all schema types and their fields
390 $('.schema-type-item').each(function() {
391 const schemaTypeItem = $(this);
392 const schemaIndex = schemaTypeItem.attr('data-index');
393 const schemaType = schemaTypeItem.find('input[name*="[type]"]').val();
394
395 if (schemaType) {
396 const schemaTypeData = {
397 type: schemaType,
398 fields: {}
399 };
400
401 // Collect fields for this schema type
402 schemaTypeItem.find('[name*="schema_markup[types][' + schemaIndex + '][fields]"]').each(function() {
403 const name = $(this).attr('name');
404 const value = $(this).val();
405
406 // Check if it's an array field with empty brackets (e.g., ingredients[])
407 if (name.match(/\[\]$/)) {
408 // Extract field name before []
409 const matches = name.match(/schema_markup\[types\]\[(\d+)\]\[fields\]\[([^\]]+)\]\[\]/);
410 if (matches) {
411 const fieldName = matches[2];
412 if (!schemaTypeData.fields[fieldName]) {
413 schemaTypeData.fields[fieldName] = [];
414 }
415 schemaTypeData.fields[fieldName].push(value);
416 }
417 } else {
418 // Parse the field name to get the structure
419 const matches = name.match(/schema_markup\[types\]\[(\d+)\]\[fields\]\[([^\]]+)\](?:\[([^\]]+)\])?(?:\[([^\]]+)\])?/);
420 if (matches) {
421 const field1 = matches[2];
422 const field2 = matches[3];
423 const field3 = matches[4];
424
425 if (field3) {
426 // Nested array (e.g., faq_items[0][question])
427 if (!schemaTypeData.fields[field1]) {
428 schemaTypeData.fields[field1] = [];
429 }
430 if (!schemaTypeData.fields[field1][field2]) {
431 schemaTypeData.fields[field1][field2] = {};
432 }
433 schemaTypeData.fields[field1][field2][field3] = value;
434 } else if (field2) {
435 // Simple nested (e.g., ingredients[0])
436 if (!schemaTypeData.fields[field1]) {
437 schemaTypeData.fields[field1] = [];
438 }
439 schemaTypeData.fields[field1].push(value);
440 } else {
441 // Simple field
442 schemaTypeData.fields[field1] = value;
443 }
444 }
445 }
446 });
447
448 formData.schema_types.push(schemaTypeData);
449 }
450 });
451
452 $.ajax({
453 url: metasyncSchemaMarkup.ajaxurl,
454 type: 'POST',
455 data: formData,
456 success: function(response) {
457 if (response.success) {
458 // Show JSON preview
459 $('#schema-json-preview').text(response.data.json);
460 $('#schema-preview-output').slideDown();
461 $('#copy_schema_button').show();
462 } else {
463 // Check if validation errors exist
464 if (response.data && response.data.validation_errors) {
465 // Display validation errors
466 displayValidationErrors(response.data.validation_errors);
467 } else {
468 alert('Error: ' + (response.data.message || 'Could not generate preview'));
469 }
470 }
471 },
472 error: function() {
473 alert('Error generating preview. Please try again.');
474 },
475 complete: function() {
476 button.prop('disabled', false).html(originalText);
477 }
478 });
479 });
480
481 // Copy Schema to Clipboard
482 $(document).on('click', '#copy_schema_button', function(e) {
483 e.preventDefault();
484 const schemaText = $('#schema-json-preview').text();
485
486 // Create temporary textarea
487 const temp = $('<textarea>');
488 $('body').append(temp);
489 temp.val(schemaText).select();
490 document.execCommand('copy');
491 temp.remove();
492
493 // Visual feedback
494 const button = $(this);
495 const originalHtml = button.html();
496 button.html('<span class="dashicons dashicons-yes" style="color: #46b450;"></span> Copied!');
497 setTimeout(function() {
498 button.html(originalHtml);
499 }, 2000);
500 });
501
502 // Close Preview
503 $(document).on('click', '#close_preview', function(e) {
504 e.preventDefault();
505 $('#schema-preview-output').slideUp();
506 $('#copy_schema_button').hide();
507 });
508
509 // Restrict recipe time inputs to numbers and decimals only
510 $(document).on('keydown', '.recipe-time-input', function(e) {
511 const key = e.key;
512 const value = $(this).val();
513
514 // Allow navigation and control keys
515 const allowedKeys = [
516 'Backspace', 'Delete', 'Tab', 'Escape', 'Enter',
517 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown',
518 'Home', 'End'
519 ];
520
521 // Allow Ctrl/Cmd combinations (for copy, paste, select all, etc.)
522 if (e.ctrlKey || e.metaKey) {
523 return true;
524 }
525
526 // Allow navigation keys
527 if (allowedKeys.indexOf(key) !== -1) {
528 return true;
529 }
530
531 // Allow numbers (0-9)
532 if (key >= '0' && key <= '9') {
533 return true;
534 }
535
536 // Allow decimal point (period only), but only one
537 if (key === '.') {
538 // Prevent if decimal point already exists
539 if (value.indexOf('.') !== -1) {
540 e.preventDefault();
541 return false;
542 }
543 return true;
544 }
545
546 // Block all other keys
547 e.preventDefault();
548 return false;
549 });
550
551 // Prevent paste of non-numeric content
552 $(document).on('paste', '.recipe-time-input', function(e) {
553 e.preventDefault();
554
555 let pastedData = (e.originalEvent.clipboardData || window.clipboardData).getData('text');
556
557 // Normalize comma to period for decimal separator
558 pastedData = pastedData.replace(',', '.');
559
560 // Remove any non-numeric characters except decimal point
561 pastedData = pastedData.replace(/[^0-9.]/g, '');
562
563 // Ensure only one decimal point
564 const parts = pastedData.split('.');
565 if (parts.length > 2) {
566 pastedData = parts[0] + '.' + parts.slice(1).join('');
567 }
568
569 // Only allow numeric values with optional single decimal point
570 const numericRegex = /^[0-9]*\.?[0-9]*$/;
571
572 if (!numericRegex.test(pastedData)) {
573 return false;
574 }
575
576 // Insert the cleaned pasted value
577 const currentValue = $(this).val();
578 const cursorPosition = this.selectionStart;
579 const newValue = currentValue.substring(0, cursorPosition) + pastedData + currentValue.substring(this.selectionEnd);
580
581 // Final check: ensure no more than one decimal point in final value
582 if ((newValue.match(/\./g) || []).length > 1) {
583 return false;
584 }
585
586 $(this).val(newValue);
587 this.setSelectionRange(cursorPosition + pastedData.length, cursorPosition + pastedData.length);
588
589 return false;
590 });
591
592 // Collapsible override fields section toggle
593 $(document).on('click', '.schema-override-header', function(e) {
594 e.preventDefault();
595 const targetId = $(this).data('toggle-target');
596 const content = $('#' + targetId);
597 const icon = $(this).find('.toggle-icon');
598
599 if (content.is(':visible')) {
600 content.slideUp(200);
601 icon.css('transform', 'rotate(0deg)');
602 } else {
603 content.slideDown(200);
604 icon.css('transform', 'rotate(180deg)');
605 }
606 });
607
608 // Reset override field button
609 $(document).on('click', '.reset-override-field', function(e) {
610 e.preventDefault();
611 const fieldId = $(this).data('field');
612 const field = $('#' + fieldId);
613
614 // Determine placeholder based on field type
615 let defaultValue = '';
616 if (fieldId.indexOf('override_title_') !== -1) {
617 defaultValue = '{{post_title}}';
618 } else if (fieldId.indexOf('override_description_') !== -1) {
619 defaultValue = '{{post_description}}';
620 } else if (fieldId.indexOf('override_image_') !== -1) {
621 defaultValue = '{{featured_image}}';
622 } else {
623 defaultValue = field.data('default-value') || '';
624 }
625
626 // Reset the field value to placeholder
627 field.val(defaultValue);
628
629 // If it's an image field, hide the preview when resetting to placeholder
630 if (fieldId.indexOf('override_image_') !== -1) {
631 const index = fieldId.replace('override_image_', '');
632 const preview = $('#override_image_preview_' + index);
633 // If resetting to placeholder, hide preview (will use default featured image)
634 if (defaultValue === '{{featured_image}}') {
635 preview.hide();
636 }
637 }
638 });
639
640 // Image uploader for override image field
641 let overrideImageUploader;
642 $(document).on('click', '.upload-image-button', function(e) {
643 e.preventDefault();
644 const targetIndex = $(this).data('target');
645 const fieldId = $(this).data('field-id');
646
647 // If the media frame already exists, reopen it
648 if (overrideImageUploader) {
649 overrideImageUploader.open();
650 overrideImageUploader.targetField = fieldId;
651 overrideImageUploader.targetPreview = 'override_image_preview_' + targetIndex;
652 return;
653 }
654
655 // Create the media frame
656 overrideImageUploader = wp.media({
657 title: 'Choose Schema Image',
658 button: {
659 text: 'Use this image'
660 },
661 multiple: false,
662 library: {
663 type: 'image'
664 }
665 });
666
667 // Store target field info
668 overrideImageUploader.targetField = fieldId;
669 overrideImageUploader.targetPreview = 'override_image_preview_' + targetIndex;
670
671 // When an image is selected, run a callback
672 overrideImageUploader.on('select', function() {
673 const attachment = overrideImageUploader.state().get('selection').first().toJSON();
674 $('#' + overrideImageUploader.targetField).val(attachment.url);
675 $('#' + overrideImageUploader.targetPreview + ' img').attr('src', attachment.url);
676 $('#' + overrideImageUploader.targetPreview).show();
677 });
678
679 // Open the uploader dialog
680 overrideImageUploader.open();
681 });
682
683 });
684
685
686