PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.86
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.86
51.1.86 51.1.84 51.1.85 51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 All 40 releases
← All changes | includes/widgets/Form_Builder/editor-handler.js +296 -0 51.1.2 → 51.1.86 View file →
@@ -1,0 +1,296 @@
1 +"use strict";
2 +(function ($) {
3 + const FLAG = "kingAddonsFormBuilderEditorBound";
4 +
5 + /**
6 + * Bind Elementor editor handlers once.
7 + *
8 + * @returns {void}
9 + */
10 + const bindOnce = () => {
11 + if (window[FLAG]) {
12 + return;
13 + }
14 + window[FLAG] = true;
15 +
16 + $(window).on("elementor:init", () => {
17 +
18 + elementor.hooks.addAction(
19 + "panel/open_editor/widget/king-addons-form-builder",
20 + function (panel, model, view) {
21 + if (view && view._kingAddonsFormBuilderBound) {
22 + return;
23 + }
24 + if (view) {
25 + view._kingAddonsFormBuilderBound = true;
26 + }
27 +
28 + const $panelRoot = $("#elementor-panel");
29 + const $elements = panel.$el.find(".elementor-repeater-fields");
30 +
31 + if (!$panelRoot.length) {
32 + return;
33 + }
34 +
35 + if (view && view._kingAddonsStepObserver) {
36 + view._kingAddonsStepObserver.disconnect();
37 + }
38 +
39 + const stepObserver = new MutationObserver(function (mutations) {
40 + mutations.forEach((mutation) => {
41 + if (mutation.type !== "childList") {
42 + return;
43 + }
44 + mutation.addedNodes.forEach((node) => {
45 + if (!(node instanceof Element)) {
46 + return;
47 + }
48 + const rowTools = node.querySelectorAll(".elementor-repeater-row-tools");
49 + const rowControls = node.querySelectorAll(".elementor-repeater-row-controls");
50 + if (!rowControls.length || !rowTools.length) {
51 + return;
52 + }
53 +
54 + const selects = [];
55 + rowControls.forEach(function (item) {
56 + selects.push(item.querySelector("select"));
57 + });
58 +
59 + rowTools.forEach(function (item, i) {
60 + if (selects[i] && selects[i].value === "king-addons-fb-step") {
61 + item.classList.add("king-addons-fb-step-editor-bg");
62 + }
63 + });
64 + });
65 + });
66 + });
67 +
68 + if (view) {
69 + view._kingAddonsStepObserver = stepObserver;
70 + }
71 +
72 + stepObserver.observe($panelRoot[0], {
73 + childList: true,
74 + subtree: true,
75 + });
76 +
77 + changeStepBackground();
78 +
79 + elementor.channels.editor.off("section:activated.kingAddonsFormBuilder");
80 + elementor.channels.editor.on("section:activated.kingAddonsFormBuilder", function () {
81 + updateDynamicOptions(view);
82 + });
83 +
84 + const formFieldsCollection = view.model.get("settings").get("form_fields");
85 + view.stopListening(formFieldsCollection, "add change remove");
86 + view.listenTo(formFieldsCollection, "add change remove", function () {
87 + updateDynamicOptions(view);
88 + });
89 +
90 + function changeStepBackground() {
91 + $elements.each(function () {
92 + if ($(this).find("select").val() === "king-addons-fb-step") {
93 + $(this)
94 + .find(".elementor-repeater-row-tools")
95 + .addClass("king-addons-fb-step-editor-bg");
96 + }
97 + });
98 +
99 + $panelRoot.off("change.kingAddonsFormBuilder", "select");
100 + $panelRoot.on("change.kingAddonsFormBuilder", "select", function () {
101 + const $select = $(this);
102 + const $tools = $select
103 + .closest(".elementor-repeater-row-controls")
104 + .prev(".elementor-repeater-row-tools");
105 +
106 + if ($select.val() === "king-addons-fb-step") {
107 + $tools.addClass("king-addons-fb-step-editor-bg");
108 + return;
109 + }
110 + if ($tools.hasClass("king-addons-fb-step-editor-bg")) {
111 + $tools.removeClass("king-addons-fb-step-editor-bg");
112 + }
113 + });
114 + }
115 +
116 + function updateDynamicOptions() {
117 + const formFieldsModel = view.model.get("settings").get("form_fields");
118 +
119 + const emailField = view.model.get("settings").get("email_field");
120 + const firstNameField = view.model.get("settings").get("first_name_field");
121 + const lastNameField = view.model.get("settings").get("last_name_field");
122 + const phoneField = view.model.get("settings").get("phone_field");
123 + const birthdayField = view.model.get("settings").get("birthday_field");
124 + const addressField = view.model.get("settings").get("address_field");
125 + const countryField = view.model.get("settings").get("country_field");
126 + const cityField = view.model.get("settings").get("city_field");
127 + const stateField = view.model.get("settings").get("state_field");
128 + const zipField = view.model.get("settings").get("zip_field");
129 +
130 + const emailSelectControl = panel.$el
131 + .find(".elementor-control-email_field")
132 + .find('select[data-setting="email_field"]');
133 + const firstNameSelectControl = panel.$el
134 + .find(".elementor-control-first_name_field")
135 + .find('select[data-setting="first_name_field"]');
136 + const lastNameSelectControl = panel.$el
137 + .find(".elementor-control-last_name_field")
138 + .find('select[data-setting="last_name_field"]');
139 + const phoneSelectControl = panel.$el
140 + .find(".elementor-control-phone_field")
141 + .find('select[data-setting="phone_field"]');
142 + const birthdaySelectControl = panel.$el
143 + .find(".elementor-control-birthday_field")
144 + .find('select[data-setting="birthday_field"]');
145 + const addressSelectControl = panel.$el
146 + .find(".elementor-control-address_field")
147 + .find('select[data-setting="address_field"]');
148 + const countrySelectControl = panel.$el
149 + .find(".elementor-control-country_field")
150 + .find('select[data-setting="country_field"]');
151 + const citySelectControl = panel.$el
152 + .find(".elementor-control-city_field")
153 + .find('select[data-setting="city_field"]');
154 + const stateSelectControl = panel.$el
155 + .find(".elementor-control-state_field")
156 + .find('select[data-setting="state_field"]');
157 + const zipSelectControl = panel.$el
158 + .find(".elementor-control-zip_field")
159 + .find('select[data-setting="zip_field"]');
160 +
161 + const selectControls = [
162 + emailSelectControl,
163 + firstNameSelectControl,
164 + lastNameSelectControl,
165 + phoneSelectControl,
166 + birthdaySelectControl,
167 + addressSelectControl,
168 + countrySelectControl,
169 + citySelectControl,
170 + stateSelectControl,
171 + zipSelectControl,
172 + ];
173 + const fieldValues = [
174 + emailField,
175 + firstNameField,
176 + lastNameField,
177 + phoneField,
178 + birthdayField,
179 + addressField,
180 + countryField,
181 + cityField,
182 + stateField,
183 + zipField,
184 + ];
185 +
186 + const options = {none: "None"};
187 + const seenIds = {};
188 + $panelRoot.find(".king-addons-field-id-dup-notice").remove();
189 +
190 + formFieldsModel.each(function (field) {
191 + const fieldLabel = field.get("field_label");
192 + let fieldId = (field.get("field_id") || "").toString().trim();
193 + const fallbackId = (field.get("_id") || "").toString();
194 +
195 + if (!fieldId && fallbackId) {
196 + assignFieldId(field, fallbackId);
197 + fieldId = fallbackId;
198 + }
199 +
200 + if (fieldId && seenIds[fieldId]) {
201 + const $wrap = $panelRoot.find(".elementor-repeater-fields-wrapper").first();
202 + if ($wrap.length && !$panelRoot.find(".king-addons-field-id-dup-notice").length) {
203 + $wrap.prepend(
204 + '<div class="elementor-panel-alert elementor-panel-alert-warning king-addons-field-id-dup-notice">' +
205 + "Two fields share the same Field ID. Each ID must be unique or submitted values will collide." +
206 + "</div>"
207 + );
208 + }
209 + }
210 +
211 + if (fieldId) {
212 + seenIds[fieldId] = true;
213 + options[fieldId] = fieldLabel;
214 + }
215 + });
216 +
217 + view.model.setSetting("email_field", _.extend(emailField, {options}));
218 + view.model.setSetting("first_name_field", _.extend(firstNameField, {options}));
219 + view.model.setSetting("last_name_field", _.extend(lastNameField, {options}));
220 + view.model.setSetting("phone_field", _.extend(phoneField, {options}));
221 + view.model.setSetting("birthday_field", _.extend(birthdayField, {options}));
222 + view.model.setSetting("address_field", _.extend(addressField, {options}));
223 + view.model.setSetting("country_field", _.extend(countryField, {options}));
224 + view.model.setSetting("city_field", _.extend(cityField, {options}));
225 + view.model.setSetting("state_field", _.extend(stateField, {options}));
226 + view.model.setSetting("zip_field", _.extend(zipField, {options}));
227 +
228 + _.each(selectControls, function (control) {
229 + control.empty();
230 + });
231 +
232 + _.each(options, function (label, value) {
233 + _.each(selectControls, function (control, i) {
234 + const isSelected = fieldValues[i] === value ? " selected" : "";
235 + control.append(
236 + '<option value="' + value + '"' + isSelected + ">" + label + "</option>"
237 + );
238 + });
239 + });
240 + }
241 +
242 + function assignFieldId(field, nextId) {
243 + if (!field || !nextId) {
244 + return;
245 + }
246 +
247 + if (typeof field.setSetting === "function") {
248 + field.setSetting("field_id", nextId);
249 + } else if (typeof field.set === "function") {
250 + field.set("field_id", nextId);
251 + } else {
252 + field.attributes.field_id = nextId;
253 + }
254 +
255 + const $row = $panelRoot
256 + .find(":input[value=" + field.attributes._id + "]")
257 + .closest(".elementor-repeater-fields");
258 + $row.find(':input[data-setting="field_id"]').val(nextId);
259 + $row.find(".king-addons-form-field-shortcode").val('id=["' + nextId + '"]');
260 + }
261 +
262 + // Change the selector below to match the field_id field in your repeater.
263 + const customIdFieldSelector = 'input[data-setting="field_id"]';
264 +
265 + // Change the selector below to match the shortcode field in your repeater.
266 + const shortcodeFieldSelector = ".king-addons-form-field-shortcode";
267 +
268 + // Listen for changes in the field_id field (namespaced).
269 + $panelRoot.off("input.kingAddonsFormBuilder", customIdFieldSelector);
270 + $panelRoot.on("input.kingAddonsFormBuilder", customIdFieldSelector, function () {
271 + const newCustomId = $(this).val();
272 +
273 + const $shortcodeField = $(this)
274 + .closest(".elementor-repeater-fields")
275 + .find(shortcodeFieldSelector);
276 +
277 + let updatedShortcode;
278 + const currentShortcode = $shortcodeField.val();
279 + const match = currentShortcode.match(/\[id="[^"]*"\]/);
280 +
281 + if (match) {
282 + updatedShortcode = currentShortcode.replace(match[0], `[id="${newCustomId}"]`);
283 + } else {
284 + updatedShortcode = `[id="${newCustomId}"]`;
285 + }
286 +
287 + $shortcodeField.val(updatedShortcode);
288 + });
289 + });
290 + ;
291 + });
292 + };
293 +
294 +
295 + bindOnce();
296 +}(jQuery));