/*eslint no-var: "error"*/ /*eslint no-console: "off"*/ /*eslint no-bitwise: "off"*/ /*eslint-disable no-trailing-spaces*/ /*eslint-env es6*/ // Put this file in path/to/plugin/amd/src import {call} from 'core/ajax'; import {processCollectedJavascript} from 'core/fragment'; import {replaceNodeContents} from 'core/templates'; import notification from 'core/notification'; import {load_strings} from './string-helper'; import Debugger from './debugger'; //import {markFormSubmitted} from 'core_form/changechecker'; // Moodle 4.00+ only //import {notifyFormSubmittedByJavascript} from 'core_form/events'; // Moodle 4.00+ only /** * Create a random UUID in both secure and insecure contexts * @returns UUID */ function create_uuid() { if (crypto.randomUUID !== undefined ) { return crypto.randomUUID(); } else { return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ); } } export default { install(Vue/*,options*/){ let debug = new Debugger("treestudyplan-mform-helper"); let strings = load_strings({ editmod: { save$core: "save$core", cancel$core: "cancel$core", } }); Vue.component('mform', { props: { name: { type: String, }, params: { type: Object, }, title: { type: String, default: "", }, variant: { type: String, default: "primary", }, type: { type: String, default: "link", } }, data() { return { content: "", loading: true, uuid: create_uuid(), text: strings, submitok: false, observer: null, inputs: [], }; }, computed: { }, methods: { openForm() { const self = this; self.$refs["editormodal"].show(); }, onShown() { const self = this; debug.info(`Loading form "${self.name}" with params`,self.params); self.loading = false; call([{ methodname: 'local_treestudyplan_get_mform', args: {formname: self.name, params: JSON.stringify(self.params)} }])[0].then((data)=>{ const html = data.html; self.loading = false; // Process the collected javascript; const js = processCollectedJavascript(data.javascript); replaceNodeContents(self.$refs["content"], html, js); self.initListenChanges(); }).catch(notification.exception); }, onSave() { const self = this; let form = this.$refs["content"].getElementsByTagName("form")[0]; // markFormSubmitted(form); // Moodle 4.00+ only // We call this, so other modules can update the form with the latest state. form.dispatchEvent(new Event("save-form-state")); // Tell all form fields we are about to submit the form. // notifyFormSubmittedByJavascript(form); // Moodle 4.00+ only const formdata = new FormData(form); const data = new URLSearchParams(formdata).toString(); if(this.checkSave()){ call([{ methodname: 'local_treestudyplan_submit_mform', args: {formname: self.name, params: JSON.stringify(self.params), formdata: data} }])[0].then((response)=>{ const updatedplan = JSON.parse(response.data); self.$emit("saved",updatedplan,formdata); }).catch(notification.exception); } /* No error if we cannot save, since it would just be to handle the edge case where someone clicks on the save button before an invalid input got a chance to update. */ }, checkSave() { let canSave = true; this.inputs.forEach(el => { el.focus(); el.blur(); if (el.classList.contains("is-invalid")) { canSave = false; } },this); this.submitok = canSave; return canSave; }, initListenChanges() { const content = this.$refs["content"]; this.inputs = content.querySelectorAll("input.form-control"); // Check if save needs to be blocked immediately. (delay call by a few ms) setTimeout(this.checkSave, 100); // Disconnect any existing observer. if(this.observer) { this.observer.disconnect(); } // Initialize new observer and callback. this.observer = new MutationObserver((mutationList) => { for(const mix in mutationList){ const mutation = mutationList[mix]; if (mutation.type === 'attributes' && mutation.attributeName === 'class') { this.checkSave(); } } }); // Connect the observer to the form inputs. this.inputs.forEach(el => { this.observer.observe(el,{ attributes: true }); },this); }, }, unmount() { if(this.observer) { this.observer.disconnect(); } }, template: `
`, }); } };