Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Comprowssor
<table data-comprowssor>
<caption>Middle Jurassic sections</caption>
<thead>
<tr>
<th>Name</th>
<th>Period <small>[Mya]</small></th>
<th>Duration <small>[My]</small></th>
<th>Species</th>
</tr>
</thead>
<tbody>
<tr>
<td>Callovian</td>
<td>166-163</td>
<td>3</td>
<td>Agilisaurus, Liopleurodon, Huayangosaurus</td>
</tr>
<tr>
<td>Bathonian</td>
<td>168-166</td>
<td>2</td>
<td>Metriorhynchus, Teleidosaurus, Shunosaurus</td>
</tr>
<tr>
<td>Bajocian</td>
<td>170-168</td>
<td>2</td>
<td>Belemnites, Ophionautilus, Somalinautilus</td>
</tr>
<tr>
<td>Aalenian</td>
<td>174-170</td>
<td>4</td>
<td>Abbasites, Belemnites, Steneosaurus</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Total</th>
<td>174-163</td>
<td>11</td>
<td>Agilisaurus, Liopleurodon, Huayangosaurus, Metriorhynchus, Teleidosaurus, Shunosaurus, Belemnites, Ophionautilus, Somalinautilus, Abbasites, Steneosaurus</td>
</tr>
</tfoot>
</table>
// --------------------------------------------------
// Comprowssor v0.5 by smutnyleszek@gmail.com
// http://leszekpietrzak.com
// License CC0 1.0
// --------------------------------------------------
// --------------------------------------------------
// Helper functions
// --------------------------------------------------
function hasClass(el, cl) {
return el.className && new RegExp('(\\s|^)' + cl + '(\\s|$)').test(el.className);
}
function addClass(el, cl) {
if (!hasClass(el, cl)) { el.className += ' ' + cl; }
}
function removeClass(el, cl) {
var reg = new RegExp('(\\s|^)' + cl + '(\\s|$)');
el.className = el.className.replace(reg, ' ').replace(/(^\s*)|(\s*$)/g, '');
}
function toggleClass(el, cl) {
if (hasClass(el, cl)) { removeClass(el, cl); } else { addClass(el, cl); }
}
function addEventHandler(elem, eventType, handler) {
if (elem.addEventListener) {
elem.addEventListener (eventType, handler, false);
} else if (elem.attachEvent) {
elem.attachEvent ('on' + eventType, handler);
}
}
// --------------------------------------------------
// main Comprowssor creator function
// --------------------------------------------------
function Comprowssor(customOptions) {
this.options = {
column: 0,
classActive: 'active',
dataColumn: 'data-comprowssor-column',
dataValue: 'data-comprowssor-value',
dataInit: 'data-comprowssor',
dataSelect: 'data-comprowssor-select'
};
// check if there are any custom options
if (customOptions) {
// go through all the options and set new values if provided
if (customOptions.column) { this.options.column = customOptions.column; }
if (customOptions.classActive) { this.options.classActive = customOptions.classActive; }
}
this.helpers = {
prepareRows: function (options) {
// declarations
var tables = document.querySelectorAll('[' + options.dataInit + ']');
var a, b, c;
// loop through every instance of comprowssor
for (a = 0; a < tables.length; a += 1) {
// declarations
var dropdown;
var importantColumn;
var rowList;
var rowChildren;
var cellValue;
var cellValues = [];
var dropdownList;
// check if -column html data is set or get the default from options
if (tables[a].getAttribute(options.dataColumn)) {
importantColumn = parseInt(tables[a].getAttribute(options.dataColumn), 10);
} else {
importantColumn = options.column;
}
// loop through every row of curent table
// to set data attributes and get values for dropdown
rowList = tables[a].querySelectorAll('tbody>tr');
for (b = 0; b < rowList.length; b += 1) {
// activate first row
if(b === 0) {
addClass(rowList[b], options.classActive);
}
// loop through all td nodes of row
rowChildren = rowList[b].querySelectorAll('td');
for (c = 0; c < rowChildren.length; c += 1) {
// get only the chosen column
if (c === importantColumn) {
// get cell content and push it to values array
cellValue = rowChildren[c].textContent;
cellValues.push(cellValue);
// clear cell content
rowChildren[c].textContent = '';
// save value in parent row attribute
rowChildren[c].parentNode.setAttribute(options.dataValue, cellValue);
// insert dropdown in cell
dropdown = document.createElement('select');
dropdown.setAttribute(options.dataSelect, true);
console.log(rowChildren);
rowChildren[c].appendChild(dropdown);
}
}
}
// loop through every dropdown and add options to it
dropdownList = tables[a].querySelectorAll('[' + options.dataSelect + ']');
for (b = 0; b < dropdownList.length; b += 1) {
// loop through all cell values
for (c = 0; c < cellValues.length; c += 1) {
// add option
dropdownList[b].options[dropdownList[b].options.length] = new Option(cellValues[c], cellValues[c]);
}
}
}
},
selectRow: function (options, dropdown) {
// declarations
var parentTable = dropdown.parentNode.parentNode.parentNode.parentNode;
var a, b, c;
var rowList;
var rowValue;
var dropdownList;
// loop through every row of curent table
// to change active row
rowList = parentTable.querySelectorAll('tbody>tr');
for (a = 0; a < rowList.length; a += 1) {
// get row data value
rowValue = rowList[a].getAttribute(options.dataValue);
// change classes
if (dropdown.value === rowValue) {
addClass(rowList[a], options.classActive);
} else {
removeClass(rowList[a], options.classActive);
}
// loop through every dropdown
dropdownList = parentTable.querySelectorAll('[' + options.dataSelect + ']');
for (b = 0; b < dropdownList.length; b += 1) {
// from all options select the current active one
for (c = 0; c < dropdownList[b].options.length; c += 1) {
if (dropdownList[b].options[c].value === dropdown.value) {
dropdownList[b].selectedIndex = c;
}
}
}
}
}
};
this.run = function () {
// declarations
var that = this;
var dropdownList;
var a;
// create dropdown for every row and save the important value to data-attribute
that.helpers.prepareRows(that.options);
// wait for content load
addEventHandler(document, 'DOMContentLoaded', function () {
// loop throguh all dropdowns
var dropdownList = document.querySelectorAll('[' + that.options.dataSelect + ']');
for (a = 0; a < dropdownList.length; a += 1) {
// add event listener to change
addEventHandler(dropdownList[a], 'change', function (event) {
that.helpers.selectRow(that.options, this);
});
}
});
};
}
table[data-comprowssor] {
tbody {
tr {
display: none;
&.active {
display: table-row;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment