JsViews Maps: Sorted Table Grid Views
This sample will probably be added to jsviews.com
by BorisMoore
HTML
<script src="//www.jsviews.com/download/jsviews.js"></script>
<link rel="stylesheet" href="//www.jsviews.com/samples/samples.css">
<div id="page"></div>
<script type="text/x-jsrender" id="tmpl">
<h4>View one</h4>
{^{pager rows cols pageLength=12 page=1 sortby='role'}}
<div class="pagerHeader one">
{^{pager_header/}}
</div>
<table class="grid">
<tbody><tr>
{^{for ~tag.cols}}
<td data-link="{on ~tag.sort #index}">
{{:label}}
{^{if ~tag.options.sortby === field}}
{{!--<img data-link="src{:~tag.options.reverseSort ? 'images/up.png' : 'images/down.png'}" />--}}
<span data-link="~tag.options.reverseSort ? '^' : 'v'" ></span>
{{/if}}
</td>
{{/for}}
<td></td>
</tr></tbody>
<tbody>
{^{pager_rows}}
<tr>
{^{props}}
<td><input data-link="prop" /></td>
{{/props}}
<td><button class="delete" data-link="{on ~parentTags.pager.remove #index}"></button></td>
</tr>
{{/pager_rows}}
{^{pager_add_row}}
<tr class="addRow">
{^{props}}
<td><input data-link="{:prop:} {on 'keydown' ~parentTags.pager.insert}" /></td>
{{/props}}
<td><button data-link="{on ~parentTags.pager.add}">add</button></td>
</tr>
{{/pager_add_row}}
</tbody>
</table>
{{/pager}}
<h4>View two</h4>
{^{pager rows cols pageLength=2 page=1 sortby='name'}}
<div class="pagerHeader two">
{^{pager_header/}}
</div>
<table class="grid">
<tbody><tr>
{^{for ~tag.cols}}
<td data-link="{on ~tag.sort #index}">
{{:label}}
{^{if ~tag.options.sortby === field}}
{{!--<img data-link="src{:~tag.options.reverseSort ? 'images/up.png' : 'images/down.png'}" />--}}
<span data-link="~tag.options.reverseSort ? '^' : 'v'" ></span>
{{/if}}
</td>
{{/for}}
<td></td>
</tr></tbody>
<tbody>
{^{pager_rows}}
<tr>
{^{props}}
<td><input data-link="prop" /></td>
{{/props}}
<td><button...
CSS
.pagerHeader input {
width: 30px;
}
.pagerHeader select {
width: 60px;
}
.pagerHeader input[type=checkbox] {
width: auto;
}
.pagerHeader .nav {
width: 20px;
height: 20px;
padding: 0;
}
.delete:before {
content: "\00d7";
color: red;
}
JavaScript
var rowPagerMap = $.views.map({
getTgt: function(rows, options) {
if (options.sortby) {
rows = rows.slice().sort(function(a, b) {
return (options.reverseSort ? -1 : 1) * a[options.sortby].toLowerCase().localeCompare(b[options.sortby].toLowerCase());
});
}
var pageLen = parseInt(options.pageLength),
start = parseInt(options.page) * pageLen - pageLen,
end = start + pageLen;
return rows.slice(start, end);
}
});
$.views.tags({
pager: {
init: function() {
this.rows = this.tagCtx.args[0];
this.cols = this.tagCtx.args[1];
this.options = this.tagCtx.props;
this.rowToAdd = this.createRow();
this.blankRow = this.createRow();
this.map = rowPagerMap.map(this.rows, this.options);
this.updatePage();
},
insert: function(ev) {
if (ev.which === 13) {
// On Enter, insert
this.add();
}
},
add: function() {
$.observable(this.rows).insert(this.createRow(this.rowToAdd));
$.observable(this.rowToAdd).setProperty(this.blankRow);
},
remove: function(index) {
$.observable(this.rows).remove($.inArray(this.map.tgt[index], this.rows));
// (Alternatively: $.inArray(eventArgs.view.data, this.rows) - but that would break if you use itemVar=...)
},
page: function(page) {
$.observable(this.options).setProperty("page", parseInt(page));
},
prevPage: function() {
this.page(this.options.page - 1);
},
nextPage: function() {
this.page(this.options.page + 1);
},
sort: function(index) {
var col = this.cols[index].field;
// (Alternatively: col = eventArgs.view.data.field; - but that would break if you use itemVar=...)
$.observable(this.options).setProperty({
sortby: col,
reverseSort: this.options.sortby === col ? !this.options.reverseSort : false
});
},
updatePage: function() {
$.observable(this).setProperty("isMaxPage", this.options.page * this.options.pageLength >= this.map.src.length);
$.observable(this).setProperty("isMinPage", this.options.page <=...