PluginProbe ʕ •ᴥ•ʔ
Strong Testimonials / 2.33
Strong Testimonials v2.33
3.3.3 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 8 years ago addon-licenses.js 9 years ago admin-compat.js 8 years ago admin-fields.js 7 years ago admin-form.js 8 years ago admin-global.js 8 years ago admin-order.js 9 years ago admin.js 8 years ago custom-spinner.js 8 years ago help.js 8 years ago rating-edit.js 9 years ago view-category-filter.js 9 years ago views.js 7 years ago
admin-fields.js
603 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 });
409
410
411 // admin-table field
412 var data2 = {
413 'action': 'wpmtst_add_field_4',
414 'nextKey': key,
415 'fieldClass': fieldClass,
416 'fieldType': fieldType,
417 'security': wpmtstAdmin.ajax_nonce
418 };
419
420 var ajax2 = ajax1.then(function () {
421 return $.get(ajaxurl, data2, function (response) {
422 $table.append(response);
423 });
424 });
425
426
427 // hidden inputs
428 var data3 = {
429 'action': 'wpmtst_add_field_3',
430 'nextKey': key,
431 'fieldClass': fieldClass,
432 'fieldType': fieldType,
433 'security': wpmtstAdmin.ajax_nonce
434 };
435
436 var ajax3 = ajax2.then(function () {
437 return $.get(ajaxurl, data3, function (response) {
438 $table.parent().append(response);
439 });
440 });
441
442 ajax3.done(function () {
443
444 formPreview();
445 $("#add-field, #submit").removeAttr("disabled");
446
447 // Successfully added so show "Close" link
448 $("span.close-field").show();
449
450 $parent
451 // Reset temporary status
452 .removeData("status").removeAttr("data-status")
453 // update parent list item
454 .find(".custom-field-header a.field").html($fieldLabel.val()).end()
455 // update hidden [record_type] input
456 .find('input[name$="[record_type]"]').val(fieldClass);
457
458 });
459
460 });
461
462 /**
463 * ------------------------------------------------------------
464 * Functions
465 * ------------------------------------------------------------
466 */
467
468 function getCatCount() {
469 $.get(ajaxurl, {
470 'action': 'wpmtst_get_cat_count',
471 'security': wpmtstAdmin.ajax_nonce
472 },
473 function (response) {
474 catCount = parseInt(response);
475 });
476 }
477
478 // Preview
479 function formPreview() {
480 var formFields = $theForm.find("[name^='fields']");
481 if (!formFields.length) return;
482
483 var data = {
484 'action': 'wpmtst_get_form_preview',
485 'fields': formFields.serialize()
486 };
487 $.post(ajaxurl, data, function (response) {
488 var newDiv = $("<div></div>").hide().html(response)
489 $("#fields-editor-preview")
490 .children().first()
491 .after(newDiv)
492 .fadeOut(300, function () {
493 newDiv.show();
494 $(this).remove();
495 });
496 });
497 }
498
499 /*
500 * Disable any Post fields already in use.
501 *
502 * Doing this client-side so a Post field can be added
503 * but not saved before adding more fields;
504 * i.e. add multiple fields of either type without risk
505 * of duplicating single Post fields before clicking "Save".
506 */
507 function togglePostFields() {
508 $fieldList.find('input[name$="[record_type]"]').each(function () {
509 var $parent = $(this).closest("li");
510 var value = $(this).val();
511 if ("post" === value) {
512 var name = $parent.find(".field-name").val();
513 $fieldList.find("select.field-type.new").find('option[value="' + name + '"]').attr("disabled", "disabled");
514 }
515 });
516 }
517
518 // Only allow one category field
519 function toggleCategoryFields() {
520 var categoryInUse = false;
521
522 $fieldList.find('input[name$="[record_type]"]').each(function () {
523 var $parent = $(this).closest("li");
524 var value = $(this).val();
525 if ('optional' === value) {
526 var fieldType = $parent.find('input[name$="[input_type]"]').val();
527 if (!categoryInUse) {
528 categoryInUse = ( 'category' === fieldType.split('-')[0] );
529 }
530 }
531 });
532
533 var $options = $fieldList.find('option[value^="category"]');
534 if (categoryInUse) {
535 $options.each(function () {
536 var text = $(this).text();
537 $(this)
538 .attr("disabled", "disabled")
539 .text(text + ' ' + wpmtstAdmin.inUse)
540 .data('origText', text);
541 });
542 }
543 else if (0 === catCount) {
544 $options.each(function () {
545 var text = $(this).text();
546 $(this)
547 .attr("disabled", "disabled")
548 .text(text + ' ' + wpmtstAdmin.noneFound)
549 .data('origText', text);
550 });
551 } else {
552 $options.each(function () {
553 $(this)
554 .removeAttr("disabled")
555 .text($(this).data('origText'));
556 });
557 }
558 }
559
560 // Actions on opening/closing the field
561 function toggleField($field) {
562 $field.replaceSelect()
563 .toggleClass("open")
564 .scrollUp()
565 .find("span.link")
566 .toggleClass("open")
567 .end()
568 .find(".custom-field")
569 .toggleClass("open")
570 .slideToggle()
571 .find(".first-field")
572 .focus();
573 }
574
575 // Build a unique name
576 function getUniqueName(fieldName, fieldIndex) {
577 fieldName = sanitizeName(fieldName);
578
579 // Get names of *other* fields
580 var names = $theForm.find("input.field-name").not(":eq(" + fieldIndex + ")").map(function () {
581 return this.value;
582 }).get();
583
584 names = names.filter(function (x) {
585 return (x !== (undefined || ''));
586 });
587
588 var uniqueName = fieldName;
589 var i = 2;
590
591 while ($.inArray(uniqueName, names) >= 1) {
592 uniqueName = fieldName + '_' + i++;
593 }
594 return uniqueName;
595 }
596
597 // Dismiss the "Fields saved" notice.
598 function dismissNotice() {
599 $('.wpmtst.notice').find(".notice-dismiss").click();
600 }
601
602 })(jQuery);
603