diff options
author | Luke Bennett <lbennett@gitlab.com> | 2018-10-15 16:36:19 +0300 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2018-10-15 16:36:19 +0300 |
commit | 7cf19c0b816bf7bc146a7f634c65d2e7484f26e1 (patch) | |
tree | 1fd5af973b40f7793a9824765d961098a1c60faf /app/assets/javascripts/dirty_submit | |
parent | 280a132e15c8e1f66487312584e734b108b00df7 (diff) |
Prioritize group settings, improve panel titles, disable submit without changes
Diffstat (limited to 'app/assets/javascripts/dirty_submit')
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; |