Walking Trip …

Walking Trip

Walking Trip

Offenbach's Suite ... Warts 'n All

Offenbach's Suite ... Warts 'n All

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

Posted in Photography, Trips | Tagged , , | 34 Comments

Maths Symbology via Div Primer Tutorial

Maths Symbology via Div Primer Tutorial

Maths Symbology via Div Primer Tutorial

We’ve long been interested by …

  • HTML and Javascript and CSS web applications … that can …
  • display Mathematical symbology … and be capable of …
  • some sharing capabilities

So, in a similar line of thinking to HTML/Javascript Binomial Multiplication Game Jeopardy Tutorial we’re harnessing …

  • HTML div contenteditable=true … and its …
  • onchange and onblur value change events … as well as …
  • onkeypress keyboard event (purely for a time when to intervene) … we allow for …
  • display controllables are …
    1. content symbology helper inspired by W3school’s https://www.w3schools.com/charsets/ref_utf_math.asp (thanks) … and …
    2. content superscript and normal and subscript modes of placement … and …
    3. font colour
    4. background colour
    5. font size

… we start down our road of discovery.

At this early “proof of concept” stage we have a talk_maths.html live run link for you to explore with, or take a look at our Vivax Solutions webpage (thanks) inspired tutorial picture for today.


Previous relevant HTML/Javascript Binomial Multiplication Game Jeopardy Tutorial is shown below.

HTML/Javascript Binomial Multiplication Game Jeopardy Tutorial

HTML/Javascript Binomial Multiplication Game Jeopardy Tutorial

Today, as with WordPress 4.1.1’s HTML/Javascript Binomial Multiplication Game Jeopardy Tutorial, we add a Double Jeopardy (aka the game, not so much the movie) clause to our HTML/Javascript Binomial Multiplication Game Primer Tutorial starting game from a couple of days ago.

So we now have four modes of game usage …

  • Multiplying Binomials (with Trinomials)
  • Double Jeopardy Binomials (with Trinomials) (ie. you supply either one of the two questions that would suit the answers shown)
  • Expanding to Quadratic Equations
  • Double Jeopardy Quadratic Equations (ie. you supply either one of the two questions that would suit the answers shown)

This adds a lot of new mathematics functionality to the game, just building on those HTML and Javascript ideas from a couple of days ago.

If you like practising your algebra maybe you should try, and hope you enjoy, the game and/or look at the HTML/Javascript programming source code you could call multiplying_binomials.html and which changed multiplying_binomials.htmlin this way.


Previous relevant HTML/Javascript Binomial Multiplication Game Primer Tutorial is shown below.

HTML/Javascript Binomial Multiplication Game Primer Tutorial

HTML/Javascript Binomial Multiplication Game Primer Tutorial

We can probably all think of good mathematics games we could invent in a program, but when you sit down to program you can be put off by the mathematical symbols you’d like to involve in the game, but find it unwieldy to do so. Below we talked a bit about this with HTML/Javascript MathML Primer Tutorial as shown below.

The use of MathML HTML tags is a great idea for sure, but with our “Multiplying Binomials” mathematics game today, that we would like to serve up to you today, all we want is to represent the “to the power of 2″ (ie: ²) symbol, and the MathML solution feels like a bit of overkill … and so we thought about it a bit …

  • you can’t use HTML entities in HTML input type=text elements … so …
  • nor can you use <sup>2</sup> … unless you want to look kind of dumb … but …
  • suppose you put in the header section (between <head> and </head>) <meta charset=”UTF-8″ /> then we can assign a Javascript (global) variable to a copied and pasted ² found on the net somewhere, for instance … as in the code

    var twosup="²";

… sounds promising as far as writing things onto the HTML input type=text element but what about the hassle for the user to have the control themselves interactively entering these ²s. Well, we can think of two useful (pragmatic) helper ideas here, they being …

  • we know there are going to be two ²s involved in any one Multiplying Binomials answer so why not initialize the value first presented in the HTML input type=text element’s value with 2 ²s spread apart a little that the user can build on to build up their answer without having to worry about the keypad production of any ² … and …
  • present a helper ² button that appends a ² at a time of the user’s choosing to the end of their Multiplying Binomials answer (separately for their Intermediate (show working) Answer and/or their final Answer)

We’ve used this game ourselves and found it reasonably easy to use, and it teaches you some mathematical patience to answer the Multiplying Binomials questions asked.

And what created the interest for this web application? The Maths is Fun website we think is wonderful here, as it is for so many mathematical subjects for school students, in particular.

So please try examining the HTML and Javascript programming source code, for the game, you could call multiplying_binomials.html (and just see that the var twosup=”²”; line (and any other lines containing ²) looks the way it should) and test it for yourself with a live run link.


Previous relevant HTML/Javascript MathML Primer Tutorial is shown below.

HTML/Javascript MathML Primer Tutorial

HTML/Javascript MathML Primer Tutorial

The HTML5 specification allows for the use of mathematical symbology via MathML HTML tags.

The display of mathematical symbology was not so easy to achieve very easily with older versions of HTML, and MathML makes this a lot easier for web content creators.

Today, with our tutorial, we show the use of MathML HTML tags to show operations on 2×2 matrices (in fact the matrix is the same on either side of + – x and / operators). Matrix mathematics can get hugely more complicated than in this primer tutorial, and should you want to study this further, and you are starting from scratch:

  • stop scratching
  • maybe start with a peruse of Wikipedia, and then take it from there to other research
  • link about matrix inversion

Today we have HTML and Javascript programmable source code you could call mathml_tutorial.html and here is its live run.

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.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , | Leave a comment

Inhouse Slideshow Design Exif Korn Shell Deployment Tutorial

Inhouse Slideshow Design Exif Korn Shell Deployment Tutorial

Inhouse Slideshow Design Exif Korn Shell Deployment Tutorial

As promised with yesterday’s Inhouse Slideshow Design Exif Integration Tutorial we’re here today to talk about a Korn Shell assisted deployment strategy for …

the “implementation and deployment” phase of the “Inhouse Slideshow Exif Integration” project

We have the presentation part of many of our blog postings featuring this “Inhouse Slideshow” methodology, and recently we genericized it from a different set of HTML slideshow displays to a single index.php distributed to web server folders where these slideshow images resided. By “generic” we mean generic, as they all feature identical content, so our strategy is … ask of the user the following information (for our parent job.ksh), the safeguards being with the fact that they are not allowed to use blank answers, and the input file size in bytes is asked for, as well as a string to find in all those input files …


#!/bin/ksh
echo 'Files of a pattern and the same size replaced by a new version ...'
echo ''
echo 'Path to new version of file eg. ./index.php'
read index

if [ -f "$index" ]; then
echo ''
echo 'Must find this string eg. foreach (glob('
read findstring

if [ ! -z "$findstring" ]; then
echo ''
echo 'Must be this many bytes long eg. 7006'
read thismany

if [ ! -z "$thismany" ]; then
echo ''
echo 'Path to files to be replaced by this new version of file eg. /a/path/to/root/directory/of/interest/'
read path

if [ -d "$path" ]; then
echo ''
echo 'Filespec or filename of files to be replaced by a new version of file eg. index.php'
read filespec

if [ ! -z "$filespec" ]; then
echo ''
echo 'Starting the assembly of information to later execute a copy script or manual cp statements ...'
# find $path -size ${thismany}c -name "$filespec" -exec cp $index {} \;
IFS=
result=`find $path -size ${thismany}c -name "$filespec" -exec grep -H "$findstring" {} \;`
if [ -z "$result" ]; then
echo "No candidate files for change"
exit
else
indexsed=`echo "$index" | sed '/\//s//~!/g'`
echo $result | cut -d : -f 1 | uniq | sed "/^/s//cp $indexsed /g" | sed '/\~\!/s//\//g'
echo ''
echo 'Optional ksh file as above to create and get edit and execute advice eg. ./therealchange.ksh'
read thisksh

if [ ! -z "$findstring" ]; then
echo "#/bin/ksh" > $thisksh
echo $result | cut -d : -f 1 | uniq | sed "/^/s//cp $indexsed /g" | sed '/\~\!/s//\//g' >> $thisksh
echo "vi $thisksh # can edit, with a wq! to save, in vi editor"
echo "ksh $thisksh # can execute the statements to perform the copying"
exit
fi
fi
echo ''
echo 'Finished'
fi
else
echo "$path path is non-existant"
fi
fi
fi
else
echo "$index file not found"
fi
exit

… the use of which you can see us applying in a MacBook Pro (local MAMP web server) environment and then at the rjmprogramming.com.au web server as a “live run”. Notice all the sanity checks we make, such as editing the optional script output of the parent script execution, and the rerun to establish that then there should be no further input files found to process, and the (doh!) bringing up of one of the Inhouse Slideshow presentations to see that now, yes, they include an “Exif Slideshow” mode of use improvement. If you write such a procedure yourself, please know that a backup mechanism could improve your peace of mind considerably. Korn Shell being that powerful tool it is, it can happen in the blink of an eye, a big mistake by user mistake!


Previous relevant Inhouse Slideshow Design Exif Integration Tutorial is shown below.

Inhouse Slideshow Design Exif Integration Tutorial

Inhouse Slideshow Design Exif Integration Tutorial

A project of reasonable scale has several phases to it, the ones that spring to mind for us, being …

  • concept
  • planning and design
  • coding and unit testing
  • user acceptance and testing
  • platform acceptance and testing
  • implementation and deployment
  • going live
  • monitoring performance and uptake and usage patterns
  • user feedback and improvement planning

… in that order conceptually and initially, perhaps, but often messed up as a project matures and grows.

We have a mini project getting the work of yesterday’s PHP Exif Image Information Revisit Tutorial‘s PHP Exif information web application’s workings and aesthetics be put to good use, and straight off the bat we got going …

  • project “One Image Website Exif Integration” as small enough (“planning and design” established we’d only need to change 6 or 7 files) to have a very simple TextWrangler 7 file session followed by sftp over to the RJM Programming website as its “implementation and deployment” phase … the coding changes involving …
    HTML (new)

    <body id="body" style="background-color: #E4E4E4;" onload=' if (document.URL.indexOf("exif=") != -1) { dexifit(); } window.setTimeout("FadeInImage()", 4000); '>
    <a onclick=huhit(); onmousedown=huhittwo(); style=display:inline-block;cursor:pointer;text-decoration:underline;>Exif Run</a>


    <div id=dexif></div>
    </body>
    </html>
    CSS (new) is “Overlay Iframe Remembering” work

    <style>
    iframe {
    width: calc(100% - 2px);
    height: calc(100% - 2px);
    }
    </style>
    Javascript (new code) and integration steps


    function huhit() {
    top.location.href=('' + document.URL).split('#')[0].split('?')[0] + '?exif=y';
    }

    function huhittwo() {
    alinktop='#';
    }

    function dexifit() {
    document.getElementById('dexif').innerHTML='<iframe id=iexif style="position:absolute;top:0px;left:0px;z-index:45;" src=../PHP/read_exif_off_image_rotate.php></iframe>';
    }

    //
    // The existence of iframe "iexif" causes the "get new image" Javascript function to intervene and update the "src" property of iframe "iexif" with a
    // URL showing an image Exif report webpage as per "top.location.href=('' + document.URL).split('#')[0].split('?')[0] + '?exif=y';" codeline above (rather than display a new image and scroll within it (that being the default behaviour the build up for unchanged for our work))
    //

    … and today we shall …

  • get up to the “implementation and deployment” phase of the “Inhouse Slideshow Exif Integration” project … via …

    … above (or see them in a new window with the changed index.php‘s live run) … the “implementation and deployment” phase being involved (and big) enough that we need to explain more about with tomorrow’s blog posting … and in the meantime as a “refresher” have a read of Inhouse Slideshow Design Makeover Tutorial below

Previous relevant Inhouse Slideshow Design Makeover Tutorial is shown below.

Inhouse Slideshow Design Makeover Tutorial

Inhouse Slideshow Design Makeover Tutorial

One of the last times we considered the way we “worked” using our “Inhouse Slideshow Design” was when we presented Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial below, some time back. Perhaps, that is because this method has gone out of favour with us, with the number of image files required, and we’ve preferred in more recent times to …

  • annotate individual screenshots
  • compose multi-slide PDF presentations
  • compose multi-slide animated GIF presentations
  • compose multi-slide video presentations (much less often) … rather than using …
  • inhouse slideshow … when many slides are needed to explain a blog posting

Looking back, we spent too long creating these inhouse slideshows, compiling image lists into td cells of a single tr row in a single table element within individually tailored index.html (HTML) files.

Today’s makeover genericizes an overarching piece of PHP (we’ll be calling index.php) we place into the web server directory with these


foreach (glob("*-[0-9]*.[jJgGpP][pPiInN]*") as $ifil) {
if (strpos($spush, "'" . $surlprefix . $ifil . "'") === false) {
$ibits=explode("-", $ifil);
if (sizeof($ibits) > 1) {
$proposedstitle=str_replace("_", " ", $ibits[0]);
if ($proposedstitle != $stitle) {
if ($stitle == "") {
$stitle=$proposedstitle;
} else if (strpos($sothers, $proposedstitle) === false) {
$spush.="\n firstones.push(" . $scnt . "); \n";
$spush.="\n lastones.push(" . (-1 + $scnt) . "); \n";
$sothers.="<br><a id='apre" . $sscnt . "' href='#s" . $scnt . "' title=\"Movie'ize Here vs Follow Red Right Arrows with Bottom Scrollbar\" onclick='prehavealook(this); havealook(-" . $scnt . ");'>" . $proposedstitle . "</a>";
$sscnt++;
}
}
$smodebit.="\n if (smode != '0') document.getElementById('row').innerHTML+='<td><span style=\"color:red;font-size:14px;\"><b>--></b></span></td><td><img onclick=\"onck(this);\" id=\"i" . $scnt . "\" src=\"" . $surlprefix . $ifil . "\" title=\"" . $proposedstitle . "\" /></td>'; \n";
$spush.="\n uarraydatauri.push('" . $surlprefix . $ifil . "'); \n";
$scnt++;
}
}
}

… image filenames we can collect in that “glob” friendly *-[0-9]*.[jJgGpP][pPiInN]* (filespec) habit we had (and have), make genericization possible, and we’ll proceed on that understanding. What extra is needed, though, is to cater for more than one set of such slideshow image sets within any one web server directory (gleaned off the incoming URL, in PHP).

Here’s what we came up with in PHP called index.php we’ll start placing into the relevant rjmprogramming.com.au web server folders, over the next several days.


Previous relevant Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial is shown below.

Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial

Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial

To us, there are great similarities between animated GIFs and slideshows, as two forms of “presentation”, and so to extend yesterday’s Animated GIF via PHP Writing PHP Data URI Tutorial animated GIF creator “PHP Writes PHP” web application that now has the option for data URI “exports” we add the functionality for …

  • slideshow creation (using our inhouse methods) which defaults to a horizontal (hashtag type of) navigation … as well as adding a …
  • slideshow creation, with Data URI image data, using functionality as if CSS z-index (ie. slides stacked on top of each other in “overlay” style) was being used, but actually isn’t …

… that little bit different to another “stacked” (or z-index feeling) approach we talked about with Multiple Class Slideshow Details Tutorial, where HTML element “class” properties were changed so that the last class defined reflects the look of the slideshow slide desired at any given time. We just use an array, and a setTimeout timer to achieve the same ends today, with our work (or “presentation”). If this “horizontal versus stack” navigation choice interests you, also take a read of HTML Input Element Types Randomized History Tutorial.

Again, with all this added functionality, because it is “hosted” in an HTML iframe element all the existant web browser (Windows right click or Mac OS X two finger gesture) functionality can come into play, and make life quite interesting for your non-mobile users “collecting” data URIs … there are worse hobbies!

You can see this in the context of how this PHP tutorial_to_animated_gif.php code changed for slideshows in this way or try it as a live run.


Previous relevant Animated GIF via PHP Writing PHP Data URI Tutorial is shown below.

Animated GIF via PHP Writing PHP Data URI Tutorial

Animated GIF via PHP Writing PHP Data URI Tutorial

The previous relevant “PHP writes PHP” methodology animated GIF creator we talked about, first, with Animated GIF via PHP Writing PHP Primer Tutorial came back to mind yesterday with our Missing Javascript Audio on Unmute Tutorial, where we pondered on whether an animated GIF could be represented on a webpage by a data URI. Why take an interest in this? Data URIs are very important to do with …

  • future mobile development web form navigation benefits from their usage
  • the use of data URIs make your web pages independent of web server location issues, so make your web data more portable, and flexible

… and ideally, animated GIFs are also not just a decorative part of all this web application usage (as they can be a very efficient representation of an animation that could not be a more succinct way to show that animation or presentation), and if they can be made to be like any other GIF or image data file in the ways they can be represented (and used), then that is all for the good.

So we changed the Jeroen van Wissen’s inspired PHP (“PHP writes PHP” methodology) code tutorial_to_animated_gif.php code allow for this extra animated GIF data URI representation in a new additional HTML iframe (containing the animegif.html of code below) that when harnessing existant web browser (Windows right click or Mac OS X two finger gesture) functionality can glean for us, as required, that animated GIF’s data URI representation. But don’t get too excited about this being rocket science, in that with a bit of effort, and PHP, it could have been gleaned from what we already produced, in that (in PHP “land”) …


$lastbitto="\$fp = fopen('animegif.gif', 'w');
\$data = \$gif->GetAnimation();
\$dataUri = 'data:image/gif;base64,' . base64_encode(\$data);
fwrite(\$fp, \$data);
fclose(\$fp);
\$fp = fopen('animegif.html', 'w');
fwrite(\$fp, '<!doctype html><html><body><h1>Data URI version below<h1><br><h4> ... via web browser (Windows right click, Mac OS X two finger gesture ...</h4><br><img src=' . \"\\n\" . \$dataUri . \"\\n\" . ' title=DataURI></img></body></html>');
fclose(\$fp);";

You can see this in the context of how this PHP code changed in this way or try it as a live run.


Previous relevant Animated GIF via PHP Writing PHP Primer Tutorial is shown below.

Animated GIF via PHP Writing PHP Primer Tutorial

Animated GIF via PHP Writing PHP Primer Tutorial

We find another very useful reason for PHP to write PHP. Today we establish a PHP web application to dynamically create Animated GIF images via some still images, like Gifpal would do.

We have some great open source PHP code to thank for the basis of the functionality we found at Jeroen van Wissen’s very useful link, thanks.

Then we added a more user friendly interface to get the information off the user we need. We present this in an HTML form, which navigates to the same PHP to do the actual assembly of the Animated GIF via techniques where PHP writes PHP … and really needs to, to be useful.

Do you remember, last, when we did some PHP writing PHP functionality … PHP Writes PHP Vertical TextBoxes Primer Tutorial?

And inside the PHP it makes big use of the GD and Image Functions to read and write the image data we assemble via the user information.

This Animated GIF form of animation is the easiest to implement, as it consists of just the one GIF image file, but the user has very little control over the animation settings, such as the delay between stills, one of the settings we ask about in our web application.

Our PHP source code today you could call tutorial_to_animated_gif.php and we redirect you to some live run ideas …

  • normal run with HTML form which posts back to itself … live run
  • example GET parameters run (like our tutorial picture)

Hope you find this tutorial useful.

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.

Posted in eLearning, Operating System, Tutorials | Tagged , , , , , , , , , , , , , , | Leave a comment

Inhouse Slideshow Design Exif Integration Tutorial

Inhouse Slideshow Design Exif Integration Tutorial

Inhouse Slideshow Design Exif Integration Tutorial

A project of reasonable scale has several phases to it, the ones that spring to mind for us, being …

  • concept
  • planning and design
  • coding and unit testing
  • user acceptance and testing
  • platform acceptance and testing
  • implementation and deployment
  • going live
  • monitoring performance and uptake and usage patterns
  • user feedback and improvement planning

… in that order conceptually and initially, perhaps, but often messed up as a project matures and grows.

We have a mini project getting the work of yesterday’s PHP Exif Image Information Revisit Tutorial‘s PHP Exif information web application’s workings and aesthetics be put to good use, and straight off the bat we got going …

  • project “One Image Website Exif Integration” as small enough (“planning and design” established we’d only need to change 6 or 7 files) to have a very simple TextWrangler 7 file session followed by sftp over to the RJM Programming website as its “implementation and deployment” phase … the coding changes involving …
    HTML (new)

    <body id="body" style="background-color: #E4E4E4;" onload=' if (document.URL.indexOf("exif=") != -1) { dexifit(); } window.setTimeout("FadeInImage()", 4000); '>
    <a onclick=huhit(); onmousedown=huhittwo(); style=display:inline-block;cursor:pointer;text-decoration:underline;>Exif Run</a>


    <div id=dexif></div>
    </body>
    </html>
    CSS (new) is “Overlay Iframe Remembering” work

    <style>
    iframe {
    width: calc(100% - 2px);
    height: calc(100% - 2px);
    }
    </style>
    Javascript (new code) and integration steps


    function huhit() {
    top.location.href=('' + document.URL).split('#')[0].split('?')[0] + '?exif=y';
    }

    function huhittwo() {
    alinktop='#';
    }

    function dexifit() {
    document.getElementById('dexif').innerHTML='<iframe id=iexif style="position:absolute;top:0px;left:0px;z-index:45;" src=../PHP/read_exif_off_image_rotate.php></iframe>';
    }

    //
    // The existence of iframe "iexif" causes the "get new image" Javascript function to intervene and update the "src" property of iframe "iexif" with a
    // URL showing an image Exif report webpage as per "top.location.href=('' + document.URL).split('#')[0].split('?')[0] + '?exif=y';" codeline above (rather than display a new image and scroll within it (that being the default behaviour the build up for unchanged for our work))
    //

    … and today we shall …

  • get up to the “implementation and deployment” phase of the “Inhouse Slideshow Exif Integration” project … via …

    … above (or see them in a new window with the changed index.php‘s live run) … the “implementation and deployment” phase being involved (and big) enough that we need to explain more about with tomorrow’s blog posting … and in the meantime as a “refresher” have a read of Inhouse Slideshow Design Makeover Tutorial below

Previous relevant Inhouse Slideshow Design Makeover Tutorial is shown below.

Inhouse Slideshow Design Makeover Tutorial

Inhouse Slideshow Design Makeover Tutorial

One of the last times we considered the way we “worked” using our “Inhouse Slideshow Design” was when we presented Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial below, some time back. Perhaps, that is because this method has gone out of favour with us, with the number of image files required, and we’ve preferred in more recent times to …

  • annotate individual screenshots
  • compose multi-slide PDF presentations
  • compose multi-slide animated GIF presentations
  • compose multi-slide video presentations (much less often) … rather than using …
  • inhouse slideshow … when many slides are needed to explain a blog posting

Looking back, we spent too long creating these inhouse slideshows, compiling image lists into td cells of a single tr row in a single table element within individually tailored index.html (HTML) files.

Today’s makeover genericizes an overarching piece of PHP (we’ll be calling index.php) we place into the web server directory with these


foreach (glob("*-[0-9]*.[jJgGpP][pPiInN]*") as $ifil) {
if (strpos($spush, "'" . $surlprefix . $ifil . "'") === false) {
$ibits=explode("-", $ifil);
if (sizeof($ibits) > 1) {
$proposedstitle=str_replace("_", " ", $ibits[0]);
if ($proposedstitle != $stitle) {
if ($stitle == "") {
$stitle=$proposedstitle;
} else if (strpos($sothers, $proposedstitle) === false) {
$spush.="\n firstones.push(" . $scnt . "); \n";
$spush.="\n lastones.push(" . (-1 + $scnt) . "); \n";
$sothers.="<br><a id='apre" . $sscnt . "' href='#s" . $scnt . "' title=\"Movie'ize Here vs Follow Red Right Arrows with Bottom Scrollbar\" onclick='prehavealook(this); havealook(-" . $scnt . ");'>" . $proposedstitle . "</a>";
$sscnt++;
}
}
$smodebit.="\n if (smode != '0') document.getElementById('row').innerHTML+='<td><span style=\"color:red;font-size:14px;\"><b>--></b></span></td><td><img onclick=\"onck(this);\" id=\"i" . $scnt . "\" src=\"" . $surlprefix . $ifil . "\" title=\"" . $proposedstitle . "\" /></td>'; \n";
$spush.="\n uarraydatauri.push('" . $surlprefix . $ifil . "'); \n";
$scnt++;
}
}
}

… image filenames we can collect in that “glob” friendly *-[0-9]*.[jJgGpP][pPiInN]* (filespec) habit we had (and have), make genericization possible, and we’ll proceed on that understanding. What extra is needed, though, is to cater for more than one set of such slideshow image sets within any one web server directory (gleaned off the incoming URL, in PHP).

Here’s what we came up with in PHP called index.php we’ll start placing into the relevant rjmprogramming.com.au web server folders, over the next several days.


Previous relevant Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial is shown below.

Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial

Animated GIF and Slideshow via PHP Writing PHP Data URI Tutorial

To us, there are great similarities between animated GIFs and slideshows, as two forms of “presentation”, and so to extend yesterday’s Animated GIF via PHP Writing PHP Data URI Tutorial animated GIF creator “PHP Writes PHP” web application that now has the option for data URI “exports” we add the functionality for …

  • slideshow creation (using our inhouse methods) which defaults to a horizontal (hashtag type of) navigation … as well as adding a …
  • slideshow creation, with Data URI image data, using functionality as if CSS z-index (ie. slides stacked on top of each other in “overlay” style) was being used, but actually isn’t …

… that little bit different to another “stacked” (or z-index feeling) approach we talked about with Multiple Class Slideshow Details Tutorial, where HTML element “class” properties were changed so that the last class defined reflects the look of the slideshow slide desired at any given time. We just use an array, and a setTimeout timer to achieve the same ends today, with our work (or “presentation”). If this “horizontal versus stack” navigation choice interests you, also take a read of HTML Input Element Types Randomized History Tutorial.

Again, with all this added functionality, because it is “hosted” in an HTML iframe element all the existant web browser (Windows right click or Mac OS X two finger gesture) functionality can come into play, and make life quite interesting for your non-mobile users “collecting” data URIs … there are worse hobbies!

You can see this in the context of how this PHP tutorial_to_animated_gif.php code changed for slideshows in this way or try it as a live run.


Previous relevant Animated GIF via PHP Writing PHP Data URI Tutorial is shown below.

Animated GIF via PHP Writing PHP Data URI Tutorial

Animated GIF via PHP Writing PHP Data URI Tutorial

The previous relevant “PHP writes PHP” methodology animated GIF creator we talked about, first, with Animated GIF via PHP Writing PHP Primer Tutorial came back to mind yesterday with our Missing Javascript Audio on Unmute Tutorial, where we pondered on whether an animated GIF could be represented on a webpage by a data URI. Why take an interest in this? Data URIs are very important to do with …

  • future mobile development web form navigation benefits from their usage
  • the use of data URIs make your web pages independent of web server location issues, so make your web data more portable, and flexible

… and ideally, animated GIFs are also not just a decorative part of all this web application usage (as they can be a very efficient representation of an animation that could not be a more succinct way to show that animation or presentation), and if they can be made to be like any other GIF or image data file in the ways they can be represented (and used), then that is all for the good.

So we changed the Jeroen van Wissen’s inspired PHP (“PHP writes PHP” methodology) code tutorial_to_animated_gif.php code allow for this extra animated GIF data URI representation in a new additional HTML iframe (containing the animegif.html of code below) that when harnessing existant web browser (Windows right click or Mac OS X two finger gesture) functionality can glean for us, as required, that animated GIF’s data URI representation. But don’t get too excited about this being rocket science, in that with a bit of effort, and PHP, it could have been gleaned from what we already produced, in that (in PHP “land”) …


$lastbitto="\$fp = fopen('animegif.gif', 'w');
\$data = \$gif->GetAnimation();
\$dataUri = 'data:image/gif;base64,' . base64_encode(\$data);
fwrite(\$fp, \$data);
fclose(\$fp);
\$fp = fopen('animegif.html', 'w');
fwrite(\$fp, '<!doctype html><html><body><h1>Data URI version below<h1><br><h4> ... via web browser (Windows right click, Mac OS X two finger gesture ...</h4><br><img src=' . \"\\n\" . \$dataUri . \"\\n\" . ' title=DataURI></img></body></html>');
fclose(\$fp);";

You can see this in the context of how this PHP code changed in this way or try it as a live run.


Previous relevant Animated GIF via PHP Writing PHP Primer Tutorial is shown below.

Animated GIF via PHP Writing PHP Primer Tutorial

Animated GIF via PHP Writing PHP Primer Tutorial

We find another very useful reason for PHP to write PHP. Today we establish a PHP web application to dynamically create Animated GIF images via some still images, like Gifpal would do.

We have some great open source PHP code to thank for the basis of the functionality we found at Jeroen van Wissen’s very useful link, thanks.

Then we added a more user friendly interface to get the information off the user we need. We present this in an HTML form, which navigates to the same PHP to do the actual assembly of the Animated GIF via techniques where PHP writes PHP … and really needs to, to be useful.

Do you remember, last, when we did some PHP writing PHP functionality … PHP Writes PHP Vertical TextBoxes Primer Tutorial?

And inside the PHP it makes big use of the GD and Image Functions to read and write the image data we assemble via the user information.

This Animated GIF form of animation is the easiest to implement, as it consists of just the one GIF image file, but the user has very little control over the animation settings, such as the delay between stills, one of the settings we ask about in our web application.

Our PHP source code today you could call tutorial_to_animated_gif.php and we redirect you to some live run ideas …

  • normal run with HTML form which posts back to itself … live run
  • example GET parameters run (like our tutorial picture)

Hope you find this tutorial useful.

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.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , | Leave a comment

PHP Exif Image Information Revisit Tutorial

PHP Exif Image Information Revisit Tutorial

PHP Exif Image Information Revisit Tutorial

Another “revisit” today to the PHP Exif Information web application displayer of PHP Exif Image Zip Mystery Game Hints Tutorial. Now supposing we put this scenario to you …

  • you are working in PHP … ie. you have to work in a serverside “something” for the purposes of Exif work …
  • your webpage has a top header bit that goes the full way across the webpage … and …

  • your webpage has a one line form footer bit that goes the full way across the webpage … and …

  • between that you want to display …
    1. Exif textual information … and …
    2. the image that the Exif is talking about, and we want it (as an improvement for today’s work) …
      • proportional (ie. retain the image’s original aspect ratio)
      • not repeated
      • above the fold
      • fully shown

Now we ask you, in PHP, do you need to know the dimensions of that image to satisfy the requirements above? Well, we first thought (surely it must be) so, but going through the motions of doing today’s work, we realized that, though you can (for the PHP global $image variable with the image URL) …


list($width, $height, $type, $attr) = getimagesize($image);

… in PHP to determine those image dimensions, with the way our web application works, we didn’t need to, as you can “link” PHP with the CSS calc function to bypass any Javascript (eg. DOM) client script approach, abstracting the need to know hard and fast dimensions in PHP (and consequently not running into any window resizing or zooming issues (as a matter of fact, zooming up can make the Exif text information resize up quite nicely thank you very much and don’t mind if I do but we digress and so and usefully))


if ($image != "") {
list($width, $height, $type, $attr) = getimagesize($image);
// $iwidth=$width;
// $iheight=$height;
// $csswh=" width:" . $iwidth . "px; height:" . $iheight . "px; ";
$csswh=" width: calc(100% - 10px); height: calc(100% - 220px); text-align: right; margin-right: 20px; } form { position: absolute; left:50px; top: calc(100% - 45px); width:100%; height:40px; ";
}

… used later on to build up the HTML for the webpage, that also looks much better because the image and Exif wording are more likely to be separated from each other now


$htmlis="<html><head>" . $javascript . "<style>" . $bcsscolour . " div { font-size:9px; overflow: visible; float:right; " . $csswh . " } </style><meta name='viewport' content='width=device-width, initial-scale=1, minimum-scale=0.25, maximum-scale=8, user-scalable=yes'><title>Exif for " . $image . "</title></head><body style='background-color:" . $bcolour . ";'><h1 id='myh1'>Exif <select onchange=\"if (this.value.length == 2) { top.alinktop=''; top.document.getElementById('dexif').innerHTML=''; top.location.href=top.document.URL.split('index.')[0]+'index-ssmhalf.html'; } else { var zipurl=prompt('Enter image zipfile URL for Mystery Trip game (good for 2 players)','mysterytrip.zip'); if (zipurl != null) { if (zipurl.toLowerCase().indexOf('.zip') != -1) { location.href=document.URL.split('#')[0].split('?')[0] + '?image=' + encodeURIComponent(zipurl); } } } \"><option value=''>for</option><option value=' '>zipfile</option>" . $anotheroption . "</select> " . $image . "</h1><h3>RJM Programming - August, 2016 <a id='ageolocation style='visibility:hidden;' href='#mygeolocation'>Geolocation Context for Photograph" . $various . "</a></h3><h4>Thanks to <a target=_blank title=Useful href=//www.v-nessa.net/2010/08/02/using-php-to-extract-image-exif-data>//www.v-nessa.net/2010/08/02/using-php-to-extract-image-exif-data</a></h4><div onclick=\"window.open('" . $image . "','_blank','top=5,left=5');\" style='background-color:yellow; background: url(" . str_replace("/Applications/MAMP/htdocs/","HTTP://localhost:8888/",$image) . ") no-repeat; background-position: 5px; background-size: contain; '><br>" . "        Image type of " . $image . " is: " . $types[$imagetype];

The changed PHP read_exif_off_image_rotate.php includes these aesthetic and usability improvements you can test for yourself at this live run link.


Previous relevant PHP Exif Image Zip Mystery Game Hints Tutorial is shown below.

PHP Exif Image Zip Mystery Game Hints Tutorial

PHP Exif Image Zip Mystery Game Hints Tutorial

Just like with the recent PHP Wikipedia Geo Map Google Chart Tutorial we find a use for the talents of Google Chart

… as we improve the functionality of our “Mystery Trip in Images Game” we started with yesterday’s PHP Exif Image Zip Mystery Game Primer Tutorial.

They are used respectively for …

  • final view of a map of the trip after the second player has finished their guessing of Start and Finish place characteristics (as we also do with another Google Maps window, thanks, that gives directions between two (latitude, longitude) sets)
  • as a mechanism to provide a hint (that is not totally obvious, and thereby giving the game away)

And so today we can take you to a real zip file of JPEG images of a Mystery Trip, taken on an iPhone that you can try with a second player at this live run link.

The photos were taken deliberately to be obtuse, so as not to give the game away with their visual content. How are we able to give you hints in a programmatical sense? Well, on a JPEG coming out of an iPhone there is geodata (metadata latitude and longitude) stored that we access via Exif image attribute (PHP) methods.

The changed PHP read_exif_off_image_rotate.php includes these “best for two player” game interactive improvements, as well as allowing the user be able to reach this Mystery Game from old URL (simpler) arrangements, from older incarnations (you can read below).


Previous relevant PHP Exif Image Zip Mystery Game Primer Tutorial is shown below.

PHP Exif Image Zip Mystery Game Primer Tutorial

PHP Exif Image Zip Mystery Game Primer Tutorial

There’s a fair bit to the design of a new game we’re developing that uses the image metadata ideas from PHP Exif Image Information Rotation Tutorial in its workings.

Our early days work starts down the road by collecting zipfile and other pertinent Exif data item ideas off …

  • first game player, who sets up the game parameters while player 2 is not watching, in a form that is submitted ahead of …
  • second player then turns around and tries to guess details of a Start place and End place, and any other places photographed by player 1

As you can see to simplify things we are introducing PHP zipfile coding to group together a set of photographs into the one file concept.

It will be tomorrow that you see a more complete and rounded game solution, and by then we can come up with a name for it too!

Feel free to try the changed read_exif_off_image_rotate.php live run to try out this game in an early incarnation.


Previous relevant PHP Exif Image Information Rotation Tutorial is shown below.

PHP Exif Image Information Rotation Tutorial

PHP Exif Image Information Rotation Tutorial

The “Stop Press” of PHP Exif Image Information Primer Tutorial as shown below, introduced us to some PHP able to glean quite a bit of really useful Exif information stored with an image file, perhaps straight off a digital camera or mobile phone or mobile tablet. We use the great advice of //www.v-nessa.net/2010/08/02/using-php-to-extract-image-exif-data to cycle through this information.

This information was of interest regarding …

Sometimes you’ll see Gimp using exif functionality when it becomes aware of the possibility your image could be rotated to advantage

… as we saw Gimp doing this in relation to a photograph image coming off my Android Mobile Phone that we used, in its “rotated-by-Gimp” form, in our recent Mindfulness Follow Up Tutorial. But how about if we want to detect what Gimp detects, to fix this camera orientation issue ourselves? Well, in amongst the Exif information, we found …

  • IFD0.Orientation: 6 … and then surfing the web we found …
  • this useful link explaining this Exif setting … thanks

… which gave us the means to apply a rotation the way Gimp does. How did we decide to apply this rotation? There are lots of ways, and we decided on this occasion to use CSS and apply a background image, with a transformation, to an HTML div element, also showing all that Exif information. We do this with new PHP you could call read_exif_off_image_rotate.php that has this corresponding new live run link. To get there, from where we’ve last been, take a skeg here.

So, coming back to our “clouds” photo we saw an Exif IFD0.Orientation value of 6 and consulted this useful link to find that we should rotate the image by 90 degrees. We do this with the HTML and inline CSS that goes, for the encasing HTML div element …


<div style='background-color:yellow; background: url(clouds.jpg); opacity:0.6; norepeat; -webkit-transform: rotate(90deg); -moz-transform: rotate(90deg); -ms-transform: rotate(90deg); -o-transform: rotate(90deg); transform: rotate(90deg); '>
</div>

… in regard to using the original camera image …

Now you may have heard of geographical knowledge stored within photographs, and perhaps you’ll see the live run‘s (turn your head or computer) …


GPS.GPSVersion

… that if fleshed out, with other data elements underneath, would put that image into the category of those where geographical information resides. You may want to start reading more about (the huge topic of) “Geotagging” from this useful Wikipedia webpage … thanks.


Previous relevant PHP Exif Image Information Primer Tutorial is shown below.

PHP Exif Image Information Primer Tutorial

PHP Exif Image Information Primer Tutorial

Our (Mac OS X laptop) local MAMP web server is an Apache/PHP/MySql web server. In this environment you can find out a lot with some PHP code as per …

<?php phpinfo(); ?>

… and if, in doing this, you find a reference to the “exif” Exchangeable Image Information functionality existing, you are a lucky candidate to introduce some image “interrogation” (but not this) logic to your PHP code.

We followed a lot of the advice of the very useful link (thanks) to create some PHP called …

… where we may (or maybe not) be waking you up (before we go go ‘Cause I’m not plannin’ on going solo yo (to be honest, like)) … it’s a slow news day … to the fact that images can show on a web page but may not be all you would understand them to be … shock, horror!

Yes, an image that is a GIF in all but name will often display fine even if it’s been given a name like MyNameIs.Jpeg man person.

If this outrage makes you …

  • a) fall on the floor laughing
  • b) cause a road rage incident
  • c) wake up in a cold sweat
  • d) wake up in a warmish to lukewarm sweat
  • e) tear the cat’s hair out (no animals were harmed in the making of this blog posting)

… then we’re here to tell you that you need to take a Bex and have a lie down.

In any case, there is a solution to this in PHP if the exif functionality is available to you, and this matter is of concern, and you can see us showing you how to test for that with the code above and this live run. Sometimes you’ll see Gimp using exif functionality when it becomes aware of the possibility your image could be rotated to advantage … we’ve had this happen and thanked Gimp with more than the usual toast and herbal tea offerings you’d be used to giving … we take it?!

Stop Press

As of 8/8/2016 (well, what do you know? … understood everywhere!?) we’re revisiting Exif and PHP to learn more and our tutorial picture now reflects the early days of the revisit and the new resultant PHP we wrote, that you could call read_exif_off_image.php, inspired, largely from //www.v-nessa.net/2010/08/02/using-php-to-extract-image-exif-data (thanks), and has this live run link, the output of which is pointed to by the red arrow in the tutorial picture.

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.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , | Leave a comment

Local Fonts Revisited Textarea Tutorial

Local Fonts Revisited Textarea Tutorial

Local Fonts Revisited Textarea Tutorial

We find with some projects you have to remain fairly “current”, else it becomes very hard to get back into it. The recent Local Fonts Revisited Onclick Tutorial is very much “one of those projects”. There is a correlation for my tiny little mind, that being when the job is very hierarchical with its concepts. Though we admire “onions of the 4th dimension” … wouldn’t it be sacrilege not too?! … it’s just hard work, unless, as we say, you stay “current” with the job. Many more days away from “Local Fonts” and we think it could have got ugly.

As above, for “speed of progress”. This “Local Fonts” project needs patience, and even so, we may conclude it is not worthwhile pursuing, but believe it or not, with this project, there is an aim, that being to be able to show a blog posting webpage such as the one you are on, in a “Local Font” of your creation. We’ll see. In any case, on a long trip you often learn other things than just the final destination “moral”. We like a good trip, and well acknowledge that old thought that the world can be divided into those who like the trip and those who like to get there, but there are also those who like both (maybe even this).

And so today, we saunter along, just trying to cater for the confusion in our mind regarding how …

  • textarea elements … use …
    1. line feeds … as distinct from …
    2. <br> (HTML br element line breaks)

    … because it really matters in this project … it not being to everybody’s taste, we grant you

  • with regard to whether we persevere with the element in that textarea form … or instead …
  • overlay the textarea element with an equivalently sized div contenteditable=true … or instead …
  • replace them with a cloned div contenteditable=true

… and, as you may have guessed from “the build up” above, yes, we go with the latter (because, respectively, the textarea element is purely for text and “Local Fonts” involve imagery and when using “overlay” techniques we seemed to have trouble with element focus issues), via a whole rewriting of the webpage’s …

  • document.body.innerHTML … by replacing …
  • the [textarea].outerHTML … via a …
  • reworked (new) div contenteditable=true [div].outerHTML plucking the good bits out of the [textarea].outerHTML (ie. content and width and height), and “melding out” the inappropriate bits, and also adding in our own better replacement bits … as per (at the document.body onload event Javascript function) …

    document.body.innerHTML=document.body.innerHTML.replace(tas[itas].outerHTML, tas[itas].outerHTML.replace(' ', ' contenteditable=true ').replace(' cols=', ' data-cols=').replace(' rows=', ' data-rows=').replace(/textarea/g, 'div').replace(' id="', ' id="overlay').replace(' style="', ' style="width:' + ('' + tasrect.width).replace('px','') + 'px;height:' + ('' + tasrect.height).replace('px','') + 'px;')); //.tas[itas].style.visibility='hidden';

… and yes, you can see for yourself with the changed under_local_font.html‘s live run link and code that we pick optimal times, considering that new div contenteditable=true element’s innerHTML (ie. its HTML content), that we needed to convert …


String.fromCharCode(10) // ie. line feeds ... to ...


'<br>' // ie. HTML line breaks

… to get the correct result.


Previous relevant Local Fonts Revisited Onclick Tutorial is shown below.

Local Fonts Revisited Onclick Tutorial

Local Fonts Revisited Onclick Tutorial

Not much doing aesthetics wise with today’s improvements on yesterday’s Local Fonts Revisited Application Tutorial. It’s more a shoring up of the logic of that div contenteditable=true user defined field and incorporating two new ideas or concepts, those being …

  • a decision for the div’s onblur and onchange event logics to start with a scenario where innerHTML is equivalent to (innerText || contentWindow || contentDocument) before building all the imagery needed for the whole div content (ie. like changing from an SQL UPDATE idea to a DELETE/INSERT paradigm) … and for this we developed methodologies whereby …
  • the img (local font) insertions can be converted back to either …
    1. “spanized” form (ie. as span element) …or …
    2. straight text

    … either of which can then get you back to “straight text” with the …

    var outsidec=('' + (divo.innerText || divo.contentWindow || divo.contentDocument));

    … again

At first we thought Javascript [String].split(‘<img’) thoughts, but soon realized what would be much neater (and cuter) would be to “infuse” into the img elements onclick logic to self destruct. We like this because …

  • the onclick event has the scope to know about its title property or a global data attributes “data-index” we start using today (and access via [divObject].getAttribute(‘data-index’)) … as well as the fact that …
  • the onclick event can be accessed programmatically via the [imgObject].click() Javascript functionality … and so lends itself to …
  • a sequence of [imgObject].click() calls “do a procedure maketh for (var ijh=0; ijh<imgids.length; ijh++) { selfdestruct(ijh,”); }” (like up where we wanted to help with “img (local font) insertions can be converted back”)

Here’s the img element onclick logic function …


function selfdestruct(indx,ititle) {
var issa=[];
if (imgids.length > indx) {
var inc=imgids[indx].split(String.fromCharCode(9))[0];
var parid=imgids[indx].split(String.fromCharCode(9))[1];
var csid=imgids[indx].split(String.fromCharCode(9))[2];
var atti=imgids[indx].split(String.fromCharCode(9))[3];
var ih=String.fromCharCode(eval('' + inc.replace('ximage','').replace('image','')));
var intag='img';
if (1 == 3 && document.getElementsByClassName) {
issa=document.getElementsByClassName(inc);
var iil=0; //for (var iil=0; iil<issa.length; iil++) {
if (ititle != '') {
for (iil=0; iil<issa.length; iil++) {
if (issa[iil].outerHTML.indexOf(' data-index=') != -1) {
if (ititle == issa[iil].getAttribute('data-index')) {
document.getElementById(parid).innerHTML=document.getElementById(parid).innerHTML.replace(issa[iil].outerHTML, '<span class="' + csid + '">' + ih + '</span>');
}
} else {
if (ititle == issa[iil].title) {
document.getElementById(parid).innerHTML=document.getElementById(parid).innerHTML.replace(issa[iil].outerHTML, '<span class="' + csid + '">' + ih + '</span>');
}
}
}
} else if (issa.length > 0) {
document.getElementById(parid).innerHTML=document.getElementById(parid).innerHTML.replace(issa[iil].outerHTML, '<span class="' + csid + '">' + ih + '</span>');
}
} else {
var ijl;
var huhs=document.getElementsByTagName(intag);
for (ijl=0; ijl<huhs.length; ijl++) {
if (huhs[ijl].className.indexOf(inc) != -1) {
issa.push(huhs[ijl]);
}
}
var il=0; //for (var il=0; il<issa.length; il++) {
if (ititle != '') {
for (il=0; il<issa.length; il++) {
if (issa[il].outerHTML.indexOf(' data-index=') != -1) {
if (ititle == issa[il].getAttribute('data-index')) {
document.getElementById(parid).innerHTML=document.getElementById(parid).innerHTML.replace(issa[il].outerHTML, '<span class="' + csid + '">' + ih + '</span>');
}
} else {
if (ititle == issa[il].title) {
document.getElementById(parid).innerHTML=document.getElementById(parid).innerHTML.replace(issa[il].outerHTML, '<span class="' + csid + '">' + ih + '</span>');
}
}
}
} else if (issa.length > 0) {
document.getElementById(parid).innerHTML=document.getElementById(parid).innerHTML.replace(issa[il].outerHTML, '<span class="' + csid + '">' + ih + '</span>');
}
}
}
}

… instigated in the changed calling arrangement (for that div contenteditable=true red bordered element) …


imgids.push('ximage' + ic + String.fromCharCode(9) + 'arialdiv' + String.fromCharCode(9) + 'span' + outsidec.substring(ii, eval(1 + ii)) + String.fromCharCode(9) + eval(-1 + imgids.length));
dcs=docgetclasssub('span' + outsidec.substring(ii, eval(1 + ii)).charCodeAt(), 'span', document.getElementById('ximage' + ic).outerHTML.replace(' id=', ' class=').replace('<img','<img title="Click to reveal original font character" data-index="' + eval(-1 + imgids.length) + '" onclick="selfdestruct(' + eval(-1 + imgids.length) + ',' + eval(-1 + imgids.length) + ');"'));
for (var idcs=1; idcs<dcs.length; idcs++) {
imgids.push('ximage' + ic + String.fromCharCode(9) + 'arialdiv' + String.fromCharCode(9) + 'span' + outsidec.substring(ii, eval(1 + ii)) + String.fromCharCode(9) + eval(-1 + imgids.length));
}

To see these ideas in play, you can see this idea play out at the changed under_local_font.html‘s live run link.


Previous relevant Local Fonts Revisited Application Tutorial is shown below.

Local Fonts Revisited Application Tutorial

Local Fonts Revisited Application Tutorial

It’s going to take a while to “bed this in”, the web application of yesterday’s Local Fonts Revisited Recall Tutorial involving local font management, and now thinking about “applying” local fonts digitized by the user.

We want to explore alternative ideas to …

  • character by character traversal of an HTML element (with innerHTML … the raw textual wording of which can be gleaned via code like (for HTML element object “divo”)) …

    var outsidec=('' + (divo.innerText || divo.contentWindow || divo.contentDocument));

    … for chances of “font character image” substitution to the innerHTML content … because it can be slow (though we think we can improve on that slowness, in future code releases) … so today we look to …
  • idea of applying a “background image strip version of the textual content” brought to the fore (which can mean retract what’s there to the back) only where a user defined font character exists … alas, we discovered (without a lot more effort (we may yet do)) this only suits monospaced fonts such as Courier New (going back to that decision we made that the digitizing canvas should be 70 x 70)

At first we tried that linear gradient thought that a background might “glow above” the foreground (tee hee, but seriously, this technique does suit sometimes, as with Javascript and PHP Base64 Media Tutorial). But then we saw sense and to “retract what’s there to the back” we could set the existant element CSS property color:transparent, opening the door to the plan below.

The plan we have going forward with this approach goes like …

  • find text elements with defined innerHTML … that …
  • have a defined “ID” … and …
  • apart from <br> and &gt; and &lt; and &amp; and &nbsp; if innerHTML is equivalent to (innerText || contentWindow || contentDocument) … we …
  • CSS (via Javascript DOM) …
    1. document.getElementById(‘arial_span’).style.color = ‘transparent';
    2. document.getElementById(‘arial_span’).style.backgroundRepeat = ‘no-repeat';
    3. document.getElementById(‘arial_span’).style.backgroundSize=’105% 100%';
    4. letsomethrough( document.getElementById(‘arial_span’) ).style.backgroundImage = ‘URL(“‘ + document.getElementById(‘ifsrc’).src.replace(‘?ipinto=y’, document.getElementById(‘ipinto’).value) + ‘”)';
  • “spanize” the parent text element as above via that Javascript function letsomethrough by nesting all “lonely” (find in code later below where var outside is true) text characters within a …
    1. span element (why span? … because it is CSS display:inline) … that if for a letter (as per the “w” of below) digitized by the user …
    2. will inherit its colour from the parent (ie. be transparent, and allow the background imagery to “shine through”, via <span>w</span>) … whereas if for a letter not digitized by the user …
    3. we define the colour to be black, overriding transparent, via <span style=”color:black;”>w</span>

As you can see, this is ongoing, and we hope to iron out some of the restrictiveness and get to cross browser issues and “apply” to real world data, such as this blog contents, perhaps.

In the meantime, see this idea play out at the changed under_local_font.html‘s live run link.

You can also see this play out at WordPress 4.1.1’s Local Fonts Revisited Application Tutorial.


Previous relevant Local Fonts Revisited Recall Tutorial is shown below.

Local Fonts Revisited Recall Tutorial

Local Fonts Revisited Recall Tutorial

Onto yesterday’s Local Fonts Revisited Primer Tutorial Local Fonts web application start, we’ve progressed today with some “recall” work.

In this respect we had to decide a mechanism by which a user could recall their work. Our decision is to …

  • be saving user defined font characters into a long “canvas” strip element … and …
  • allow a “Save” button be pressed … to …
  • convert that “canvas” strip element to data URI and subsequently to a web server image file (via PHP) … that has a filename whereby …
  • on web application rerun if such a Local Fonts web server image file is found (via PHP) … this triggers …
  • a select (dropdown) element appears in the h1 heading element allowing the user to “recall” that Local Font work …in which case …
  • a long “canvas” strip element appears with these Local Font characters … and tomorrow …

… leaving tomorrow’s work to “meld” that recall data into the natural workflow of that previous work.

It’s best you view the changed under_local_font.html‘s live run link to see what we mean here, getting the [canvasContext].drawImage() functionality to be able to draw multiple images into a single canvas element, the curiosity being that we needed to


function athy() {
var xid='';
if (lastcid != cid) {
lastcid=cid;
compcanv=document.getElementById('compositeimages');
compcanvc=compcanv.getContext('2d');

var isd=docgetclass('athy', 'img');
for (var jsd=0; jsd<isd.length; jsd++) {
xid=String.fromCharCode(eval('' + isd[jsd].id.replace('image','')));
curx=eval(70 * eval('' + origlist.indexOf(xid)));
compcanvc.drawImage(document.getElementById(isd[jsd].id),0,0,70,70,curx,cury,70,70);
}
}
}

… a form of verbosity we were not expecting but required because the canvas would clear in between Local Font character definitions.


Previous relevant Local Fonts Revisited Primer Tutorial is shown below.

Local Fonts Revisited Primer Tutorial

Local Fonts Revisited Primer Tutorial

Working off our work on the Textarea Pointing web application of the series of blog postings ending with Textarea Pointing Local Font Canvas Overlay Deletes Tutorial today we’re starting out on a Local Fonts web application journey.

At this early stage we’re missing a bit of accountability and recall but we have worked a way to combine …

  • proper web font text characters … with …
  • tailored canvas drawn “scribble” Local Font alternatives … within a grandchild child iframe element … the in between child iframe called via the srcdoc content mode of populating

The user can see these characters “infiltrate” text strings there on the webpage, one …

  1. a list of the ascii characters we’re dealing with using these Local Fonts … and the other …
  2. a user controllable HTML div contenteditable=true text string that dynamically changes appropriately as the user defines their Local Font characters

Like the idea? Well, follow the journey in the days to follow today’s “proof of concept” under_local_font.html live run link.

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.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Ajax Auto-completion Internationalization Stay Tutorial

Ajax Auto-completion Internationalization Stay Tutorial

Ajax Auto-completion Internationalization Stay Tutorial

With yesterday’s Ajax Auto-completion Internationalization Trip Tutorial

  • we got to a destination on a trip … and today, as far as being online goes with this, we start thinking more about …
  • your stay at that destination … new options today involving …
    1. accomodation via starting with a Google image search helper …
    2. weather via the wonderful Weather Underground API …
    3. inhouse Sunrise and Sunset information …
    4. inhouse Moon position and other planetary positioning … for those astronomy enthusiasts … via that Python and PHP work of PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial

To do this we again rely on transference of data attributes between HTML Ajax created elements and the dynamically created “Trip Mode” select (dropdown) element. You can see some of this going into the Ajax created elements, as per


if (is_capital) {
idname=" onclick=\" if (stopoffs.indexOf(this.value) != -1) { stopoffs='~'; } if (accoms.indexOf(this.getAttribute('data-accom')) == -1) { accoms+=this.id + '=' + this.getAttribute('data-accom') + '~'; } if (weathers.indexOf(this.getAttribute('data-weatherurl').replace('EncodedPlaceGoesHere',encodeURIComponent('" + myThisDiv.innerHTML.split(',')[0] + "'))) == -1) { weathers+='" + myThisDiv.innerHTML + "'.toLowerCase().split(' (')[0].replace(/\ /g,'_') + '=' + this.getAttribute('data-weatherurl').replace('EncodedPlaceGoesHere',encodeURIComponent('" + myThisDiv.innerHTML.split(',')[0] + "')) + '~'; } stopoffs+=this.value + '~';\" name=\"" + myThisCapital.toLowerCase().split(' (')[0].replace(/\ /g,'_') + "\" id=\"" + myThisDiv.innerHTML.toLowerCase().split(' (')[0].replace(/\ /g,'_') + "\" data-accom=\"" + (myThisDiv.innerHTML.toLowerCase().split(' (')[0] + ', ' + myThisCapital.toLowerCase().split(' (')[0]).replace(/\ /g,'+') + "\" ";
} else {
idname=" onclick=\"if (stopoffs.indexOf(this.value) != -1) { stopoffs='~'; } if (accoms.indexOf(this.getAttribute('data-accom')) == -1) { accoms+=this.id + '=' + this.getAttribute('data-accom') + '~'; } if (weathers.indexOf(this.getAttribute('data-weatherurl').replace('EncodedPlaceGoesHere',encodeURIComponent('" + myThisDiv.innerHTML.split(',')[0] + "'))) == -1) { weathers+='" + myThisDiv.innerHTML + "'.toLowerCase().split(' (')[0].replace(/\ /g,'_') + '=' + this.getAttribute('data-weatherurl').replace('EncodedPlaceGoesHere',encodeURIComponent('" + myThisDiv.innerHTML.split(',')[0] + "')) + '~'; } stopoffs+=this.value + '~';\" id=\"" + myThisCapital.toLowerCase().split(' (')[0].replace(/\ /g,'_') + "\" name=\"" + myThisDiv.innerHTML.toLowerCase().split(' (')[0].replace(/\ /g,'_') + "\" data-accom=\"" + (myThisCapital.toLowerCase().split(' (')[0] + ', ' + myThisDiv.innerHTML.toLowerCase().split(' (')[0]).replace(/\ /g,'+') + "\" ";
}

… and then transferred up into the dynamically created “Trip Mode” select (dropdown) element (ie. the one with multiple entry abilities (by this time)), as per


function loadifsrc(iois) {
var xintstuff='', latlong='';
if (iois.src != '') {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (iois.src.indexOf('tdinto=') != -1) {
xintstuff=document.getElementById(iois.src.split('tdinto=')[1].split('&')[0]).innerHTML;
} else {
xintstuff=aconto.body.innerHTML;
}
//alert(xintstuff);
if (xintstuff.indexOf(' data-geo="') != -1) {
latlong=xintstuff.split(' data-geo="')[1].split('"')[0];
if (('' + iois.title).indexOf('countryname=') != -1 && ('' + iois.title).indexOf('~') != -1) {
if (accoms.indexOf('' + ('' + iois.title).split('~')[1] + '=') != -1) {
document.getElementById(('' + iois.title).split('~')[1]).setAttribute('data-accom', accoms.split('' + ('' + iois.title).split('~')[1] + '=')[1].split('~')[0]);
}
if (weathers.indexOf('' + ('' + iois.title).split('~')[1] + '=') != -1) {
document.getElementById(('' + iois.title).split('~')[1]).setAttribute('data-weatherurl', weathers.split('' + ('' + iois.title).split('~')[1] + '=')[1].split('~')[0]);
}
document.getElementById(('' + iois.title).split('~')[1]).setAttribute('data-countrygeo', latlong);
} else if (('' + iois.title).indexOf('capitalid=') != -1) {
if (accoms.indexOf('' + ('' + iois.title).split('capitalid=')[1] + '=') != -1) {
document.getElementById(('' + iois.title).split('~')[1]).setAttribute('data-accom', accoms.split('' + ('' + iois.title).split('capitalid=')[1] + '=')[1].split('~')[0]);
}
if (weathers.indexOf('' + ('' + iois.title).split('capitalid=')[1] + '=') != -1) {
document.getElementById(('' + ('' + iois.title).split('capitalid=')[1])).setAttribute('data-weatherurl', weathers.split('' + ('' + iois.title).split('capitalid=')[1] + '=')[1].split('~')[0]);
}
document.getElementById(('' + iois.title).split('capitalid=')[1]).setAttribute('data-capitalgeo', latlong);
}
}

}
}
}

… so that, by the time the user selects a place and clicks the new “Accomodation” button, for example, code like below will make use of the data attributes


var accomurl='https://www.google.com/search?q=accomodation+in+Beijing,+China&rlz=1C5CHFA_enAU832AU832&source=lnms&tbm=isch&sa=X&ved=0ahUKEwiyo92AkqrjAhVGbn0KHda2AyIQ_AUIESgC&biw=1437&bih=755';
var accomfrom='Beijing,+China';
var accomto='Beijing,+China';


function tripplan(iscapitaltrip,sin) {
var pwo=null;
var i=0, j=0, tripurl='', dcity='', dctry='', dweather=[], dcs=[], daccom=[], daccomc='', daccomsel=[];
var totalsel=sin.innerHTML.split('</option>'), sofarsel=stopoffs.split('~'), selsel=[];
if (iscapitaltrip == -1) { tripurl='//wunderground.com'; }
selsel.push("");
for (i=0; i<sin.options.length; i++) {
daccom.push(-1);
daccomsel.push(-1);
}

for (i=0; i<sin.options.length; i++) {
if (sin.options[i].selected) {
if (sin.options[i].value != '') {
dcity='';
dctry='';
dcs=sin.options[i].outerHTML.split(' data-capitalgeo="');
if (dcs.length > 1) { dcity=dcs[1].split('"')[0]; }
dcs=sin.options[i].outerHTML.split(' data-countrygeo="');
if (dcs.length > 1) { dctry=dcs[1].split('"')[0]; }
dcs=sin.options[i].outerHTML.split(' data-accom="');
if (dcs.length > 1) { daccomc=dcs[1].split('"')[0]; }

dcs=sin.options[i].outerHTML.split(' data-weatherurl="');
if (dcs.length > 1) { dweather.push(dcs[1].split('"')[0]); } else { dweather.push(""); }
if (dcity != '') { selsel.push(sin.options[i].value + '#0000' + dcity); }
if (daccomc != '') { daccomsel[eval(-1 + selsel.length)]=i; }
for (j=0; j<sofarsel.length; j++) {
if (sofarsel[j].split('#')[0] == sin.options[i].value.split('#')[0]) { daccom[j]=i; sofarsel[j]+='#00' + i; if (dcity != '') { sofarsel[j]+='#0000' + dcity; } }
}
}
}
}
// ...
if (iscapitaltrip == -6) { // accomodation
if (daccom[1] != -1) {
tripurl=accomurl.replace(accomfrom, sin.options[daccom[1]].getAttribute('data-accom'));
window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
}
}

// ...
}

Try the extended Trip Planning functionality with the changed auto_language_complete.html live run link for more “Happy Planning”!


Previous relevant Ajax Auto-completion Internationalization Trip Tutorial is shown below.

Ajax Auto-completion Internationalization Trip Tutorial

Ajax Auto-completion Internationalization Trip Tutorial

We add onto yesterday’s Ajax Auto-completion Internationalization Capitals Tutorial some Trip Planning functionality today. Don’t know about you, but we find ourselves mulling over maps for hours, wondering about far off lands. Now that Google Maps makes it so easy to deal with …

  • map detail around a single place … it also …
  • in “Directions” mode Google Maps becomes a trip planning tool par excellence

… and so we harness that, along with the newly introduced …

allow for integration of inhouse Timezone Places web application

… so that when the user chooses the “Country” button display mode (rather than the “Capital” button display mode) they see Country Timezone Webpage Child Iframes lined up from left to right, to …

  • get ideas of the “when” of timezones … incorporating …
  • the inhouse menus (with suboptions like “Weather”) interfacing to the great Google Charts Map Chart maps

… to try to meld a bit of “when” with “where”, two of the important concepts when it comes to trippingtrips.

Remember that Google Maps can be used to visit a place ahead of time and download a set of “offline maps” that do not require WiFi later to access, as those caught out by huge (accidental and “in all innocence”) global roaming phone bills can probably attest to.

Getting this going, in broad brush terms, what did we do?

  • well, the dogs got up pretty early and needed feeding …
  • then the cat came along, like “Lord Muck” … and so …
  • the fish gave me sideways glances until “fish flaked” … when they then looked out at 2:15 or maybe 4:45 or is that one at 14:30 … … but we digress …
  • we need latitude and longitude geographicals in order to display the map data … and so in the …
  • newly included (in the top h1 header element) we have an HTML select element dropdown …

    function sadd(inih) {
    var purlis='', psuffix='';
    if (inih.indexOf("'s the capital city of ") != -1) {
    if (inih.indexOf('#') != -1) { psuffix=' (' + inih.split('#')[1] + ')'; }
    purlis=document.URL.split('#')[0].split('?')[0] + '?capital=' + encodeURIComponent(inih.split('#')[0].split(' (')[0].split("'s ")[0].replace(', ',',_').replace(/\ /g,'_')) + '#' + encodeURIComponent(inih.split("'s the capital city of ")[1].replace(', ',',_').replace(/\ /g,'_') + psuffix);
    } else if (inih.indexOf("'s capital city is ") != -1) {
    purlis=document.URL.split('#')[0].split('?')[0] + '?country=' + encodeURIComponent(inih.split('#')[0].split(' (')[0].split("'s ")[0].replace(', ',',_').replace(/\ /g,'_')) + '#' + encodeURIComponent(inih.split("'s capital city is ")[1].replace(', ',',_').replace(/\ /g,'_') + psuffix);
    } else if (inih != '') {
    purlis=document.URL.split('#')[0].split('?')[0] + '?country=' + encodeURIComponent(inih.split('#')[0].split(' (')[0].split("'s ")[0].replace(', ',',_').replace(/\ /g,'_'));
    }
    if (purlis != '') {
    var wasih=document.getElementById('expands').innerHTML;
    if (wasih.indexOf('<') == -1) {
    stopoffs="~";
    document.getElementById('expands').innerHTML='<select id=divselect style="display:inline-block;width:' + ('' + ospan.width).replace('px','') + 'px;" onchange="lastdiviframe(this.value);"><option value="">Trip Planning ' + wasih + '</option><option' + idname + ' value="' + purlis + '">' + inih.split('#')[0] + '</option></select> <div style=display:inline-block; id=dbut><font size=2>Trip Mode: </font><input style=display:inline-block; type=checkbox onchange="document.getElementById(' + "'" + 'divselect' + "'" + ').multiple=true; document.getElementById(' + "'" + 'dbut' + "'" + ').innerHTML=' + "'" + '<input style=display:inline-block; onclick=tripplan(1,selois); type=button value=Capital></input> <input style=display:inline-block; onclick=tripplan(0,selois); type=button value=Country Trip></input>' + "'" + ';"></input></div>';
    selois=document.getElementById('divselect');
    } else if (document.getElementById('divselect').innerHTML.indexOf(purlis) == -1) {
    document.getElementById('divselect').innerHTML+='<option' + idname + ' value="' + purlis + '">' + inih.split('#')[0] + '</option>';
    }
    }
    return inih.split('#')[0];
    }

    … storing places selected, in the onload iframe event of the Wikipedia reader we set global data attributes

    function loadifsrctwo(iois) {
    var xintstuff='', latlong='';
    if (iois.src != '') {
    var aconto = (iois.contentWindow || iois.contentDocument);
    if (aconto != null) {
    if (aconto.document) { aconto = aconto.document; }
    if (iois.src.indexOf('tdinto=') != -1) {
    xintstuff=document.getElementById(iois.src.split('tdinto=')[1].split('&')[0]).innerHTML;
    } else {
    xintstuff=aconto.body.innerHTML;
    }
    if (xintstuff.indexOf(' data-geo="') != -1) {
    latlong=xintstuff.split(' data-geo="')[1].split('"')[0];
    if (('' + iois.title).indexOf('countryname=') != -1 && ('' + iois.title).indexOf('~') != -1) {
    document.getElementById(('' + iois.title).split('~')[1]).setAttribute('data-countrygeo', latlong);
    } else if (('' + iois.title).indexOf('capitalid=') != -1) {
    document.getElementById(('' + iois.title).split('capitalid=')[1]).setAttribute('data-capitalgeo', latlong);
    }
    }
    }
    }
    }

    … ensures that …
  • should the HTML input type=checkbox, being checked by the user, signal to the web application that the user wants to “swing into” Trip Planning mode of use, then that select element dropdown multiple attribute possibilities are switched on (and the checkbox replaced by those aforesaid mentioned “Capital” and “Country” buttons) … meaning …
  • that on selecting multiple options from that dropdown there is also the information necessary to trip plan, and show those maps …

    function tripplan(iscapitaltrip,sin) {
    var i=0, j=0, retval='', aot, tripurl='', dcity='', dctry='',dcs=[];
    var totalsel=sin.innerHTML.split('</option>'), sofarsel=stopoffs.split('~'), selsel=[];
    selsel.push("");
    for (i=0; i<sin.options.length; i++) {
    if (sin.options[i].selected) {
    if (sin.options[i].value != '') {
    //alert(sin.options[i].outerHTML);
    dcity='';
    dctry='';
    dcs=sin.options[i].outerHTML.split(' data-capitalgeo="');
    if (dcs.length > 1) { dcity=dcs[1].split('"')[0]; }
    dcs=sin.options[i].outerHTML.split(' data-countrygeo="');
    if (dcs.length > 1) { dctry=dcs[1].split('"')[0]; }
    // data-capitalgeo="-16.500,-68.150" data-countrygeo="-16.712,-64.666"
    //aot=sin.options[i].text.split('(')[eval(-1 + sin.options[i].text.replace(')','').split('(').length)].replace(')','').split(':');
    selsel.push(sin.options[i].value + '#0000' + dcity);
    for (j=0; j<sofarsel.length; j++) {
    if (sofarsel[j].split('#')[0] == sin.options[i].value.split('#')[0]) { sofarsel[j]+='#00' + i; if (dcity != '') { sofarsel[j]+='#0000' + dcity; } }
    }
    }
    }
    }
    selsel.push("");
    if (selsel.length == sofarsel.length) {
    // eg. HTTP://localhost:8888/Ajax/AutoCompletion/auto_language_complete.html?capital=La_Paz#Bolivia%23BO%20(BO)#001
    // //www.rjmprogramming.com.au/PHP/tz_places.php?iso=GB&iso2=AU&iso3=NZ
    if (iscapitaltrip == 0) {
    tripurl='//www.rjmprogramming.com.au/PHP/tz_places.php?iso=' + sofarsel[1].split('%23')[1].split('(')[1].split(')')[0];
    } else { // Sydney,+New+South+Wales
    if (sofarsel[1].indexOf('capital=') != -1) {
    if (sofarsel[1].indexOf('#0000') != -1) {
    tripurl='//www.google.com/maps/dir/' + sofarsel[1].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (sofarsel[1].indexOf('#00') != -1) {
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    } else if (sofarsel[1].indexOf('country=') != -1) {
    if (sofarsel[1].indexOf('#0000') != -1) {
    tripurl='//www.google.com/maps/dir/' + sofarsel[1].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (sofarsel[1].indexOf('#00') != -1) {
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    }
    }
    for (i=2; i<sofarsel.length; i++) {
    if (sofarsel[i] != '') {
    if (iscapitaltrip == 0) {
    tripurl+='&iso' + i + '=' + sofarsel[i].split('%23')[1].split('(')[1].split(')')[0];
    } else {
    if (sofarsel[i].indexOf('capital=') != -1) {
    if (sofarsel[i].indexOf('#0000') != -1) {
    tripurl+='/' + sofarsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,'');
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sofarsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (sofarsel[i].indexOf('#00') != -1) {
    tripurl+='/' + sin.options[eval(sofarsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(sofarsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    } else if (sofarsel[i].indexOf('country=') != -1) {
    if (sofarsel[1].indexOf('#0000') != -1) {
    tripurl+='/' + sofarsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sofarsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (sofarsel[i].indexOf('#00') != -1) {
    tripurl+='/' + sin.options[eval(sofarsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(sofarsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    }
    }
    }
    }
    window.open(tripurl, "_blank", "left=10,top=330,width=1300,height=470");
    } else {
    if (iscapitaltrip == 0) {
    tripurl='//www.rjmprogramming.com.au/PHP/tz_places.php?iso=' + selsel[1].split('%23')[1].split('(')[1].split(')')[0];
    } else { // Sydney,+New+South+Wales
    if (selsel[1].indexOf('capital=') != -1) {
    if (selsel[1].indexOf('#0000') != -1) {
    tripurl='//www.google.com/maps/dir/' + selsel[1].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (selsel[1].indexOf('#00') != -1) {
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    } else if (selsel[1].indexOf('country=') != -1) {
    if (selsel[1].indexOf('#0000') != -1) {
    tripurl='//www.google.com/maps/dir/' + selsel[1].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (selsel[1].indexOf('#00') != -1) {
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    }
    }
    for (i=2; i<selsel.length; i++) {
    if (selsel[i] != '') {
    if (iscapitaltrip == 0) {
    tripurl+='&iso' + i + '=' + selsel[i].split('%23')[1].split('(')[1].split(')')[0];
    } else {
    if (selsel[i].indexOf('capital=') != -1) {
    if (selsel[i].indexOf('#0000') != -1) {
    tripurl+='/' + selsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,'');
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + selsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (selsel[i].indexOf('#00') != -1) {
    tripurl+='/' + sin.options[eval(selsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(selsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    } else if (selsel[i].indexOf('country=') != -1) {
    if (selsel[1].indexOf('#0000') != -1) {
    tripurl+='/' + selsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + selsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (selsel[i].indexOf('#00') != -1) {
    tripurl+='/' + sin.options[eval(selsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(selsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    }
    }
    }
    }
    window.open(tripurl, "_blank", "left=10,top=330,width=1300,height=470");
    }
    }

    … into popup windows

Try the new Trip Planning functionality with the changed auto_language_complete.html live run link. Happy planning!


Previous relevant Ajax Auto-completion Internationalization Capitals Tutorial is shown below.

Ajax Auto-completion Internationalization Capitals Tutorial

Ajax Auto-completion Internationalization Capitals Tutorial

Having seen Toy Story 4 we were inspired enough to dedicate today’s blog post to all those onions out there dedicated to improving the layers of our understanding, all those “onions of the 4th dimension” out there! Because yesterday’s Ajax Auto-completion Internationalization Email Tutorial has been built upon in a couple of ways new to us (but no doubt not to a lot of ewesyouseyous (pardon my Liverpudlian)).

  • “onions of the 4th dimension” … uppercase and lowercase separation 2x multiplier of functionality … via the …
  • keyboard event “onkeypress” (better than “onkeydown” (though “onkeydown” is good for Ctrl and Alt and Shift and Del scenarios)) can differentiate uppercase to lowercase letters to Country versus Capital respectively
  • “gone fishing” part 2 … users learn by trial and error of that first keyboard letter pressed … eg. how many world capital cities start with “q”? (types of “fishing” is now, additionally, possible, as a learning aid with this web application)
  • “can an HTML element get an ID property added dynamically?” … today we find out … and answer is “yes” … this is useful to allow a programmatical click of an (Ajax created) element later
  • “can an array member be found, in full, in Javascript (ie. indexed)?” … today and yesterday we found out … and answer is “yes” … Javascript [string{MustBeObject}].indexOf([string]) function(s) (or should we say “members”) acts like C++ Object Oriented Programming style object “members” where the Object type is part of the full definition of a function (“member”) definition … so a [String].indexOf([String]) type will go to a different piece of code to an [Array].indexOf([String]) type (calling object)
  • allow for integration of inhouse Timezone Places web application, as required

Get the feel for this with the changed auto_language_complete.html live run link.


Previous relevant Ajax Auto-completion Internationalization Email Tutorial is shown below.

Ajax Auto-completion Internationalization Email Tutorial

Ajax Auto-completion Internationalization Email Tutorial

On top of the progress of yesterday’s Ajax Auto-completion Internationalization Revisit Tutorial we have a dual purpose set of improvements today, those being …

  • introduction of “long hover” functionality to the Ajax Autocompletion menus presented, whereby the Wikipedia and Google Chart optional functionalities from yesterday are “sneak previewed” for the user … which, in turn, helps with …
  • sharing email functionality in two “client email application” ways …
    1. readying a webpage that does well using the web browser Edit menu Select All and Copy options to be a useful email attachment … and a separate new …
    2. email 📧 emoji “a” mailto: link to the “client email application” for an email with one body link back to the website webpage via a ?country= argument
  • So what’s “long hover”? Well, it’s not formally an event in HTML. And it’s not a concept at all with mobile platforms. To us, a “long hover event” action item is one that only occurs when the user hovers (tripping an “onmouseover” event) over that action item for a longer than usual amount of time (and we say 2 seconds) before “moving away” (tripping an “onmouseout” event). See the new codings required to make this happen, that “setTimeout(overandout, 2000)” two second delay the crucial difference, below.

    1. within the Ajax onreadystatechange logic function …

      myTempDiv.title = myCodesArray[myi] + ';' + myThisCapital;
      myTempDiv.innerHTML = myThisCountry;
      myTempDiv.onmouseover = overmakeSelection;
      myTempDiv.onmouseout = outmakeSelection;

      myTempDiv.onclick = makeSelection;
      myTempDiv.className = "mysuggestions";

      … and then …
    2. some new Javascript functions to help this change out …

      var lhcandidate='', lhready=false, overcnt=0;
      function overandout() {
      if (lhcandidate != '' && overcnt == 1) {
      overcnt=0;
      lhready=true;
      makeSelection(null);
      }
      }

      function overmakeSelection(evt) {
      overcnt++;
      if (evt) {
      lhcandidate = evt.target;
      } else {
      lhcandidate = window.event.srcElement;
      }
      setTimeout(overandout, 2000);
      }

      function outmakeSelection(evt) {
      if (overcnt > 0) { overcnt--; }
      lhcandidate='';
      lhready=false;
      }

    … opening more scope for collaboration and sharing with this web application.

    Again, feel free to have a go at the changed auto_language_complete.html live run link.


    Previous relevant Ajax Auto-completion Internationalization Revisit Tutorial is shown below.

    Ajax Auto-completion Internationalization Revisit Tutorial

    Ajax Auto-completion Internationalization Revisit Tutorial

    Way back in 2013 we touched on AutoCompletion ideas when we presented Ajax Auto-completion Internationalization Tutorial. Quite a bit of water under bridges, and here in 2019 we feel like extending its functionalities by …

    … all “optional extras”. Remember with such new functionality it is really annoying for a user if the usual workflow of the web application is broken by your changes. We design ours today on an “only if the optional data is found” basis, so we don’t expect more than the usual complaints. That way an HTML div can be empty for “no data found”, or filled with an HTML table of three (td) cells each with an HTML iframe same-domain call of those Google Chart (1) and Wikipedia (2) inhouse interfacings.

    Feel free to have a go at the changed auto_language_complete.html live run link.


    Previous relevant Ajax Auto-completion Internationalization Tutorial is shown below.

    Ajax Auto-completion Internationalization Tutorial

    Ajax Auto-completion Internationalization Tutorial

    Yesterday’s tutorial (called PHP Gettext Internationalization Primer Tutorial) reignited something I’ve been curious about for ages … and knew it was out there … the notion of linking “country codes” to “language codes” and coming up with more informed thoughts regarding language choices … continuing on with our “internationalization” discussions of yesterday.

    We came up against this issue with the Ajax Auto-completion FollowUp Tutorial as of below, when we, lazily, only supplied a Google Translate window of “Welcome” to Country users who had a “Country Code” the same as the “Language Code”, such as Poland. However, you’ll find Poland is in the minority for this straightforward arrangement.

    So we delved into those codes (ie. locales) as of yesterday, like “de_DE” (German for Germany), and lo and behold (for two days running now … and am pretty tired on the 78th rounding of the Sydney Harbour Bridge) there are ways and means, and the biggest helping hand for us came from Zend Framework … and, by the way, Zend is an Apache framework … so, thanks.

    If you try today’s live run, then, for some countries, you’ll get multiple Google Translate “window.open()” method windows coming up, representing more of the languages spoken in that country (but of course it is not definitive, in this multivaried and fascinating woooooooorrrrrrrld on which we all cohabitate, man person).

    The use of Google Translate in this way, is great in itself with regard to translations (and sometimes an audio pronunciation possibility), as well as with written language issues such as “right to left” versus “left to right” usage.

    This whole scenario involves Ajax and auto-completion as concepts you may want to delve into as well, and if so, would recommend a perusal of all the linked tutorials below, to get the whole picture.

    On top of that, you’ll perhaps want to see the downloadable supervising HTML code you could call auto_language_complete.html (that changed from the previous venture into auto-completion as per auto_language_complete.html) which is, as of today … even though we said “Ajax … Tutorial” … supervising some newly created PHP (to help with the locales data) you could call lc_CC.php … so feel free to delve into all these “internationalization” (of language) ideas further at your leisure, and know that “internationalization” concepts cover so much more as well with issues such as “date formats” and currency formats”, just to name two, that you may want to do some research and development on, as well.


    Previous relevant Ajax Auto-completion FollowUp Tutorial
    is shown below.

    Ajax Preview Window Tutorial  (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax Auto-completion FollowUp Tutorial (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax techniques make your web pages very dynamic and useful, and there will be fewer changes of webpage required when using Ajax, because information derived from a data source (maybe a feed, maybe a database read, maybe a local source of data (as for this tutorial’s countries_attributed.xml … today, we use attributes, as distinct from yesterday’s tutorial … in source code note use of getAttribute() method … thanks to link and languages.xml … in source code note use of getAttribute() method … thanks to link … (by the way, with this last derived XML, it would be a great improvement and give more frequent lookup success to amend all the country code attributes to equal language code attributes (eg. it turns out mythical country Zolmovia (originally, code=Zm) speaks mainly Spanish (language code=es), so what am saying is change Zm to es in countries_attributed.xml) here)) make many changes of webpage obsolete.

    Today we build on Ajax Auto-completion Primer Tutorial as shown below, in that we attempt a (non 100% successful) coding relationship that tries to give a welcome message in the home language of the country you pick, via the wonderful Google Translate.

    One useful Ajax friendly piece of functionality is called auto-completion, where you have an HTML input text tag element you fill in, and you’d like to help out the user with both spelling and suggestions, so you present possibilities once they have pressed a key, and then the user can opt to pick one of the “(looks-like-a) dropdown”-listed options. This often helps with the proper nouns in our life, or, as is the case with the tutorial, country names. So we reward the user with a map courtesy of Google Maps (thanks) should it all go swimmingly (hope you’re not in Chad looking for a swim). In addition, when successful in establishing a likely home language for your country (will be sometimes wrong, sometimes unknowable with the shortcuts here, and maybe sometimes wrong (for these we apologize)).

    Have a look at the HTML/Javascript downloadable code which you could rename to auto_language_complete.html

    Here is a new link to some downloadable PHP programming source code explaining changes made (from tutorial below) here.

    Try a live run here.

    By the way, Gimp was used to make the layered image of this tutorial using techniques as explained in Gimp Layers Primer Tutorial.

    Regarding this topic I really like “JavaScript & Ajax” seventh edition by Tom Negrino and Dori Smith and the code in this book was followed closely, with small amendments.


    Previous relevant Ajax Auto-completion Primer Tutorial is shown below.

    Ajax Preview Window Tutorial  (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax Auto-completion Primer Tutorial (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax techniques make your web pages very dynamic and useful, and there will be fewer changes of webpage required when using Ajax, because information derived from a data source (maybe a feed, maybe a database read, maybe a local source of data (as for this tutorial’s countries.xml … thanks to link here)) make many changes of webpage obsolete.

    Today we more or less build on your previous Ajax knowledge (which am sure has moved along a long way from) beginning (at least, at this blog) with Ajax Preview Window Tutorial as shown below.

    Let’s have a look at Wikipedia’s thoughts on Ajax below.

    Ajax (also AJAX; /ˈeɪdʒæks/; an acronym for Asynchronous JavaScript and XML)[1] is a group of interrelated web development techniques used on the client-side to create asynchronous web applications. With Ajax, web applications can send data to, and retrieve data from, a server asynchronously (in the background) without interfering with the display and behavior of the existing page. Data can be retrieved using the XMLHttpRequest object. Despite the name, the use of XML is not required (JSON is often used instead. See AJAJ), and the requests do not need to be asynchronous.[2]

    Ajax is not a single technology, but a group of technologies. HTML and CSS can be used in combination to mark up and style information. The DOM is accessed with JavaScript to dynamically display, and allow the user to interact with, the information presented. JavaScript and the XMLHttpRequest object provide a method for exchanging data asynchronously between browser and server to avoid full page reloads.

    One useful Ajax friendly piece of functionality is called auto-completion, where you have an HTML input text tag element you fill in, and you’d like to help out the user with both spelling and suggestions, so you present possibilities once they have pressed a key, and then the user can opt to pick one of the “(looks-like-a) dropdown”-listed options. This often helps with the proper nouns in our life, or, as is the case with the tutorial, country names. So we reward the user with a map courtesy of Google Maps (thanks) should it all go swimmingly (hope you’re not in Chad looking for a swim).

    Have a look at the HTML/Javascript downloadable code which you could rename to countries_auto_complete.html
    Try a live run here.

    By the way, Gimp was used to make the layered image of this tutorial using techniques as explained in Gimp Layers Primer Tutorial.

    Regarding this topic I really like “JavaScript & Ajax” seventh edition by Tom Negrino and Dori Smith and the code in this book was followed closely, with small amendments.


    Previous relevant Ajax Preview Window Tutorial is shown below.

    Ajax Preview Window Tutorial

    Ajax Preview Window Tutorial

    Ajax is a client-side meets server-side melding of PHP (or ASP.Net) and Javascript and HTML and CSS and allows you to stay on the web page you are on doing many more things, rather than constantly changing web pages the way that HTML form tag makes you do. Ajax works with XMLHttpRequest object to quiz the server-side while staying on the client side. You may have guessed that we have been working up to this, and I refer you to the previous tutorial about JavaScript and the DOM Tutorial and PHP + JavaScript + HTML Primer Tutorial for important information to learn before tackling Ajax. Ajax shares similar restrictions to iFrames in limiting you to work within your own domain, generally speaking. Ajax normally makes use of the onmouseover (hence the amateurish added rendition of a cursor, where I was hovering over the option tag, but couldn’t take a snapshot of this … ie. too lazy to get the camera!) and onmouseout events of HTML elements and you may notice the less than ideal Internet Explorer behaviour for this Ajax code, and that is because for Internet Explorer the option tag has no onmouseover nor onmouseout event defined, so we did an awful kludge.

    Earlier tutorials …

    JavaScript is a tremendous web client-side language to learn. You may have heard of a server-side JavaScript, but this tutorial only deals with client-side work. This tutorial builds a JavaScript layer on top of the PHP tutorial made earlier, showing how the DOM can be used to change the look of your webpage dynamically, even if most of it is in an iFrame (but there are limits).

    PHP is a wonderful language to learn. It is usually associated with being a web server-side language (as with this tutorial, where it is being shown on a local MAMP web server) but can be a command line tool as well. If you like PHP you may eventually like ASP.Net and/or Python, and vice versa. It has sophisticated data structures, Object Oriented (the thinking that you can build classes with data and methods which define objects created as you run the program … eg. you might write a class for book and have data members for things like numPages and publisher, author, creationDate and have methods called things like getCreationDate, setCreationDate, getAuthor, setAuthor allowing the user to use these methods rather than changing the data members themselves … heaven forbid that!) code concepts, and really combines well with JavaScript (as a client-side language).

    Download programming source code and rename to ajax.php (but Ajax only works within the domain you use it, and this code mentions www.rjmprogramming.com.au so just use it for reference purposes or rewrite for purposes that suit you within your domain of interest).

    Regarding this topic I really like “JavaScript & Ajax” seventh edition by Tom Negrino and Dori Smith

    Did you know …
    JavaScript makes a great easy-access Calculator?

    Try typing the lines below into the address bar of your favourite browser:

    Javascript: eval(512 / 380);
    Javascript: eval(512 * 380);
    Javascript: eval(512 – 380);
    Javascript: eval(512 + 380);
    Javascript: eval(512 % 380);

    These days we spend so much time on the Internet it is a much quicker way to get to a calculator!

    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.

Posted in Ajax, eLearning, Event-Driven Programming, Trips, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Ajax Auto-completion Internationalization Trip Tutorial

Ajax Auto-completion Internationalization Trip Tutorial

Ajax Auto-completion Internationalization Trip Tutorial

We add onto yesterday’s Ajax Auto-completion Internationalization Capitals Tutorial some Trip Planning functionality today. Don’t know about you, but we find ourselves mulling over maps for hours, wondering about far off lands. Now that Google Maps makes it so easy to deal with …

  • map detail around a single place … it also …
  • in “Directions” mode Google Maps becomes a trip planning tool par excellence

… and so we harness that, along with the newly introduced …

allow for integration of inhouse Timezone Places web application

… so that when the user chooses the “Country” button display mode (rather than the “Capital” button display mode) they see Country Timezone Webpage Child Iframes lined up from left to right, to …

  • get ideas of the “when” of timezones … incorporating …
  • the inhouse menus (with suboptions like “Weather”) interfacing to the great Google Charts Map Chart maps

… to try to meld a bit of “when” with “where”, two of the important concepts when it comes to trippingtrips.

Remember that Google Maps can be used to visit a place ahead of time and download a set of “offline maps” that do not require WiFi later to access, as those caught out by huge (accidental and “in all innocence”) global roaming phone bills can probably attest to.

Getting this going, in broad brush terms, what did we do?

  • well, the dogs got up pretty early and needed feeding …
  • then the cat came along, like “Lord Muck” … and so …
  • the fish gave me sideways glances until “fish flaked” … when they then looked out at 2:15 or maybe 4:45 or is that one at 14:30 … … but we digress …
  • we need latitude and longitude geographicals in order to display the map data … and so in the …
  • newly included (in the top h1 header element) we have an HTML select element dropdown …

    function sadd(inih) {
    var purlis='', psuffix='';
    if (inih.indexOf("'s the capital city of ") != -1) {
    if (inih.indexOf('#') != -1) { psuffix=' (' + inih.split('#')[1] + ')'; }
    purlis=document.URL.split('#')[0].split('?')[0] + '?capital=' + encodeURIComponent(inih.split('#')[0].split(' (')[0].split("'s ")[0].replace(', ',',_').replace(/\ /g,'_')) + '#' + encodeURIComponent(inih.split("'s the capital city of ")[1].replace(', ',',_').replace(/\ /g,'_') + psuffix);
    } else if (inih.indexOf("'s capital city is ") != -1) {
    purlis=document.URL.split('#')[0].split('?')[0] + '?country=' + encodeURIComponent(inih.split('#')[0].split(' (')[0].split("'s ")[0].replace(', ',',_').replace(/\ /g,'_')) + '#' + encodeURIComponent(inih.split("'s capital city is ")[1].replace(', ',',_').replace(/\ /g,'_') + psuffix);
    } else if (inih != '') {
    purlis=document.URL.split('#')[0].split('?')[0] + '?country=' + encodeURIComponent(inih.split('#')[0].split(' (')[0].split("'s ")[0].replace(', ',',_').replace(/\ /g,'_'));
    }
    if (purlis != '') {
    var wasih=document.getElementById('expands').innerHTML;
    if (wasih.indexOf('<') == -1) {
    stopoffs="~";
    document.getElementById('expands').innerHTML='<select id=divselect style="display:inline-block;width:' + ('' + ospan.width).replace('px','') + 'px;" onchange="lastdiviframe(this.value);"><option value="">Trip Planning ' + wasih + '</option><option' + idname + ' value="' + purlis + '">' + inih.split('#')[0] + '</option></select> <div style=display:inline-block; id=dbut><font size=2>Trip Mode: </font><input style=display:inline-block; type=checkbox onchange="document.getElementById(' + "'" + 'divselect' + "'" + ').multiple=true; document.getElementById(' + "'" + 'dbut' + "'" + ').innerHTML=' + "'" + '<input style=display:inline-block; onclick=tripplan(1,selois); type=button value=Capital></input> <input style=display:inline-block; onclick=tripplan(0,selois); type=button value=Country Trip></input>' + "'" + ';"></input></div>';
    selois=document.getElementById('divselect');
    } else if (document.getElementById('divselect').innerHTML.indexOf(purlis) == -1) {
    document.getElementById('divselect').innerHTML+='<option' + idname + ' value="' + purlis + '">' + inih.split('#')[0] + '</option>';
    }
    }
    return inih.split('#')[0];
    }

    … storing places selected, in the onload iframe event of the Wikipedia reader we set global data attributes

    function loadifsrctwo(iois) {
    var xintstuff='', latlong='';
    if (iois.src != '') {
    var aconto = (iois.contentWindow || iois.contentDocument);
    if (aconto != null) {
    if (aconto.document) { aconto = aconto.document; }
    if (iois.src.indexOf('tdinto=') != -1) {
    xintstuff=document.getElementById(iois.src.split('tdinto=')[1].split('&')[0]).innerHTML;
    } else {
    xintstuff=aconto.body.innerHTML;
    }
    if (xintstuff.indexOf(' data-geo="') != -1) {
    latlong=xintstuff.split(' data-geo="')[1].split('"')[0];
    if (('' + iois.title).indexOf('countryname=') != -1 && ('' + iois.title).indexOf('~') != -1) {
    document.getElementById(('' + iois.title).split('~')[1]).setAttribute('data-countrygeo', latlong);
    } else if (('' + iois.title).indexOf('capitalid=') != -1) {
    document.getElementById(('' + iois.title).split('capitalid=')[1]).setAttribute('data-capitalgeo', latlong);
    }
    }
    }
    }
    }

    … ensures that …
  • should the HTML input type=checkbox, being checked by the user, signal to the web application that the user wants to “swing into” Trip Planning mode of use, then that select element dropdown multiple attribute possibilities are switched on (and the checkbox replaced by those aforesaid mentioned “Capital” and “Country” buttons) … meaning …
  • that on selecting multiple options from that dropdown there is also the information necessary to trip plan, and show those maps …

    function tripplan(iscapitaltrip,sin) {
    var i=0, j=0, retval='', aot, tripurl='', dcity='', dctry='',dcs=[];
    var totalsel=sin.innerHTML.split('</option>'), sofarsel=stopoffs.split('~'), selsel=[];
    selsel.push("");
    for (i=0; i<sin.options.length; i++) {
    if (sin.options[i].selected) {
    if (sin.options[i].value != '') {
    //alert(sin.options[i].outerHTML);
    dcity='';
    dctry='';
    dcs=sin.options[i].outerHTML.split(' data-capitalgeo="');
    if (dcs.length > 1) { dcity=dcs[1].split('"')[0]; }
    dcs=sin.options[i].outerHTML.split(' data-countrygeo="');
    if (dcs.length > 1) { dctry=dcs[1].split('"')[0]; }
    // data-capitalgeo="-16.500,-68.150" data-countrygeo="-16.712,-64.666"
    //aot=sin.options[i].text.split('(')[eval(-1 + sin.options[i].text.replace(')','').split('(').length)].replace(')','').split(':');
    selsel.push(sin.options[i].value + '#0000' + dcity);
    for (j=0; j<sofarsel.length; j++) {
    if (sofarsel[j].split('#')[0] == sin.options[i].value.split('#')[0]) { sofarsel[j]+='#00' + i; if (dcity != '') { sofarsel[j]+='#0000' + dcity; } }
    }
    }
    }
    }
    selsel.push("");
    if (selsel.length == sofarsel.length) {
    // eg. HTTP://localhost:8888/Ajax/AutoCompletion/auto_language_complete.html?capital=La_Paz#Bolivia%23BO%20(BO)#001
    // //www.rjmprogramming.com.au/PHP/tz_places.php?iso=GB&iso2=AU&iso3=NZ
    if (iscapitaltrip == 0) {
    tripurl='//www.rjmprogramming.com.au/PHP/tz_places.php?iso=' + sofarsel[1].split('%23')[1].split('(')[1].split(')')[0];
    } else { // Sydney,+New+South+Wales
    if (sofarsel[1].indexOf('capital=') != -1) {
    if (sofarsel[1].indexOf('#0000') != -1) {
    tripurl='//www.google.com/maps/dir/' + sofarsel[1].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (sofarsel[1].indexOf('#00') != -1) {
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    } else if (sofarsel[1].indexOf('country=') != -1) {
    if (sofarsel[1].indexOf('#0000') != -1) {
    tripurl='//www.google.com/maps/dir/' + sofarsel[1].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (sofarsel[1].indexOf('#00') != -1) {
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    }
    }
    for (i=2; i<sofarsel.length; i++) {
    if (sofarsel[i] != '') {
    if (iscapitaltrip == 0) {
    tripurl+='&iso' + i + '=' + sofarsel[i].split('%23')[1].split('(')[1].split(')')[0];
    } else {
    if (sofarsel[i].indexOf('capital=') != -1) {
    if (sofarsel[i].indexOf('#0000') != -1) {
    tripurl+='/' + sofarsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,'');
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sofarsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (sofarsel[i].indexOf('#00') != -1) {
    tripurl+='/' + sin.options[eval(sofarsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(sofarsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    } else if (sofarsel[i].indexOf('country=') != -1) {
    if (sofarsel[1].indexOf('#0000') != -1) {
    tripurl+='/' + sofarsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sofarsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (sofarsel[i].indexOf('#00') != -1) {
    tripurl+='/' + sin.options[eval(sofarsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(sofarsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(sofarsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    }
    }
    }
    }
    window.open(tripurl, "_blank", "left=10,top=330,width=1300,height=470");
    } else {
    if (iscapitaltrip == 0) {
    tripurl='//www.rjmprogramming.com.au/PHP/tz_places.php?iso=' + selsel[1].split('%23')[1].split('(')[1].split(')')[0];
    } else { // Sydney,+New+South+Wales
    if (selsel[1].indexOf('capital=') != -1) {
    if (selsel[1].indexOf('#0000') != -1) {
    tripurl='//www.google.com/maps/dir/' + selsel[1].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (selsel[1].indexOf('#00') != -1) {
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    } else if (selsel[1].indexOf('country=') != -1) {
    if (selsel[1].indexOf('#0000') != -1) {
    tripurl='//www.google.com/maps/dir/' + selsel[1].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (selsel[1].indexOf('#00') != -1) {
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    }
    }
    for (i=2; i<selsel.length; i++) {
    if (selsel[i] != '') {
    if (iscapitaltrip == 0) {
    tripurl+='&iso' + i + '=' + selsel[i].split('%23')[1].split('(')[1].split(')')[0];
    } else {
    if (selsel[i].indexOf('capital=') != -1) {
    if (selsel[i].indexOf('#0000') != -1) {
    tripurl+='/' + selsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,'');
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + selsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (selsel[i].indexOf('#00') != -1) {
    tripurl+='/' + sin.options[eval(selsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(selsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    } else if (selsel[i].indexOf('country=') != -1) {
    if (selsel[1].indexOf('#0000') != -1) {
    tripurl+='/' + selsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + selsel[i].split('#0000')[1].split('#')[0].replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    } else if (selsel[i].indexOf('#00') != -1) {
    tripurl+='/' + sin.options[eval(selsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    window.open(tripurl, "_blank", "left=" + eval(10 + i) + ",top=330,width=1300,height=470");
    tripurl='//www.google.com/maps/dir/' + sin.options[eval(selsel[i].split('#00')[1].split('#')[0])].id.replace(/\_/g,'+') + ',' + sin.options[eval(selsel[1].split('#00')[1].split('#')[0])].name.replace(/\_/g,'+'); // .replace(/\ /g,''); // + '/' + jiplace + '+' + jicont;
    }
    }
    }
    }
    }
    window.open(tripurl, "_blank", "left=10,top=330,width=1300,height=470");
    }
    }

    … into popup windows

Try the new Trip Planning functionality with the changed auto_language_complete.html live run link. Happy planning!


Previous relevant Ajax Auto-completion Internationalization Capitals Tutorial is shown below.

Ajax Auto-completion Internationalization Capitals Tutorial

Ajax Auto-completion Internationalization Capitals Tutorial

Having seen Toy Story 4 we were inspired enough to dedicate today’s blog post to all those onions out there dedicated to improving the layers of our understanding, all those “onions of the 4th dimension” out there! Because yesterday’s Ajax Auto-completion Internationalization Email Tutorial has been built upon in a couple of ways new to us (but no doubt not to a lot of ewesyouseyous (pardon my Liverpudlian)).

  • “onions of the 4th dimension” … uppercase and lowercase separation 2x multiplier of functionality … via the …
  • keyboard event “onkeypress” (better than “onkeydown” (though “onkeydown” is good for Ctrl and Alt and Shift and Del scenarios)) can differentiate uppercase to lowercase letters to Country versus Capital respectively
  • “gone fishing” part 2 … users learn by trial and error of that first keyboard letter pressed … eg. how many world capital cities start with “q”? (types of “fishing” is now, additionally, possible, as a learning aid with this web application)
  • “can an HTML element get an ID property added dynamically?” … today we find out … and answer is “yes” … this is useful to allow a programmatical click of an (Ajax created) element later
  • “can an array member be found, in full, in Javascript (ie. indexed)?” … today and yesterday we found out … and answer is “yes” … Javascript [string{MustBeObject}].indexOf([string]) function(s) (or should we say “members”) acts like C++ Object Oriented Programming style object “members” where the Object type is part of the full definition of a function (“member”) definition … so a [String].indexOf([String]) type will go to a different piece of code to an [Array].indexOf([String]) type (calling object)
  • allow for integration of inhouse Timezone Places web application, as required

Get the feel for this with the changed auto_language_complete.html live run link.


Previous relevant Ajax Auto-completion Internationalization Email Tutorial is shown below.

Ajax Auto-completion Internationalization Email Tutorial

Ajax Auto-completion Internationalization Email Tutorial

On top of the progress of yesterday’s Ajax Auto-completion Internationalization Revisit Tutorial we have a dual purpose set of improvements today, those being …

  • introduction of “long hover” functionality to the Ajax Autocompletion menus presented, whereby the Wikipedia and Google Chart optional functionalities from yesterday are “sneak previewed” for the user … which, in turn, helps with …
  • sharing email functionality in two “client email application” ways …
    1. readying a webpage that does well using the web browser Edit menu Select All and Copy options to be a useful email attachment … and a separate new …
    2. email 📧 emoji “a” mailto: link to the “client email application” for an email with one body link back to the website webpage via a ?country= argument
  • So what’s “long hover”? Well, it’s not formally an event in HTML. And it’s not a concept at all with mobile platforms. To us, a “long hover event” action item is one that only occurs when the user hovers (tripping an “onmouseover” event) over that action item for a longer than usual amount of time (and we say 2 seconds) before “moving away” (tripping an “onmouseout” event). See the new codings required to make this happen, that “setTimeout(overandout, 2000)” two second delay the crucial difference, below.

    1. within the Ajax onreadystatechange logic function …

      myTempDiv.title = myCodesArray[myi] + ';' + myThisCapital;
      myTempDiv.innerHTML = myThisCountry;
      myTempDiv.onmouseover = overmakeSelection;
      myTempDiv.onmouseout = outmakeSelection;

      myTempDiv.onclick = makeSelection;
      myTempDiv.className = "mysuggestions";

      … and then …
    2. some new Javascript functions to help this change out …

      var lhcandidate='', lhready=false, overcnt=0;
      function overandout() {
      if (lhcandidate != '' && overcnt == 1) {
      overcnt=0;
      lhready=true;
      makeSelection(null);
      }
      }

      function overmakeSelection(evt) {
      overcnt++;
      if (evt) {
      lhcandidate = evt.target;
      } else {
      lhcandidate = window.event.srcElement;
      }
      setTimeout(overandout, 2000);
      }

      function outmakeSelection(evt) {
      if (overcnt > 0) { overcnt--; }
      lhcandidate='';
      lhready=false;
      }

    … opening more scope for collaboration and sharing with this web application.

    Again, feel free to have a go at the changed auto_language_complete.html live run link.


    Previous relevant Ajax Auto-completion Internationalization Revisit Tutorial is shown below.

    Ajax Auto-completion Internationalization Revisit Tutorial

    Ajax Auto-completion Internationalization Revisit Tutorial

    Way back in 2013 we touched on AutoCompletion ideas when we presented Ajax Auto-completion Internationalization Tutorial. Quite a bit of water under bridges, and here in 2019 we feel like extending its functionalities by …

    … all “optional extras”. Remember with such new functionality it is really annoying for a user if the usual workflow of the web application is broken by your changes. We design ours today on an “only if the optional data is found” basis, so we don’t expect more than the usual complaints. That way an HTML div can be empty for “no data found”, or filled with an HTML table of three (td) cells each with an HTML iframe same-domain call of those Google Chart (1) and Wikipedia (2) inhouse interfacings.

    Feel free to have a go at the changed auto_language_complete.html live run link.


    Previous relevant Ajax Auto-completion Internationalization Tutorial is shown below.

    Ajax Auto-completion Internationalization Tutorial

    Ajax Auto-completion Internationalization Tutorial

    Yesterday’s tutorial (called PHP Gettext Internationalization Primer Tutorial) reignited something I’ve been curious about for ages … and knew it was out there … the notion of linking “country codes” to “language codes” and coming up with more informed thoughts regarding language choices … continuing on with our “internationalization” discussions of yesterday.

    We came up against this issue with the Ajax Auto-completion FollowUp Tutorial as of below, when we, lazily, only supplied a Google Translate window of “Welcome” to Country users who had a “Country Code” the same as the “Language Code”, such as Poland. However, you’ll find Poland is in the minority for this straightforward arrangement.

    So we delved into those codes (ie. locales) as of yesterday, like “de_DE” (German for Germany), and lo and behold (for two days running now … and am pretty tired on the 78th rounding of the Sydney Harbour Bridge) there are ways and means, and the biggest helping hand for us came from Zend Framework … and, by the way, Zend is an Apache framework … so, thanks.

    If you try today’s live run, then, for some countries, you’ll get multiple Google Translate “window.open()” method windows coming up, representing more of the languages spoken in that country (but of course it is not definitive, in this multivaried and fascinating woooooooorrrrrrrld on which we all cohabitate, man person).

    The use of Google Translate in this way, is great in itself with regard to translations (and sometimes an audio pronunciation possibility), as well as with written language issues such as “right to left” versus “left to right” usage.

    This whole scenario involves Ajax and auto-completion as concepts you may want to delve into as well, and if so, would recommend a perusal of all the linked tutorials below, to get the whole picture.

    On top of that, you’ll perhaps want to see the downloadable supervising HTML code you could call auto_language_complete.html (that changed from the previous venture into auto-completion as per auto_language_complete.html) which is, as of today … even though we said “Ajax … Tutorial” … supervising some newly created PHP (to help with the locales data) you could call lc_CC.php … so feel free to delve into all these “internationalization” (of language) ideas further at your leisure, and know that “internationalization” concepts cover so much more as well with issues such as “date formats” and currency formats”, just to name two, that you may want to do some research and development on, as well.


    Previous relevant Ajax Auto-completion FollowUp Tutorial
    is shown below.

    Ajax Preview Window Tutorial  (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax Auto-completion FollowUp Tutorial (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax techniques make your web pages very dynamic and useful, and there will be fewer changes of webpage required when using Ajax, because information derived from a data source (maybe a feed, maybe a database read, maybe a local source of data (as for this tutorial’s countries_attributed.xml … today, we use attributes, as distinct from yesterday’s tutorial … in source code note use of getAttribute() method … thanks to link and languages.xml … in source code note use of getAttribute() method … thanks to link … (by the way, with this last derived XML, it would be a great improvement and give more frequent lookup success to amend all the country code attributes to equal language code attributes (eg. it turns out mythical country Zolmovia (originally, code=Zm) speaks mainly Spanish (language code=es), so what am saying is change Zm to es in countries_attributed.xml) here)) make many changes of webpage obsolete.

    Today we build on Ajax Auto-completion Primer Tutorial as shown below, in that we attempt a (non 100% successful) coding relationship that tries to give a welcome message in the home language of the country you pick, via the wonderful Google Translate.

    One useful Ajax friendly piece of functionality is called auto-completion, where you have an HTML input text tag element you fill in, and you’d like to help out the user with both spelling and suggestions, so you present possibilities once they have pressed a key, and then the user can opt to pick one of the “(looks-like-a) dropdown”-listed options. This often helps with the proper nouns in our life, or, as is the case with the tutorial, country names. So we reward the user with a map courtesy of Google Maps (thanks) should it all go swimmingly (hope you’re not in Chad looking for a swim). In addition, when successful in establishing a likely home language for your country (will be sometimes wrong, sometimes unknowable with the shortcuts here, and maybe sometimes wrong (for these we apologize)).

    Have a look at the HTML/Javascript downloadable code which you could rename to auto_language_complete.html

    Here is a new link to some downloadable PHP programming source code explaining changes made (from tutorial below) here.

    Try a live run here.

    By the way, Gimp was used to make the layered image of this tutorial using techniques as explained in Gimp Layers Primer Tutorial.

    Regarding this topic I really like “JavaScript & Ajax” seventh edition by Tom Negrino and Dori Smith and the code in this book was followed closely, with small amendments.


    Previous relevant Ajax Auto-completion Primer Tutorial is shown below.

    Ajax Preview Window Tutorial  (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax Auto-completion Primer Tutorial (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax techniques make your web pages very dynamic and useful, and there will be fewer changes of webpage required when using Ajax, because information derived from a data source (maybe a feed, maybe a database read, maybe a local source of data (as for this tutorial’s countries.xml … thanks to link here)) make many changes of webpage obsolete.

    Today we more or less build on your previous Ajax knowledge (which am sure has moved along a long way from) beginning (at least, at this blog) with Ajax Preview Window Tutorial as shown below.

    Let’s have a look at Wikipedia’s thoughts on Ajax below.

    Ajax (also AJAX; /ˈeɪdʒæks/; an acronym for Asynchronous JavaScript and XML)[1] is a group of interrelated web development techniques used on the client-side to create asynchronous web applications. With Ajax, web applications can send data to, and retrieve data from, a server asynchronously (in the background) without interfering with the display and behavior of the existing page. Data can be retrieved using the XMLHttpRequest object. Despite the name, the use of XML is not required (JSON is often used instead. See AJAJ), and the requests do not need to be asynchronous.[2]

    Ajax is not a single technology, but a group of technologies. HTML and CSS can be used in combination to mark up and style information. The DOM is accessed with JavaScript to dynamically display, and allow the user to interact with, the information presented. JavaScript and the XMLHttpRequest object provide a method for exchanging data asynchronously between browser and server to avoid full page reloads.

    One useful Ajax friendly piece of functionality is called auto-completion, where you have an HTML input text tag element you fill in, and you’d like to help out the user with both spelling and suggestions, so you present possibilities once they have pressed a key, and then the user can opt to pick one of the “(looks-like-a) dropdown”-listed options. This often helps with the proper nouns in our life, or, as is the case with the tutorial, country names. So we reward the user with a map courtesy of Google Maps (thanks) should it all go swimmingly (hope you’re not in Chad looking for a swim).

    Have a look at the HTML/Javascript downloadable code which you could rename to countries_auto_complete.html
    Try a live run here.

    By the way, Gimp was used to make the layered image of this tutorial using techniques as explained in Gimp Layers Primer Tutorial.

    Regarding this topic I really like “JavaScript & Ajax” seventh edition by Tom Negrino and Dori Smith and the code in this book was followed closely, with small amendments.


    Previous relevant Ajax Preview Window Tutorial is shown below.

    Ajax Preview Window Tutorial

    Ajax Preview Window Tutorial

    Ajax is a client-side meets server-side melding of PHP (or ASP.Net) and Javascript and HTML and CSS and allows you to stay on the web page you are on doing many more things, rather than constantly changing web pages the way that HTML form tag makes you do. Ajax works with XMLHttpRequest object to quiz the server-side while staying on the client side. You may have guessed that we have been working up to this, and I refer you to the previous tutorial about JavaScript and the DOM Tutorial and PHP + JavaScript + HTML Primer Tutorial for important information to learn before tackling Ajax. Ajax shares similar restrictions to iFrames in limiting you to work within your own domain, generally speaking. Ajax normally makes use of the onmouseover (hence the amateurish added rendition of a cursor, where I was hovering over the option tag, but couldn’t take a snapshot of this … ie. too lazy to get the camera!) and onmouseout events of HTML elements and you may notice the less than ideal Internet Explorer behaviour for this Ajax code, and that is because for Internet Explorer the option tag has no onmouseover nor onmouseout event defined, so we did an awful kludge.

    Earlier tutorials …

    JavaScript is a tremendous web client-side language to learn. You may have heard of a server-side JavaScript, but this tutorial only deals with client-side work. This tutorial builds a JavaScript layer on top of the PHP tutorial made earlier, showing how the DOM can be used to change the look of your webpage dynamically, even if most of it is in an iFrame (but there are limits).

    PHP is a wonderful language to learn. It is usually associated with being a web server-side language (as with this tutorial, where it is being shown on a local MAMP web server) but can be a command line tool as well. If you like PHP you may eventually like ASP.Net and/or Python, and vice versa. It has sophisticated data structures, Object Oriented (the thinking that you can build classes with data and methods which define objects created as you run the program … eg. you might write a class for book and have data members for things like numPages and publisher, author, creationDate and have methods called things like getCreationDate, setCreationDate, getAuthor, setAuthor allowing the user to use these methods rather than changing the data members themselves … heaven forbid that!) code concepts, and really combines well with JavaScript (as a client-side language).

    Download programming source code and rename to ajax.php (but Ajax only works within the domain you use it, and this code mentions www.rjmprogramming.com.au so just use it for reference purposes or rewrite for purposes that suit you within your domain of interest).

    Regarding this topic I really like “JavaScript & Ajax” seventh edition by Tom Negrino and Dori Smith

    Did you know …
    JavaScript makes a great easy-access Calculator?

    Try typing the lines below into the address bar of your favourite browser:

    Javascript: eval(512 / 380);
    Javascript: eval(512 * 380);
    Javascript: eval(512 – 380);
    Javascript: eval(512 + 380);
    Javascript: eval(512 % 380);

    These days we spend so much time on the Internet it is a much quicker way to get to a calculator!

    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.

Posted in Ajax, eLearning, Event-Driven Programming, Trips, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Ajax Auto-completion Internationalization Capitals Tutorial

Ajax Auto-completion Internationalization Capitals Tutorial

Ajax Auto-completion Internationalization Capitals Tutorial

Having seen Toy Story 4 we were inspired enough to dedicate today’s blog post to all those onions out there dedicated to improving the layers of our understanding, all those “onions of the 4th dimension” out there! Because yesterday’s Ajax Auto-completion Internationalization Email Tutorial has been built upon in a couple of ways new to us (but no doubt not to a lot of ewesyouseyous (pardon my Liverpudlian)).

  • “onions of the 4th dimension” … uppercase and lowercase separation 2x multiplier of functionality … via the …
  • keyboard event “onkeypress” (better than “onkeydown” (though “onkeydown” is good for Ctrl and Alt and Shift and Del scenarios)) can differentiate uppercase to lowercase letters to Country versus Capital respectively
  • “gone fishing” part 2 … users learn by trial and error of that first keyboard letter pressed … eg. how many world capital cities start with “q”? (types of “fishing” is now, additionally, possible, as a learning aid with this web application)
  • “can an HTML element get an ID property added dynamically?” … today we find out … and answer is “yes” … this is useful to allow a programmatical click of an (Ajax created) element later
  • “can an array member be found, in full, in Javascript (ie. indexed)?” … today and yesterday we found out … and answer is “yes” … Javascript [string{MustBeObject}].indexOf([string]) function(s) (or should we say “members”) acts like C++ Object Oriented Programming style object “members” where the Object type is part of the full definition of a function (“member”) definition … so a [String].indexOf([String]) type will go to a different piece of code to an [Array].indexOf([String]) type (calling object)
  • allow for integration of inhouse Timezone Places web application, as required

Get the feel for this with the changed auto_language_complete.html live run link.


Previous relevant Ajax Auto-completion Internationalization Email Tutorial is shown below.

Ajax Auto-completion Internationalization Email Tutorial

Ajax Auto-completion Internationalization Email Tutorial

On top of the progress of yesterday’s Ajax Auto-completion Internationalization Revisit Tutorial we have a dual purpose set of improvements today, those being …

  • introduction of “long hover” functionality to the Ajax Autocompletion menus presented, whereby the Wikipedia and Google Chart optional functionalities from yesterday are “sneak previewed” for the user … which, in turn, helps with …
  • sharing email functionality in two “client email application” ways …
    1. readying a webpage that does well using the web browser Edit menu Select All and Copy options to be a useful email attachment … and a separate new …
    2. email 📧 emoji “a” mailto: link to the “client email application” for an email with one body link back to the website webpage via a ?country= argument
  • So what’s “long hover”? Well, it’s not formally an event in HTML. And it’s not a concept at all with mobile platforms. To us, a “long hover event” action item is one that only occurs when the user hovers (tripping an “onmouseover” event) over that action item for a longer than usual amount of time (and we say 2 seconds) before “moving away” (tripping an “onmouseout” event). See the new codings required to make this happen, that “setTimeout(overandout, 2000)” two second delay the crucial difference, below.

    1. within the Ajax onreadystatechange logic function …

      myTempDiv.title = myCodesArray[myi] + ';' + myThisCapital;
      myTempDiv.innerHTML = myThisCountry;
      myTempDiv.onmouseover = overmakeSelection;
      myTempDiv.onmouseout = outmakeSelection;

      myTempDiv.onclick = makeSelection;
      myTempDiv.className = "mysuggestions";

      … and then …
    2. some new Javascript functions to help this change out …

      var lhcandidate='', lhready=false, overcnt=0;
      function overandout() {
      if (lhcandidate != '' && overcnt == 1) {
      overcnt=0;
      lhready=true;
      makeSelection(null);
      }
      }

      function overmakeSelection(evt) {
      overcnt++;
      if (evt) {
      lhcandidate = evt.target;
      } else {
      lhcandidate = window.event.srcElement;
      }
      setTimeout(overandout, 2000);
      }

      function outmakeSelection(evt) {
      if (overcnt > 0) { overcnt--; }
      lhcandidate='';
      lhready=false;
      }

    … opening more scope for collaboration and sharing with this web application.

    Again, feel free to have a go at the changed auto_language_complete.html live run link.


    Previous relevant Ajax Auto-completion Internationalization Revisit Tutorial is shown below.

    Ajax Auto-completion Internationalization Revisit Tutorial

    Ajax Auto-completion Internationalization Revisit Tutorial

    Way back in 2013 we touched on AutoCompletion ideas when we presented Ajax Auto-completion Internationalization Tutorial. Quite a bit of water under bridges, and here in 2019 we feel like extending its functionalities by …

    … all “optional extras”. Remember with such new functionality it is really annoying for a user if the usual workflow of the web application is broken by your changes. We design ours today on an “only if the optional data is found” basis, so we don’t expect more than the usual complaints. That way an HTML div can be empty for “no data found”, or filled with an HTML table of three (td) cells each with an HTML iframe same-domain call of those Google Chart (1) and Wikipedia (2) inhouse interfacings.

    Feel free to have a go at the changed auto_language_complete.html live run link.


    Previous relevant Ajax Auto-completion Internationalization Tutorial is shown below.

    Ajax Auto-completion Internationalization Tutorial

    Ajax Auto-completion Internationalization Tutorial

    Yesterday’s tutorial (called PHP Gettext Internationalization Primer Tutorial) reignited something I’ve been curious about for ages … and knew it was out there … the notion of linking “country codes” to “language codes” and coming up with more informed thoughts regarding language choices … continuing on with our “internationalization” discussions of yesterday.

    We came up against this issue with the Ajax Auto-completion FollowUp Tutorial as of below, when we, lazily, only supplied a Google Translate window of “Welcome” to Country users who had a “Country Code” the same as the “Language Code”, such as Poland. However, you’ll find Poland is in the minority for this straightforward arrangement.

    So we delved into those codes (ie. locales) as of yesterday, like “de_DE” (German for Germany), and lo and behold (for two days running now … and am pretty tired on the 78th rounding of the Sydney Harbour Bridge) there are ways and means, and the biggest helping hand for us came from Zend Framework … and, by the way, Zend is an Apache framework … so, thanks.

    If you try today’s live run, then, for some countries, you’ll get multiple Google Translate “window.open()” method windows coming up, representing more of the languages spoken in that country (but of course it is not definitive, in this multivaried and fascinating woooooooorrrrrrrld on which we all cohabitate, man person).

    The use of Google Translate in this way, is great in itself with regard to translations (and sometimes an audio pronunciation possibility), as well as with written language issues such as “right to left” versus “left to right” usage.

    This whole scenario involves Ajax and auto-completion as concepts you may want to delve into as well, and if so, would recommend a perusal of all the linked tutorials below, to get the whole picture.

    On top of that, you’ll perhaps want to see the downloadable supervising HTML code you could call auto_language_complete.html (that changed from the previous venture into auto-completion as per auto_language_complete.html) which is, as of today … even though we said “Ajax … Tutorial” … supervising some newly created PHP (to help with the locales data) you could call lc_CC.php … so feel free to delve into all these “internationalization” (of language) ideas further at your leisure, and know that “internationalization” concepts cover so much more as well with issues such as “date formats” and currency formats”, just to name two, that you may want to do some research and development on, as well.


    Previous relevant Ajax Auto-completion FollowUp Tutorial
    is shown below.

    Ajax Preview Window Tutorial  (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax Auto-completion FollowUp Tutorial (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax techniques make your web pages very dynamic and useful, and there will be fewer changes of webpage required when using Ajax, because information derived from a data source (maybe a feed, maybe a database read, maybe a local source of data (as for this tutorial’s countries_attributed.xml … today, we use attributes, as distinct from yesterday’s tutorial … in source code note use of getAttribute() method … thanks to link and languages.xml … in source code note use of getAttribute() method … thanks to link … (by the way, with this last derived XML, it would be a great improvement and give more frequent lookup success to amend all the country code attributes to equal language code attributes (eg. it turns out mythical country Zolmovia (originally, code=Zm) speaks mainly Spanish (language code=es), so what am saying is change Zm to es in countries_attributed.xml) here)) make many changes of webpage obsolete.

    Today we build on Ajax Auto-completion Primer Tutorial as shown below, in that we attempt a (non 100% successful) coding relationship that tries to give a welcome message in the home language of the country you pick, via the wonderful Google Translate.

    One useful Ajax friendly piece of functionality is called auto-completion, where you have an HTML input text tag element you fill in, and you’d like to help out the user with both spelling and suggestions, so you present possibilities once they have pressed a key, and then the user can opt to pick one of the “(looks-like-a) dropdown”-listed options. This often helps with the proper nouns in our life, or, as is the case with the tutorial, country names. So we reward the user with a map courtesy of Google Maps (thanks) should it all go swimmingly (hope you’re not in Chad looking for a swim). In addition, when successful in establishing a likely home language for your country (will be sometimes wrong, sometimes unknowable with the shortcuts here, and maybe sometimes wrong (for these we apologize)).

    Have a look at the HTML/Javascript downloadable code which you could rename to auto_language_complete.html

    Here is a new link to some downloadable PHP programming source code explaining changes made (from tutorial below) here.

    Try a live run here.

    By the way, Gimp was used to make the layered image of this tutorial using techniques as explained in Gimp Layers Primer Tutorial.

    Regarding this topic I really like “JavaScript & Ajax” seventh edition by Tom Negrino and Dori Smith and the code in this book was followed closely, with small amendments.


    Previous relevant Ajax Auto-completion Primer Tutorial is shown below.

    Ajax Preview Window Tutorial  (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax Auto-completion Primer Tutorial (try twirling round bottom of image for a synopsis ... 'do the twirl now')

    Ajax techniques make your web pages very dynamic and useful, and there will be fewer changes of webpage required when using Ajax, because information derived from a data source (maybe a feed, maybe a database read, maybe a local source of data (as for this tutorial’s countries.xml … thanks to link here)) make many changes of webpage obsolete.

    Today we more or less build on your previous Ajax knowledge (which am sure has moved along a long way from) beginning (at least, at this blog) with Ajax Preview Window Tutorial as shown below.

    Let’s have a look at Wikipedia’s thoughts on Ajax below.

    Ajax (also AJAX; /ˈeɪdʒæks/; an acronym for Asynchronous JavaScript and XML)[1] is a group of interrelated web development techniques used on the client-side to create asynchronous web applications. With Ajax, web applications can send data to, and retrieve data from, a server asynchronously (in the background) without interfering with the display and behavior of the existing page. Data can be retrieved using the XMLHttpRequest object. Despite the name, the use of XML is not required (JSON is often used instead. See AJAJ), and the requests do not need to be asynchronous.[2]

    Ajax is not a single technology, but a group of technologies. HTML and CSS can be used in combination to mark up and style information. The DOM is accessed with JavaScript to dynamically display, and allow the user to interact with, the information presented. JavaScript and the XMLHttpRequest object provide a method for exchanging data asynchronously between browser and server to avoid full page reloads.

    One useful Ajax friendly piece of functionality is called auto-completion, where you have an HTML input text tag element you fill in, and you’d like to help out the user with both spelling and suggestions, so you present possibilities once they have pressed a key, and then the user can opt to pick one of the “(looks-like-a) dropdown”-listed options. This often helps with the proper nouns in our life, or, as is the case with the tutorial, country names. So we reward the user with a map courtesy of Google Maps (thanks) should it all go swimmingly (hope you’re not in Chad looking for a swim).

    Have a look at the HTML/Javascript downloadable code which you could rename to countries_auto_complete.html
    Try a live run here.

    By the way, Gimp was used to make the layered image of this tutorial using techniques as explained in Gimp Layers Primer Tutorial.

    Regarding this topic I really like “JavaScript & Ajax” seventh edition by Tom Negrino and Dori Smith and the code in this book was followed closely, with small amendments.


    Previous relevant Ajax Preview Window Tutorial is shown below.

    Ajax Preview Window Tutorial

    Ajax Preview Window Tutorial

    Ajax is a client-side meets server-side melding of PHP (or ASP.Net) and Javascript and HTML and CSS and allows you to stay on the web page you are on doing many more things, rather than constantly changing web pages the way that HTML form tag makes you do. Ajax works with XMLHttpRequest object to quiz the server-side while staying on the client side. You may have guessed that we have been working up to this, and I refer you to the previous tutorial about JavaScript and the DOM Tutorial and PHP + JavaScript + HTML Primer Tutorial for important information to learn before tackling Ajax. Ajax shares similar restrictions to iFrames in limiting you to work within your own domain, generally speaking. Ajax normally makes use of the onmouseover (hence the amateurish added rendition of a cursor, where I was hovering over the option tag, but couldn’t take a snapshot of this … ie. too lazy to get the camera!) and onmouseout events of HTML elements and you may notice the less than ideal Internet Explorer behaviour for this Ajax code, and that is because for Internet Explorer the option tag has no onmouseover nor onmouseout event defined, so we did an awful kludge.

    Earlier tutorials …

    JavaScript is a tremendous web client-side language to learn. You may have heard of a server-side JavaScript, but this tutorial only deals with client-side work. This tutorial builds a JavaScript layer on top of the PHP tutorial made earlier, showing how the DOM can be used to change the look of your webpage dynamically, even if most of it is in an iFrame (but there are limits).

    PHP is a wonderful language to learn. It is usually associated with being a web server-side language (as with this tutorial, where it is being shown on a local MAMP web server) but can be a command line tool as well. If you like PHP you may eventually like ASP.Net and/or Python, and vice versa. It has sophisticated data structures, Object Oriented (the thinking that you can build classes with data and methods which define objects created as you run the program … eg. you might write a class for book and have data members for things like numPages and publisher, author, creationDate and have methods called things like getCreationDate, setCreationDate, getAuthor, setAuthor allowing the user to use these methods rather than changing the data members themselves … heaven forbid that!) code concepts, and really combines well with JavaScript (as a client-side language).

    Download programming source code and rename to ajax.php (but Ajax only works within the domain you use it, and this code mentions www.rjmprogramming.com.au so just use it for reference purposes or rewrite for purposes that suit you within your domain of interest).

    Regarding this topic I really like “JavaScript & Ajax” seventh edition by Tom Negrino and Dori Smith

    Did you know …
    JavaScript makes a great easy-access Calculator?

    Try typing the lines below into the address bar of your favourite browser:

    Javascript: eval(512 / 380);
    Javascript: eval(512 * 380);
    Javascript: eval(512 – 380);
    Javascript: eval(512 + 380);
    Javascript: eval(512 % 380);

    These days we spend so much time on the Internet it is a much quicker way to get to a calculator!

    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.

Posted in Ajax, eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment