はじめに
checkboxをページ間で保持する場合のイメージを記載する。
内容
以下javascriptで行う。
・ボタンを動的に作成
・チェックボックスを動的に作成
・ページ送り時のチェックボックスの保持
・ボタン押すと、checkした箇所のidを取得する
以下を考慮
ページ送りで以下が発生する。
・チェックしたものが戻るとチェックされていない
・ボタン、チェックボックスが増える。
そのために以下を行う。
・チェックボックスをページ送りで保持する方法として「セッションストレージ」を使用。
・作成のタイミングを考慮
jsでボタン等作成する時、
複雑な箇所はinnerHTMLで行えばよい
tr.innerHTML = `<td>${i + 1}</td><td class="checkbox-cell"></td>`;
ただし、要素を直接操作するばあい、document.createElement などを使用する。
以下をベースに付与していく
var checkbox = document.createElement('input');
チェックボックスを変更したときという処理ができる。
checkbox.addEventListener('change', function(e){});
ソース例
実際に動かさないと理解できない場合、以下を動かしてみる。
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>チェックボックスのサンプル</title>
<style>
.hidden {
display: none;
}
</style>
</head>
<body>
<!-- IDを取得するボタン -->
<table>
<thead>
<tr>
<th>ID</th>
<th>チェックボックス</th>
</tr>
</thead>
<tbody>
<!-- JavaScriptでデータを動的に挿入 -->
</tbody>
</table>
<button id="prevButton">前へ</button>
<button id="nextButton">次へ</button>
<script src="script.js"></script>
</body>
</html>
script.js
const itemsPerPage = 15;
let currentPage = 1;
let totalPages = 4; // 50件を20件ずつ表示するためのページ数
//ただのメモ
const now = new Date();
const y = now.getFullYear().toString().slice(-2);
const m = ('0' + (now.getMonth() + 1)).slice(-2);
const d = ('0' + now.getDate()).slice(-2);
const H = ('0' + now.getHours()).slice(-2);
const i = ('0' + now.getMinutes()).slice(-2);
const s = ('0' + now.getSeconds()).slice(-2);
const formattedDate = `${y}${m}${d}_${H}${i}${s}`;
console.log(formattedDate);
function renderPage(page) {
const tbody = document.querySelector('tbody');
tbody.innerHTML = ''; // 既存のデータをクリア
const start = (page - 1) * itemsPerPage;
const end = start + itemsPerPage;
for (let i = start; i < end && i < 50; i++) {
const tr = document.createElement('tr');
tr.innerHTML = `<td>${i + 1}</td><td class="checkbox-cell"></td>`;
tbody.appendChild(tr);
}
// 一覧画面のチェックボックスの処理
var checkboxCells = document.querySelectorAll('.checkbox-cell');
checkboxCells.forEach(function(cell, index) {
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.className = 'customCheckbox';
var recordId = cell.parentElement.querySelector('td:first-child').textContent;
checkbox.dataset.recordId = recordId;
var storedState = sessionStorage.getItem('checkbox-' + recordId);
if (storedState === null) {
checkbox.checked = false;
} else {
checkbox.checked = (storedState === 'true');
}
checkbox.addEventListener('change', function(e) {
sessionStorage.setItem('checkbox-' + e.target.dataset.recordId, e.target.checked);
});
cell.appendChild(checkbox);
});
}
window.addEventListener('beforeunload', function() {
sessionStorage.clear();
});
document.getElementById('prevButton').addEventListener('click', function() {
if (currentPage > 1) {
currentPage--;
renderPage(currentPage);
}
});
document.getElementById('nextButton').addEventListener('click', function() {
if (currentPage < totalPages) {
currentPage++;
renderPage(currentPage);
}
});
/// ボタンを動的に作成する関数
function createGetCheckedIdsButton() {
const btn = document.createElement("button");
btn.innerHTML = "チェックされたIDを取得";
btn.id = "getCheckedIds";
btn.addEventListener("click", function() {
const checkedIds = [];
// セッションストレージのキーをループして、'checkbox-'で始まるキーを検索
for (let i = 0; i < sessionStorage.length; i++) {
const key = sessionStorage.key(i);
if (key.startsWith('checkbox-') && sessionStorage.getItem(key) === 'true') {
const recordId = key.replace('checkbox-', '');
checkedIds.push(recordId);
}
}
console.log(checkedIds);
alert('チェックされたID: ' + checkedIds.join(', '));
});
document.body.insertBefore(btn, document.querySelector('table'));
}
// ページが読み込まれたときの処理
window.onload = function() {
createGetCheckedIdsButton();
// セッションストレージのデータを全て削除
sessionStorage.clear();
// ... その他の処理 ...
};
// 初期表示
renderPage(currentPage);
document.getElementById('getCheckedIds').addEventListener('click', function() {
// const checkedCheckboxes = document.querySelectorAll('input.customCheckbox:checked');
// const checkedIds = [];
// checkedCheckboxes.forEach(function(checkbox) {
// checkedIds.push(checkbox.dataset.recordId);
// });
const checkedIds = [];
// セッションストレージのキーをループして、'checkbox-'で始まるキーを検索
for (let i = 0; i < sessionStorage.length; i++) {
const key = sessionStorage.key(i);
if (key.startsWith('checkbox-') && sessionStorage.getItem(key) === 'true') {
const recordId = key.replace('checkbox-', '');
checkedIds.push(recordId);
}
}
console.log(checkedIds);
alert('チェックされたID: ' + checkedIds.join(', '));
});
その他メモ
kintoneの場合
ボタン、チェックボタンが増えないようにする。
・id、classを付与し、同じものがあれば処理を進めないようにする。
kintone.events.on('app.record.index.show', function(event) {
const btn = createGetCheckedIdsButton(event);
document.body.insertBefore(btn, document.querySelector('table'));
createCheckboxInTable();
sessionStorage.clear();
return event;
});
function createGetCheckedIdsButton(event) {
if (document.getElementById("getCheckedIds")) {
return; // ボタンがすでに存在する場合は関数を終了
}
const btn = document.createElement("button");
btn.innerHTML = "チェックされたIDを取得";
btn.id = "getCheckedIds";
btn.addEventListener("click", function() {
const checkedIds = [];
for (let i = 0; i < sessionStorage.length; i++) {
const key = sessionStorage.key(i);
if (key.startsWith('checkbox-') && sessionStorage.getItem(key) === 'true') {
const recordId = key.replace('checkbox-', '');
checkedIds.push(recordId);
}
}
console.log(checkedIds);
alert('チェックされたID: ' + checkedIds.join(', '));
});
return btn;
}
function createCheckboxInTable() {
let table = document.getElementsByClassName("recordlist-data")[0];
// 既にヘッダーにチェックボックス部分があるか確認
if (!table.tHead.querySelector('.custom-checkbox-header')) {
let headerCell = document.createElement('th');
headerCell.className = 'recordlist-header-cell custom-checkbox-header'; // クラスを追加
headerCell.style.width = '30px';
headerCell.appendChild(document.createTextNode('チェックボックス'));
table.tHead.insertBefore(headerCell, table.tHead.children[1]);
}
for (let i = 0; i < table.rows.length; i++) {
if (table.tBodies[0].rows[i].querySelector('.custom-checkbox-cell')) {
continue; // 既にチェックボックスが存在する行はスキップ
}
let recordId = table.tBodies[0].rows[i].querySelector('.recordlist-cell').textContent;
let cell = table..tBodies[0].rows[i].insertCell(1);
cell.className = 'recordlist-cell custom-checkbox-cell'; // クラスを追加
let checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.value = '0';
let storedState = sessionStorage.getItem('checkbox-' + recordId);
checkbox.checked = (storedState === 'true');
checkbox.addEventListener('change', function() {
sessionStorage.setItem('checkbox-' + recordId, this.checked);
});
let wrapper = document.createElement('div');
wrapper.style.textAlign = 'center';
wrapper.appendChild(checkbox);
cell.appendChild(wrapper);
}
}
ボタンが複数の時の対応
function createButton(buttonId, buttonText, actionFunction, kintoneEvent) {
const btn = document.createElement("button");
btn.id = buttonId;
btn.innerHTML = buttonText;
btn.addEventListener("click", function(clickEvent) {
actionFunction(clickEvent, kintoneEvent); // kintoneのイベントも引数として渡す
});
document.body.insertBefore(btn, document.querySelector('table'));
}
// ボタンをクリックしたときの動作を定義
function actionForButton1(clickEvent, kintoneEvent) {
// ここでclickEventとkintoneEventを使用する
// 例えば、kintoneEventの中の情報や、clickEventの情報を使って処理を行う
}
function actionForButton2() {
console.log('ボタン2がクリックされました');
// その他の処理...
}
function actionForButton3() {
console.log('ボタン3がクリックされました');
// その他の処理...
}
// ボタンの作成
// kintoneのイベントハンドラ
kintone.events.on('app.record.index.show', function(event) {
createButton("button1", "ボタン1のテキスト", actionForButton1, event);
createButton("button2", "ボタン2のテキスト", actionForButton2);
createButton("button3", "ボタン3のテキスト", actionForButton3);
return event;
});