Google Chart Area Bar Column Line Superimposition Tutorial

Google Chart Area Bar Column Line Superimposition Tutorial

Google Chart Area Bar Column Line Superimposition Tutorial

Our study of the Google Charts API has led us to identify “synergy sets” of chart functionality as per …

  • “the statisticals” … Area and Bar and Column and Line charts … the subject of today’s tutorial … damn! … did you see the title already?!
  • “the wheres” … Map and Geo and Intensity charts
  • “the sectors” … Pie and Histogram charts
  • “the timelies” … Timeline and Annotated Timeline and Calendar charts

These “synergies” in our mind are based on the data format, and/or the “synergies” we discover when using them, as in interesting follow up views or presentations of the data.

It is all round “synergy” as far as the Area and Bar and Column and Line (“the statisticals”) charts go, as they use the same data and just present it in different ways, in the sense that depending on the nature of the data, one or other of these presentation effects will be more aesthetically pleasing and/or (practically) informative than the others. That’s why we’ve taken on the work of today to …

  • be able to move from one of Area or Bar or Column or Line charts in an easy way …
    1. right from the start … or …
    2. after data entry when shown

    … and move …

    1. totally to the user selected chart display … or …
    2. superimpose one chart over another
  • via user access approaches …
    1. “&onclick=y” Google Chart select (ie. onclick event, for Google Charts) menu options (that also allow superimposition of a Google Chart on top of another same type of Google Chart with altered data) … via the appending of “+” to existant user interaction options … or …
    2. new HTML “a” links always in view for the user to click or double click (for superimposition)

Did you shudder at the reference to “double click”? We do not even reference the HTML/Javascript “ondblclick” event with our logic, today, just saying a scenario of “two clicks on the one link within two seconds” amounts to a “double click” in our logic, causing the web application to change capes into Superimposition Web Application Mode.

We channel the works of the previous Google Chart Column Chart Statistical Share Tutorial and the discovery, with recent Geo Chart interfacing work with Google Geo and Map Chart Co-ordinate Overlay Tutorial, that overlaying HTML iframe contents containing Google Charts data was possible … and still is … quiet yayyyyyyyyyy.

Howevvvvver (and we ask, when is “the return of the butts”;), we need to curb our enthusiasm somewhat here. Those “precision buffs” out there will not be happy as it stands now, because many changes of data will cause different SVG element scaling. Yes, Google Charts uses SVG. We may revisit to see if this can be controlled, but for now, for this reson, and for the reason of some ugly textual superimpositions that occur, we hold back on “full enthusiasm mode” and instead put on special purpose “cape B”, designed for Superishimposition Web Application Mode.

Yet, here are are, urging you to try …

… to see whether any/all of this is of interest, or has been a real bummer of an experience, and you wished you’d never come across any of it in even one second of your little life. We hope the former?! Toodle pip!


Previous relevant Google Chart Column Chart Statistical Share Tutorial is shown below.

Google Chart Column Chart Statistical Share Tutorial

Google Chart Column Chart Statistical Share Tutorial

Yesterday’s Google Chart Column Chart Statistical Table Tutorial improved inhouse Google Chart Column Chart web application “Spreadsheet Table” concept design left an opportunity down at the bottom right for more integration. Wasted space in a “spreadsheet”? We want to offer some “optionals”. So we’ve seen, like with Google Chart Select Event Cache Issue Tutorial, that the four Google Charts of common data input structure, namely …

… have synergies with each other and a Sharing “grid” of functionality to aid the user could consist of …

  • display in HTML iframe within that lower right region of the Statistics Table … and …
  • open in a new Window … or …
  • email with your default Email Client application

… could be useful work today, as Tables and Graphs often form the basis for communication and discussion.

Our Google Chart Column Chart web application changed this way in column_chart.php to allow for this. You might want to try it yourself at this live run link.

Unaffected is the HTML and Javascript “Timed Survey Count” web application live run‘s underlying timed_count.html code.


Previous relevant Google Chart Column Chart Statistical Table Tutorial is shown below.

Google Chart Column Chart Statistical Table Tutorial

Google Chart Column Chart Statistical Table Tutorial

Sometimes it is a hard decision whether to separate the (often long winded) story leading up to something from the something itself. Today, at the risk of sounding verbose, just in case you are coming in here for the first time today, we are including the “back story”. If you are a regular, you’ll know once the blog posting title changes radically, it’s like a new start, and today’s story is both a new start and a continuation of what you would be familiar with by now, the “Timed Survey Count” web application we last talked about just below, with HTML Select Element Dynamic Multiple Attribute CSS Tutorial.

If you are a big spreadsheet person, with most of the major applications over the many years of one of personal computing’s first “killer apps” you’ll be familiar with the relationship between …

  • Spreadsheet (worksheet) … and …
  • Chart … most commonly, debatably, with a Column Chart

… for what else are the innards of the data arrangement of the Google Charts Column Chart than those underpinning what is the basis of a design of a Spreadsheet (worksheet) … and a relational database table, at that … columns and rows.

And when we started wanting our own Statistics functionality for that “Timed Survey Count” web application, and we showed yesterday the first “dippings of the toesies in the seas of statistical waves of wafting words with little to no meaning” … but we digress. It was then that it occurred to us that to dip further would probably involve the use of an HTML table element, and then it occurred to us, with the help of New Century Maths Stages 5.2/5.3 pages 394 and 395 (by Klaas Bootsma, David Badger, Colin Skene, Robert Yen, David Adams), thanks, that this table would best, at least first off, look like a Spreadsheet, and then as time goes on, act like one more and more, but not try to reinvent some historically well working wheels.

Then we thought that this functionality should be put into our interface to the Google Chart Column Chart we last tweaked back at Trip Google Chart London Population Timeline Tutorial, so that now we have three display modes of use with this web application, namely …

  1. Google Chart display
  2. Spreadsheet Table display
  3. Both

… which isn’t as fundamental a PHP change as you’d think …


if ($GETmode == 'Both') {
echo " <h1>" . $GETtitle . " Statistics Table and Column Chart</h1> \n";
echo '<div id="statistics_table" style="display:block;">' . $statistics . '</div><div id="chart_div" style="display:block;"></div><div id="bitsatend" style="display:inline;"></div>' . " \n";
} else if ($GETmode != 'Statistics') {
echo " <h1>" . $GETtitle . " Column Chart</h1> \n";
echo '<div id="statistics_table" style="display:none;"></div><div id="chart_div" style="display:block;"></div><div id="bitsatend" style="display:inline;"></div>' . " \n";
} else {
echo " <h1>" . $GETtitle . " Statistics Table</h1> \n";
echo '<div id="statistics_table" style="display:block;">' . $statistics . '</div><div id="chart_div" style="display:none;"></div><div id="bitsatend" style="display:inline;"></div>' . " \n";
}

… though the looks (above) can be vastly different, but is simple due to Google Charts contained by an HTML div element … such a talented beasting … just see HTML Div Overlay Jigsaw Talents Primer Tutorial

And so our Google Chart Column Chart web application changed this way in column_chart.php to allow for this. You might want to try it yourself at this live run link.

And the HTML and Javascript “Timed Survey Count” web application live run‘s underlying timed_count.html code changed in this way regarding this improved statistical data integration.


Previous relevant HTML Select Element Dynamic Multiple Attribute CSS Tutorial is shown below.

HTML Select Element Dynamic Multiple Attribute CSS Tutorial

HTML Select Element Dynamic Multiple Attribute CSS Tutorial

There’s a dual purpose to today’s work on our “Timed Survey Count” web application, that being …

  • Styling CSS work
  • Preliminary Statistics functionality

… respectively because …

  • we got sick of the look of Styling work (or lack of) up until now, and we like to have a pass at the end when Styling, because we don’t mind having Styling defined at any/all of …
    1. external CSS
    2. local CSS
    3. HTML element style property

    … because we tend to like to use that last one as we go along, until our Styling CSS push near the end, and this both clarifies our thoughts in this regard, and it is surprising how easy it is to design local CSS to override HTML style settings anyway, even to the extent of the use of !important to push CSS Styling precedence in the direction of something defined anywhere in one of those ways mentioned above.

  • we want to start on this here in summary form, and then develop something generic, as a separate web application based on these musings

As time goes on with web programming, it’ll probably be the case that you find CSS more and more readable, but have to really point out a great boon for CSS readability if the HTML web page looks obvious in some way about its design …


td:nth-child(2) {
background-color: white;
text-align: right;
border: 3px solid #f0f0f0;
}

… where the obvious HTML table cell (3 of) look of our web application, tees up nicely with the marvellous CSS nth-child(n) selector above, making it pretty obvious even without looking up references that the styling applies to the second cell in our web application table (of 3) cells. Find the other thing about all this is that when perusing CSS “code” this way, it often only takes one obvious styling section to stick out at you, to help you join the dots into understanding a lot of the rest. Mind you, it’s not “rocket science” CSS styling we’re dealing with today, building on yesterday’s HTML Select Element Dynamic Multiple Attribute Chart Tutorial foundations, and it pays to practice CSS both with simple examples, and perhaps build on complex ones you see off the “net” and tinker with, in private … cupboards are excellent here … as long as there’s room in there coming up to New Year’s Eve, with the dogs wanting the space, with the fireworks going on.

Continuing on the theme of lack of rocket science have you noticed with the HTML Javascript code the most complex we ever get with our use of collections is to use an array … and usually in this pattern, exemplified for our array pie_chart_diff

  1. var pie_chart_diff=[]; // you initialize the array (to be empty)
  2. pie_chart_diff.push(into_array_variable); // populate the array
  3. pie_chart_diff.sort(); // sort the members of the array, normally strings that have a readily sortable data structure similar to date ones we use like YYYY_mm_dd_HH24_mi_ss
  4. use that collected data via code like …

    for (iii=0; iii<pie_chart_diff.length; iii++) {
    // do stuff with pie_chart_diff[iii]
    }

And so it behoves us to …

  • usher you into a New Year (yay!!!) with …
  • HTML and Javascript live run‘s underlying timed_count.html code changed in this way regarding our initial foray into some Statistics functionality and a CSS Styling “makeover” today

… and we hope your sleeping patterns are not affected by this break with transmission, as we fully expect the adult readers to be able to handle all other aspects of the New Year?!


Previous relevant HTML Select Element Dynamic Multiple Attribute Chart Tutorial is shown below.

HTML Select Element Dynamic Multiple Attribute Chart Tutorial

HTML Select Element Dynamic Multiple Attribute Chart Tutorial

We’re starting down the road of “Reporting”, primarily, with our latest “Timed Survey Count” web application. In the blog posting title today we say “Chart” and that “Chart” being referred to today are Google Charts, specifically …

  • Histogram Chart … when there is one data point
  • Pie Chart Differences … when there are two data points
  • Column Chart … when there are more than two data points … and onclick select event usage can glean some statistical information here, as you can seeing happen with today’s tutorial picture

