This content originally appeared on DEV Community and was authored by KUMAR HARSH
Hold Shift And Check Checkboxes
✨ Demo
Before we begin today's Blog I would like to Thank You everyone who is consistently reading my Blog and supporting me. This is my 10th day on dev.to and my 10th blog as well and the support I have received is something I never even Imagined. Once again a big Thank You to everyone reading this blog.
Today we worked on something very useful, a common layout you would see in an email client.
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.
By default some checkboxes were provided and due to this code in CSS we can check any box and the text had a line-through.
input:checked + p {
background: #f9f9f9;
text-decoration: line-through;
}
So the very first thing we did was to select all checkboxes where I Learned how to select the elements by the type
key.
const checkboxes = document.querySelectorAll(
'.inbox input[type="checkbox"]'
);
Now that we have a NodeList of all the checkboxes we will loop through every single one using forEach()
and add eventListeners()
.
checkboxes.forEach((checkbox) =>
checkbox.addEventListener("click", handleCheck)
);
One thing to note here is that we use the click
event instead of change
event, because click
event will fire even if we use the keyboard.
Now we will write our logic inside the handleCheck
function, which will be called as soon as the user clicks any of the boxes.
Next thing we need to take care of is, when we check the first box, we need to put that into a variable, because when we check our second one (while holding down shift
) we need to know what the last one was. So we'll create a variable to maintain a reference to it, and after creating the variable we'll update it at the end of the handleCheck
function.
let lastChecked;
function handleCheck(e) {
//rest of the code
lastChecked = this;
Note: We use
let
instead ofconst
because this variable is going to update constantly.
Now we need to figure out what checkboxes we need to check based on the checkboxes the user clicks. So rather than trying to find where in the DOM they are and trying to figure out like which elements are in-between and finding it's parents.......
This is vary fragile way to do so because we are dependent on the HTML set and if someone else comes along and changes the HTML a little bit, the code would just break and we do not want that.
What we are going to do instead is we are going to loop over every single checkbox and we are going to create a variable called inBetween
(set to false
initially) and what inBetween
will do is we'll loop over the entire NodeList of checkboxes and as soon as we find a checked checkbox we'll it's value to true
and the loop will go one and the second time we find the checked element we'll set if back to false
again.
Now before we code the logic for inBetweeen
we need to perform another check, first if the shift
if pressed down and secondly while clicking the checkbox, user is checking it and not unchecking it because the click
event gets fired on both occasions.
let inBetween = false;
if (e.shiftKey && this.checked) {
//loop over every single checkbox
checkboxes.forEach((checkbox) => {
if (checkbox === this || checkbox === lastChecked) {
inBetween = !inBetween;
}
if (inBetween) {
checkbox.checked = true;
}
});
}
This (e.shiftKey && this.checked)
ensures that we do not loop over the checkboxes unless shift
is pressed and the click was checking and not unchecking.
Using this part we loop over every single checkbox and update inBetween
accordingly.
checkboxes.forEach((checkbox) => {
if (checkbox === this || checkbox === lastChecked) {
inBetween = !inBetween;
}
We have used this:
if (checkbox === this || checkbox === lastChecked) {
inBetween = !inBetween;
}
instead of simply setting to true
or false
so that our checkboxes work both ways so we do inBetween
is opposite of itself.
NOTE: keep in mind checks are always performed top->bottom.
First case is where user clicks a lower checkbox first and then clicks upper checkbox in which case checkbox === this
is true (here this
is equal to the one that got checked) and since this checkbox is the one we are currently looping over so condition is true.
Seconnd case is where, first the user clicks a upper box and then clicks a box below it. In this case checkbox === lastChecked
is true as the upper box is kept in lastChecked
variable and the lower box is the currently checked box, so we revert the value of inBetween
using inBetween = !inBetween
that is set it to true.
Long story short, it will start checking from top and as soon as checked box is found inBetween
is set to true and second time a checked box is found inBetween
is set to false again.
Making use of inBetween
flag this checks all boxes while inBetween
is true that all the boxes in between
if (inBetween) {
checkbox.checked = true;
}
This is the complete JavaScript code:
const checkboxes = document.querySelectorAll(
'.inbox input[type="checkbox"]'
);
let lastChecked;
function handleCheck(e) {
//we need to check if they had the shift key down
//and check that they are checking it not unchecking it
let inBetween = false;
if (e.shiftKey && this.checked) {
//loop over every single checkbox
checkboxes.forEach((checkbox) => {
if (checkbox === this || checkbox === lastChecked) {
inBetween = !inBetween;
}
if (inBetween) {
checkbox.checked = true;
}
});
}
lastChecked = this;
}
checkboxes.forEach((checkbox) =>
checkbox.addEventListener("click", handleCheck)
);
and with this our project for the day was completed.
GitHub repo:
Blog on Day-9 of javascript30
Blog on Day-8 of javascript30
Blog on Day-7 of javascript30
Follow me on Twitter
Follow me on Linkedin
DEV Profile
You can also do the challenge at javascript30
Thanks @wesbos , WesBos to share this with us! ??
Please comment and let me know your views
Thank You!
This content originally appeared on DEV Community and was authored by KUMAR HARSH
KUMAR HARSH | Sciencx (2021-06-10T17:27:42+00:00) JavaScript-30-Day-10. Retrieved from https://www.scien.cx/2021/06/10/javascript-30-day-10/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.