Skip to content

Instantly share code, notes, and snippets.

@aq2bq
Last active January 27, 2022 05:07
Show Gist options
  • Save aq2bq/573ec8a6933d2e2226961d27ee333288 to your computer and use it in GitHub Desktop.
Save aq2bq/573ec8a6933d2e2226961d27ee333288 to your computer and use it in GitHub Desktop.
bulk-checking.js
<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>
<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>
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