Along the way, getting this functionality together, we used the Emoji Overlay concepts we talked about at Emoji Overlay Primer Tutorial along with the emoji specifics at this great link (thanks), to hook up with yesterday’s new Cookie dropdown of HTML Select Element Dynamic Multiple Attribute Cookie Tutorial, except that instead of yesterday’s …

… we did think about multiple attribute mode “dropdown” use here, but decided against it, for now

… “now” has come with a “rethink” for us to remember those early words of the blog posting title, that being “HTML Select Element Dynamic Multiple Attribute”, and divide that dropdown’s usage into …

  • single attribute mode usage for Cookie functionality … and …
  • multiple attribute mode usage for Reporting functionality creating HTML iframe “child” element reports in the bottom part of the web application’s table’s third column

We hope you can see it is fairly obvious why when you have multiple related data points of interest to a user a multiple attribute mode dropdown (ie. HTML select element) might be of great usefulness.

Today, the HTML and Javascript live run‘s underlying timed_count.html code changed in this way regarding our initial steps into “Reporting” Google Chart functionality today. We again hope you try it out and/or get something out of this tutorial.

Before we go, a couple of code points of interest … those of you interested in the awkward way our PHP code (unchanged) and HTML referenced the Javascript function pifilter() even from a couple of days ago, it’s intent becomes clearer today as a foot in a door (for Histogram reporting purposes) …


function pifilter(inpi) {
var ainpi=inpi.split(" value='"), crest='';
if (ainpi.length == 1) {
ainpi=inpi.split(' value="');
if (ainpi.length == 1) {
ainpi=inpi.split(' value=');
if (ainpi.length > 1) {
crest=ainpi[1].split('>')[0];
}
} else {
crest=ainpi[1].split('"')[0];
}
} else {
crest=ainpi[1].split("'")[0];
}
if (crest != "") {
return inpi.replace("<p ", "<p style=display:none; ") + "<a style=text-decoration:none;cursor:pointer; title='Histogram Google Chart' onclick=' draw_one_histogram(this.innerHTML); '>" + crest + "</a><br><br>";
}

return inpi;
}

