Skip to content

Instantly share code, notes, and snippets.

@nohuhu
Created January 30, 2020 01:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nohuhu/01a7bb42b1c1e1378ea0df6829799055 to your computer and use it in GitHub Desktop.
Save nohuhu/01a7bb42b1c1e1378ea0df6829799055 to your computer and use it in GitHub Desktop.
Statium computed table example
import React from 'react';
import ViewModel, { Bind } from 'statium';
const Store = () => (
<ViewModel initialState={{
loading: true,
records: [],
}}
controller={{
initialize: load,
handlers: {
load,
},
}}>
<Table />
</ViewModel>
);
const Table = () => (
<ViewModel initialState={{
filter: '',
page: 0,
limit: 100,
}}
formulas={{
values: filteredValues,
}}>
<Bind props={['loading', 'values', ['filter', true], ['page', true], ['limit', true]]}
controller>
{ ({ loading, values, filter, setFilter, page, setPage, limit, setLimit },
{ $dispatch }) => (
<div>
<button disabled={!!loading}
onClick={e => { $dispatch('load') }}>
Load records
</button>
<div>Filtered record count: {values.length}</div>
<div>
<label>
Filter students by name:
<input value={filter}
onChange={e => { setFilter(e.target.value); }} />
</label>
<label>
# records to display:
<input value={limit}
onChange={e => { setLimit(Number(e.target.value)); }} />
</label>
</div>
<table>
<thead>
<tr>
<th style={{ padding: "0 20px" }}>id</th>
<th style={{ padding: "0 20px" }}>student name</th>
<th style={{ padding: "0 20px" }}>100m time</th>
</tr>
</thead>
<tbody>
{ values.slice(page * limit, page * limit + limit)
.map(record => (
<tr key={record.id}>
<td style={{ padding: "0 20px" }}>{record.id}</td>
<td style={{ padding: "0 20px" }}>{record.name}</td>
<td style={{ padding: "0 20px" }}>{record.result}</td>
</tr>
))}
</tbody>
</table>
<div>Page:</div>
<div style={{ display: "flex", flexWrap: "wrap" }}>
{ [...Array(Math.ceil(values.length / limit))].map((_, idx) => (
<a key={idx} href="#"
style={{ padding: "8px" }}
onClick={e => {
e.preventDefault();
setPage(idx);
}}>
<span>
{idx + 1} &nbsp;
</span>
</a>
))}
</div>
</div>
)}
</Bind>
</ViewModel>
);
const load = async ({ $set }) => {
const records = [...Array(10000)].map((_, idx) => ({
id: idx,
name: `Student ${idx + 1}`,
result: Math.round(Math.random() * 100),
}));
await $set({
records,
loading: false,
});
};
const filteredValues = $get => {
const records = $get('records');
const filter = $get('filter');
if (!filter) {
return records;
}
const regex = new RegExp(filter);
return records.filter(record => regex.test(record.name));
};
export default Store;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment