diff --git a/application/controllers/components/stv/Student.php b/application/controllers/components/stv/Student.php index ce9000da8..c59092c7f 100644 --- a/application/controllers/components/stv/Student.php +++ b/application/controllers/components/stv/Student.php @@ -256,6 +256,8 @@ class Student extends FHC_Controller public function check() { + $_POST = json_decode($this->input->raw_input_stream, true); + $this->load->library('form_validation'); $this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'callback_isValidDate', [ @@ -272,7 +274,7 @@ class Student extends FHC_Controller $gebdatum = $this->input->post('gebdatum'); if (!$vorname && !$nachname && !$gebdatum) { - return $this->outputJsonSuccess([]); + return $this->outputJsonError(['#' => 'At least one of vorname, nachname or gebdatum must be set']); } $this->load->model('person/Person_model', 'PersonModel'); diff --git a/public/js/components/Stv/Studentenverwaltung/List/New.js b/public/js/components/Stv/Studentenverwaltung/List/New.js index c71bce46f..1eab67967 100644 --- a/public/js/components/Stv/Studentenverwaltung/List/New.js +++ b/public/js/components/Stv/Studentenverwaltung/List/New.js @@ -1,7 +1,7 @@ import {CoreRESTClient} from '../../../../RESTClient.js'; import BsModal from '../../../Bootstrap/Modal.js'; import FhcFormValidation from '../../../Form/Validation.js'; -import VueDatePicker1 from '../../../vueDatepicker.js.php'; +import VueDatePicker from '../../../vueDatepicker.js.php'; var _uuid = 0; @@ -9,128 +9,98 @@ export default { components: { BsModal, FhcFormValidation, - VueDatePicker1 + VueDatePicker }, props: { studiengangKz: Number }, data() { return { - date: null, - geschlechter: [] + geschlechter: [], + formData: {}, + suggestions: {}, + person: null + } + }, + computed: { + saveTitle() { + if (this.person === null) + return 'Bitte auswählen'; + if (this.person === 0) + return 'Neue Person anlegen'; + return 'zu ' + (this.person.vorname + ' ' + this.person.nachname).trim() + ' hinzufügen'; + }, + formDataPerson() { + if (this.person) + return this.person; + return this.formData; } }, methods: { open() { this.$refs.modal.show(); }, - send(e) { - this.sendForm(e.target, 'components/stv/student/check') + reset() { + this.formData = {}; + this.person = null; + this.suggestions = []; + this.$fhcAlert.resetFormValidation(this.$refs.form) + }, + loadSuggestions() { + if (this.person) + return; + // TODO(chris): load serialized + CoreRESTClient + .post('components/stv/student/check', { + vorname: this.formData.vorname, + nachname: this.formData.nachname, + gebdatum: this.formData.gebdatum + }) + .then(result => CoreRESTClient.getData(result.data) || []) .then(result => { - console.log('check: ', result); + this.suggestions = result; + }) + .catch(() => { + // NOTE(chris): repeat request + window.setTimeout(this.loadSuggestions, 100); }); }, - sendForm(form, url) { - this.resetFormValidation(form); - const data = new FormData(form); - return CoreRESTClient - .post(url, data) + send(e) { + if (e.person === null) + this.$fhcAlert.alertError('Select a person first'); // TODO(chris): better error handling! + + this.$fhcAlert.resetFormValidation(form); + const data = {...this.formData, ...(this.person || {})}; + CoreRESTClient + .post('components/stv/student/add') .then(result => result.data) .then(result => { if (CoreRESTClient.isError(result)) throw new Error(CoreRESTClient.getError(result)); - return result; + return CoreRESTClient.getData(result); }) - .catch(this.handleErrors(form)); - }, - resetForm() { - const form = this.$refs.form; - form.reset(); - this.resetFormValidation(form); - }, - resetFormValidation(form) { - const event = new Event('fhc-form-reset'); - form.querySelectorAll(['[data-fhc-form-validate],[data-fhc-form-error]']).forEach(el => el.dispatchEvent(event)); - /*const alert = form.querySelector('div.alert.alert-danger[role="alert"]'); - if (alert) { - alert.innerHTML = ''; - alert.classList.add('d-none'); - } - form.querySelectorAll('.invalid-feedback').forEach(n => n.remove()); - form.querySelectorAll('.is-invalid').forEach(n => n.classList.remove('is-invalid')); - form.querySelectorAll('.is-valid').forEach(n => n.classList.remove('is-valid'));*/ - }, - handleErrors(error, form) { - if (form === undefined) { - if (error && error.nodeType === Node.ELEMENT_NODE) - return err => this.handleErrors(err, error); - } else { - if (error?.response?.status == 400) { - let errors = CoreRESTClient.getError(error.response.data); - if (typeof errors !== "object") - errors = error.response.data; - - // NOTE(chris): reset form validation - this.resetFormValidation(form); - - // NOTE(chris): set form input validation - const notFound = Object.entries(errors).filter(([key, detail]) => { - const input = form.querySelector('[data-fhc-form-validate="' + key + '"]'); - if (!input) - return true; - - input.dispatchEvent(new CustomEvent('fhc-form-invalidate', {detail})); - - /*const input = form.querySelector('[name="' + key + '"]'); - if (!input) - return true; - input.classList.add('is-invalid'); - const feedback = document.createElement('div'); - feedback.classList.add('invalid-feedback'); - feedback.innerHTML = detail; - input.after(feedback);*/ - return false; - }).map(arr => arr[1]); - - - //const alert = form.querySelector('div.alert.alert-danger[role="alert"]'); - const alert = form.querySelector('[data-fhc-form-error]'); - if (alert && notFound.length) { - alert.dispatchEvent(new CustomEvent('fhc-form-error', {detail: notFound})); - /*notFound.forEach(txt => { - const p = document.createElement('p'); - p.innerHTML = txt; - alert.append(p); - }); - - if (notFound.length) { - alert.lastChild.classList.add('mb-0'); - alert.classList.remove('d-none'); - }*/ - } else { - notFound.forEach(this.$fhcAlert.alertError); - } - return; - } - } - this.$fhcAlert.handleSystemError(error); - },test() {console.log('test')} + .then(result => { + this.$fhcAlert.alertSuccess('Gespeichert'); + console.log('saved'); + // TODO(chris): close + }) + .catch(this.$fhcAlert.handleFormValidation); + } }, created() { this.uuid = _uuid++; + // TODO(chris): geschlechter in parent? CoreRESTClient .get('components/stv/Student/getGeschlechter') .then(result => CoreRESTClient.getData(result.data)) .then(result => { - this.geschlechter = result.data; + this.geschlechter = result; }) - .catch(err => { - console.error(CoreRestClient.getError(err.response.data) || err.message); - }); + .catch(this.$fhcAlert.handleSystemError); }, template: `
` diff --git a/public/js/plugin/FhcAlert.js b/public/js/plugin/FhcAlert.js index aa0da4110..b232c813a 100644 --- a/public/js/plugin/FhcAlert.js +++ b/public/js/plugin/FhcAlert.js @@ -300,6 +300,73 @@ export default { // Fallback fhcerror.alertSystemError('alertSystemError throws Generic Error\r\nError Controller Path: ' + FHC_JS_DATA_STORAGE_OBJECT.called_path + '/' + FHC_JS_DATA_STORAGE_OBJECT.called_method); + }, + resetFormValidation(form) { + const event = new Event('fhc-form-reset'); + form.querySelectorAll(['[data-fhc-form-validate],[data-fhc-form-error]']).forEach(el => el.dispatchEvent(event)); + /*const alert = form.querySelector('div.alert.alert-danger[role="alert"]'); + if (alert) { + alert.innerHTML = ''; + alert.classList.add('d-none'); + } + form.querySelectorAll('.invalid-feedback').forEach(n => n.remove()); + form.querySelectorAll('.is-invalid').forEach(n => n.classList.remove('is-invalid')); + form.querySelectorAll('.is-valid').forEach(n => n.classList.remove('is-valid'));*/ + }, + handleFormValidation(error, form) { + if (form === undefined) { + if (error && error.nodeType === Node.ELEMENT_NODE) + return err => $fhcAlert.handleFormValidation(err, error); + } else { + if (error?.response?.status == 400) { + let errors = CoreRESTClient.getError(error.response.data); + if (typeof errors !== "object") + errors = error.response.data; + + // NOTE(chris): reset form validation + $fhcAlert.resetFormValidation(form); + + // NOTE(chris): set form input validation + const notFound = Object.entries(errors).filter(([key, detail]) => { + const input = form.querySelector('[data-fhc-form-validate="' + key + '"]'); + if (!input) + return true; + + input.dispatchEvent(new CustomEvent('fhc-form-invalidate', {detail})); + + /*const input = form.querySelector('[name="' + key + '"]'); + if (!input) + return true; + input.classList.add('is-invalid'); + const feedback = document.createElement('div'); + feedback.classList.add('invalid-feedback'); + feedback.innerHTML = detail; + input.after(feedback);*/ + return false; + }).map(arr => arr[1]); + + + //const alert = form.querySelector('div.alert.alert-danger[role="alert"]'); + const alert = form.querySelector('[data-fhc-form-error]'); + if (alert && notFound.length) { + alert.dispatchEvent(new CustomEvent('fhc-form-error', {detail: notFound})); + /*notFound.forEach(txt => { + const p = document.createElement('p'); + p.innerHTML = txt; + alert.append(p); + }); + + if (notFound.length) { + alert.lastChild.classList.add('mb-0'); + alert.classList.remove('d-none'); + }*/ + } else { + notFound.forEach($fhcAlert.alertError); + } + return; + } + } + $fhcAlert.handleSystemError(error); } }; app.config.globalProperties.$fhcAlert = $fhcAlert;