Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save nicholasnadel/24800754b6f961e126eddc091eaebcaa to your computer and use it in GitHub Desktop.

Select an option

Save nicholasnadel/24800754b6f961e126eddc091eaebcaa to your computer and use it in GitHub Desktop.
Accessible Table Generator - WIP 13/09

Accessible Table Generator - WIP 13/09

Wanted to create a quick and simple generator which made tables suitable for accessibility.

A Pen by nicholasnadel on CodePen.

License.

<div class="codecopiedalert">
<i class="material-icons">sentiment_very_satisfied</i>
Table Code Copied!
</div>
<h1>Accessible Table Generator</h1>
<div id="maincont" class="container">
<div id="infodisplay" class="per50 floatleft">
<h3>Instructions</h3>
<ul>
<li>Select Size</li>
<li>Add caption</li>
<li>Choose column and/or row headers</li>
<li>Click cells to edit them (Ctrl+B for bold etc works) then Click 'Prepare Table Code'</li>
<li>If you're happy, click 'Copy to Clipboard' then Ctrl+V to paste in a location of your choice!</li>
</ul>
</div>
<div class="per50 floatleft coderdy">
<div id="tablepreview" class="">
<div class="topbar"><span class="option"> <a id="sizertoggle" href="#" class="material-icons">border_all <span class="label">Size</span> </a>
</span>
<span class="option">
<a id="captiontoggle" href="#" class="material-icons">speaker_notes <span class="label">Caption</span></a>
</span>
<span class="option">
<a id="titletoggle" href="#" class="material-icons"><i class="material-icons">view_week</i><span class="label">col & row THs</span>
</a>
</span>
<form><span id="colcount"></span>x<span id="rowcount"></span></form>
<div class="clear"></div>
</div>
<div id="sizer" class="table_size_chooser "><div class="SizeChooser"><table><tbody><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td></tr><tr><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td class=""> </td><td> </td><td> </td></tr></tbody></table>
</div>
</div> <!-- end of sizer --> <div id="captioner">
<textarea placeholder="Enter caption here"></textarea>
<button id="applycaption">Update Table</button>
</div>
<div id="headerer">
<input type="checkbox" id="colheadercheck" name="columnheaders" value="columnheaders" checked> Column Headers
<input type="checkbox"
id="rowheadercheck" name="rowheaders" value="rowheaders">Row Headers
<button id="applyheaders">Update Table</button>
</div>
</div> <!-- end of table preview -->
<pre id="tablecode"></pre>
<button class="btn copybtn" data-clipboard-target="#tablecode"> <i class="material-icons">content_copy</i>Copy to Clipboard
</button>
</div>
<div class="clear"></div>
</div>
<div id="tabledisplay" class="per100">
<h2>Table Preview<button id="gencode"><i class="material-icons">code</i><span id="preparetext">Push edits to code</span></button></h2>
<div class="container">
<div class="table-responsive">
</div>
</div>
</div>
// highlighter for sizer visuals
$('td').mouseover(function(){
var $this = $(this);
var col = $this.index();
var row = $this.closest('tr').index();
$('#colcount').text(col+1);
$('#rowcount').text(row+1);
});
$("table").delegate('td','mouseover mouseleave', function(e) {
var cellindex = 0;
if (e.type == 'mouseover') {
$(this).addClass("cell");
var cells = $(this).parent().children("td");
for(var i=0;i<cells.length;i++){
if($(cells[i]).hasClass("cell")){
$(this).removeClass("cell");
cellindex = i;
break;
}
}
$(this).parent().addClass("row");
var rows = $(this).parent().parent().children("tr");
for(var i=0;i<rows.length;i++){
var tds = $(rows[i]).children("td");
for(var j=0;j<=cellindex;j++){
$(tds[j]).addClass("SizeChooser-hover");
}
if($(rows[i]).hasClass("row")){
$(this).parent().removeClass("row");
break;
}
}
}
else {
$("td").removeClass("SizeChooser-hover");
}
});
// END highlighter for sizer visuals
// toggle sizer input
$( "#sizertoggle" ).click(function() {
$("#tablepreview").removeClass("showcaptioner").removeClass("showheaderer");
$("#tablepreview").toggleClass('showsizer');
});
// toggle caption input
$("#captiontoggle").click(function() {
$("#tablepreview").removeClass("showsizer").removeClass("showheaderer");
$("#tablepreview").toggleClass('showcaptioner');
});
$("#titletoggle").click(function() {
$("#tablepreview").removeClass("showsizer").removeClass("showcaptioner");
$("#tablepreview").toggleClass('showheaderer');
});
// on sizer td click, generate new table
$( "#tablepreview td" ).click(function() {
$("#tablepreview").removeClass('showsizer');
$('#tabledisplay .table-responsive').empty();
row = $('#colcount').text();
col = $('#rowcount').text();
var rows = col; //here's your number of rows and columns
var cols = row;
var table = $('<table class="table table-bordered"><tbody>');
for(var r = 0; r < rows; r++)
{
var tr = $('<tr>');
for (var c = 0; c < cols; c++)
$('<td contenteditable="true">click to edit</td>').appendTo(tr);
tr.appendTo(table);
}
table.appendTo('#tabledisplay .table-responsive');
gencode();
});
// BEAUTIFY STRING
function process(str) {
var div = document.createElement('div');
div.innerHTML = str.trim();
return format(div, 0).innerHTML;
}
function format(node, level) {
var indentBefore = new Array(level++ + 1).join(' '),
indentAfter = new Array(level - 1).join(' '),
textNode;
for (var i = 0; i < node.children.length; i++) {
textNode = document.createTextNode('\n' + indentBefore);
node.insertBefore(textNode, node.children[i]);
format(node.children[i], level);
if (node.lastElementChild == node.children[i]) {
textNode = document.createTextNode('\n' + indentAfter);
node.appendChild(textNode);
}
}
return node;
}
// ON APPLYING CAPTION
$('button#applycaption').click(function(){
//remove caption input window
$("#tablepreview").removeClass('showcaptioner');
var caption = $('#captioner textarea').val();
$( "#tabledisplay table caption" ).remove();
gencode();
});
// ON APPLYING CAPTION
$('button#applyheaders').click(function(){
//remove caption input window
$("#tablepreview").removeClass('showheaderer');
gencode();
});
$('#gencode').click(function(){
gencode();
$('#preparetext').text('Code Updated Above');
$("body").addClass("codeupdated").delay(1500).queue(function(){
$(this).removeClass("codeupdated").dequeue();
$('#preparetext').text('Push edits to code');
});
});
function gencode(){
if ($('#rowheadercheck').is(':checked')) {
// add th to first row
$('#tabledisplay tr td:first-child').replaceWith(function(i, html) {
return '<th scope="row">click to edit</th>';
});
}
if ( !$('#rowheadercheck').is(':checked')) {
// alert('notcheck');
// add th to first row
$('#tabledisplay tr th:first-child').replaceWith(function(i, html) {
return '<td contenteditable="true">click to edit</td>';
});
}
if ($('#colheadercheck').is(':checked')) {
// add th to first row
$('#tabledisplay tr:first-child').children('td').replaceWith(function(i, html) {
return '<th scope="col">click to edit</th>';
});
}
var caption = $('#captioner textarea').val();
$( "#tabledisplay table caption" ).remove();
$( "#tabledisplay table" ).prepend( "<caption class='heading'>"+caption+"</caption>" );
$("th, td").removeAttr("contenteditable");
// update code display
var htmlString = $( '#tabledisplay .container' ).html();
$('#tablecode').text(process(htmlString));
$("#tabledisplay th, #tabledisplay td").attr("contenteditable","true");
}
var clipboard = new Clipboard('.btn');
clipboard.on('success', function(e) {
$("body").addClass("codecopied").delay(2500).queue(function(){
$(this).removeClass("codecopied").dequeue();
});
});
clipboard.on('error', function(e) {
console.log(e);
});
$('.codecopiedalert').click(function() {
$('body').removeClass("codecopied");
});
// THIS IS TO MAKE THE TABLE EDITABLE
var $TABLE = $('#table');
var $BTN = $('#export-btn');
var $EXPORT = $('#export');
$('.table-add').click(function () {
var $clone = $TABLE.find('tr.hide').clone(true).removeClass('hide table-line');
$TABLE.find('table').append($clone);
});
$('.table-remove').click(function () {
$(this).parents('tr').detach();
});
$('.table-up').click(function () {
var $row = $(this).parents('tr');
if ($row.index() === 1) return; // Don't go above the header
$row.prev().before($row.get(0));
});
$('.table-down').click(function () {
var $row = $(this).parents('tr');
$row.next().after($row.get(0));
});
// A few jQuery helpers for exporting only
jQuery.fn.pop = [].pop;
jQuery.fn.shift = [].shift;
$BTN.click(function () {
var $rows = $TABLE.find('tr:not(:hidden)');
var headers = [];
var data = [];
// Get the headers (add special header logic here)
$($rows.shift()).find('th:not(:empty)').each(function () {
headers.push($(this).text().toLowerCase());
});
// Turn all existing rows into a loopable array
$rows.each(function () {
var $td = $(this).find('td');
var h = {};
// Use the headers from earlier to name our hash keys
headers.forEach(function (header, i) {
h[header] = $td.eq(i).text();
});
data.push(h);
});
// Output the result
$EXPORT.text(JSON.stringify(data));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.7.1/clipboard.min.js"></script>
$leftsize: 250px;
#maincont {padding-top: 48px;}
//INFO DISPLAY
#infodisplay {background: rgba(0,0,0,0.6); position: relative; padding: 48px 48px;
padding-top: 52px;}
#infodisplay ul{color: #fff;
padding: 0; margin: 0;}
#infodisplay h3 {
margin: 0;
color: #fff;
background: #000000;
background: -webkit-linear-gradient(to right, #434343, #000000);
background: linear-gradient(to right, #434343, #000000); font-weight: normal;
position: absolute; width: 100%; top: 0; left:0;
text-align: center; padding: 6px;
}
*{font-family: 'Montserrat', sans-serif;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.clear {clear: both; float: none;}
span.label {position: relative; bottom: 6px;}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px; /* Preferred icon size */
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
color: #fff;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;
/* Support for IE. */
font-feature-settings: 'liga';
}
a.material-icons {text-decoration: none;}
body{background: #1e88e5; margin: 0;}
h1, h2 {color: #fff; font-weight: normal; text-align: center; background: rgba(255,255,255,0.1); margin: 0; padding: 12px;}
h2 {color: #fff; background: #000000;
background: -webkit-linear-gradient(to right, #434343, #000000);
background: linear-gradient(to right, #434343, #000000);
}
.container {max-width: 1170px; width: 100%; display: block; margin: 0 auto; box-sizing: border-box; padding: 12px;}
.per50 {float: left; display: block; width: 50%; box-sizing: border-box; padding: 24px;}
#tablecode {background: #fff; display: block; min-height: $leftsize; margin: 0; padding: 24px; max-height: 200px; overflow-y: scroll; }
// SIZE CHOOSER
.SizeChooser {
margin: 5px 10px 5px 10px;
position: relative;
}
.SizeChooser table {
border-collapse: separate;
border-spacing: 3px;
}
.SizeChooser td {
cursor: pointer;
border: 1px #ccc solid;
height: 10px;
min-width: 10px;
line-height: 10px;
}
.SizeChooser-selected {
border: 1px #333 solid !important;
}
.SizeChooser-hover {
background-color: #DEF;
}
.SizeChooser form span {
background-color: #fff;
border: 1px #ccc solid;
width: 30px;
display: inline-block;
}
.SizeChooser form {
margin: 5px 0 0 3px;
}
//.tschide {display: none;}
#tablepreview #sizer {display: none;}
#tablepreview.showsizer #sizer {display: block;}
#tablepreview #captioner {display: none;}
#tablepreview.showcaptioner #captioner {display: block;}
#tablepreview #headerer {display: none;}
#tablepreview.showheaderer #headerer {display: block;}
.topbar {background: rgba(0,0,0,0.2); box-sizing: border-box; padding: 0px 0px; color: #fff; width: 100%; display: block;}
.topbar form {
float: right;
line-height: 20px;
font-size: 18px;
padding: 6px 12px;
}
span.option { display: block; border-right: 1px solid #1a548a; float: left;
}
.option a {font-size: 24px; padding: 6px 12px;}
.option a:hover {background: rgba(0,0,0,0.2);}
.option a .label {font-size: 18px;}
#tableselector {
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
}
#tablepreview {position: relative;}
#sizer, #headerer {position: absolute; top: 39px; background: #0e385d; width: 100%; height: $leftsize;}
#headerer {box-sizing: border-box; padding: 12px; color: #fff;}
#captioner {position: absolute; top: 39px; background: #0e385d; width: 100%; box-sizing: border-box; padding: 24px; height: $leftsize;}
#captioner textarea {max-width: 100%; width: 100%;}
.table-bordered>tbody>tr>td, .table-bordered>tbody>tr>th, .table-bordered>tfoot>tr>td, .table-bordered>tfoot>tr>th, .table-bordered>thead>tr>td, .table-bordered>thead>tr>th {
border: 1px solid #ddd;
}
.table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th {
padding: 8px;
line-height: 1.42857143;
vertical-align: top;
border-top: 1px solid #ddd;
}
caption {
padding-top: 8px;
padding-bottom: 8px;
color: #777;
text-align: left;
}
.table-bordered {
border: 1px solid #ddd;
border-collapse: collapse;
}
.table {
width: 100%;
max-width: 100%;
margin-bottom: 20px;
}
.table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th {
padding: 8px;
line-height: 1.42857143;
vertical-align: top;
border-top: 1px solid #ddd;
}
#tabledisplay {background: #fff; display: block; min-height: 50vh; font-family: 'Open Sans',sans-serif;}
.floatleft {padding-top: 0;}
th {
text-align: left;
}
caption {
padding-top: 8px;
padding-bottom: 8px;
color: #777;
text-align: left;
}
.copybtn .material-icons {position: relative; top: 6px; right: 3px;}
.copybtn {background: #ff5722; border: 0; outline: 0; width: 100%; display: block; color: #fff; padding: 3px 12px 11px 12px; font-size: 16px; background: grey; color: lightgray; opacity: 0.7;}
.copybtn:hover {cursor: not-allowed;}
.coderdy .copybtn {background: #ff5722; color: #fff; opacity: 1.0;}
.coderdy .copybtn:hover {cursor: pointer; background: #ff6939;}
.codecopiedalert {display: block; position: fixed; top: 50%; left: 50%; width: 400px; height: 180px; background: #abff81; transform: translateY(-50%) translateX(-50%); z-index: 99; font-size: 24px; font-weight: bold; text-align: center; box-sizing: border-box; padding: 24px; border-radius: 20px; box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);}
.codecopiedalert .material-icons { color: black; font-size: 72px; display: block; margin-bottom: 12px;}
.codecopiedalert {display: none;}
.codecopied .codecopiedalert {display: block;}
#tabledisplay button {display: inline-block; margin-left: 20px; background: #6dbd45; outline: 0; border: 0; font-size: 18px; padding: 6px 12px; color: #000;}
#tabledisplay button:hover {background: lighten(#6dbd45,10%); cursor: pointer;}
#tabledisplay .material-icons {color: #000; font-size: 20px; line-height: 18px; position: relative; right: 3px; top: 3px;}
.codeupdated {}
@-webkit-keyframes demo {
0% {
}
100% {
background: #6dbd45;
}
}
.codeupdated #tablecode {
-webkit-animation-name: demo;
-webkit-animation-duration: 150ms;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in-out;
}
// caption styling
caption.heading {
background-color: #002649;
border: none;
border-top: none;
color: #FFF;
border-radius: 0;
text-indent: 12px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment