Created
April 25, 2024 14:37
-
-
Save goulvench/a5d5f44a47dc3375e275fefce3ca4122 to your computer and use it in GitHub Desktop.
A very generic Stmulus controller which can be used to show/hide, check/uncheck, enable/disable, collapse/expand, and focus fields after toggling a checkbox.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Visit The Stimulus Handbook for more details | |
// https://stimulusjs.org/handbook/introduction | |
// | |
// Example HTML: | |
// <div data-controller="toggle-other"> | |
// <input type="checkbox" value="nope" data-action="toggle-other#toggle" /> | |
// <input type="checkbox" value="yeap" data-action="toggle-other#toggle" data-toggle-other-target="disable focus" /> | |
// <input type="text" name="other" data-toggle-other-target="focus" data-toggle-other-target="enable" /> | |
// </div> | |
// | |
// Behaviour: | |
// When the target is checked, the other targets are enabled/disabled, checked/unchecked, collapsed/expanded, or receive focus. | |
import ApplicationController from "./application_controller" | |
export default class extends ApplicationController { | |
static targets = [ | |
"toggler", | |
"focus", | |
"disable", | |
"enable", | |
"collapse", | |
"uncollapse", | |
"check", | |
"uncheck", | |
"show", | |
"hide", | |
] | |
toggle(e) { | |
if (!this.hasTogglerTarget) { | |
return | |
} | |
this.toggleDisabled() | |
this.toggleCollapse() | |
this.toggleShow() | |
this.toggleCheck() | |
if (e && !this.isChecked) { | |
this.setFocus() | |
} | |
} | |
check(e) { | |
this.toggleCheck() | |
} | |
get is_checked() { | |
return this.togglerTarget.checked | |
} | |
toggleDisabled() { | |
const is_checked = this.is_checked | |
new Array(...this.disableTargets).forEach((target) => | |
this.toggleDisabledTarget(target, is_checked) | |
) | |
new Array(...this.enableTargets).forEach((target) => | |
this.toggleDisabledTarget(target, !is_checked) | |
) | |
} | |
toggleCollapse() { | |
const is_checked = this.is_checked | |
new Array(...this.collapseTargets).forEach( | |
function (target) { | |
if (is_checked) { | |
new bootstrap.Collapse(target, { | |
show: true, | |
}) | |
} else { | |
new bootstrap.Collapse(target, { | |
hide: true, | |
}) | |
} | |
}.bind(this) | |
) | |
new Array(...this.uncollapseTargets).forEach( | |
function (target) { | |
if (is_checked) { | |
new bootstrap.Collapse(target, { | |
hide: true, | |
}) | |
} else { | |
new bootstrap.Collapse(target, { | |
show: true, | |
}) | |
} | |
}.bind(this) | |
) | |
} | |
toggleCheck() { | |
const is_checked = this.is_checked | |
new Array(...this.checkTargets).forEach( | |
(target) => (target.checked = is_checked) | |
) | |
new Array(...this.uncheckTargets).forEach( | |
(target) => (target.checked = !is_checked) | |
) | |
} | |
toggleShow() { | |
const is_checked = this.is_checked | |
new Array(...this.showTargets).forEach((target) => | |
target.classList.toggle("d-none", !is_checked) | |
) | |
new Array(...this.hideTargets).forEach((target) => | |
target.classList.toggle("d-none", is_checked) | |
) | |
} | |
toggleDisabledTarget(target, is_checked) { | |
if (is_checked) { | |
target.classList.add("disabled") | |
target.setAttribute("disabled", "disabled") | |
target.setAttribute("aria-disabled", "true") | |
target.setAttribute("tabindex", -1) | |
} else { | |
target.classList.remove("disabled") | |
target.removeAttribute("disabled") | |
target.removeAttribute("aria-disabled") | |
target.removeAttribute("tabindex") | |
} | |
} | |
setFocus() { | |
if (this.hasFocusTarget) { | |
var focussable = this.focusTargets.filter((element) => !element.disabled) | |
if (focussable.length) { | |
focussable[0].focus() | |
} | |
} else if (this.hasDisableTarget) { | |
this.disableTarget.focus() | |
} else if (this.hasCollapseTarget) { | |
this.collapseTarget.focus() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment