apex4x
Version:
The Comprehensive ARIA Development Suite
2,044 lines • 75.3 kB
JavaScript
/*@license
ARIA Grid Module 2.0 for Apex 4X
Author: Bryan Garaventa (https://www.linkedin.com/in/bgaraventa)
Home: WhatSock.com : Download: https://github.com/whatsock/apex
License: MIT (https://opensource.org/licenses/MIT)
*/
(function () {
var baseId = "grid" + $A.genId(),
gridInc = 1;
if (!("Grid" in $A))
$A.extend({
Grid: function (container) {
var that = this,
container =
typeof container === "string" ? $A.get(container) : container,
isArray = function (v) {
return (
v &&
typeof v === "object" &&
typeof v.length === "number" &&
typeof v.splice === "function" &&
!v.propertyIsEnumerable("length")
);
},
config = {
gridClass: "data-grid",
gridReadOnlyClass: "data-grid-readonly",
cellReadOnlyClass: "data-grid-cell-readonly",
gridEditableClass: "data-grid-editable",
gridSelectableClass: "data-grid-selectable",
gridRowClass: "data-grid-row",
gridCellClass: "data-grid-cell",
gridCellToggleClass: "data-grid-cell-toggle",
gridCellTogglePressedClass: "data-grid-cell-toggle-pressed",
gridCellLinkClass: "data-grid-cell-link",
gridRowFocusedClass: "data-grid-row-focused",
gridCellFocusedClass: "data-grid-cell-focused",
editFieldClass: "data-grid-cell-link-edit",
edit: false,
colHeaders: {
map: [],
},
rowHeaders: {
enabled: false,
id: null,
},
page: {
row: {
max: 0,
collectionMap: [],
collection: {},
toggleButtonRole: "Toggle Button",
toggleButtonState: "Pressed",
disabledText: "Disabled",
editLinkAction: "Editable",
build: function (rowObject) {
gridInc++;
var bid = baseId + "tr" + gridInc;
rowObject.rowNodeId = bid;
rowObject.rowNode = $A.create(
"tr",
{
role: "row",
id: bid,
},
null,
config.gridRowClass,
);
for (id in rowObject.cells) {
gridInc++;
var cid = baseId + "td" + gridInc;
rowObject.cells[id].id = id;
rowObject.cells[id].cellNodeId = cid;
rowObject.cells[id].data = {};
rowObject.cells[id].cellNode = $A.create(
"td",
{
id: cid,
},
null,
config.gridCellClass,
);
config.page.row.bindCell(
rowObject.cells[id],
rowObject.cells[id].cellNode,
rowObject,
rowObject.rowNode,
);
rowObject.cells[id].cellNodeA = $A.create(
"strong",
{
id: cid + "a",
},
null,
rowObject.cells[id].type == "toggle"
? config.gridCellToggleClass
: config.gridCellLinkClass,
);
rowObject.cells[id].cellNodeS1 = $A.create("span");
rowObject.cells[id].cellNodeS2 = $A.create(
"span",
null,
$A.sraCSS,
);
rowObject.cells[id].cellNodeS3 = $A.create(
"span",
null,
$A.sraCSS,
);
rowObject.cells[id].cellNode.appendChild(
rowObject.cells[id].cellNodeA,
);
rowObject.cells[id].cellNodeA.appendChild(
rowObject.cells[id].cellNodeS1,
);
rowObject.cells[id].cellNodeA.appendChild(
rowObject.cells[id].cellNodeS2,
);
rowObject.cells[id].cellNodeA.appendChild(
rowObject.cells[id].cellNodeS3,
);
rowObject.cells[id].rowObject = rowObject;
$A.data(rowObject.cells[id].cellNode, "celldata", {
rowId: rowObject.id,
rowNodeId: rowObject.rowNodeId,
cellId: id,
cellNodeId: rowObject.cells[id].cellNodeId,
});
}
$A.data(rowObject.rowNode, "rowdata", {
rowId: rowObject.id,
rowNodeId: rowObject.rowNodeId,
});
},
trackPos: {
row: 0,
col: 0,
},
resetPos: function (cellNode) {
var d = $A.data(cellNode, "celldata");
config.page.row.trackPos.row =
$A.inArray(d.rowId, config.page.rendered) || 0;
for (var i = 0; i < config.colHeaders.map.length; i++) {
if (d.cellId == config.colHeaders.map[i].id) {
config.page.row.trackPos.col = i;
break;
}
}
return d;
},
dblClickTitle: "Click to activate",
editFieldTitle: "Press Enter to save, or Escape to cancel.",
cellOffset: function (cellObject) {
return $A.offset(cellObject.cellNodeA);
},
bindCell: function (cellObject, cellNode, rowObject, rowNode) {
var trigger = function () {
cellNode = cellObject.cellNode;
rowObject = cellObject.rowObject;
rowNode = cellObject.rowObject.rowNode;
if (config.edit && !cellObject.readonly) {
if (cellObject.type == "toggle") {
config.page.row.changed(
cellNode,
cellObject,
cellObject.value ? false : true,
);
} else {
if (config.page.row.editFieldActive) clearEdit();
config.page.row.editFieldActive = cellObject;
$A.on(config.page.row.editField, {
"keydown.gridcontrol": function (ev) {
var k = ev.which || ev.keyCode;
if (k == 13 || k == 27 || k == 9) {
ev.preventDefault();
ev.stopPropagation();
if (k == 13)
config.page.row.changed(
cellNode,
config.page.row.editFieldActive,
this.value,
);
clearEdit(true);
}
},
"blur.gridcontrol": function (ev) {
ev.preventDefault();
},
});
config.page.row.editField.value = cellObject.value;
$A.setAttr(config.page.row.editField, {
title: config.page.row.editFieldTitle,
});
$A.loop(
document.body.children,
function (i, o) {
$A.setAttr(o, "aria-hidden", "true");
},
"array",
);
document.body.appendChild(
config.page.row.editFieldDiv,
);
$A.css(
config.page.row.editFieldDiv,
config.page.row.cellOffset(cellObject),
);
config.page.row.editField.focus();
if (
config.page.row.editLoad &&
typeof config.page.row.editLoad === "function"
)
config.page.row.editLoad.apply(
config.page.row.editField,
[config.page.row.editField, cellObject],
);
}
} else if (config.page.row.selectEnabled) {
var wasSelected = rowObject.selected;
if (!config.page.row.multiSelect)
config.page.row.unselectAll();
if (!wasSelected || config.page.row.multiSelect)
config.page.row.select(cellObject);
if (!config.page.row.ariaSelect)
$A.announce(cellObject.cellNode);
}
},
nav = function (k, ev) {
cellNode = cellObject.cellNode;
rowObject = cellObject.rowObject;
rowNode = cellObject.rowObject.rowNode;
// PageUp 33
// PageDown 34
// End 35
// Home 36
// Left 37
// Up 38
// Right 39
// Down 40
if (k == 33) {
if (pressed.alt)
config.page.first(cellObject, rowObject);
else config.page.prev(cellObject, rowObject);
} else if (k == 34) {
if (pressed.alt)
config.page.last(cellObject, rowObject);
else config.page.next(cellObject, rowObject);
} else if (k >= 35 && k <= 40) {
var move = false,
rowMax = config.page.rendered.length - 1,
colMax = config.colHeaders.map.length - 1;
if (
k == 35 &&
pressed.ctrl &&
config.page.current < config.page.total
) {
config.page.last(cellObject, rowObject, true);
return;
} else if (
k == 35 &&
pressed.ctrl &&
config.page.current == config.page.total
) {
config.page.row.trackPos.row = rowMax;
move = true;
} else if (
k == 35 &&
config.page.row.trackPos.col < colMax
) {
config.page.row.trackPos.col = colMax;
move = true;
} else if (
k == 36 &&
pressed.ctrl &&
config.page.current > 1
) {
config.page.first(cellObject, rowObject);
return;
} else if (
k == 36 &&
pressed.ctrl &&
config.page.current == 1
) {
config.page.row.trackPos.row = 0;
move = true;
} else if (
k == 36 &&
config.page.row.trackPos.col > 0
) {
config.page.row.trackPos.col = 0;
move = true;
} else if (
k == 37 &&
config.page.row.trackPos.col > 0
) {
config.page.row.trackPos.col -= 1;
move = true;
} else if (
k == 38 &&
config.page.row.trackPos.row > 0 &&
pressed.alt
) {
config.page.row.trackPos.row = 0;
move = true;
} else if (
k == 38 &&
config.page.row.trackPos.row > 0
) {
config.page.row.trackPos.row -= 1;
move = true;
} else if (
k == 38 &&
config.page.row.trackPos.row == 0
) {
config.page.prev(cellObject, rowObject, true);
return;
} else if (
k == 39 &&
config.page.row.trackPos.col < colMax
) {
config.page.row.trackPos.col += 1;
move = true;
} else if (
k == 40 &&
config.page.row.trackPos.row < rowMax &&
pressed.alt
) {
config.page.row.trackPos.row = rowMax;
move = true;
} else if (
k == 40 &&
config.page.row.trackPos.row < rowMax
) {
config.page.row.trackPos.row += 1;
move = true;
} else if (
k == 40 &&
config.page.row.trackPos.row >= rowMax
) {
config.page.next(cellObject, rowObject);
return;
}
if (move) {
config.page.row.move({
rowId:
config.page.rendered[
config.page.row.trackPos.row
],
cellId:
config.colHeaders.map[
config.page.row.trackPos.col
].id,
});
}
}
};
var pressed = {
ctrl: false,
alt: false,
};
$A.on(cellNode, {
"click.gridcontrol": function (ev) {
var t = ev.srcElement || ev.target;
if (t != this || this != config.page.row.focusedCell)
config.page.row.move(config.page.row.resetPos(this));
if (
"ontouchstart" in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0
) {
cellObject = getCellObject(this);
trigger();
}
ev.preventDefault();
},
"dblclick.gridcontrol": function (ev) {
if (useDblClick) {
if (this != config.page.row.focusedCell)
config.page.row.move(config.page.row.resetPos(this));
if (
!(
"ontouchstart" in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0
)
) {
cellObject = getCellObject(this);
trigger();
}
ev.stopPropagation();
ev.preventDefault();
}
},
"mouseup.gridcontrol": function (ev) {
if (!useDblClick) {
if (!ev.which && ev.button && ev.button & 1)
ev.which = 1;
if (ev.which === 1) {
if (this != config.page.row.focusedCell)
config.page.row.move(
config.page.row.resetPos(this),
);
if (
!(
"ontouchstart" in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0
)
) {
cellObject = getCellObject(this);
trigger();
}
ev.stopPropagation();
ev.preventDefault();
}
}
},
"keydown.gridcontrol": function (ev) {
var k = ev.which || ev.keyCode;
pressed.ctrl = ev.ctrlKey;
pressed.alt = ev.altKey;
if (
(k >= 33 && k <= 40) ||
k == 13 ||
k == 32 ||
k == 46 ||
k == 65
) {
cellObject = getCellObject(this);
if (k == 13 || k == 32) {
if (k == 32 && pressed.ctrl) {
var str = "";
for (
var i = 0;
i < config.colHeaders.map.length;
i++
) {
var o = config.colHeaders.map[i];
str +=
$A.getText(
cellObject.rowObject.cells[o.id].cellNode,
) + ", ";
}
$A.announce(str);
} else trigger();
} else if (k >= 33 && k <= 40) nav(k, ev);
else if (k == 46 && config.page.row.deleteRow.enabled) {
config.page.row.deleteRow.callback();
config.page.row.move();
} else if (
k == 65 &&
pressed.ctrl &&
config.page.row.selectEnabled
) {
config.page.row.selectAll();
$A.announce(config.page.row.selectState);
}
ev.stopPropagation();
ev.preventDefault();
}
},
"keyup.gridcontrol": function (ev) {
pressed.ctrl = false;
pressed.alt = false;
},
"focus.gridcontrol": function (ev) {
cellObject = getCellObject(this);
$A.addClass(this, config.gridCellFocusedClass);
$A.addClass(
cellObject.rowObject.rowNode,
config.gridRowFocusedClass,
);
if (this != config.page.row.focusedCell)
config.page.row.move(
config.page.row.resetPos(this),
true,
);
},
"blur.gridcontrol": function (ev) {
$A.query(
"tr." +
config.gridRowFocusedClass +
", td." +
config.gridCellFocusedClass,
config.dc.container,
function (i, o) {
$A.remClass(
o,
config.gridRowFocusedClass +
" " +
config.gridCellFocusedClass,
);
},
);
},
});
},
clean: function (rowObject, keepData) {
$A.remAttr(rowObject.rowNode, [
"title",
"aria-selected",
"aria-rowindex",
]);
$A.remClass(
rowObject.rowNode,
config.gridRowFocusedClass +
" " +
config.page.row.selectClass,
);
if (!keepData) $A.removeData(rowObject.rowNode, "rowdata");
for (var n in rowObject.cells) {
$A.remAttr(rowObject.cells[n].cellNode, [
"aria-activedescendant",
"aria-labelledby",
"aria-describedby",
"tabindex",
"aria-colindex",
"aria-selected",
"aria-readonly",
]);
$A.remClass(
rowObject.cells[n].cellNode,
config.cellReadOnlyClass +
" " +
config.gridCellFocusedClass +
" " +
(rowObject.cells[n].toggleClass ||
config.gridCellTogglePressedClass),
);
$A.remAttr(rowObject.cells[n].cellNodeA, [
"title",
"role",
"aria-pressed",
"aria-disabled",
]);
rowObject.cells[n].cellNodeS1.innerHTML = "";
rowObject.cells[n].cellNodeS2.innerHTML = "";
rowObject.cells[n].cellNodeS3.innerHTML = "";
if (!keepData)
$A.removeData(rowObject.cells[n].cellNode, "celldata");
}
},
changed: function (cellNode, cellObject, val) {
var ret =
config.page.row.changed.cb &&
typeof config.page.row.changed.cb === "function"
? config.page.row.changed.cb.apply(cellNode, [
cellObject,
val,
cellObject.rowObject,
that,
])
: true;
if (typeof ret !== "boolean") ret = true;
if (ret) {
config.page.row.update(
cellObject.rowObject.id,
cellObject.id,
val,
);
}
},
selectEnabled: false,
selectState: "Selected",
selectClass: "selected",
multiSelect: false,
preserveSelect: false,
ariaSelect: true,
selected: [],
select: function (cellObject, sv) {
var newVal =
sv || (cellObject.rowObject.selected ? false : true),
ret =
config.page.row.select.cb &&
typeof config.page.row.select.cb === "function"
? config.page.row.select.cb.apply(
cellObject.rowObject.rowNode,
[
cellObject.rowObject,
newVal,
config.page.row.selected,
that,
],
)
: true;
if (typeof ret !== "boolean") ret = true;
if (ret) {
cellObject.rowObject.selected = newVal;
var found = false;
for (
var i = config.page.row.selected.length - 1;
i >= 0;
i--
) {
if (
config.page.row.selected[i] ===
cellObject.rowObject.id &&
!cellObject.rowObject.selected
)
config.page.row.selected.splice(i, 1);
else if (
config.page.row.selected[i] ===
cellObject.rowObject.id &&
cellObject.rowObject.selected
)
found = true;
}
if (!found && cellObject.rowObject.selected)
config.page.row.selected.push(cellObject.rowObject.id);
var isR =
$A.inArray(
cellObject.rowObject.id,
config.page.rendered,
) !== -1;
if (isR) {
var altTxt = "";
if (cellObject.rowObject.selected) {
$A.addClass(
cellObject.rowObject.rowNode,
config.page.row.selectClass,
);
altTxt = config.page.row.selectState
? config.page.row.selectState + ". "
: "";
} else {
$A.remClass(
cellObject.rowObject.rowNode,
config.page.row.selectClass,
);
}
altTxt += config.page.row.dblClickTitle;
$A.setAttr(cellObject.rowObject.rowNode, "title", altTxt);
if (config.page.row.ariaSelect)
$A.setAttr(
cellObject.rowObject.rowNode,
"aria-selected",
cellObject.rowObject.selected ? "true" : "false",
);
for (var i = 0; i < config.colHeaders.map.length; i++) {
if (config.page.row.ariaSelect)
$A.setAttr(
cellObject.rowObject.cells[
config.colHeaders.map[i].id
].cellNode,
"aria-selected",
cellObject.rowObject.selected ? "true" : "false",
);
else
cellObject.rowObject.cells[
config.colHeaders.map[i].id
].cellNodeS3.innerHTML = cellObject.rowObject.selected
? "<span> " +
formatStr(config.page.row.selectState) +
"</span>"
: "";
}
}
}
},
unselectAll: function () {
for (
var i = config.page.row.selected.length - 1;
i >= 0;
i--
) {
var rowId = config.page.row.selected[i];
config.page.row.select(
config.page.row.collection[rowId].cells[
config.colHeaders.map[0].id
],
false,
);
config.page.row.selected.splice(i, 1);
}
},
selectAll: function () {
if (
config.page.row.selectEnabled &&
config.page.row.multiSelect
) {
if (!config.page.row.preserveSelect)
config.page.row.unselectAll();
for (var i = 0; i < config.page.rendered.length; i++) {
config.page.row.select(
config.page.row.collection[config.page.rendered[i]]
.cells[config.colHeaders.map[0].id],
true,
);
}
}
},
deleteRow: {
enabled: false,
callback: function (ids) {
var rt =
config.page.row.deleteRow.callback.runBefore &&
typeof config.page.row.deleteRow.callback.runBefore ===
"function"
? config.page.row.deleteRow.callback.runBefore.apply(
that,
[
ids && ids.length
? ids
: config.page.row.selected,
],
)
: true;
if (typeof rt !== "boolean") rt = true;
if (!rt) return false;
var deleted = [];
if (ids && ids.length) {
config.page.row.unselectAll();
for (var i = 0; i < ids.length; i++) {
if (
config.page.row.collection[ids[i]] &&
config.page.row.collection[ids[i]].cells
)
config.page.row.selected.push(ids[i]);
}
}
var si = config.page.row.selected.length;
for (
var i = config.page.row.selected.length - 1;
i >= 0;
i--
) {
var rowObject =
config.page.row.collection[
config.page.row.selected[i]
],
pos = $A.inArray(
rowObject.id,
config.page.row.collectionMap,
);
if (pos !== -1) {
var ret =
config.page.row.deleteRow.callback.cb &&
typeof config.page.row.deleteRow.callback.cb ===
"function"
? config.page.row.deleteRow.callback.cb.apply(
rowObject.rowNode,
[rowObject, that],
)
: true;
if (typeof ret !== "boolean") ret = true;
if (ret) {
deleted.push(rowObject.id);
config.page.row.clean(rowObject);
for (var n in rowObject.cells) {
$A.remove(rowObject.cells[n].cellNode);
}
$A.remove(rowObject.rowNode);
var isR = $A.inArray(
rowObject.id,
config.page.rendered,
);
if (isR !== -1) config.page.rendered.splice(isR, 1);
config.page.row.selected.splice(i, 1);
config.page.row.collectionMap.splice(pos, 1);
delete config.page.row.collection[rowObject.id];
}
}
}
if (si != config.page.row.selected.length) {
config.page.row.trackPos.row = 0;
config.page.sync();
config.page.open(config.page.current);
if (
config.page.row.deleteRow.callback.runAfter &&
typeof config.page.row.deleteRow.callback.runAfter ===
"function"
)
config.page.row.deleteRow.callback.runAfter.apply(
that,
[deleted],
);
return true;
}
return false;
},
},
update: function (rowId, cellId, val, silent) {
if (
!config.page.row.collection[rowId] ||
!config.page.row.collection[rowId].cells[cellId]
)
return;
var cellObject =
config.page.row.collection[rowId].cells[cellId],
type = cellObject.type;
config.page.row.collection[rowId].cells[cellId].value =
type == "toggle" ? (val ? true : false) : val;
var inA = $A.inArray(rowId, config.page.rendered);
if (inA !== -1) {
if (type == "toggle") {
var accText =
" " + formatStr(config.page.row.toggleButtonRole);
if (val) {
$A.setAttr(cellObject.cellNodeA, {
"aria-describedby": $A.getAttr(
cellObject.cellNode,
"aria-describedby",
),
role: "button",
"aria-pressed": "true",
});
$A.addClass(
cellObject.cellNodeA,
cellObject.toggleClass ||
config.gridCellTogglePressedClass,
);
accText +=
" " +
formatStr(config.page.row.toggleButtonState);
} else {
$A.setAttr(cellObject.cellNodeA, {
"aria-describedby": $A.getAttr(
cellObject.cellNode,
"aria-describedby",
),
role: "button",
"aria-pressed": "false",
});
$A.remClass(
cellObject.cellNodeA,
cellObject.toggleClass ||
config.gridCellTogglePressedClass,
);
}
if (
cellObject.readonly ||
config.page.row.selectEnabled ||
!config.edit
)
// accText += ' ' + formatStr(config.page.row.disabledText);
$A.setAttr(
cellObject.cellNodeA,
"aria-disabled",
"true",
);
// cellObject.cellNodeS2.innerHTML = '<span>' + accText + '</span>';
} else {
cellObject.cellNodeS1.innerHTML =
"<span>" + formatStr(val) + "</span>";
}
if (!silent) $A.announce(cellObject.cellNodeA);
}
},
focusedCell: null,
move: function (o, s) {
if (!o && config.page.row.focusedCell) {
setTimeout(function () {
config.page.row.focusedCell.focus();
}, 1);
return;
}
var oldCell = config.page.row.focusedCell,
newCell =
config.page.row.collection[o.rowId].cells[o.cellId]
.cellNode;
if (oldCell && oldCell != newCell)
$A.setAttr(oldCell, "tabindex", "-1");
config.page.row.focusedCell = newCell;
config.page.row.resetPos(newCell);
$A.setAttr(newCell, "tabindex", "0");
if (!s) newCell.focus();
if (
config.page.row.move.cb &&
typeof config.page.row.move.cb === "function"
)
config.page.row.move.cb.apply(newCell, [
newCell,
oldCell,
config.dc,
that,
]);
},
},
pageRole: "Page",
current: 1,
total: 1,
sync: function (n) {
var prevC = config.page.current,
prevT = config.page.total;
if (
!config.page.row.max ||
!config.page.row.collectionMap.length
) {
config.page.current = config.page.total = 1;
} else {
var rMax = config.page.row.max,
tRows = config.page.row.collectionMap.length;
if (rMax >= tRows)
config.page.current = config.page.total = 1;
else {
var p = Math.ceil(tRows / rMax);
config.page.total = p;
if (config.page.current > p) config.page.current = p;
}
}
var r = [];
if (n) {
if (n > config.page.row.total) n = config.page.row.total;
var g = (n - 1) * config.page.row.max,
l = g + config.page.row.max;
config.page.current = n;
if (!config.page.row.max)
l = config.page.row.collectionMap.length;
for (var u = g; u < l; u++) {
var rowId = config.page.row.collectionMap[u];
if (!(isNaN(rowId) && !rowId)) {
config.page.row.collection[rowId].rowIndex = u + 1;
r.push(rowId);
}
}
}
if (
prevC != config.page.current ||
prevT != config.page.total
) {
if (
config.page.indexChanged &&
typeof config.page.indexChanged === "function"
)
config.page.indexChanged.apply(that, [
config.page.current,
config.page.total,
that,
]);
}
if (n) return r;
},
on: {
open: null,
close: null,
change: null,
add: null,
rem: null,
},
open: function (n, reOpen) {
if (config.page.row.editFieldActive) clearEdit(true, true);
if (isNaN(n) || n < 1) n = 1;
if (reOpen && config.dc.loaded) config.page.close();
var isLoaded = config.dc.loaded;
if (!isLoaded) config.dc.render();
config.page.render(config.page.sync(n));
if (
!isLoaded &&
config.page.on.open &&
typeof config.page.on.open === "function"
)
config.page.on.open.apply(container, [
container,
config.dc,
that,
]);
},
close: function () {
if (config.page.row.editFieldActive) clearEdit(true, true);
if (
config.page.on.close &&
typeof config.page.on.close === "function"
)
config.page.on.close.apply(container, [
container,
config.dc,
that,
]);
config.page.row.unselectAll();
config.page.removeRendered();
config.dc.remove();
},
rendered: [],
removeRendered: function () {
if (!config.page.row.preserveSelect)
config.page.row.unselectAll();
for (var i = 0; i < config.page.rendered.length; i++) {
var id = config.page.rendered[i],
rowObject = config.page.row.collection[id];
config.page.row.clean(rowObject, true);
if (
config.page.on.rem &&
typeof config.page.on.rem === "function"
)
config.page.on.rem.apply(rowObject.rowNode, [
rowObject,
config.dc,
that,
]);
for (var n in rowObject.cells) {
if (rowObject.cells[n].cellNode.parentNode)
rowObject.cells[n].cellNode.parentNode.removeChild(
rowObject.cells[n].cellNode,
);
}
rowObject.rowNode.parentNode.removeChild(rowObject.rowNode);
}
config.page.rendered = [];
},
render: function (ids) {
if (config.page.row.editFieldActive) clearEdit(true, true);
if (config.page.row.selectEnabled && config.edit)
config.edit = false;
if (!config.dc.loaded) return;
if (config.page.rendered.length) config.page.removeRendered();
config.page.rendered = ids;
var initPos = {},
aoIds = [];
for (var h = 0; h < ids.length; h++) {
gridInc++;
var tr = config.page.row.collection[ids[h]].rowNode,
colIndex = 1,
selected = config.page.row.collection[ids[h]].selected,
altTxt = selected ? config.page.row.selectState + ". " : "";
$A.addClass(tr, config.gridRowClass);
aoIds.push(config.page.row.collection[ids[h]].rowNodeId);
if (config.page.row.selectEnabled) {
$A.setAttr(tr, {
title: altTxt + config.page.row.dblClickTitle,
});
if (config.page.row.ariaSelect)
$A.setAttr(tr, {
"aria-selected": selected ? "true" : "false",
});
if (selected) {
$A.addClass(tr, config.page.row.selectClass);
}
}
$A.setAttr(
tr,
"aria-rowindex",
config.page.row.collection[ids[h]].rowIndex,
);
var aoIds2 = [];
for (var i = 0; i < config.colHeaders.map.length; i++) {
gridInc++;
var o = config.colHeaders.map[i],
cellObject =
config.page.row.collection[ids[h]].cells[o.id];
$A.addClass(cellObject.cellNode, config.gridCellClass);
aoIds2.push(cellObject.cellNodeId);
if (o.colClass)
$A.addClass(cellObject.cellNode, o.colClass);
$A.setAttr(cellObject.cellNode, {
role: "gridcell",
"aria-colindex": colIndex,
"aria-labelledby": cellObject.cellNodeId + "a",
"aria-describedby":
config.rowHeaders.enabled &&
config.rowHeaders.id &&
config.rowHeaders.id != cellObject.id &&
cellObject.rowObject.cells[config.rowHeaders.id]
? cellObject.rowObject.cells[config.rowHeaders.id]
.cellNodeId +
" " +
o.thId
: o.thId,
tabindex: "-1",
});
if (
cellObject.type == "toggle" ||
(config.edit && !cellObject.readonly)
)
$A.setAttr(cellObject.cellNode, {
"aria-activedescendant": cellObject.cellNodeId + "a",
});
if (
config.rowHeaders.enabled &&
config.rowHeaders.id &&
config.rowHeaders.id == cellObject.id
)
$A.setAttr(cellObject.cellNode, {
role: "rowheader",
scope: "row",
});
if (config.page.row.selectEnabled) {
if (
cellObject.type == "toggle" &&
(config.page.row.toggleButtonRole ||
config.page.row.toggleButtonState)
) {
var altTxt = cellObject.value
? config.page.row.toggleButtonRole +
" " +
config.page.row.toggleButtonState
: config.page.row.toggleButtonRole;
$A.setAttr(cellObject.cellNodeA, "title", altTxt);
}
if (config.page.row.ariaSelect)
$A.setAttr(
cellObject.cellNode,
"aria-selected",
selected ? "true" : "false",
);
else if (selected)
cellObject.cellNodeS3.innerHTML = selected
? "<span> " +
formatStr(config.page.row.selectState) +
"</span>"
: "";
} else if (config.edit && !cellObject.readonly) {
var altTxt = "";
if (
cellObject.type == "toggle" &&
(config.page.row.toggleButtonRole ||
config.page.row.toggleButtonState)
) {
altTxt = cellObject.value
? config.page.row.toggleButtonRole +
" " +
config.page.row.toggleButtonState
: config.page.row.toggleButtonRole;
altTxt += ". ";
} else if (config.page.row.editLinkAction) {
altTxt = config.page.row.editLinkAction + ". ";
}
$A.setAttr(
cellObject.cellNodeA,
"title",
altTxt + config.page.row.dblClickTitle,
);
} else if (
cellObject.type == "toggle" &&
(config.page.row.toggleButtonRole ||
config.page.row.toggleButtonState)
) {
var altTxt = cellObject.value
? config.page.row.toggleButtonRole +
" " +
config.page.row.toggleButtonState
: config.page.row.toggleButtonRole;
$A.setAttr(cellObject.cellNodeA, "title", altTxt);
}
if (
h === config.page.row.trackPos.row &&
i === config.page.row.trackPos.col
)
initPos = {
rowId: ids[h],
cellId: o.id,
};
if (cellObject.readonly || config.page.row.selectEnabled) {
$A.setAttr(cellObject.cellNode, "aria-readonly", "true");
$A.addClass(
cellObject.cellNode,
config.cellReadOnlyClass,
);
}
if (cellObject.type == "toggle") {
cellObject.cellNodeS1.innerHTML =
"<span>" + formatStr(cellObject.name) + "</span>";
var accText =
" " + formatStr(config.page.row.toggleButtonRole);
if (cellObject.value) {
$A.setAttr(cellObject.cellNodeA, {
"aria-describedby": $A.getAttr(
cellObject.cellNode,
"aria-describedby",
),
role: "button",
"aria-pressed": "true",
});
$A.addClass(
cellObject.cellNodeA,
cellObject.toggleClass ||
config.gridCellTogglePressedClass,
);
accText +=
" " +
formatStr(config.page.row.toggleButtonState);
} else {
$A.setAttr(cellObject.cellNodeA, {
"aria-describedby": $A.getAttr(
cellObject.cellNode,
"aria-describedby",
),
role: "button",
"aria-pressed": "false",
});
$A.remClass(
cellObject.cellNodeA,
cellObject.toggleClass ||
config.gridCellTogglePressedClass,
);
}
if (
cellObject.readonly ||
config.page.row.selectEnabled ||
!config.edit
)
// accText += ' ' + formatStr(config.page.row.disabledText);
$A.setAttr(
cellObject.cellNodeA,
"aria-disabled",
"true",
);
// cellObject.cellNodeS2.innerHTML = '<span>' + accText + '</span>';
} else {
cellObject.cellNodeS1.innerHTML =
"<span>" + formatStr(cellObject.value) + "</span>";
if (config.edit && !cellObject.readonly) {
$A.setAttr(cellObject.cellNodeA, {
"aria-describedby": $A.getAttr(
cellObject.cellNode,
"aria-describedby",
),
role: "button",
});
var accText =
" " + formatStr(config.page.row.editLinkAction);
cellObject.cellNodeS2.innerHTML =
"<span>" + accText + "</span>";
} else {
$A.setAttr(
cellObject.cellNodeA,
"role",
"presentation",
);
}
}
tr.appendChild(cellObject.cellNode);
colIndex += 1;
}
config.dc.tbody.appendChild(tr);
if (
config.page.on.add &&
typeof config.page.on.add === "function"
)
config.page.on.add.apply(tr, [
config.page.row.collection[ids[h]],
config.dc,
that,
]);
}
if ("rowId" in initPos && "cellId" in initPos)
config.page.row.move(initPos, true);
},
prev: function (cellObject, rowObject, byArrow) {
if (config.page.current > 1) {
config.page.render(config.page.sync(config.page.current - 1));
config.page.row.move({
rowId:
config.page.rendered[
byArrow ? config.page.rendered.length - 1 : 0
],
cellId: cellObject.id,
});
$A.announce(config.page.pageRole + " " + config.page.current);
if (
config.page.on.change &&
typeof config.page.on.change === "function"
)
config.page.on.change.apply(container, [
config.page.current,
config.page.total,
that,
]);
}
},
next: function (cellObject, rowObject) {
if (config.page.current < config.page.total) {
config.page.render(config.page.sync(config.page.current + 1));
config.page.row.move({
rowId: config.page.rendered[0],
cellId: cellObject.id,
});
$A.announce(config.page.pageRole + " " + config.page.current);
if (
config.page.on.change &&
typeof config.page.on.change === "function"
)
config.page.on.change.apply(container, [
config.page.current,
config.page.total,
that,
]);
}
},
first: function (cellObject, rowObject) {
if (config.page.current > 1) {
config.page.render(config.page.sync(1));
config.page.row.move({
rowId: config.page.rendered[0],
cellId: cellObject.id,
});
$A.announce(config.page.pageRole + " " + config.page.current);
if (
config.page.on.change &&
typeof config.page.on.change === "function"
)
config.page.on.change.apply(container, [
config.page.current,
config.page.total,
that,
]);
}
},
last: function (cellObject, rowObject, lr) {
if (config.page.current < config.page.total) {
config.page.render(config.page.sync(config.page.total));
config.page.row.move({
rowId: lr
? config.page.rendered[config.page.rendered.length - 1]
: config.page.rendered[0],
cellId: cellObject.id,
});
$A.announce(config.page.pageRole + " " + config.page.current);
if (
config.page.on.change &&
typeof config.page.on.change === "function"
)
config.page.on.change.apply(container, [
config.page.current,
config.page.total,
that,
]);
}
},
},
};
gridInc++;
var uId = baseId + "u" + gridInc,
getCellObject = function (cellNode) {
var o = $A.data(
cellNode || config.page.row.focusedCell,
"celldata",
);
return config.page.row.collection[o.rowId].cells[o.cellId];
};
config.page.row.editMaxLength = 255;
config.page.row.editFieldDiv = $A.create(
"div",
{
role: "application",
},
null,
config.editFieldClass,
);
config.page.row.editField = $A.create(
"input",
{
type: "text",
maxlength: config.page.row.editMaxLength,
},
null,
config.editFieldClass,
);
config.page.row.editFieldDiv.appendChild(config.page.row.editField);
$A.on(window, "resize." + uId, function () {
if (config.page.row.editFieldActive) {
$A.css(
config.page.row.editFieldDiv,
config.page.row.cellOffset(config.page.row.editFieldActive),
);
}
});
var clearEdit = function (ret, sk) {
config.page.row.editField.value = "";
$A.off(config.page.row.editField, ".gridcontrol");
$A.remove(config.page.row.editFieldDiv);
if (ret) {
config.page.row.editFieldActive = null;
$A.loop(
document.body.children,
function (i, o) {
$A.setAttr(o, "aria-hidden", "false");
$A.remAttr(o, "aria-hidden");
},
"array",
);
if (!sk) config.page.row.move();
}
};
config.dc = $A.toDC({
id: uId,
role: "Grid",
exposeBounds: false,
contentOnly: false,
root: container,
afterRender: function (dc) {
gridInc++;
dc.tableId = baseId + "t" + gridInc;
dc.theadId = baseId + "tth" + gridInc;
dc.trId = baseId + "tthtr" + gridInc;
dc.tbodyId = baseId + "ttb" + gridInc;
dc.table = $A.create(
"table",
{
role: "grid",
id: dc.tableId,
},
null,
config.gridClass,
);
if (config.edit) $A.addClass(dc.table, config.gridEditableClass);
else if (config.page.row.selectEnabled) {
$A.addClass(dc.table, config.gridSelectableClass);
if (config.page.row.multiSelect)
$A.setAttr(dc.table, "aria-multiselectable", "true");
} else if (!config.edit && !config.page.row.selectEnabled) {
$A.addClass(dc.table, config.gridReadOnlyClass);
$A.setAttr(dc.table, "aria-readonly", "true");
}
dc.thead = $A.create("thead", {
role: "rowgroup",
id: dc.theadId,
});
dc.tbody = $A.create("tbody", {
role: "rowgroup",
id: dc.tbodyId,
});
dc.tr = $A.create(
"tr",
{
role: "row",
id: dc.trId,
},
null,
config.gridRowClass,
);
dc.table.appendChild(dc.thead);
dc.table.appendChild(dc.tbody);
dc.thead.appendChild(dc.tr);
var ids = [];
for (var i = 0; i < config.colHeaders.map.length; i++) {
gridInc++;
var o = config.colHeaders.map[i],
th = $A.create(
"th",
{
role: "columnheader",
id: baseId + "th" + gridInc,
scope: "col",
"aria-labelledby": baseId + "th" + gridInc + "s",
tabindex: "-1",
},
null,
config.gridCellClass,
);
config.colHeaders.map[i].thId = baseId + "th" + gridInc;
ids.push(baseId + "th" + gridInc);
if (o.colClass) $A.addClass(th, o.colClass);
$A.on(th, "click", function (ev) {
config.page.row.move();
});
th.innerHTML =
'<strong id="' +
baseId +
"th" +
gridInc +
"s" +
'"><span>' +
formatStr(o.name) +
"</span></strong>";
dc.tr.appendChild(th);
}
dc.container.appendChild(dc.table);
},
beforeRemove: function (dc) {
if (dc.table) $A.remove(dc.table);
dc.table = dc.thead = dc.tbody = dc.tr = null;
},
});
that.id = uId;
that.getDC = function () {
return config.dc;
};
that.container = container;
that.mapColumnNames = function (o) {
if (!o || (typeof o !== "object" && !o.length)) return;
config.colHeaders.map = [];
for (var n = 0; n < o.length; n++) {
config.colHeaders.map.push({
id: o[n].id,
name: o[n].lbl,
colClass: o[n].colClass || "",
});
}
};
that.changeColumnOrder = function (oldVal, newVal) {
if (
isNaN(oldVal) ||
isNaN(newVal) ||
!config.colHeaders.map[oldVal] ||
newVal >= config.colHeaders.map.length
)
return;
var o = config.colHeaders.map.splice(oldVal, 1);
o.splice(0, 0, newVal, 0);
[].splice.apply(config.colHeaders.map, o);
};
that.enableRowHeaders = function (bool, colId) {
config.rowHeaders = {
enabled: bool ? true : false,
id: colId,
};
};
that.setRowMax = function (n) {
config.page.row.max = isNaN(n) ? 0 : n;
};
that.editable = function (bool) {
config.edit = bool ? true : false;
};
that.add = function (rows) {
if (!isArray(rows)) rows = [rows];
$A.loop(
rows,
function (ri, row) {
if (!(!row || (isNaN(row.id) && !row.id) || !row.cells)) {
if (row.id in config.page.row.collection) {
var pos = $A.inArray(row.id, config.page.row.selected);
if (pos !== -1) config.page.row.selected.splice(pos, 1);
config.page.row.clean(config.page.row.collection[row.id]);
$A.remove(config.page.row.collection[row.id].rowNode);
pos = $A.inArray(row.id, config.page.row.collectionMap);
if (pos !== -1) config.page.row.collectionMap.splice(pos, 1);
delete config.page.row.collection[row.id];
}
config.page.row.build(row);
config.page.row.collectionMap.push(row.id);
config.page.row.collection[row.id] = row;
config.page.sync();
}
},
"array",
);
};
that.setChangeListener = function (fn) {
if (typeof fn !== "function") return;
config.page.row.changed.cb = fn;
};
that.setPageChangeListener = function (fn) {
if (typeof fn !== "function") return;
config.page.on.change = fn;
};
that.setEditMaxLength = function (n) {
if (isNaN(n)) n = 0;
config.page.row.editMaxLength = n;
};
that.setEditLoadListener = function (fn) {
if (typeof fn !== "function") return;
config.page.row.editLoad = fn;
};
that.setPageIndexChangeListener = function (fn) {
if (typeof fn !== "function") return;
config.page.indexChanged = fn;
};
that.setSelect = function (o, undefined) {
if (!o || typeof o !== "object") return;
if ("enable" in o)
config.page.row.selectEnabled = o.enable ? true : false;
if ("toggleClass" in o)
config.page.row.selectClass = o.toggleClass || "selected";
if ("multiSelect" in o)
config.page.row.multiSelect = o.multiSelect ? true : false;
if ("ariaSelect" in o)
config.page.row.ariaSelect = o.ariaSelect ? true : false;
if ("preserve" in o)
config.page.row.preserveSelect = o.preserve ? true : false;
if ("callback" in o)
config.page.row.select.cb =
typeof o.callback === "function" ? o.callback : null;
};
that.unselectAll = function () {
config.page.row.unselectAll();
};
that.selectAll = function () {
config.page.row.selectAll();
};
that.getSelected = function () {
var ret = [];
for (var i = 0; i < config.page.row.selected.length; i++)
ret.push(config.page.row.collection[config.page.row.selected[i]]);
return ret;
};
that.select = function (ids) {
if (!isArray(ids)) ids = [ids];
for (var i = 0; i < ids.length; i++) {
var rowId = ids[i],
rowObject = config.page.row.collection[rowId];
if (
rowObject &&
rowObject.cells &&
rowObject.cells[config.colHeaders.map[0].id]
) {
config.page.row.select(
rowObject.cells[config.colHeaders.map[0].id],
true,
);
}
}
};
that.setDelete = function (o) {
if (!o || typeof o !== "object") return;
if ("enable" in o)
config.page.row.deleteRow.enabled = o.enable ? true : false;
if ("callback" in o)
config.page.row.deleteRow.callback.cb =
typeof o.callback === "function" ? o.callback : null;
if ("runBefore" in o)
config.page.row.deleteRow.callback.runBefore =
typeof o.runBefore === "function" ? o.runBefore : null;
if ("runAfter" in o)
config.page.row.deleteRow.callback.runAfter =
typeof o.runAfter === "function" ? o.runAfter : null;
};
that.deleteRows = function (ids) {
if (config.page.row.deleteRow.enabled) {
if (ids && ids.length)
return config.page.row.deleteRow.callback(ids);
else return config.page.row.deleteRow.callback();
}
return false;
};
that.deleteAllRows = function () {
if (config.page.row.deleteRow.enabled) {
return config.page.row.deleteRow.callback(
config.page.row.collectionMap,
);
}
return false;
};
that.setAccessibleText = function (o) {
if (!o || typeof o !== "object") return;
if ("toggleButtonRole" in o)
config.page.row.toggleButtonRole = o.toggleButtonRole;
if ("toggleButtonState" in o)
config.page.row.toggleButtonState = o.toggleButtonState;
if ("disabledText" in o)
config.page.row.disabledText = o.disabledText;
if ("editLinkAction" in o)
config.page.row.editLinkAction = o.editLinkAction;
if ("pageRole" in o) config.page.pageRole = o.pageRole;
if ("editFieldTitle" in o)
config.page.row.editFieldTitle = o.editFieldTitle;
if ("dblClickTitle" in o)
config.page.row.dblClickTitle = o.dblClickTitle;
if ("selectState" in o) config.page.row.selectState = o.selectState;
};
that.setStaticClasses = function (o) {
if (!o || typeof o !== "object") return;
if ("gridClass" in o) config.gridClass = o.gridClass;
if ("gridReadOnlyClass" in o)
config.gridReadOnlyClass = o.gridReadOnlyClass;
if ("cellReadOnlyClass" in o)
config.cellReadOnlyClass = o.cellReadOnlyClass;
if ("gridEditableClass" in o)
config.gridEditableClass = o.gridEditableClass;
if ("gridSelectableClass" in o)
config.gridSelectableClass = o.gridSelectableClass;
if ("gridRowClass" in o) config.gridRowClass = o.gridRowClass;
if ("gridCellClass" in o) config.gridCellClass = o.gridCellClass;
if ("gridCellToggleClass" in o)
config.gridCellToggleClass = o.gridCellToggleClass;
if ("gridCellTogglePressedClass" in o)
config.gridCellTogglePressedClass = o.gridCellTogglePressedClass;
if ("gridCellLinkClass" in o)
config.gridCellLinkClass = o.gridCellLinkClass;
if ("gridRowFocusedClass" in o)
config.gridRowFocusedClass = o.gridRowFocusedClass;
if ("gridCellFocusedClass" in o)
config.gridCellFocusedClass = o.gridCellFocusedClass;
if ("editFieldClass" in o) config.editFieldClass = o.editFieldClass;
};
that.currentPage = function () {
return config.page.current;
};
that.totalPages = function () {
return config.page.total;
};
that.totalRows = function () {
return config.page.row.collectionMap.length;
};
that.openPage = function (n, reOpen) {
if (isNaN(n) || n < 1) return;
config.page.open(n, reOpen);
};
that.prevPage = function () {
if (!config.dc.loaded) return;
var cellObject = getCellObject();
config.page.prev(cellObject, cellObject.rowObject);
};
that.nextPage = function () {
if (!config.dc.loaded) return;
var cellObject = getCellObject();
config.page.next(cellObject, cellObject.rowObject);
};
that.firstPage = function () {
if (!config.dc.loaded) return;
var cellObject = getCellObject();
config.page.first(cellObject, cellObject.rowObject);
};
that.lastPage = function () {
if (!config.dc.loaded) return;
var cellObject = getCellObject();
config.page.last(cellObject, cellObject.rowObject);
};
that.setOpenListener = function (f) {
if (f && typeof f === "function") config.page.on.open = f;
};
that.setCloseListener = function (f) {
if (f && typeof f === "function") config.page.on.close = f;
};
that.setAddListener = function (f) {
if (f && typeof f === "function") config.page.on.add = f;
};
that.setRemoveListener = function (f) {
if (f && typeof f === "function") config.page.on.rem = f;
};
that.setMoveListener = function (f) {
if (f && typeof f === "function") config.page.row.move.cb = f;
};
that.getData = function (rowId, cellId, keyName) {
if (
!rowId ||
!cellId ||
!keyName ||
!(rowId in config.page.row.collection) ||
!(cellId in config.page.row.collection[rowId].cells)
)
return null;
return config.page.row.collection[rowId].cells[cellId].data[keyName];
};
that.setData = function (rowId, cellId, keyName, data) {
if (
!rowId ||
!cellId ||
!keyName ||
!(rowId in config.page.row.collection) ||
!(cellId in config.page.row.collection[rowId].cells)
)
return;
config.page.row.collection[rowId].cells[cellId].data[keyName] = data;
};
that.getValue = function (rowId, cellId) {
if (
!rowId ||
!cellId ||
!(rowId in config.page.row.collection) ||
!(cellId in config.page.row.collection[rowId].cells)
)
return null;
return config.page.row.collection[rowId].cells[cellId].value;
};
that.setValue = function (rowId, cellId, value) {
config.page.row.update(rowId, cellId, value, true);
};
that.setEditOffset = function (f) {
if (f && typeof f === "function") config.page.row.cellOffset = f;
};
that.open = function (n) {
config.page.open(n, true);
};
that.close = function () {
config.page.close();
};
that.focus = function () {
config.page.row.move();
};
var useDblClick = false;
that.useDblClick = function (b) {
useDblClick = b ? true : false;
};
return that;
},
});
var formatStr = function (s, q) {
var str = "";
if (typeof s === "number") str = s.toString();
else str = s;
var i = str.length,
aRet = [];
while (i--) {
var iC = str[i].charCodeAt();
if (str[i] != "\n" && (iC < 65 || iC > 127 || (iC > 90 && iC < 97)))
aRet[i] = "&#" + iC + ";";
else aRet[i] = str[i];
}
return aRet.join("");
};
})();