Skip to content

Commit d1f04d8

Browse files
committed
Add toggle switch partial and stimulus controller
1 parent 52fe467 commit d1f04d8

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Controller } from "@hotwired/stimulus"
2+
3+
export default class extends Controller {
4+
static targets = ["checkbox"]
5+
static values = {
6+
onlyOne: Boolean,
7+
group: String
8+
}
9+
10+
connect() {
11+
if (this.onlyOneValue) {
12+
this.enforceSingleSelection()
13+
}
14+
}
15+
16+
toggle(event) {
17+
if (this.onlyOneValue && event.target.checked) {
18+
this.uncheckOtherCheckboxesInGroup(event.target)
19+
}
20+
}
21+
22+
enforceSingleSelection() {
23+
const checkboxesInGroup = this.getCheckboxesInGroup()
24+
const anyChecked = checkboxesInGroup.some(checkbox => checkbox.checked)
25+
26+
if (!anyChecked && checkboxesInGroup.length > 0) {
27+
// Ensure at least one checkbox is checked if none are checked
28+
checkboxesInGroup[0].checked = true
29+
}
30+
}
31+
32+
uncheckOtherCheckboxesInGroup(currentCheckbox) {
33+
const checkboxesInGroup = this.getCheckboxesInGroup()
34+
35+
checkboxesInGroup.forEach(checkbox => {
36+
if (checkbox !== currentCheckbox) {
37+
checkbox.checked = false
38+
}
39+
})
40+
}
41+
42+
getCheckboxesInGroup() {
43+
const container = this.element.closest('[data-better_together--dynamic-fields-target="container"]')
44+
const allCheckboxes = container.querySelectorAll('input[type="checkbox"].toggle-switch')
45+
46+
if (this.hasGroupValue) {
47+
// Filter checkboxes by group
48+
return Array.from(allCheckboxes).filter(checkbox => checkbox.dataset.group === this.groupValue)
49+
}
50+
51+
// If no group is specified, return all checkboxes
52+
return Array.from(allCheckboxes)
53+
}
54+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<%# locals: (form:, attr:, checked: form.object.public_send(attr), only_one: false, group: nil) %>
2+
<div class="form-check form-switch"
3+
data-controller="better_together--toggle-switch"
4+
data-better_together--toggle-switch-only-one-value="<%= only_one %>"
5+
data-better_together--toggle-switch-group-value="<%= group %>">
6+
<%= form.check_box attr,
7+
class: 'form-check-input toggle-switch',
8+
data: { action: 'click->better_together--toggle-switch#toggle', group: group },
9+
'data-better_together--toggle-switch-target' => 'checkbox' %>
10+
<%= form.label attr,
11+
form.object.class.human_attribute_name(attr),
12+
checked:,
13+
class: 'form-check-label' %>
14+
</div>

0 commit comments

Comments
 (0)