|
<!doctype html> |
|
<meta charset="utf-8" /> |
|
<link rel="stylesheet" type="text/css" href="https://npmcdn.com/[email protected]"> |
|
|
|
|
|
|
|
<style> |
|
.external-editor { |
|
display: none; |
|
} |
|
|
|
.external-editor.is-editing { |
|
display: block; |
|
} |
|
|
|
.external-editor.is-invalid { |
|
background-color: red; |
|
color: white; |
|
} |
|
|
|
.external-editor-placeholder { |
|
width: 100%; |
|
height: 100%; |
|
position: absolute; |
|
left: 0; |
|
padding-left: 8px; |
|
padding-right: 8px; |
|
padding-top: 2px; |
|
background-color: magenta; |
|
color: white; |
|
} |
|
|
|
</style> |
|
|
|
<div class="grid-target"></div> |
|
|
|
<section class="external-editor"> |
|
<h2 class="title">some custom external editor</h2> |
|
<p> |
|
<input type="text" id="username" placeholder="ok"></input> |
|
</p> |
|
</section> |
|
|
|
<script src="https://npmcdn.com/[email protected]"></script> |
|
<script src="https://npmcdn.com/[email protected]/faker.js"></script> |
|
<script src="https://d3js.org/d3.v4.js"></script> |
|
<script src="https://npmcdn.com/@zambezi/[email protected]"></script> |
|
<script src="https://npmcdn.com/@zambezi/[email protected]"></script> |
|
<script src="https://npmcdn.com/@zambezi/[email protected]"></script> |
|
<script src="https://npmcdn.com/@zambezi/[email protected]"></script> |
|
<script> |
|
|
|
var table = grid.createGrid() |
|
.columns( |
|
[ |
|
{ key: 'name', locked: 'left', width: 200 } |
|
, { |
|
key: 'username' |
|
, components: [ |
|
gridComponents.createEditCell() |
|
.component(createExternalEditor()) |
|
.on('change', onUsernameChange) |
|
.on('validationerror', console.error.bind(console, 'VALIDATION')) |
|
.on('editstart', d => console.debug('edit start', d)) |
|
.on('editend', d => console.debug('edit end', d)) |
|
.validate(validateUserName) |
|
.editable(isNotZack) |
|
|
|
, grid.updateTextIfChanged |
|
] |
|
} |
|
, { key: 'email', sortDescending: true } |
|
, { key: 'phone' } |
|
] |
|
) |
|
, rows = _.range(1, 2000).map(faker.Helpers.createCard) |
|
|
|
d3.select('.grid-target') |
|
.style('height', '300px') |
|
.datum(rows) |
|
.call(table) |
|
|
|
function onUsernameChange(row, value) { |
|
row.username = value.toUpperCase() |
|
} |
|
|
|
function validateUserName(row, value) { |
|
if (!value) return 'Username cannot be empty' |
|
if (!value.split('').some(isDifferentCharacter())) return 'Cannot all be the same character' |
|
} |
|
|
|
function isDifferentCharacter() { |
|
let found |
|
return function check(ch) { |
|
if (found && !~found.indexOf(ch)) return true |
|
found = ch |
|
return false |
|
} |
|
} |
|
|
|
function onUsernameChange(row, value) { |
|
row.username = value.toUpperCase() |
|
} |
|
|
|
function validateUserName(row, value) { |
|
if (!value) return 'Username cannot be empty' |
|
if (!value.split('').some(isDifferentCharacter())) return 'Cannot all be the same character' |
|
} |
|
|
|
function isNotZack(cell) { |
|
return cell.row.username.indexOf('Zac') !== 0 |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// On some other module somewhere, something like this is defined, |
|
|
|
function createExternalEditor() { |
|
|
|
const dispatch = d3.dispatch('partialedit', 'commit', 'cancel') |
|
, api = d3Utils.rebind().from(dispatch, 'on') |
|
|
|
function externalEditor(s) { |
|
s.each(externalEditorEach) |
|
} |
|
|
|
return api(externalEditor) |
|
|
|
function externalEditorEach(d, i) { |
|
|
|
console.debug('externalEditorEach', d, i) |
|
|
|
const target = d3.select(this).text('EDITING EXTERNALLY') |
|
.classed('external-editor-placeholder', true) |
|
, { column, row, isValidInput } = d |
|
|
|
, form = d3.select('.external-editor') |
|
.datum(d) |
|
.classed('is-editing', true) |
|
.classed('is-invalid', !isValidInput) |
|
|
|
, title = form.select('.title') |
|
.text(`edit ${column.id} currently «${column.value(row)}»`) |
|
, input = form.select('[type=text]') |
|
.property('value', d.tempInput || column.format(column.value(row))) |
|
.on('input', onInput) |
|
.on('change', commit) |
|
.on('blur', commit) |
|
.each(focus) |
|
|
|
function onInput(d, i) { |
|
dispatch.call('partialedit', this, d) |
|
} |
|
|
|
function focus() { |
|
this.focus() |
|
} |
|
|
|
function commit() { |
|
dispatch.call('commit', this, d) |
|
form.classed('is-editing', false) |
|
} |
|
} |
|
} |
|
|
|
</script> |