import "formBuilder/dist/form-render.min.js"; import "src/decidim/decidim_awesome/forms/rich_text_plugin" export default class CustomFieldsRenderer { // eslint-disable-line no-unused-vars constructor() { this.lang = this.getLang(window.DecidimAwesome.currentLocale); } getLang(lang) { const langs = { // ar: 'ar-SA', // Not in decidim yet "ar": "ar-TN", "ca": "ca-ES", "cs": "cs-CZ", "da": "da-DK", "de": "de-DE", "el": "el-GR", "en": "en-US", "es": "es-ES", "fa": "fa-IR", "fi": "fi-FI", "fr": "fr-FR", "he": "he-IL", "hu": "hu-HU", "it": "it-IT", "ja": "ja-JP", "my": "my-MM", "nb": "nb-NO", "nl": "nl-NL", "pl": "pl-PL", "pt": "pt-BR", "qz": "qz-MM", "ro": "ro-RO", "ru": "ru-RU", "sl": "sl-SI", "th": "th-TH", "tr": "tr-TR", "uk": "uk-UA", "vi": "vi-VN", "zh-TW": "zh-TW", "zh": "zh-CN" }; if (langs[lang]) { return langs[lang]; } if (langs[lang.substr(0, 2)]) { return langs[lang.substr(0, 2)]; } return "en-US"; } /* * Creates an XML document with a subset of html-compatible dl/dd/dt elements * to store the custom fields answers */ dataToXML(data) { const $dl = $("
"); let $dd = null, $div = null, $dt = null, datum = null, key = null, label = null, text = null, val = null; $dl.attr("class", "decidim_awesome-custom_fields"); $dl.attr("data-generator", "decidim_awesome"); $dl.attr("data-version", window.DecidimAwesome.version); for (key in data) { // eslint-disable-line guard-for-in // console.log("get the data!", key, data[key]); // Richtext plugin does not saves userdata, so we get it from the hidden input if (data[key].type === "textarea" && data[key].subtype === "richtext") { data[key].userData = [$(`#${data[key].name}-input`).val()]; } if (data[key].userData && data[key].userData.length) { $dt = $("
"); $dt.text(data[key].label); $dt.attr("name", data[key].name); $dd = $("
"); // console.log("data for", key, data[key].name, data[key]) for (val in data[key].userData) { // eslint-disable-line guard-for-in $div = $("
"); label = data[key].userData[val]; text = null; if (data[key].values) { datum = data[key].values.find((obj) => obj.value === label); // eslint-disable-line no-loop-func if (datum) { // eslint-disable-line max-depth text = label; label = datum.label; } } else if (data[key].type === "date" && label) { datum = new Date(label).toLocaleDateString(); if (datum) { // eslint-disable-line max-depth text = label; label = datum; } } // console.log("userData", text, "label", label, 'key', key, 'data', data) if (data[key].type === "textarea" && data[key].subtype === "richtext") { $div.html(label); } else { $div.text(label); } if (text) { $div.attr("alt", text); } $dd.append($div); } $dd.attr("id", data[key].name); $dd.attr("name", data[key].type); $dl.append($dt); $dl.append($dd); } } // console.log("dataToXML", $dl[0].outerHTML); return `${$dl[0].outerHTML}`; } fixBuggyFields() { if (!this.$element) { return false; } /** * Hack to fix required checkboxes being reset * Issue: https://github.com/decidim-ice/decidim-module-decidim_awesome/issues/82 */ this.$element.find(".formbuilder-checkbox-group").each((_key, group) => { const inputs = $(".formbuilder-checkbox input", group); const $label = $(group).find("label"); const data = this.spec.find((obj) => obj.type === "checkbox-group" && obj.name === $label.attr("for")); let values = data.userData; if (!inputs.length || !data || !values) { return; } inputs.each((_idx, input) => { let index = values.indexOf(input.value); if (index >= 0) { values.splice(index, 1) // setting checked=true do not makes the browser aware that the form is valid if the field is required if (!input.checked) {$(input).click();} } else if (input.checked) {$(input).click();} }); // Fill "other" option const otherOption = $(".other-option", inputs.parent())[0]; const otherVal = $(".other-val", inputs.parent())[0]; const otherText = values.join(" "); if (otherOption) { if (otherText) { otherOption.checked = true; otherOption.value = otherText; otherVal.value = otherText; } else { otherOption.checked = false; otherOption.value = ""; otherVal.value = ""; } } }); /** * Hack to fix required radio buttons "other" value * Issue: https://github.com/decidim-ice/decidim-module-decidim_awesome/issues/133 */ this.$element.find(".formbuilder-radio input.other-val").on("input", (input) => { const $input = $(input.currentTarget); const $group = $input.closest(".formbuilder-radio-group"); $group.find("input").each((_key, radio) => { const name = $(radio).attr("name"); if (name && name.endsWith("[]")) { $(radio).attr("name", name.slice(0, -2)); } }); }); return this; } // Saves xml to the hidden input storeData() { if (!this.$element) { return false; } const $form = this.$element.closest("form"); const $body = $form.find(`input[name="${this.$element.data("name")}"]`); if ($body.length && this.instance) { this.spec = this.instance.userData; $body.val(this.dataToXML(this.spec)); this.$element.data("spec", this.spec); } // console.log("storeData spec", this.spec, "$body", $body,"$form",$form,"this",this); return this; } init($element) { this.$element = $element; this.spec = $element.data("spec"); // console.log("init", $element, "this", this) // in case of multilang tabs we only render one form due a limitation in the library for handling several instances this.instance = $element.formRender({ i18n: { locale: this.lang, location: window.DecidimAwesome.formBuilderLangsLocation }, formData: this.spec, render: true, disableInjectedStyle: true, controlConfig: { "textarea.richtext": { editorOptions: $element.data("editorOptions") } } }); this.fixBuggyFields(); } }