Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport self hosted cdn #624

Merged
merged 2 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading