PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 4.0.6
Visualizer – Tables & Charts Manager with Built-in AI Generator v4.0.6
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 3.10.4 All 148 releases
visualizer / js / preview.js

preview.js in Visualizer – Tables & Charts Manager with Built-in AI Generator 4.0.6, at js/preview.js

287 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* global visualizer */
2 /* global console */
3 /* global vizSettingsHaveChanged */
4 /* global vizHaveSettingsChanged */
5 /* global wp */
6
7 (function($, v) {
8 var timeout;
9
10 $(document).ready(function() {
11 // when data is impported using csv/url, update the hidden data and the advanced settings sidebar.
12 // editor and sidebar are both JSON objects
13 window.vizUpdateHTML = function( editor, sidebar ) {
14 $('.viz-simple-editor').remove();
15 $('#content').append(editor.html);
16 $('#settings-form .viz-group').remove();
17 $('#settings-form').append(sidebar.html);
18
19 $('#settings-form .control-text').change(updateChart).keyup(updateChart);
20 $('#settings-form .control-select, #settings-form .control-checkbox, #settings-form .control-check').change(updateChart);
21 $('#settings-form .color-picker-hex').wpColorPicker({
22 change: updateChart,
23 clear: updateChart
24 });
25 $('#settings-form textarea[name="manual"]').change(validateJSON).keyup(validateJSON);
26 initManualConfigEditor();
27 vizSettingsHaveChanged(false);
28 };
29
30 // Update google chart filter control.
31 window.vizUpdateFilterControl = function() {
32 $( '#control_wrapper_canvas' ).removeClass( 'no-filter' );
33 var controlsOpt = $( '.vz-controls-opt' ).map(
34 function() {
35 var val = $(this).val();
36 return '' !== val && 'false' !== val ? val : false ;
37 }
38 ).get();
39 controlsOpt = controlsOpt.filter( function(el) { return el; } );
40 if ( controlsOpt.length === 0 ) {
41 $( '#control_wrapper_canvas' ).addClass( 'no-filter' ).html('');
42 }
43 }
44
45 /**
46 * Capture the relevant form data.
47 *
48 * @returns {Object} The captured form data.
49 */
50 function captureFormData() {
51 const formData = new FormData(document.querySelector('#settings-form'));
52 const featureData = {};
53
54 formData.forEach((value, optionKey) => {
55 if (
56 ! value ||
57 ( ! ['permissions', 'controls', 'manual', 'lazy'].some( key => optionKey.startsWith(key) ) )
58 ) {
59 return;
60 }
61
62 if ( optionKey.endsWith('[]') ) {
63 if( !featureData[optionKey] ) {
64 featureData[optionKey] = [];
65 }
66 featureData[optionKey].push(value);
67 } else {
68 featureData[optionKey] = value;
69 }
70 });
71
72 for (const key in featureData) {
73 if (Array.isArray(featureData[key])) {
74 featureData[key] = featureData[key].join(','); // We can not send arrays in the tracking data.
75 }
76 }
77
78 return featureData;
79 }
80
81 const initialCaptureData = captureFormData();
82
83 /**
84 * Capture feature usage.
85 */
86 async function trackSavedData() {
87 const savedData = captureFormData();
88
89 // Remove default values.
90 for (const key in savedData) {
91
92 if ( key === 'lazy_load_chart' ) {
93 continue;
94 }
95
96 if ( savedData[key] === initialCaptureData[key] ) {
97 delete savedData[key];
98 }
99 }
100
101 const hasPermission = Object.keys(savedData).some(key => key.startsWith('permissions')).length > 0;
102 const hasControls = Object.keys(savedData).some(key => key.startsWith('controls')).length > 0;
103
104 const featureData = {
105 lazy: savedData.lazy_load_chart,
106 permissions: hasPermission ? 'used' : 'ignored',
107 controls: hasControls ? 'used' : 'ignored',
108 };
109
110 if (savedData.manual) {
111 featureData['manualConfig'] = savedData.manual;
112 }
113
114 const urlParams = new URLSearchParams(window.location.search);
115
116 window?.tiTrk?.with('visualizer')?.add({
117 feature: 'chart-edit',
118 featureComponent: 'saved-data',
119 featureData,
120 groupId: urlParams.get('chart') ?? ''
121 });
122
123 // Do not make the user to wait too long for the event to be uploaded.
124 const timer = new Promise((resolve) => setTimeout(resolve, 500));
125 await Promise.race([timer, window?.tiTrk?.uploadEvents()]);
126 }
127
128 document.querySelector('#settings-button')?.addEventListener('click', async function() {
129 if( typeof window.tiTrk !== 'undefined' ) {
130 try {
131 await trackSavedData();
132 } catch (e) {
133 console.warn(e);
134 }
135 }
136
137 // Get and send the chart ID (used by Visualizer Block).
138 var urlParams = new URLSearchParams(window.location.search);
139 var chartID = urlParams.get('chart');
140 if ( chartID ) {
141 window.parent.postMessage({ chartID: chartID}, '*');
142 }
143
144 $('#settings-form').submit();
145 });
146
147 // this portion captures if the settings have changed so that tabs can handle that information.
148 var viz_settings_have_changed = false;
149
150 window.vizHaveSettingsChanged = function(){
151 return viz_settings_have_changed;
152 };
153
154 window.vizSettingsHaveChanged = function(value){
155 viz_settings_have_changed = value;
156 };
157 // this portion captures if the settings have changed so that tabs can handle that information.
158
159 function updateChart() {
160 vizUpdateFilterControl();
161 clearTimeout(timeout);
162 timeout = setTimeout(function() {
163 var settings = $('#settings-form').serializeObject();
164 settings = JSON.stringify( settings ).replace( /<\/?[^>]+(>|$)/g, '' );
165 settings = JSON.parse( settings );
166 delete settings['width'];
167 delete settings['height'];
168
169 v.charts.canvas.settings = settings;
170 $('body').trigger('visualizer:render:currentchart:update', {visualizer: v});
171 vizSettingsHaveChanged(true);
172 }, 1500);
173 }
174
175 function validateJSON() {
176 $('#visualizer-error-manual').remove();
177 try{
178 JSON.parse($(this).val());
179 }catch(error){
180 var $after = $(this).next('.CodeMirror').length ? $(this).next('.CodeMirror') : $(this);
181 $('<div class="visualizer-error" id="visualizer-error-manual">Invalid JSON: ' + error + '</div>').insertAfter($after);
182 }
183 }
184
185 function initManualConfigEditor() {
186 var $textarea = $('textarea[name="manual"]');
187 if (!$textarea.length || $textarea.data('cm-initialized')) return;
188
189 var CodeMirrorLib = (typeof wp !== 'undefined' && wp.CodeMirror) ? wp.CodeMirror : null;
190 if (!CodeMirrorLib) return;
191
192 $textarea.data('cm-initialized', true);
193
194 var cm = CodeMirrorLib.fromTextArea($textarea.get(0), {
195 mode: 'application/json',
196 lineNumbers: true,
197 lineWrapping: true,
198 matchBrackets: true,
199 autoCloseBrackets: true
200 });
201
202 // Refresh when any sidebar group is expanded so line numbers render correctly
203 // (CodeMirror can't measure gutter width while the container is hidden).
204 $(document).on('click.vizManualConfig', '.viz-group-title', function() {
205 setTimeout(function() { cm.refresh(); }, 50);
206 });
207
208 cm.on('change', function() {
209 cm.save();
210 $textarea.trigger('change');
211 });
212 }
213
214 $('.control-text').change(updateChart).keyup(updateChart);
215 $('.control-select, .control-checkbox, .control-check').change(updateChart);
216 $('.color-picker-hex').wpColorPicker({
217 change: updateChart,
218 clear: updateChart
219 });
220 $('textarea[name="manual"]').change(validateJSON).keyup(validateJSON);
221 initManualConfigEditor();
222
223 $(document).on('change', 'input[name="paging_bool"], input[name="pagination"]', function() {
224 $('.viz-pagination-options').toggle($(this).is(':checked'));
225 });
226
227 });
228 })(jQuery, visualizer);
229
230 (function($) {
231 $.fn.serializeObject = function() {
232 var self = this,
233 json = {},
234 push_counters = {},
235 patterns = {
236 "validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
237 "key": /[a-zA-Z0-9_]+|(?=\[\])/g,
238 "push": /^$/,
239 "fixed": /^\d+$/,
240 "named": /^[a-zA-Z0-9_]+$/
241 };
242
243 this.build = function(base, key, value) {
244 base[key] = value;
245 return base;
246 };
247
248 this.push_counter = function(key) {
249 if (push_counters[key] === undefined) {
250 push_counters[key] = 0;
251 }
252 return push_counters[key]++;
253 };
254
255 $.each($(this).serializeArray(), function() {
256 // skip invalid keys
257 if (!patterns.validate.test(this.name)) {
258 return;
259 }
260
261 var k,
262 keys = this.name.match(patterns.key),
263 merge = this.value,
264 reverse_key = this.name;
265
266 while ((k = keys.pop()) !== undefined) {
267 // adjust reverse_key
268 reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');
269
270 if (k.match(patterns.push)) {
271 // push
272 merge = self.build([], self.push_counter(reverse_key), merge);
273 } else if (k.match(patterns.fixed)) {
274 // fixed
275 merge = self.build([], k, merge);
276 } else if (k.match(patterns.named)) {
277 // named
278 merge = self.build({}, k, merge);
279 }
280 }
281
282 json = $.extend(true, json, merge);
283 });
284
285 return json;
286 };
287 })(jQuery);