… and note here a way we code HTML a links more and more these days, when we have functionality to do but no real navigation as our intent, to use an href hashtag (#) navigation we’ve noticed can move things … and we don’t want to move … is to have no href at all, and at least style with “cursor:pointer”.

Secondly, and lastly (… so turrah for now), we’ll leave you with an updated function howManyCookies because it changed a lot from yesterday …


function howManyCookies() {
var proposedsel="", sorted="", sorteda=[], lastone='';
var cookies = document.cookie.split("; ");

for (var i = eval(-1 + cookies.length); i >= 0; i--) {
var cookie = cookies[i];
var eqPos = cookie.indexOf("=");
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
if (name.indexOf("dat") == 0) {
if (proposedsel == "") proposedsel='<span style="width:300px;position:absolute;top:76px;left:90px;"><select id="cookiesel" style="width:190px;background-color:pink;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value,this); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select><div style=display:inline; id=dchkpie> <input title="Histogram and Pie Chart Difference Google Charts" style=display:inline;color:lightblue; type=checkbox id=chkpie onchange=" dochkpie(true); "></input> </div></span><span style=opacity:1.0;position:absolute;top:35px;left:150px;font-size:24px;visibility:hidden;z-index:6; onclick="document.getElementById(' + "'chkpie'" + ').click();" class=emojioverlay>&x1F370;&x1F4C8;</span>';
sorteda.push('<option title="' + cookiedate(name).replace("_","/").replace("_","/").replace("_","-").replace("_",":").replace("_",":") + " : " + decodeURIComponent(cookievalue(name)) + '" value="' + name + '">' + cookiedate(name).replace("_","/").replace("_","/").replace("_","-").replace("_",":").replace("_",":") + " : " + decodeURIComponent(cookievalue(name)) + '</option>');
//proposedsel=proposedsel.replace('</select>','<option title="' + cookiedate(name).replace("_","/").replace("_","/").replace("_","-").replace("_",":").replace("_",":") + " : " + decodeURIComponent(cookievalue(name)) + '" value="' + name + '">' + cookiedate(name).replace("_","/").replace("_","/").replace("_","-").replace("_",":").replace("_",":") + " : " + decodeURIComponent(cookievalue(name)) + '</option></select>');
} else if (name == "subject") {
if (proposedsel == "") proposedsel='<span style="width:300px;position:absolute;top:76px;left:90px;"><select id="cookiesel" style="width:190px;background-color:pink;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value,this); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select><div style=display:inline; id=dchkpie> <input title="Histogram and Pie Chart Difference Google Charts" style=display:inline;color:lightblue; type=checkbox id=chkpie onchange=" dochkpie(true); "></input> </div></span><span style=opacity:1.0;position:absolute;top:35px;left:150px;font-size:24px;visibility:hidden;z-index:6; onclick="document.getElementById(' + "'chkpie'" + ').click();" class=emojioverlay>&x1F370;&x1F4C8;</span>';
proposedsel=proposedsel.replace('<option value="">Recall all below</option>','<option value="">Recall all below</option><option value="' + name + '">Timed Count of: ' + decodeURIComponent(cookievalue(name)) + '</option>');
} else if (name == "items") {
if (proposedsel == "") proposedsel='<span style="width:300px;position:absolute;top:76px;left:90px;"><select id="cookiesel" style="width:190px;background-color:pink;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value,this); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select><div style=display:inline; id=dchkpie> <input title="Histogram and Pie Chart Difference Google Charts" style=display:inline;color:lightblue; type=checkbox id=chkpie onchange=" dochkpie(true); "></input> </div></span><span style=opacity:1.0;position:absolute;top:35px;left:150px;font-size:24px;visibility:hidden;z-index:6; onclick="document.getElementById(' + "'chkpie'" + ').click();" class=emojioverlay>&x1F370;&x1F4C8;</span>';
proposedsel=proposedsel.replace('<option value="">Recall all below</option>','<option value="">Recall all below</option><option value="' + name + '">Made Up Of: ' + '[' + decodeURIComponent(cookievalue(name)).replace(/\+/g,' ') + ']' + '</option>');
} else if (name == "howoften") {
if (proposedsel == "") proposedsel='<span style="width:300px;position:absolute;top:76px;left:90px;"><select id="cookiesel" style="width:190px;background-color:pink;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value,this); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select><div style=display:inline; id=dchkpie> <input title="Histogram and Pie Chart Difference Google Charts" style=display:inline;color:lightblue; type=checkbox id=chkpie onchange=" dochkpie(true); "></input> <span style=opacity:1.0;position:absolute;top:35px;left:150px;font-size:24px;visibility:hidden;z-index:6; onclick="document.getElementById(' + "'chkpie'" + ').click();" class=emojioverlay>&x1F370;&x1F4C8;</span> <input title="Histogram and Pie Chart Difference Google Charts" style=display:inline;color:lightblue; type=checkbox id=chkpie onchange=" dochkpie(true); "></input> <input title="Histogram and Pie Chart Difference Google Charts" style=display:inline;color:lightblue; type=checkbox id=chkpie onchange=" dochkpie(true); "></input></div></span>';
proposedsel=proposedsel.replace('<option value="">Recall all below</option>','<option value="">Recall all below</option><option value="' + name + '">Every Starting: ' + timeval(decodeURIComponent(cookievalue(name))) + '</option>');
} else if (name == "reason" || name == "person" || name == "place") {
if (proposedsel == "") proposedsel='<span style="width:300px;position:absolute;top:76px;left:90px;"><select id="cookiesel" style="width:190px;background-color:pink;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value,this); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select><div style=display:inline; id=dchkpie> <input title="Histogram and Pie Chart Difference Google Charts" style=display:inline;color:lightblue; type=checkbox id=chkpie onchange=" dochkpie(true); "></input> </div></span><span style=opacity:1.0;position:absolute;top:35px;left:150px;font-size:24px;visibility:hidden;z-index:6; onclick="document.getElementById(' + "'chkpie'" + ').click();" class=emojioverlay>&x1F370;&x1F4C8;</span>';
proposedsel=proposedsel.replace('<option value="">Recall all below</option>','<option value="">Recall all below</option><option value="' + name + '">' + name.replace('reason','For').replace('place','At').replace('person','By') + ': ' + decodeURIComponent(cookievalue(name)) + '</option>');
} else if (proposedsel == "") {
proposedsel='<span style="width:300px;position:absolute;top:76px;left:90px;"><select id="cookiesel" style="width:190px;background-color:pink;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value,this); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select><div style=display:inline; id=dchkpie> <input title="Histogram and Pie Chart Difference Google Charts" style=display:inline;color:lightblue; type=checkbox id=chkpie onchange=" dochkpie(true); "></input> </div></span><span style=opacity:1.0;position:absolute;top:35px;left:150px;font-size:24px;visibility:hidden;z-index:6; onclick="document.getElementById(' + "'chkpie'" + ').click();" class=emojioverlay>&x1F370;&x1F4C8;</span>';
}
}
if (proposedsel != "" && sorted == "" && sorteda.length > 0) {
sorteda.sort();
for (var isort=eval(-1 + sorteda.length); isort>=0; isort--) {
if (lastone == "") {
sorted+=sorteda[isort];
lastone=sorteda[isort];
} else if (sorteda[isort] != lastone) {
sorted+=sorteda[isort];
lastone=sorteda[isort];
}
}
}
if (proposedsel != "" && sorted != "") proposedsel=proposedsel.replace('</select>',sorted + '</select>');
if (proposedsel != "") setTimeout(checkforclass,500);
return proposedsel;
}


Previous relevant HTML Select Element Dynamic Multiple Attribute Cookie Tutorial is shown below.

HTML Select Element Dynamic Multiple Attribute Cookie Tutorial

HTML Select Element Dynamic Multiple Attribute Cookie Tutorial

We’ve been going on and on and on and on and on and on and on about “Save and Recall” “accountability” functionality with our “Timed Survey Counter” web application we left off with HTML Select Element Dynamic Multiple Attribute Post Tutorial yesterday, when we shored it up this way for large amounts of data. That’s well and good within the one connected “session” of work, which is what we’ve referred to before as “intrasession” in our Emoji Overlay Share Tutorial. In that same tutorial we extended …

  • intrasession accountability thinking … with …
  • intersession accountability

… via HTTP Cookies, and here, today, we are getting that “intersession” accountability via client HTTP Cookies stored on your local web browser. Again, this is a design decision, because, depending on the permanence you want to have regarding your data …

  • HTTP Cookies are all fine and good for those smaller amounts of data that doesn’t have to last beyond the lifespan of your web browser having its Cache cleared … versus …
  • Indexeddb client Javascript run databases, as we mentioned with, Home Grown Spreadsheet Indexeddb Primer Tutorial have one degree more of a permanent feel … versus …
  • Web Server flat file systems (perhaps based on an IP address formulated naming system) can be a permanent data solution but rely on you having access to that web server, and unless you’re using directories protected by the web server hosting (eg. Apache can be organised for these), there is nothing more than file priviledge and permissions as security measures … versus …
  • Proprietry Databases like MySql have storage and security features for a fully permanent arrangement

… and we’ve decided the first HTTP Cookies type of data storage “intersession” (and/or “intrasession”) wise will do us for this project. If you think a weakness here is that just because we use “client” HTTP Cookies, that means there is no scope for PHP code to help us out into the future, think again. PHP can see “client” HTTP Cookies, just not at the same time period as your client Javascript does, but can nonetheless. To read more about this, please consult this useful link.

But today, we don’t call on the PHP to do anything about our first foray into our “Timed Survey Counter” web application’s HTTP Cookie functionality, where, as for most Cookie functionality, you concern yourself (as a coder) with …

  • When do we save the web application’s “Timed Survey Counter” data into HTTP Cookie recallable form? We do it during the HTML form element’s onsubmit HTML form event logic as so

    function validateform() {
    var bulkofurl='';
    var ps=document.getElementsByTagName('p');
    for (var ips=0; ips<ps.length; ips++) {
    if (ps[ips].outerHTML.indexOf(' name="') != -1) {
    bulkofurl+='&' + ps[ips].outerHTML.split(' name="')[1].split('"')[0] + '=' + encodeURIComponent(ps[ips].innerHTML);
    } else if (ps[ips].outerHTML.indexOf(' id="') != -1) {
    bulkofurl+='&' + ps[ips].outerHTML.split(' id="')[1].split('"')[0] + '=' + encodeURIComponent(ps[ips].innerHTML);
    }
    }
    cookiesaved=false;
    savecookie('theseones');

    if (bulkofurl.length > 800) {
    document.getElementById('myform').action=document.getElementById('myform').action.replace('.html','.php').replace('.htm','.php');
    document.getElementById('myform').method='POST';
    //alert('doing php');
    }
    return true;
    }

    … which corresponds to the user tapping or clicking the “Save and Recall” button, but before it goes off and (actually) “saves and recalls”
  • How will we show previous session HTTP Cookie recallable settings? We’ve decided it should be a single attribute mode “dropdown” just below the “Save and Recall” button.
  • When do we construct the “dropdown” above? We do it just after the Javascript ” if (count == 0) {“ and after any PHP interventional code … remember yesterday’s HTML Select Element Dynamic Multiple Attribute Post Tutorial … and now we add to that

    <script type='text/javascript'>
    // Other Javascript local code

    function docount() {
    if (count == 0) {
    // PHP intervention will go here ...

    // ... end of PHP intervention
    document.getElementById('cookieextras').innerHTML=howManyCookies();
    // Start of rest of Javascript code of function docount() ...

    // ... End of rest of Javascript code of function docount()
    }

    // Rest of local Javascript code ...

    // ... End of rest ... then new ...
    function howManyCookies() {
    var proposedsel="";
    var cookies = document.cookie.split("; ");

    for (var i = eval(-1 + cookies.length); i >= 0; i--) {
    var cookie = cookies[i];
    var eqPos = cookie.indexOf("=");
    var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
    if (name.indexOf("dat") == 0) {
    if (proposedsel == "") proposedsel='<select id="cookiesel" style="background-color:pink;position:absolute;top:76px;left:60px;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select>';
    proposedsel=proposedsel.replace('</select>','<option value="' + name + '">' + cookiedate(name).replace("_","/").replace("_","/").replace("_","-").replace("_",":").replace("_",":") + " : " + decodeURIComponent(cookievalue(name)) + '</option></select>');
    } else if (name == "subject") {
    if (proposedsel == "") proposedsel='<select id="cookiesel" style="background-color:pink;position:absolute;top:76px;left:60px;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select>';
    proposedsel=proposedsel.replace('<option value="">Recall all below</option>','<option value="">Recall all below</option><option value="' + name + '">Timed Count of: ' + decodeURIComponent(cookievalue(name)) + '</option>');
    } else if (name == "items") {
    if (proposedsel == "") proposedsel='<select id="cookiesel" style="background-color:pink;position:absolute;top:76px;left:60px;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select>';
    proposedsel=proposedsel.replace('<option value="">Recall all below</option>','<option value="">Recall all below</option><option value="' + name + '">Made Up Of: ' + '[' + decodeURIComponent(cookievalue(name)).replace(/\+/g,' ') + ']' + '</option>');
    } else if (name == "howoften") {
    if (proposedsel == "") proposedsel='<select id="cookiesel" style="background-color:pink;position:absolute;top:76px;left:60px;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select>';
    proposedsel=proposedsel.replace('<option value="">Recall all below</option>','<option value="">Recall all below</option><option value="' + name + '">Every Starting: ' + timeval(decodeURIComponent(cookievalue(name))) + '</option>');
    } else if (name == "reason" || name == "person" || name == "place") {
    if (proposedsel == "") proposedsel='<select id="cookiesel" style="background-color:pink;position:absolute;top:76px;left:60px;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select>';
    proposedsel=proposedsel.replace('<option value="">Recall all below</option>','<option value="">Recall all below</option><option value="' + name + '">' + name.replace('reason','For').replace('place','At').replace('person','By') + ': ' + decodeURIComponent(cookievalue(name)) + '</option>');
    } else if (proposedsel == "") {
    proposedsel='<select id="cookiesel" style="background-color:pink;position:absolute;top:76px;left:60px;" onchange=" if (this.value.length != 1) { recallThisCookie(this.value); } "><option value=" ">Previous session values below ...</option><option value="--">Clear all below</option><option value="">Recall all below</option></select>';
    }
    }
    return proposedsel;
    }

    </script>
    </head>
    <body onload="docount(); amendvia((location.search.split('max=')[1] ? location.search.split('max=')[1].split('&')[0] : ''));" style='background-color:magenta;'>
    <!-- Lots more HTML here -->
    <div id=cookieextras></div>
    <!-- Bit more HTML here -->

    … making sure there are options to effectively “Clear Cookies” and to “Recall All the Cookie Information” … we did think about multiple attribute mode “dropdown” use here, but decided against it, for now

And so we have an “intersession” capability of data “accountability” to add to our pre-existing “intrasession” data “accountability”.

The HTML and Javascript live run‘s underlying timed_count.html code changed in this way regarding “intersession” HTTP Cookie data “accountability” today. We hope you try it out and/or get something out of this discussion.


Previous relevant HTML Select Element Dynamic Multiple Attribute Post Tutorial is shown below.

HTML Select Element Dynamic Multiple Attribute Post Tutorial

HTML Select Element Dynamic Multiple Attribute Post Tutorial

In the real world of web application programming, as far as what we call “accountability” goes, and we think of …

“accountability” with a web application, for us, goes along the lines of having a web application whose data can be recalled and reused for another time

… it often takes up a good deal of the design and programming coding time. The term “overkill” can come into the “accountability” topic area “big time”. Overdesign, and you waste time. It goes towards asking …

  • Who could use this web application?
  • How might they apply the functionality of this web application?

… as to, in your opinion, along with consulting the potential users, how much data will happen to cater for your designated “happy” percentage of users out there. Of course, if you are writing this for a client, the client is always right … that is, when they aren’t “left” out … chortle, chortle.

Your program design comes into it too. Are you wasteful with the design? Like, relooking at our current “Timed Survey Count” web application we last talked about at HTML Select Element Dynamic Multiple Attribute Mobile Tutorial as shown below, I can see that …

  • data length could be made smaller by shortening the “date” data item names at the “cost” of making the analysis of its meaning proceeding synchronously from the most detailed (perhaps earliest) date definition item and filling in less detailed ones as they are analyzed (through) via previous knowledge … the simplest example here would be to strip off subsequent dates appearing on the same day as a previously more fully defined date data item, and another would be not to include date data items where nothing happened (ie. the 1*0 ones) … versus …
  • the coding complexity (and the danger of bugs) this might introduce … but “Who has bugs?” “What’s this bug thingo?” … deeper chortle, deeper chortle

… and this tradeoff decision, for us, today, is to say “forget that coding complexity above” and “let’s just cater, dynamically, at the HTML form validation phase (via the onsubmit HTML form event) for the use of a PHP helper web application for those longer data tallying/surveys the user performs” … the latter of which is not trivial either, but, to us, is a more long lasting and satisfying, use of coding time … and that means …

  • the onsubmit HTML form event code’s job becomes to “guesstimate” the length of an address bar URL method=GET HTML form scenario “submit”, and if less than (we say 800) a conservative length number for the date related data items, then we can stick with the default (and still avoid “the dreaded” error 414 request URI too long error message) …
    1. method=GET
    2. action=./timed_count.html

    … for a long, but not too long address bar URL to be fired off … whereas …

  • the onsubmit HTML form event code, using Javascript DOM, will set the …
    1. method=POST
    2. action=./timed_count.php

… for those more serious surveys. Which means that users without the means to PHP can still work with the smaller, shorter more trivial data length surveys without having to resort to the more heavy duty PHP web serverside code ‘helper’ web application usage.

The design of today’s new PHP ‘helper’ timed_count.php is that simple thought process of …

  • you take what it’s helping as a “basis” (ie. it has a variable called $basis) … gleaned via good ol’ file_get_contents … and then …
  • trace through all the $_POST data, because on this occasion the date data item names of $_POST[] are not entirely known, and so we got great help here, from this great link … thanks for …


    foreach($_POST as $k => $v) { // thanks to http://stackoverflow.com/questions/8567847/loop-through-post-variables-with-similar-names
    if(strpos($k, 'data') === 0) {
    // these are the date related "tallying" "survey" date/time pointing data items
    }
    }

    … and then

  • pick the stop where all your PHP intervention Javascript code can be placed (in Javascript function docount()) … and we also show that onsubmit event code change … for us, after

    <script type='text/javascript'>
    // Other Javascript local code

    function docount() {
    if (count == 0) {
    // PHP intervention will go here ...

    // ... end of PHP intervention
    // Start of rest of Javascript code of function docount() ...

    // ... End of rest of Javascript code of function docount()
    }

    // Rest of local Javascript code ...

    // ... End of rest ... then new ...
    function validateform() {
    var bulkofurl='';
    var ps=document.getElementsByTagName('p');
    for (var ips=0; ips<ps.length; ips++) {
    if (ps[ips].outerHTML.indexOf(' name="') != -1) {
    bulkofurl+='&' + ps[ips].outerHTML.split(' name="')[1].split('"')[0] + '=' + encodeURIComponent(ps[ips].innerHTML);
    } else if (ps[ips].outerHTML.indexOf(' id="') != -1) {
    bulkofurl+='&' + ps[ips].outerHTML.split(' id="')[1].split('"')[0] + '=' + encodeURIComponent(ps[ips].innerHTML);
    }
    }
    if (bulkofurl.length > 800) {
    document.getElementById('myform').action=document.getElementById('myform').action.replace('.html','.php').replace('.htm','.php');
    document.getElementById('myform').method='POST';
    //alert('doing php');
    }
    return true;
    }


    </script>
    </head>
    <body onload="docount(); amendvia((location.search.split('max=')[1] ? location.search.split('max=')[1].split('&')[0] : ''));" style='background-color:magenta;'>
    <form onsubmit="return validateform()" id='myform' method='GET' action='./timed_count.html'>

    … then …
  • analyze the needs and “plonk” the relevant Javascript DOM to “catch up” with the default method=GET logic … arriving back at athe “common train stop” “GetPost” (shall we say … eh, wot, guv’?)

In practice, to get this right takes time, but you have everything there at your disposal to do a good job, as long as you are working with an HTML (and Javascript and CSS) web inspector, as we do today with the Safari web browser’s Web Inspector (that came with Safari, when it came with Mac OS X). You can see it there at the bottom in today’s tutorial picture. Doing this job without that Web Inspector is actually hard to imagine, for me at least.

Am sure you won’t be surprised to hear that all this affects the HTML and Javascript more than you might think, and by the way, as well, today, we’ve added in more “accountability” (for reporting purposes) user fields (“at”, “by”, “for” for “where?”, “who?”, “why?” purposes) in the live run‘s underlying timed_count.html code, which changed in this way regarding the shoring up of data “accountability” with the potential for more seriously in depth “survey” scenarios.


Previous relevant HTML Select Element Dynamic Multiple Attribute Mobile Tutorial is shown below.

HTML Select Element Dynamic Multiple Attribute Mobile Tutorial

HTML Select Element Dynamic Multiple Attribute Mobile Tutorial

There’s no threetwo ways about it, mobile platforms do not like HTML select element in multiple attribute mode use. I waited a whole day to see if the “big guns” would change their mind, and here we are, and they haven’t … and … just between you and me … we have a feeling in our water they’re not going to change their mind.

So what’s an alternative? Well, given that mobile platforms are still okay writing to (an HTML select element called “selo”) selo.options[0].text that comma separated “tallying” we do, we think, for mobile platforms, as an alternative approach we’ll combine …

  • selo.options[0].text as that one option element “tallying” dropdown part (as is) … with …
  • other HTML input type=button replacements for all the other HTML select element option elements (we’ll still use for non-mobile platforms)

And while we’re at this discusion, building on yesterday’s HTML Select Element Dynamic Multiple Attribute Survey Tutorial, how do we … yes, us … distinguish a mobile platform from a non-mobile one? We’re doing it in Javascript DOM via code like …


if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
// do mobile specific code
} else {
// do non-mobile specific code
}

Now, moving on from this, we’ve done a few other things, namely …

  • made the date data sortable in both an alphabetic and/or numerical way by using YYYY_mm_dd_HH24_mi_ss type of date/time formatting … which comes in handy when we come to …
  • our first “accountability” steps in this project to be able to save a snapshot and recall it via get parameter URL construction
  • allowed for keyboard “tallying” via a new separate “tallying” field option, because this allows the user to not have to be accurate with a mouse press of some sort, when they are rushed just trying to record lots of data items, and it could even be that several people can each be responsible for a particular (keyboard) keystroke all recording on the one device (but imagine this would be quite a squeezy prospect), and might allow for the screen not to distract from the data recording

With this last one, on mobile platforms, have you noticed with web applications on some mobile platforms, how a …


document.getElementById("myInputTypeIsTextElement").focus();

… attempt to focus to a “keyboard” keystroke element, on entering the web application the first time, is discouraged, or outright ignored? Am sure there is a reason, but even this is not a big concern here, because subsequent “document.getElementById(“myInputTypeIsTextElement”).focus();” are granted, and that just means that, perhaps quite rightly, a mobile user initially decides on their focus as to whether they will …

  • tap buttons with a mouse …
  • tap (keyboard) keystroke buttons

… which, when you think about it, is much of a muchness, unless you have one of those bluetooth keypads we talked about with Tablet Run Web Server Blog PHP Tutorial when the “keyboard” approach could have many advantages for “tallying” concentration, when it is very busy.

So we’re still going, but today’s work leaves us with this live run and with this HTML and Javascript underlying timed_count.html code, which changed in this way regarding the information above. We hope you try it out yourself.


Previous relevant HTML Select Element Dynamic Multiple Attribute Survey Tutorial is shown below.

HTML Select Element Dynamic Multiple Attribute Survey Tutorial

HTML Select Element Dynamic Multiple Attribute Survey Tutorial

It’s good with web programming where you do an application with realtime use, and we hope we are getting closer today (as with WordPress 4.1.1’s HTML Select Element Dynamic Multiple Attribute Survey Tutorial) with a “Timed Count” web application where the words that spring to mind regarding how it works, at least to us, are …

  • survey
  • tally

Think the teacher counting students who uses a counter system to “tally” the counter with what was expected at the end, or those people doing traffic “surveys” “tallying” up what they observe, presumably in relation to a time of day as well. Well, today, with our web application, we default its usage to that latter case, but it is flexible enough, even at this early stage to cater for other scenarios.

In a “survey” project of this type, the “tallying” is just one aspect of the job, and we’ll be talking about “accountability” and “reporting”, from where we see it, in tutorials to come, but just for now, we’re happy to be …

  • Asking (as needed) and recording, “for internal use only”, the “survey” title
  • Asking (as required) for a Starting (Time Elapsed) Period of interest
  • In realtime (ie. dynamically) record, via an HTML select element in multiple attribute mode use (as yesterday’s HTML Select Element Dynamic Multiple Attribute Game Tutorial got us more and more into, manperson), the “survey” “tallying” (or measurements, or findings) for that relevant time period … and …
  • At the break of a time period summarize previous, “for internal use only”, and ready the user for a clean slate where the counts are zeroed

Pretty simple concept, huh? But am sure you can see what use this could be, particularly with some more bells and whistles?! And if so … or even if not … why not try our live run with its HTML and Javascript underlying timed_count.html code.


Previous relevant HTML Select Element Dynamic Multiple Attribute Game Tutorial is shown below.

HTML Select Element Dynamic Multiple Attribute Game Tutorial

HTML Select Element Dynamic Multiple Attribute Game Tutorial

Today, we have a new game that makes use of HTML select element multiple attribute mode use during the workings of the game.

This is on the way to a mathematics statistics application and also looking back at yesterday’s HTML Select Element Dynamic Multiple Attribute Tutorial‘s first HTML select element multiple attribute mode blog posting here at this blog.

For this game, unlike yesterday’s …

Should it be “the full circle” of toggling capability, or just from Single attribute mode to Multiple attribute mode (but not back again) … and we pick the latter

… we have “the full circle” applying today, where the user is …

  • shown the game status in Single attribute mode … and …
  • waiting for user interaction in Multiple attribute mode

… and we need all of …

  • onclick (select) and onclick (option)
  • onfocus (select) and onfocus (option)

… but curiously, not the usual onchange (select) event … to work the functionality for the Random Counting Numbers Game whose HTML and Javascript code you can examine at random_counting_numbers.html link. Food for thought, we hope.


Previous relevant HTML Select Element Dynamic Multiple Attribute Tutorial is shown below.

HTML Select Element Dynamic Multiple Attribute Tutorial

HTML Select Element Dynamic Multiple Attribute Tutorial

Am sure a lot of web programmers would like to invent some generic code to allow the HTML select (“dropdown”) element be able to toggle between the …

  1. Single select attribute mode … and …
  2. Multiple select attribute mode

… dynamically, using Javascript DOM. But in order to be able to write a practically useful generic bit of code you have to have a confluence of agreed design guidelines, with lots of people participating and sticking to the guidelines, or have a concept whose predictability about “event” logic is pretty easy to envisage and define, for a lot of programmers to agree upon. But trying to pin down the “event” logic of a …

  • HTML select (“dropdown”) element onchange event … or even the …
  • HTML select (“dropdown”) element onclick event (as a first “wild” thought getting into the problem)

… is like catching a worm at the bottom of a 27 storey building being thrown from the top … you need to know when to give up too … think this salutary thought.

But that doesn’t mean the idea of an HTML select (“dropdown”) element being able to be dynamically toggled is not a good idea, but it just means you need to focus on …

  • Should it be “the full circle” of toggling capability, or just from Single attribute mode to Multiple attribute mode (but not back again) … and we pick the latter
  • Define what can be done to repeat the actions of the (what was only for the Single attribute mode of use) onchange event logic but for a scenario where that is applied several times for variable inputs, and is that requirement …
    1. synchronous … or …
    2. asynchronous

    … and for us, today, we need “synchronous” alas (as “asynchronous” would be a lot easier) … and this will become apparent later

Okay, “later” has arrived, and it is time to define where we applied an example of HTML select (“dropdown”) element being able to be dynamically toggled in our web applications. We decided to do it for our interfacings to our …

As we said earlier, we’re dealing with “synchronous” requirements here, giving the user the nominal video duration time, plus twenty seconds, to view the current video before the “child” calls the “parent” to change videos, powered via the Javascript setTimeout timer functionality, possible only because of the YouTube API’s video duration time information (which we already had stored on the text of the “dropdown” … we must have seen this coming?!).

Okay, what we are doing here can be defined, and that is good for this project, but can you imagine a generic HTML select (“dropdown”) element being able to be dynamically toggled for all the other myriad of uses HTML select (“dropdown”) elements are put to by programmers … recalls to mind that lame excuse at school … “it depends” … but that is true here, and generic thoughts will need a much more lateral thought process “outside the box” to get towards a better generic idea.

However, in the meantime, this change today will have made quite a lot of difference to …

  • YouTube API for Iframe embedded videos “parent” web application live run (where you perform a Search for YouTube videos of interest such as this Adelaide search example) … and the recent …
  • TimeZone Places “grandparent” web application live run … and …
  • Australian Indigenous Languages “grandparent” web application live run … and …
  • Country Quiz “grandparent” web application live run

And we hope you get something out of trying out this new additional functionality … the Single attribute mode of use is unchanged.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

This entry was posted in eLearning, Event-Driven Programming, Tutorials and tagged , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *