JsViews Maps: Sorted Table Variants
This sample will probably be added to jsviews.com
by BorisMoore
HTML
<link rel="stylesheet" href="//www.jsviews.com/samples/samples.css">
<script src="//www.jsviews.com/download/jsviews.js"></script>
<script src="//www.jsviews.com/download/sample-tag-controls/jsonview/jsonview.js"></script>
<div id="content"></div>
<script type="text/x-jsrender" id="tmpl">
<h4>Page options</h4>
<div>
Sort column
<select data-link="options.sortby">
{{for cols}}
<option value="{{:field}}">{{:label}}</option>
{{/for}}
</select>
</div>
<div>
Page length <input data-link="options.pageLength trigger=true"/>
</div>
<div>
Page
<select data-link="options.page">
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</div>
<h4>Page options</h4>
<button data-link="{on ~newitem}">new</button>
<h4>Choose Columns</h4>
<table class="nowidth"><tbody>
{^{for cols}}
<tr>
<td>{{:label}}</td>
<td><input type="checkbox" data-link="show" /></td>
</tr>
{{/for}}
</tbody></table>
<h4>Paged Team</h4>
<table class="nowidth"><thead><tr>
{^{for cols}}
{^{if show}}<th>{{:label}}</th>{{/if}}
{{/for}}
<th></th><th></th>
</tr></thead>
<tbody>
{^{for ~pagedRows.tgt}}
<tr>
{^{filteredCols cols=~root.cols}}
<td><input data-link="prop trigger=true" /></td>
{{/filteredCols}}
<td><button data-link="{on ~add}">add</button></td>
<td><button data-link="{on ~remove}">remove</button></td>
</tr>
{{/for}}
</tbody></table>
<h4>Full Team</h4>
<table class="nowsidth"><thead><tr>
{^{for cols}}
<th>{{:label}}</th>
{{/for}}
</tr></thead>
<tbody>
{^{pager rows cols=cols pageLength=5 page=1 sortby='role'}}
<tr>
{^{props}}
<td><input data-link="prop trigger=true" /></td>
{{/props}}
</tr>
{{/pager}}
</tbody></table>
<h4>Paged Team</h4>
<table><thead><tr>
{^{for cols}}
<th>{{:label}}</th>
{{/for}}
</tr></thead>
<tbody>
{^{for...
CSS
.pagerHeader input {
width: 30px;
}
.pagerHeader select {
width: 60px;
}
.pagerHeader input[type=checkbox] {
width: auto;
}
.pagerHeader .nav {
width: 20px;
height: 20px;
padding: 0;
}
JavaScript
var rowPagerMap = $.views.map({
getTgt: function(rows, options) {
if (options.sortby) {
rows = rows.slice().sort(function(a, b) {
return 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);
},
obsSrc: function(map, ev, eventArgs) {
var target = map.tgt;
switch (eventArgs.change) {
case "remove":
var index = $.inArray(eventArgs.items[0], target);
if (index > -1) {
$.observable(target).remove(index);
}
break;
case "insert":
$.observable(target).insert(eventArgs.items);
}
}
}),
filteredColumnsMap = $.views.map({
baseMap: $.views.tags.props.dataMap,
getTgt: function(source, options) {
var key, col, i, l,
tgt = [],
cols = options.cols;
for (i=0, l=cols.length; i<l; i++) {
col = cols[i];
field = col.field;
if (col.show) {
tgt.push({ key: field, prop: source[field] });
}
}
return tgt;
},
obsSrc: function(map, ev, eventArgs) { // This corresponds to obsSrc of props.dataMap, but with filtered columns
if (eventArgs.change === "set") {
var target = map.tgt,
l = target.length;
while (l--) {
if (target[l].key === eventArgs.path) {
break;
}
}
if (l > -1) {
$.observable(target[l]).setProperty("prop", eventArgs.value);
}
}
}
});
$.views.tags({
filteredCols: {
dataMap: filteredColumnsMap,
baseTag: "props",
init: function(tagCtx) {
var tag = this;7
tag.callRefresh = function() {
tag.refresh()
}
$.observable(tagCtx.props.cols).observeAll(tag.callRefresh);
},
onDispose: function() {
$.observable(this.tagCtx.props.cols).unobserveAll(this.callRefresh);
}
},
pager: {
init: function() {
var tag = this;
tag.options = tag.tagCtx.props;
tag.src =...