Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions examples/keyboard_navigation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<!--

Copyright (c) 2020, the Regular Table Authors.

This file is part of the Regular Table library, distributed under the terms of
the Apache License 2.0. The full license can be found in the LICENSE file.

-->

<!--

Explanation

-->

<!DOCTYPE html>
<html>

<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<script src="../dist/umd/regular-table.js"></script>
<link rel='stylesheet' href="../dist/css/material.css">
<style>
td {
outline: none;
border-right: 1px solid #eee;
border-bottom: 1px solid #eee;
min-width: 22px;
}
tbody th {
border-right: 1px solid #eee;
}
</style>
</head>

<body>
<regular-table></regular-table>

<script>
// Data Model
window.DATA = Array.from(Array(78).fill()).map(() => Array(100).fill());

window.DATA_COLUMN_NAMES = (() => {
const caps = Array.from(Array(26)).map((val, i) => String.fromCharCode(i + 65));
return caps.concat(
caps.map((letter) => letter + letter),
caps.map((letter) => letter + letter + letter)
);
})();

const num_rows = window.DATA[0].length;
const num_columns = window.DATA.length;

window.dataListener = function(x0, y0, x1, y1) {
return {
num_rows,
num_columns,
row_headers: Array.from(Array(Math.ceil(y1) - y0).keys()).map((y) => [`${y + y0}`]),
column_headers: window.DATA_COLUMN_NAMES.slice(x0, x1).map((x) => [x]),
data: window.DATA.slice(x0, x1).map((col) => col.slice(y0, y1)),
};
}
</script>

<script>

const table = document.getElementsByTagName("regular-table")[0];

let xIndex = 0;
let yIndex = 0;

// add click event in grid set x y

const updateFocus = () => {
const tds = table.querySelectorAll("regular-table tbody tr td");
for (const td of tds) {
td.setAttribute("contenteditable", true); // TODO css style
const meta = table.getMeta(td);
if (meta.x === xIndex && meta.y === yIndex) {
td.focus();
} else {
td.blur();
}
}
}

// TODO split function
function step(active_cell, dx, dy) {

// TODO - this shouldn't be!
const scrollStep = 4; // if scroll * 2 > num rows or columns theres a problem
const meta = table.getMeta(active_cell);

if (meta.x + dx < num_columns && 0 <= meta.x + dx) {
xIndex = meta.x + dx;
}
if (dx !== 0) {
// scroll x axis if necessary
const columns = table.querySelectorAll("regular-table tbody tr:first-child td");
if (meta.x0 + columns.length <= xIndex + scrollStep) {
table.scrollTo(meta.x0 + 2, meta.y0, num_columns, num_rows);
} else if (xIndex - scrollStep < meta.x0) {
if (0 < meta.x0 - 1) {
table.scrollTo(meta.x0 - 1, meta.y0, num_columns, num_rows);
} else {
table.scrollTo(0, meta.y0, num_columns, num_rows);
}
}
}

if (meta.y + dy < num_rows && 0 <= meta.y + dy) {
yIndex = meta.y + dy;
}
if (dy !== 0) {
// scroll y axis if necessary
const rows = table.querySelectorAll("regular-table tbody tr");
if (meta.y0 + rows.length <= yIndex + scrollStep) {
table.scrollTo(meta.x0, meta.y0 + 1, num_columns, num_rows);
} else if (yIndex - scrollStep + 2 < meta.y0) {
if (0 < meta.y0 - 1) {
table.scrollTo(meta.x0, meta.y0 - 1, num_columns, num_rows);
} else {
table.scrollTo(meta.x0, 0, num_columns, num_rows);
}
}
}
updateFocus();
}

table.setDataListener(window.dataListener);

table.addStyleListener(updateFocus);

table.addEventListener("keydown", (event) => {
const target = document.activeElement;
switch (event.keyCode) {
// left arrow
case 37:
step(target, -1, 0);
break;
// up arrow
case 38:
step(target, 0, -1);
break;
// right arrow
case 39:
step(target, 1, 0);
break;
// down arrow
case 40:
step(target, 0, 1);
break;
}
});

table.draw();
</script>
</body>

</html>
87 changes: 77 additions & 10 deletions examples/spreadsheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,24 @@ function compile(input) {
## User Interaction

```javascript
table.addStyleListener(() => {
for (const td of table.querySelectorAll("td")) {
let xIndex = 0;
let yIndex = 0;

const updateFocus = () => {
const tds = table.querySelectorAll("regular-table tbody tr td");
for (const td of tds) {
td.setAttribute("contenteditable", true);
const meta = table.getMeta(td);
if (meta.x === xIndex && meta.y === yIndex) {
td.focus();
} else {
// console.error("blur here?");
// td.blur();
}
}
});
};

table.addStyleListener(updateFocus);

table.draw();
```
Expand Down Expand Up @@ -181,7 +194,7 @@ table.addEventListener("keypress", (event) => {
if (event.keyCode === 13) {
event.preventDefault();
write(target);
increment(target);
step(target, 0, 1);
}
});

Expand All @@ -191,20 +204,74 @@ table.addEventListener("keyup", (event) => {
highlight(target);
}
});

table.addEventListener("keydown", (event) => {
const target = document.activeElement;
switch (event.keyCode) {
// left arrow
case 37:
step(target, -1, 0);
break;
// up arrow
case 38:
step(target, 0, -1);
break;
// right arrow
case 39:
step(target, 1, 0);
break;
// down arrow
case 40:
step(target, 0, 1);
break;
}
});
```

This also makes use of `increment()`, which uses some simple metadata-math
to look up the cell in the next row of this column, and `focus()` it.

```javascript
function increment(active_cell) {
// TODO split function
function step(active_cell, dx, dy) {
// TODO - this shouldn't be!
const scrollStep = 2; // if scroll * 2 > num rows or columns theres a problem
const meta = table.getMeta(active_cell);
const rows = Array.from(table.querySelectorAll("tbody tr"));
const next_row = rows[meta.y - meta.y0 + 1];
if (next_row) {
const td = next_row.children[meta.x + 1];
td.focus();

if (meta.x + dx < NUM_COLUMNS && 0 <= meta.x + dx) {
xIndex = meta.x + dx;
}
if (dx !== 0) {
// scroll x axis if necessary
const columns = table.querySelectorAll("regular-table tbody tr:first-child td");
Comment thread
JHawk marked this conversation as resolved.
if (meta.x0 + columns.length <= xIndex + scrollStep) {
table.scrollTo(meta.x0 + 2, meta.y0, NUM_COLUMNS, NUM_ROWS);
} else if (xIndex - scrollStep < meta.x0) {
if (0 < meta.x0 - 1) {
table.scrollTo(meta.x0 - 1, meta.y0, NUM_COLUMNS, NUM_ROWS);
} else {
table.scrollTo(0, meta.y0, NUM_COLUMNS, NUM_ROWS);
}
}
}

if (meta.y + dy < NUM_ROWS && 0 <= meta.y + dy) {
yIndex = meta.y + dy;
}
if (dy !== 0) {
// scroll y axis if necessary
const rows = table.querySelectorAll("regular-table tbody tr");
if (meta.y0 + rows.length <= yIndex + scrollStep) {
table.scrollTo(meta.x0, meta.y0 + 1, NUM_COLUMNS, NUM_ROWS);
} else if (yIndex - scrollStep + 2 < meta.y0) {
if (0 < meta.y0 - 1) {
table.scrollTo(meta.x0, meta.y0 - 1, NUM_COLUMNS, NUM_ROWS);
} else {
table.scrollTo(meta.x0, 0, NUM_COLUMNS, NUM_ROWS);
}
}
}
updateFocus();
}
```

Expand Down