<!DOCTYPE html>
|
<html>
|
<head>
|
<meta charset="utf-8">
|
<title>Test Cell Editors</title>
|
<meta name="viewport" content="width=570">
|
<style>
|
@import "../../dojo/resources/dojo.css";
|
@import "../css/dgrid.css";
|
@import "../../dijit/themes/claro/claro.css";
|
@import "../css/skins/claro.css";
|
|
.heading {
|
font-weight: bold;
|
padding-bottom: 0.25em;
|
}
|
|
#grid {
|
margin: 10px;
|
height: 15em;
|
width: 500px;
|
}
|
|
.outer {
|
border: 1px solid #333;
|
padding: 0 4px;
|
}
|
|
.rendercell {
|
background-color: #ccf;
|
}
|
|
.formatter {
|
background-color: #cfc;
|
}
|
</style>
|
<script src="../../dojo/dojo.js"
|
data-dojo-config="async: true, isDebug: true"></script>
|
<script>
|
var grid, // stores global reference to grid instance
|
editFirst; // function defined within require callback
|
|
require(["dgrid/OnDemandGrid", "dgrid/Selection", "dgrid/Keyboard", "dgrid/Editor",
|
"dojo/_base/lang", "dojo/_base/declare", "dojo/on", "dojo/dom-construct",
|
"dojo/store/Memory", "dstore/Memory", "dstore/Trackable", "dojo/data/ObjectStore",
|
"dgrid/test/data/createAsyncStore", "dojo/domReady!"
|
], function(Grid, Selection, Keyboard, Editor, lang, declare, on, domConstruct, LegacyMemory, Memory, Trackable, ObjectStore, createAsyncStore){
|
var today = new Date(),
|
form = document.getElementById("editorForm"),
|
typesArea = document.getElementById("editorComponentTypes"),
|
optionsData = [
|
{ id: "1", name: "one" },
|
{ id: "2", name: "two" },
|
{ id: "3", name: "three" },
|
{ id: "4", name: "four" },
|
{ id: "5", name: "five" }
|
],
|
optionsLength = optionsData.length,
|
optionsStore = new LegacyMemory({ data: optionsData }),
|
optionsDataStore = new ObjectStore({
|
objectStore: optionsStore,
|
labelProperty: "name"
|
}),
|
CustomGrid = declare([Grid, Selection, Keyboard, Editor]),
|
TestStoreMixin = declare(null, {
|
put: function(object, options){
|
console.log("put called for ID: ", object.id, object);
|
return this.inherited(arguments);
|
}
|
}),
|
TestStore = declare([ Memory, Trackable, TestStoreMixin ]),
|
// define choices of component type which will be available in form
|
componentTypes = [
|
// native input types
|
{ label: "text", generate: generateText },
|
{ label: "checkbox", generate: generateBool },
|
{ label: "radio", generate: generateBoolRadio },
|
{
|
label: "textarea",
|
generate: generateText,
|
column: { editorArgs: { rows: 3 } }
|
},
|
// TODO: support select?
|
// Dijits
|
{ label: "dijit/form/TextBox", generate: generateText },
|
{ label: "dijit/form/SimpleTextarea", generate: generateText },
|
{
|
label: "dijit/form/CheckBox",
|
generate: generateBool,
|
// Dijit's CheckBox is a bit special, in that value reports
|
// a string value if checked, but false if unchecked.
|
column: {
|
editorArgs: { value: "enabled" },
|
get: function(item){
|
// ensure initial rendering matches up with widget behavior
|
return item.editor ? "enabled" : false;
|
},
|
set: function(item){
|
// convert to boolean for save
|
return !!item.editor;
|
}
|
}
|
},
|
{
|
label: "dijit/form/ValidationTextBox",
|
generate: generateText,
|
column: { editorArgs: { required: true } }
|
},
|
{
|
label: "dijit/form/NumberSpinner",
|
generate: generateNumber,
|
column: { editorArgs: { constraints: { min: 0 } } }
|
},
|
{
|
label: "dijit/form/DateTextBox",
|
generate: generateDate,
|
renderCell: function(object, value){
|
var div = document.createElement("div");
|
div.appendChild(document.createTextNode(value ? value.toString() : "No Date"));
|
return div;
|
}
|
},
|
{
|
label: "dijit/form/HorizontalSlider",
|
generate: generateNumber,
|
column: { editorArgs: { minimum: 0, maximum: 1000 } }
|
},
|
{
|
label: "dijit/form/FilteringSelect",
|
generate: generateOptionValue,
|
column: { editorArgs: { store: optionsStore } }
|
},
|
{
|
label: "dijit/form/Select",
|
generate: generateOptionValue,
|
column: { editorArgs: {
|
store: optionsDataStore,
|
// need to set width directly for Select to size correctly
|
style: { width: "99%" }
|
} }
|
},
|
{
|
label: "text input combining first/last name",
|
editor: "text",
|
generate: generateName,
|
column: {
|
get: function(object){
|
return object.firstName + " " + object.lastName;
|
},
|
set: function(object){
|
// Recombine to single field, and remove our combined field.
|
// Admittedly, this won't treat middle names very nicely.
|
var parts = object.editor.split(/ +/, 2);
|
object.firstName = parts[0];
|
object.lastName = parts[1];
|
delete object.editor;
|
}
|
}
|
},
|
{
|
label: "dijit/form/TextBox converting to uppercase on save",
|
editor: "dijit/form/TextBox",
|
generate: generateTextUC,
|
column: {
|
set: function(object){
|
return object.editor.toUpperCase();
|
}
|
}
|
}
|
],
|
optStr = "",
|
i;
|
|
// data generation functions used for populating store data,
|
// used by different componentTypes
|
function generateText(){
|
return { editor: "generated text " + Math.floor(Math.random() * 1000) };
|
}
|
|
function generateNumber(){
|
return { editor: Math.floor(Math.random() * 1000) };
|
}
|
|
function generateBool(){
|
return { editor: Math.random() > 0.5 ? true : false };
|
}
|
|
function generateBoolRadio(i){
|
// Variant of generateBool that only returns true for i = 0
|
return { editor: !i };
|
}
|
|
function generateDate(){
|
// return a date within the past year
|
return { editor: new Date(today - Math.random() * 31536000000) };
|
}
|
|
function generateOptionValue(){
|
return { editor: optionsData[Math.floor(Math.random() * optionsLength)].id };
|
}
|
|
function generateTextUC(){
|
return { editor: "GENERATED TEXT " + Math.floor(Math.random() * 1000) };
|
}
|
|
function generateName(){
|
// returns an item with firstName and lastName fields,
|
// for testing a more complex scenario with a column.set function.
|
return {
|
firstName: ["John", "Jane"][Math.floor(Math.random() * 2)],
|
lastName: ["Doe", "Smith"][Math.floor(Math.random() * 2)]
|
};
|
}
|
|
function getSelected(select){
|
var options = select.options,
|
i;
|
for(i = options.length; i--;){
|
if(options[i].selected){
|
return options[i].value;
|
}
|
}
|
}
|
|
function customRenderCell(object, data){
|
var container = domConstruct.create("div", { "class": "outer" });
|
domConstruct.place('<span class="rendercell">' +
|
("" + data).replace(/</g, "<") + "</span>", container);
|
return container;
|
}
|
|
function customFormatter(data){
|
return '<div class="outer"><span class="formatter">' +
|
("" + data).replace(/</g, "<") + "</span></div>";
|
}
|
|
var cancelDataChange = false;
|
form.onsubmit = function(){
|
var
|
choice = getSelected(form.elements.editor),
|
options = componentTypes[choice],
|
editorType = options.editor || options.label,
|
editOn = getSelected(form.elements.editOn),
|
deps = editorType.indexOf("/") > -1 ? [editorType] : [],
|
data = [],
|
async = form.elements.async.checked,
|
store,
|
i;
|
|
for(i = 0; i < 200; i++){
|
data.push(lang.mixin(options.generate(i), { id: i }));
|
}
|
|
store = async ?
|
createAsyncStore({ data: data, delay: 100 }, TestStoreMixin) :
|
new TestStore({ data: data });
|
|
require(deps, function(ctor){
|
var columnArgs = {
|
autoSelect: form.elements.autoSelect.checked,
|
autoSave: form.elements.autoSave.checked,
|
editor: ctor || editorType
|
};
|
|
if(editOn){
|
columnArgs.editOn = editOn;
|
}
|
|
if(form.elements.customRenderCell.checked){
|
columnArgs.renderCell = customRenderCell;
|
}else if(options.renderCell){
|
columnArgs.renderCell = options.renderCell;
|
}
|
|
if(form.elements.customFormatter.checked){
|
columnArgs.formatter = customFormatter;
|
}
|
cancelDataChange = form.elements.cancelDataChange.checked;
|
|
if(!grid){
|
grid = new CustomGrid({
|
collection: store,
|
columns: {
|
editor: lang.mixin({}, options.column, columnArgs)
|
},
|
farOffRemoval: async ? 400 : Infinity
|
}, "grid");
|
}else{
|
// instead of destroying/recreating, just reset store + columns
|
grid.set("collection", null);
|
grid.set("columns", {
|
editor: lang.mixin({}, options.column, columnArgs)
|
});
|
grid.set("collection", store);
|
}
|
});
|
|
return false;
|
};
|
|
// generate radios in editorComponentTypes div
|
for(i in componentTypes){
|
optStr += '<option value="' + i + '">' + componentTypes[i].label + "</option>";
|
}
|
domConstruct.place('<select name="editor">' + optStr + "</select>", typesArea);
|
|
on(document.body, "dgrid-datachange", function(evt){
|
console.log(evt.grid.id + " row " + evt.cell.row.id + " data changed" +
|
(evt.parentType ? " (via " + evt.parentType + "): " : ": "),
|
evt.oldValue, " -> ", evt.value);
|
|
if(cancelDataChange){
|
evt.preventDefault();
|
}
|
});
|
|
on(document.body, "dgrid-editor-show", function(evt){
|
console.log("show editOn editor: ", evt);
|
});
|
on(document.body, "dgrid-editor-hide", function(evt){
|
console.log("hide editOn editor: ", evt);
|
});
|
|
editFirst = function(){
|
var grid = window.grid;
|
window.grid.edit(window.grid.cell(0, "editor"));
|
};
|
});
|
</script>
|
</head>
|
<body class="claro">
|
<h2>Testing Editors</h2>
|
(Testing editors using Dijit widgets requires the dijit package to be installed)
|
<form id="editorForm">
|
<p><label>Component type:
|
<span id="editorComponentTypes"></span>
|
</label></p>
|
|
<p><label>editOn:
|
<select name="editOn">
|
<option value="" selected>none (always on)</option>
|
<option value="click">click</option>
|
<option value="dblclick">double-click</option>
|
<option value="dgrid-cellfocusin">dgrid-cellfocusin</option>
|
</select>
|
</label></p>
|
<p><label><input type="checkbox" name="autoSave" value="true"> autoSave</label></p>
|
|
<p><label><input type="checkbox" name="cancelDataChange" value="false"> cancel dgrid-datachange</label></p>
|
|
<p><label><input type="checkbox" name="customRenderCell" value="true"> use custom renderCell</label></p>
|
|
<p><label><input type="checkbox" name="customFormatter" value="true"> use custom formatter
|
(note: customRenderCell supersedes this setting)</label></p>
|
|
<p><label><input type="checkbox" name="autoSelect" value="true"> automatically select text (textbox-based editors only)</label></p>
|
|
<p><label><input type="checkbox" name="async" value="true"> use async store</label></p>
|
|
<div>
|
<button type="submit" id="editorFormSubmit">Recreate Grid</button>
|
</div>
|
</form>
|
<div id="grid"></div>
|
<button type="button" onclick="grid.save();">Save</button>
|
<button type="button" onclick="grid.revert();">Revert</button>
|
<button type="button" onclick="editFirst();">Edit first cell</button>
|
</body>
|
</html>
|