본문 바로가기

JavaScript30 Challenge

[JavaScript30] Day 10

Hold Shift and Check Checkboxes

 

Shift키를 누른 상태에서 아래의 다른 체크박스를 클릭하면

두 체크박스 사이의 모든 체크박스가 선택되는 기능입니다.

 

체크박스가 클릭 될때마다 실행되는 handleCheck라는 함수를 만듭니다.

handleCheck에서는 Shift키를 누른채로 클릭을 했을 때, 

inBtween을 체크해서 true인 체크박스들 모두가 선택되도록 해준다.

const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]');
//console.log(checkboxes);

let lastChecked;

function handleCheck(e) {
  // check if they had the shift ket down
  // AND check that they are checking it
  let inBetween = false;
  if (e.shiftKey && this.checked) {
    // go ahead and do what we please
    // loop over every single checkbox
    checkboxes.forEach(checkbox => {
      console.log(checkbox);
      if (checkbox === this || checkbox === lastChecked) {
        inBetween = !inBetween;        
        console.log('Starting ti check them inbetween!')
      }

      if (inBetween) {
        checkbox.checked = true;
      }
    });
  }

  // console.log(e);
  lastChecked = this;
}

checkboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck));

 

++Gmail의 기능과 같은 형식

이 코드로는 부족한점이 처음부터 Shift를 누르고 클릭을하면

내가 클릭한 체크박스 아래로 모든 체크 박스가 선택이 된다.

 

Gmail의 경우 Shift를 누르고 클릭을해도 이전에 선택되어진 체크박스가 없다면 

방금 클릭한 체크박스만 선택된다.

 

이 부분을 수정하려면 lastChecked가 아직 생기지 않았다면 return 해주는 코드로 Gmail과 동일하게 작동시킬 수 있었다.

if (lastChecked === undefined) { return lastChecked = this; };

 

더 살펴보면 Gmail은 첫번째 선택된 체크박스를 기준으로 방금 선택된 체크박스까지가 모두 선택되는 방식이다

예를들어

2번으로 시작해서 쉬프트를 누른후 10번째를 클릭하면 -> 2~10 선택

쉬프트를 누른 상태에서 5번째 클릭하면 -> 2~5가 선택된다.

 

하지만 우리가 만든 코드는 

2번으로 시작해서 쉬프트를 누른후 10번째를 클릭하면 -> 2~10 선택

쉬프트를 누른 상태에서 5번째 클릭하면 -> 2~4, 6~10(2~10에서 5만 제외)이 선택된다.

 

const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]');

let firstChecked = null;
let lastChecked = null;

function handleCheck(e, checkbox, idx) {
	if (!e.shiftKey) {
		firstChecked = idx;		
	} else {
		if (firstChecked === undefined) { return firstChecked = idx; }
		lastChecked = idx;
		const status = checkbox.checked;

		checkboxes.forEach((changed, changed_idx) => {
			const start = Math.min(firstChecked, lastChecked);
			const end = Math.max(firstChecked, lastChecked);
			console.log(start, end);
			if (start <= changed_idx && end >= changed_idx) {
				changed.checked = status;
			}
		});
	}
}

checkboxes.forEach((selected, selected_idx) => selected.addEventListener('click', event => handleCheck(event, selected, selected_idx)));

 

 

JavaScript30 강의를 보고 공부한 글입니다. (https://javascript30.com/)

'JavaScript30 Challenge' 카테고리의 다른 글

[JavaScript30] Day 12  (0) 2020.05.14
[JavaScript30] Day 11  (0) 2020.05.04
[JavaScript30] Day 9  (0) 2020.04.26
[JavaScript30] Day 8  (0) 2020.04.25
[JavaScript30] Day 7  (0) 2020.04.22