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 =...