Some of my recent posts involved the automatic production of thumbnail tables, in which specific javascript code produced the tables. I thought it might be a good idea to produce an HTML app to allow the creation of custom HTML tables. In this post I will give an example of a cross platform offline appointment calendar. I had previously posted an appointment calendar creation application, but that either has to be used online or with a virtual server.
Here is the code:
<html xmlns=’http://www.w3.org/1999/xhtml’>
<head profile=’http://gmpg.org/xfn/11′>
<title>Table Maker</title>
<style type=’text/css’>
style{display: block; position: relative; width: 100%; font :normal normal 700 15px Arial; background: black; color: white; white-space: pre-wrap}
</style>
</head>
<body><input type=”button” id=”b1″ name=”b1″ value=”Load” onclick=’makeTable();’ /><table id=”table1″ align=”center” valign=”top”></table>
<br /><br />
<input type=”radio” id=”r1″ name=”r1″ value=”” onclick=’dup(“n”);’/>Duplicate <input type=”radio” id=”r1″ name=”r1″ value=”” onclick=’dup(“y”);’ />Sequence     <input type=”text” id=”lim” name=”lim” value=”total number” />
<br /><br />
<textarea id=”t1″ name=”t1″ rows=”10″ cols=”” value = “” ondblclick=’fillCell();’>text</textarea>
<br /><br />
<input type=”text” id=”t2″ name=”t2″ value=”# cells” /> <input type=”text” id=”t3″ name=”t3″ value=”cell/row” />
<br /><br />
<textarea id=”ta” name=”ta” rows=”10″ cols=” “></textarea>
<br /><br />
<style contenteditable=”true” scoped>
body {margin-left:0;margin-right:0;font:normal normal normal 12px Arial;}
a{ text-decoration: }
:link { color: rgb(0, 0, 255) }
:visited {color :rgb(100, 0,100) }
:hover { }
:active { }
#table1{position: relative; top:0; border-collapse: collapse; empty-cells: show}
td{border: 1px inset}
#r1{position: relative}
#t1{position: relative; width: 100%;}
#t2{}
#t3{}
#ta{position: relative; width: 100%;}
#b1{position: relative; top: 0}
</style>var lim = 0; var lim2 = 0; var str = ”
“; var cnt = 0; var str2 = arry = new Array(); var a = 0; var b = -1; var no = 0; var rep = “1”; var rep2 = “”; var rep3 = “”; var rep4 = “”;function dup(seq) {
var dupstr = document.getElementById(“t1”).value;
dupstr2 = new Array();
lim2 = document.getElementById(“lim”).value;
for (var i=0; i ” + document.getElementById(“t1”).value + “”;
if (cnt % document.getElementById(“t3”).value == 0) {
str += “”; } } str += ”
“;
document.getElementById(“table1”).innerHTML = str;
document.getElementById(“ta”).innerHTML = ”
\n” + str + “\n”;
}
function fillCell() {
for (var i=0; i
</body>
</html>
These inputs determine the number of cells to create and the number of cells per row.
<input type=”text” id=”t2″ name=”t2″ value=”# cells” /> <input type=”text” id=”t3″ name=”t3″ value=”cell/row” />
Clicking the Load button calls the makeTable() function and creates a string with the table code which is copied into the second textarea.
This is how that looks:
<table align=”center” valign=”top”>
<tr><td id=’td1′>text </td><td id=’td2′>text </td><td id=’td3′>text </td><td id=’td4′>text </td><td id=’td5′>text </td><td id=’td6′>text </td><td id=’td7′>text </td></tr><tr><td id=’td8′>text </td><td id=’td9′>text </td><td id=’td10′>text </td><td id=’td11′>text </td><td id=’td12′>text </td><td id=’td13′>text </td><td id=’td14′>text </td></tr><tr><td id=’td15′>text </td><td id=’td16′>text </td><td id=’td17′>text </td><td id=’td18′>text </td><td id=’td19′>text </td><td id=’td20′>text </td><td id=’td21′>text </td></tr><tr><td id=’td22′>text </td><td id=’td23′>text </td><td id=’td24′>text </td><td id=’td25′>text </td><td id=’td26′>text </td><td id=’td27′>text </td><td id=’td28′>text </td></tr><tr><td id=’td29′>text </td><td id=’td30′>text </td><td id=’td31′>text </td><td id=’td32′>text </td><td id=’td33′>text </td><td id=’td34′>text </td><td id=’td35′>text </td></tr><tr><td id=’td36′>text </td><td id=’td37′>text </td><td id=’td38′>text </td><td id=’td39′>text </td><td id=’td40′>text </td><td id=’td41′>text </td><td id=’td42′>text </td></tr><tr><td id=’td43′>text </td><td id=’td44′>text </td><td id=’td45′>text </td><td id=’td46′>text </td><td id=’td47′>text </td><td id=’td48′>text </td><td id=’td49′>text </td></tr><tr><td id=’td50′>text </td><td id=’td51′>text </td><td id=’td52′>text </td><td id=’td53′>text </td><td id=’td54′>text </td><td id=’td55′>text </td><td id=’td56′>text </td></tr><tr><td id=’td57′>text </td><td id=’td58′>text </td><td id=’td59′>text </td><td id=’td60′>text </td><td id=’td61′>text </td><td id=’td62′>text </td><td id=’td63′>text </td></tr><tr><td id=’td64′>text </td><td id=’td65′>text </td><td id=’td66′>text </td><td id=’td67′>text </td><td id=’td68′>text </td><td id=’td69′>text </td><td id=’td70′>text </td></tr><tr><td id=’td71′>text </td><td id=’td72′>text </td><td id=’td73′>text </td><td id=’td74′>text </td><td id=’td75′>text </td><td id=’td76′>text </td><td id=’td77′>text </td></tr><tr></tr>
</table>
The contents of the cells must now be created. Coding each one by hand for a large table could be tedious. Fortunately, in many cases there is a lot of repetion, such as in this case, in which the entries differ by sequential values.
In this example, the editable cells will be filled with textareas, ids being assigned sequentially
‘<textarea id=ta[” rows=”” cols=””></textarea>’~
Filling the total number box and clicking one of the radiobuttons will append n-1 copies of the original using the function dup().
function dup(seq) {
var dupstr = document.getElementById(“t1”).value;
dupstr2 = new Array();
lim2 = document.getElementById(“lim”).value;
for (var i=0; i <=lim2 -2 ; i++) {
rep2 = i + 2;
rep4 = rep2.toString();
if (seq ==”y”) {
dupstr2[i+1] = dupstr.replace(/\[/g, rep4 );
document.getElementById(“t1”).value += dupstr2[i+1];
} else {
document.getElementById(“t1″).value += dupstr;
}
}
}
Choosing Duplicate will just append the original but using Sequence will append and sequentially replace a selected character. As in previous examples, I chose ~ for a delimiter, since commas might be used in the entries. For the same reason, I chose [ as the replaceable character.
In this example I used Sequence. The first item had to be manually replaced, but all others were sequentially numbered, a great time saver.
Here is how the first textarea appears:
‘<textarea id=”ta1″ rows= cols=””></textarea>’~'<textarea id=”ta2″ rows= cols=””></textarea>’~'<textarea id=”ta3″ rows= cols=””></textarea>’~'<textarea id=”ta4″ rows= cols=””></textarea>’~'<textarea id=”ta5″ rows= cols=””></textarea>’~'<textarea id=”ta6″ rows= cols=””></textarea>’~'<textarea id=”ta7″ rows= cols=””></textarea>’~'<textarea id=”ta8″ rows= cols=””></textarea>’~'<textarea id=”ta9″ rows= cols=””></textarea>’~'<textarea id=”ta10″ rows= cols=””></textarea>’~'<textarea id=”ta11″ rows= cols=””></textarea>’~'<textarea id=”ta12″ rows= cols=””></textarea>’~'<textarea id=”ta13″ rows= cols=””></textarea>’~'<textarea id=”ta14″ rows= cols=””></textarea>’~'<textarea id=”ta15″ rows= cols=””></textarea>’~'<textarea id=”ta16″ rows= cols=””></textarea>’~'<textarea id=”ta17″ rows= cols=””></textarea>’~'<textarea id=”ta18″ rows= cols=””></textarea>’~'<textarea id=”ta19″ rows= cols=””></textarea>’~'<textarea id=”ta20″ rows= cols=””></textarea>’~'<textarea id=”ta21″ rows= cols=””></textarea>’~'<textarea id=”ta22″ rows= cols=””></textarea>’~'<textarea id=”ta23″ rows= cols=””></textarea>’~'<textarea id=”ta24″ rows= cols=””></textarea>’~'<textarea id=”ta25″ rows= cols=””></textarea>’~'<textarea id=”ta26″ rows= cols=””></textarea>’~'<textarea id=”ta27″ rows= cols=””></textarea>’~'<textarea id=”ta28″ rows= cols=””></textarea>’~'<textarea id=”ta29″ rows= cols=””></textarea>’~'<textarea id=”ta30″ rows= cols=””></textarea>’~'<textarea id=”ta31″ rows= cols=””></textarea>’~'<textarea id=”ta32″ rows= cols=””></textarea>’~'<textarea id=”ta33″ rows= cols=””></textarea>’~'<textarea id=”ta34″ rows= cols=””></textarea>’~'<textarea id=”ta35″ rows= cols=””></textarea>’~
I then needed to customize the days of the month. To do this I had to reuse the first textarea, so I cut the existing text and entered the following:
‘[‘~
Using Sequence for 31 days gave the following:
‘1’~’2’~’3’~’4’~’5’~’6’~’7’~’8’~’9’~’10’~’11’~’12’~’13’~’14’~’15’~’16’~’17’~’18’~’19’~’20’~’21’~’22’~’23’~’24’~’25’~’26’~’27’~’28’~’29’~’30’~’31’~
Since there were 35 cells and only 31 days, I had to add blank values. This is how it would look to start the month on a Tuesday, the third day of the week:
”~”~’1’~’2’~’3’~’4’~’5’~’6’~’7’~’8’~’9’~’10’~’11’~’12’~’13’~’14’~’15’~’16’~’17’~’18’~’19’~’20’~’21’~’22’~’23’~’24’~’25’~’26’~’27’~’28’~’29’~’30’~’31’~”~”~
There are two leading and two trailing blank cells.
I then pasted the cut text back and cut and pasted the day numbers in units of seven numbers into the proper location.Here is how that looks:
”~”~’1’~’2’~’3’~’4’~’5’~
‘<textarea id=”ta1″ rows=”” cols=””></textarea>’~'<textarea id=”ta2″ rows= cols=””></textarea>’~'<textarea id=”ta3″ rows= cols=””></textarea>’~'<textarea id=”ta4″ rows=”” cols=””></textarea>’~'<textarea id=”ta5″ rows= cols=””></textarea>’~'<textarea id=”ta6″ rows=”” cols=””></textarea>’~'<textarea id=”ta7″ rows= cols=””></textarea>’~’6’~’7’~’8’~’9’~’10’~’11’~’12’~'<textarea id=”ta8″ rows= cols=””></textarea>’~'<textarea id=”ta9″ rows= cols=””></textarea>’~'<textarea id=”ta10″ rows= cols=””></textarea>’~'<textarea id=”ta11″ rows= cols=””></textarea>’~'<textarea id=”ta12″ rows= cols=””></textarea>’~'<textarea id=”ta13″ rows= cols=””></textarea>’~'<textarea id=”ta14″ rows= cols=””></textarea>’~’13’~’14’~’15’~’16’~’17’~’18’~’19’~'<textarea id=”ta15″ rows= cols=””></textarea>’~'<textarea id=”ta16″ rows= cols=””></textarea>’~'<textarea id=”ta17″ rows= cols=””></textarea>’~'<textarea id=”ta18″ rows= cols=””></textarea>’~'<textarea id=”ta19″ rows= cols=””></textarea>’~'<textarea id=”ta20″ rows= cols=””></textarea>’~'<textarea id=”ta21″ rows= cols=””></textarea>’~’20’~’21’~’22’~’23’~’24’~’25’~’26’~'<textarea id=”ta22″ rows= cols=””></textarea>’~'<textarea id=”ta23″ rows= cols=””></textarea>’~'<textarea id=”ta24″ rows= cols=””></textarea>’~'<textarea id=”ta25″ rows= cols=””></textarea>’~'<textarea id=”ta26″ rows= cols=””></textarea>’~'<textarea id=”ta27″ rows= cols=””></textarea>’~'<textarea id=”ta28″ rows= cols=””></textarea>’~’27’~’28’~’29’~’30’~’31’~”~”~'<textarea id=”ta29″ rows= cols=””></textarea>’~'<textarea id=”ta30″ rows= cols=””></textarea>’~'<textarea id=”ta31″ rows= cols=””></textarea>’~'<textarea id=”ta32″ rows= cols=””></textarea>’~'<textarea id=”ta33″ rows= cols=””></textarea>’~'<textarea id=”ta34″ rows= cols=””></textarea>’~'<textarea id=”ta35″ rows= cols=””></textarea>’~
I then created a string for a day header
‘Sunday’~’Monday’~’Tuesday’~’Wednesday’~’Thursday’~’Friday’~’Saturday’~
and added it to the front of the other text.
Double clicking the first textarea creates the following code:
var arr=[
‘Sunday’,’Monday’,’Tuesday’,’Wednesday’,’Thursday’,’Friday’,’Saturday’,
”,”,’1′,’2′,’3′,’4′,’5′,
‘<textarea id=”ta1″ rows= cols=””></textarea>’,'<textarea id=”ta2″ rows= cols=””></textarea>’,'<textarea id=”ta3″ rows= cols=””></textarea>’,'<textarea id=”ta4″ rows= cols=””></textarea>’,'<textarea id=”ta5″ rows= cols=””></textarea>’,'<textarea id=”ta6″ rows= cols=””></textarea>’,'<textarea id=”ta7″ rows= cols=””></textarea>’,’6′,’7′,’8′,’9′,’10’,’11’,’12’,'<textarea id=”ta8″ rows= cols=””></textarea>’,'<textarea id=”ta9″ rows= cols=””></textarea>’,'<textarea id=”ta10″ rows= cols=””></textarea>’,'<textarea id=”ta11″ rows= cols=””></textarea>’,'<textarea id=”ta12″ rows= cols=””></textarea>’,'<textarea id=”ta13″ rows= cols=””></textarea>’,'<textarea id=”ta14″ rows= cols=””></textarea>’,’13’,’14’,’15’,’16’,’17’,’18’,’19’,'<textarea id=”ta15″ rows= cols=””></textarea>’,'<textarea id=”ta16″ rows= cols=””></textarea>’,'<textarea id=”ta17″ rows= cols=””></textarea>’,'<textarea id=”ta18″ rows= cols=””></textarea>’,'<textarea id=”ta19″ rows= cols=””></textarea>’,'<textarea id=”ta20″ rows= cols=””></textarea>’,'<textarea id=”ta21″ rows= cols=””></textarea>’,’20’,’21’,’22’,’23’,’24’,’25’,’26’,'<textarea id=”ta22″ rows= cols=””></textarea>’,'<textarea id=”ta23″ rows= cols=””></textarea>’,'<textarea id=”ta24″ rows= cols=””></textarea>’,'<textarea id=”ta25″ rows= cols=””></textarea>’,'<textarea id=”ta26″ rows= cols=””></textarea>’,'<textarea id=”ta27″ rows= cols=””></textarea>’,'<textarea id=”ta28″ rows= cols=””></textarea>’,’27’,’28’,’29’,’30’,’31’,”,”,'<textarea id=”ta29″ rows= cols=””></textarea>’,'<textarea id=”ta30″ rows= cols=””></textarea>’,'<textarea id=”ta31″ rows= cols=””></textarea>’,'<textarea id=”ta32″ rows= cols=””></textarea>’,'<textarea id=”ta33″ rows= cols=””></textarea>’,'<textarea id=”ta34″ rows= cols=””></textarea>’,'<textarea id=”ta35″ rows= cols=””></textarea>’]; var no = 0; var lim=76;
function fillCells() {
for (var i=0; i <= lim; i ++ ){
no = i + 1;
document.getElementById(“td” + no).innerHTML= arr[i];
}
}
which is appended to the second textarea.
I used the block style element that I had described in a previous post, so I could interactively edit the table style.
When finished with any style adjustments, create a blank html file, copy and paste the table style code between <style> tags, copy and paste the table code into the body and copy and paste the javascript code between tags.
Click image for larger view
This gave an acceptable calendar, but I thought it could be a little nicer with some further style adjustments, so I added some more code to the style section.
Here is how the final calendar appears:
Click image for larger view
and here is the calendar code:
<html xmlns=’http://www.w3.org/1999/xhtml’>
<head profile=’http://gmpg.org/xfn/11′>
<title>test</title>
<style type=’text/css’>
body {margin-left:0;margin-right:0;font:normal normal normal 12px Arial;}
a{ text-decoration: }
:link { color: rgb(0, 0, 255) }
:visited {color :rgb(100, 0,100) }
:hover { }
:active { }
#table1{position: relative; top:0; border-collapse: collapse; empty-cells: show}
td{border: 1px inset}
textarea{height: 100px}
#tr1{background: #DDFFEE}
</style>
</head>
<body onload=’fillCells();’><table align=”center” valign=”top”>
<tr style=”background: #FFEEAA; font-size: 15pt”><td id=’td1′>text </td><td id=’td2′>text </td><td id=’td3′>text </td><td id=’td4′>text </td><td id=’td5′>text </td><td id=’td6′>text </td><td id=’td7′>text </td></tr><tr id=”tr1″><td id=’td8′>text </td><td id=’td9′>text </td><td id=’td10′>text </td><td id=’td11′>text </td><td id=’td12′>text </td><td id=’td13′>text </td><td id=’td14′>text </td></tr><tr><td id=’td15′>text </td><td id=’td16′>text </td><td id=’td17′>text </td><td id=’td18′>text </td><td id=’td19′>text </td><td id=’td20′>text </td><td id=’td21′>text </td></tr><tr id=”tr1″><td id=’td22′>text </td><td id=’td23′>text </td><td id=’td24′>text </td><td id=’td25′>text </td><td id=’td26′>text </td><td id=’td27′>text </td><td id=’td28′>text </td></tr><tr><td id=’td29′>text </td><td id=’td30′>text </td><td id=’td31′>text </td><td id=’td32′>text </td><td id=’td33′>text </td><td id=’td34′>text </td><td id=’td35′>text </td></tr><tr id=”tr1″><td id=’td36′>text </td><td id=’td37′>text </td><td id=’td38′>text </td><td id=’td39′>text </td><td id=’td40′>text </td><td id=’td41′>text </td><td id=’td42′>text </td></tr><tr><td id=’td43′>text </td><td id=’td44′>text </td><td id=’td45′>text </td><td id=’td46′>text </td><td id=’td47′>text </td><td id=’td48′>text </td><td id=’td49′>text </td></tr><tr id=”tr1″><td id=’td50′>text </td><td id=’td51′>text </td><td id=’td52′>text </td><td id=’td53′>text </td><td id=’td54′>text </td><td id=’td55′>text </td><td id=’td56′>text </td></tr><tr><td id=’td57′>text </td><td id=’td58′>text </td><td id=’td59′>text </td><td id=’td60′>text </td><td id=’td61′>text </td><td id=’td62′>text </td><td id=’td63′>text </td></tr><tr id=”tr1″><td id=’td64′>text </td><td id=’td65′>text </td><td id=’td66′>text </td><td id=’td67′>text </td><td id=’td68′>text </td><td id=’td69′>text </td><td id=’td70′>text </td></tr><tr><td id=’td71′>text </td><td id=’td72′>text </td><td id=’td73′>text </td><td id=’td74′>text </td><td id=’td75′>text </td><td id=’td76′>text </td><td id=’td77′>text </td></tr><tr></tr>
</table>
var arr=[
‘Sunday’,’Monday’,’Tuesday’,’Wednesday’,’Thursday’,’Friday’,’Saturday’,
”,”,’1′,’2′,’3′,’4′,’5′,
”,”,”,”,”,”,”,’6′,’7′,’8′,’9′,’10’,’11’,’12’,”,”,”,”,”,”,”,’13’,’14’,’15’,’16’,’17’,’18’,’19’,”,”,”,”,”,”,”,’20’,’21’,’22’,’23’,’24’,’25’,’26’,”,”,”,”,”,”,”,’27’,’28’,’29’,’30’,’31’,”,”,”,”,”,”,”,”,”]; var no = 0; var lim=76;
function fillCells() {
for (var i=0; i
</body>
</html>
The textareas are editable and scrollable, so nearly anything can be put in them. However, in this example they cannot be saved. However, that is not difficult. Since the textareas have an id, their values can be placed in a delimited string and saved in local storage. I have done that and it works fine, but I think that code is beyond the scope of this post. The editable calendar was not a goal in itself, but an example of how to easily create complex tables. I will leave it as an exercise to write the code to make it work.
There is also the need to change the date numbering and I have done that as well, but I will also leave that as an exercise.