Skip to content

Commit 5c4b856

Browse files
committed
fixed inBetween & lastChecked bugs 🐞+ improved UX
1. user clicks shift before first selection, all checkboxes below are selected. - lastChecked is undefined and inBetween remains true. 2. user selects and deselects a checkbox and then holds shift before selecting a checkbox, all checkboxes between current and last are selected. - lastChecked remains defined though it has been deselected. Improved UX by checking direction when checkboxes get deselected.
1 parent 359b569 commit 5c4b856

File tree

1 file changed

+62
-29
lines changed

1 file changed

+62
-29
lines changed

10 - Hold Shift and Check Checkboxes/index-FINISHED.html

+62-29
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
border-bottom: 0;
3131
}
3232

33-
3433
input:checked + p {
3534
background: #F9F9F9;
3635
text-decoration: line-through;
@@ -45,7 +44,7 @@
4544
padding: 20px;
4645
transition: background 0.2s;
4746
flex: 1;
48-
font-family: 'helvetica neue';
47+
font-family:'helvetica neue';
4948
font-size: 20px;
5049
font-weight: 200;
5150
border-left: 1px solid #D1E2FF;
@@ -54,7 +53,7 @@
5453
<!--
5554
The following is a common layout you would see in an email client.
5655
57-
When a user clicks a checkbox, holds Shift, and then clicks another checkbox a few rows down, all the checkboxes in-between those two checkboxes should be checked.
56+
When a user clicks a checkbox, holds Shift, and then clicks another checkbox a few rows down, all the checkboxes inbetween those two checkboxes should be checked.
5857
5958
-->
6059
<div class="inbox">
@@ -80,7 +79,7 @@
8079
</div>
8180
<div class="item">
8281
<input type="checkbox">
83-
<p>Try do it without any libraries</p>
82+
<p>Try to do it without any libraries</p>
8483
</div>
8584
<div class="item">
8685
<input type="checkbox">
@@ -97,34 +96,68 @@
9796
</div>
9897

9998
<script>
100-
const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]');
101-
102-
let lastChecked;
103-
104-
function handleCheck(e) {
105-
// Check if they had the shift key down
106-
// AND check that they are checking it
107-
let inBetween = false;
108-
if (e.shiftKey && this.checked) {
109-
// go ahead and do what we please
110-
// loop over every single checkbox
111-
checkboxes.forEach(checkbox => {
112-
console.log(checkbox);
113-
if (checkbox === this || checkbox === lastChecked) {
114-
inBetween = !inBetween;
115-
console.log('Starting to check them in between!');
116-
}
117-
118-
if (inBetween) {
119-
checkbox.checked = true;
120-
}
121-
});
99+
class listSelect {
100+
constructor () {
101+
this.checkboxes = document.querySelectorAll('input[type="checkbox"]');
102+
this.proto = Array.prototype;
103+
this.lastIndex;
104+
}
105+
106+
findIndex = node => this.proto.findIndex.call(this.checkboxes, box => node === box )
107+
108+
firstLast ( node, currentIndex ) {
109+
const indexArr = this.proto.reduce.call(this.checkboxes, (arr, box) => {
110+
if( box.checked ){
111+
arr.push( this.findIndex(box) );
112+
}
113+
return arr;
114+
}, []),
115+
firstLastArr = ( (arr, unchecked, current) => {
116+
if ( ! unchecked ) {
117+
return arr;
118+
}
119+
arr[0] = current > arr[0] && current > this.lastIndex ? current +1 : arr[0];
120+
arr[1] = current < arr[1] && current < this.lastIndex ? current -1 : arr[1];
121+
122+
return arr;
123+
})([indexArr[0], indexArr[indexArr.length -1]], false == node.checked, currentIndex);
124+
125+
return firstLastArr;
126+
127+
}
128+
129+
update (node, currentIndex) {
130+
const firstLast = this.firstLast(node, currentIndex);
131+
132+
this.checkboxes.forEach( (box, index) => {
133+
if( index >= firstLast[0] && index <= firstLast[1] ) {
134+
box.checked = true;
135+
} else {
136+
box.checked = false;
137+
}
138+
})
139+
140+
}
141+
142+
}
143+
144+
145+
const lS = new listSelect();
146+
function change(e) {
147+
const currentIndex = lS.findIndex(this);
148+
149+
if ( ! e.shiftKey ) {
150+
return;
151+
}
152+
153+
lS.update(this, currentIndex);
154+
155+
lS.lastIndex = currentIndex;
156+
122157
}
123158

124-
lastChecked = this;
125-
}
159+
lS.checkboxes.forEach( box => box.addEventListener('click', change ) )
126160

127-
checkboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck));
128161
</script>
129162
</body>
130163
</html>

0 commit comments

Comments
 (0)