Skip to content
This repository was archived by the owner on Oct 26, 2024. It is now read-only.

Commit 505f97a

Browse files
Merge pull request #2 from stimulus-components/indeterminate-state
Adding indeterminate support
2 parents a1f552f + 9a81124 commit 505f97a

File tree

5 files changed

+85
-5
lines changed

5 files changed

+85
-5
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- Indeterminate state support
12+
13+
Add `data-target="checkbox-select-all.checkboxAll"` attribute to use it. It's optional.
14+
```diff
15+
- <input type="checkbox" data-action="change->checkbox-select-all#toggle" />
16+
+ <input type="checkbox" data-target="checkbox-select-all.checkboxAll" data-action="change->checkbox-select-all#toggle" />
17+
```
18+
919
## [1.0.0] - 2020-10-15
1020

1121
### Added

README.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,44 @@ application.register("checkbox-select-all", CheckboxSelectAll)
2828

2929
## Usage
3030

31+
### Without Rails
32+
33+
```html
34+
<table>
35+
<tbody>
36+
<td class="block">
37+
<label>
38+
<input type="checkbox" data-target="checkbox-select-all.checkboxAll" data-action="change->checkbox-select-all#toggle" />
39+
<span>Select All / Deselect All</span>
40+
</label>
41+
</td>
42+
43+
<td class="block">
44+
<label>
45+
<input type="checkbox" data-target="checkbox-select-all.checkbox" value="1" />
46+
<span>Team 1</span>
47+
</label>
48+
</td>
49+
50+
<td class="block">
51+
<label>
52+
<input type="checkbox" data-target="checkbox-select-all.checkbox" checked="checked" value="2" />
53+
<span>Team 2</span>
54+
</label>
55+
</td>
56+
57+
<td class="block">
58+
<label>
59+
<input type="checkbox" data-target="checkbox-select-all.checkbox" value="3" />
60+
<span>Team 3</span>
61+
</label>
62+
</td>
63+
</tbody>
64+
</table>
65+
```
66+
67+
### With Rails
68+
3169
In your models:
3270
```ruby
3371
class User < ApplicationRecord
@@ -66,7 +104,7 @@ In your view:
66104
```html
67105
<%= form_with model: @user, data: { controller: 'checkbox-select-all' } do |f| %>
68106
<label>
69-
<input type="checkbox" data-action="change->checkbox-select-all#toggle" />
107+
<input type="checkbox" data-target="checkbox-select-all.checkboxAll" data-action="change->checkbox-select-all#toggle" />
70108
<span>Select All / Deselect All</span>
71109
</label>
72110

index.html

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,12 @@ <h2 class="text-center text-2xl font-bold my-4">Essential links</h2>
9898
<tbody>
9999
<td class="block">
100100
<label>
101-
<input id="checkbox-select-all" type="checkbox" data-action="change->checkbox-select-all#toggle" />
101+
<input
102+
id="checkbox-select-all"
103+
type="checkbox"
104+
data-target="checkbox-select-all.checkboxAll"
105+
data-action="change->checkbox-select-all#toggle"
106+
/>
102107
<span>Select All / Deselect All</span>
103108
</label>
104109
</td>
@@ -112,7 +117,7 @@ <h2 class="text-center text-2xl font-bold my-4">Essential links</h2>
112117

113118
<td class="block">
114119
<label>
115-
<input type="checkbox" data-target="checkbox-select-all.checkbox" />
120+
<input type="checkbox" data-target="checkbox-select-all.checkbox" checked="checked" />
116121
<span>Team 2</span>
117122
</label>
118123
</td>

src/index.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
11
import { Controller } from 'stimulus'
22

33
export default class extends Controller {
4-
static targets = ['checkbox']
4+
static targets = ['checkboxAll', 'checkbox']
5+
6+
connect () {
7+
this.refresh = this.refresh.bind(this)
8+
9+
if (!this.hasCheckboxAllTarget) return
10+
11+
this.checkboxTargets.forEach(checkbox => checkbox.addEventListener('change', this.refresh))
12+
this.refresh()
13+
}
14+
15+
disconnect () {
16+
if (!this.hasCheckboxAllTarget) return
17+
18+
this.checkboxTargets.forEach(checkbox => checkbox.removeEventListener('change', this.refresh))
19+
}
520

621
toggle (e) {
722
e.preventDefault()
@@ -10,4 +25,12 @@ export default class extends Controller {
1025
checkbox.checked = e.target.checked
1126
})
1227
}
28+
29+
refresh () {
30+
const checkboxesCount = this.checkboxTargets.length
31+
const checkboxesCheckedCount = this.checkboxTargets.filter(checkbox => checkbox.checked).length
32+
33+
this.checkboxAllTarget.checked = checkboxesCheckedCount > 0
34+
this.checkboxAllTarget.indeterminate = checkboxesCheckedCount > 0 && checkboxesCheckedCount < checkboxesCount
35+
}
1336
}

src/index.test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ describe('#checkboxSelectAll', () => {
1111
() => document.querySelectorAll("[data-target='checkbox-select-all.checkbox']:checked").length
1212
)
1313

14-
expect(targetsBefore).toBe(0)
14+
expect(targetsBefore).toBe(1)
1515

16+
// Uncheck all
17+
await toggleCheckbox.click()
18+
19+
// Check all
1620
await toggleCheckbox.click()
1721

1822
const targetsAfter = await page.evaluate(

0 commit comments

Comments
 (0)