]> BookStack Code Mirror - bookstack/blob - resources/js/components/ajax-form.js
91029d04221247cbc4b079fd3d807a4eb25cb93f
[bookstack] / resources / js / components / ajax-form.js
1 import {onEnterPress, onSelect} from "../services/dom";
2
3 /**
4  * Ajax Form
5  * Will handle button clicks or input enter press events and submit
6  * the data over ajax. Will always expect a partial HTML view to be returned.
7  * Fires an 'ajax-form-success' event when submitted successfully.
8  *
9  * Will handle a real form if that's what the component is added to
10  * otherwise will act as a fake form element.
11  *
12  * @extends {Component}
13  */
14 class AjaxForm {
15     setup() {
16         this.container = this.$el;
17         this.responseContainer = this.container;
18         this.url = this.$opts.url;
19         this.method = this.$opts.method || 'post';
20         this.successMessage = this.$opts.successMessage;
21         this.submitButtons = this.$manyRefs.submit || [];
22
23         if (this.$opts.responseContainer) {
24             this.responseContainer = this.container.closest(this.$opts.responseContainer);
25         }
26
27         this.setupListeners();
28     }
29
30     setupListeners() {
31
32         if (this.container.tagName === 'FORM') {
33             this.container.addEventListener('submit', this.submitRealForm.bind(this));
34             return;
35         }
36
37         onEnterPress(this.container, event => {
38             this.submitFakeForm();
39             event.preventDefault();
40         });
41
42         this.submitButtons.forEach(button => onSelect(button, this.submitFakeForm.bind(this)));
43     }
44
45     submitFakeForm() {
46         const fd = new FormData();
47         const inputs = this.container.querySelectorAll(`[name]`);
48         for (const input of inputs) {
49             fd.append(input.getAttribute('name'), input.value);
50         }
51         this.submit(fd);
52     }
53
54     submitRealForm(event) {
55         event.preventDefault();
56         const fd = new FormData(this.container);
57         this.submit(fd);
58     }
59
60     async submit(formData) {
61         this.responseContainer.style.opacity = '0.7';
62         this.responseContainer.style.pointerEvents = 'none';
63
64         try {
65             const resp = await window.$http[this.method.toLowerCase()](this.url, formData);
66             this.$emit('success', {formData});
67             this.responseContainer.innerHTML = resp.data;
68             if (this.successMessage) {
69                 window.$events.emit('success', this.successMessage);
70             }
71         } catch (err) {
72             this.responseContainer.innerHTML = err.data;
73         }
74
75         window.components.init(this.responseContainer);
76         this.responseContainer.style.opacity = null;
77         this.responseContainer.style.pointerEvents = null;
78     }
79
80 }
81
82 export default AjaxForm;