X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/d41452f39c90deaca98b4fe0e8c87f7d7aa395b8..refs/pull/5429/head:/resources/js/components/ajax-form.js diff --git a/resources/js/components/ajax-form.js b/resources/js/components/ajax-form.js index 92b19dcff..de1a6db43 100644 --- a/resources/js/components/ajax-form.js +++ b/resources/js/components/ajax-form.js @@ -1,58 +1,79 @@ -import {onEnterPress, onSelect} from "../services/dom"; +import {onEnterPress, onSelect} from '../services/dom.ts'; +import {Component} from './component'; /** * Ajax Form * Will handle button clicks or input enter press events and submit * the data over ajax. Will always expect a partial HTML view to be returned. * Fires an 'ajax-form-success' event when submitted successfully. - * @extends {Component} + * + * Will handle a real form if that's what the component is added to + * otherwise will act as a fake form element. */ -class AjaxForm { +export class AjaxForm extends Component { + setup() { this.container = this.$el; + this.responseContainer = this.container; this.url = this.$opts.url; this.method = this.$opts.method || 'post'; this.successMessage = this.$opts.successMessage; this.submitButtons = this.$manyRefs.submit || []; + if (this.$opts.responseContainer) { + this.responseContainer = this.container.closest(this.$opts.responseContainer); + } + this.setupListeners(); } setupListeners() { + if (this.container.tagName === 'FORM') { + this.container.addEventListener('submit', this.submitRealForm.bind(this)); + return; + } + onEnterPress(this.container, event => { - this.submit(); + this.submitFakeForm(); event.preventDefault(); }); - this.submitButtons.forEach(button => onSelect(button, this.submit.bind(this))); + this.submitButtons.forEach(button => onSelect(button, this.submitFakeForm.bind(this))); } - async submit() { + submitFakeForm() { const fd = new FormData(); - const inputs = this.container.querySelectorAll(`[name]`); - console.log(inputs); + const inputs = this.container.querySelectorAll('[name]'); for (const input of inputs) { fd.append(input.getAttribute('name'), input.value); } + this.submit(fd); + } + + submitRealForm(event) { + event.preventDefault(); + const fd = new FormData(this.container); + this.submit(fd); + } + + async submit(formData) { + this.responseContainer.style.opacity = '0.7'; + this.responseContainer.style.pointerEvents = 'none'; - this.container.style.opacity = '0.7'; - this.container.style.pointerEvents = 'none'; try { - const resp = await window.$http[this.method.toLowerCase()](this.url, fd); - this.container.innerHTML = resp.data; - this.$emit('success', {formData: fd}); + const resp = await window.$http[this.method.toLowerCase()](this.url, formData); + this.$emit('success', {formData}); + this.responseContainer.innerHTML = resp.data; if (this.successMessage) { window.$events.emit('success', this.successMessage); } } catch (err) { - this.container.innerHTML = err.data; + this.responseContainer.innerHTML = err.data; } - window.components.init(this.container); - this.container.style.opacity = null; - this.container.style.pointerEvents = null; + window.$components.init(this.responseContainer); + this.responseContainer.style.opacity = null; + this.responseContainer.style.pointerEvents = null; } } - -export default AjaxForm; \ No newline at end of file