css Audio - Active file-generic CSS - Active Generic - Active HTML - Active JS - Active SVG - Active Text - Active file-generic Video - Active header Love html icon-new-collection icon-person icon-team numbered-list123 pop-out spinner split-screen star tv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              <section>
	<ul>
		<li>Drag-drop columns by column header</li>
		<li>Sort by clicking column header; toggle ascending / descending</li>
		<li>Resize columns</li>
		<li>Click row to select / deselect, only one or none</li>
		<li>Check box to highlight / unhighlight (separate from select, doesn't need to be)</li>
		<li>Show / hide column toggle</li>
		<li>Comfortable, Cozy, Compact cell sizing</li>
		<li>Keyboard controls: up, down, enter, spacebar</li>
		<li>Options include: data alignment, fixed width, checkboxes, custom events</li>
	</ul>
	<p><button value="selected">Get selected</button><span>[]</span></p>
	<p><button value="checked">Get checked</button><span>[]</span></p>
	<p>
		<label>Name</label><input type="checkbox" value="name" checked>
		<label>Gender</label><input type="checkbox" value="gender" checked>
		<label>Age</label><input type="checkbox" value="age" checked>
	</p>
	<p>
		<select>
			<option value="comfortable">Comfortable</option>
			<option value="cozy">Cozy</option>
			<option value="compact" selected>Compact</option>
		</select>
		
	</p>
</section>
<div id="simpleGrid"></div>
            
          
!
            
              @import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css);

*,*:before,*:after {
	box-sizing: border-box;
}

body {
	margin:0;
}

section {
	font-family: monospace;
	border: 1px solid orange;
	max-width: 700px;
	width: 100%;
	margin: 24px auto;
}

section ul {
	font-size: 150%;
}

section button, section label, section select {
	margin-left: 20px;
	margin-right: 1ch;
}

#simpleGrid {
	max-width: 700px;
	width: 100%;
	margin: 24px auto;
	/* forcing vertical scrollbar */
/* 	height: 120px; */
}

.simpleGrid-grid {
	list-style: none;
	margin: 0;
	padding: 0;
	--resize-width: 10px;
	--border-style: 1px solid #000;
	--checked-color: LightSkyBlue;
	--selected-color: DodgerBlue;
	--hovered-color: WhiteSmoke;
	display: flex;
	border: var(--border-style);
	max-width: 100%;
	max-height: 100%;
	overflow-x: auto;
	overflow-y: auto;
	position: relative;
}

.simpleGrid-grid:focus {
	outline: 0;
}

.simpleGrid-grid.simpleGrid-noselect {
	user-select: none;
}

.simpleGrid-column {
	position: relative;
	flex: 1 0 auto;
	border-left: var(--border-style);
	height: 100%;
}

/* super-fun css selector to determine when to remove vertical borders from a column */
.simpleGrid-column:first-child,
.simpleGrid-column[style*="display"]:first-child + .simpleGrid-column:not([style*="display"]) {
	border-left: none;
}

/* grid cell */
.simpleGrid-th,
.simpleGrid-td {
	display: block;
	padding: 4px;
	white-space: pre;
	overflow: hidden;
	text-overflow: ellipsis;
}

.simpleGrid-grid.compact .simpleGrid-th,
.simpleGrid-grid.compact .simpleGrid-td {
	padding: 4px;
}

.simpleGrid-grid.cozy .simpleGrid-th,
.simpleGrid-grid.cozy .simpleGrid-td {
	padding: 6px;
}

.simpleGrid-grid.comfortable .simpleGrid-th,
.simpleGrid-grid.comfortable .simpleGrid-td {
	padding: 8px;
}

.simpleGrid-left {
	text-align: left;
}

.simpleGrid-center {
	text-align: center;
}

.simpleGrid-right {
	text-align: right;
}

/* grid header cell */
.simpleGrid-th {
	background: #e0e0e0;
	font-weight: 600;
}

.simpleGrid-td {
	border-top: var(--border-style);
}

.simpleGrid-td.simpleGrid-hovered {
	background: var(--hovered-color);
}

.simpleGrid-td.simpleGrid-checked {
	background: var(--checked-color);
	color: #fff;
}

.simpleGrid-td.simpleGrid-selected {
	background: var(--selected-color);
	color: #fff;
}

.simpleGrid-selectColumn {
	text-align: center;
	flex: 0 0 auto;
	z-index: 10;
	background: #fff;
}

.simpleGrid-selectColumn .simpleGrid-td {
	padding-left: 8px;
	padding-right: 8px;
}

.simpleGrid-selectColumn input{
	margin: 0;
}

/* allows for a column to be sorted */
.simpleGrid-sort{
	padding-right: 3ch !important;
	position: relative;
}

.simpleGrid-sort:after {
	content:"\f0dc";
	font-family: fontawesome;
	opacity: .3;
	position: absolute;
	top:50%;
	transform: translatey(-50%);
	right: 1ch;
	cursor: pointer;
}

.simpleGrid-sort.simpleGrid-desc:after{
	content:"\f0d7";
	opacity: 1;
}

.simpleGrid-sort.simpleGrid-asc:after{
	content:"\f0d8";
	opacity: 1;
}

/* allows for a column to be moved */
.simpleGrid-move {
	cursor: move;
}

.simpleGrid-placeholder {
	background: #eee;
	position:relative;
	height: unset;
}

.simpleGrid-placeholder:after {
	content:"";
	position: absolute;
	width: calc(100% - .5em);
	height: calc(100% - .5em);
	margin: .25em;
	border: 2px dashed;
	opacity: .3;
	top:0;
	left:0;
}

.simpleGrid-moving {
	position: absolute;
	z-index: 10;
	background: #fff;
	border: 0;
	outline:var(--border-style);
	overflow: hidden;
}

/* allows for a column to be resized */
.simpleGrid-resize {
	position: absolute;
	width: var(--resize-width);
	height: 100%;
	top:0;
	left: 100%;
	margin-left: calc(var(--resize-width) / -2);
	cursor: col-resize;
	z-index: 11;
	opacity: 0;
}

.simpleGrid-column:last-child .simpleGrid-resize {
	display: none;
}

.simpleGrid-column[style*="width"]:not(:last-child) {
	flex: 0 0 auto;
}
            
          
!
            
              /*
this.columnDefs = [{
	title: 'Header',
	path: 'path.to.data.for.row',
	resize: true / false,
	move: true / false,
	sort: true / false,
	show: true / false
	index: 0, // optional, will otherwise be assigned for column ordering
}]
*/

function SimpleGrid(options){
	
	if(!options.container instanceof HTMLElement) {
		return false;
	}
	
	// reference to the container for the grid
	this.containerEl = options.container;
	// minimum width of a column in pixels, for resizing
	this.minColumnWidth = options.minColumnWidth || 20;
	// toggle checkboxes for multiple selection
	this.checkboxes = typeof options.checkboxes === 'boolean' ? options.checkboxes : true;
	// events to be fired
	this.events = Object.assign(this.getDefaultEvents(), options.events);
	// column definitions
	this.columnDefs = (options.columnDefs || []);
	// we wrap the lines of data so we can hold states (selected, checked)
	this.dataStore = (options.dataStore || []).map((item) => ({data: item, selected: false, checked: false}));
	// a repository of all the cell elements instead of selecting all of them
	this.cells = [];
	// how many pixels a thing should be moved to be considered actually moved
	this.threshold = 10;
	// create the grid
	this.init();
}

SimpleGrid.prototype = {
	constructor: SimpleGrid,
	
	addListeners: function(){

		this.containerEl.addEventListener('mousedown', (e) => {
			if(e.target.classList.contains('simpleGrid-resize')){
				this.prepareResize(e.target.parentNode, e.pageX);
			} else if(e.target.classList.contains('simpleGrid-move') && !e.target.parentNode.classList.contains('simpleGrid-moving')){
				this.prepareMove(e.target.parentNode, e.pageX);
			}
		});
		
		this.containerEl.addEventListener('click', (e) => {
			if(e.target.classList.contains('simpleGrid-td')){
				var cells = e.target.parentNode.querySelectorAll('.simpleGrid-td');
				var index = e.target.classList.contains('simpleGrid-selected') ? -1 : [...cells].indexOf(e.target);
				this.dataStore.forEach((item, i) => item.selected = index === i);
				this.buildRows();
				if(typeof this.events.onClick === 'function') {
					this.events.onClick(this.getItems('selected'));
				}
			}
		});
		
		this.containerEl.addEventListener('mouseover', (e) => {
			if(e.target.classList.contains('simpleGrid-td')){
				var column = e.target.parentNode;
				var index = [...column.children].filter((cell) => cell.classList.contains('simpleGrid-td')).indexOf(e.target);
				this.cells.forEach((cell, i) => {
					cell.classList.toggle('simpleGrid-hovered', Math.floor(i/this.columnDefs.length) === index);
				});
			}
		});
		
		this.containerEl.addEventListener('mouseout', (e) => {
			if(e.target.classList.contains('simpleGrid-td')){
				this.cells.forEach((cell) => cell.classList.remove('simpleGrid-hovered'));
			}
		});
		
		this.containerEl.addEventListener('dblclick', (e) => {
			if(e.target.classList.contains('simpleGrid-resize')){
				e.target.parentNode.style.removeProperty('width');
				this.emptyWidths();
			}
		});
		
		this.containerEl.addEventListener('keydown', (e) => {			
			var selected = this.getItems('selected');

			if(selected.length) {
				var arrowKeys = {
					arrowdown: 1,
					arrowup: -1
				};
				
				// up and down arrow keys
				if(typeof arrowKeys[e.key.toLowerCase()] !== 'undefined'){
					e.preventDefault();
					var selectedIndex = this.dataStore.findIndex((item) => item.selected);
					var nextIndex = selectedIndex + arrowKeys[e.key.toLowerCase()];
					if(nextIndex < 0) nextIndex = this.dataStore.length - 1;
					if(nextIndex >= this.dataStore.length) nextIndex = 0;
					this.dataStore.forEach((item, i) => item.selected = i === nextIndex);
					this.buildRows();
				
				// enter key
				} else if (e.key.toLowerCase() === 'enter') {
					e.preventDefault();
					if(typeof this.events.onEnter === 'function') {
						this.events.onEnter(selected);
					}
				
				// spacebar
				} else if (e.key.toLowerCase() === ' ') {
					e.preventDefault();
					this.dataStore.forEach((item) => {
						if(item.selected) item.checked = !item.checked;
					});
					this.handleMasterCheckbox().buildRows();
					if(typeof this.events.onCheck === 'function') {
						this.events.onCheck(selected);
					}
				}
			}
		});
		
		if(this.checkboxes && this.selectColumn){
			this.selectColumn.addEventListener('change', (e) => {
				if(e.target !== this.masterCheckbox){
					var cells = this.selectColumn.querySelectorAll('.simpleGrid-td');
					var index = [...cells].indexOf(e.target.parentNode);
					this.dataStore[index].checked = e.target.checked;
				} else {
					this.dataStore.forEach((item) => item.checked = e.target.checked);
				};
				this.handleMasterCheckbox().buildRows();
			});
			
		}

		return this;
	},
	
	attemptSort: function(target){
		if(target.classList.contains('simpleGrid-sort')){
			var direction = target.classList.contains('simpleGrid-asc') ? 'simpleGrid-desc' : 'simpleGrid-asc';
			target.classList.remove('simpleGrid-asc', 'simpleGrid-desc');
			target.classList.add(direction);
			var index = [...this.grid.children].indexOf(target.parentNode);
			this.sortColumn(this.columnDefs[index], direction);
		}
	},
	
	beginMove: function(item, e){
		var delta = e.pageX - item.start;
		item.el.style.left = (item.offset + delta) + 'px';
		
		// checking difference between move and sort
		this.moveDelta = Math.max(Math.abs(delta), this.moveDelta);
		
		// do this twice because the placeholder might jump trying to find the right place to go
		this.handlePlaceholder(item, e);
		this.handlePlaceholder(item, e);
		
	},
	
	beginResize: function(item, e){
		var delta = e.pageX - item.start;
		this.resizeDelta = Math.max(Math.abs(delta), this.resizeDelta);
		item.el.style.width = Math.max(item.width + delta, this.minColumnWidth) + 'px';
	},
	
	buildColumns: function(){
		// columns should never be "rebuilt" after the init, only hidden
		this.createIndexes().forEach(this.createColumn, this);
		if(this.checkboxes){
			var def = {
				title: this.getMasterCheckbox(),
				resize: false,
				sort: false,
				index: this.columnDefs.length,
				show: true
			};

			this.selectColumn = this.createColumn(def, this.columnDefs.length);
			this.selectColumn.classList.add('simpleGrid-selectColumn');
			this.columnDefs.push(def);
			// move as if it was done by hand
			this.grid.insertBefore(this.selectColumn, this.grid.firstElementChild);
			this.reindexColumns();
			this.updateColumnVisibility();
		}
		return this;
	},
	
	
	buildRows: function(){
		// clear all rows of data
		this.cells = this.cells.reduce((arr, cell) => {
			cell.remove();
			return arr;
		}, []);
		
		this.dataStore.forEach(this.createDataRow, this);
		this.emptyWidths();
		
		if(this.checkboxes && this.selectColumn){
			this.dataStore.forEach((item, i) => {
				// create checkboxes in cells
				var checkbox = document.createElement('input');
				checkbox.type = 'checkbox';
				checkbox.checked = !!item.checked;
				var cell = this.createCell(checkbox);
				cell.classList.toggle('simpleGrid-selected', !!item.selected);
				cell.classList.toggle('simpleGrid-checked', !!item.checked);
				this.selectColumn.appendChild(cell);
			});
			this.reorderCells();
		}
		
		return this;
	},
	
	createCell: function(content){
		var cell = document.createElement('span');
		this.cells.push(cell);
		cell.className = 'simpleGrid-td';
		cell.appendChild(content);
		return cell;
	},
	
	createColumn: function(def, index){
		
		var column = document.createElement('li');
		var resize = document.createElement('div');
		var headerCell = document.createElement('div');
		column.className = 'simpleGrid-column';
		column.dataset.columnIndex = index;
		
		if(!isNaN(def.width)) {
			column.style.width = Math.max(this.minColumnWidth, def.width) + 'px';
			def.resize = false;
		}
		
		if(def.align) {
			column.classList.add(`simpleGrid-${def.align}`);
		}

		if(def.title) {
			var title = typeof def.title === 'string' ? document.createTextNode(def.title) : def.title;
			headerCell.appendChild(title);
		}
		headerCell.className = 'simpleGrid-th';

		resize.classList.toggle('simpleGrid-resize', typeof def.resize !== 'boolean' || def.resize);
		headerCell.classList.toggle('simpleGrid-move', typeof def.move !== 'boolean' || def.move);
		headerCell.classList.toggle('simpleGrid-sort', typeof def.sort !== 'boolean' || def.sort);
		
		column.appendChild(resize);
		column.appendChild(headerCell);

		this.grid.appendChild(column);
		return column;
	},
	
	createDataRow: function(row){
		// each row is created by appending the correct data to the correct column
		this.columnDefs.map((def) => def.path).forEach((path, i) => {
			if(path){
			   	var data = this.getDataFromPath(row.data, path);
				var text = document.createTextNode(data);
				var cell = this.createCell(text);
				cell.classList.toggle('simpleGrid-selected', !!row.selected);
				cell.classList.toggle('simpleGrid-checked', !!row.checked);
				this.grid.children[i].appendChild(cell);
			}
		});
	},
	
	createIndexes: function(){
		// format all defs; indexes should be less that the length - 1
		var columns = this.columnDefs.map((def, i, arr) => {
			if(!isNaN(def.index) && def.index >= arr.length) def.index = null;
			return def;
		});
		
		// find all defs without indexes
		var orphans = this.columnDefs.filter((def) => isNaN(def.index));
		
		// now assign indexes to orphans
		this.columnDefs = columns.map((def, i, arr) => {
			var withIndex = arr.find((def) => def.index === i);
			if(!withIndex) {
				withIndex = orphans.shift();
				withIndex.index = i;
			}
			return withIndex;
		});
		
		// sort and assign new indexes
		this.columnDefs.sort((a, b) => a.index > b.index).forEach((def, i) => def.index = i);
		
		return this.columnDefs;
	},
	
	createPlaceholder: function(width){
		var placeholder = document.createElement('li');
		placeholder.classList.add('simpleGrid-column', 'simpleGrid-placeholder');
		placeholder.style.width = parseInt(width) + 'px';
		return placeholder;
	},
	
	emptyWidths: function(){
		// if columns are hidden, this will handle it
		var lastVisibleEl = [...this.grid.children].reduce((lastEl, thisEl, i) => {
			return this.columnDefs[i].show ? thisEl : lastEl;
		}, this.grid.lastElementChild);
		
		// this will remove width styles from columns that don't need it
		[...this.grid.children].forEach((column, i) => {	
			if(isNaN(this.columnDefs[i].width)){
				var width = column.offsetWidth;
				column.style.removeProperty('width');
				var delta = width - column.offsetWidth;
				if(Math.abs(delta) > this.threshold && column !== lastVisibleEl){
					column.style.width = width + 'px';
				}
			}
		});
	},
	
	getColumnIndexByTitle: function(title){
		return this.columnDefs.findIndex((column) => typeof column.title === 'string' && column.title.toLowerCase() === title.toLowerCase());
	},
	
	getDataFromPath: function(obj, str){		
		return str.split('.').reduce((current, key) => {
			return typeof current[key] !== 'undefined' && current[key] !== null ? current[key] : current;
		}, obj);
	},
	
	getDefaultEvents: function(){
		return {
			onCheck: function(item){},
			onClick: function(item){},
			onEnter: function(item){}
		}
	},
	
	getItems: function(key, index){
		return this.dataStore.filter((item) => typeof key !== 'undefined' ? item[key] : true).map((item) => item.data);
	},
	
	getMasterCheckbox: function(){
		this.masterCheckbox = document.createElement('input');
		this.masterCheckbox.type = 'checkbox';
		this.masterCheckbox.className = 'simpleGrid-masterCheckbox';
		return this.masterCheckbox;
	},
	
	handleMasterCheckbox: function(){
		if(this.checkboxes && this.selectColumn){
			var check = (item) => item.checked;
			this.masterCheckbox.indeterminate = this.dataStore.some(check) && !this.dataStore.every(check);
			if(!this.masterCheckbox.indeterminate) this.masterCheckbox.checked = this.dataStore.every(check);
		}
		return this;
	},
	
	handlePlaceholder: function(item, e){
		var els = document.elementsFromPoint(e.pageX, e.pageY).filter((el) =>
			el.parentNode && el.parentNode === item.el.parentNode && el !== item.el
		);
		if(els.length && els.indexOf(this.placeholder) === -1) {
			this.swapElements(els.concat(this.placeholder));
		}
	},
	
	hasChanged: function(ref){
		if(!isNaN(ref)){
			if(ref > this.threshold) return true;
			ref = null;
			this.emptyWidths();
		}
	},

	init: function(){
		// clear the container
		this.containerEl.innerHTML = '';
		// create / append the grid
		this.grid = document.createElement('ul');
		this.grid.tabIndex = 1;
		this.grid.className = 'simpleGrid-grid';
		this.containerEl.appendChild(this.grid);
		
		this.buildColumns().buildRows().addListeners();
	},
	
	prepareMove: function(column, start){
		this.grid.classList.add('simpleGrid-noselect');
		[...this.grid.children].forEach((column) => column.style.width = column.offsetWidth + 'px');
		
		// initialize delta
		this.moveDelta = 0;
		this.timestamp = new Date().getTime();
		
		// need to replace this column with a placeholder of the same width
		this.placeholder = this.createPlaceholder(column.offsetWidth);
		this.grid.insertBefore(this.placeholder, column);
		
		// then apply class for absolute positioning to the column
		column.classList.add('simpleGrid-moving');
		column.style.width = this.placeholder.style.width;
		column.style.left = this.placeholder.offsetLeft + 'px';
		
		this.onMousemove = this.beginMove.bind(this, {
			el: column,
			start: start,
			offset: this.placeholder.offsetLeft
		});

		this.onMouseup = this.stopListening.bind(this);
		this.containerEl.addEventListener('mousemove', this.onMousemove);
		this.containerEl.addEventListener('mouseup', this.onMouseup);
	},
	
	prepareResize: function(column, start){
		
		[...this.grid.children].forEach((column) => {
			if(column !== this.grid.lastElementChild) column.style.width = column.offsetWidth + 'px'
		});
		
		this.resizeDelta = 0;

		this.onMousemove = this.beginResize.bind(this, {
			el: column,
			start: start,
			width: column.offsetWidth
		});

		this.onMouseup = this.stopListening.bind(this);
		this.containerEl.addEventListener('mousemove', this.onMousemove);
		this.containerEl.addEventListener('mouseup', this.onMouseup);
		this.grid.classList.add('simpleGrid-noselect');
	},
	
	reindexColumns: function(){
		// rewrite indexes based on column moves		
		this.columnDefs = [...this.grid.children].reduce((arr, el, i) => {
			var index = parseInt(el.dataset.columnIndex);
			el.dataset.columnIndex = i;
			return arr.concat(this.columnDefs[index]);
		}, []);
	},
	
	removePlaceholder: function(column){
		if(this.placeholder){
			// remove the move architecture
			this.placeholder.parentNode.replaceChild(column, this.placeholder);
			column.classList.remove('simpleGrid-moving');
			column.style.removeProperty('left');
			this.placeholder = null;
			// move indexes
			this.reindexColumns();
		}
	},
	
	reorderCells: function(){
		// when the select column is added, this.cells is not in order
		var columns = this.columnDefs.length;
		var rows = this.dataStore.length;
		// checkboxes need to be shifted
		var orphans = this.cells.splice(this.cells.length - rows, rows);
		while(orphans.length) this.cells.splice((columns * (rows - orphans.length+1)) - 1, 0, orphans.shift());
	},
	
	sortColumn: function(def, dir){
		var values = (item, i) => ({value: (this.getDataFromPath(item.data, def.path) || '').toString(), index: i});
		this.dataStore = this.dataStore.map(values)
			.sort(dir === 'simpleGrid-desc' ? (a, b) => a.value < b.value : (a, b) => a.value > b.value)
			.reduce((arr, val) => arr.concat(this.dataStore[val.index]), []);
		
		this.buildRows();
	},
	
	stopListening: function(e){
		this.grid.classList.remove('simpleGrid-noselect');
		this.containerEl.removeEventListener('mousemove', this.onMousemove);
		this.containerEl.removeEventListener('mouseup', this.onMouseup);
		this.onMousemove = null;
		this.onMouseup = null;
		
		this.removePlaceholder(e.target.parentNode);
		this.hasChanged(this.resizeDelta);
		const timeDelta = new Date().getTime() - this.timestamp < 300;
		if(!this.hasChanged(this.moveDelta) && timeDelta) {
			this.attemptSort(e.target);
		}
	},
	
	swapElements: function(els){
		if(els[0].compareDocumentPosition(els[1]) > 3) els.reverse();
		els[0].parentNode.insertBefore(els[0], els[1]);
	},
	
	updateColumnVisibility: function(){
		[...this.grid.children].forEach((column, i) => {
			if(isNaN(this.columnDefs[i].width)) column.style.removeProperty('width');
			column.style.removeProperty('display');
			if(typeof this.columnDefs[i].show === 'boolean' && !this.columnDefs[i].show) column.style.display = 'none';
		});
		this.emptyWidths();
	}
}

var columns = [{
	title: 'Name',
	path: 'name.first'
}, {
	title: 'Gender',
	path: 'gender'
}, {
	title: 'Age',
	path: 'age',
	align: 'right'
}];

var rows = [{
	name: {
		first: 'John',
		last: 'Smith'
	},
	gender: 'male',
	age: 25
}, {
	name: {
		first: 'Mary',
		last: 'Jones'
	},
	gender: 'female',
	age: 27
}, {
	name: {
		first: 'Chris',
		last: 'Johnson'
	},
	gender: 'male',
	age: 31
}, {
	name: {
		first: 'Kevin',
		last: 'Monroe'
	},
	gender: 'male',
	age: 29
}, {
	name: {
		first: 'Danielle',
		last: 'Almonte'
	},
	gender: 'female',
	age: 23
}];

var simpleGrid = new SimpleGrid({
	container: document.getElementById('simpleGrid'),
	columnDefs: columns,
	dataStore: rows,
	checkboxes: true,
	events: {
		onCheck: function(item){},
		onClick: function(item){},
		onEnter: function(item){
			alert(JSON.stringify(item));
		}
	}
});


/* ========= for demo only ========== */
var buttons = document.querySelectorAll('section button');
[...buttons].forEach(function(button){
	button.addEventListener('click', function(){
		if(this.value !== ''){
			var data = simpleGrid.getItems(this.value);
			this.nextElementSibling.innerHTML = JSON.stringify(data);
		}
	})
});
var checkboxes = document.querySelectorAll('section input[type="checkbox"]');
[...checkboxes].forEach(function(checkbox){
	checkbox.addEventListener('click', function(){
		if(this.value !== ''){
			var index = simpleGrid.getColumnIndexByTitle(this.value);
			simpleGrid.columnDefs[index].show = this.checked;
			simpleGrid.updateColumnVisibility();
		}
	})
});
var select = document.querySelector('section select');
select.addEventListener('change', function(){
	// var sizes = ['compact', 'cozy', 'comfortable'];
	simpleGrid.grid.classList.remove('compact', 'cozy', 'comfortable');
	simpleGrid.grid.classList.add(this.value);
});

            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console