List Web Application Cookie Tutorial

List Web Application Cookie Tutorial

List Web Application Cookie Tutorial

About 6pm Sydney, Australia time on 26th March, 2017, our latest “Make a List” web application became quite a bit more “accountable”, but even if you’ve been trying it out “in detail” it’s quite possible you didn’t notice. You see, we’ve had it quite accountable already within a “session” of work, it passing data to our, still, just client side, web application via URL (PHP $_GET[]) parameters. While you, as a user, are concentrating on the general “flow” of this web application’s logic, this web application is pretty accountable and of some use, we think. However, consider the following two points …

  1. What about if I revisit the web application much later? Will it remember anything from that previous session using it?
  2. What if the amount of data I’m involving gets too big?

The second of these needs the help of a serverside language like PHP, and we’ll get to that in a later tutorial in this thread, so rest assured, if you have no interest in PHP or other serverside languages, that should not stop you with the progress made with today’s tutorial and/or any others earlier than this posting on the thread of blog postings.

The first of the two above can be addressed with an extension of client side HTML and Javascript logic on top of what we left off with yesterday with List Web Application Row Sorting Tutorial as shown below. This “intersession” accountability (as distinct from the “intrasession” accountability we think of URL (PHP $_GET[]) parameter passing to be) is achieved by the introduction to this web application of HTTP Cookies logic. HTTP Cookies are stored in the web browser the web application is using, at the client, and is not really a permanent data storage, unless you are a user who never clears the browser cache, that is.

So what are the “design principles” of the HTTP Cookie usage we apply?

  • HTTP Cookies are only created or updated when a URL containing ? and & is sent to the web server … which is us saying “only store HTTP Cookies reflecting real use of the web application that is asking for some accountability”
  • HTTP Cookies are capable of being referenced to fill in web application default data when the URL is not containing ? and & and if, any time in the past 6 months, it has had a URL containing ? and & involved in its usage … in which case …
    1. the HTTP Cookie data is used to piece together the data of that last URL containing ? and & session … and …
    2. a “Retain” button is created and shown, that given no other actions, will disappear in 5 seconds
    3. a “Clear” button is created and shown, that given no other actions, will disappear in 10 seconds, and if clicked will clear the relevant web application HTTP Cookie data and restart the web application, as if it had never been used before (except that the special URL (PHP $_GET[]) parameter “?clear=y” tells the web application logic, that this is the intention of the user)
    4. various other activity on the web application will “Retain” this HTTP Cookie derived default data
  • … which is reflected by the Javascript (new to the web application for today’s tutorial) below (noting that before we started with this code, we added <body onload=’ml_cookieVal(true); chooseone();’ style=’background-color:#f7e7e7;’>, and all mentions of “location.search” were replaced with (the global variable) “locationsearch” (ie. we were leaving a place for HTTP Cookie logic to intervene “into” the program URL (PHP $_GET[]) parameter “scene”)) that is definable even before the document.body‘s onload event logic (which is a crucial timing aspect to the coding design) …


    var locationsearch=location.search.replace('?clear=y','').replace('?','');
    var usedc=false;

    function clearyes() {
    document.getElementById('clear').style.display='none';
    }

    function clearmaybe() {
    if (usedc) {
    document.getElementById('clear').click();
    } else {
    document.getElementById('retain').style.display='none';
    setTimeout(clearyes,5000);
    }
    }

    function ml_setCookie() { // thanks to JavaScript and Ajax by Tom Negrino and Dori Smith
    var expireDate = new Date();
    expireDate.setMonth(expireDate.getMonth()+6);
    if (eurl.indexOf('body=') != -1) {
    var xpurl=decodeURIComponent(eurl.split('body=')[1]);
    if (xpurl.indexOf('?') != -1) document.cookie = "locationsearch=" + encodeURIComponent(xpurl.split('?')[1]) + ";expires=" + expireDate.toGMTString();
    }
    }

    function ml_cookieVal(firstcall) {
    if (document.cookie != '') {
    var expireDate = new Date();
    var tCookie=document.cookie.split("; ");
    for (var j=0; j<tCookie.length; j++) {
    if ("locationsearch" == tCookie[j].split("=")[0]) {
    if (document.URL.indexOf('?clear=') != -1 && firstcall) {
    expireDate.setMonth(expireDate.getMonth()-6);
    document.cookie = "locationsearch=;expires=" + expireDate.toGMTString();
    } else if (document.URL.replace('?clear=','').indexOf('?') != -1 && document.URL.indexOf('&') != -1 && firstcall) {
    expireDate.setMonth(expireDate.getMonth()+6);
    var xpurl=document.URL.split('#')[0].split('?')[1];
    document.cookie = "locationsearch=" + encodeURIComponent(xpurl) + ";expires=" + expireDate.toGMTString();
    } else {
    locationsearch=decodeURIComponent(tCookie[j].split("=")[1]);
    if (firstcall) {
    document.getElementById('retain').style.display='inline';
    document.getElementById('clear').style.display='inline';
    usedc=true;
    setTimeout(clearmaybe, 5000);
    }
    }
    return locationsearch;
    }
    }
    }
    return '';
    }

    Our “fifth draft” live run link pointing at the HTML and Javascript mylist.htm changed in this way, for HTTP Cookie functionality purposes.

    And today’s presentation channels Animated GIF via PHP Writing PHP Primer Tutorial, because we wanted a few scenes to establish an “intersession” simulation for your perusal. We hope it helps.


    Previous relevant List Web Application Row Sorting Tutorial is shown below.

    List Web Application Row Sorting Tutorial

    List Web Application Row Sorting Tutorial

    Think “list”, think “sort”, too. Sorting a list is a very common, and often useful web application piece of functionality, as “sorting” often increases “order” for we humans.

    But, as with “order”, the idea of “sort” can be quite varied in the eyes of the users of your web application. And also, think whether you want …

    • choices between numerical sorting and alphabetic (is uppercase versus lowercase an issue?) … normal and/or reversed
    • sorts at various character positioning or delimiting within the data
    • exceptions, perhaps

    … but, today, with our web application, we are just dealing with the first idea above, offering a numerical sort on that “Quantity or Weight”“Population” column data, and an alphabetic sort for any other column, with normal (down ⬇ arrow Emoji) and reversed (up ⬆ arrow Emoji) sorting modes in play.

    To show you what we mean here, we are taking the same input CSV “World Populous Country” population data we used with Linux vi Buffer Sort Primer Tutorial and entering it into our web application in the Country name alphabetical order it has in the data set, and allow the “Quantity or Weight”“Population” column’s new “sort” up and down arrow Emojis (for normal numerical sort and reverse numerical sort respectively), specifically the up arrow Emoji, to show sorted data from Most Populous Country to Least Populous Country, as you might be more interested in seeing, in real life. You can simulate this yourself by clicking the up arrow Emoji next to “Quantity or Weight”“Population” table column heading …

    We remained just using client side HTML and Javascript for this, and all that precedes. Here is the new Javascript function added today for sorting purposes …


    function sortby(direction,sio) {
    var nn, arrtosort=[], thisoneis, zero=0, dotp=-1, blanks=" ", newoarrc='', newoarrdelim='';
    var idprefix=sio.id.replace('dsort_','').replace('usort_','');
    was_io=null;
    is_io=null;
    var inps=document.getElementsByTagName('input');
    for (var ninps=0; ninps<inps.length; ninps++) {
    if (inps[ninps].id) {
    if (inps[ninps].id.toLowerCase().indexOf(idprefix.toLowerCase()) == 0 && inps[ninps].id != 'i0i' && inps[ninps].id.toLowerCase().replace(idprefix.toLowerCase(),"").substring(0,1) >= "1" && inps[ninps].id.toLowerCase().replace(idprefix.toLowerCase(),"").substring(0,1) <= "9") {
    if (eval(inps[ninps].id.replace(idprefix,"")) != maxrow) {
    thisoneis=" " + oarray[-1 + eval(inps[ninps].id.toLowerCase().replace(idprefix.toLowerCase(),""))];
    if (idprefix == "qw") {
    zero=0;
    if ((inps[ninps].value + " ").substring(zero,eval(1 + zero)) == "-" || (inps[ninps].value + " ").substring(zero,eval(1 + zero)) == "." || ((inps[ninps].value + " ").substring(zero,eval(1 + zero)) >= "0" && (inps[ninps].value + " ").substring(zero,eval(1 + zero)) <= "9")) {
    while (zero < eval(inps[ninps].value.length - 1) && (inps[ninps].value + " ").substring(zero,eval(1 + zero)) == "-" || (inps[ninps].value + " ").substring(zero,eval(1 + zero)) == "." || ((inps[ninps].value + " ").substring(zero,eval(1 + zero)) >= "0" && (inps[ninps].value + " ").substring(zero,eval(1 + zero)) <= "9")) { zero++; } } if (zero != 0) { dotp=inps[ninps].value.substring(0,zero).indexOf("."); if (dotp == -1) { arrtosort.push(blanks.substring(0,eval(10 - zero)) + inps[ninps].value + "~!`" + thisoneis.slice(-8)); } else { arrtosort.push(blanks.substring(0,eval(10 - dotp)) + inps[ninps].value + "~!`" + thisoneis.slice(-8)); } } else { arrtosort.push(inps[ninps].value + "~!`" + thisoneis.slice(-8)); } } else { arrtosort.push(inps[ninps].value + "~!`" + thisoneis.slice(-8)); } } } } } if (arrtosort.length > 1) { arrtosort.sort(); if (direction != 0) { for (nn=0; nn<arrtosort.length; nn++) { newoarrc+=newoarrdelim + arrtosort[nn].split("~!`")[1].trim(); newoarrdelim=','; } } else { for (nn=eval(-1 + arrtosort.length); nn>=0; nn--) { newoarrc+=newoarrdelim + arrtosort[nn].split("~!`")[1].trim(); newoarrdelim=','; } } oarrc=newoarrc; oarrdelim=','; reordered=true; oarray=eval("[" + oarrc + "]"); var purl=decodeURIComponent(eurl.split('body=')[1]); var sortbits=(purl + '&').split('&order='); if (sortbits.length > 1) { location.href=purl.replace('&order=' + sortbits[1].split('&')[0], '&order=' + encodeURIComponent('[' + oarrc + ']')); } else { location.href=purl + '&order=' + encodeURIComponent('[' + oarrc + ']'); } } }

    Also, with the changes today, we offer the "table cell swapping" functionality listed in an earlier blog posting in this thread. Personally, we think the use would be rare, but perhaps if you have many columns to fill in and miss the order when doing this, perhaps this "table cell swapping" may be a "cute" bit of functionality to have. We use the reasoning ...

    • user has clicked into an HTML input type=text field that is not blank ... and so the Javascript global variable was_io is set to this HTML input type=text field object, for a first round of this, as distinct from global variable is_io being, albeit, briefly, on the second click (that we talk about below) ...
    • user has not done any Emoji clicking, nor used the keyboard in any way (checked via ...

      <body style='background-color:yellow;' onload='addlotsofrows();' onkeyup='was_io=null; is_io=null;'>

      ) ... when user has clicked into an HTML input type=text field that is not blank ... so we set the Javascript global variable is_io's value to be swapped with the Javascript global variable was_io's value (property)

    Today has our "fourth draft" live run link pointing at the HTML and Javascript mylist.htm changed in this way, for sorting functionality purposes. We hope it sets you to thinking even more about lists.


    Previous relevant List Web Application Row Swapping Tutorial is shown below.

    List Web Application Row Swapping Tutorial

    List Web Application Row Swapping Tutorial

    Think "list", think "order". So to have a web application involving a list where there is no possible way to reorder is not such a useful web application.

    Now, the word "order" can mean many things to many people, so you may want to consult with potential users about their desired approach to the myriad ideas out there for performing some sort of reordering process on their ...

    • table rows
    • table cells
    • depending on some sort of sort criteria of data

    ... the list ... chortle, chortle ... goes on and on.

    We opt, today, for some work on that "table rows" idea above, augment existant functionality last talked about with List Web Application Genericization Tutorial as shown below. Though we like a drag and drop approach to the Emojis, and tomorrow's "edition" may have this, this "drag and drop" is not that good for mobile device users, so instead, we have additionally attached to the code, some dynamically added HTML select element dropdowns in that table header record where you can define some row swapping criteria. Also available as a mobile device (or non-mobile device) alternative idea to "drag and drop" is the "two discrete clicks" idea we allow for in the methodology used for our row swapping "venture" today.

    That leaves us with our "third draft" live run link pointing at the (still purely client side) HTML and Javascript mylist.htm changed in this way. Hope it sets you to thinking more about lists.


    Previous relevant List Web Application Genericization Tutorial is shown below.

    List Web Application Genericization Tutorial

    List Web Application Genericization Tutorial

    Genericization jobs, at least for us, are an invitation for second phase design. We like to put down an initial design, and often see that it could be "ever so much" more generic, so we set aside thinking and designing to that end.

    What is the "genericization" improvements we could make to our "early days" "Make a List" web application. Well, yesterday, it felt like something designed for a ...

    • shopping list ... but what about other list ideas like ...
    • list of countries with some informational columns
    • list of planets with orbital and environmental information
    • list of insects with habitat, size, reproduction, social setup information

    ? Are you getting the gist? Well, we offer the user the chance, just for that period where they have not yet entered any record Item information yet, allow for a mechanism that can add up to six new columns of information (but not changing "Quantity or Weight" and "Item") to augment what your list contains. Guess you'd classify this as a data driven genericization.

    We think data driven genericizations are the most satisfying to do because the heart of any good web application revolves around data. It's just that, as you might guess, we are fond here, of many different approaches to data derivation and reporting, from the simple ephemeral forms to set in stone database approaches. It is up to you (hoo?!), the programmer, and the client, to determine the permanence of that data, in that web application, or mobile application, or desktop application.

    No data, though, we find, very often, a dull program maketh.

    The method we use, in practice to allow users to add columns we've never done before in our recollection. We ...

    • just until that first Item cell's HTML input type=text's onblur event logic is instigated offer 6 new HTML input type=text table header record places, either side of the existant 3 columns, where the user can define new columns (and their names) in that classic spreadsheet and relational database thought ...

      name=value
    • close up shop and Javascript DOM change things to readonly ways they will remain, once the user instigates that first Item cell's HTML input type=text's onblur event logic

    ... which also felt like a kind of satisfying way of both helping people out with more complex reports, and making it fairly obvious that it is optional, and that if you are just there for that first "shopping list" type vision of usage, go for it, because there is nothing different in what these users have to do.

    The fundamental rearrangement for HTML and Javascript code was that a "template" row that was once hardcoded (as in the commented out // codelines below), and called into play when adding a new table record (ie. row), is now based on a dynamic str1 variable, that is managed by the event logic of the onblur events of those new table header record HTML input type=text elements as well.


    //rec="<tr id='tr" + maxrow + "'><td><span>";
    rec=str1.replace(/colspan='1'/g,"colspan='one'").replace(/colspan="1"/g,'colspan="one"').replace(/colspan=1/g,"colspan=one").replace(/1/g,maxrow).replace(/colspan='one'/g,"colspan='1'").replace(/colspan="one"/g,'colspan="1"').replace(/colspan=one/g,"colspan=1").split('<span>')[0] + '<span>';
    for (icoi=0; icoi<coi.length; icoi++) {
    rec+='&#';
    rec+=('' + en[eval(coi.substring(icoi,eval(1 + icoi)))]);
    rec+=';&#';
    rec+='8419';
    rec+=";";
    }
    //rec+="</span></td><td><input id='qw" + maxrow + "' name='qw" + maxrow + "' value=''></input></td><td><input style='width:90%;' onblur='process(this);' id='i" + maxrow + "' name='i" + maxrow + "' value=''></input></td></tr>" + String.fromCharCode(10); // + "<tr id='tr" + eval(1 + maxrow) + "' style='display:table-row;'></tr>";
    rec+="</span>" + str1.replace('tr1','tr' + maxrow).split('</span>')[1].replace(/colspan='1'/g,"colspan='one'").replace(/colspan="1"/g,'colspan="one"').replace(/colspan=1/g,"colspan=one").replace(/1/g,maxrow).replace(/colspan='one'/g,"colspan='1'").replace(/colspan="one"/g,'colspan="1"').replace(/colspan=one/g,"colspan=1");

    So here is the "second draft" live run link pointing at the (still purely client side) HTML and Javascript mylist.htm changed in this way. Hope it sets you to thinking more about lists.


    Previous relevant List Web Application Primer Tutorial is shown below.

    List Web Application Primer Tutorial

    List Web Application Primer Tutorial

    We're starting out pretty simply, but we hope, pretty usefully, with today's new web application, which is "Make a List" via ...

    • an Emoji numbering system
    • a Quantity or Weight measurement entered by the user interactively
    • an Item entered by the user interactively

    Pretty simple, huh? A little more complex is a facility to be a bit "accountable" and a bit "sharing" with our HTML and Javascript and CSS web application. So we turn to an ...

    • email client approach to sending the list off to an email recipient ... via ...
    • the clicking of an HTML a link whose ....
    • href property is of the form mailto:[emailee]?subject=[subject]&body=[URLpointingTOyourLIST]

    And so, we hope you see that there are two aspects to the method by which we construct our list via Javascript DOM techniques, those being ...

    • with our dynamically unfolding HTML table (and tbody) of rows (tr) and sets of 3 cells (td x 3) we don't want to show any unfilled out rows (tr) so we could either ...
      1. only add a row (tr) when the Item is filled out (which we tried for a while using a linked list of HTML div elements at the end of row (tr) elements) and rejected for ...
      2. allow for a lot of rows (tr) that are invisible (style=display:none;) until we need them, at the HTML Item input element's onblur to a non-blank value event, when they become (style=display:table-row;) (do you remember something similar with Middle Word Game Primer Tutorial?)
    • we need to cater for (big long, presumably) email URLs arriving at this same web application ... our method of "sharing" (that we often use) ... and this involves a web application automated (programmatic) simulation of what the onblur logic is above, as much as anything, because ...
      1. speaking personally, there is a sense of satisfaction with event-driven programming, when you access some event logic from two or more different modes of entry
      2. we don't like to reinvent wheels, so this design makes some good sense

    So here is the "first draft" live run link pointing at the (so far purely client side) HTML and Javascript mylist.html to start the ball rolling. But it is doubtful that we'll settle on this first draft, a list being one of the most useful data container in programming "history ... and beyond!".

    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 *