Skip to content

Commit e2b3766

Browse files
committed
Added keep selection property
1 parent eb9a80e commit e2b3766

File tree

9 files changed

+115
-37
lines changed

9 files changed

+115
-37
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
- (Done) Request and response handler to support JSON object transformation (solved issue [#3](http://github.com/rstaib/jquery-bootgrid/issues/3))
1111
- (Done) WIA-ARIA busy attribute to indicate that the table is loading
1212
- Metadata for rows
13-
- New behaviour to maintain row selection during filtering and sorting
13+
- (Done) New behaviour to maintain row selection during filtering, paging and sorting
1414
- (Done) Entire row click selection
1515
- (Done) New event (`click`)
1616
- (Done) Responsive table support
320 Bytes
Binary file not shown.
375 Bytes
Binary file not shown.

build/jquery.bootgrid.js

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,10 @@
187187
that.total = total;
188188
that.totalPages = Math.ceil(total / that.rowCount);
189189

190-
// clear multi selectbox state
191-
that.element.find("thead " + getCssSelector(that.options.css.selectBox)).prop("checked", false);
190+
if (!that.options.keepSelection)
191+
{
192+
that.selectedRows = [];
193+
}
192194

193195
renderRows.call(that, rows);
194196
renderInfos.call(that);
@@ -564,24 +566,30 @@
564566
tpl = this.options.templates,
565567
tbody = this.element.children("tbody").first(),
566568
selection = this.options.selection && this.identifier != null,
569+
allRowsSelected = true,
567570
html = "",
568571
cells = "",
569-
id = "",
572+
rowAttr = "",
570573
rowCss = "";
571574

572575
$.each(rows, function (i, row)
573576
{
574577
cells = "";
575-
id = " data-row-id=\"" + ((that.identifier == null) ? i : row[that.identifier]) + "\"";
576-
rowCss = (selection && $.inArray(row[that.identifier], that.selectedRows) !== -1) ?
577-
css.selected : "";
578+
rowAttr = " data-row-id=\"" + ((that.identifier == null) ? i : row[that.identifier]) + "\"";
579+
rowCss = "";
578580

579581
if (selection)
580582
{
581-
var selectBox = tpl.select.resolve(getParams.call(that,
582-
{ type: "checkbox", value: row[that.identifier] }));
583-
cells += tpl.cell.resolve(getParams.call(that, { content: selectBox,
584-
css: css.selectCell }));
583+
var selected = ($.inArray(row[that.identifier], that.selectedRows) !== -1),
584+
selectBox = tpl.select.resolve(getParams.call(that,
585+
{ type: "checkbox", value: row[that.identifier], checked: selected }));
586+
cells += tpl.cell.resolve(getParams.call(that, { content: selectBox, css: css.selectCell }));
587+
allRowsSelected = (allRowsSelected && selected);
588+
if (selected)
589+
{
590+
rowCss += css.selected;
591+
rowAttr += " aria-selected=\"true\"";
592+
}
585593
}
586594

587595
$.each(that.columns, function (j, column)
@@ -599,9 +607,17 @@
599607
}
600608
});
601609

602-
html += tpl.row.resolve(getParams.call(that, { id: id, css: rowCss, cells: cells }));
610+
if (rowCss.length > 0)
611+
{
612+
rowAttr += " class=\"" + rowCss + "\"";
613+
}
614+
html += tpl.row.resolve(getParams.call(that, { attr: rowAttr, cells: cells }));
603615
});
604616

617+
// sets or clears multi selectbox state
618+
that.element.find("thead " + getCssSelector(that.options.css.selectBox))
619+
.prop("checked", allRowsSelected);
620+
605621
tbody.html(html);
606622

607623
registerRowEvents.call(this, tbody);
@@ -646,7 +662,8 @@
646662

647663
var $this = $(this),
648664
id = that.converter.from($this.data("row-id")),
649-
row = that.currentRows.first(function (item) { return item[that.identifier] === id; });
665+
row = (this.identifier == null) ? that.currentRows[id] :
666+
that.currentRows.first(function (item) { return item[that.identifier] === id; });
650667

