Skip to content

Commit

Permalink
backport: Use cdn (#624)
Browse files Browse the repository at this point in the history
* backport: self hosted cdn

* backport: update js files content
  • Loading branch information
Stef-Rousset authored Nov 13, 2024
1 parent 9157876 commit 27b6e4a
Show file tree
Hide file tree
Showing 3 changed files with 314 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
require("formBuilder/dist/form-builder.min.js")
import "src/decidim/decidim_awesome/forms/rich_text_plugin"

window.CustomFieldsBuilders = window.CustomFieldsBuilders || [];

$(() => {
$(".awesome-edit-config .proposal_custom_fields_editor").each((_idx, el) => {
const key = $(el).closest(".proposal_custom_fields_container").data("key");
const configVar = $(el).closest(".proposal_custom_fields_container").data("var");
// DOCS: https://formbuilder.online/docs
window.CustomFieldsBuilders.push({
el: el,
key: key,
var: configVar,
config: {
i18n: {
locale: "fr-FR",
location: "https://decidim.storage.opensourcepolitics.eu/osp-cdn/form_builder/1.1.0"
},
formData: $(`input[name="config[${configVar}][${key}]"]`).val(),
disableFields: ["button", "file"],
disabledActionButtons: ["save", "data", "clear"],
disabledAttrs: [
"access",
"inline",
"className"
],
controlOrder: [
"text",
"textarea",
"number",
"date",
"checkbox-group",
"radio-group",
"select",
"autocomplete",
"header",
"paragraph"
],
disabledSubtypes: {
// default color as it generate hashtags in decidim (TODO: fix hashtag generator with this)
text: ["color"],
// disable default wysiwyg editors as they present problems
textarea: ["tinymce", "quill"]
}
},
instance: null
});
});

$(document).on("formBuilder.create", (_event, idx, list) => {
if (!list[idx]) {
return;
}

$(list[idx].el).formBuilder(list[idx].config).promise.then(function(res) {
list[idx].instance = res;
// Attach to DOM
list[idx].el.FormBuilder = res;
// remove spinner
$(list[idx].el).find(".loading-spinner").remove();
// for external use
$(document).trigger("formBuilder.created", [list[idx]]);
if (idx < list.length) {
$(document).trigger("formBuilder.create", [idx + 1, list]);
}
});
});

if (window.CustomFieldsBuilders.length) {
$(document).trigger("formBuilder.create", [0, window.CustomFieldsBuilders]);
}

$("form.awesome-edit-config").on("submit", () => {
window.CustomFieldsBuilders.forEach((builder) => {
$(`input[name="config[${builder.var}][${builder.key}]"]`).val(builder.instance.actions.getData("json"));
});
});
});
225 changes: 225 additions & 0 deletions app/packs/src/decidim/decidim_awesome/forms/custom_fields_renderer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
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(containerSelector) {
this.containerSelector = containerSelector || ".proposal_custom_field:last";
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 = $("<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/>");
$dt.text(data[key].label);
$dt.attr("name", data[key].name);
$dd = $("<dd/>");
// console.log("data for", key, data[key].name, data[key])
for (val in data[key].userData) { // eslint-disable-line guard-for-in
$div = $("<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);
}
}
return `<xml>${$dl[0].outerHTML}</xml>`;
}

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;
console.log("Spec data:", this.spec);
$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) {
console.log("CustomFieldsRenderer init");
this.$element = $element;
console.log("Element for rendering:", $element);

this.spec = $element.data("spec");
console.log("Spec data:", this.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: "https://decidim.storage.opensourcepolitics.eu/osp-cdn/form_builder/1.1.0"
},
formData: this.spec,
render: true,
disableInjectedStyle: true,
controlConfig: {
"textarea.richtext": {
editorOptions: $element.data("editorOptions")
}
}
});
this.fixBuggyFields();
}
}
10 changes: 10 additions & 0 deletions config/initializers/awesome_defaults.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

# A URL where to obtain the translations for the FormBuilder component
# you can a custom place if you are worried about the CDN geolocation
# Download them from https://github.com/kevinchappell/formBuilder-languages

# For instance, copy them to your /public/fb_locales/ directory and set the path here:
Decidim::DecidimAwesome.configure do |config|
config.form_builder_langs_location = "https://decidim.storage.opensourcepolitics.eu/osp-cdn/form_builder/1.1.0/"
end

0 comments on commit 27b6e4a

Please sign in to comment.