Last active
January 27, 2022 05:07
-
-
Save aq2bq/573ec8a6933d2e2226961d27ee333288 to your computer and use it in GitHub Desktop.
bulk-checking.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Bulk Checking</title> | |
<script src="main.js"></script> | |
<link rel="stylesheet" href="main.css" /> | |
</head> | |
<body> | |
<div class="check-all-alert hidden"></div> | |
<div> | |
<h3>選択された件数:<span class="checked-count">0</span></h3> | |
</div> | |
<ul class="pagination"> | |
<li><a href="1.html">1</a></li> | |
<li><a href="2.html">2</a></li> | |
</ul> | |
<table> | |
<thead> | |
<tr> | |
<th><input type="checkbox" class="item-all-checkbox" /></th> | |
<th>all in this page</th> | |
</tr> | |
</thead> | |
<tbody> | |
<tr> | |
<td><input type="checkbox" value="1" class="item-each-checkbox" /></td> | |
<td>data1</td> | |
</tr> | |
<tr> | |
<td><input type="checkbox" value="2" class="item-each-checkbox" /></td> | |
<td>data2</td> | |
</tr> | |
<tr> | |
<td><input type="checkbox" value="3" class="item-each-checkbox" /></td> | |
<td>data3</td> | |
</tr> | |
</tbody> | |
</table> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Bulk Checking</title> | |
<script src="main.js"></script> | |
<link rel="stylesheet" href="main.css" /> | |
</head> | |
<body> | |
<div class="check-all-alert hidden"></div> | |
<div> | |
<h3>選択された件数:<span class="checked-count">0</span></h3> | |
</div> | |
<ul class="pagination"> | |
<li><a href="1.html">1</a></li> | |
<li><a href="2.html">2</a></li> | |
</ul> | |
<table> | |
<thead> | |
<tr> | |
<th><input type="checkbox" class="item-all-checkbox" /></th> | |
<th>all in this page</th> | |
</tr> | |
</thead> | |
<tbody> | |
<tr> | |
<td><input type="checkbox" value="3" class="item-each-checkbox" /></td> | |
<td>data4</td> | |
</tr> | |
<tr> | |
<td><input type="checkbox" value="4" class="item-each-checkbox" /></td> | |
<td>data5</td> | |
</tr> | |
<tr> | |
<td><input type="checkbox" value="5" class="item-each-checkbox" /></td> | |
<td>data6</td> | |
</tr> | |
</tbody> | |
</table> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
document.addEventListener("DOMContentLoaded", (loadEvent) => { | |
console.log(loadEvent); | |
const ALL_COUNT = 6; | |
/** | |
* Checkbox Component | |
* | |
* @param {Element} elem | |
* | |
* @typedef {Object} CheckboxUI | |
* @property {string} value | |
* @property {(value: string) => void } check | |
* @property {(value: string) => void } uncheck | |
* @property {(callback: (value: string) => void) => function } dispatchOnCheck | |
* @property {(callback: (value: string) => void) => function } dispatchOnUncheck | |
* @return {CheckboxUI} | |
*/ | |
const CheckboxUI = (elem) => { | |
const value = elem.value; | |
const _onCheckHandlers = []; | |
const _onUncheckHandlers = []; | |
const dispatchOnCheck = (callback) => _onCheckHandlers.push(callback); | |
const dispatchOnUncheck = (callback) => _onUncheckHandlers.push(callback); | |
const check = () => { | |
elem.checked = true; | |
_onCheckHandlers.forEach((callback) => callback(value)); | |
}; | |
const uncheck = () => { | |
elem.checked = false; | |
_onUncheckHandlers.forEach((callback) => callback(value)); | |
}; | |
const _handleOnChange = (event) => { | |
event.target.checked ? check() : uncheck(); | |
}; | |
elem.addEventListener("change", _handleOnChange); | |
return { value, check, uncheck, dispatchOnCheck, dispatchOnUncheck }; | |
}; | |
/** | |
* CheckAllBox Component | |
* | |
* @typedef {Object} CheckAllBoxUI | |
* @property {() => void } check | |
* @property {() => void } uncheck | |
* @property {(callback: () => void) => function } dispatchOnCheck | |
* @property {(callback: () => void) => function } dispatchOnUncheck | |
* @return {CheckAllBoxUI} | |
*/ | |
const CheckAllBoxUI = () => { | |
const elem = document.querySelector(".item-all-checkbox"); | |
const _onCheckHandlers = []; | |
const _onUncheckHandlers = []; | |
const dispatchOnCheck = (callback) => _onCheckHandlers.push(callback); | |
const dispatchOnUncheck = (callback) => _onUncheckHandlers.push(callback); | |
const check = () => { | |
elem.checked = true; | |
}; | |
const uncheck = () => { | |
elem.checked = false; | |
}; | |
const _handleOnCheck = () => | |
_onCheckHandlers.forEach((callback) => callback()); | |
const _handleOnUncheck = () => | |
_onUncheckHandlers.forEach((callback) => callback()); | |
const _handleOnChange = (event) => { | |
event.target.checked ? _handleOnCheck() : _handleOnUncheck(); | |
}; | |
elem.addEventListener("change", _handleOnChange); | |
return { check, uncheck, dispatchOnCheck, dispatchOnUncheck }; | |
}; | |
/** | |
* CheckAllBox Component | |
* | |
* @typedef {{render: (value: string) => void}} CheckedCountUI | |
* @return {CheckedCountUI} | |
*/ | |
const CheckedCountUI = () => { | |
const elem = document.querySelector(".checked-count"); | |
const render = (count) => (elem.innerText = count); | |
return { render }; | |
}; | |
/** | |
* CheckingAllPageAlert Component | |
* | |
* @typedef {Object} CheckingAllPageAlertUI | |
* @property {() => void } suggestCheckingAllPage | |
* @property {() => void } suggestUncheckingAllPage | |
* @property {(callback: () => void) => function } dispatchOnCheckAllPage | |
* @property {(callback: () => void) => function } dispatchOnUncheckAllPage | |
* @property {() => void } reset | |
* @return {CheckingAllPageAlertUI} | |
*/ | |
const CheckingAllPageAlertUI = () => { | |
const elem = document.querySelector(".check-all-alert"); | |
const stateEnum = { init: 0, checkable: 1, uncheckable: 2 }; | |
let state = stateEnum.init; | |
const _setState = (newState) => (state = newState); | |
const _onCheckHandlers = []; | |
const _onUncheckHandlers = []; | |
const dispatchOnCheckAllPage = (callback) => | |
_onCheckHandlers.push(callback); | |
const dispatchOnUncheckAllPage = (callback) => | |
_onUncheckHandlers.push(callback); | |
const _show = () => { | |
elem.classList.add("shown"); | |
elem.classList.remove("hidden"); | |
}; | |
const _hide = () => { | |
elem.classList.add("hidden"); | |
elem.classList.remove("shown"); | |
}; | |
const suggestCheckingAllPage = () => { | |
_show(); | |
_setState(stateEnum.checkable); | |
elem.innerText = `${ALL_COUNT}件すべてを選択`; | |
}; | |
const suggestUncheckingAllPage = () => { | |
_setState(stateEnum.uncheckable); | |
elem.innerText = "選択解除"; | |
}; | |
const _handleOnClick = () => { | |
switch (state) { | |
case stateEnum.checkable: | |
suggestUncheckingAllPage(); | |
_onCheckHandlers.forEach((callback) => callback()); | |
break; | |
case stateEnum.uncheckable: | |
_onUncheckHandlers.forEach((callback) => callback()); | |
_hide(); | |
break; | |
default: | |
void 0; | |
} | |
}; | |
const reset = () => { | |
_setState(stateEnum.init); | |
_hide(); | |
}; | |
elem.addEventListener("click", _handleOnClick); | |
return { | |
suggestCheckingAllPage, | |
suggestUncheckingAllPage, | |
dispatchOnCheckAllPage, | |
dispatchOnUncheckAllPage, | |
reset, | |
}; | |
}; | |
/** | |
* IdStorage | |
* @typedef {Object} IdStorage | |
* @property {(value: string) => boolean } isExists | |
* @property {() => void } reset | |
* @property {(value: string) => string[] } add | |
* @property {(value: string) => string[] } remove | |
* @property {() => number } getCount | |
* @return {IdStorage} | |
*/ | |
const IdStorage = () => { | |
let ids = | |
sessionStorage | |
.getItem("ids") | |
?.split(",") | |
.filter((id) => id !== "") || []; | |
const isExists = (id) => ids.includes(id); | |
const _save = () => { | |
sessionStorage.setItem("ids", ids); | |
console.log("ids", ids); | |
return ids; | |
}; | |
const reset = () => { | |
sessionStorage.removeItem("ids"); | |
}; | |
const add = (thisId) => { | |
if (!isExists(thisId)) ids = [thisId, ...ids]; | |
_save(); | |
}; | |
const remove = (thisId) => { | |
ids = ids.filter((id) => id !== thisId); | |
_save(); | |
}; | |
const getCount = () => { | |
return ids.length; | |
}; | |
return { reset, add, remove, isExists, getCount }; | |
}; | |
/** | |
* Initialization | |
*/ | |
// idStorage | |
const idStorage = IdStorage(); | |
// checkedCount | |
const checkedCount = CheckedCountUI(); | |
// checkAllBox | |
const checkAllBox = CheckAllBoxUI(); | |
// checkingAllPageAlert | |
const checkingAllPageAlert = CheckingAllPageAlertUI(); | |
// checkBoxes | |
const checkBoxes = Array.from( | |
document.querySelectorAll(".item-each-checkbox") | |
).map((elem) => { | |
const checkbox = CheckboxUI(elem); | |
// dispatching | |
checkbox.dispatchOnCheck((value) => { | |
idStorage.add(value); | |
checkedCount.render(idStorage.getCount()); | |
}); | |
checkbox.dispatchOnUncheck((value) => { | |
idStorage.remove(value); | |
checkedCount.render(idStorage.getCount().toString()); | |
checkAllBox.uncheck(); | |
checkingAllPageAlert.reset(); | |
}); | |
if (idStorage.isExists(checkbox.value)) checkbox.check(); | |
return checkbox; | |
}); | |
// dispatching | |
checkingAllPageAlert.dispatchOnCheckAllPage(() => { | |
checkedCount.render(ALL_COUNT); | |
}); | |
checkingAllPageAlert.dispatchOnUncheckAllPage(() => { | |
checkBoxes.forEach((checkbox) => checkbox.uncheck()); | |
}); | |
checkAllBox.dispatchOnCheck(() => { | |
checkBoxes.forEach((checkbox) => checkbox.check()); | |
checkingAllPageAlert.suggestCheckingAllPage(); | |
checkedCount.render(ALL_COUNT); | |
}); | |
checkAllBox.dispatchOnUncheck(() => { | |
checkBoxes.forEach((checkbox) => checkbox.uncheck()); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment