From deab35971dd3cec8c96d097275fd84eda37e5b8d Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Willms Date: Mon, 1 Jul 2024 10:24:31 +0200 Subject: refactor forms to sfc, fixes #4300 --- app/controllers/admin/plugin.php | 4 +- resources/assets/javascripts/bootstrap/forms.js | 191 +----------------- resources/vue/components/StudipForm.vue | 249 ++++++++++++++++++++++++ templates/forms/form.php | 24 ++- templates/vue-app.php | 9 +- 5 files changed, 289 insertions(+), 188 deletions(-) create mode 100644 resources/vue/components/StudipForm.vue diff --git a/app/controllers/admin/plugin.php b/app/controllers/admin/plugin.php index 0a01083..9d7d589 100644 --- a/app/controllers/admin/plugin.php +++ b/app/controllers/admin/plugin.php @@ -586,13 +586,13 @@ class Admin_PluginController extends AuthenticatedController 'label' => _('Standardbeschreibung des Plugins'), 'type' => 'info', 'value' => $this->metadata['descriptionlong'] ?? $this->metadata['description'], - 'if' => "STUDIPFORM_SELECTEDLANGUAGES.description === 'de_DE'" + 'if' => "i18n.description === 'de_DE'" ], 'manifest_info_en' => [ 'label' => sprintf(_('Standardbeschreibung des Plugins (%s)'), _('Englisch')), 'type' => 'info', 'value' => $this->metadata['descriptionlong_en'] ?? $this->metadata['description_en'] ?? null, - 'if' => "STUDIPFORM_SELECTEDLANGUAGES.description === 'en_GB'" + 'if' => "i18n.description === 'en_GB'" ], 'description_mode' => [ 'label' => _('Modus der neuen Beschreibung'), diff --git a/resources/assets/javascripts/bootstrap/forms.js b/resources/assets/javascripts/bootstrap/forms.js index 7643612..7ee123d 100644 --- a/resources/assets/javascripts/bootstrap/forms.js +++ b/resources/assets/javascripts/bootstrap/forms.js @@ -242,190 +242,13 @@ function createSelect2(element) { } STUDIP.ready(function () { - let forms = window.document.querySelectorAll('form.default.studipform:not(.vueified)'); - if (forms.length > 0) { - STUDIP.Vue.load().then(({createApp}) => { - forms.forEach(f => { - createApp({ - el: f, - data() { - let params = JSON.parse(f.dataset.inputs); - params.STUDIPFORM_REQUIRED = f.dataset.required ? JSON.parse(f.dataset.required) : []; - params.STUDIPFORM_SERVERVALIDATION = f.dataset.server_validation > 0; - params.STUDIPFORM_DISPLAYVALIDATION = false; - params.STUDIPFORM_VALIDATIONNOTES = []; - params.STUDIPFORM_AUTOSAVEURL = f.dataset.autosave; - params.STUDIPFORM_VALIDATION_URL = f.dataset.validation_url; - params.STUDIPFORM_VALIDATED = false; - params.STUDIPFORM_REDIRECTURL = f.dataset.url; - params.STUDIPFORM_INPUTS_ORDER = []; - params.STUDIPFORM_SELECTEDLANGUAGES = {}; - for (let i in JSON.parse(f.dataset.inputs)) { - params.STUDIPFORM_INPUTS_ORDER.push(i); - } - return params; - }, - methods: { - submit: function (e) { - if (this.STUDIPFORM_VALIDATED) { - return; - } - let v = this; - v.STUDIPFORM_VALIDATIONNOTES = []; - this.STUDIPFORM_DISPLAYVALIDATION = true; - - //validation: - let validation_promise = this.validate(); - validation_promise.then(function (validated) { - if (!validated) { - v.$el.scrollIntoView({ - behavior: 'smooth' - }); - return; - } - - if (v.STUDIPFORM_AUTOSAVEURL) { - let params = v.getFormValues(); - params.STUDIPFORM_AUTOSTORE = 1; - - $.ajax({ - url: v.STUDIPFORM_AUTOSAVEURL, - data: params, - type: 'post', - success(output) { - if (output === 'STUDIPFORM_STORE_SUCCESS' && v.STUDIPFORM_REDIRECTURL) { - //The form has been stored successfully: - window.location.href = v.STUDIPFORM_REDIRECTURL; - } else if (output !== 'STUDIPFORM_STORE_SUCCESS') { - Report.error($gettext('Es ist ein Fehler aufgetreten'), output); - } - } - }); - } else { - v.STUDIPFORM_VALIDATED = true; - v.$el.submit(); - } - }); - e.preventDefault(); - }, - getFormValues() { - let v = this; - let params = { - security_token: this.$refs.securityToken.value - }; - Object.keys(v.$data).forEach(function (i) { - if (!i.startsWith('STUDIPFORM_')) { - if (typeof v.$data[i] === 'boolean') { - params[i] = v.$data[i] ? 1 : 0; - } else { - params[i] = v.$data[i]; - } - } - }); - return params; - }, - validate() { - let v = this; - this.STUDIPFORM_VALIDATIONNOTES = []; - - return new Promise((resolve, reject) => { - let validated = v.$el.checkValidity(); - - $(v.$el).find('input, select, textarea').each(function () { - if (!this.validity.valid) { - let note = { - name: this.name, - label: $(this.labels[0]).find('.textlabel').text(), - description: $gettext('Fehler!'), - describedby: this.id - }; - if ($(this).data('validation_requirement')) { - note.description = $(this).data('validation_requirement'); - } - if (this.validity.tooShort) { - note.description = $gettextInterpolate( - $gettext('Geben Sie mindestens %{min} Zeichen ein.'), - {min: this.minLength} - ); - } - if (this.validity.valueMissing) { - if (this.type === 'checkbox') { - note.description = $gettext('Dieses Feld muss ausgewählt sein.'); - } else { - if (this.minLength > 0) { - note.description = $gettextInterpolate( - $gettext('Hier muss ein Wert mit mindestens %{min} Zeichen eingetragen werden.'), - {min: this.minLength} - ); - } else { - note.description = $gettext('Hier muss ein Wert eingetragen werden.'); - } - - } - } - v.STUDIPFORM_VALIDATIONNOTES.push(note); - } - }); - - if (v.STUDIPFORM_SERVERVALIDATION) { - let params = v.getFormValues(); - if (v.STUDIPFORM_AUTOSAVEURL) { - params.STUDIPFORM_AUTOSTORE = 1; - } - params.STUDIPFORM_SERVERVALIDATION = 1; - - $.post(v.STUDIPFORM_VALIDATION_URL, params).done((output) => { - for (let i in output) { - v.STUDIPFORM_VALIDATIONNOTES.push({ - name: output[i].name, - label: output[i].label, - description: output[i].error, - describedby: null - }); - } - validated = v.STUDIPFORM_VALIDATIONNOTES.length < 1; - resolve(validated); - }); - } else { - resolve(validated); - } - }); - }, - setInputs(inputs) { - for (const [key, value] of Object.entries(inputs)) { - if (this[key] !== undefined) { - this[key] = value; - } - } - }, - selectLanguage(input_name, language_id) { - let languages = { - ...this.STUDIPFORM_SELECTEDLANGUAGES - }; - languages[input_name] = language_id; - this.STUDIPFORM_SELECTEDLANGUAGES = languages; - } - }, - computed: { - ordererValidationNotes: function () { - let orderedNotes = []; - for (let i in this.STUDIPFORM_INPUTS_ORDER) { - for (let k in this.STUDIPFORM_VALIDATIONNOTES) { - if (this.STUDIPFORM_VALIDATIONNOTES[k].name === this.STUDIPFORM_INPUTS_ORDER[i]) { - orderedNotes.push(this.STUDIPFORM_VALIDATIONNOTES[k]); - } - } - } - return orderedNotes; - } - }, - mounted () { - $(this.$el).addClass("vueified"); - } - }); - }); - }); - } + // let forms = window.document.querySelectorAll('form.default.studipform:not(.vueified)'); + // if (forms.length > 0) { + // STUDIP.Vue.load().then(({createApp}) => { + // forms.forEach(f => { + // }); + // }); + // } /* * Form elements with the "simplevue" class are meant for forms that just need some vue components diff --git a/resources/vue/components/StudipForm.vue b/resources/vue/components/StudipForm.vue new file mode 100644 index 0000000..d190764 --- /dev/null +++ b/resources/vue/components/StudipForm.vue @@ -0,0 +1,249 @@ + + diff --git a/templates/forms/form.php b/templates/forms/form.php index fe19404..b6406d0 100644 --- a/templates/forms/form.php +++ b/templates/forms/form.php @@ -19,7 +19,29 @@ foreach ($allinputs as $input) { } } $form_id = md5(uniqid()); -?>
getParts() as $index => $part) { + $vueApp->withSlot('part' . $index, $part->renderWithCondition()); +} +echo $vueApp->withProps([ + 'form'=> [ + 'autosave' => $form->isAutoStoring(), + 'values' => $inputs, + 'required' => $required_inputs, + 'serverValidation' => $server_validation, + 'url' => $form->getURL() ?? false, + ], + + 'debug-mode' => $form->getDebugMode(), + 'is-collapsable' => $form->isCollapsable(), + 'is-secure' => $form->getDataSecure(), + 'request-url' => $_SERVER['REQUEST_URI'], + 'slots' => array_keys($vueApp->getSlots()), +]); +?> + +isAutoStoring()) : ?> action="getURL()) ?>" diff --git a/templates/vue-app.php b/templates/vue-app.php index 2c34929..95a228e 100644 --- a/templates/vue-app.php +++ b/templates/vue-app.php @@ -3,6 +3,7 @@ * @var array $attributes * @var string $baseComponent * @var array $props + * @var array $slots * @var array $storeData */ ?> @@ -10,5 +11,11 @@
> - < /> + < > + $slot): ?> + + + >
-- cgit v1.0