Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bennett <lbennett@gitlab.com>2018-10-15 16:36:19 +0300
committerPhil Hughes <me@iamphill.com>2018-10-15 16:36:19 +0300
commit7cf19c0b816bf7bc146a7f634c65d2e7484f26e1 (patch)
tree1fd5af973b40f7793a9824765d961098a1c60faf /app/assets/javascripts/dirty_submit
parent280a132e15c8e1f66487312584e734b108b00df7 (diff)
Prioritize group settings, improve panel titles, disable submit without changes
Diffstat (limited to 'app/assets/javascripts/dirty_submit')
-rw-r--r--app/assets/javascripts/dirty_submit/dirty_submit_collection.js13
-rw-r--r--app/assets/javascripts/dirty_submit/dirty_submit_factory.js9
-rw-r--r--app/assets/javascripts/dirty_submit/dirty_submit_form.js82
3 files changed, 104 insertions, 0 deletions
diff --git a/app/assets/javascripts/dirty_submit/dirty_submit_collection.js b/app/assets/javascripts/dirty_submit/dirty_submit_collection.js
new file mode 100644
index 00000000000..42b051b2270
--- /dev/null
+++ b/app/assets/javascripts/dirty_submit/dirty_submit_collection.js
@@ -0,0 +1,13 @@
+import DirtySubmitForm from './dirty_submit_form';
+
+class DirtySubmitCollection {
+ constructor(forms) {
+ this.forms = forms;
+
+ this.dirtySubmits = [];
+
+ this.forms.forEach(form => this.dirtySubmits.push(new DirtySubmitForm(form)));
+ }
+}
+
+export default DirtySubmitCollection;
diff --git a/app/assets/javascripts/dirty_submit/dirty_submit_factory.js b/app/assets/javascripts/dirty_submit/dirty_submit_factory.js
new file mode 100644
index 00000000000..95a896a7f0b
--- /dev/null
+++ b/app/assets/javascripts/dirty_submit/dirty_submit_factory.js
@@ -0,0 +1,9 @@
+import DirtySubmitCollection from './dirty_submit_collection';
+import DirtySubmitForm from './dirty_submit_form';
+
+export default function dirtySubmitFactory(formOrForms) {
+ const isCollection = formOrForms instanceof NodeList || formOrForms instanceof Array;
+ const DirtySubmitClass = isCollection ? DirtySubmitCollection : DirtySubmitForm;
+
+ return new DirtySubmitClass(formOrForms);
+}
diff --git a/app/assets/javascripts/dirty_submit/dirty_submit_form.js b/app/assets/javascripts/dirty_submit/dirty_submit_form.js
new file mode 100644
index 00000000000..5bea47f23c5
--- /dev/null
+++ b/app/assets/javascripts/dirty_submit/dirty_submit_form.js
@@ -0,0 +1,82 @@
+import _ from 'underscore';
+
+class DirtySubmitForm {
+ constructor(form) {
+ this.form = form;
+ this.dirtyInputs = [];
+ this.isDisabled = true;
+
+ this.init();
+ }
+
+ init() {
+ this.inputs = this.form.querySelectorAll('input, textarea, select');
+ this.submits = this.form.querySelectorAll('input[type=submit], button[type=submit]');
+
+ this.inputs.forEach(DirtySubmitForm.initInput);
+ this.toggleSubmission();
+
+ this.registerListeners();
+ }
+
+ registerListeners() {
+ const throttledUpdateDirtyInput = _.throttle(
+ event => this.updateDirtyInput(event),
+ DirtySubmitForm.THROTTLE_DURATION,
+ );
+ this.form.addEventListener('input', throttledUpdateDirtyInput);
+ this.form.addEventListener('submit', event => this.formSubmit(event));
+ }
+
+ updateDirtyInput(event) {
+ const input = event.target;
+
+ if (!input.dataset.dirtySubmitOriginalValue) return;
+
+ this.updateDirtyInputs(input);
+ this.toggleSubmission();
+ }
+
+ updateDirtyInputs(input) {
+ const { name } = input;
+ const isDirty =
+ input.dataset.dirtySubmitOriginalValue !== DirtySubmitForm.inputCurrentValue(input);
+ const indexOfInputName = this.dirtyInputs.indexOf(name);
+ const isExisting = indexOfInputName !== -1;
+
+ if (isDirty && !isExisting) this.dirtyInputs.push(name);
+ if (!isDirty && isExisting) this.dirtyInputs.splice(indexOfInputName, 1);
+ }
+
+ toggleSubmission() {
+ this.isDisabled = this.dirtyInputs.length === 0;
+ this.submits.forEach(element => {
+ element.disabled = this.isDisabled;
+ });
+ }
+
+ formSubmit(event) {
+ if (this.isDisabled) {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ }
+
+ return !this.isDisabled;
+ }
+
+ static initInput(element) {
+ element.dataset.dirtySubmitOriginalValue = DirtySubmitForm.inputCurrentValue(element);
+ }
+
+ static isInputCheckable(input) {
+ return input.type === 'checkbox' || input.type === 'radio';
+ }
+
+ static inputCurrentValue(input) {
+ return DirtySubmitForm.isInputCheckable(input) ? input.checked.toString() : input.value;
+ }
+}
+
+DirtySubmitForm.THROTTLE_DURATION = 500;
+
+export default DirtySubmitForm;