PluginProbe ʕ •ᴥ•ʔ
Strong Testimonials / 2.38
Strong Testimonials v2.38
3.3.2 3.3.1 trunk 1.0.1 2.30.9 2.31.10 2.32 2.32.1 2.32.2 2.32.3 2.32.4 2.33 2.34 2.35 2.36 2.37 2.38 2.38.1 2.39 2.39.1 2.39.2 2.39.3 2.40.0 2.40.1 2.40.2 2.40.3 2.40.4 2.40.5 2.40.6 2.40.7 2.41.0 2.41.1 2.50.0 2.50.1 2.50.2 2.50.3 2.50.4 2.51.0 2.51.1 2.51.2 2.51.3 2.51.4 2.51.5 2.51.6 2.51.7 2.51.8 2.51.9 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 3.1.19 3.1.2 3.1.20 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.10 3.2.11 3.2.12 3.2.13 3.2.14 3.2.15 3.2.16 3.2.17 3.2.18 3.2.19 3.2.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0
strong-testimonials / admin / js / views.js
strong-testimonials / admin / js Last commit date
lib 7 years ago addon-licenses.js 7 years ago admin-compat.js 7 years ago admin-fields.js 7 years ago admin-form.js 7 years ago admin-global.js 7 years ago admin-order.js 7 years ago custom-spinner.js 7 years ago help.js 7 years ago rating-edit.js 7 years ago view-category-filter.js 7 years ago views.js 7 years ago
views.js
1337 lines
1 /**
2 * Strong Testimonials - Views
3 */
4
5 // Function to get the Max value in Array
6 Array.max = function (array) {
7 return Math.max.apply(Math, array);
8 };
9
10 (function ($) {
11 $.fn.showInlineBlock = function () {
12 return this.css('display', 'inline-block');
13 };
14 })(jQuery);
15
16 /**
17 * jQuery alterClass plugin
18 *
19 * Remove element classes with wildcard matching. Optionally add classes:
20 * $( '#foo' ).alterClass( 'foo-* bar-*', 'foobar' )
21 *
22 * https://gist.github.com/peteboere/1517285
23 *
24 * Copyright (c) 2011 Pete Boere (the-echoplex.net)
25 * Free under terms of the MIT license: http://www.opensource.org/licenses/mit-license.php
26 */
27 (function ($) {
28 $.fn.alterClass = function (removals, additions) {
29
30 var self = this;
31
32 if (removals.indexOf('*') === -1) {
33 // Use native jQuery methods if there is no wildcard matching
34 self.removeClass(removals);
35 return !additions ? self : self.addClass(additions);
36 }
37
38 var patt = new RegExp('\\s' +
39 removals.replace(/\*/g, '[A-Za-z0-9-_]+').split(' ').join('\\s|\\s') +
40 '\\s', 'g');
41
42 self.each(function (i, it) {
43 var cn = ' ' + it.className + ' ';
44 while (patt.test(cn)) {
45 cn = cn.replace(patt, ' ');
46 }
47 it.className = $.trim(cn);
48 });
49
50 return !additions ? self : self.addClass(additions);
51 };
52 })(jQuery);
53
54 /**
55 * Special handling after toggling certain options.
56 */
57 (function ($) {
58 // custom handling
59 $.fn.afterToggle = function () {
60
61 // Category selector
62 var $categoryDivs = $('.view-category-list-panel');
63 // Set initial width to compensate for narrowed box due to checkbox being hidden first
64 // and to prevent horizontal jumpiness as filter is applied.
65 if (!$categoryDivs.hasClass('fixed')) {
66 $categoryDivs.width($categoryDivs.outerWidth(true)).addClass('fixed');
67 }
68
69 // Slideshow controls
70 var $controls = $('#view-slideshow_controls_type');
71 var $pager = $('#view-slideshow_pager_type');
72 var controlsValue = $controls.val();
73 var pagerValue = $pager.val();
74
75 if ('full' === controlsValue) {
76 $('.then_has-pager').fadeOut();
77 $pager.val('none');
78 $('option[value="text"]', '#view-slideshow_controls_style').prop('disabled', false);
79 }
80 else if ('sides' === controlsValue) {
81 $('.then_has-pager').fadeIn();
82 var $style = $('#view-slideshow_controls_style');
83 if ('text' === $style.val()) {
84 $('option:first', $style).prop('selected', true);
85 }
86 $('option[value="text"]', $style).prop('disabled', true);
87 }
88 else {
89 $('.then_has-pager').fadeIn();
90 $('option[value="text"]', '#view-slideshow_controls_style').prop('disabled', false);
91 }
92
93 if ('none' === pagerValue && ('none' === controlsValue || 'sides' === controlsValue)) {
94 $('.then_has-position').fadeOut();
95 }
96 else {
97 $('.then_has-position').fadeIn();
98 }
99
100 // If no navigation, must start automatically.
101 if ('none' === pagerValue && 'none' === controlsValue) {
102 $('#view-auto_start').val('1').prop('checked', true);
103 }
104
105 return this;
106 };
107 }(jQuery));
108
109 /**
110 * Remove 'result' query argument.
111 */
112 removeResultArg = function () {
113 var urlParams = new URLSearchParams(window.location.search);
114 if (urlParams.has('result')) {
115 urlParams.delete('result');
116 var newURL = window.location.pathname;
117 if (urlParams.toString()) {
118 newURL = newURL + '?' + urlParams.toString();
119 }
120 window.history.replaceState({}, document.title, newURL);
121 }
122 };
123
124 /**
125 * Initial actions on document.ready
126 */
127 jQuery(document).ready(function ($) {
128
129 // Masonry in the Layout section
130 $('.view-layout-masonry .example-container')
131 .find('.box')
132 .width(jQuery('.grid-sizer').width())
133 .end()
134 .masonry();
135
136 // Category select width
137 $.fn.afterToggle();
138
139 removeResultArg();
140 });
141
142 (function ($) {
143 'use strict';
144
145 // the shortcode code
146 $('#view-shortcode').on('focus', function () {
147 $(this).select();
148 });
149
150 $('.expand-cats').on('click', function () {
151 // TODO i18n
152 var $categoryDivs = $('.view-category-list-panel');
153 if ($categoryDivs.hasClass('tall-panel')) {
154 $categoryDivs.addClass('short-panel').removeClass('tall-panel');
155 $(this).val('expand list');
156 } else {
157 $categoryDivs.removeClass('short-panel').addClass('tall-panel');
158 $(this).val('collapse list');
159 }
160 $(this).blur();
161 });
162
163 // Masonry example
164 var masonryExample = $('.view-layout-masonry .example-container');
165 masonryExample.find('.box').width($('.grid-sizer').width()).end().masonry({
166 columnWidth: '.grid-sizer',
167 gutter: 10,
168 itemSelector: '.box',
169 percentPosition: true
170 });
171
172 // Column count selector
173 var columnCount = $('#view-column-count');
174 var columnCountChange = function () {
175 var col = columnCount.val();
176 $('.example-container').alterClass('col-*', 'col-' + col);
177 masonryExample.find('.box').width($('.grid-sizer').width()).end().masonry();
178 };
179
180 columnCountChange();
181 columnCount.on('change', columnCountChange);
182 $('input[name=\'view[data][layout]\']').on('change', function () {
183 if ('masonry' === $(this).val()) {
184 setTimeout(columnCountChange, 200);
185 }
186 });
187
188 // Color pickers
189 var myOptions = {
190 // you can declare a default color here, or in the data-default-color attribute on the input
191 //defaultColor: '#FFFFFF',
192 // a callback to fire whenever the color changes to a valid color
193 change: function (event, ui) {
194 setTimeout(function () {
195 updateBackgroundPreview();
196 }, 250);
197 },
198 // a callback to fire when the input is emptied or an invalid color
199 clear: function (event, ui) {
200 setTimeout(function () {
201 updateBackgroundPreview();
202 }, 250);
203 },
204 // hide the color picker controls on load
205 //hide: true,
206 // show a group of common colors beneath the square
207 // or, supply an array of colors to customize further
208 palettes: true
209 };
210 $('.wp-color-picker-field').wpColorPicker(myOptions);
211
212 /**
213 * Restore defaults
214 */
215 // TODO i18n
216 $('#restore-defaults').on('click', function () {
217 return confirm('Restore the default settings?');
218 });
219
220 /**
221 * -----------------
222 * Dependent options
223 * -----------------
224 */
225
226 /**
227 * Special handling
228 * TODO Use a technique similar to if-then for adding/removing classes
229 */
230
231 /*
232 var viewContent = $('#view-content');
233 var viewContentChange = function () {
234 var thisValue = viewContent.val();
235 viewContent.closest('td').find('.highlight2').each(function (index, el) {
236 if ('excerpt' === thisValue) {
237 $(el).addClass('highlight-on');
238 } else {
239 $(el).removeClass('highlight-on');
240 }
241 });
242 };
243 viewContentChange();
244 viewContent.on('change', viewContentChange);
245 */
246
247 /**
248 * Update option for [adding read-more to excerpts] based on setting
249 * for [read-more type] (link to post or expand in place).
250 */
251 var viewHybrid = $('#view-more_post_in_place');
252
253 var viewHybridChange = function () {
254
255 var thisValue = viewHybrid.val();
256
257 // var viewMoreFullPost = $('#view-more_full_post');
258 // if ('1' === thisValue) {
259 // viewMoreFullPost.prop('disabled', true).find('option[value=\'1\']').prop('selected', true);
260 // } else {
261 // viewMoreFullPost.removeProp('disabled');
262 // }
263
264 var viewDefaultMore = $('#view-use_default_more');
265 if ('1' === thisValue) {
266 viewDefaultMore.prop('disabled', true).find('option[value=\'0\']').prop('selected', true);
267 } else {
268 viewDefaultMore.removeProp('disabled');
269 }
270 viewDefaultMore.change();
271
272 };
273
274 viewHybridChange();
275
276 viewHybrid.on('change', viewHybridChange);
277
278 /**
279 * Plugin: Show/Hide parts based on current Mode
280 */
281 $.fn.updateScreen = function (mode, speed) {
282 speed = speed || 400;
283 if (!mode)
284 return;
285
286 var modeDesc = $('.mode-description');
287 modeDesc.html('');
288 $('.then_' + mode).fadeIn(speed);
289 $('.then_not_' + mode).fadeOut(speed);
290
291 /**
292 * Special handling
293 */
294 switch (mode) {
295 case 'form':
296 // hack
297 setTimeout(formTemplateDescriptions, 500);
298 break;
299 case 'slideshow':
300 break;
301 case 'display':
302 // update single/multiple selector ONLY
303 $.fn.selectPerOption($('#view-single_or_multiple'));
304 break;
305 case 'single_template':
306 break;
307 default:
308 }
309
310 /**
311 * Update description
312 *
313 * @since 2.22.0
314 */
315 var data = {
316 'action': 'wpmtst_view_get_mode_description',
317 'mode': mode
318 };
319 $.get(ajaxurl, data, function (response) {
320 if (response) {
321 modeDesc.html(response);
322 }
323 });
324
325 return this;
326 };
327
328 /**
329 * Plugin: Toggle dependent options for checkboxes.
330 *
331 * Show/hide other option groups when checkbox is "on".
332 * Single value
333 */
334 $.fn.toggleOption = function (el, speed) {
335 speed = speed || 400;
336 var option = $(el).attr('id').split('-').pop();
337 var checked = $(el).prop('checked');
338 var deps = '.then_' + option;
339 var indeps = '.then_not_' + option;
340 if (checked) {
341 $(deps).fadeIn(speed);
342 $(indeps).fadeOut(speed);
343 }
344 else {
345 $(deps).fadeOut(speed);
346 $(indeps).fadeIn(speed);
347 }
348 return this;
349 };
350
351 /**
352 * Plugin: Toggle dependent options for checkboxes.
353 *
354 * Show/hide other option groups when checkbox is "on".
355 * Multiple values
356 *
357 * @since 1.20.0
358 */
359 $.fn.selectPerOption = function (el, speed) {
360 speed = speed || 400;
361 var fast = 0;
362 //var option = $(el).attr("id").split("-").pop();
363 var currentValue = $(el).val();
364 var deps = '.then_' + currentValue;
365 var depsFast = deps + '.fast';
366 var indeps = '.then_not_' + currentValue;
367 var indepsFast = indeps + '.fast';
368 if (currentValue) {
369
370 $(depsFast).not('.then_not_' + currentMode).fadeIn(fast);
371 $(deps).not('.fast, .then_not_' + currentMode).fadeIn(speed);
372
373 $(indepsFast).fadeOut(fast);
374 $(indeps).not('.fast').fadeOut(speed);
375
376 } else {
377
378 $(indepsFast).fadeIn(fast);
379 $(indeps).not('.fast').fadeIn(speed);
380
381 $(depsFast).fadeOut(fast);
382 $(deps).not('.fast').fadeOut(speed);
383
384 }
385 return this;
386 };
387
388 /**
389 * Plugin: Toggle dependent options for selects.
390 *
391 * Show/hide other option groups when one and only one *specific* option is selected.
392 * class="if select"
393 * ~TRIP~
394 */
395 $.fn.selectOption = function (el, speed) {
396 speed = speed || 400;
397 var currentValue = $(el).val();
398 var tripValue = $(el).find('.trip').val();
399 var option = $(el).attr('id').split('-').pop();
400 var deps = '.then_' + option;
401 if (currentValue === tripValue) {
402 $(deps).fadeIn(speed);
403 }
404 else {
405 $(deps).fadeOut(speed);
406 }
407 return this;
408 };
409
410 /**
411 * Plugin: Toggle dependent options for selects.
412 *
413 * Show/hide other option groups when one and only one *specific* option is selected.
414 * class="if selectnot"
415 * ~TRIP~
416 */
417 $.fn.selectNotOption = function (el, speed) {
418 speed = speed || 400;
419 var currentValue = $(el).val();
420 var tripValue = $(el).find('.trip').val();
421 var option = $(el).attr('id').split('-').pop();
422 var deps = '.then_' + option;
423 if (currentValue === tripValue) {
424 $(deps).fadeOut(speed);
425 }
426 else {
427 $(deps).fadeIn(speed);
428 }
429 return this;
430 };
431
432 /**
433 * Plugin: Toggle dependent options for selects.
434 *
435 * Show/hide other option groups when any *non-empty (initial)* option is selected.
436 * class="if selectany"
437 */
438 $.fn.selectAnyOption = function (el, speed) {
439 speed = speed || 400;
440 var currentValue = $(el).val();
441 var option = $(el).attr('id').split('-').pop();
442 var deps = '.then_' + option + '.then_' + currentValue;
443 var indeps = '.then_not_' + option + '.then_' + currentValue;
444 if (currentValue) {
445 $(deps).fadeIn(speed);
446 $(indeps).fadeOut(speed);
447 }
448 else {
449 $(deps).fadeOut(speed);
450 $(indeps).fadeIn(speed);
451 }
452 return this;
453 };
454
455 /**
456 * Plugin: Toggle dependent options.
457 *
458 * Show/hide other option groups depending on value (1:1 relationshsip).
459 * Using both option and value, which is different method than other functions.
460 * class="if selectgroup"
461 *
462 * @since 1.20.0
463 */
464 $.fn.selectGroupOption = function (el) {
465 var speed = 400,
466 fastOut = 0,
467 fastIn = 100;
468 var option = $(el).attr('id').split('-').pop();
469 var currentValue = $(el).val();
470 var deps = '.then_' + option + '.then_' + currentValue;
471 var depsFast = deps + '.fast';
472 var indeps = '.then_' + option + '.then_not_' + currentValue;
473 var indepsFast = indeps + '.fast';
474 if (currentValue) {
475 $(depsFast).fadeIn(fastIn);
476 $(deps).not('.fast').fadeIn(speed);
477 $(indepsFast).fadeOut(fastOut);
478 $(indeps).not('.fast').fadeOut(speed);
479 }
480 else {
481 $(indepsFast).fadeIn(fastIn);
482 $(indeps).not('.fast').fadeIn(speed);
483 $(depsFast).fadeOut(fastOut);
484 $(deps).not('.fast').fadeOut(speed);
485 }
486 return this;
487 };
488
489 /**
490 * Initial state
491 */
492 var $mode = $('#view-mode');
493 var currentMode = $mode.find('input:checked').val();
494 $mode.find('input:checked').closest('label').addClass('checked');
495 $.fn.updateScreen(currentMode);
496
497 /**
498 * Mode listener
499 */
500 $mode.find('input').on('change', function () {
501 currentMode = $(this).val();
502 $mode.find('input').not(':checked').closest('label').removeClass('checked');
503 $mode.find('input:checked').closest('label').addClass('checked');
504 $.fn.updateScreen(currentMode);
505
506 // Force default template since we have more than one group of templates.
507 $('input[type=radio][name=\'view[data][template]\'][value=\'default\']').prop('checked', true);
508 templateRadios.change();
509 $('input[type=radio][name=\'view[data][form-template]\'][value=\'default-form\']').prop('checked', true);
510 // formTemplateRadios.change();
511 layoutRadios.change();
512 backgroundRadios.change();
513 });
514
515 /**
516 * Initial state & Change listeners
517 */
518 function initialize () {
519 $('.if.toggle').each(function (index, el) {
520 $.fn.toggleOption(this);
521 $(this).on('change', function () {
522 $.fn.toggleOption(this);
523 });
524 });
525
526 $('.if.select').each(function (index, el) {
527 $.fn.selectOption(this);
528 $(this).on('change', function () {
529 $.fn.selectOption(this);
530 });
531 });
532
533 $('.if.selectnot').each(function (index, el) {
534 $.fn.selectNotOption(this);
535 $(this).on('change', function () {
536 $.fn.selectNotOption(this).afterToggle();
537 });
538 });
539
540 $('.if.selectany').each(function (index, el) {
541 $.fn.selectAnyOption(this);
542 $(this).on('change', function () {
543 $.fn.selectAnyOption(this);
544 });
545 });
546
547 $('.if.selectper').each(function (index, el) {
548 $.fn.selectPerOption(this);
549 $(this).on('change', function () {
550 $.fn.selectPerOption(this).afterToggle();
551 });
552 });
553
554 $('.if.selectgroup').each(function (index, el) {
555 $.fn.selectGroupOption(this);
556 $(this).on('change', function () {
557 $.fn.selectGroupOption(this);
558 });
559 });
560
561 $('.field-name select').each(function () {
562 var $el = $(this);
563 var $elParent = $el.closest('.field3');
564 var fieldValue = $el.val();
565 var fieldType = $el.find('option:selected').data('type');
566 var key = $elParent.data('key');
567 var typeSelectParent = $elParent.find('td.field-type');
568 var typeSelect = typeSelectParent.find('select');
569
570 if (fieldValue === 'post_date') {
571 typeSelect.prop('disabled', true);
572 typeSelect.parent().append('<input type="hidden" class="save-type" name="view[data][client_section][' + key + '][save-type]" value="date">');
573 }
574 else if (fieldValue === 'submit_date') {
575 typeSelect.prop('disabled', true);
576 typeSelect.parent().append('<input type="hidden" class="save-type" name="view[data][client_section][' + key + '][save-type]" value="date">');
577 }
578 else if (fieldValue === 'category') {
579 typeSelect.prop('disabled', true);
580 typeSelect.parent().append('<input type="hidden" class="save-type" name="view[data][client_section][' + key + '][save-type]" value="category">');
581 }
582 else if (fieldType === 'rating') { /* --- type! --- */
583 typeSelect.prop('disabled', true);
584 typeSelectParent.append('<input type="hidden" class="save-type" name="view[data][client_section][' + key + '][save-type]" value="rating">');
585 }
586 else {
587 $(typeSelect).prop('disabled', false);
588 $(typeSelect).parent().find('input.save-type').remove();
589 }
590 });
591
592 }
593
594 initialize();
595
596 /**
597 * Link field text change listener
598 */
599 function textChangeListener () {
600 $('select[id^="view-fieldtext"]').on('change', function () {
601 if ($(this).val() === 'custom') {
602 var key = $(this).closest('.field3').data('key');
603 $('#view-fieldtext' + key + '-custom').focus();
604 }
605 });
606 }
607
608 textChangeListener();
609
610 /**
611 * Template change listener
612 */
613 // TODO Use ID
614 var templateRadios = $('input[type=radio][name=\'view[data][template]\']');
615
616 function templateDescriptions () {
617 var templateRadioOff, templateRadioOn, template;
618
619 templateRadioOff = templateRadios.filter(':not(:checked)');
620 templateRadioOff.closest('li').removeClass('current-selection').find('.options').hide();
621
622 templateRadioOn = templateRadios.filter(':checked');
623 template = templateRadioOn.val();
624 templateRadioOn.closest('li').addClass('current-selection').find('.options').show();
625
626 // Check for forced options
627 if (template) {
628 $('input.forced').removeProp('disabled').removeClass('forced');
629 var data = {
630 'action': 'wpmtst_force_check',
631 'template': template
632 };
633 $.get(ajaxurl, data, function (response) {
634 if (response.success) {
635 var arrayLength, $el, inputName;
636 arrayLength = response.data.length;
637 for (var i = 0; i < arrayLength; i++) {
638 $el = $('#' + response.data[i]);
639 $el.prop('checked', true).change();
640 inputName = $el.prop('name');
641 $('input[name=\'' + inputName + '\']').prop('disabled', true).addClass('forced');
642 }
643 }
644 });
645
646 // Special handling
647 if ('unstyled' === template) {
648 $('input[name=\'view[data][background][type]\']').prop('disabled', true);
649 $('input[name=\'view[data][font-color][type]\']').prop('disabled', true);
650 } else {
651 $('input[name=\'view[data][background][type]\']').prop('disabled', false);
652 $('input[name=\'view[data][font-color][type]\']').prop('disabled', false);
653 }
654
655 // Special handling for Lucid add-on until I can incorporate a template group config file
656 if ('lucid' === template.substr(0, 5) || 'single_template' === currentMode) {
657 $('.then_lucid').show();
658 } else {
659 $('.then_lucid').hide();
660 }
661 }
662 }
663
664 templateDescriptions();
665
666 templateRadios.on('change', templateDescriptions);
667
668 /**
669 * Form template change listener
670 */
671 var formTemplateRadios = $('input[type=radio][name=\'view[data][form-template]\']');
672
673 function formTemplateDescriptions () {
674 var formTemplateRadioOff, formTemplateRadioOn, formTemplate;
675
676 formTemplateRadioOff = formTemplateRadios.filter(':not(:checked)');
677 formTemplateRadioOff.closest('li').removeClass('current-selection').find('.options').hide();
678
679 formTemplateRadioOn = formTemplateRadios.filter(':checked');
680 formTemplate = formTemplateRadioOn.val();
681 formTemplateRadioOn.closest('li').addClass('current-selection').find('.options').show();
682 }
683
684 formTemplateDescriptions();
685
686 formTemplateRadios.on('change', formTemplateDescriptions);
687
688 /**
689 * Layout change listener
690 */
691 // TODO Use ID instead.
692 var layoutRadios = $('input[type=radio][name=\'view[data][layout]\']');
693
694 function layoutDescriptions () {
695 var layoutRadioOff, layoutRadioOn, layout;
696
697 layoutRadioOff = layoutRadios.filter(':not(:checked)');
698 layoutRadioOff.closest('li').removeClass('current-selection').find('.options').hide();
699
700 layoutRadioOn = layoutRadios.filter(':checked');
701 layout = layoutRadioOn.attr('id');
702 layoutRadioOn.closest('li').addClass('current-selection').find('.options').show();
703
704 $('.layout-description, .layout-example').hide();
705 $('.' + layout).show();
706
707 // Special handling
708
709 if ('view-layout-normal' === layout)
710 $('#column-count-wrapper').fadeOut();
711 else
712 $('#column-count-wrapper').fadeIn();
713
714 if ('view-layout-masonry' === layout) {
715 if ($('#view-pagination').is(':checked')) {
716 alert('Masonry is incompatible with pagination. Please disable pagination first.');
717 $('#view-layout-normal').prop('checked', true).change();
718 }
719 }
720 }
721
722 layoutDescriptions();
723
724 layoutRadios.on('change', layoutDescriptions);
725
726 /**
727 * Pagination change listener
728 */
729 function paginationChangeListener () {
730 // Pagination is incompatible with Masonry
731 // TODO DRY
732 if ($(this).is(':checked') && 'masonry' === layoutRadios.filter(':checked').val()) {
733 alert('Pagination is incompatible with Masonry. Please select another layout first.');
734 $(this).prop('checked', false).change();
735 }
736 }
737
738 $('#view-pagination').on('change', paginationChangeListener);
739
740 /**
741 * Disallow standard pagination with query limit.
742 */
743 var $viewQuantity = $('#view-all'),
744 $viewPaginationType = $('#view-pagination_type');
745
746 function paginationTypeChangeListener () {
747 if (this.value === 'standard' && $viewQuantity.val() === '0' && $('#view-pagination').is(':checked')) {
748 alert('Standard pagination is incompatible with Count.');
749 $(this).val('simple').change();
750 }
751 }
752
753 function quantityChangeListener () {
754 if (this.value === '0' && $viewPaginationType.val() === 'standard' && $('#view-pagination').is(':checked')) {
755 alert('Count is incompatible with Standard pagination.');
756 $(this).val(1).change();
757 }
758 }
759
760 $viewPaginationType.on('change', paginationTypeChangeListener);
761 $viewQuantity.on('change', quantityChangeListener);
762
763 /**
764 * ----------------------------------------------------------------------
765 * Background and Font colors
766 * ----------------------------------------------------------------------
767 */
768 function updateBackgroundPreview () {
769 var c1,
770 c2,
771 c3,
772 background = backgroundRadios.filter(':checked').val(),
773 fontColor = fontColorRadios.filter(':checked').val();
774
775 if ('custom' === fontColor) {
776 c3 = document.getElementById('fc-color').value;
777 backgroundPreview.css('color', c3);
778 } else {
779 backgroundPreview.css('color', 'inherit');
780 }
781 switch (background) {
782 case '':
783 backgroundPreview.css('background', 'transparent');
784 break;
785 case 'single':
786 c1 = document.getElementById('bg-color').value;
787 backgroundPreview.css('background', c1);
788 break;
789 case 'gradient':
790 c1 = document.getElementById('bg-gradient1').value;
791 c2 = document.getElementById('bg-gradient2').value;
792 backgroundPreview.css(constructGradientCSS(c1, c2));
793 break;
794 case 'preset':
795 backgroundPreset(backgroundPresetSelector.val());
796 break;
797 default:
798 }
799
800 }
801
802 var backgroundRadios = $('input[type=radio][name=\'view[data][background][type]\']'),
803 backgroundPreview = $('#background-preview'),
804 backgroundPresetSelector = $('#view-background-preset');
805
806 /**
807 * Font-color change listener
808 */
809 // TODO Use ID instead.
810 var fontColorRadios = $('input[type=radio][name=\'view[data][font-color][type]\']');
811
812 function fontColorDescriptions () {
813 var fontColorRadioOff, fontColorRadioOn, fontColorID;
814
815 fontColorRadioOff = fontColorRadios.filter(':not(:checked)');
816 fontColorRadioOff.closest('li').removeClass('current-selection');
817
818 fontColorRadioOn = fontColorRadios.filter(':checked');
819 fontColorID = fontColorRadioOn.filter(':checked').attr('id');
820 fontColorRadioOn.closest('li').addClass('current-selection');
821
822 $('#view-font-color-info')
823 .find('.font-color-description:visible')
824 .hide()
825 .end()
826 .find('.' + fontColorID)
827 .show();
828
829 updateBackgroundPreview();
830 }
831
832 fontColorDescriptions();
833
834 fontColorRadios.on('change', fontColorDescriptions);
835
836 /**
837 * Background change listener
838 */
839 function backgroundDescriptions () {
840 var backgroundRadioOff, backgroundRadioOn, backgroundID;
841
842 backgroundRadioOff = backgroundRadios.filter(':not(:checked)');
843 backgroundRadioOff.closest('li').removeClass('current-selection').find('.options').hide();
844
845 backgroundRadioOn = backgroundRadios.filter(':checked');
846 backgroundID = backgroundRadioOn.filter(':checked').attr('id');
847 backgroundRadioOn.closest('li').addClass('current-selection').find('.options').show();
848
849 $('#view-background-info')
850 .find('.background-description:visible')
851 .hide()
852 .end()
853 .find('.' + backgroundID)
854 .show();
855
856 updateBackgroundPreview();
857 }
858
859 backgroundDescriptions();
860
861 backgroundRadios.on('change', backgroundDescriptions);
862
863 backgroundPresetSelector.on('change', function () {
864 backgroundPreset($(this).val());
865 });
866
867 function backgroundPreset (preset) {
868 if (!preset) {
869 backgroundPreview.css('background', 'transparent');
870 return;
871 }
872
873 var data = {
874 'action': 'wpmtst_get_background_preset_colors',
875 'key': preset,
876 };
877 $.get(ajaxurl, data, function (response) {
878 var presetObj = JSON.parse(response);
879 if (presetObj.color && presetObj.color2) {
880 backgroundPreview.css(constructGradientCSS(presetObj.color, presetObj.color2));
881 }
882 else if (presetObj.color) {
883 backgroundPreview.css('background', presetObj.color);
884 }
885 else {
886 backgroundPreview.css('background', 'transparent');
887 }
888 });
889 }
890
891 function constructGradientCSS (c1, c2) {
892 return {
893 'background': 'linear-gradient(to bottom, ' + c1 + ' 0%, ' + c2 + ' 100%)'
894 };
895 }
896
897 //$.fn.updateScreen(currentMode);
898
899 /**
900 * -------------
901 * Client fields
902 * -------------
903 */
904
905 /**
906 * Make client fields sortable
907 */
908
909 var customFieldList = $('#custom-field-list2');
910
911 // Prevent single click on handle from opening accordion
912 customFieldList.on('click', 'span.handle', function (e) {
913 e.stopImmediatePropagation();
914 e.preventDefault();
915 });
916
917 // customFieldList.find(".field-properties").hide();
918
919 customFieldList.sortable({
920 placeholder: 'sortable-placeholder',
921 // forcePlaceholderSize: true,
922 handle: '.handle',
923 cursor: 'move',
924 helper: 'clone',
925 start: function (e, ui) {
926 ui.placeholder.height(ui.item.height());
927 }
928 });
929 //}).disableSelection(); // <-- this breaks Firefox
930
931 /**
932 * Add client field
933 */
934 $('#add-field').on('click', function (e) {
935 var keys = $('.field3').map(function () {
936 return $(this).data('key');
937 }).get();
938 var nextKey = Array.max(keys) + 1;
939 var data = {
940 'action': 'wpmtst_view_add_field',
941 'key': nextKey,
942 };
943 $.get(ajaxurl, data, function (response) {
944 $.when(customFieldList.append(response)).then(function () {
945 var $newField = customFieldList.find('#field-' + nextKey);
946 $newField
947 .find('div.link').click().end()
948 .find('.field-dep').hide().end()
949 .find('.first-field').focus();
950 });
951 });
952 });
953
954 /**
955 * Field type change listener
956 */
957 customFieldList.on('change', '.field-type select', function () {
958 var $el = $(this);
959 var $elParent = $el.closest('.field3');
960 var fieldType = $el.val();
961 var fieldName = $elParent.find('.field-name').find('select').val();
962 // var key = $elParent.attr("id").split('-').slice(-1)[0];
963 var key = $elParent.data('key');
964 var data;
965
966 switch (fieldType) {
967
968 case 'link2':
969 case 'link':
970 // if changing to [link], add link fields
971 data = {
972 'action': 'wpmtst_view_add_field_link',
973 'fieldName': fieldName,
974 'fieldType': fieldType,
975 'key': key,
976 };
977 $.get(ajaxurl, data, function (response) {
978 // insert into placeholder div
979 $elParent.find('.field-property-box').html(response);
980
981 // Trigger conditional select
982 var $newFieldSelect = $elParent.find('.if.selectgroup');
983 $.fn.selectGroupOption($newFieldSelect);
984 $newFieldSelect.on('change', function () {
985 $.fn.selectGroupOption($newFieldSelect);
986 });
987 textChangeListener();
988
989 // Get field name --> Get field label --> Populate link_text label
990 var fieldName = $elParent.find('.field-name').find('select').val();
991 var data2 = {
992 'action': 'wpmtst_view_get_label',
993 'name': fieldName,
994 };
995 $.get(ajaxurl, data2, function (response) {
996 // var key = $elParent.attr("id").split('-').slice(-1)[0];
997 $('#view-fieldtext' + key + '-label').val(response);
998 });
999
1000 });
1001 break;
1002
1003 case 'date':
1004 // if changing to [date], add date fields
1005 data = {
1006 'action': 'wpmtst_view_add_field_date',
1007 'key': key,
1008 };
1009 $.get(ajaxurl, data, function (response) {
1010 // insert into placeholder div
1011 $elParent.find('.field-property-box').html(response);
1012 });
1013 break;
1014
1015 case 'text':
1016 // if changing to [text], remove meta fields
1017 $elParent.find('.field-property-box').empty();
1018 break;
1019
1020 default:
1021
1022 }
1023 });
1024
1025 /**
1026 * Field name change listener.
1027 */
1028 customFieldList.on('change', '.field-name select', function () {
1029 var $el = $(this);
1030 var $elParent = $el.closest('.field3');
1031 var fieldType = $el.find('option:selected').data('type');
1032 var fieldValue = $el.val();
1033 var key = $elParent.data('key');
1034 var typeSelectParent = $elParent.find('.field-type');
1035 var typeSelect = typeSelectParent.find('select');
1036 var data;
1037
1038 $elParent.not('.open').addClass('open').find('.field-properties').addClass('open').slideDown();
1039
1040 if ('' === fieldValue) {
1041 $elParent.find('.field-description').html('');
1042 // Hide dependent inputs if nothing has been selected
1043 $elParent.find('.field-dep').hide();
1044 }
1045 else {
1046 // Update field label
1047 data = {
1048 'action': 'wpmtst_view_get_label',
1049 'name': fieldValue,
1050 'key': key,
1051 };
1052 $.get(ajaxurl, data, function (response) {
1053 if (response) {
1054 $elParent.find('.field-description').html(response);
1055 }
1056 });
1057
1058 // Show dependent inputs
1059 $elParent.find('.field-dep').show();
1060 }
1061
1062 switch (fieldValue) {
1063 // First, the immutables
1064 case 'post_date':
1065 case 'submit_date':
1066 // Disable type selector
1067 typeSelect.val('date').prop('disabled', true);
1068 typeSelectParent.append('<input type="hidden" class="save-type" name="view[data][client_section][' + key + '][save-type]" value="date">');
1069
1070 // add format field
1071 data = {
1072 'action': 'wpmtst_view_add_field_date',
1073 'key': key,
1074 };
1075 $.get(ajaxurl, data, function (response) {
1076 // Insert into placeholder div. Add hidden field because we are
1077 // disabling the <select> so its value will not be submitted.
1078 $elParent.find('.field-property-box').html(response); // .find("input").focus();
1079 $el.parent().append('<input type="hidden" class="save-type" name="view[data][client_section][' + key + '][type]" value="date">');
1080 });
1081 break;
1082
1083 case 'link2':
1084 case 'link':
1085 // Get field name --> Get field label --> Populate link_text label
1086 var fieldName = $elParent.find('.field-name').find('select').val();
1087 var data2 = {
1088 'action': 'wpmtst_view_get_label',
1089 'name': fieldName,
1090 };
1091 $.get(ajaxurl, data2, function (response) {
1092 var key = $elParent.attr('id').split('-').slice(-1)[0];
1093 $('#view-fieldtext' + key + '-label').val(response);
1094 });
1095 break;
1096
1097 case 'category':
1098 $(typeSelect).val('category').prop('disabled', true);
1099 typeSelectParent.append('<input type="hidden" class="save-type" name="view[data][client_section][' + key + '][save-type]" value="category">');
1100 $elParent.find('.field-property-box').empty();
1101 break;
1102
1103 default:
1104 // Special handling
1105 if ('rating' === fieldType) {
1106 typeSelect.val('rating').prop('disabled', true);
1107 typeSelectParent.append('<input type="hidden" class="save-type" name="view[data][client_section][' + key + '][save-type]" value="rating">');
1108 $elParent.find('.field-property-box').empty();
1109 break;
1110 }
1111
1112 $(typeSelect).val('text').prop('disabled', false);
1113 // remove meta field
1114 $elParent.find('.field-property-box').empty();
1115 // remove the saved type that's only necessary when we disable the input (above)
1116 $el.parent().find('input.save-type').remove();
1117 }
1118 });
1119
1120 /**
1121 * Delete a client field
1122 */
1123 customFieldList.on('click', 'span.delete', function (e) {
1124 var thisField = $(this).closest('.field2');
1125 var yesno = confirm('Remove this field?');
1126 if (yesno) {
1127 thisField.fadeOut(function () {
1128 $(this).remove();
1129 });
1130 }
1131 // Prevent click from expanding accordion
1132 e.stopImmediatePropagation();
1133 e.preventDefault();
1134 });
1135
1136 customFieldList.on('click', 'div.link', function (e) {
1137 $(this)
1138 .closest('.field2')
1139 .toggleClass('open')
1140 .find('.field-properties')
1141 .slideToggle(100);
1142 return false;
1143 });
1144
1145 /**
1146 * Slider|Carousel change listener
1147 */
1148 var $sliderType = $('#view-slider_type');
1149 var $effect = $('#view-effect');
1150 var $position = $('view-slideshow_nav_position');
1151
1152 var sliderTypeUpdate = function () {
1153 if ($sliderType.val() === 'show_multiple') {
1154 $effect.find('option[value=\'horizontal\']').prop('selected', true);
1155 $position.find('option[value=\'outside\']').prop('selected', true);
1156
1157 $sliderType.parent().siblings('.option-desc.singular').hide();
1158 $sliderType.parent().siblings('.option-desc.plural').showInlineBlock();
1159 } else {
1160 $sliderType.parent().siblings('.option-desc.singular').showInlineBlock();
1161 $sliderType.parent().siblings('.option-desc.plural').hide();
1162 }
1163
1164 $effect.change();
1165 $position.change();
1166 };
1167
1168 sliderTypeUpdate();
1169
1170 $sliderType.on('change', sliderTypeUpdate);
1171
1172 /**
1173 * MaxSlides change listener
1174 */
1175 var $maxSlides = $('[id^=\'view-max_slides\']');
1176
1177 // Update display
1178 var maxSlidesUpdateValue = function (el) {
1179 var $el = $(el);
1180 var maxSlidesValue = parseInt($el.val());
1181 if (maxSlidesValue > 1) {
1182 $el.parent().siblings('.option-desc.singular').hide();
1183 $el.parent().siblings('.option-desc.plural').showInlineBlock();
1184 } else {
1185 $el.parent().siblings('.option-desc.singular').showInlineBlock();
1186 $el.parent().siblings('.option-desc.plural').hide();
1187 }
1188 };
1189
1190 // Initial display
1191 $maxSlides.each( function (index, el) {
1192 maxSlidesUpdateValue(el);
1193 });
1194
1195 // Update on change
1196 var maxSlidesUpdate = function (e) {
1197 maxSlidesUpdateValue( $(e.target) );
1198 };
1199
1200 // Event listener
1201 $maxSlides.each( function (index, el) {
1202 $(el).on('change', maxSlidesUpdate);
1203 });
1204
1205 /**
1206 * MoveSlides change listener
1207 */
1208 var $moveSlides = $('[id^=\'view-move_slides\']');
1209
1210 // Update display
1211 var moveSlidesUpdateValue = function (el) {
1212 var $el = $(el);
1213 var moveSlidesValue = parseInt($el.val());
1214 if (moveSlidesValue > 1) {
1215 $el.parent().siblings('.option-desc.singular').hide();
1216 $el.parent().siblings('.option-desc.plural').showInlineBlock();
1217 } else {
1218 $el.parent().siblings('.option-desc.singular').showInlineBlock();
1219 $el.parent().siblings('.option-desc.plural').hide();
1220 }
1221 };
1222
1223 // Initial display
1224 $moveSlides.each( function (index, el) {
1225 moveSlidesUpdateValue(el);
1226 });
1227
1228 // Update on change
1229 var moveSlidesUpdate = function (e) {
1230 moveSlidesUpdateValue( $(e.target) );
1231 };
1232
1233 // Event listener
1234 $moveSlides.each( function (index, el) {
1235 $(el).on('change', moveSlidesUpdate);
1236 });
1237
1238 /**
1239 * Restore default breakpoints
1240 */
1241 $('#restore-default-breakpoints').click(function (e) {
1242 var data = {
1243 'action': 'wpmtst_restore_default_breakpoints'
1244 };
1245
1246 $.get(ajaxurl, data, function (response) {
1247
1248 var object = JSON.parse(response);
1249 var targetId;
1250 var el;
1251
1252 for (var key in object) {
1253
1254 if (object.hasOwnProperty(key)) {
1255
1256 // width
1257 targetId = 'view-breakpoint_' + key;
1258 el = $('[id="' + targetId + '"]');
1259 el.val(parseInt(object[key].width));
1260
1261 // max_slides
1262 targetId = 'view-max_slides_' + key;
1263 el = $('[id="' + targetId + '"]');
1264 el.val(parseInt(object[key].max_slides));
1265
1266 // margin
1267 targetId = 'view-margin_' + key;
1268 el = $('[id="' + targetId + '"]');
1269 el.val(parseInt(object[key].margin));
1270
1271 // move_slides
1272 targetId = 'view-move_slides_' + key;
1273 el = $('[id="' + targetId + '"]');
1274 el.val(parseInt(object[key].move_slides));
1275
1276 }
1277
1278 }
1279
1280 document.getElementById('restored-message').classList.add('copied');
1281 setTimeout(function () {
1282 document.getElementById('restored-message').classList.remove('copied');
1283 }, 2000);
1284
1285 });
1286 });
1287
1288 })(jQuery);
1289
1290 /**
1291 * Click to copy to keyboard
1292 * Thanks https://www.sitepoint.com/javascript-copy-to-clipboard/
1293 */
1294 (function () {
1295
1296 'use strict';
1297
1298 // click events
1299 document.body.addEventListener('click', copy, true);
1300
1301 // event handler
1302 function copy (e) {
1303
1304 // find target element
1305 var
1306 t = e.target,
1307 c = t.dataset.copytarget,
1308 inp = (c ? document.querySelector(c) : null);
1309
1310 // is element selectable?
1311 if (inp && inp.select) {
1312
1313 // select text
1314 inp.select();
1315
1316 try {
1317 // copy text
1318 document.execCommand('copy');
1319 inp.blur();
1320
1321 //t.classList.add('copied');
1322 //setTimeout(function() { t.classList.remove('copied'); }, 1500);
1323 document.getElementById('copy-message').classList.add('copied');
1324 setTimeout(function () {
1325 document.getElementById('copy-message').classList.remove('copied');
1326 }, 2000);
1327 }
1328 catch (err) {
1329 alert('Sorry, please press Ctrl/Cmd+C to copy instead.');
1330 }
1331
1332 }
1333
1334 }
1335
1336 })();
1337