Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit.

  • Loading branch information...
commit efed1594f89b9f574184c8cfa73fbace294c9c56 0 parents
Anthony Super antscode authored
0  COMMITMESSAGE
No changes.
85 assets/datatablegrouper.css
... ... @@ -0,0 +1,85 @@
  1 +/* The group cell */
  2 +.yui-skin-sam .yui-dt .group
  3 +{
  4 + border-top: 1px solid #CBCBCB;
  5 + border-bottom: 1px solid #7f7f7f;
  6 + font-weight: bold;
  7 + background-image: url(http://yui.yahooapis.com/2.7.0/build/assets/skins/sam/sprite.png);
  8 + background-position: 0px -1300px;
  9 + position: absolute;
  10 + margin-top: -24px; /* Makes the group appear above the first row. Set to the height of the group. */
  11 + color: black;
  12 + cursor: default;
  13 +}
  14 +
  15 +/* Group inner style */
  16 +.yui-skin-sam .yui-dt .group .liner
  17 +{
  18 + padding: 4px 10px;
  19 + border-right: 1px solid #CBCBCB;
  20 +}
  21 +
  22 +/* Selected group */
  23 +.yui-skin-sam .yui-dt .group-selected
  24 +{
  25 + background-image: none;
  26 + background-color: #426FD9;
  27 + color: White;
  28 +}
  29 +
  30 +/* Make the group headers scroll with the other rows */
  31 +.yui-dt-scrollable .yui-dt-bd {
  32 + //position:relative;
  33 +}
  34 +
  35 +/* The first group in the data table */
  36 +.yui-skin-sam .yui-dt .group-first
  37 +{
  38 + border-top: 1px solid #7f7f7f;
  39 +}
  40 +
  41 +/* The first row in the group */
  42 +.yui-skin-sam .yui-dt .group-first-row td
  43 +{
  44 + padding-top: 24px; /* Room for the header to appear above the first row. Set to the height of the group. */
  45 +}
  46 +
  47 +/* The group when collapsed */
  48 +.yui-skin-sam .yui-dt .group-collapsed
  49 +{
  50 + margin-top: 0px; /* Makes the group cover up the first row in the group. */
  51 +}
  52 +
  53 +/* The first rown in the group when collapsed */
  54 +.yui-skin-sam .yui-dt .group-first-row-collapsed td
  55 +{
  56 + padding-top: 0px; /* Makes the group cover up the first row in the group. */
  57 +}
  58 +
  59 +/* Base styles for the group icon */
  60 +.yui-skin-sam .yui-dt .group .icon
  61 +{
  62 + width: 18px;
  63 + height: 15px;
  64 + position: absolute;
  65 +}
  66 +
  67 +/* The label within the group */
  68 +.yui-skin-sam .yui-dt .group .label
  69 +{
  70 + margin-left: 25px;
  71 +}
  72 +
  73 +/* The group icon when expanded */
  74 +.yui-skin-sam .yui-dt .group-expanded .icon
  75 +{
  76 + background-image: url(dt-group-arrow-down.png);
  77 + background-repeat: no-repeat;
  78 +}
  79 +
  80 +/* The group icon when collapsed */
  81 +.yui-skin-sam .yui-dt .group-collapsed .icon
  82 +{
  83 + background-image: url(dt-group-arrow-up.png);
  84 + background-repeat: no-repeat;
  85 +}
BIN  assets/dt-group-arrow-down.png
BIN  assets/dt-group-arrow-up.png
22 data.js
... ... @@ -0,0 +1,22 @@
  1 +data = {
  2 + addresses: [
  3 + { name:"John A. Smith", address:"1236 Some Street", city:"Melbourne", state:"Victoria", amount:5, active:"yes", colors:["red"], last_login:"4/19/2007"},
  4 + { name: "John D. Smith", address: "1623 Some Street", city: "Melbourne", state: "Victoria", amount: 5, active: "yes", colors: ["red"], last_login: "4/19/2007" },
  5 + { name: "Bob C. Uncle", address: "9996 Random Road", city: "Melbourne", state: "Victoria", amount: 0, active: "maybe", colors: ["green"], last_login: "1/23/2004" },
  6 + { name: "Bob F. Uncle", address: "9899 Random Road", city: "Melbourne", state: "Victoria", amount: 0, active: "maybe", colors: ["green"], last_login: "1/23/2004" },
  7 + { name: "John G. Smith", address: "1723 Some Street", city: "Melbourne", state: "Victoria", amount: 5, active: "yes", colors: ["red"], last_login: "4/19/2007" },
  8 + { name: "Bob I. Uncle", address: "9909 Random Road", city: "Sydney", state: "New South Wales", amount: 0, active: "maybe", colors: ["green"], last_login: "1/23/2004" },
  9 + { name: "John J. Smith", address: "1623 Some Street", city: "Sydney", state: "New South Wales", amount: 5, active: "yes", colors: ["red"], last_login: "4/19/2007" },
  10 + { name: "Bob L. Uncle", address: "9989 Random Road", city: "Sydney", state: "New South Wales", amount: 0, active: "maybe", colors: ["green"], last_login: "1/23/2004" },
  11 + { name: "John M. Smith", address: "1293 Some Street", city: "Perth", state: "Western Australia", amount: 5, active: "yes", colors: ["red"], last_login: "4/19/2007" },
  12 + { name: "Bob O. Uncle", address: "9959 Random Road", city: "Perth", state: "Western Australia", amount: 0, active: "maybe", colors: ["green"], last_login: "1/23/2004" },
  13 + { name: "John P. Smith", address: "6123 Some Street", city: "Brisbane", state: "Queensland", amount: 5, active: "yes", colors: ["red"], last_login: "4/19/2007" },
  14 + { name: "Bob R. Uncle", address: "9989 Random Road", city: "Brisbane", state: "Queensland", amount: 0, active: "maybe", colors: ["green"], last_login: "1/23/2004" },
  15 + { name: "Joan B. Jones", address: "3271 Another Ave", city: "Brisbane", state: "Queensland", amount: 3, active: "no", colors: ["red", "blue"], last_login: "2/15/2006" },
  16 + { name: "Joan E. Jones", address: "3217 Another Ave", city: "Brisbane", state: "Queensland", amount: 3, active: "no", colors: ["red", "blue"], last_login: "2/15/2006" },
  17 + {name:"Joan H. Jones", address:"3241 Another Ave", city:"Darwin", state:"Nortern Territory", amount:3, active:"no", colors:["red","blue"], last_login:"2/15/2006"},
  18 + { name: "Joan K. Jones", address: "3721 Another Ave", city: "Darwin", state: "Nortern Territory", amount: 3, active: "no", colors: ["red", "blue"], last_login: "2/15/2006" },
  19 + {name:"Joan N. Jones", address:"3621 Another Ave", city:"Hobart", state:"Tasmania", amount:3, active:"no", colors:["red","blue"], last_login:"2/15/2006"},
  20 + { name: "Joan Q. Jones", address: "3281 Another Ave", city: "Hobart", state: "Tasmania", amount: 3, active: "no", colors: ["red", "blue"], last_login: "2/15/2006" }
  21 + ]
  22 +};
309 datatablegrouper.js
... ... @@ -0,0 +1,309 @@
  1 +/**
  2 +* Adds grouping functionality to a YUI DataTable.
  3 +* http://datatablegrouper.codeplex.com
  4 +*
  5 +* Copyright (c) 2009 Anthony Super
  6 +* http://antscode.blogspot.com
  7 +*
  8 +* @class DataTableGrouper
  9 +* @contructor
  10 +* @param groupBy {string} The data field to group by.
  11 +*/
  12 +var DataTableGrouper = function(groupBy) {
  13 + var dom = YAHOO.util.Dom,
  14 + event = YAHOO.util.Event;
  15 +
  16 + /**
  17 + * A reference to the current class instance.
  18 + * @property _this
  19 + * @type {Object}
  20 + * @private
  21 + */
  22 + var _this = this;
  23 +
  24 + /**
  25 + * The YUI data table associated with this object.
  26 + * @property dataTable
  27 + * @type {Object}
  28 + * @private
  29 + */
  30 + this.dataTable = null;
  31 +
  32 + /**
  33 + * The current group name. Used to determine when a new group starts when rowFormatter is called.
  34 + * @property currentGroupName
  35 + * @type {String}
  36 + * @private
  37 + */
  38 + this.currentGroupName = null;
  39 +
  40 + /**
  41 + * The groups found in the current data set.
  42 + * @property groups
  43 + * @type {Array}
  44 + * @private
  45 + */
  46 + this.groups = [];
  47 +
  48 + /**
  49 + * A flag to reset the group array. Set each time a new data set is passed.
  50 + * @property resetGroups
  51 + * @type {Boolean}
  52 + * @private
  53 + */
  54 + this.resetGroups = true;
  55 +
  56 + /**
  57 + * Event handler for group click.
  58 + * @property groupClickEvent
  59 + * @type {Event}
  60 + */
  61 + this.onGroupClick = new YAHOO.util.CustomEvent("onGroupClick", this);
  62 +
  63 + /**
  64 + * The currently selected group
  65 + * @property groupClickEvent
  66 + * @type {Event}
  67 + */
  68 + this.selectedGroup = null;
  69 +
  70 + /**
  71 + * Initialises the grouper.
  72 + * @method init
  73 + * @param parent {Object} The YUI DataTable to apply the grouping to.
  74 + */
  75 + this.init = function(dataTable) {
  76 + this.dataTable = dataTable;
  77 +
  78 + // Initialise the groups
  79 + this.initGroups(); /* Not required but prevents flickering */
  80 +
  81 + // Re-initialise the groups when data is changed
  82 + dataTable.subscribe("sortedByChange", function() { _this.initGroups() }); /* Not required but prevents flickering */
  83 + dataTable.subscribe("renderEvent", function() { _this.initGroups() });
  84 +
  85 + // Update group widths when columns are resized
  86 + dataTable.subscribe("columnSetWidthEvent", function() { _this.resizeGroups() });
  87 +
  88 + // Unselect any group when a row is clicked
  89 + dataTable.subscribe("rowClickEvent", function() { _this.unselectGroup() });
  90 + }
  91 +
  92 + /**
  93 + * A YUI DataTable custom row formatter. The row formatter must be applied to the DataTable
  94 + * via the formatRow configuration property.
  95 + * @method rowFormatter
  96 + * @param tr {Object} To row to be formatted.
  97 + * @param record {Object} To current data record.
  98 + */
  99 + this.rowFormatter = function(tr, record) {
  100 + if (this.resetGroups) {
  101 + this.groups = [];
  102 + this.currentGroupName = null;
  103 + this.resetGroups = false;
  104 + }
  105 +
  106 + var groupName = record.getData(groupBy);
  107 +
  108 + if (groupName != this.currentGroupName) {
  109 + this.groups.push({ name: groupName, row: tr, group: null });
  110 + dom.addClass(tr, "group-first-row");
  111 + }
  112 +
  113 + this.currentGroupName = groupName;
  114 + return true;
  115 + };
  116 +
  117 + /**
  118 + * Initialises the groups for the current data set.
  119 + * @method initGroups
  120 + * @private
  121 + */
  122 + this.initGroups = function() {
  123 + if (!this.resetGroups) {
  124 + // Insert each group in the array
  125 + for (var i = 0; i < this.groups.length; i++) {
  126 + this.groups[i].group = this.insertGroup(this.groups[i].name, this.groups[i].row);
  127 + }
  128 +
  129 + this.resetGroups = true;
  130 + }
  131 + }
  132 +
  133 + /**
  134 + * Updates the width of all groups to match the data table.
  135 + * @method resizeGroups
  136 + * @private
  137 + */
  138 + this.resizeGroups = function() {
  139 + // Insert each group in the array
  140 + for (var i = 0; i < this.groups.length; i++) {
  141 + this.setGroupWidth(this.groups[i].group, this.groups[i].row);
  142 + }
  143 + }
  144 +
  145 + /**
  146 + * Sets the width of a group to the parent row width.
  147 + * @method resizeGroups
  148 + * @param group {Object} To group to set width to.
  149 + * @param row {Object} To row to get width from.
  150 + * @private
  151 + */
  152 + this.setGroupWidth = function(group, row) {
  153 + group.style.width = dom.getRegion(row).width + "px";
  154 + }
  155 +
  156 + /**
  157 + * Inserts a group before the specified row.
  158 + * @method insertGroup
  159 + * @param name {String} The name of the group.
  160 + * @param beforeRow {Object} To row to insert the group.
  161 + * @private
  162 + */
  163 + this.insertGroup = function(name, row) {
  164 + var group = document.createElement("div");
  165 + var icon = document.createElement("div");
  166 +
  167 + // Row is expanded by default
  168 + group.className = "group group-expanded";
  169 +
  170 + if (dom.hasClass(row, "yui-dt-first")) {
  171 + // If this is the first row in the table, transfer the class to the group
  172 + dom.removeClass(row, "yui-dt-first");
  173 + dom.addClass(group, "group-first");
  174 + }
  175 +
  176 + // Add a liner as per standard YUI cells
  177 + var liner = document.createElement("div");
  178 + liner.className = "liner";
  179 +
  180 + // Add icon
  181 + icon.className = "icon";
  182 + liner.appendChild(icon);
  183 +
  184 + // Add label
  185 + var label = document.createElement("div");
  186 + label.innerHTML = name;
  187 + label.className = "label";
  188 + liner.appendChild(label);
  189 + group.appendChild(liner);
  190 +
  191 + // Set the width of the group
  192 + this.setGroupWidth(group, row);
  193 +
  194 + // Insert the group
  195 + var cell = row.cells[0];
  196 + dom.insertBefore(group, cell.childNodes[0]);
  197 +
  198 + // Attach visibility toggle to icon click
  199 + event.addListener(icon, "click", function(e) { _this.toggleVisibility(e) });
  200 +
  201 + // Attach group click event handler
  202 + event.addListener(group, "click", function(e) { _this.handleGroupClick(e) });
  203 +
  204 + return group;
  205 + }
  206 +
  207 + /**
  208 + * Handles the group click event.
  209 + * @method handleGroupClick
  210 + * @param e {Event} The event fired from clicking the group.
  211 + * @private
  212 + */
  213 + this.handleGroupClick = function(e) {
  214 + var group = dom.getAncestorByClassName(event.getTarget(e), "group");
  215 +
  216 + // Fire the onGroupClick event
  217 + this.onGroupClick.fire(group);
  218 +
  219 + // Stop the event to prevent the row from being selected
  220 + event.stopEvent(e);
  221 + return false;
  222 + }
  223 +
  224 + /**
  225 + * Handles the group select event.
  226 + * @method onEventSelectGroup
  227 + * @param type {String} The type of event fired.
  228 + * @param e {Object} The selected group.
  229 + * @private
  230 + */
  231 + this.onEventSelectGroup = function(type, group) {
  232 + this.selectGroup(group);
  233 + }
  234 +
  235 + /**
  236 + * Selects a group.
  237 + * @method selectGroup
  238 + */
  239 + this.selectGroup = function(group) {
  240 + // Unselect any previous group
  241 + this.unselectGroup();
  242 +
  243 + // Select the new group
  244 + dom.addClass(group, "group-selected");
  245 + this.selectedGroup = group;
  246 +
  247 + // Unselect all rows in the data table
  248 + var selectedRows = this.dataTable.getSelectedTrEls();
  249 +
  250 + for (var i = 0; i < selectedRows.length; i++) {
  251 + this.dataTable.unselectRow(selectedRows[i]);
  252 + }
  253 + }
  254 +
  255 + /**
  256 + * Unselects any selected group.
  257 + * @method unselectGroup
  258 + */
  259 + this.unselectGroup = function() {
  260 + if (this.selectedGroup) {
  261 + dom.removeClass(this.selectedGroup, "group-selected");
  262 + }
  263 + }
  264 +
  265 + /**
  266 + * Toggles the visibility of the group specified in the event.
  267 + * @method toggleVisibility
  268 + * @param e {Event} The event fired from clicking the group.
  269 + * @private
  270 + */
  271 + this.toggleVisibility = function(e) {
  272 + var group = dom.getAncestorByClassName(event.getTarget(e), "group");
  273 + var row = dom.getAncestorByTagName(group, "tr");
  274 + var visibleState;
  275 +
  276 + // Change the class of the group
  277 + if (dom.hasClass(group, "group-expanded")) {
  278 + visibleState = false;
  279 + dom.replaceClass(group, "group-expanded", "group-collapsed");
  280 + }
  281 + else {
  282 + visibleState = true;
  283 + dom.replaceClass(group, "group-collapsed", "group-expanded");
  284 + }
  285 +
  286 + // Change the class of the first row
  287 + if (!visibleState) {
  288 + dom.replaceClass(row, "group-first-row", "group-first-row-collapsed");
  289 + }
  290 + else {
  291 + dom.replaceClass(row, "group-first-row-collapsed", "group-first-row");
  292 + }
  293 +
  294 + // Hide all subsequent rows in the group
  295 + row = dom.getNextSibling(row);
  296 +
  297 + while (row && !dom.hasClass(row, "group-first-row") &&
  298 + !dom.hasClass(row, "group-first-row-collapsed")) {
  299 + if (visibleState) {
  300 + row.style.display = "table-row";
  301 + }
  302 + else {
  303 + row.style.display = "none";
  304 + }
  305 +
  306 + row = dom.getNextSibling(row);
  307 + }
  308 + }
  309 +}
58 example.htm
... ... @@ -0,0 +1,58 @@
  1 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2 +<html xmlns="http://www.w3.org/1999/xhtml">
  3 +<head>
  4 + <title>YUI Data Table Grouper Example</title>
  5 + <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/fonts/fonts-min.css" />
  6 + <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/datatable/assets/skins/sam/datatable.css" />
  7 + <link rel="stylesheet" type="text/css" href="assets/datatablegrouper.css" />
  8 + <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
  9 + <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/dragdrop/dragdrop-min.js"></script>
  10 + <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/element/element-min.js"></script>
  11 + <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/datasource/datasource-min.js"></script>
  12 + <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/datatable/datatable.js"></script>
  13 + <script type="text/javascript" src="data.js"></script>
  14 + <script type="text/javascript" src="datatablegrouper.js"></script>
  15 +</head>
  16 +<body class="yui-skin-sam">
  17 +<div id="dtContainer"></div>
  18 +<script type="text/javascript">
  19 +
  20 + // Define the columns for the data table
  21 + // Note that you should not include the column you want to group by
  22 + var myColumnDefs = [
  23 + { key: "city", label: "City", sortable: true, resizeable: true, width: 200 },
  24 + { key: "name", label: "Name", sortable: true, resizeable: true, width: 150 }
  25 + ];
  26 +
  27 + // Initialise the data source
  28 + // Ensure that you also include the field to group by in the responseSchema
  29 + var myDataSource = new YAHOO.util.DataSource(data.addresses); // See data.js
  30 + myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
  31 + myDataSource.responseSchema = {
  32 + fields: ["state", "city", "name"]
  33 + };
  34 +
  35 + // Create a DataTableGrouper, passing the name of the field to group by
  36 + var myGrouper = new DataTableGrouper("state");
  37 +
  38 + // Create a YUI DataTable based on the supplied columns & data source
  39 + var myDataTable = new YAHOO.widget.DataTable("dtContainer",
  40 + myColumnDefs, myDataSource,
  41 + {
  42 + // The following row formatter must be specified in order for the grouping
  43 + // to occur.
  44 + formatRow: function(el, record) { return myGrouper.rowFormatter(el, record) }
  45 + });
  46 +
  47 + // Demonstrate row selection
  48 + myDataTable.subscribe("rowClickEvent", myDataTable.onEventSelectRow);
  49 +
  50 + // Demonstrate group selection
  51 + myGrouper.onGroupClick.subscribe(myGrouper.onEventSelectGroup);
  52 +
  53 + // Initialise the DataTableGrouper
  54 + myGrouper.init(myDataTable);
  55 +
  56 +</script>
  57 +</body>
  58 +</html>
61 modified_example.htm
... ... @@ -0,0 +1,61 @@
  1 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2 +<html xmlns="http://www.w3.org/1999/xhtml">
  3 +<head>
  4 + <title>YUI Data Table Grouper Example</title>
  5 + <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/fonts/fonts-min.css" />
  6 + <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.7.0/build/datatable/assets/skins/sam/datatable.css" />
  7 + <link rel="stylesheet" type="text/css" href="assets/datatablegrouper.css" />
  8 + <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
  9 + <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/dragdrop/dragdrop-min.js"></script>
  10 + <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/element/element-min.js"></script>
  11 + <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/datasource/datasource-min.js"></script>
  12 + <script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/datatable/datatable.js"></script>
  13 + <script type="text/javascript" src="data.js"></script>
  14 + <script type="text/javascript" src="datatablegrouper.js"></script>
  15 +</head>
  16 +<body class="yui-skin-sam">
  17 +<div id="dtContainer"></div>
  18 +<script type="text/javascript">
  19 +
  20 + // Define the columns for the data table
  21 + // Note that you should not include the column you want to group by
  22 + var myColumnDefs = [
  23 + { key: "city", label: "City", sortable: true, resizeable: true, width: 200, editor:new YAHOO.widget.TextboxCellEditor({disableBtns:false})},
  24 + { key: "name", label: "Name", sortable: true, resizeable: true, width: 150 }
  25 + ];
  26 +
  27 + // Initialise the data source
  28 + // Ensure that you also include the field to group by in the responseSchema
  29 + var myDataSource = new YAHOO.util.DataSource(data.addresses); // See data.js
  30 + myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
  31 + myDataSource.responseSchema = {
  32 + fields: ["state", "city", "name"]
  33 + };
  34 +
  35 + // Create a DataTableGrouper, passing the name of the field to group by
  36 + var myGrouper = new DataTableGrouper("state");
  37 +
  38 + // Create a YUI DataTable based on the supplied columns & data source
  39 + var myDataTable = new YAHOO.widget.DataTable("dtContainer",
  40 + myColumnDefs, myDataSource,
  41 + {
  42 + // The following row formatter must be specified in order for the grouping
  43 + // to occur.
  44 + formatRow: function(el, record) { return myGrouper.rowFormatter(el, record) }
  45 + });
  46 +
  47 + // cell editing
  48 + myDataTable.subscribe("cellClickEvent", myDataTable.onEventShowCellEditor);
  49 +
  50 + // Demonstrate row selection
  51 + myDataTable.subscribe("rowClickEvent", myDataTable.onEventSelectRow);
  52 +
  53 + // Demonstrate group selection
  54 + myGrouper.onGroupClick.subscribe(myGrouper.onEventSelectGroup);
  55 +
  56 + // Initialise the DataTableGrouper
  57 + myGrouper.init(myDataTable);
  58 +
  59 +</script>
  60 +</body>
  61 +</html>

0 comments on commit efed159

Please sign in to comment.
Something went wrong with that request. Please try again.