651668
if (selection && that.options.rowSelect)
652669
{
@@ -990,6 +1007,18 @@
9901007
**/
9911008
rowSelect: false,
9921009

1010+
/**
1011+
* Defines whether the row selection is saved internally on filtering, paging and sorting
1012+
* (even if the selected rows are not visible).
1013+
*
1014+
* @property keepSelection
1015+
* @type Boolean
1016+
* @default false
1017+
* @for defaults
1018+
* @since 1.1.0
1019+
**/
1020+
keepSelection: false,
1021+
9931022
highlightRows: false, // highlights new rows (find the page of the first new row)
9941023
sorting: true,
9951024
multiSort: false,
@@ -1018,6 +1047,15 @@
10181047
**/
10191048
url: "", // or use function () { return ""; }
10201049

1050+
/**
1051+
* Defines whether the search is case sensitive or insensitive.
1052+
*
1053+
* @property caseSensitive
1054+
* @type Boolean
1055+
* @default true
1056+
* @for defaults
1057+
* @since 1.1.0
1058+
**/
10211059
caseSensitive: true,
10221060

10231061
// note: The following properties should not be used via data-api attributes
@@ -1169,9 +1207,9 @@
11691207
pagination: "<ul class=\"{{css.pagination}}\"></ul>",
11701208
paginationItem: "<li class=\"{{ctx.css}}\"><a href=\"{{ctx.uri}}\" class=\"{{css.paginationButton}}\">{{ctx.text}}</a></li>",
11711209
rawHeaderCell: "<th class=\"{{ctx.css}}\">{{ctx.content}}</th>", // Used for the multi select box
1172-
row: "<tr{{ctx.id}} class=\"{{ctx.css}}\">{{ctx.cells}}</tr>",
1210+
row: "<tr{{ctx.attr}}>{{ctx.cells}}</tr>",
11731211
search: "<div class=\"{{css.search}}\"><div class=\"input-group\"><span class=\"{{css.icon}} input-group-addon glyphicon-search\"></span> <input type=\"text\" class=\"{{css.searchField}}\" placeholder=\"{{lbl.search}}\" /></div></div>",
1174-
select: "<input name=\"select\" type=\"{{ctx.type}}\" class=\"{{css.selectBox}}\" value=\"{{ctx.value}}\" />"
1212+
select: "<input name=\"select\" type=\"{{ctx.type}}\" class=\"{{css.selectBox}}\" value=\"{{ctx.value}}\" {{ctx.checked}} />"
11751213
}
11761214
};
11771215

@@ -1388,7 +1426,8 @@
13881426
for (i = 0; i < this.selectedRows.length; i++)
13891427
{
13901428
this.element.find("tbody > tr[data-row-id=\"" + this.selectedRows[i] + "\"]")
1391-
.addClass(this.options.css.selected).find(selectBoxSelector).prop("checked", true);
1429+
.addClass(this.options.css.selected)._bgAria("selected", "true")
1430+
.find(selectBoxSelector).prop("checked", true);
13921431
}
13931432

13941433
this.element.trigger("selected" + namespace, [selectedRows]);
@@ -1441,7 +1480,8 @@
14411480
for (i = 0; i < deselectedRows.length; i++)
14421481
{
14431482
this.element.find("tbody > tr[data-row-id=\"" + deselectedRows[i][this.identifier] + "\"]")
1444-
.removeClass(this.options.css.selected).find(selectBoxSelector).prop("checked", false);
1483+
.removeClass(this.options.css.selected)._bgAria("selected", "false")
1484+
.find(selectBoxSelector).prop("checked", false);
14451485
}
14461486

14471487
this.element.trigger("deselected" + namespace, [deselectedRows]);
@@ -1540,7 +1580,6 @@
15401580
{
15411581
return (value) ? "checked=\"checked\"" : "";
15421582
}
1543-
15441583
return value;
15451584
}
15461585
};

build/jquery.bootgrid.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demo/index.htm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
<button id="destroy" type="button" class="btn btn-default">Destroy</button>
5454
<button id="init" type="button" class="btn btn-default">Init</button>
5555
<div class="table-responsive">
56-
<table id="grid" class="table table-condensed table-hover table-striped" data-selection="true" data-multi-select="true" data-row-select="true">
56+
<table id="grid" class="table table-condensed table-hover table-striped" data-selection="true" data-multi-select="true" data-row-select="true" data-keep-selection="true">
5757
<thead>
5858
<tr>
5959
<th data-column-id="id" data-identifier="true" data-type="numeric" data-align="right">ID</th>

src/extensions.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ if (!String.prototype.resolve)
6262
{
6363
return (value) ? "checked=\"checked\"" : "";
6464
}
65-
6665
return value;
6766
}
6867
};

src/internal.js

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,10 @@ function loadData()
177177
that.total = total;
178178
that.totalPages = Math.ceil(total / that.rowCount);
179179

180-
// clear multi selectbox state
181-
that.element.find("thead " + getCssSelector(that.options.css.selectBox)).prop("checked", false);
180+
if (!that.options.keepSelection)
181+
{
182+
that.selectedRows = [];
183+
}
182184

183185
renderRows.call(that, rows);
184186
renderInfos.call(that);
@@ -554,24 +556,30 @@ function renderRows(rows)
554556
tpl = this.options.templates,
555557
tbody = this.element.children("tbody").first(),
556558
selection = this.options.selection && this.identifier != null,
559+
allRowsSelected = true,
557560
html = "",
558561
cells = "",
559-
id = "",
562+
rowAttr = "",
560563
rowCss = "";
561564

562565
$.each(rows, function (i, row)
563566
{
564567
cells = "";
565-
id = " data-row-id=\"" + ((that.identifier == null) ? i : row[that.identifier]) + "\"";
566-
rowCss = (selection && $.inArray(row[that.identifier], that.selectedRows) !== -1) ?
567-
css.selected : "";
568+
rowAttr = " data-row-id=\"" + ((that.identifier == null) ? i : row[that.identifier]) + "\"";
569+
rowCss = "";
568570

569571
if (selection)
570572
{
571-
var selectBox = tpl.select.resolve(getParams.call(that,
572-
{ type: "checkbox", value: row[that.identifier] }));
573-
cells += tpl.cell.resolve(getParams.call(that, { content: selectBox,
574-
css: css.selectCell }));
573+
var selected = ($.inArray(row[that.identifier], that.selectedRows) !== -1),
574+
selectBox = tpl.select.resolve(getParams.call(that,
575+
{ type: "checkbox", value: row[that.identifier], checked: selected }));
576+
cells += tpl.cell.resolve(getParams.call(that, { content: selectBox, css: css.selectCell }));
577+
allRowsSelected = (allRowsSelected && selected);
578+
if (selected)
579+
{
580+
rowCss += css.selected;
581+
rowAttr += " aria-selected=\"true\"";
582+
}
575583
}
576584

577585
$.each(that.columns, function (j, column)
@@ -589,9 +597,17 @@ function renderRows(rows)
589597
}
590598
});
591599

592-
html += tpl.row.resolve(getParams.call(that, { id: id, css: rowCss, cells: cells }));
600+
if (rowCss.length > 0)
601+
{
602+
rowAttr += " class=\"" + rowCss + "\"";
603+
}
604+
html += tpl.row.resolve(getParams.call(that, { attr: rowAttr, cells: cells }));
593605
});
594606

607+
// sets or clears multi selectbox state
608+
that.element.find("thead " + getCssSelector(that.options.css.selectBox))
609+
.prop("checked", allRowsSelected);
610+
595611
tbody.html(html);
596612

597613
registerRowEvents.call(this, tbody);
@@ -636,7 +652,8 @@ function registerRowEvents(tbody)
636652

