PluginProbe
weForms – Easy Drag & Drop Contact Form Builder For WordPress / 1.5.4
weForms – Easy Drag & Drop Contact Form Builder For WordPress v1.5.4
1.6.7 1.6.8 1.6.9 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.18 1.6.19 1.6.2 1.6.20 1.6.21 1.6.22 1.6.23 1.6.24 1.6.25 1.6.26 1.6.27 1.6.28 1.6.3 1.6.4 1.6.5 1.6.6 All 74 releases
weforms / assets / wpuf / js / wpuf-form-builder-components.js

wpuf-form-builder-components.js in weForms – Easy Drag & Drop Contact Form Builder For WordPress 1.5.4, at assets/wpuf/js/wpuf-form-builder-components.js

1,633 lines 55.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 'use strict';
2
3 ;(function ($) {
4 'use strict';
5
6 Vue.component('builder-stage', {
7 template: '#tmpl-wpuf-builder-stage',
8
9 mixins: wpuf_form_builder_mixins(wpuf_mixins.builder_stage),
10
11 computed: {
12 form_fields: function form_fields() {
13 return this.$store.state.form_fields;
14 },
15
16 field_settings: function field_settings() {
17 return this.$store.state.field_settings;
18 },
19
20 hidden_fields: function hidden_fields() {
21 return this.$store.state.form_fields.filter(function (item) {
22 return 'custom_hidden_field' === item.template;
23 });
24 },
25
26 editing_form_id: function editing_form_id() {
27 return this.$store.state.editing_field_id;
28 },
29
30 pro_link: function pro_link() {
31 return wpuf_form_builder.pro_link;
32 }
33 },
34
35 mounted: function mounted() {
36 var self = this,
37 in_column_field = false;
38
39 // bind jquery ui sortable
40 $('#form-preview-stage .wpuf-form.sortable-list').sortable({
41 placeholder: 'form-preview-stage-dropzone',
42 items: '.field-items',
43 handle: '.control-buttons .move',
44 scroll: true,
45 over: function over() {
46 in_column_field = false;
47
48 // if the field drop in column field, then stop field rendering in the builder stage
49 $(".wpuf-column-inner-fields").on("drop", function (event) {
50 var targetColumn = event.currentTarget.classList,
51 isColumnExist = $.inArray(".wpuf-column-inner-fields", targetColumn);
52
53 if (isColumnExist) {
54 in_column_field = true;
55 }
56 });
57 },
58 update: function update(e, ui) {
59 var item = ui.item[0],
60 data = item.dataset,
61 source = data.source,
62 toIndex = parseInt($(ui.item).index()),
63 payload = {
64 toIndex: toIndex
65 };
66
67 if ('panel' === source) {
68 // prepare the payload to add new form element
69 var field_template = ui.item[0].dataset.formField,
70 field = $.extend(true, {}, self.field_settings[field_template].field_props);
71
72 // check if these are already inserted
73 if (self.isSingleInstance(field_template) && self.containsField(field_template)) {
74 swal({
75 title: "Oops...",
76 text: "You already have this field in the form"
77 });
78
79 $(this).find('.button.ui-draggable.ui-draggable-handle').remove();
80 return;
81 }
82
83 // add a random integer id
84 field.id = self.get_random_id();
85
86 // add meta key
87 if ('yes' === field.is_meta && !field.name) {
88 field.name = field.label.replace(/\W/g, '_').toLowerCase() + '_' + field.id;
89 }
90
91 payload.field = field;
92
93 // add new form element
94 if (!in_column_field) {
95 self.$store.commit('add_form_field_element', payload);
96 }
97
98 // remove button from stage
99 $(this).find('.button.ui-draggable.ui-draggable-handle').remove();
100 } else if ('stage' === source) {
101 payload.fromIndex = parseInt(data.index);
102
103 self.$store.commit('swap_form_field_elements', payload);
104 }
105 }
106 });
107 },
108
109 methods: {
110
111 open_field_settings: function open_field_settings(field_id) {
112 this.$store.commit('open_field_settings', field_id);
113 },
114
115 clone_field: function clone_field(field_id, index) {
116 var payload = {
117 field_id: field_id,
118 index: index,
119 new_id: this.get_random_id()
120 };
121
122 // single instance checking
123 var field = _.find(this.$store.state.form_fields, function (item) {
124 return parseInt(item.id) === parseInt(payload.field_id);
125 });
126
127 // check if these are already inserted
128 if (this.isSingleInstance(field.template) && this.containsField(field.template)) {
129 swal({
130 title: "Oops...",
131 text: "You already have this field in the form"
132 });
133 return;
134 }
135
136 this.$store.commit('clone_form_field_element', payload);
137 },
138
139 delete_field: function delete_field(index) {
140 var self = this;
141
142 swal({
143 text: self.i18n.delete_field_warn_msg,
144 type: 'warning',
145 showCancelButton: true,
146 confirmButtonColor: '#d54e21',
147 confirmButtonText: self.i18n.yes_delete_it,
148 cancelButtonText: self.i18n.no_cancel_it,
149 confirmButtonClass: 'btn btn-success',
150 cancelButtonClass: 'btn btn-danger'
151 }).then(function () {
152 self.$store.commit('delete_form_field_element', index);
153 }, function () {});
154 },
155
156 delete_hidden_field: function delete_hidden_field(field_id) {
157 var i = 0;
158
159 for (i = 0; i < this.form_fields.length; i++) {
160 if (parseInt(field_id) === parseInt(this.form_fields[i].id)) {
161 this.delete_field(i);
162 }
163 }
164 },
165
166 is_pro_feature: function is_pro_feature(template) {
167 return this.field_settings[template] && this.field_settings[template].pro_feature ? true : false;
168 },
169
170 is_template_available: function is_template_available(field) {
171 var template = field.template;
172
173 if (this.field_settings[template]) {
174 if (this.is_pro_feature(template)) {
175 return false;
176 }
177
178 return true;
179 }
180
181 // for example see 'mixin_builder_stage' mixin's 'is_taxonomy_template_available' method
182 if (_.isFunction(this['is_' + template + '_template_available'])) {
183 return this['is_' + template + '_template_available'].call(this, field);
184 }
185
186 return false;
187 },
188
189 is_full_width: function is_full_width(template) {
190 if (this.field_settings[template] && this.field_settings[template].is_full_width) {
191 return true;
192 }
193
194 return false;
195 },
196
197 is_invisible: function is_invisible(field) {
198 return field.recaptcha_type && 'invisible_recaptcha' === field.recaptcha_type ? true : false;
199 },
200
201 get_field_name: function get_field_name(template) {
202 return this.field_settings[template].title;
203 }
204 }
205 });
206
207 Vue.component('field-checkbox', {
208 template: '#tmpl-wpuf-field-checkbox',
209
210 mixins: [wpuf_mixins.option_field_mixin],
211
212 computed: {
213 value: {
214 get: function get() {
215 var value = this.editing_form_field[this.option_field.name];
216
217 if (this.option_field.is_single_opt) {
218 var option = Object.keys(this.option_field.options)[0];
219
220 if (value === option) {
221 return true;
222 } else {
223 return false;
224 }
225 }
226
227 return this.editing_form_field[this.option_field.name];
228 },
229
230 set: function set(value) {
231 if (this.option_field.is_single_opt) {
232 value = value ? Object.keys(this.option_field.options)[0] : '';
233 }
234
235 this.$store.commit('update_editing_form_field', {
236 editing_field_id: this.editing_form_field.id,
237 field_name: this.option_field.name,
238 value: value
239 });
240 }
241 }
242 }
243 });
244
245 Vue.component('field-html_help_text', {
246 template: '#tmpl-wpuf-field-html_help_text',
247
248 mixins: [wpuf_mixins.option_field_mixin]
249 });
250
251 Vue.component('field-multiselect', {
252 template: '#tmpl-wpuf-field-multiselect',
253
254 mixins: [wpuf_mixins.option_field_mixin],
255
256 computed: {
257 value: {
258 get: function get() {
259 return this.editing_form_field[this.option_field.name];
260 },
261
262 set: function set(value) {
263 this.$store.commit('update_editing_form_field', {
264 editing_field_id: this.editing_form_field.id,
265 field_name: this.option_field.name,
266 value: value
267 });
268 }
269 }
270 },
271
272 mounted: function mounted() {
273 this.bind_selectize();
274 },
275
276 methods: {
277 bind_selectize: function bind_selectize() {
278 var self = this;
279
280 $(this.$el).find('.term-list-selector').selectize({}).on('change', function () {
281 var data = $(this).val();
282
283 self.value = data;
284 });
285 }
286 }
287
288 });
289
290 /**
291 * Common settings component for option based fields
292 * like select, multiselect, checkbox, radio
293 */
294 Vue.component('field-option-data', {
295 template: '#tmpl-wpuf-field-option-data',
296
297 mixins: [wpuf_mixins.option_field_mixin],
298
299 data: function data() {
300 return {
301 show_value: false,
302 options: [],
303 selected: []
304 };
305 },
306
307 computed: {
308 field_options: function field_options() {
309 return this.editing_form_field.options;
310 },
311
312 field_selected: function field_selected() {
313 return this.editing_form_field.selected;
314 }
315 },
316
317 mounted: function mounted() {
318 var self = this;
319
320 this.set_options();
321
322 $(this.$el).find('.option-field-option-chooser').sortable({
323 items: '.option-field-option',
324 handle: '.sort-handler',
325 update: function update(e, ui) {
326 var item = ui.item[0],
327 data = item.dataset,
328 toIndex = parseInt($(ui.item).index()),
329 fromIndex = parseInt(data.index);
330
331 self.options.swap(fromIndex, toIndex);
332 }
333 });
334 },
335
336 methods: {
337 set_options: function set_options() {
338 var self = this;
339 var field_options = $.extend(true, {}, this.editing_form_field.options);
340
341 _.each(field_options, function (label, value) {
342 self.options.push({ label: label, value: value, id: self.get_random_id() });
343 });
344
345 if (this.option_field.is_multiple && !_.isArray(this.field_selected)) {
346 this.selected = [this.field_selected];
347 } else {
348 this.selected = this.field_selected;
349 }
350 },
351
352 // in case of select or radio buttons, user should deselect default value
353 clear_selection: function clear_selection() {
354 this.selected = null;
355 },
356
357 add_option: function add_option() {
358 var count = this.options.length,
359 new_opt = this.i18n.option + '-' + (count + 1);
360
361 this.options.push({
362 label: new_opt, value: new_opt, id: this.get_random_id()
363 });
364 },
365
366 delete_option: function delete_option(index) {
367 if (this.options.length === 1) {
368 this.warn({
369 text: this.i18n.last_choice_warn_msg,
370 showCancelButton: false,
371 confirmButtonColor: "#46b450"
372 });
373
374 return;
375 }
376
377 this.options.splice(index, 1);
378 },
379
380 set_option_label: function set_option_label(index, label) {
381 this.options[index].value = label.toLocaleLowerCase().replace(/\s/g, '_');
382 }
383 },
384
385 watch: {
386 options: {
387 deep: true,
388 handler: function handler(new_opts) {
389 var options = {},
390 i = 0;
391
392 for (i = 0; i < new_opts.length; i++) {
393 options[new_opts[i].value] = new_opts[i].label;
394 }
395
396 this.update_value('options', options);
397 }
398 },
399
400 selected: function selected(new_val) {
401 this.update_value('selected', new_val);
402 }
403 }
404 });
405
406 Vue.component('field-option-pro-feature-alert', {
407 template: '#tmpl-wpuf-field-option-pro-feature-alert',
408
409 mixins: [wpuf_mixins.option_field_mixin],
410
411 computed: {
412 pro_link: function pro_link() {
413 return wpuf_form_builder.pro_link;
414 }
415 }
416 });
417
418 /**
419 * Sidebar field options panel
420 */
421 Vue.component('field-options', {
422 template: '#tmpl-wpuf-field-options',
423
424 mixins: wpuf_form_builder_mixins(wpuf_mixins.field_options),
425
426 data: function data() {
427 return {
428 show_basic_settings: true,
429 show_advanced_settings: false,
430 show_quiz_settings: false
431 };
432 },
433
434 computed: {
435 editing_field_id: function editing_field_id() {
436 this.show_basic_settings = true;
437 this.show_advanced_settings = false;
438 this.show_quiz_settings = false;
439
440 return parseInt(this.$store.state.editing_field_id);
441 },
442
443 editing_form_field: function editing_form_field() {
444 var self = this,
445 i = 0;
446
447 for (i = 0; i < self.$store.state.form_fields.length; i++) {
448 // check if the editing field exist in normal fields
449 if (self.$store.state.form_fields[i].id === parseInt(self.editing_field_id)) {
450 return self.$store.state.form_fields[i];
451 }
452
453 // check if the editing field belong to column field
454 if (self.$store.state.form_fields[i].template === 'column_field') {
455 var innerColumnFields = self.$store.state.form_fields[i].inner_fields;
456
457 for (var columnFields in innerColumnFields) {
458 if (innerColumnFields.hasOwnProperty(columnFields)) {
459 var columnFieldIndex = 0;
460
461 while (columnFieldIndex < innerColumnFields[columnFields].length) {
462 if (innerColumnFields[columnFields][columnFieldIndex].id === self.editing_field_id) {
463 return innerColumnFields[columnFields][columnFieldIndex];
464 }
465 columnFieldIndex++;
466 }
467 }
468 }
469 }
470 }
471 },
472
473 settings: function settings() {
474 var settings = [],
475 template = this.editing_form_field.template;
476
477 if (_.isFunction(this['settings_' + template])) {
478 settings = this['settings_' + template].call(this, this.editing_form_field);
479 } else {
480 settings = this.$store.state.field_settings[template].settings;
481 }
482
483 return _.sortBy(settings, function (item) {
484 return parseInt(item.priority);
485 });
486 },
487
488 basic_settings: function basic_settings() {
489 return this.settings.filter(function (item) {
490 return 'basic' === item.section;
491 });
492 },
493
494 advanced_settings: function advanced_settings() {
495 return this.settings.filter(function (item) {
496 return 'advanced' === item.section;
497 });
498 },
499
500 quiz_settings: function quiz_settings() {
501 return this.settings.filter(function (item) {
502 return 'quiz' === item.section;
503 });
504 },
505
506 form_field_type_title: function form_field_type_title() {
507 var template = this.editing_form_field.template;
508
509 if (_.isFunction(this['form_field_' + template + '_title'])) {
510 return this['form_field_' + template + '_title'].call(this, this.editing_form_field);
511 }
512
513 return this.$store.state.field_settings[template].title;
514 },
515
516 form_settings: function form_settings() {
517 return this.$store.state.settings;
518 }
519 },
520
521 watch: {
522 form_settings: function form_settings() {
523 return this.$store.state.settings;
524 }
525 }
526 });
527
528 Vue.component('field-radio', {
529 template: '#tmpl-wpuf-field-radio',
530
531 mixins: [wpuf_mixins.option_field_mixin],
532
533 computed: {
534 value: {
535 get: function get() {
536 return this.editing_form_field[this.option_field.name];
537 },
538
539 set: function set(value) {
540 this.$store.commit('update_editing_form_field', {
541 editing_field_id: this.editing_form_field.id,
542 field_name: this.option_field.name,
543 value: value
544 });
545 }
546 }
547 }
548 });
549
550 Vue.component('field-range', {
551 template: '#tmpl-wpuf-field-range',
552
553 mixins: [wpuf_mixins.option_field_mixin],
554
555 computed: {
556 value: {
557 get: function get() {
558 return this.editing_form_field[this.option_field.name];
559 },
560
561 set: function set(value) {
562 this.update_value(this.option_field.name, value);
563 }
564 },
565
566 minColumn: function minColumn() {
567 return this.editing_form_field.min_column;
568 },
569
570 maxColumn: function maxColumn() {
571 return this.editing_form_field.max_column;
572 }
573 },
574
575 methods: {}
576 });
577
578 Vue.component('field-select', {
579 template: '#tmpl-wpuf-field-select',
580
581 mixins: [wpuf_mixins.option_field_mixin],
582
583 computed: {
584 value: {
585 get: function get() {
586 return this.editing_form_field[this.option_field.name];
587 },
588
589 set: function set(value) {
590 this.$store.commit('update_editing_form_field', {
591 editing_field_id: this.editing_form_field.id,
592 field_name: this.option_field.name,
593 value: value
594 });
595 }
596 }
597 }
598 });
599
600 Vue.component('field-text', {
601 template: '#tmpl-wpuf-field-text',
602
603 mixins: [wpuf_mixins.option_field_mixin],
604
605 computed: {
606 value: {
607 get: function get() {
608 return this.editing_form_field[this.option_field.name];
609 },
610
611 set: function set(value) {
612 this.update_value(this.option_field.name, value);
613 }
614 }
615 },
616
617 methods: {
618 on_focusout: function on_focusout(e) {
619 wpuf_form_builder.event_hub.$emit('field-text-focusout', e, this);
620 },
621 on_keyup: function on_keyup(e) {
622 wpuf_form_builder.event_hub.$emit('field-text-keyup', e, this);
623 }
624 }
625 });
626
627 Vue.component('field-text-meta', {
628 template: '#tmpl-wpuf-field-text-meta',
629
630 mixins: [wpuf_mixins.option_field_mixin],
631
632 computed: {
633 value: {
634 get: function get() {
635 return this.editing_form_field[this.option_field.name];
636 },
637
638 set: function set(value) {
639 this.update_value(this.option_field.name, value);
640 }
641 }
642 },
643
644 created: function created() {
645 if ('yes' === this.editing_form_field.is_meta) {
646 if (!this.value) {
647 this.value = this.editing_form_field.label.replace(/\W/g, '_').toLowerCase();
648 }
649
650 wpuf_form_builder.event_hub.$on('field-text-keyup', this.meta_key_autocomplete);
651 }
652 },
653
654 methods: {
655 meta_key_autocomplete: function meta_key_autocomplete(e, label_vm) {
656 if ('label' === label_vm.option_field.name && parseInt(this.editing_form_field.id) === parseInt(label_vm.editing_form_field.id)) {
657 this.value = label_vm.value.replace(/\W/g, '_').toLowerCase();
658 }
659 }
660 }
661 });
662
663 Vue.component('field-textarea', {
664 template: '#tmpl-wpuf-field-textarea',
665
666 mixins: [wpuf_mixins.option_field_mixin],
667
668 computed: {
669 value: {
670 get: function get() {
671 return this.editing_form_field[this.option_field.name];
672 },
673
674 set: function set(value) {
675 this.update_value(this.option_field.name, value);
676 }
677 }
678 }
679 });
680
681 Vue.component('field-visibility', {
682 template: '#tmpl-wpuf-field-visibility',
683
684 mixins: [wpuf_mixins.option_field_mixin],
685
686 computed: {
687 selected: {
688 get: function get() {
689
690 return this.editing_form_field[this.option_field.name].selected;
691 },
692
693 set: function set(value) {
694
695 this.$store.commit('update_editing_form_field', {
696 editing_field_id: this.editing_form_field.id,
697 field_name: this.option_field.name,
698 value: {
699 selected: value,
700 choices: []
701 }
702 });
703 }
704 },
705
706 choices: {
707 get: function get() {
708 return this.editing_form_field[this.option_field.name].choices;
709 },
710
711 set: function set(value) {
712
713 this.$store.commit('update_editing_form_field', {
714 editing_field_id: this.editing_form_field.id,
715 field_name: this.option_field.name,
716 value: {
717 selected: this.selected,
718 choices: value
719 }
720 });
721 }
722 }
723
724 },
725
726 methods: {},
727
728 watch: {
729 selected: function selected(new_val) {
730 this.update_value('selected', new_val);
731 }
732 }
733 });
734 /**
735 * Field template: Checkbox
736 */
737 Vue.component('form-checkbox_field', {
738 template: '#tmpl-wpuf-form-checkbox_field',
739
740 mixins: [wpuf_mixins.form_field_mixin]
741 });
742
743 /**
744 * Field template: Column Field
745 */
746 var mixins = [wpuf_mixins.form_field_mixin];
747
748 if (window.wpuf_forms_mixin_builder_stage) {
749 mixins.push(window.wpuf_forms_mixin_builder_stage);
750 }
751
752 if (window.weforms_mixin_builder_stage) {
753 mixins.push(window.weforms_mixin_builder_stage);
754 }
755
756 Vue.component('form-column_field', {
757 template: '#tmpl-wpuf-form-column_field',
758
759 mixins: mixins,
760
761 data: function data() {
762 return {
763 columnClasses: ['column-1', 'column-2', 'column-3'] // don't edit class names
764 };
765 },
766 mounted: function mounted() {
767 this.resizeColumns(this.field.columns);
768
769 // bind jquery ui draggable
770 var self = this,
771 sortableFields = $(self.$el).find('.wpuf-column-inner-fields .wpuf-column-fields-sortable-list'),
772 sortableTriggered = 1,
773 columnFieldArea = $('.wpuf-field-columns'),
774 columnFields = $(self.$el).find(".wpuf-column-field-inner-columns .wpuf-column-inner-fields");
775
776 columnFieldArea.mouseenter(function () {
777 self.resizeColumns(self.field.columns);
778 });
779
780 columnFieldArea.mouseleave(function () {
781 columnFields.unbind("mouseup");
782 columnFields.unbind("mousemove");
783 });
784
785 // bind jquery ui sortable
786 $(sortableFields).sortable({
787 placeholder: 'form-preview-stage-dropzone',
788 connectWith: sortableFields,
789 items: '.column-field-items',
790 handle: '.wpuf-column-field-control-buttons .move',
791 scroll: true,
792 stop: function stop(event, ui) {
793 var data_source = ui.item.context.attributes['data-source'].value;
794
795 if ('panel' === data_source) {
796 var payload = {
797 toIndex: parseInt($(ui.item).index()),
798 field_template: ui.item.context.attributes['data-form-field'].value,
799 to_column: $(this).context.parentElement.classList[0]
800 };
801
802 self.add_column_inner_field(payload);
803
804 // remove button from stage
805 $(this).find('.button.ui-draggable.ui-draggable-handle').remove();
806 }
807 },
808 update: function update(e, ui) {
809 var item = ui.item[0],
810 data = item.dataset,
811 source = data.source,
812 toIndex = parseInt($(ui.item).index()),
813 payload = {
814 toIndex: toIndex
815 };
816
817 if ('column-field-stage' === source) {
818 payload.field_id = self.field.id;
819 payload.fromIndex = parseInt(ui.item.context.attributes['column-field-index'].value);
820 payload.fromColumn = ui.item.context.attributes['in-column'].value;
821 payload.toColumn = ui.item.context.parentElement.parentElement.classList[0];
822
823 // when drag field one column to another column, sortable event trigger twice and try to swap field twice.
824 // So the following conditions are needed to check and run swap_column_field_elements commit only once
825 if (payload.fromColumn !== payload.toColumn && sortableTriggered === 1) {
826 sortableTriggered = 0;
827 } else {
828 sortableTriggered++;
829 }
830
831 if (payload.fromColumn === payload.toColumn) {
832 sortableTriggered = 1;
833 }
834
835 if (sortableTriggered === 1) {
836 self.$store.commit('swap_column_field_elements', payload);
837 }
838 }
839 }
840 });
841 },
842
843 computed: {
844 column_fields: function column_fields() {
845 return this.field.inner_fields;
846 },
847
848 innerColumns: function innerColumns() {
849 return this.field.columns;
850 },
851
852 editing_form_id: function editing_form_id() {
853 return this.$store.state.editing_field_id;
854 },
855
856 field_settings: function field_settings() {
857 return this.$store.state.field_settings;
858 }
859 },
860
861 methods: {
862 is_template_available: function is_template_available(field) {
863 var template = field.template;
864
865 if (this.field_settings[template]) {
866 if (this.is_pro_feature(template)) {
867 return false;
868 }
869
870 return true;
871 }
872
873 // for example see 'mixin_builder_stage' mixin's 'is_taxonomy_template_available' method
874 if (_.isFunction(this['is_' + template + '_template_available'])) {
875 return this['is_' + template + '_template_available'].call(this, field);
876 }
877
878 return false;
879 },
880
881 is_pro_feature: function is_pro_feature(template) {
882 return this.field_settings[template] && this.field_settings[template].pro_feature ? true : false;
883 },
884
885 get_field_name: function get_field_name(template) {
886 return this.field_settings[template].title;
887 },
888
889 is_full_width: function is_full_width(template) {
890 if (this.field_settings[template] && this.field_settings[template].is_full_width) {
891 return true;
892 }
893
894 return false;
895 },
896
897 is_invisible: function is_invisible(field) {
898 return field.recaptcha_type && 'invisible_recaptcha' === field.recaptcha_type ? true : false;
899 },
900
901 isAllowedInClolumnField: function isAllowedInClolumnField(field_template) {
902 var restrictedFields = ['column_field', 'custom_hidden_field', 'step_start'];
903
904 if ($.inArray(field_template, restrictedFields) >= 0) {
905 return true;
906 }
907
908 return false;
909 },
910
911 add_column_inner_field: function add_column_inner_field(data) {
912 var payload = {
913 toWhichColumnField: this.field.id,
914 toWhichColumnFieldMeta: this.field.name,
915 toIndex: data.toIndex,
916 toWhichColumn: data.to_column
917 };
918
919 if (this.isAllowedInClolumnField(data.field_template)) {
920 swal({
921 title: "Oops...",
922 text: "You cannot add this field as inner column field"
923 });
924 return;
925 }
926
927 // check if these are already inserted
928 if (this.isSingleInstance(data.field_template) && this.containsField(data.field_template)) {
929 swal({
930 title: "Oops...",
931 text: "You already have this field in the form"
932 });
933 return;
934 }
935
936 var field = $.extend(true, {}, this.$store.state.field_settings[data.field_template].field_props),
937 form_fields = this.$store.state.form_fields;
938
939 field.id = this.get_random_id();
940
941 if ('yes' === field.is_meta && !field.name && field.label) {
942 field.name = field.label.replace(/\W/g, '_').toLowerCase();
943
944 var same_template_fields = form_fields.filter(function (form_field) {
945 return form_field.template === field.template;
946 });
947
948 if (same_template_fields) {
949 field.name += '_' + this.get_random_id();
950 }
951 }
952
953 payload.field = field;
954
955 // add new form element
956 this.$store.commit('add_column_inner_field_element', payload);
957 },
958 moveFieldsTo: function moveFieldsTo(column) {
959 var payload = {
960 field_id: this.field.id,
961 move_to: column,
962 inner_fields: this.getInnerFields()
963 };
964
965 // clear inner fields & push mergedFields to column-1
966 this.$store.commit('move_column_inner_fields', payload);
967 },
968 getInnerFields: function getInnerFields() {
969 return this.field.inner_fields;
970 },
971
972 open_column_field_settings: function open_column_field_settings(field, index, column) {
973 var self = this,
974 payload = {
975 field_id: self.field.id,
976 column_field: field,
977 index: index,
978 column: column
979 };
980 self.$store.commit('open_column_field_settings', payload);
981 },
982
983 clone_column_field: function clone_column_field(field, index, column) {
984 var self = this,
985 payload = {
986 field_id: self.field.id,
987 column_field_id: field.id,
988 index: index,
989 toColumn: column,
990 new_id: self.get_random_id()
991 };
992
993 // check if the field is allowed to duplicate
994 if (self.isSingleInstance(field.template)) {
995 swal({
996 title: "Oops...",
997 text: "You already have this field in the form"
998 });
999 return;
1000 }
1001
1002 self.$store.commit('clone_column_field_element', payload);
1003 },
1004
1005 delete_column_field: function delete_column_field(index, fromColumn) {
1006 var self = this,
1007 payload = {
1008 field_id: self.field.id,
1009 index: index,
1010 fromColumn: fromColumn
1011 };
1012
1013 swal({
1014 text: self.i18n.delete_field_warn_msg,
1015 type: 'warning',
1016 showCancelButton: true,
1017 confirmButtonColor: '#d54e21',
1018 confirmButtonText: self.i18n.yes_delete_it,
1019 cancelButtonText: self.i18n.no_cancel_it,
1020 confirmButtonClass: 'btn btn-success',
1021 cancelButtonClass: 'btn btn-danger'
1022 }).then(function () {
1023 self.$store.commit('delete_column_field_element', payload);
1024 }, function () {});
1025 },
1026
1027 resizeColumns: function resizeColumns(columnsNumber) {
1028 var self = this;
1029
1030 (function () {
1031 var columnElement;
1032 var startOffset;
1033 var columnField = $(self.$el).context.parentElement;
1034 var total_width = parseInt($(columnField).width());
1035
1036 Array.prototype.forEach.call($(self.$el).find(".wpuf-column-field-inner-columns .wpuf-column-inner-fields"), function (column) {
1037 column.style.position = 'relative';
1038
1039 var grip = document.createElement('div');
1040 grip.innerHTML = "&nbsp;";
1041 grip.style.top = 0;
1042 grip.style.right = 0;
1043 grip.style.bottom = 0;
1044 grip.style.width = '5px';
1045 grip.style.position = 'absolute';
1046 grip.style.cursor = 'col-resize';
1047 grip.addEventListener('mousedown', function (e) {
1048 columnElement = column;
1049 startOffset = column.offsetWidth - e.pageX;
1050 });
1051
1052 column.appendChild(grip);
1053 });
1054
1055 $(self.$el).find(".wpuf-column-field-inner-columns .wpuf-column-inner-fields").mousemove(function (e) {
1056 if (columnElement) {
1057 var currentColumnWidth = startOffset + e.pageX;
1058
1059 columnElement.style.width = 100 * currentColumnWidth / total_width + '%';
1060 }
1061 });
1062
1063 $(self.$el).find(".wpuf-column-field-inner-columns .wpuf-column-inner-fields").mouseup(function () {
1064 var colOneWidth = 0,
1065 colTwoWidth = 0,
1066 colThreeWidth = 0;
1067
1068 if (columnsNumber === 3) {
1069 colOneWidth = 100 / columnsNumber;
1070 colTwoWidth = 100 / columnsNumber;
1071 colThreeWidth = 100 / columnsNumber;
1072 } else if (columnsNumber === 2) {
1073 colOneWidth = 100 / columnsNumber;
1074 colTwoWidth = 100 / columnsNumber;
1075 colThreeWidth = 0;
1076 } else {
1077 colOneWidth = $(columnField).find(".column-1").width();
1078 colTwoWidth = $(columnField).find(".column-2").width();
1079 colThreeWidth = 0;
1080 }
1081
1082 self.field.inner_columns_size['column-1'] = colOneWidth + '%';
1083 self.field.inner_columns_size['column-2'] = colTwoWidth + '%';
1084 self.field.inner_columns_size['column-3'] = colThreeWidth + '%';
1085
1086 columnElement = undefined;
1087 });
1088 })();
1089 }
1090 },
1091
1092 watch: {
1093 innerColumns: function innerColumns(new_value) {
1094 var columns = parseInt(new_value),
1095 columns_size = this.field.inner_columns_size;
1096
1097 Object.keys(columns_size).forEach(function (column) {
1098 if (columns === 1) {
1099 columns_size[column] = '100%';
1100 }
1101
1102 if (columns === 2) {
1103 columns_size[column] = '50%';
1104 }
1105
1106 if (columns === 3) {
1107 columns_size[column] = '33.33%';
1108 }
1109 });
1110
1111 // if columns number reduce to 1 then move other column fields to the first column
1112 if (columns === 1) {
1113 this.moveFieldsTo("column-1");
1114 }
1115
1116 // if columns number reduce to 2 then move column-2 and column-3 fields to the column-2
1117 if (columns === 2) {
1118 this.moveFieldsTo("column-2");
1119 }
1120
1121 this.resizeColumns(columns);
1122 }
1123 }
1124 });
1125
1126 /**
1127 * Field template: Hidden
1128 */
1129 Vue.component('form-custom_hidden_field', {
1130 template: '#tmpl-wpuf-form-custom_hidden_field',
1131
1132 mixins: [wpuf_mixins.form_field_mixin]
1133 });
1134
1135 /**
1136 * Field template: Custom HTML
1137 */
1138 Vue.component('form-custom_html', {
1139 template: '#tmpl-wpuf-form-custom_html',
1140
1141 mixins: [wpuf_mixins.form_field_mixin],
1142
1143 data: function data() {
1144 return {
1145 raw_html: '<p>from data</p>'
1146 };
1147 }
1148 });
1149
1150 /**
1151 * Field template: Dropdown/Select
1152 */
1153 Vue.component('form-dropdown_field', {
1154 template: '#tmpl-wpuf-form-dropdown_field',
1155
1156 mixins: [wpuf_mixins.form_field_mixin]
1157 });
1158
1159 /**
1160 * Field template: Email
1161 */
1162 Vue.component('form-email_address', {
1163 template: '#tmpl-wpuf-form-email_address',
1164
1165 mixins: [wpuf_mixins.form_field_mixin]
1166 });
1167
1168 /**
1169 * Field template: Featured Image
1170 */
1171 Vue.component('form-featured_image', {
1172 template: '#tmpl-wpuf-form-featured_image',
1173
1174 mixins: [wpuf_mixins.form_field_mixin]
1175 });
1176
1177 /**
1178 * Sidebar form fields panel
1179 */
1180 Vue.component('form-fields', {
1181 template: '#tmpl-wpuf-form-fields',
1182
1183 mixins: wpuf_form_builder_mixins(wpuf_mixins.form_fields),
1184
1185 computed: {
1186 panel_sections: function panel_sections() {
1187 return this.$store.state.panel_sections;
1188 },
1189
1190 field_settings: function field_settings() {
1191 return this.$store.state.field_settings;
1192 },
1193
1194 form_fields: function form_fields() {
1195 return this.$store.state.form_fields;
1196 }
1197 },
1198
1199 mounted: function mounted() {
1200 // bind jquery ui draggable
1201 $(this.$el).find('.panel-form-field-buttons .button').draggable({
1202 connectToSortable: '#form-preview-stage .wpuf-form, .wpuf-column-inner-fields .wpuf-column-fields-sortable-list',
1203 helper: 'clone',
1204 revert: 'invalid',
1205 cancel: '.button-faded'
1206 }).disableSelection();
1207 },
1208
1209 methods: {
1210 panel_toggle: function panel_toggle(index) {
1211 this.$store.commit('panel_toggle', index);
1212 },
1213
1214 add_form_field: function add_form_field(field_template) {
1215 var payload = {
1216 toIndex: this.$store.state.form_fields.length
1217 };
1218
1219 // check if these are already inserted
1220 if (this.isSingleInstance(field_template) && this.containsField(field_template)) {
1221 swal({
1222 title: "Oops...",
1223 text: "You already have this field in the form"
1224 });
1225 return;
1226 }
1227
1228 var field = $.extend(true, {}, this.$store.state.field_settings[field_template].field_props);
1229
1230 field.id = this.get_random_id();
1231
1232 if (!field.name && field.label) {
1233 field.name = field.label.replace(/\W/g, '_').toLowerCase();
1234
1235 var same_template_fields = this.form_fields.filter(function (form_field) {
1236 return form_field.template === field.template;
1237 });
1238
1239 if (same_template_fields.length) {
1240 field.name += '_' + same_template_fields.length;
1241 }
1242 }
1243
1244 payload.field = field;
1245
1246 // add new form element
1247 this.$store.commit('add_form_field_element', payload);
1248 },
1249
1250 is_pro_feature: function is_pro_feature(field) {
1251 return this.field_settings[field].pro_feature;
1252 },
1253
1254 alert_pro_feature: function alert_pro_feature(field) {
1255 var title = this.field_settings[field].title;
1256
1257 swal({
1258 title: '<i class="fa fa-lock"></i> ' + title + ' <br>' + this.i18n.is_a_pro_feature,
1259 text: this.i18n.pro_feature_msg,
1260 type: '',
1261 showCancelButton: true,
1262 cancelButtonText: this.i18n.close,
1263 confirmButtonColor: '#46b450',
1264 confirmButtonText: this.i18n.upgrade_to_pro
1265 }).then(function (is_confirm) {
1266 if (is_confirm) {
1267 window.open(wpuf_form_builder.pro_link, '_blank');
1268 }
1269 }, function () {});
1270 },
1271
1272 alert_invalidate_msg: function alert_invalidate_msg(field) {
1273 var validator = this.field_settings[field].validator;
1274
1275 if (validator && validator.msg) {
1276 this.warn({
1277 title: validator.msg_title || '',
1278 html: validator.msg,
1279 type: 'warning',
1280 showCancelButton: false,
1281 confirmButtonColor: '#46b450',
1282 confirmButtonText: this.i18n.ok
1283 });
1284 }
1285 },
1286
1287 get_invalidate_btn_class: function get_invalidate_btn_class(field) {
1288 return this.field_settings[field].validator.button_class;
1289 }
1290 }
1291 });
1292
1293 /**
1294 * Field template: Image Upload
1295 */
1296 Vue.component('form-image_upload', {
1297 template: '#tmpl-wpuf-form-image_upload',
1298
1299 mixins: [wpuf_mixins.form_field_mixin]
1300 });
1301
1302 /**
1303 * Field template: Multi-Select
1304 */
1305 Vue.component('form-multiple_select', {
1306 template: '#tmpl-wpuf-form-multiple_select',
1307
1308 mixins: [wpuf_mixins.form_field_mixin]
1309 });
1310
1311 /**
1312 * Field Template: Post Content
1313 */
1314 Vue.component('form-post_content', {
1315 template: '#tmpl-wpuf-form-post_content',
1316
1317 mixins: [wpuf_mixins.form_field_mixin]
1318 });
1319
1320 /**
1321 * Field Template: Post Excerpt
1322 */
1323 Vue.component('form-post_excerpt', {
1324 template: '#tmpl-wpuf-form-post_excerpt',
1325
1326 mixins: [wpuf_mixins.form_field_mixin]
1327 });
1328
1329 /**
1330 * Field template: post_tags
1331 */
1332 Vue.component('form-post_tags', {
1333 template: '#tmpl-wpuf-form-post_tags',
1334
1335 mixins: [wpuf_mixins.form_field_mixin]
1336 });
1337
1338 /**
1339 * Field template: Post Title
1340 */
1341 Vue.component('form-post_title', {
1342 template: '#tmpl-wpuf-form-post_title',
1343
1344 mixins: [wpuf_mixins.form_field_mixin]
1345 });
1346
1347 /**
1348 * Field template: Radio
1349 */
1350 Vue.component('form-radio_field', {
1351 template: '#tmpl-wpuf-form-radio_field',
1352
1353 mixins: [wpuf_mixins.form_field_mixin]
1354 });
1355
1356 /**
1357 * Field template: Recaptcha
1358 */
1359 Vue.component('form-recaptcha', {
1360 template: '#tmpl-wpuf-form-recaptcha',
1361
1362 mixins: [wpuf_mixins.form_field_mixin],
1363
1364 computed: {
1365 has_recaptcha_api_keys: function has_recaptcha_api_keys() {
1366 return wpuf_form_builder.recaptcha_site && wpuf_form_builder.recaptcha_secret ? true : false;
1367 },
1368
1369 no_api_keys_msg: function no_api_keys_msg() {
1370 return wpuf_form_builder.field_settings.recaptcha.validator.msg;
1371 }
1372 }
1373 });
1374
1375 /**
1376 * Field template: Section Break
1377 */
1378 Vue.component('form-section_break', {
1379 template: '#tmpl-wpuf-form-section_break',
1380
1381 mixins: [wpuf_mixins.form_field_mixin]
1382 });
1383
1384 /**
1385 * Field template: taxonomy
1386 */
1387 Vue.component('form-taxonomy', {
1388 template: '#tmpl-wpuf-form-taxonomy',
1389
1390 mixins: [wpuf_mixins.form_field_mixin],
1391
1392 computed: {
1393 terms: function terms() {
1394 var i;
1395
1396 for (i in wpuf_form_builder.wp_post_types) {
1397 var taxonomies = wpuf_form_builder.wp_post_types[i];
1398
1399 if (taxonomies.hasOwnProperty(this.field.name)) {
1400 var tax_field = taxonomies[this.field.name];
1401
1402 if (tax_field.terms) {
1403 return tax_field.terms;
1404 }
1405 }
1406 }
1407
1408 return [];
1409 },
1410
1411 sorted_terms: function sorted_terms() {
1412 var self = this;
1413 var terms = $.extend(true, [], this.terms);
1414
1415 // selection type and terms
1416 if (this.field.exclude_type && this.field.exclude) {
1417
1418 if (this.field.exclude.length > 1) {
1419 var filter_ids = this.field.exclude.split(',').map(function (id) {
1420 id = id.trim();
1421 id = parseInt(id);
1422 return id;
1423 }).filter(function (id) {
1424 return isFinite(id);
1425 });
1426 }
1427
1428 terms = terms.filter(function (term) {
1429
1430 switch (self.field.exclude_type) {
1431 case 'exclude':
1432 return _.indexOf(filter_ids, term.term_id) < 0;
1433
1434 case 'include':
1435 return _.indexOf(filter_ids, term.term_id) >= 0;
1436
1437 case 'child_of':
1438 return _.indexOf(filter_ids, parseInt(term.parent)) >= 0;
1439 }
1440 });
1441 }
1442
1443 // order
1444 terms = _.sortBy(terms, function (term) {
1445 return term[self.field.orderby];
1446 });
1447
1448 if ('DESC' === this.field.order) {
1449 terms = terms.reverse();
1450 }
1451
1452 var parent_terms = terms.filter(function (term) {
1453 return !term.parent;
1454 });
1455
1456 parent_terms.map(function (parent) {
1457 parent.children = self.get_child_terms(parent.term_id, terms);
1458 });
1459
1460 return parent_terms.length ? parent_terms : terms;
1461 }
1462 },
1463
1464 methods: {
1465 get_child_terms: function get_child_terms(parent_id, terms) {
1466 var self = this;
1467
1468 var child_terms = terms.filter(function (term) {
1469 return parseInt(term.parent) === parseInt(parent_id);
1470 });
1471
1472 child_terms.map(function (child) {
1473 child.children = self.get_child_terms(child.term_id, terms);
1474 });
1475
1476 return child_terms;
1477 },
1478
1479 get_term_dropdown_options: function get_term_dropdown_options() {
1480 var self = this,
1481 options = '';
1482
1483 if (this.field.type === 'select') {
1484 options = '<option value="">' + this.field.first + '</option>';
1485 }
1486
1487 _.each(self.sorted_terms, function (term) {
1488 options += self.get_term_dropdown_options_children(term, 0);
1489 });
1490
1491 return options;
1492 },
1493
1494 get_term_dropdown_options_children: function get_term_dropdown_options_children(term, level) {
1495 var self = this,
1496 option = '';
1497
1498 var indent = '',
1499 i = 0;
1500
1501 for (i = 0; i < level; i++) {
1502 indent += '&nbsp;&nbsp;';
1503 }
1504
1505 option += '<option value="' + term.id + '">' + indent + term.name + '</option>';
1506
1507 if (term.children.length) {
1508 _.each(term.children, function (child_term) {
1509 option += self.get_term_dropdown_options_children(child_term, level + 1);
1510 });
1511 }
1512
1513 return option;
1514 },
1515
1516 get_term_checklist: function get_term_checklist() {
1517 var self = this,
1518 checklist = '';
1519
1520 checklist += '<ul class="wpuf-category-checklist">';
1521
1522 _.each(this.sorted_terms, function (term) {
1523 checklist += self.get_term_checklist_li(term);
1524 });
1525
1526 checklist += '</ul>';
1527
1528 return checklist;
1529 },
1530
1531 get_term_checklist_li: function get_term_checklist_li(term) {
1532 var self = this,
1533 li = '';
1534
1535 li += '<li><label class="selectit"><input type="checkbox"> ' + term.name + '</label></li>';
1536
1537 if (term.children.length) {
1538 li += '<ul class="children">';
1539
1540 _.each(term.children, function (child_term) {
1541 li += self.get_term_checklist_li(child_term);
1542 });
1543
1544 li += '</ul>';
1545 }
1546
1547 return li;
1548 },
1549
1550 get_term_checklist_inline: function get_term_checklist_inline() {
1551 var self = this,
1552 checklist = '';
1553
1554 _.each(this.sorted_terms, function (term) {
1555 checklist += self.get_term_checklist_li_inline(term);
1556 });
1557
1558 return checklist;
1559 },
1560
1561 get_term_checklist_li_inline: function get_term_checklist_li_inline(term) {
1562 var self = this,
1563 li_inline = '';
1564
1565 li_inline += '<label class="wpuf-checkbox-inline"><input type="checkbox"> ' + term.name + '</label>';
1566
1567 if (term.children.length) {
1568 _.each(term.children, function (child_term) {
1569 li_inline += self.get_term_checklist_li_inline(child_term);
1570 });
1571 }
1572
1573 return li_inline;
1574 }
1575 }
1576 });
1577
1578 /**
1579 * Field template: Text
1580 */
1581 Vue.component('form-text_field', {
1582 template: '#tmpl-wpuf-form-text_field',
1583
1584 mixins: [wpuf_mixins.form_field_mixin]
1585 });
1586
1587 Vue.component('form-textarea_field', {
1588 template: '#tmpl-wpuf-form-textarea_field',
1589
1590 mixins: [wpuf_mixins.form_field_mixin]
1591 });
1592
1593 /**
1594 * Field template: Website URL
1595 */
1596 Vue.component('form-website_url', {
1597 template: '#tmpl-wpuf-form-website_url',
1598
1599 mixins: [wpuf_mixins.form_field_mixin]
1600 });
1601
1602 Vue.component('help-text', {
1603 template: '#tmpl-wpuf-help-text',
1604
1605 props: {
1606 text: {
1607 type: String,
1608 default: ''
1609 }
1610 },
1611
1612 mounted: function mounted() {
1613 $(".wpuf-tooltip").tooltip();
1614 }
1615 });
1616
1617 Vue.component('text-editor', {
1618 template: '#tmpl-wpuf-text-editor',
1619
1620 props: ['rich', 'default_text'],
1621
1622 computed: {
1623 site_url: function site_url() {
1624 return wpuf_form_builder.site_url;
1625 },
1626
1627 is_full: function is_full() {
1628 return 'yes' === this.rich;
1629 }
1630 }
1631 });
1632 })(jQuery);
1633