Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Advance Row Selection - Extension #829

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
10 changes: 9 additions & 1 deletion Selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,15 @@ return declare(null, {
}
this._fireSelectionEvents();
},

selectInverse: function() {
if (this.allSelected) {
this.clearSelection();
} else {
for (var each in this._rowIdToObject) {
this.select(this._rowIdToObject[each], null, null)
}
}
},
isSelected: function(object){
// summary:
// Returns true if the indicated row is selected.
Expand Down
12 changes: 10 additions & 2 deletions extensions/ColumnResizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,16 @@ function resizeColumnWidth(grid, colId, width, parentType){
if(width === "auto"){
delete column.width;
}else{
column.width = width;
width += "px";
// while using columnResizer and advanceRowSelection together, on resizing
// columns it gives an error Cannot set property 'width' of undefined,
// Added if condition when column is undefined then not to update column width.
// This extension consider columns created for placing Select All/Inverse/None Buttons
// as grid's column because they all share same class name. But we don't need
// to make them resizable atleast for now.
if(column) {
column.width = width;
width += "px";
}
}

rule = grid._columnSizes[colId];
Expand Down
196 changes: 196 additions & 0 deletions extensions/advanceSelection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
define(["dojo/_base/declare", "dojo/html", "dojo/has", "dojo/dom-construct", "dijit/form/Button", "put-selector/put", "dojo/on"], function(
declare, html, has, domConstruct, Button, put, on) {
/*
* Advance Row Selection plugin for dgrid
* Originally contributed by RCorp(Ramanan Corporation, India) 2013-11-27
*
*/

var invalidClassChars = /[^\._a-zA-Z0-9-]/g;
var contentBoxSizing = has("ie") < 8 && !has("quirks");
return declare(null, {
constructor: function() {
// selectAllButton: widget Button
// Button widget to select All
this.selectAllButton = '';

// hiderMenuNode: widget Button
// Button widget to de-select All.
this.selectNoneButton = '';

// hiderMenuNode: widget Button
// Button widget to inverse selection.
this.selectInverseButton = '';

// seletorNode: DOMNode
// The node for the placement of selection Buttons.
this.selectorNode = '';
},
renderHeader: function() {
// summary:
// override the Grid's renderHeader function
this.inherited(arguments);
headerNode = this.headerNode

var row = this.createButtonRowCells("th", function(th, column) {
var contentNode = column.headerNode = th;
if (contentBoxSizing) {
// we're interested in the th, but we're passed the inner div
th = th.parentNode;
}
var field = column.field;
if (field) {
th.field = field;
}
// allow for custom header content manipulation
if (column.renderHeaderCell) {
// appendIfNode(contentNode, column.renderHeaderCell(contentNode));
} else if (column.label || column.field) {
contentNode.appendChild(document.createTextNode(column.label || column.field));
}
if (column.sortable !== false && field && field != "_item") {
th.sortable = true;
th.className += " dgrid-sortable";
}
}, this.subRows && this.subRows.headerRows);

row.id = this.id + "-header-filterable";
this._rowIdToObject[row.id = this.id + "-header-filterable"] = this.columns;
headerNode.appendChild(row);
var trTag = ''
if ((has("ie") < 9 || has("quirks"))) {
// because of tBody Tag, get children of children
trTag = row.children[0].children[0]
} else {
trTag = row.children[0];
}
this.selectorNode = trTag;

// first Cell
this._createSelectAllButton();
// second Cell
this._createSelectNoneButton();
// third Cell
this._createSelectInverseButton();
// place row on top of the hedader-node
domConstruct.place(row, headerNode, 0);
},
createButtonRowCells: function(tag, each, subRows) {
// summary:
// Generates the new header row for the placement of Buttons
// for selection
var columns = this.columns,
headerNode = this.headerNode,
i = headerNode.childNodes.length;

headerNode.setAttribute("role", "row");
// summary:
// Generates the grid for each row (used by renderHeader and and renderRow)
var row = put("table.dgrid-row-table[role=presentation]"),
cellNavigation = this.cellNavigation,
// IE < 9 needs an explicit tbody; other browsers do not
tbody = (has("ie") < 9 || has("quirks")) ? put(row, "tbody") : row,
tr, si, sl, i, l, // iterators
subRow, column, id, extraClassName, cell, innerCell, colSpan, rowSpan; // used inside loops
// Allow specification of custom/specific subRows, falling back to
// those defined on the instance.
subRows = subRows || this.subRows;

tr = put(tbody, "tr");
// // add the td to the tr at the end for better performance

// Create Cell for selecAll
tr.appendChild(this._addButton(tag, "selectAll"));
// Create Cell for selecNone
tr.appendChild(this._addButton(tag, "selectNone"));
// Create Cell for selecInverse
tr.appendChild(this._addButton(tag, "selectInverse"));
return row;
},
_addButton: function(tag, id) {
// summary:
// Create cells for Selector Buttons
var cell = put(tag + (".dgrid-cell.dgrid-cell-padding" + (id ? ".dgrid-column-" + id : "")).replace(invalidClassChars, "-") + "[role=" + (tag === "th" ? "columnheader" : "gridcell") + "]");
// diffrent id string for buttons cells
cell.id = id + '_Button_Cell';
if (contentBoxSizing) {
// The browser (IE7-) does not support box-sizing: border-box, so we emulate it with a padding div
innerCell = put(cell, "!dgrid-cell-padding div.dgrid-cell-padding"); // remove the dgrid-cell-padding, and create a child with that class
cell.contents = innerCell;
} else {
innerCell = cell;
}
return cell;
},
addSelectionButtons: function(button, index) {
// summary:
// Set Button Position
// index: integer
// position of the button in selectorNode
// button: selector button widget
this.selectorNode.children[index].appendChild(button.domNode)
},
addAllSelectionButtons: function(posSelectAll, posSelectNone, posSelectInverse) {
// summary:
// set position of all selector buttons
// posSelectAll: integer
// position of the Select All button in selectorNode
// posSelectNone: integer
// position of the Select None button in selectorNode
// posSelectInverse: integer
// position of the Select Inverse button in selectorNode
//
this.selectorNode.children[posSelectAll].appendChild(this.selectAllButton.domNode, posSelectAll)
this.selectorNode.children[posSelectNone].appendChild(this.selectNoneButton.domNode, posSelectNone)
this.selectorNode.children[posSelectInverse].appendChild(this.selectInverseButton.domNode, posSelectInverse)
},
_createSelectAllButton: function() {
// summary:
// Button widget to select All rows
var _this = this;
this.selectAllButton = new Button({
label: "Select All",
});
this.selectAllButton.on('click', function(evt) {
_this.selectAll();
})
// by default Place Select all at first cell
this.addSelectionButtons(this.selectAllButton, 0)
},
_createSelectNoneButton: function() {
// summary:
// Button widget to de-select All rows
var _this = this;
this.selectNoneButton = new Button({
label: "Select None",
});
this.selectNoneButton.on('click', function(evt) {
_this.clearSelection();
})
// by default Place Select None at second cell
this.addSelectionButtons(this.selectNoneButton, 1)
},
_createSelectInverseButton: function() {
// summary:
// Button widget to toggle selection of rows
var _this = this;
this.selectInverseButton = new Button({
label: "Select Inverse",
});
this.selectInverseButton.on('click', function() {
if (_this.allSelected) {
_this.clearSelection();
} else {
for (var i in _this._rowIdToObject) {
_this.select(_this._rowIdToObject[i], null, null)
}
}
if (_this._fireSelectionEvents) {
_this._fireSelectionEvents();
}
})
// by default Place Select Inverse at third cell
this.addSelectionButtons(this.selectInverseButton, 2)
}
});
});
104 changes: 104 additions & 0 deletions test/extensions/Row_advanceSelection.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test Dijit Cell Editors</title>
<meta name="viewport" content="width=570">
<style>
@import "../../../dojo/resources/dojo.css";
@import "../../../dijit/themes/claro/claro.css";
@import "../../css/skins/claro.css";
.heading {
font-weight: bold;
padding-bottom: 0.25em;
}
#grid .field-date, #grid .field-date2 {
width: 16em;
}
#grid .field-integer {
width: 6em;
}
#grid .field-bool {
width: 6em;
}
.ui-widget{
margin: 10px;
}
</style>
<script src="../../../dojo/dojo.js"
data-dojo-config="async: true"></script>
<script>
require(["dgrid/List", "dgrid/extensions/advanceSelection", "dgrid/extensions/ColumnHider", "dgrid/extensions/ColumnReorder", "dgrid/extensions/ColumnResizer", "dgrid/OnDemandGrid", "dgrid/Selection", "dgrid/Keyboard", "dgrid/editor", "dijit/form/CheckBox", "dijit/form/TimeTextBox", "dijit/form/Select","dojo/data/ObjectStore", "dijit/form/FilteringSelect", "dojo/_base/declare", "dgrid/test/data/base", "dojo/domReady!"],
function(List, advanceSelection, ColumnHider, ColumnResizer, ColumnReorder, Grid, Selection, Keyboard, editor, CheckBox, TimeTextBox, Select, ObjectStore, FilteringSelect, declare){

stateStore = new ObjectStore({
objectStore:testStateStore,
labelProperty: "name"
});

var columns = [
{field: "id", label: "id"},
editor({
label: "CheckBox",
field: "bool2",
editorArgs: {
value: "checked"
}
}, CheckBox),
editor({label: "Time", field: "date2", editorArgs: {
timePattern: "HH:mm:ss",
clickableIncrement: "T00:15:00",
visibleIncrement: "T00:15:00",
visibleRange: "T01:00:00"}}, TimeTextBox),
editor({
label: "Select Options",
field: "bool",
get: function(item){
// return as string to match option in list
return "" + item.bool;
},
set: function(item){
// convert back to boolean from string
return item.bool == "true";
},
editorArgs: {
style: "width:75px;",
options: [
{value: "true", label: "true"},
{value: "false", label: "false"}
]
}
}, Select, "dblclick"),
editor({label: "Select Store", field: "state", editorArgs: {store: stateStore, maxHeight: 150, style: "width:120px;"}}, Select, "click"),
editor({label: "FilteringSelect Store", field: "state2", editorArgs: {store: stateStore, maxHeight: 150, style: "width:120px;"}}, FilteringSelect)
// Note that mileage may vary with editOn + widgets with multiple focusable children, e.g. dijit/Editor
];

// just add advanceSelection extension
window.grid = new (declare([Grid, Selection, advanceSelection, ColumnHider, ColumnReorder, ColumnResizer, Keyboard]))({
store: testTypesStore,
columns: columns,
selectionMode: "none"
}, "grid");

grid.on("dgrid-datachange", function(evt){
console.log("data changed: ", evt.oldValue, " -> ", evt.value);
console.log("cell: ", evt.cell, evt.cell.row.id);
});
grid.on("dgrid-editor-show", function(evt){
console.log("show editOn editor: ", evt);
});
grid.on("dgrid-editor-hide", function(evt){
console.log("hide editOn editor: ", evt);
});
});

</script>
</head>
<body class="claro">
<h2>Another basic grid with more editors</h2>
(Click fields to edit)
<div id="grid"></div>
<button type="button" id="save" onclick="grid.save()">Save</button>
</body>
</html>