637653
var $this = $(this),
638654
id = that.converter.from($this.data("row-id")),
639-
row = that.currentRows.first(function (item) { return item[that.identifier] === id; });
655+
row = (this.identifier == null) ? that.currentRows[id] :
656+
that.currentRows.first(function (item) { return item[that.identifier] === id; });
640657

641658
if (selection && that.options.rowSelect)
642659
{

src/public.js

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ Grid.defaults = {
9494
**/
9595
rowSelect: false,
9696

97+
/**
98+
* Defines whether the row selection is saved internally on filtering, paging and sorting
99+
* (even if the selected rows are not visible).
100+
*
101+
* @property keepSelection
102+
* @type Boolean
103+
* @default false
104+
* @for defaults
105+
* @since 1.1.0
106+
**/
107+
keepSelection: false,
108+
97109
highlightRows: false, // highlights new rows (find the page of the first new row)
98110
sorting: true,
99111
multiSort: false,
@@ -122,6 +134,15 @@ Grid.defaults = {
122134
**/
123135
url: "", // or use function () { return ""; }
124136

137+
/**
138+
* Defines whether the search is case sensitive or insensitive.
139+
*
140+
* @property caseSensitive
141+
* @type Boolean
142+
* @default true
143+
* @for defaults
144+
* @since 1.1.0
145+
**/
125146
caseSensitive: true,
126147

127148
// note: The following properties should not be used via data-api attributes
@@ -273,9 +294,9 @@ Grid.defaults = {
273294
pagination: "<ul class=\"{{css.pagination}}\"></ul>",
274295
paginationItem: "<li class=\"{{ctx.css}}\"><a href=\"{{ctx.uri}}\" class=\"{{css.paginationButton}}\">{{ctx.text}}</a></li>",
275296
rawHeaderCell: "<th class=\"{{ctx.css}}\">{{ctx.content}}</th>", // Used for the multi select box
276-
row: "<tr{{ctx.id}} class=\"{{ctx.css}}\">{{ctx.cells}}</tr>",
297+
row: "<tr{{ctx.attr}}>{{ctx.cells}}</tr>",
277298
search: "<div class=\"{{css.search}}\"><div class=\"input-group\"><span class=\"{{css.icon}} input-group-addon glyphicon-search\"></span> <input type=\"text\" class=\"{{css.searchField}}\" placeholder=\"{{lbl.search}}\" /></div></div>",
278-
select: "<input name=\"select\" type=\"{{ctx.type}}\" class=\"{{css.selectBox}}\" value=\"{{ctx.value}}\" />"
299+
select: "<input name=\"select\" type=\"{{ctx.type}}\" class=\"{{css.selectBox}}\" value=\"{{ctx.value}}\" {{ctx.checked}} />"
279300
}
280301
};
281302

@@ -492,7 +513,8 @@ Grid.prototype.select = function(rowIds)
492513
for (i = 0; i < this.selectedRows.length; i++)
493514
{
494515
this.element.find("tbody > tr[data-row-id=\"" + this.selectedRows[i] + "\"]")
495-
.addClass(this.options.css.selected).find(selectBoxSelector).prop("checked", true);
516+
.addClass(this.options.css.selected)._bgAria("selected", "true")
517+
.find(selectBoxSelector).prop("checked", true);
496518
}
497519

498520
this.element.trigger("selected" + namespace, [selectedRows]);
@@ -545,7 +567,8 @@ Grid.prototype.deselect = function(rowIds)
545567
for (i = 0; i < deselectedRows.length; i++)
546568
{
547569
this.element.find("tbody > tr[data-row-id=\"" + deselectedRows[i][this.identifier] + "\"]")
548-
.removeClass(this.options.css.selected).find(selectBoxSelector).prop("checked", false);
570+
.removeClass(this.options.css.selected)._bgAria("selected", "false")
571+
.find(selectBoxSelector).prop("checked", false);
549572
}
550573

551574
this.element.trigger("deselected" + namespace, [deselectedRows]);

0 commit comments

Comments
 (0)