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 / admin-fields.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
admin-fields.js
604 lines
1 /**
2 * Strong Testimonials Custom Fields Editor
3 *
4 * @namespace wpmtstAdmin
5 * @namespace wpmtstAdmin.newField
6 */
7
8 // Function to get the Max value in Array
9 Array.max = function (array) {
10 return Math.max.apply(Math, array);
11 };
12
13 // Convert "A String" to "a_string"
14 function sanitizeName(label) {
15 return label.trim().replace(/\W/g, " ").replace(/\s+/g, "_").toLowerCase();
16 }
17
18 (function ($) {
19
20 /**
21 * If open, scroll field into view.
22 * If closed, scroll all the way up.
23 *
24 * @returns {jQuery}
25 */
26 $.fn.scrollUp = function () {
27 var containerOffset;
28 this.each(function () {
29 containerOffset = 0;
30 if ($(this).hasClass("open")) {
31 containerOffset = parseInt($(this).offset().top) - 72;
32 }
33 $("html, body").animate({scrollTop: containerOffset}, 800);
34 });
35
36 return this;
37 };
38
39 /**
40 * Replace the field type selector with its value. Better than readonly.
41 *
42 * @returns {jQuery}
43 */
44 $.fn.replaceSelect = function () {
45 this.each(function () {
46 if ($(this).hasClass("open")) {
47 $(this).find("select.field-type").each(function (index, el) {
48 $(el).replaceWith(el.value);
49 });
50 }
51 });
52
53 return this;
54 }
55
56 /**
57 * Initialize
58 */
59 var catCount = 0;
60 getCatCount();
61
62 var $theForm = $("#wpmtst-custom-fields-form");
63 var $fieldList = $("#custom-field-list");
64
65 formPreview();
66 toggleCategoryFields();
67
68 /**
69 * Sortable
70 */
71 $fieldList.sortable({
72 placeholder: "sortable-placeholder",
73 forcePlaceholderSize: true,
74 handle: ".handle",
75 cursor: "move",
76 update: function (event, ui) {
77 dismissNotice();
78 formPreview();
79 }
80 });
81
82 /**
83 * ------------------------------------------------------------
84 * Events
85 * ------------------------------------------------------------
86 */
87
88 /**
89 * Any changes.
90 */
91 $theForm.on("change", "input", function () {
92 dismissNotice();
93 formPreview();
94 });
95
96 /**
97 * Disable buttons on submit.
98 * Thanks https://stackoverflow.com/a/25651260/51600
99 */
100 $theForm.submit(function(){
101 $('#field-group-actions').find('.button').each(function (index) {
102 // Create a disabled clone of the submit button
103 $(this).clone(false).removeAttr('id').prop('disabled', true).insertBefore($(this));
104 // Hide the actual submit button and move it to the beginning of the form
105 $(this).hide();
106 });
107 });
108
109 /**
110 * Save Changes
111 */
112 $('#submit-form').on('click',function(e){
113
114 // Validate field type
115 $("select.field-type").each(function (index) {
116 if ('none' === this.value) {
117 $(this).closest('tr').addClass('form-error');
118 $(this).parent().find('.form-error-text').show();
119 var $parent = $(this).closest("li");
120 if (!$parent.hasClass("open")) {
121 $parent.find("a.field").click();
122 }
123 $(this).focus();
124 e.preventDefault();
125 } else {
126 $(this).closest('tr').removeClass('form-error');
127 $(this).parent().find('.form-error-text').hide();
128 }
129 });
130
131 // Validate field name
132 $("input.field-name").each(function (index) {
133 if ('name' === $(this).val() || 'date' === $(this).val()) {
134 $(this).closest('tr').addClass('form-error');
135 $(this).parent().find('.field-name-help.important').addClass('form-error-text');
136 var $parent = $(this).closest("li");
137 if (!$parent.hasClass("open")) {
138 $parent.find("a.field").click();
139 }
140 $(this).focus();
141 e.preventDefault();
142 } else {
143 $(this).closest('tr').removeClass('form-error');
144 $(this).parent().find('.field-name-help.important').removeClass('form-error-text');
145 }
146 });
147
148 });
149
150 /**
151 * Cancel Changes
152 */
153 $('#reset').on('click',function(e){
154 $theForm.submit();
155 });
156
157 /**
158 * Restore Defaults
159 */
160 $('#restore-defaults').on('click',function(e){
161 if (confirm("Restore the default fields?")) {
162 $theForm.submit();
163 } else {
164 $(this).blur();
165 return false;
166 }
167 });
168
169 /**
170 * Prevent single click on handle from opening accordion
171 */
172 $fieldList.on("click", "span.handle", function (e) {
173 e.stopImmediatePropagation();
174 e.preventDefault();
175 });
176
177 /**
178 * Open/close
179 */
180 $fieldList.on("click", "span.link", function () {
181 toggleField($(this).closest("li"));
182 return false;
183 });
184
185 /**
186 * Validate field label
187 */
188 $fieldList.on("change blur", "input.field-label", function () {
189 var newLabel = $(this).val().trim();
190 // fill in blank label
191 if ('' === newLabel) {
192 newLabel = wpmtstAdmin.newField;
193 }
194 $(this).val(newLabel);
195
196 var $parent = $(this).closest("li");
197 var fieldIndex = $parent.index();
198
199 // update parent list item
200 $parent.find("a.field").html(newLabel);
201
202 // fill in blank field name
203 var $fieldName = $parent.find("input.field-name");
204 if ('new_field' === $fieldName.val()) {
205 $fieldName.val(getUniqueName(newLabel, fieldIndex)).change();
206 }
207 });
208
209 /**
210 * Validate field name
211 */
212 $fieldList.on("change", "input.field-name", function () {
213 var fieldName = $(this).val();
214 var $parent = $(this).closest("li");
215 var fieldIndex = $parent.index();
216
217 if (fieldName) {
218 $(this).val(getUniqueName(fieldName, fieldIndex));
219 } else {
220 var fieldLabel = $(this).closest(".field-table").find(".field-label").val();
221 $(this).val(getUniqueName(fieldLabel, fieldIndex));
222 }
223
224 // Check new name, not initial value
225 if ('name' === $(this).val() || 'date' === $(this).val()) {
226 $(this).closest('tr').addClass('form-error');
227 $(this).parent().find('.field-name-help.important').addClass('form-error-text');
228 $(this).focus()
229 return false;
230 } else {
231 $(this).closest('tr').removeClass('form-error');
232 $(this).parent().find('.field-name-help.important').removeClass('form-error-text');
233 }
234 });
235
236 /**
237 * Delete field
238 */
239 $fieldList.on("click", ".delete-field", function () {
240 $(this).blur();
241 dismissNotice();
242 var thisField = $(this).closest("li");
243 var thisLabel = thisField.find(".field").text();
244 if (confirm('Delete "' + thisLabel + '"?')) {
245 thisField.fadeOut(function () {
246 $.when(thisField.remove()).then(function () {
247 formPreview();
248 toggleCategoryFields();
249 $("#add-field, #submit").removeAttr("disabled");
250 })
251 });
252 }
253 });
254
255 /**
256 * Close field
257 */
258 $fieldList.on("click", "span.close-field a", function () {
259 toggleField($(this).closest("li"));
260 return false;
261 });
262
263 /**
264 * Add new field
265 */
266 $("#add-field").click(function () {
267 dismissNotice();
268 var keys = $fieldList.find("li").map(function () {
269 var key_id = $(this).attr("id");
270 return key_id.substr(key_id.lastIndexOf("-") + 1);
271 }).get();
272 var nextKey = Array.max(keys) + 1;
273
274 var data = {
275 'action': 'wpmtst_add_field',
276 'nextKey': nextKey,
277 'fieldClass': null,
278 'fieldType': null,
279 'security': wpmtstAdmin.ajax_nonce
280 };
281 $.get(ajaxurl, data, function (response) {
282 $("#add-field, #submit").attr("disabled", "disabled");
283
284 // create list item
285 var $li = $('<li id="field-' + nextKey + '" data-status="new">').append(response);
286
287 // hide elements until Type is selected
288 $li.find('.field-label-row').hide();
289 $li.find('.field-name-row').hide();
290 $li.find("span.close-field").hide();
291
292 // append to list
293 $.when($fieldList.append($li)).then(function () {
294 formPreview();
295 togglePostFields();
296 toggleCategoryFields();
297
298 // click it to open
299 $li.find("span.link").click();
300 });
301 });
302 });
303
304 /**
305 * Field type change
306 */
307 $fieldList.on("change", ".field-type", function (e) {
308 var fieldType = $(this).val();
309 var $table = $(this).closest("table");
310 var $parent = $(this).closest('li');
311
312 if ($parent.data('status') !== 'new') {
313 $table.find(".field-secondary, .field-admin-table").remove();
314 }
315
316 if ('none' === fieldType) {
317 $parent.find('.field-label-row').hide();
318 $parent.find('.field-name-row').hide();
319
320 // Hide "Close" link
321 $parent.find("span.close-field").hide();
322 $("#add-field, #submit").attr("disabled", "disabled");
323 return;
324 }
325 $parent.find('tr').removeClass('form-error');
326 $parent.find('.form-error-text').hide();
327
328 var key_id = $parent.attr("id");
329 var key = key_id.substr(key_id.lastIndexOf("-") + 1);
330
331 var $fieldLabel = $parent.find('input.field-label');
332 var $fieldName = $parent.find('input.field-name');
333 var fieldIndex = $parent.index();
334
335 // get type of field from its optgroup
336 var fieldOption = $(this).find("option[value='" + fieldType + "']");
337 var fieldClass = fieldOption.closest("optgroup").attr("class");
338
339 switch (fieldClass) {
340
341 case 'post':
342 $parent.find('.field-label-row').show();
343 $parent.find('.field-name-row').show();
344
345 // Force values if selecting a Post field.
346 if (fieldType === 'post_title') {
347 $fieldLabel.val('Testimonial Title');
348 $fieldName.val('post_title').attr('disabled', 'disabled');
349 }
350 else if (fieldType === 'featured_image') {
351 $fieldLabel.val('Photo');
352 $fieldName.val('featured_image').attr('disabled', 'disabled');
353 }
354 else if (fieldType === 'post_content') {
355 $fieldLabel.val('Testimonial');
356 $fieldName.val('post_content').attr('disabled', 'disabled');
357 }
358 // move value to hidden input
359 $fieldName.after('<input type="hidden" name="' + $fieldName.attr("name") + '" value="' + $fieldName.val() + '" />');
360 // hide help message
361 $parent.find(".field-name-help").hide();
362 break;
363
364 case 'optional':
365 $parent.find('.field-label-row').show();
366 $parent.find('.field-name-row').show();
367
368 if ('category' === fieldType.split('-')[0]) {
369 $fieldName.val('category').attr('disabled', 'disabled');
370 // move value to hidden input
371 $fieldName.after('<input type="hidden" name="' + $fieldName.attr("name") + '" value="' + $fieldName.val() + '" />');
372 // hide help message
373 $parent.find(".field-name-help").hide();
374 }
375 var forceName = fieldOption.data('force-name');
376 if (forceName) {
377 $fieldName.val(forceName).attr('disabled', 'disabled');
378 // move value to hidden input
379 $fieldName.after('<input type="hidden" name="' + $fieldName.attr("name") + '" value="' + $fieldName.val() + '" />');
380 // hide help message
381 $parent.find(".field-name-help").hide();
382 }
383 $fieldLabel.val(wpmtstAdmin.newField).focus().select();
384 break;
385
386 default:
387 $parent.find('.field-label-row').show();
388 $parent.find('.field-name-row').show();
389
390 // TODO DRY
391 $fieldLabel.val(wpmtstAdmin.newField).focus().select();
392 $fieldName.val(getUniqueName($fieldLabel.val(), fieldIndex));
393 $fieldName.removeAttr('disabled');
394 $parent.find(".field-name-help").show();
395 }
396
397 // secondary form fields
398 var data1 = {
399 'action': 'wpmtst_add_field_2',
400 'nextKey': key,
401 'fieldClass': fieldClass,
402 'fieldType': fieldType,
403 'security': wpmtstAdmin.ajax_nonce
404 };
405
406 var ajax1 = $.get(ajaxurl, data1, function (response) {
407 $table.append(response);
408 $( document ).trigger( "st-done-loading-secondary-fields", [ $table ] );
409 });
410
411
412 // admin-table field
413 var data2 = {
414 'action': 'wpmtst_add_field_4',
415 'nextKey': key,
416 'fieldClass': fieldClass,
417 'fieldType': fieldType,
418 'security': wpmtstAdmin.ajax_nonce
419 };
420
421 var ajax2 = ajax1.then(function () {
422 return $.get(ajaxurl, data2, function (response) {
423 $table.append(response);
424 });
425 });
426
427
428 // hidden inputs
429 var data3 = {
430 'action': 'wpmtst_add_field_3',
431 'nextKey': key,
432 'fieldClass': fieldClass,
433 'fieldType': fieldType,
434 'security': wpmtstAdmin.ajax_nonce
435 };
436
437 var ajax3 = ajax2.then(function () {
438 return $.get(ajaxurl, data3, function (response) {
439 $table.parent().append(response);
440 });
441 });
442
443 ajax3.done(function () {
444
445 formPreview();
446 $("#add-field, #submit").removeAttr("disabled");
447
448 // Successfully added so show "Close" link
449 $("span.close-field").show();
450
451 $parent
452 // Reset temporary status
453 .removeData("status").removeAttr("data-status")
454 // update parent list item
455 .find(".custom-field-header a.field").html($fieldLabel.val()).end()
456 // update hidden [record_type] input
457 .find('input[name$="[record_type]"]').val(fieldClass);
458
459 });
460
461 });
462
463 /**
464 * ------------------------------------------------------------
465 * Functions
466 * ------------------------------------------------------------
467 */
468
469 function getCatCount() {
470 $.get(ajaxurl, {
471 'action': 'wpmtst_get_cat_count',
472 'security': wpmtstAdmin.ajax_nonce
473 },
474 function (response) {
475 catCount = parseInt(response);
476 });
477 }
478
479 // Preview
480 function formPreview() {
481 var formFields = $theForm.find("[name^='fields']");
482 if (!formFields.length) return;
483
484 var data = {
485 'action': 'wpmtst_get_form_preview',
486 'fields': formFields.serialize()
487 };
488 $.post(ajaxurl, data, function (response) {
489 var newDiv = $("<div></div>").hide().html(response)
490 $("#fields-editor-preview")
491 .children().first()
492 .after(newDiv)
493 .fadeOut(300, function () {
494 newDiv.show();
495 $(this).remove();
496 });
497 });
498 }
499
500 /*
501 * Disable any Post fields already in use.
502 *
503 * Doing this client-side so a Post field can be added
504 * but not saved before adding more fields;
505 * i.e. add multiple fields of either type without risk
506 * of duplicating single Post fields before clicking "Save".
507 */
508 function togglePostFields() {
509 $fieldList.find('input[name$="[record_type]"]').each(function () {
510 var $parent = $(this).closest("li");
511 var value = $(this).val();
512 if ("post" === value) {
513 var name = $parent.find(".field-name").val();
514 $fieldList.find("select.field-type.new").find('option[value="' + name + '"]').attr("disabled", "disabled");
515 }
516 });
517 }
518
519 // Only allow one category field
520 function toggleCategoryFields() {
521 var categoryInUse = false;
522
523 $fieldList.find('input[name$="[record_type]"]').each(function () {
524 var $parent = $(this).closest("li");
525 var value = $(this).val();
526 if ('optional' === value) {
527 var fieldType = $parent.find('input[name$="[input_type]"]').val();
528 if (!categoryInUse) {
529 categoryInUse = ( 'category' === fieldType.split('-')[0] );
530 }
531 }
532 });
533
534 var $options = $fieldList.find('option[value^="category"]');
535 if (categoryInUse) {
536 $options.each(function () {
537 var text = $(this).text();
538 $(this)
539 .attr("disabled", "disabled")
540 .text(text + ' ' + wpmtstAdmin.inUse)
541 .data('origText', text);
542 });
543 }
544 else if (0 === catCount) {
545 $options.each(function () {
546 var text = $(this).text();
547 $(this)
548 .attr("disabled", "disabled")
549 .text(text + ' ' + wpmtstAdmin.noneFound)
550 .data('origText', text);
551 });
552 } else {
553 $options.each(function () {
554 $(this)
555 .removeAttr("disabled")
556 .text($(this).data('origText'));
557 });
558 }
559 }
560
561 // Actions on opening/closing the field
562 function toggleField($field) {
563 $field.replaceSelect()
564 .toggleClass("open")
565 .scrollUp()
566 .find("span.link")
567 .toggleClass("open")
568 .end()
569 .find(".custom-field")
570 .toggleClass("open")
571 .slideToggle()
572 .find(".first-field")
573 .focus();
574 }
575
576 // Build a unique name
577 function getUniqueName(fieldName, fieldIndex) {
578 fieldName = sanitizeName(fieldName);
579
580 // Get names of *other* fields
581 var names = $theForm.find("input.field-name").not(":eq(" + fieldIndex + ")").map(function () {
582 return this.value;
583 }).get();
584
585 names = names.filter(function (x) {
586 return (x !== (undefined || ''));
587 });
588
589 var uniqueName = fieldName;
590 var i = 2;
591
592 while ($.inArray(uniqueName, names) >= 1) {
593 uniqueName = fieldName + '_' + i++;
594 }
595 return uniqueName;
596 }
597
598 // Dismiss the "Fields saved" notice.
599 function dismissNotice() {
600 $('.wpmtst.notice').find(".notice-dismiss").click();
601 }
602
603 })(jQuery);
604