Other Side of the World Reworked Onkeydown Tutorial

Other Side of the World Reworked Onkeydown Tutorial

Other Side of the World Reworked Onkeydown Tutorial

What’s onkeydown? Well, it’s only our favourite keyboard event (of all time), facilitating web application “hotkey” logics that get given that “autocomplete” modern day moniker. The “hotkey” thinking is that at every keyboard character pressed logic follows, regarding an HTML input element textbox (for example), acting as though what you have collected from the user so far should be tested in a similar way to the “onblur” event logics would test those inputs as the user uses the Return key (or some other way) to say they are leaving the focus of the textbox concerned.

Yeah, but what if the user dithers and retakes, etcetera etcetera etcetera.

… we hear three of you say?! Yes, that’s difficult to code for, and we’re not pretending onkeydown hotkey thinking is more accurate than onblur “end of keyboard action” thinking … how could it be? But “hotkey” user entry logic is based on convenience. If it can be established that looking through the timezone places lowercase list looking for the forward slash plus the user’s lowercase entered “hotkey” characters is found twice, then you can glean a unique place that suits, and fill in the data ahead of the user having to complete the keyboard task (and arrive at the “onblur” event to come) later.

And so, there is some satisfaction adding …


// Global variables declared ...
var okdv='', lastkplace='';

// Dynamically added onkeydown "hotkey" character logic to textbox at appropriate time ...
document.getElementById('place').onkeydown=function(event){ okd(event); };

// Using ...
function okd(e){
var charx = e.which || e.keyCode;
var thisiso='', thiscountry='';
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
charx=charx;
} else if (eval('' + e.keyCode) >= 65 && eval('' + e.keyCode) <= 90) {
okdv+=String.fromCharCode(eval('' + e.keyCode));

} else if (('z' + okdv).slice(-1) != ' ' && okdv != '') {
okdv+=' ';
}
if (eval('' + okdv.length) > 2) {
//document.title=okdv;
if (eval('' + ourtzlist.toLowerCase().split('/' + okdv.replace(/\ /g,'_').toLowerCase()).length) == 3) {
//alert(evt.target.value + ourtzlist.toLowerCase().split('/' + evt.target.value.toLowerCase())[1].split('"')[0]);
lastkplace=ourtzlist.substring(eval(1 + ourtzlist.toLowerCase().split('/' + okdv.replace(/\ /g,'_').toLowerCase())[0].length)).split('"')[0].replace(/\_/g,' ');
document.getElementById('place').value=lastkplace;
setTimeout(function(){
document.getElementById('place').value=lastkplace;
}, 1000);
//alert(evt.target.value);
document.getElementById('latitude').value=ourtzlist.toLowerCase().split('/' + okdv.replace(/\ /g,'_').toLowerCase())[1].split('"')[2].split(',')[0];
document.getElementById('longitude').value=ourtzlist.toLowerCase().split('/' + okdv.replace(/\ /g,'_').toLowerCase())[1].split('"')[2].split(',')[1];
thisiso=ourtzlist.toUpperCase().split('/' + okdv.replace(/\ /g,'_').toUpperCase())[1].split('"')[2].split(',')[3];
thiscountry=nearfind(thisiso);
document.getElementById('place').title=thiscountry;
document.getElementById('sfrom').title=thiscountry;
document.getElementById('sto').title=thiscountry;
document.getElementById('place').setAttribute('data-iso',thisiso);
document.getElementById('place').setAttribute('data-country',thiscountry);
newafters(document.getElementById('place').value.replace(/\ /g,'_'), thisiso, thiscountry);
}
}
}

… these “mild smarts” onto yesterday’s Other Side of the World Reworked Lookups Tutorial‘s progress.

But more progress also happens at that “onblur” event logic talked about above. Just to consider timezone places is a bit restrictive. Maybe, Wikipedia (thanks) lookups can help glean geographical data for some entered placenames. As you can imagine, for this aspect to improvements, those lookups can only happen as the user has completed their keyboard endeavours … hence, the intervention point being the “onblur” event logics.

And along the way we add in some crow-flying distances into the mix of what, for non-mobile users, is displayed as they hover over dropdown option placenames.

Yet again, the changed other_side_of_the_world.htm‘s live run is there for you to try yourself.


Previous relevant Other Side of the World Reworked Lookups Tutorial is shown below.

Other Side of the World Reworked Lookups Tutorial

Other Side of the World Reworked Lookups Tutorial

The way the “Other Side of the World” web application from Other Side of the World Reworked Dropdowns Tutorial arranged its …

  • autocomplete … Javascript logic … was via a …
  • free Weather API … called Weather Underground API … but, today, we redesign … to start using …
  • inhouse geographical lookups

… and with today’s start on this new arrangement, we use, again

  • timezone data … PHP derived … from which we can glean …
  • data items …
    1. timezone name … containing the place name …
    2. latitude and longitude geographicals
    3. ISO-3166 2 letter country codes

    … from which we can derive a country name, via the 2 letter code

… starting out just with an “onblur” textbox element response today, with this draft of changes …


var ourtzlist="... blah de blah ...";
var icc=['AF','Afghanistan',
'AX','Aland Islands',
'AL','Albania',
'DZ','Algeria',
'AS','American Samoa',
'AD','Andorra',
... blah de blah ...
];

function oosel(seloo) {
thatiso=('' + seloo.options[seloo.selectedIndex].getAttribute('data-iso')).replace(/^null/g,'').replace(/^undefined/g,'');
thatcountry=nearfind(thatiso);
if (thatcountry == '') {
document.getElementById('place').setAttribute('data-iso', thatiso);
document.getElementById('place').setAttribute('data-country', thatcountry);
document.getElementById('place').title=thatcountry;
document.getElementById('sfrom').title=thatcountry;
document.getElementById('sto').title=thatcountry;
} else {
document.getElementById('place').setAttribute('data-iso', thatiso);
document.getElementById('place').setAttribute('data-country', thatcountry);
document.getElementById('place').title=thatcountry;
document.getElementById('sfrom').title=thatcountry;
document.getElementById('sto').title=thatcountry;
}
return seloo;
}

function nearfind(isoidea) {
if (isoidea == '') { return ""; }
for (var imm=0; imm<icc.length; imm+=2) {
if (isoidea.toLowerCase().replace(/\_/g,' ') == icc[imm].toLowerCase().replace(/\_/g,' ')) {
return icc[eval(1 + imm)].replace("'", "`");
}
}
return "";
}

function newafters(evttargetvalue, thisiso, thiscountry) {
var ivsll=1;
var sofarnear=';', sofarnearother=';', nearcountry='', nearothercountry='', neariso='', nearotheriso='';
var inlat=eval('' + document.getElementById('latitude').value), fone=true, distnear=-200.0, distother=-200.0, nearplace='', nearotherplace='', nearlat=-200.0, nearlong=-200.0, nearotherlat=-200.0, nearotherlong=-200.0;
var inlong=eval('' + document.getElementById('longitude').value);
var inlatoe=eval(-inlat), inlongoe=(eval(inlong) < 0.0 ? eval(180.000000 + (inlong)) : eval(inlong - 180.0));
var vsll=ourtzlist.split(' data-geo="');


if (thiscountry != '') {
//alert(thiscountry);
document.getElementById('sfrom').innerHTML=document.getElementById('sfrom').innerHTML.split('</option>')[0].split(' to ')[0] + ' to ' + evttargetvalue.replace(/\_/g,' ') + ', ' + thiscountry + ' ...</option>';
document.getElementById('sto').innerHTML=document.getElementById('sto').innerHTML.split('</option>')[0].split(' World to ')[0] + ' World to ' + evttargetvalue.replace(/\_/g,' ') + ', ' + thiscountry + ' ...</option>';
} else {
document.getElementById('sfrom').innerHTML=document.getElementById('sfrom').innerHTML.split('</option>')[0].split(' to ')[0] + ' to ' + evttargetvalue.replace(/\_/g,' ') + ' ...</option>';
document.getElementById('sto').innerHTML=document.getElementById('sto').innerHTML.split('</option>')[0].split(' World to ')[0] + ' World to ' + evttargetvalue.replace(/\_/g,' ') + ' ...</option>';
}
document.body.style.cursor='progress';
document.getElementById('place').style.cursor='progress';
for (var iii=0; iii<5; iii++) {
//alert('here ' + iii);
for (ivsll=1; ivsll<vsll.length; ivsll++) {
if (vsll[ivsll].split('>')[1].split('<')[0].indexOf('/') != -1 && vsll[ivsll].split('>')[1].split('<')[0].indexOf('/' + evttargetvalue.replace(/\ /g,'_') + '') == -1) {
if (fone) {
fone=false;
nearplace=vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ');
nearotherplace=vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ');
nearlat=eval(vsll[ivsll].split(',')[0]);
nearotherlat=eval(vsll[ivsll].split(',')[0]);
nearlong=eval(vsll[ivsll].split(',')[1]);
neariso=(vsll[ivsll].split(',')[3]);
nearotherlong=eval(vsll[ivsll].split(',')[1]);
nearotheriso=(vsll[ivsll].split(',')[3]);
distnear=eval(Math.abs(nearlat - inlat) + Math.abs(nearlong - inlong));
distother=eval(Math.abs(nearotherlat - inlatoe) + Math.abs(nearotherlong - inlongoe));
//alert(distnear);
} else {
if (sofarnear.indexOf(';' + vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ') + ';') == -1 && distnear > eval(Math.abs(eval(vsll[ivsll].split(',')[0]) - inlat) + Math.abs(eval(vsll[ivsll].split(',')[1]) - inlong))) {
nearplace=vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ');
nearlat=eval(vsll[ivsll].split(',')[0]);
nearlong=eval(vsll[ivsll].split(',')[1]);
neariso=(vsll[ivsll].split(',')[3]);
distnear=eval(Math.abs(nearlat - inlat) + Math.abs(nearlong - inlong));
}
if (sofarnearother.indexOf(';' + vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ') + ';') == -1 && distother > eval(Math.abs(eval(vsll[ivsll].split(',')[0]) - inlatoe) + Math.abs(eval(vsll[ivsll].split(',')[1]) - inlongoe))) {
nearotherplace=vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ');
nearotherlat=eval(vsll[ivsll].split(',')[0]);
nearotherlong=eval(vsll[ivsll].split(',')[1]);
nearotheriso=(vsll[ivsll].split(',')[3]);
distother=eval(Math.abs(nearotherlat - inlatoe) + Math.abs(nearotherlong - inlongoe));
}
}
}
}
nearcountry=nearfind(neariso);
nearothercountry=nearfind(nearotheriso);
document.getElementById('sfrom').innerHTML+='<option title="' + nearcountry + '" data-iso="' + neariso + '" data-cname="' + nearcountry + '" value="' + nearlat + ',' + nearlong + '">' + nearplace + '</option>';
document.getElementById('sto').innerHTML+='<option title="' + nearothercountry + '" data-iso="' + nearotheriso + '" data-cname="' + nearothercountry + '" value="' + nearotherlat + ',' + nearotherlong + '">' + nearotherplace + '</option>';
sofarnear+=nearplace.replace(/\_/g,' ') + ';';
sofarnearother+=nearotherplace.replace(/\_/g,' ') + ';';
//alert('iii=' + iii + ' and sofarnearother=' + sofarnearother);
fone=true;
distnear=-200.0;
distother=-200.0;
nearplace='';
nearotherplace='';
nearcountry='';
nearothercountry='';
neariso='';
nearotheriso='';
nearlat=-200.0;
nearlong=-200.0;
nearotherlat=-200.0;
nearotherlong=-200.0;
}
//alert(document.getElementById('sto').innerHTML);
document.getElementById('place').style.cursor='pointer';
document.body.style.cursor='pointer';


document.getElementById('place').value=evttargetvalue.replace(/\_/g,' ');
}

function newway(evt) {
var thisiso='', thiscountry='';
if (evt.target.value.trim() != '' && eval('' + evt.target.value.length) > 1) {
if (eval('' + ourtzlist.toLowerCase().split('/' + evt.target.value.replace(/\ /g,'_').toLowerCase()).length) == 3) {
//alert(evt.target.value + ourtzlist.toLowerCase().split('/' + evt.target.value.toLowerCase())[1].split('"')[0]);
evt.target.value=ourtzlist.substring(eval(1 + ourtzlist.toLowerCase().split('/' + evt.target.value.replace(/\ /g,'_').toLowerCase())[0].length)).split('"')[0].replace(/\_/g,' ');
//alert(evt.target.value);
document.getElementById('latitude').value=ourtzlist.toLowerCase().split('/' + evt.target.value.replace(/\ /g,'_').toLowerCase())[1].split('"')[2].split(',')[0];
document.getElementById('longitude').value=ourtzlist.toLowerCase().split('/' + evt.target.value.replace(/\ /g,'_').toLowerCase())[1].split('"')[2].split(',')[1];
thisiso=ourtzlist.toUpperCase().split('/' + evt.target.value.replace(/\ /g,'_').toUpperCase())[1].split('"')[2].split(',')[3];
thiscountry=nearfind(thisiso);
document.getElementById('place').title=thiscountry;
document.getElementById('sfrom').title=thiscountry;
document.getElementById('sto').title=thiscountry;
document.getElementById('place').setAttribute('data-iso',thisiso);
document.getElementById('place').setAttribute('data-country',thiscountry);
newafters(evt.target.value.replace(/\ /g,'_'), thisiso, thiscountry);

// distfrom[eval(-1 + jplace)]=Math.floor(great_circle_distance(inlat, inlong, ylat[eval(-1 + jplace)], xlong[eval(-1 + jplace)]));
// distto[eval(-1 + jplace)]=Math.floor(great_circle_distance(inlatoe, inlongoe, ylat[eval(-1 + jplace)], xlong[eval(-1 + jplace)]));

//var placebits=cols[0].split('/'), aname='';
//for (var ival=eval(-1 + placebits.length); ival>=0; ival--) {
// if (aname == '') {
// aname=placebits[ival];
// } else {
// aname+=', ' + placebits[ival];
// }
//}
document.getElementById('place').value=evt.target.value.replace(/\_/g,' '); //noslash(sio.options[sio.selectedIndex].text); //aname;
if (1 == 3) {
totalmore();
wthere=true;
showit(null);
newtpz();
wthere=false;
}
document.getElementById('mysb').click();
}
}
}

And so, yet again, a changed other_side_of_the_world.htm‘s live run is there for you to try yourself.


Previous relevant Other Side of the World Reworked Dropdowns Tutorial is shown below.

Other Side of the World Reworked Dropdowns Tutorial

Other Side of the World Reworked Dropdowns Tutorial

Continuing on from Other Side of the World Reworked Logic Tutorial‘s first rearrangements at the lack of access to a weather (and its associated placename) API database we turn to that top dropdown (ie. HTML select element), with its …

  • hour of day (ie. pointing at a timezone)
  • country

… options, and try to make it easier for the user to populate those latitude and longitude fields, then on to other map and video information, data flows.

These changes, amongst other things, calls on HTML iframe onload usage


<iframe onload="gountil(this);" id="irandoms" src="//www.rjmprogramming.com.au/PHP/tz_places.php" title="Randoms" style="display:none;"></iframe>

… and associated Javascript …


function srandoms() {
if (lokf == lastlokf.trim() && lokf != '') {
document.getElementById('irandoms').src=document.getElementById('irandoms').src.split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765432);
}
}

function gountil(iois) {
if (iois != null) {
aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
if (lokf != '') {
if (aconto.body.innerHTML.indexOf(lokf) == -1) {
setTimeout(srandoms, 5000); //iois.src=iois.src.split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765432);
} else if (aconto.body.innerHTML.indexOf(': ') != -1) {
document.getElementById('place').value=decodeURIComponent(aconto.body.innerHTML.split(lokf)[1].split(': ')[0].split('&')[0]).trim().split(',')[0]; // .split('max-width')[1].split('</td>')[0].replace(/\ \;/g,' ').replace(/\:/g,' ').trim().split(' ')[eval(-1 + aconto.body.innerHTML.split('max-width')[1].split('</td>')[0].replace(/\ \;/g,' ').replace(/\:/g,' ').trim().split(' ').length)].split(',')[0];
totalmore();
ourprewbit();
setTimeout(sfromit, 4000);
}
}
}
}
}
}

… and associated emoji country flag (via ISO 2 character country code, off the dropdown) Javascript logic …


var lokf='', lastlokf='';

if (!String.fromCodePoint) { // thanks to http://xahlee.info/js/js_unicode_code_point.html
// ES6 Unicode Shims 0.1 , © 2012 Steven Levithan , MIT License
String.fromCodePoint = function fromCodePoint () {
var chars = [], point, offset, units, i;
for (i = 0; i < arguments.length; ++i) {
point = arguments[i];
offset = point - 0x10000;
units = point > 0xFFFF ? [0xD800 + (offset >> 10), 0xDC00 + (offset & 0x3FF)] : [point];
chars.push(String.fromCharCode.apply(null, units));
}
return chars.join("");
}
}

function worflag(thiscc) {
var ccchar="", ccsuff="";
var lri="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var dri=["127462","127463","127464","127465","127466","127467","127468","127469","127470","127471","127472","127473","127474","127475","127476","127477","127478","127479","127480","127481","127482","127483","127484","127485","127486","127487"];
for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
ccsuff+=String.fromCodePoint(eval('' + dri[eval('' + lri.indexOf(ccchar))])); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
}
return ccsuff;
}

And so, again, a changed other_side_of_the_world.htm‘s live run calls on autocomplete.htm (which supervises Wunderground API data calling) changed in this way to offer that alternative means to an end, with dropdown logic improvements.


Previous relevant Other Side of the World Reworked Logic Tutorial is shown below.

Other Side of the World Reworked Logic Tutorial

Other Side of the World Reworked Logic Tutorial

You may recall in the recent Audio and Video Creator via Media Browsing Image Background Email Tutorial how we had a link …

on the other side of the wooooooorrrrrlllllddd

… which got us to our “Other Side of the World” web application. Well, some of the workings of that web application function best when the Weather Underground weather API’s autocomplete functionality is working. Alas, it is not (with us any more) … prescient, indeed, after the recent HTML Map Element SVG Context Google Search Tutorial‘s …

When including URLs away from the domain (ie. “third party”) on which your webpage resides then you are at risk, over time, when it comes to using URLs optionally involving arguments delimited by ? (first) and (subsequent) & (what we call the “GET” arguments) optionally delimited by # before a hashtag that used to work, but may stop working into the future.

We cannot replace the data lost regarding Weather and Placename lists from this, but we can thank Wikipedia, yet again, to help us link a single Placename with a single Geographical (Latitude, Longitude) geodata set that can match to those two HTML input elements for latitude and longitude, to improve the situation.

And so a changed other_side_of_the_world.htm‘s live run calls on autocomplete.htm (which supervises Wunderground API data calling) changed in this way to offer that alternative means to an end.

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

Other Side of the World Reworked Lookups Tutorial

Other Side of the World Reworked Lookups Tutorial

Other Side of the World Reworked Lookups Tutorial

The way the “Other Side of the World” web application from Other Side of the World Reworked Dropdowns Tutorial arranged its …

  • autocomplete … Javascript logic … was via a …
  • free Weather API … called Weather Underground API … but, today, we redesign … to start using …
  • inhouse geographical lookups

… and with today’s start on this new arrangement, we use, again

  • timezone data … PHP derived … from which we can glean …
  • data items …
    1. timezone name … containing the place name …
    2. latitude and longitude geographicals
    3. ISO-3166 2 letter country codes

    … from which we can derive a country name, via the 2 letter code

… starting out just with an “onblur” textbox element response today, with this draft of changes …


var ourtzlist="... blah de blah ...";
var icc=['AF','Afghanistan',
'AX','Aland Islands',
'AL','Albania',
'DZ','Algeria',
'AS','American Samoa',
'AD','Andorra',
... blah de blah ...
];

function oosel(seloo) {
thatiso=('' + seloo.options[seloo.selectedIndex].getAttribute('data-iso')).replace(/^null/g,'').replace(/^undefined/g,'');
thatcountry=nearfind(thatiso);
if (thatcountry == '') {
document.getElementById('place').setAttribute('data-iso', thatiso);
document.getElementById('place').setAttribute('data-country', thatcountry);
document.getElementById('place').title=thatcountry;
document.getElementById('sfrom').title=thatcountry;
document.getElementById('sto').title=thatcountry;
} else {
document.getElementById('place').setAttribute('data-iso', thatiso);
document.getElementById('place').setAttribute('data-country', thatcountry);
document.getElementById('place').title=thatcountry;
document.getElementById('sfrom').title=thatcountry;
document.getElementById('sto').title=thatcountry;
}
return seloo;
}

function nearfind(isoidea) {
if (isoidea == '') { return ""; }
for (var imm=0; imm<icc.length; imm+=2) {
if (isoidea.toLowerCase().replace(/\_/g,' ') == icc[imm].toLowerCase().replace(/\_/g,' ')) {
return icc[eval(1 + imm)].replace("'", "`");
}
}
return "";
}

function newafters(evttargetvalue, thisiso, thiscountry) {
var ivsll=1;
var sofarnear=';', sofarnearother=';', nearcountry='', nearothercountry='', neariso='', nearotheriso='';
var inlat=eval('' + document.getElementById('latitude').value), fone=true, distnear=-200.0, distother=-200.0, nearplace='', nearotherplace='', nearlat=-200.0, nearlong=-200.0, nearotherlat=-200.0, nearotherlong=-200.0;
var inlong=eval('' + document.getElementById('longitude').value);
var inlatoe=eval(-inlat), inlongoe=(eval(inlong) < 0.0 ? eval(180.000000 + (inlong)) : eval(inlong - 180.0));
var vsll=ourtzlist.split(' data-geo="');


if (thiscountry != '') {
//alert(thiscountry);
document.getElementById('sfrom').innerHTML=document.getElementById('sfrom').innerHTML.split('</option>')[0].split(' to ')[0] + ' to ' + evttargetvalue.replace(/\_/g,' ') + ', ' + thiscountry + ' ...</option>';
document.getElementById('sto').innerHTML=document.getElementById('sto').innerHTML.split('</option>')[0].split(' World to ')[0] + ' World to ' + evttargetvalue.replace(/\_/g,' ') + ', ' + thiscountry + ' ...</option>';
} else {
document.getElementById('sfrom').innerHTML=document.getElementById('sfrom').innerHTML.split('</option>')[0].split(' to ')[0] + ' to ' + evttargetvalue.replace(/\_/g,' ') + ' ...</option>';
document.getElementById('sto').innerHTML=document.getElementById('sto').innerHTML.split('</option>')[0].split(' World to ')[0] + ' World to ' + evttargetvalue.replace(/\_/g,' ') + ' ...</option>';
}
document.body.style.cursor='progress';
document.getElementById('place').style.cursor='progress';
for (var iii=0; iii<5; iii++) {
//alert('here ' + iii);
for (ivsll=1; ivsll<vsll.length; ivsll++) {
if (vsll[ivsll].split('>')[1].split('<')[0].indexOf('/') != -1 && vsll[ivsll].split('>')[1].split('<')[0].indexOf('/' + evttargetvalue.replace(/\ /g,'_') + '') == -1) {
if (fone) {
fone=false;
nearplace=vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ');
nearotherplace=vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ');
nearlat=eval(vsll[ivsll].split(',')[0]);
nearotherlat=eval(vsll[ivsll].split(',')[0]);
nearlong=eval(vsll[ivsll].split(',')[1]);
neariso=(vsll[ivsll].split(',')[3]);
nearotherlong=eval(vsll[ivsll].split(',')[1]);
nearotheriso=(vsll[ivsll].split(',')[3]);
distnear=eval(Math.abs(nearlat - inlat) + Math.abs(nearlong - inlong));
distother=eval(Math.abs(nearotherlat - inlatoe) + Math.abs(nearotherlong - inlongoe));
//alert(distnear);
} else {
if (sofarnear.indexOf(';' + vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ') + ';') == -1 && distnear > eval(Math.abs(eval(vsll[ivsll].split(',')[0]) - inlat) + Math.abs(eval(vsll[ivsll].split(',')[1]) - inlong))) {
nearplace=vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ');
nearlat=eval(vsll[ivsll].split(',')[0]);
nearlong=eval(vsll[ivsll].split(',')[1]);
neariso=(vsll[ivsll].split(',')[3]);
distnear=eval(Math.abs(nearlat - inlat) + Math.abs(nearlong - inlong));
}
if (sofarnearother.indexOf(';' + vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ') + ';') == -1 && distother > eval(Math.abs(eval(vsll[ivsll].split(',')[0]) - inlatoe) + Math.abs(eval(vsll[ivsll].split(',')[1]) - inlongoe))) {
nearotherplace=vsll[ivsll].split('>')[1].split('<')[0].split('/')[eval(-1 + vsll[ivsll].split('>')[1].split('<')[0].split('/').length)].replace(/\_/g, ' ');
nearotherlat=eval(vsll[ivsll].split(',')[0]);
nearotherlong=eval(vsll[ivsll].split(',')[1]);
nearotheriso=(vsll[ivsll].split(',')[3]);
distother=eval(Math.abs(nearotherlat - inlatoe) + Math.abs(nearotherlong - inlongoe));
}
}
}
}
nearcountry=nearfind(neariso);
nearothercountry=nearfind(nearotheriso);
document.getElementById('sfrom').innerHTML+='<option title="' + nearcountry + '" data-iso="' + neariso + '" data-cname="' + nearcountry + '" value="' + nearlat + ',' + nearlong + '">' + nearplace + '</option>';
document.getElementById('sto').innerHTML+='<option title="' + nearothercountry + '" data-iso="' + nearotheriso + '" data-cname="' + nearothercountry + '" value="' + nearotherlat + ',' + nearotherlong + '">' + nearotherplace + '</option>';
sofarnear+=nearplace.replace(/\_/g,' ') + ';';
sofarnearother+=nearotherplace.replace(/\_/g,' ') + ';';
//alert('iii=' + iii + ' and sofarnearother=' + sofarnearother);
fone=true;
distnear=-200.0;
distother=-200.0;
nearplace='';
nearotherplace='';
nearcountry='';
nearothercountry='';
neariso='';
nearotheriso='';
nearlat=-200.0;
nearlong=-200.0;
nearotherlat=-200.0;
nearotherlong=-200.0;
}
//alert(document.getElementById('sto').innerHTML);
document.getElementById('place').style.cursor='pointer';
document.body.style.cursor='pointer';


document.getElementById('place').value=evttargetvalue.replace(/\_/g,' ');
}

function newway(evt) {
var thisiso='', thiscountry='';
if (evt.target.value.trim() != '' && eval('' + evt.target.value.length) > 1) {
if (eval('' + ourtzlist.toLowerCase().split('/' + evt.target.value.replace(/\ /g,'_').toLowerCase()).length) == 3) {
//alert(evt.target.value + ourtzlist.toLowerCase().split('/' + evt.target.value.toLowerCase())[1].split('"')[0]);
evt.target.value=ourtzlist.substring(eval(1 + ourtzlist.toLowerCase().split('/' + evt.target.value.replace(/\ /g,'_').toLowerCase())[0].length)).split('"')[0].replace(/\_/g,' ');
//alert(evt.target.value);
document.getElementById('latitude').value=ourtzlist.toLowerCase().split('/' + evt.target.value.replace(/\ /g,'_').toLowerCase())[1].split('"')[2].split(',')[0];
document.getElementById('longitude').value=ourtzlist.toLowerCase().split('/' + evt.target.value.replace(/\ /g,'_').toLowerCase())[1].split('"')[2].split(',')[1];
thisiso=ourtzlist.toUpperCase().split('/' + evt.target.value.replace(/\ /g,'_').toUpperCase())[1].split('"')[2].split(',')[3];
thiscountry=nearfind(thisiso);
document.getElementById('place').title=thiscountry;
document.getElementById('sfrom').title=thiscountry;
document.getElementById('sto').title=thiscountry;
document.getElementById('place').setAttribute('data-iso',thisiso);
document.getElementById('place').setAttribute('data-country',thiscountry);
newafters(evt.target.value.replace(/\ /g,'_'), thisiso, thiscountry);

// distfrom[eval(-1 + jplace)]=Math.floor(great_circle_distance(inlat, inlong, ylat[eval(-1 + jplace)], xlong[eval(-1 + jplace)]));
// distto[eval(-1 + jplace)]=Math.floor(great_circle_distance(inlatoe, inlongoe, ylat[eval(-1 + jplace)], xlong[eval(-1 + jplace)]));

//var placebits=cols[0].split('/'), aname='';
//for (var ival=eval(-1 + placebits.length); ival>=0; ival--) {
// if (aname == '') {
// aname=placebits[ival];
// } else {
// aname+=', ' + placebits[ival];
// }
//}
document.getElementById('place').value=evt.target.value.replace(/\_/g,' '); //noslash(sio.options[sio.selectedIndex].text); //aname;
if (1 == 3) {
totalmore();
wthere=true;
showit(null);
newtpz();
wthere=false;
}
document.getElementById('mysb').click();
}
}
}

And so, yet again, a changed other_side_of_the_world.htm‘s live run is there for you to try yourself.


Previous relevant Other Side of the World Reworked Dropdowns Tutorial is shown below.

Other Side of the World Reworked Dropdowns Tutorial

Other Side of the World Reworked Dropdowns Tutorial

Continuing on from Other Side of the World Reworked Logic Tutorial‘s first rearrangements at the lack of access to a weather (and its associated placename) API database we turn to that top dropdown (ie. HTML select element), with its …

  • hour of day (ie. pointing at a timezone)
  • country

… options, and try to make it easier for the user to populate those latitude and longitude fields, then on to other map and video information, data flows.

These changes, amongst other things, calls on HTML iframe onload usage


<iframe onload="gountil(this);" id="irandoms" src="//www.rjmprogramming.com.au/PHP/tz_places.php" title="Randoms" style="display:none;"></iframe>

… and associated Javascript …


function srandoms() {
if (lokf == lastlokf.trim() && lokf != '') {
document.getElementById('irandoms').src=document.getElementById('irandoms').src.split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765432);
}
}

function gountil(iois) {
if (iois != null) {
aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
if (lokf != '') {
if (aconto.body.innerHTML.indexOf(lokf) == -1) {
setTimeout(srandoms, 5000); //iois.src=iois.src.split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765432);
} else if (aconto.body.innerHTML.indexOf(': ') != -1) {
document.getElementById('place').value=decodeURIComponent(aconto.body.innerHTML.split(lokf)[1].split(': ')[0].split('&')[0]).trim().split(',')[0]; // .split('max-width')[1].split('</td>')[0].replace(/\ \;/g,' ').replace(/\:/g,' ').trim().split(' ')[eval(-1 + aconto.body.innerHTML.split('max-width')[1].split('</td>')[0].replace(/\ \;/g,' ').replace(/\:/g,' ').trim().split(' ').length)].split(',')[0];
totalmore();
ourprewbit();
setTimeout(sfromit, 4000);
}
}
}
}
}
}

… and associated emoji country flag (via ISO 2 character country code, off the dropdown) Javascript logic …


var lokf='', lastlokf='';

if (!String.fromCodePoint) { // thanks to http://xahlee.info/js/js_unicode_code_point.html
// ES6 Unicode Shims 0.1 , © 2012 Steven Levithan , MIT License
String.fromCodePoint = function fromCodePoint () {
var chars = [], point, offset, units, i;
for (i = 0; i < arguments.length; ++i) {
point = arguments[i];
offset = point - 0x10000;
units = point > 0xFFFF ? [0xD800 + (offset >> 10), 0xDC00 + (offset & 0x3FF)] : [point];
chars.push(String.fromCharCode.apply(null, units));
}
return chars.join("");
}
}

function worflag(thiscc) {
var ccchar="", ccsuff="";
var lri="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var dri=["127462","127463","127464","127465","127466","127467","127468","127469","127470","127471","127472","127473","127474","127475","127476","127477","127478","127479","127480","127481","127482","127483","127484","127485","127486","127487"];
for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
ccsuff+=String.fromCodePoint(eval('' + dri[eval('' + lri.indexOf(ccchar))])); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
}
return ccsuff;
}

And so, again, a changed other_side_of_the_world.htm‘s live run calls on autocomplete.htm (which supervises Wunderground API data calling) changed in this way to offer that alternative means to an end, with dropdown logic improvements.


Previous relevant Other Side of the World Reworked Logic Tutorial is shown below.

Other Side of the World Reworked Logic Tutorial

Other Side of the World Reworked Logic Tutorial

You may recall in the recent Audio and Video Creator via Media Browsing Image Background Email Tutorial how we had a link …

on the other side of the wooooooorrrrrlllllddd

… which got us to our “Other Side of the World” web application. Well, some of the workings of that web application function best when the Weather Underground weather API’s autocomplete functionality is working. Alas, it is not (with us any more) … prescient, indeed, after the recent HTML Map Element SVG Context Google Search Tutorial‘s …

When including URLs away from the domain (ie. “third party”) on which your webpage resides then you are at risk, over time, when it comes to using URLs optionally involving arguments delimited by ? (first) and (subsequent) & (what we call the “GET” arguments) optionally delimited by # before a hashtag that used to work, but may stop working into the future.

We cannot replace the data lost regarding Weather and Placename lists from this, but we can thank Wikipedia, yet again, to help us link a single Placename with a single Geographical (Latitude, Longitude) geodata set that can match to those two HTML input elements for latitude and longitude, to improve the situation.

And so a changed other_side_of_the_world.htm‘s live run calls on autocomplete.htm (which supervises Wunderground API data calling) changed in this way to offer that alternative means to an end.

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, Not Categorised, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Migration Assistant on macOS Peer to Peer Tutorial

Migration Assistant on macOS Peer to Peer Tutorial

Migration Assistant on macOS Peer to Peer Tutorial

Another triennial, another macOS Migration Assistant (a desktop app in the Application folder’s Utilities folder) job to a MacBook Air with macOS Sonoma, further to Migration Assistant on macOS Primer Tutorial of the previous triennial.

We go …

  • “Peer to Peer” … with the migration … asking …
  • both Macs should share the same WiFi network (established by a screen earlier on to the goings on with today’s animated GIF presentation (where we tried a little “standing on our head” at one point, and which gave us an interesting perspective on life))) … meaning it amounts to an …
  • old Hard Disk to new Hard Disk migration (or copy) … best to have power to both Macs

Phew! Very easy to envisage and understand, and a great way to go with this task, thanks Apple! And don’t be alarmed by the initial 8-10 hour estimates of the time it will take. If it’s like our situation, it ended up maybe even less than one hour to perform!

If you have a Time Machine backup of the old Mac, that is an alternative input approach for a Mac to Mac migration.


Previous relevant Migration Assistant on macOS Primer Tutorial is shown below.

Migration Assistant on macOS Primer Tutorial

Migration Assistant on macOS Primer Tutorial

Setting up the software for new devices, including laptops, is sometimes motivated by the idea that the new computer should be as close as possible to being a clone of the other. This (data) “copy” operation is often referred to as “migration”.

Here, underlying operating systems mean more than brands, and so an Apple iPad (using iOS operating system) cannot be involved with a “migration” involving an Apple MacBook Air (using macOS operating system).

But an Apple MacBook Pro (using macOS operating system) can be involved with a “migration” involving an Apple MacBook Air (using macOS operating system), as we wish to do today, and we are going to try the …


Application -> Utilities

… “Migration Assistant” desktop application, which can work with the following “data conduits” …

  • both macOS devices sharing the same WiFi connection
  • two macOS devices are connected via an Ethernet cable
  • two macOS devices are connected via a USB lead
  • new macOS device imports data via a Time Machine backup off the other macOS device

… our method of choice being “both macOS devices sharing the same WiFi connection”. These modes of use can occur during a “Setup Assistant” session, as we do, or later. You can see this demonstrated with today’s video presentation


Previous relevant Apple iPad to New iPad Bluetooth Assisted Setup Tutorial is shown below.

Apple iPad to New iPad Bluetooth Assisted Setup Tutorial

Apple iPad to New iPad Bluetooth Assisted Setup Tutorial

As with the install qualities bluetooth helped out with during Apple TV Setup via WiFi and Bluetooth Tutorial, the other day we had occasion to setup a new iPad (preferably the same as an ailing old iPad) and, again, bluetooth came to the rescue making an Apple install or setup a very easy and enjoyable experience.

For more than 90% of the setup, including the absorption of a myriad of app installs and password rememberings, the simple steps of …

  1. hold the old iPad near the new iPad … and …
  2. patience (while bluetooth assisted install takes place)

… were all that was required to get up and going with the new iPad in about fifteen minutes from unwrapping! Cute, huh?!


Previous relevant Apple TV Setup via WiFi and Bluetooth Tutorial is shown below.

Apple iPad to New iPad Bluetooth Assisted Setup Tutorial

Apple iPad to New iPad Bluetooth Assisted Setup Tutorial

As with the install qualities bluetooth helped out with during Apple TV Setup via WiFi and Bluetooth Tutorial, the other day we had occasion to setup a new iPad (preferably the same as an ailing old iPad) and, again, bluetooth came to the rescue making an Apple install or setup a very easy and enjoyable experience.

For more than 90% of the setup, including the absorption of a myriad of app installs and password rememberings, the simple steps of …

  1. hold the old iPad near the new iPad … and …
  2. patience (while bluetooth assisted install takes place)

… were all that was required to get up and going with the new iPad in about fifteen minutes from unwrapping! Cute, huh?!


Previous relevant Apple TV Setup via WiFi and Bluetooth Tutorial is shown below.

Apple TV Setup via WiFi and Bluetooth Tutorial

Apple TV Setup via WiFi and Bluetooth Tutorial

We’re following up on the previous Apple TV Primer Tutorial with an upgrade because it is far more functional today, with its live television options (doing away with the need for television aerials for live streaming alternative), and we want to admire the Apple TV setup’s adroitness combining …

  • WiFi … and …
  • Bluetooth

… those two “giants” of modern personal computing networking functionality.

Those two appearing together all the time in Settings scenarios, we’ve often wondered how best to combine their talents, and the recent Apple TV version’s setup used them effectively (though optionally) to our minds.

At a certain point in the setup a choice that could make use of WiFi and Bluetooth together saved us having to remember Apple ID passwords and other such matters. At this point you could bring your other Apple device up close to the Apple TV device during the setup and arrange that Bluetooth was on, and it proceeded as if to suck the useful setting data out of the iPad device we offered up to the “Apple TV God”.

Very savvy indeed, and take a look at some Apple TV stream of consciousness here.

Did you know?

Do you like the jiggle? Let me explain. In iOS land you can delete mobile apps, effectively, by holding a touch down for a while, and waiting for all the icons to jiggle, and (re)touch any you want to delete. Well, the Apple TV operating system can work the same way. Also the same mobile app Install and Open arrangements, so the setup will be familiar to many, am sure.


Previous relevant Apple TV Primer Tutorial is shown below.

Apple TV Primer Tutorial

Apple TV Primer Tutorial

Do you own Apple devices like iPads and iPhones? Do you have a home WiFi wireless router? And do you have a reasonable modern television, or other home-theater device?

Three yes (or yes, no, yes might still work (with AirPlay) on reading here), here, and if you don’t already (have it and working), you might be interested in a product called Apple TV, a hardware product consisting of a “box” and a remote control.

With Apple TV, whatever you can do with video, and/or streaming services, on the iPad or iPhone can often be “projected” (or (Apple says) “mirrored”) onto that much bigger television screen, so that a presentation or piece of entertainment can be shared with others.

The setup is easy, as you can see from this link from Apple …

To start over at any time, unplug your device from power, then plug back in.

  1. Plug into power. Plug your Apple TV into power. …
  2. Connect to your home-theater devices. … with an HDMI cable …
  3. Turn on your television to find the setup screen. …
  4. Connect your remote. …
  5. Pick language settings. …
  6. Choose how to finish setup.

Much more amazing than that “old days” feeling of a Windows desktop being projected onto multiple screens at once!

Today’s tutorial picture shows Apple TV in action around our way.

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, Hardware, Networking, Operating System, Software, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , | Leave a comment

Google Chart Gantt Chart Revisit Tutorial

Google Chart Gantt Chart Revisit Tutorial

Google Chart Gantt Chart Revisit Tutorial

When you depend on others for help, as we do here … a lot (thanks, everybody) … if you don’t revisit software using, for example, Google Charts, it can become squidgyware?! We used to reference Yahoo YUI widgets, especially regarding their calendar widget … and … well, yes, class … yes, Henry

Gantt Charts …

  1. do not grow on trees
  2. do not reference dates … which can grow on trees
  3. never take prisoners

… thanks for your grisly, but no doubt accurate … and very precise and detailed offering … 3 points to Gryffindor!

Yes, we based the Gantt Chart PHP logic on, probably the latest Google Chart PHP logic we’d tackled just previous, which probably used Yahoo YUI calendar widgets. Not a problem at the time … but time moves on. Yes, Henry you have a canary … sorry, caveat … yes, go on …

  1. Gantt Charts never move on

… the class gets the picture now … sorry we proved that for a while …

… we can’t gantt …

… but in our defence?

So, what did we relearn from our revisit to our inhouse Gantt Chart interfacer we talked about at Google Chart Gantt Chart Primer Tutorial?

  1. keep thinking simple … if you know no better
  2. the web browser web inspectors are your best debugging tool

It panned out that just one line of code was stopping us. One check before that codeline, and things starting working, even though there was lots more Yahoo YUI Calendar widget code to confuse us. We’d have been faster if we’d have taken more notice of adage 1 above!

So feel free to, hopefully, now, get somewhere trying the changed gantt_chart.php PHP coded inhouse Google Chart Gantt Chart interfacer.


Previous relevant Google Chart Gantt Chart Primer Tutorial is shown below.

Google Chart Gantt Chart Primer Tutorial

Google Chart Gantt Chart Primer Tutorial

Seems a fair time back we were discussing the ‘select’ event in relation to Google Charts functionality, but probably it isn’t. And perhaps it was a fair while back, but maybe it wasn’t, that Google and its Charts team introduced a new chart called the Gantt Chart, which a lot of people out there will know well, or less well, as a Project Management tool.

What can a Gantt Chart help with? Not looking anything up here (but you might) we think the Gantt Chart is great for setting deadlines and to turn up with in meetings focussed on outcomes (more so than incomes … chortle, chortle).

Gantt Charts …

  1. establish date ranges for when tasks (or activities) should start and when they should complete
  2. allow for estimates of task “percentage achieved”
  3. define dependencies, as in, “does this task depend on the completion (or some other criteria) of another task”

Okay, so we are in the “when” of life, linking to other aspects like “why” or “how” or “where” perhaps. This means there are synergies with …

  • Calendar Chart
  • Timeline Chart

… as we last were talking about with Google Chart Select Event Calendar Timeline Post Tutorial as shown below … and so, in our business logic ‘select’ event logic, we mention conversions to these other chart types. Along the way we got great help from this very useful link, so, thanks.

Software wise our new Google Chart Gantt Chart integration involved …

  • gantt_chart.php
  • csv.php is the changed CSV spreadsheet export functionality supervised PHP programming source code as per changes (to cater for spreadsheet CSV exports involving this type of date data types)

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Gantt Charts information … via Google.

This extra ‘select’ event functionality, available via the suffix “&onclick=y” applied to the Google Chart Gantt Chart title, flows on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating your own emailable Google Chart live run for …

Stop Press

It pays to stay informed of changes, here on 6th October 2016. At Google Charts, the “visualization” call has changed and we’ve changed accordingly as per gantt_chart.php is the changed PHP programming source code as per changes. We apologize for this “outage” on this Google Chart … for how long …. we’re not sure … oops.


Previous relevant Google Chart Select Event Calendar Timeline Post Tutorial is shown below.

Google Chart Select Event Calendar Timeline Post Tutorial

Google Chart Select Event Calendar Timeline Post Tutorial

With our Google Graphs API, or Google Chart Tools, web and mobile applications changes today, as with WordPress 4.1.1’s Google Chart Select Event Calendar Timeline Post Tutorial, we chip away at a useful generic improvement. We hook into the PHP server language strength of allowing the POST method processing of HTML form data, to get around the URL “GET” (method) length restriction all web servers have, usually at about 2000 characters (we recommend the following background reading regarding this) … though with our web server it seems to be a smaller limit … anyway. Our guinea pigs today are the Google Charts Calendar Chart and its relationship with the Timeline Chart, following in from yesterday’s Google Chart Select Event Calendar Timeline Trend Tutorial as shown below, we are, again, talking about tools to monitor trends over time, allowing for onclick (or Google Chart “select”) functionality to be added for … except that today we have it working for quite a few more date “data” values …

  • Calendar Chart (and its synergies with)
  • Timeline Chart (for trend analysis, perhaps)

So we offer a conversion from Calendar Chart to Timeline Chart, at times after when the user has selected their second calendar date to “select”. The opposite way around, with the Timeline Chart, we allow conversion to a Calendar Chart with any one “select” event.

These Google Chart Calendar and Timeline Chart changes, with their generic “readiness” aspects, involved …

  • calendar_chart.php is the changed PHP programming source code as per changes
  • timeline_chart.php is the changed PHP programming source code as per changes
  • csv.php is the changed CSV spreadsheet export functionality supervised PHP programming source code as per changes (to cater for spreadsheet CSV exports involving date data types)
  • gchartgen.js is the changed Javascript programming source code as per changes … generic Javascript involving our new …

    function iftoobig(urlin) {
    if (eval(urlin.length) < 1000) { // vs 2000
    return urlin;
    } else {
    var dss, iy, ij, qns, qname='', qval='', newfbit='';
    var ournewf = document.getElementById('postform');
    var ourbae = document.getElementById('bitsatend');
    if (ourbae != null) {
    var qparts=urlin.split('?');
    if (eval(qparts.length) == 2) {
    var aparts=qparts[1].split('&');
    if (ournewf == null) {
    var ds=urlin.split('&data');
    var qp=ds[0];
    if (eval(ds.length) > 1) {
    for (iy=1; iy<eval(ds.length); iy++) {
    dss=ds[iy].indexOf('&');
    if (dss != -1) qp+=ds[iy].substring(dss);
    }
    }
    if (1 == 2) newfbit="<form style='display:none;' id='postform' method='POST' action='" + qparts[0] + "'>"; // "</form>";
    newfbit="<form style='display:none;' id='postform' method='POST' action='" + qp + "'>"; // "</form>";
    for (ij=0; ij<aparts.length; ij++) {
    qns=aparts[ij].split('=');
    newfbit+='<input type="hidden" name="' + qns[0] + '" value="' + (qns[1]) + '"></input>';
    }
    newfbit+='<input type="submit" value="Post Long Values"></input></form>';
    ourbae.innerHTML+=newfbit;
    ournewf = document.getElementById('postform');
    ournewf.submit();
    } else {
    for (ij=0; ij<aparts.length; ij++) {
    qns=aparts[ij].split('=');
    newfbit+='<input type="hidden" name="' + qns[0] + '" value="' + (qns[1]) + '"></input>';
    }
    newfbit+='<input type="submit" value="Post Long Values"></input>';
    ournewf.innerHTML=newfbit;
    ournewf.submit();
    }
    } else {
    return urlin;
    }
    return '#';
    } else {
    return urlin;
    }
    }
    }

We think ideas like this can help with time based trend analysis, and we may be adding sophistication to this over time, in addition to today’s “robustness” push.

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Calendar Chart information … via Google.
Link to Google Chart Tools Timeline Chart information … via Google.

We’d like to thank Trading Economics for the interesting U.S. Housing Starts (in 2015) data.

This extra functionality, available via the suffix “&onclick=y” applied to the Google Chart Calendar and Timeline Chart titles, flow on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating your own emailable Google Chart live run for …


Previous relevant Google Chart Select Event Calendar Timeline Trend Tutorial is shown below.

Google Chart Select Event Calendar Timeline Trend Tutorial

Google Chart Select Event Calendar Timeline Trend Tutorial

Our Google Graphs API, or Google Chart Tools, web and mobile applications changes today are specific, so far, to the Google Charts Calendar Chart and its relationship with the Timeline Chart, and, as for yesterday’s Google Chart Select Event Geo Pie Trend Tutorial as shown below, we are talking about tools to monitor trends over time, allowing for onclick (or Google Chart “select”) functionality to be added for …

  • Calendar Chart (and its synergies with)
  • Timeline Chart (for trend analysis, perhaps)

So we offer a conversion from Calendar Chart to Timeline Chart, at times after when the user has selected their second calendar date to “select”. The opposite way around, with the Timeline Chart, we allow conversion to a Calendar Chart with any one “select” event.

These Google Chart Calendar and Timeline Chart changes involved …

We think ideas like this can help with trend analysis, and we may be adding sophistication to this over time.

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Calendar Chart information … via Google.
Link to Google Chart Tools Timeline Chart information … via Google.

We’d like to thank Trading Economics for the interesting U.S. Housing Starts (in 2015) data.

This extra functionality, available via the suffix “&onclick=y” applied to the Google Chart Calendar and Timeline Chart titles, flow on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating your own emailable Google Chart live run for …


Previous relevant Google Chart Select Event Geo Pie Trend Tutorial is shown below.

Google Chart Select Event Geo Pie Trend Tutorial

Google Chart Select Event Geo Pie Trend Tutorial

Our Google Graphs API, or Google Chart Tools, web and mobile applications changes today are specific, so far, to the Google Charts Geo Chart and its relationship with the Pie Chart and Pie Chart Differences (really specifically), as intimated in yesterday’s Google Chart Onclick Pie Chart Differences Tutorial as shown below, allowing for onclick functionality to be added for …

  • Geo Chart (and its synergies with)
  • Pie Chart (data wise) and Pie Chart Differences (for trend analysis, perhaps)

So we offer a conversion from Geo Chart to Pie Chart, and Pie Chart Differences, when the Geo Chart data has two numerical data types defined, but we’ve baulked at the likelihood of the reverse being very applicable.

These Google Chart Geo and Pie Chart changes involved …

We think ideas like this can help with trend analysis, and we may be adding sophistication to this over time.

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Geo Chart information … via Google.
Link to Google Chart Tools Pie Chart information … via Google.
Link to Google Chart Tools Diff Charts information … via Google.

We’d like to thank Worldometers for the interesting population data.

This extra functionality, available via the suffix “&onclick=y” applied to the Google Chart Geo and Pie and Pie Differences Chart titles, flow on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating your own emailable Google Chart live run for …


Previous relevant Google Chart Onclick Pie Chart Differences Tutorial is shown below.

Google Chart Onclick Pie Chart Differences Tutorial

Google Chart Onclick Pie Chart Differences Tutorial

Our Google Graphs API, or Google Chart Tools, web and mobile applications changes today are specific, so far, to the Google Charts Pie Chart Differences, building on recent work such as yesterday’s Google Chart Select Event Geo Pie Synergy Tutorial as shown below, allowing for onclick functionality to be added for …

  • Pie Chart Differences

… in the sense that there is a known limitation with this chart using the preferred Google Chart “select” event.

You will understand from this, that the mechanisms by which Google Charts works differs from chart to chart, and, especially regarding event programming, and the display options, every chart should be considered to be “a different kettle of fish”.

Tomorrow we want to relate this chart in a more useful way to the Geo Chart, but that is (probably) for tomorrow.

In the meantime these Google Chart Pie Chart Difference changes involved …

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Diff Charts information … via Google.

This extra functionality, available via the suffix “&onclick=y” applied to the Google Chart Pie Chart Differences title, flows on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating your own emailable Google Chart live run for …


Previous relevant Google Chart Select Event Geo Pie Synergy Tutorial is shown below.

Google Chart Select Event Geo Pie Synergy Tutorial

Google Chart Select Event Geo Pie Synergy Tutorial

Our Google Graphs API, or Google Chart Tools, web and mobile applications changes today are specific, so far, to the Google Charts Geo Chart and its relationship with the Pie Chart, building on recent work such as yesterday’s Google Chart Select Event Map Overlay Lines Tutorial as shown below, allowing for onclick functionality to be added for …

  • Geo Chart (and its synergies with)
  • Pie Chart (data wise)

So we offer a conversion from Geo Chart to Pie Chart, but we’ve baulked at the likelihood of the reverse being very applicable.

These Google Chart Geo and Pie Chart changes involved …

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Geo Chart information … via Google.
Link to Google Chart Tools Pie Chart information … via Google.

This extra functionality, available via the suffix “&onclick=y” applied to the Google Chart Geo Chart title, flows on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating your own emailable Google Chart live run for …


Previous relevant Google Chart Select Event Map Overlay Lines Tutorial is shown below.

Google Chart Select Event Map Overlay Lines Tutorial

Google Chart Select Event Map Overlay Lines Tutorial

Our Google Graphs API, or Google Chart Tools, web and mobile applications changes today are specific, so far, to the Google Charts Map Chart, building on yesterday’s Google Chart Select Event Cache Issue Tutorial as shown below, allowing for the concept of drawing link lines overlayed onto the …

  • Map Chart

… adding to our …

The CSS “overlay” usual suspects coming into play were …

And what function do we allow once the SVG line is there, overlayed, in place, ready to be hovered over or clicked? We calculate a crow flying distance via …


function great_circle_distance(talis, gnolis, latis, longis) {
var ourdist=0.0;
var rgnol=eval((gnolis) * Math.PI / 180.0);
var rtal=eval((talis) * Math.PI / 180.0);
var rlong=eval((longis) * Math.PI / 180.0);
var rlat=eval((latis) * Math.PI / 180.0);
var deltalong = Math.abs(eval(((gnolis)-(longis)) * Math.PI / 180.0));
var acof = eval(Math.sin(rtal) * Math.sin(rlat)) + (Math.cos(rtal) * Math.cos(rlat) * Math.cos(deltalong)); // via http://en.wikipedia.org/wiki/Great-circle_distance ... thanks
ourdist = eval(Math.round((Math.acos(acof) * 6371000.0) + 0.00001) * 100) / 100;
return ourdist;
}

These Google Chart Map Chart changes involved …

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Map Chart information … via Google.

This extra functionality, available via the suffix “&onclick=y” applied to the Google Chart Map title, flows on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating your own emailable Google Chart live run for …

and/or

See this functionality in action applied to two of our recent blog postings …

  1. HTML/Javascript Where Does It Get Me To Primer Tutorial live run uses HTML/Javascript programming source code distance_from.html (changed as per distance_from.html for overlay line functionality)
  2. PHP Modularization for Lighthouses in Australia Tutorial live run uses PHP programming source code http://www.rjmprogramming.com.au/PHP/australian_lighthouses.php (changed as per distance_from.html for overlay line functionality)

Previous relevant Google Chart Select Event Cache Issue Tutorial is shown below.

Google Chart Select Event Cache Issue Tutorial

Google Chart Select Event Cache Issue Tutorial

We’re still trying for yet more “genericity” with our Google Graphs API, or Google Chart Tools, web and mobile applications today, building on yesterday’s Google Chart Select Event Email Integration Tutorial as shown below, with integration involving email, yesterday more for non-mobile usage and today, more for mobile platform usage, that we first tried on our recent “guinea pig” “guinea fowl” (so yesterday) “guinea baboon” functionalities (of recent times) …

  • Area Chart
  • Bar Chart (and Bar Chart Differences)
  • Column Chart (and Column Chart Differences)
  • Line Chart
  • Map Chart
  • Pie Chart

It probably comes as no surprise that chart data can be a great conversation starter for meetings or online discussions conducted via email, for example. They say “a picture tells a thousand words” … MMM look at that pie chart over yonder … see … three thousand words … chortle, chortle.

Do you remember yesterday? …

We use mailto links to direct the user to their default client mail supervisors to make all this happen. You will find, with PHP, that you can email without this client email via the use of the mail method.

… Well, our concentration on mailto (that works fine on non-mobile platforms) needed to be balanced with some mobile platform consideration that uses that PHP mail method, so as not to navigate too far away in our iOS app’s WebView.

And we did some work with Google Chart Pie Charts today to add “select” event functionality, and to try to stop it using the cache, as we want the iOS app reflect changes we make to things, and be able to let the iOS app user recover from an unforseen problem exacerbated by the return to a bad caching scenario.

We found good advice about this cache issue at this useful link, so, thanks. You may read from this page that there is an HTML meta tag approach to this, but we prefer a PHP approach, and use, up the top of the PHP the code snippet …


header( "Expires: Mon, 20 Dec 1998 01:00:00 GMT" );
header( "Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT" );
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Cache-Control: post-check=0, pre-check=0', false );
header( 'Pragma: no-cache' );

… you will find up the top of the PHP pie_chart.php programming source code.

These Google Chart Pie/Line/Bar/Area/Column/Map Chart changes involved …

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Area Chart information … via Google.
Link to Google Chart Tools Bar Chart information … via Google.
Link to Google Chart Tools Column Chart information … via Google.
Link to Google Chart Tools Line Chart information … via Google.
Link to Google Chart Tools Map Chart information … via Google.
Link to Google Chart Tools Pie Chart information … via Google.

This extra functionality, available via the suffix “&onclick=y” applied to the Google Chart Area and Bar and Column and Line and Map and Pie Chart title, flows on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating your own emailable Google Chart live runs for …

No guinea pigs (nor guinea fowl, nor guinea baboons) were harmed in the making of this blog post. Honest, hen!


Previous relevant Google Chart Select Event Email Integration Tutorial is shown below.

Google Chart Select Event Email Integration Tutorial

Google Chart Select Event Email Integration Tutorial

We’re still trying for yet more “genericity” with our Google Graphs API, or Google Chart Tools, web and mobile applications today (as with WordPress 4.1.1’s Google Chart Select Event Email Integration Tutorial), building on yesterday’s Google Chart Select Event Spreadsheet Integration Tutorial as shown below, with integration involving email, that we are first trying on our recent “guinea pig” “guinea fowl” functionalities (of recent times) …

  • Area Chart
  • Bar Chart (and Bar Chart Differences)
  • Column Chart (and Column Chart Differences)
  • Line Chart
  • Map Chart

It probably comes as no surprise that chart data can be a great conversation starter for meetings or online discussions conducted via email, for example. They say “a picture tells a thousand words” so imagine how many a “chart” tells?!

So today we make use of the fact that for small amounts of data the Google Charts can be shared via the emailing of a URL link as the body of an email. For larger amounts of data we may have to think some more into the future, though we’re half ready because …

  1. we are using a server side language, PHP … which means that …
  2. the $_POST[] mentions in our PHP code can eventually be put to good use here, down the track

These Google Chart Line/Bar/Area/Column/Map Chart changes involved …

We use mailto links to direct the user to their default client mail supervisors to make all this happen. You will find, with PHP, that you can email without this client email via the use of the mail method.

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Area Chart information … via Google.
Link to Google Chart Tools Bar Chart information … via Google.
Link to Google Chart Tools Column Chart information … via Google.
Link to Google Chart Tools Line Chart information … via Google.
Link to Google Chart Tools Map Chart information … via Google.

This extra functionality, available via the suffix “&onclick=y” applied to the Google Chart Area and Bar and Column and Line and Map Chart title, flows on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating your own emailable Google Chart live runs for …

No guinea pigs (nor guinea fowl) were harmed in the making of this blog post. Honest, hen!


Previous relevant Google Chart Select Event Spreadsheet Integration Tutorial is shown below.

Google Chart Select Event Spreadsheet Integration Tutorial

Google Chart Select Event Spreadsheet Integration Tutorial

We’re trying more “genericity” with our Google Graphs API, or Google Chart Tools, web and mobile applications today, building on yesterday’s Google Chart Line/Bar/Area/Column Select Event Tutorial, as shown below, with integration involving spreadsheets, that we are first trying on our recent “guinea pig” functionalities (of recent times) …

  • Area Chart
  • Bar Chart (and Bar Chart Differences)
  • Column Chart (and Column Chart Differences)
  • Line Chart
  • Map Chart

It probably comes as no surprise that chart data can be turned into spreadsheet data, especially if you have ever spent much time in those great spreadsheet applications like Microsoft Office’s Excel, where there are various pathways to display charts from your spreadsheet data. So, today, we just turn that thought around a bit, and use Comma Separated Value (CSV) files as a conduit to be able to convert our chart data into a spreadsheet. We leave it up to whatever is the default application you have to open CSV files … it doesn’t even have to be a spreadsheet application as such, but our applications today offer a downloading capability to get the spreadsheet (CSV) data down to your hard disk (or perhaps midair solutions like Google Docs).

So we see this as a good candidate as a generic Google Chart “select” event tool for users looking to integrate with spreadsheet tools.

These Google Chart Line/Bar/Area/Column/Map Chart changes involved …

You’ll see with the PHP code that a crucial technique with today’s work, which involves huge use of PHP’s header method, revolves around the use of the PHP include statement (as well as its closely related require statement). What we “included” in the PHP of above was PHP source code csv.php to aid with constructing the PHP header statements necessary to make the functionality happen. We’d like to thank this very useful link for help here.

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Area Chart information … via Google.
Link to Google Chart Tools Bar Chart information … via Google.
Link to Google Chart Tools Column Chart information … via Google.
Link to Google Chart Tools Line Chart information … via Google.
Link to Google Chart Tools Map Chart information … via Google.

This extra functionality, available via the suffix “&onclick=y” applied to the Google Chart Area and Bar and Column and Line and Map Chart title, flows on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating your own emailable Google Chart live runs for …

No guinea pigs were harmed in the making of this blog post. Honest, guv’!


Previous relevant Google Chart Line/Bar/Area/Column Select Event Tutorial is shown below.

Google Chart Line/Bar/Area/Column Select Event Tutorial

Google Chart Line/Bar/Area/Column Select Event Tutorial

Today we continue on (from yesterday’s Google Chart Line and Map Chart Select Event Prompt Tutorial) with more integration involving Google Graphs API, or Google Chart Tools, and its “select” event (like onclick) involving …

  • Area Chart
  • Bar Chart (and Bar Chart Differences)
  • Column Chart (and Column Chart Differences)
  • Line Chart

… involve similar data requirements, so we can integrate by offering a redraw of the Google Chart you are currently in, to another type of Google Chart in the list above, and allow this, as an additional “business logic” piece of functionality offered to users when they “click/touch” on the Google Chart, firing off the onclick (or Google Chart “select”) event.

This piece of functionality can be useful, even in terms of aesthetics, as some Google Charts display better than others depending on the density of the data set(s) displayed.

Along the way we also present to the user a moving average of values relevant to each data column of interest.

From yesterday, you may also recall that we can allow a redraw of one the Google Chart types as above (and for lots of others eventually) by allowing user amendment of the data.

And from the day before yesterday we outlined that first bit of “select” event business logic allowing the user to see the difference between values, on “click/touching” any one of them and on doing this firing the “select” event.

These Google Chart Line/Bar/Area/Column Chart changes involved …

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Area Chart information … via Google.
Link to Google Chart Tools Bar Chart information … via Google.
Link to Google Chart Tools Column Chart information … via Google.
Link to Google Chart Tools Line Chart information … via Google.

This extra functionality, available via the suffix “&onclick=y” applied to the Google Chart Area and Bar and Column and Line Chart title, flows on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating your own emailable Google Chart live runs for …


Previous relevant Google Chart Line and Map Chart Select Event Prompt Tutorial is shown below.

Google Chart Line and Map Chart Select Event Prompt Tutorial

Google Chart Line and Map Chart Select Event Prompt Tutorial

Here is a tutorial that further reacquaints you, maybe, with the Google Graphs API, or Google Chart Tools, and its Line Chart functionality, last talked about at this blog with PHP/Javascript/HTML Google Chart Line Chart Tutorial as shown way below, and Map Chart, for its first mention and Google Chart Map Chart Select Event Primer Tutorial, for its last mention.

There is no magic relationship between these two chart types today, rather it is the case that they are the “guinea pigs” for “generic thoughts”.

“Generic” is a favourite word for what we try to achieve here, but it can be like “nirvana” for lots of reasons …

  • do you have a market for the investment you need to put in to push for “genericity”
  • in similar mind, does the project size make it worthwhile
  • is catering for all the web browser and application platforms allow for “genericity” anyway?

… in a big organization, such queries can progress quite nicely by using teams and having planning discussions and setting timelines and deadlines between project groups, but in smaller teams it can be the case of “seeing what problems” come up, to decide on the push for “genericity” with the product, down, eventually, to the level of deciding where “business logic” code should sit (ie. in a “library” or “called” piece of code, or otherwise). So, we’re trying some “generic” thoughts and using these two disparate Google Charts to see whether there is some onclick (ie. Google Charts “select” event, which you can read a lot about here … thanks, Google) logic that, in a business sense (because we like to think of onclick being really closely tied to “business logic”, the reason being, some user “clicked/touched” something, so you better present something heading towards specific interest, to do with business, when they do this.

And we think an approach would be to offer an onclick reworking of the data of a chart should they get to the “click/touch” stage with a chart. And we decided that it is not so bad to present this in an overall “one string” chance to change the chart, because, presumanly the user went through the whole rigmarole of answering questions to get this far, and by this stage will “get the hang” of what to do to make more sweeping changes by using this new functionality. Think, too, a “faster way to do things” presented to “advanced users” willing to give things a go (otherwise they wouldn’t still be reading?!) help to improve the UX (“user experience”) of the application, whether that be web or mobile or desktop or seascape (just checking you’re still awake).

And so, in practical terms, with these two charts, we’ve recently added onclick (Google Charts “select” event) Javascript alert and prompt boxes recently, respectively, for Line Charts and Map Charts. Well, today, we make them both Javascript prompt windows to offer this chance for the user to “reshape” their chart via “click/touch” chart control.

These Google Chart Line Chart and Map Chart changes involved …

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Line Chart information … via Google.
Link to Google Chart Tools Map Chart information … via Google.

This extra functionality, available via the suffix “&onclick=y” applied to the Google Chart Map Chart title, flows on directly to the iPad iOS App we created and talked about, last, with Xcode Swift iOS Application End Game Primer Tutorial.

So please try creating you own emailable Google Chart Line Chart here or Map Chart here.


Previous Previous relevant PHP/Javascript Google Chart Line Chart Select Event Tutorial is shown below.

PHP/Javascript Google Chart Line Chart Select Event Tutorial

PHP/Javascript Google Chart Line Chart Select Event Tutorial

Here is a tutorial that reacquaints you, perhaps, with the Google Graphs API, or Google Chart Tools, and its Line Chart functionality, first talked about at this blog with PHP/Javascript/HTML Google Chart Line Chart Tutorial as shown below.

Google Chart Tools provide a perfect way to visualize data on your website. From simple line charts to complex hierarchical tree maps, the chart galley provides a large number of well-designed chart types. Populating your data is easy using the provided client- and server-side tools.

The reason for the revisit concerns a push to make more use of the onclick “feeling” Google Chart “select” event, an event triggered when you click on a feature of, in this case, a Google Chart Line Chart that our web application helps you create.

Here is some PHP code in live action for this tutorial where you define your line chart characteristics and data, where am appending of “&onclick=y” to your line chart title means the additional “select” event functionality can kick in.

The “select” event functionality (which you can read a lot about here … thanks, Google) would be full of business logic and specific to how you want to use the chart, so it is a bit hard to pin down how you should use it, but in today’s tutorial picture you can see that in a Company Performance line chart showing Sales and Expenses if you click on a Sales figure for any given Year the “select” event business logic brings up a Javascript alert() box that informs the user of the Expenses for that same Year, along with the difference between Sales and Expenses. The logic is not tied down to the exact words “Sales” and “Expenses”, and it will work this out from what you entered in for this earlier on.

Some findings here led to some small changes to that generic Javascript behind the scenes of these Google Chart suite of web applications as well so, all told, the changes involved …

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Line Chart information … via Google.

So please try creating you own emailable Google Chart Line Chart here.


Previous relevant PHP/Javascript/HTML Google Chart Line Chart Tutorial is shown below.

PHP/Javascript/HTML Google Chart Line Chart Tutorial

PHP/Javascript/HTML Google Chart Line Chart Tutorial

Here is a tutorial that introduces you to Google Graphs API, or Google Chart Tools, and its Line Chart functionality.

Google Chart Tools provide a perfect way to visualize data on your website. From simple line charts to complex hierarchical tree maps, the chart galley provides a large number of well-designed chart types. Populating your data is easy using the provided client- and server-side tools.

Let’s see some PHP code in live action for this tutorial where you define your line chart characteristics and data.

Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Line Chart information … via Google.

Link to some downloadable PHP programming code … rename to line_chart.php.

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


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


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


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


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


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


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


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


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


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


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


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, Tutorials | Tagged , , , , , , , , , , , , , | Leave a comment

Find Games Peer to Peer Tutorial

Find Games Peer to Peer Tutorial

Find Games Peer to Peer Tutorial

It wasn’t our initial intention, but on completion of the cloning aspects to …

  • sporning from the Find the Words game basis … cloning to a …
  • Finding the Numbers game

… as two distinct entities, we could piece them back together as a “more powerful combined unit” via pretty simple “peer to peer” dropdown (ie. select) element considerations.

And that can be the power of the dropdown, with its onchange event … it can be added to easily, and help with the control of webpage navigation thinking …

Find the Words dropdown new suboptions intervention


function modeize(ospan) {
var ihis=ospan.innerHTML.replace('<br> ',''), huhi=1;
var chcs=['', 'Names','Connectives'];
var rest='';
for (var ijk=0; ijk<chcs.length; ijk++) {
if (ihis.replace('Words','') != chcs[ijk]) {
rest+='<option value="' + chcs[ijk].replace('Words','') + ('">' + chcs[ijk] + '<').replace('"><', '">Words<') + '/option>';
huhi++;
}
}
rest+='';
huhi++;
rest+='';
huhi++;
rest+='';
huhi++;

if (ihis.indexOf('<') == -1) {
ospan.innerHTML='<select size=' + huhi + ' onclick="event.stopPropagation();" onchange="modesel(this,' + "'" + ospan.id + "'" + ');"><option value="' + ihis.replace('Words','') + ('">' + ihis + '<').replace('"><', '">Words<') + '/option>' + rest + '</select>';
}
}
Find the Words dropdown onchange event function intervention


function modesel(osel, ospanid) {
var anewurl='';
mode=osel.value;
if (mode != '' && mode.trim() == '') {
anewurl=document.URL.replace('_words.', '_numbers.').split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(mode.trim()) + '&across=' + numlettersacross + '&down=' + numlettersdown + '&fontpixels=' + fontpixels + '&wordlenmin=' + minwordlength + '&wordlenmax=' + minwordlength + '&table=' + tabularize; // + '#' + encodeURIComponent(jhis.replace(/\<br\>/g,''));
location.href=anewurl;
} else if (mode.toLowerCase() == 'c') {
anewurl=document.URL.replace('_words.', '_numbers.').split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(mode.trim()) + '&across=' + numlettersacross + '&down=' + numlettersdown + '&fontpixels=' + fontpixels + '&wordlenmin=' + minwordlength + '&wordlenmax=' + minwordlength + '&table=' + tabularize; // + '#' + encodeURIComponent(jhis.replace(/\<br\>/g,''));
location.href=anewurl;
}

document.getElementById(ospanid).innerHTML=(osel.value.trim() == '' ? 'Words' : osel.value.replace('Connectives', '<br> Connectives'));
}
Find the Numbers dropdown suboption additions intervention


var seloh='<select style="font-weight:bold;margin-right:40px;background-color:yellow;" id="selmode" onchange="changesel(this);" title="Modes of use for game"><option id=simpleopt value=""></option><option data-answer="" id="clueopt" value="c">Clues</option><option data-answer="" id="hclueopt" value="C">Harder</option><option value=" ">Words</option><option value="Names">Names</option><option value="Connectives">Connectives</option></select>';
Find the Numbers dropdown onchange event function intervention


function changesel(osel) {
var anewurl='';
defv=osel.value;
if (defv != '' && defv.trim() == '') {
anewurl=document.URL.replace('_numbers.', '_words.').split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(defv.trim()) + '&across=' + numlettersacross + '&down=' + numlettersdown + '&fontpixels=' + fontpixels + '&wordlenmin=' + minwordlength + '&wordlenmax=' + eval(4 * minwordlength) + '&table=' + tabularize; // + '#' + encodeURIComponent(jhis.replace(/\<br\>/g,''));
location.href=anewurl;
} else if (defv.toLowerCase() == 'names') {
anewurl=document.URL.replace('_numbers.', '_words.').split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(defv.trim()) + '&across=' + numlettersacross + '&down=' + numlettersdown + '&fontpixels=' + fontpixels + '&wordlenmin=' + minwordlength + '&wordlenmax=' + eval(4 * minwordlength) + '&table=' + tabularize; // + '#' + encodeURIComponent(jhis.replace(/\<br\>/g,''));
location.href=anewurl;
} else if (defv.toLowerCase() == 'connectives') {
anewurl=document.URL.replace('_numbers.', '_words.').split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(defv.trim()) + '&across=' + numlettersacross + '&down=' + numlettersdown + '&fontpixels=' + fontpixels + '&wordlenmin=' + minwordlength + '&wordlenmax=' + eval(4 * minwordlength) + '&table=' + tabularize; // + '#' + encodeURIComponent(jhis.replace(/\<br\>/g,''));
location.href=anewurl;
}

if ((osel.value + ' ').substring(0,1).toLowerCase() == 'c') {
document.getElementById('sclue').style.display='inline';
document.getElementById('sclue').innerHTML='' + isithard('' + findings[eval(-1 + findings.length - thisq)]);
} else {
document.getElementById('sclue').style.display='none';
}
}

And so, onto the recent Find Number Game Clues Tutorial we have …

  • an original idea …
  • cloned into two …
  • conjoinable via dropdown suboptions with an “inhouse functionality” feeling, allowing the user to feel it can be a “one stop shop” for all the underlying functionality

What is “peer to peer” thinking? Well, in this case, it is the thinking that all 6 modes of use for the two Finding web applications have equal status, with “groupthink” design (reflected by the make up of the two dropdown elements involved, which both mention all 6 possibilities) rather than any “hierarchical” structure.

And so, see …

… either capable of being a parent “in name only” (to the other), presented again, for your perusal.


Previous relevant Find Number Game Clues Tutorial is shown below.

Find Number Game Clues Tutorial

Find Number Game Clues Tutorial

Onto the “cloning start” yesterday’s Find Number Game Cloning Tutorial gave us to our Find the Number game, today, we improve on …

  • its modes of play … adding to existant …
    1. find a computer decided upon number … with …
    2. find a number via a fairly simple clue … and …
    3. find a number via a pretty cryptic clue

    … and …

  • add a hierarchy to the scoring so that a down or up user answer is worth more and a diagonal answer is worth even mode and a reversed answer is also worth more regarding the scoring and the clue modes of use add to the scoring worth as well … so that

    score+=eval(eval('' + twowordstocheck[curri].length) * scorefactor);

    … codelines reflect the nuanced variable scorefactor starting as 1 and changed at various points, can bring to the game

… via …

Clue iframe helper HTML


<iframe onload="checkclue(this);" id=hclueif src='//www.rjmprogramming.com.au/Games/Battleshipsandcruisers/index2a.php?clue=' style=display:none;></iframe>
Helped out by this iframe onload event function


var seloh='<select style="font-weight:bold;margin-right:40px;background-color:yellow;" id="selmode" onchange="changesel(this);" title="Modes of use for game"><option id=simpleopt value=""></option><option data-answer="" id="clueopt" value="c">Clues</option><option data-answer="" id="hclueopt" value="C">Harder</option></select>';
var scorefactor=1;
var findings=[], clues=[], findlen=minwordlength, thisq=0, jthisq=0, kthisq=0, alreadydone=';000;', hardclue=['Find number '], longhardclue=[];

function checkclue(iois) {
//if (iois.src.indexOf('?isan=') != -1) { alert('Here'); }
if ((' ' + iois.src).slice(-6) == '?clue=') { return ''; }
var cnum='', ourabi='';
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
ourabi='' + aconto.body.innerHTML;
if (ourabi.indexOf('</p') != -1) {
if (kthisq == 0 && hardclue[0].indexOf('Find number ') == 0) {
cnum=('' + findings[eval(-1 + findings.length - kthisq)]);
cnum=cnum.substring(0,eval(-2 + eval('' + cnum.length))) + '00';
hardclue[0]='Find the number ' + cnum + ' + <font size=2>(' + ourabi.split('>')[1].split('</p')[0] + ')</font>';
longhardclue.push(hardclue[0]);
if (defv == 'C' && document.getElementById('sclue')) {
document.getElementById('sclue').innerHTML=hardclue[0];
}
//alert('0:' + hardclue[0]);
kthisq++;
if (eval(1 + kthisq) < eval(findings.length)) {
//document.title='' + kthisq + ' ' + findings[eval(-1 + findings.length - kthisq)] + '//www.rjmprogramming.com.au/Games/Battleshipsandcruisers/index2a.php?clue=' + findings[eval(-1 + findings.length - kthisq)] + '#' + kthisq;
document.getElementById('hclueif').src='//www.rjmprogramming.com.au/Games/Battleshipsandcruisers/index2a.php?clue=' + eval(findings[eval(-1 + findings.length - kthisq)] % 100);
}
} else {
cnum=('' + findings[eval(-1 + findings.length - kthisq)]);
cnum=cnum.substring(0,eval(-2 + eval('' + cnum.length))) + '00';
longhardclue.push('Find the number ' + cnum + ' + <font size=2>(' + ourabi.split('>')[1].split('</p')[0] + ')</font>');
//alert('1:' + 'Find the number ' + cnum + ' + (' + ourabi.split('>')[1].split('</p')[0] + ')');
kthisq++;
if (eval(1 + kthisq) < eval(findings.length)) {
//document.title='' + kthisq + ' ' + findings[eval(-1 + findings.length - kthisq)] + '//www.rjmprogramming.com.au/Games/Battleshipsandcruisers/index2a.php?clue=' + findings[eval(-1 + findings.length - kthisq)] + '#' + kthisq;
document.getElementById('hclueif').src='//www.rjmprogramming.com.au/Games/Battleshipsandcruisers/index2a.php?clue=' + eval(findings[eval(-1 + findings.length - kthisq)] % 100);
}
}
}
}
}
New Javascript helping out the new dropdown Mode of Use element created via function defval fleshing out of div id=clue innards


function defval(inidea) {
//alert(1);
var cluestr='';
var scoh='';
if (document.getElementById('clue').innerHTML == '') {
defv=mode;
scoh='<span style=display:none;background-color:lightblue; id=sclue>' + isithard('' + findings[eval(-1 + findings.length - thisq)]) + '</span>';
//alert('' + seloh.replace('></option>', '>' + inidea.replace(' ', '').replace('<br>', '') + '</option>'));
document.getElementById('clue').innerHTML=(seloh.replace('></option>', '>' + inidea.replace(' ', '').replace('<br>', '') + '</option>')).replace(' value="' + mode + '"', ' value="' + mode + '" selected') + '    ' + scoh;
//alert((seloh.replace('></option>', '>' + inidea.replace(' ', '').replace('<br>', '') + '</option>')).replace(' value="' + mode + '"', ' value="' + mode + '" selected') + '    ' + scoh);
document.getElementById('selmode').value=(mode + ' ').substring(0,1).trim();
document.getElementById('clueopt').setAttribute('data-answer', '' + findings[eval(-1 + findings.length - thisq)]);
document.getElementById('hclueopt').setAttribute('data-answer', '' + findings[eval(-1 + findings.length - thisq)]);
} else {
document.getElementById('simpleopt').innerText=inidea.replace(' ', '').replace('<br>', '');
document.getElementById('clueopt').setAttribute('data-answer', '' + findings[eval(-1 + findings.length - thisq)]);
document.getElementById('hclueopt').setAttribute('data-answer', '' + findings[eval(-1 + findings.length - thisq)]);
document.getElementById('selmode').value=defv;
document.getElementById('clue').innerHTML=document.getElementById('selmode').outerHTML;
if (document.getElementById('sclue')) {
scoh=document.getElementById('sclue').outerHTML + '';
}
}
if ((document.getElementById('selmode').value + ' ').substring(0,1).toLowerCase() == 'c' || defv.toLowerCase() == 'c') {
scoh='<span style=display:none; id=sclue>' + isithard('' + findings[eval(-1 + findings.length - thisq)]) + '</span>';
scoh=scoh.replace('none;', 'inline;');
cluestr=' Find number ' + document.getElementById('clueopt').getAttribute('data-answer');
if (document.getElementById('sclue')) {
document.getElementById('sclue').style.display='inline';
document.getElementById('sclue').innerHTML=cluestr;
document.getElementById('sclue').style.display='inline-block';
}
} else if (document.getElementById('sclue')) {
scoh=scoh.replace('inline;', 'none;');
document.getElementById('sclue').style.display='none';
}
//alert(cluestr);
document.getElementById('selmode').value=defv;
lastinidea=inidea;
return document.getElementById('selmode').outerHTML.replace(/\ selected/g,'').replace(' value="' + defv + '"', ' value="' + defv + '" selected') + '    ' + scoh;
}

function isithard(insimplecluepart) {
var outhardpart='Find number ' + insimplecluepart;
if (defv == 'C') {
modefactor=2;
outhardpart=hardclue[eval(-1 + hardclue.length)];
} else if (defv == 'c') {
modefactor=1;
if (eval(eval('' + insimplecluepart) % 10) == 0) {
outhardpart='Find the number that equates to (' + ('' + eval(eval('' + insimplecluepart) * 1.3)) + ' - ' + ('' + eval(eval('' + insimplecluepart) * 0.3)) + ')';
} else if (eval(eval('' + insimplecluepart) % 9) == 0) {
outhardpart='Find the number that equates to (' + ('' + eval(eval('' + insimplecluepart) * 2 / 9)) + ' + ' + ('' + eval(eval('' + insimplecluepart) * 7 / 9)) + ')';
} else if (eval(eval('' + insimplecluepart) % 8) == 0) {
outhardpart='Find the number that equates to (' + ('' + eval(eval('' + insimplecluepart) * 3 / 8)) + ' + ' + ('' + eval(eval('' + insimplecluepart) * 5 / 8)) + ')';
} else if (eval(eval('' + insimplecluepart) % 7) == 0) {
outhardpart='Find the number that equates to (' + ('' + eval(eval('' + insimplecluepart) * 13 / 7)) + ' - ' + ('' + eval(eval('' + insimplecluepart) * 6 / 7)) + ')';
} else if (eval(eval('' + insimplecluepart) % 6) == 0) {
outhardpart='Find the number that equates to (' + ('' + eval(eval('' + insimplecluepart) / 3)) + ' x 3' + ')';
} else if (eval(eval('' + insimplecluepart) % 5) == 0) {
outhardpart='Find the number that equates to (' + ('' + eval(eval('' + insimplecluepart) / 5)) + ' + ' + ('' + eval(eval('' + insimplecluepart) * 4 / 5)) + ')';
} else if (eval(eval('' + insimplecluepart) % 4) == 0) {
outhardpart='Find the number that equates to (' + ('' + eval(eval('' + insimplecluepart) * 3)) + ' / 3' + ')';
} else if (eval(eval('' + insimplecluepart) % 3) == 0) {
outhardpart='Find the number that equates to (' + ('' + eval(eval('' + insimplecluepart) / 3)) + ' + ' + ('' + eval(eval('' + insimplecluepart) * 2 / 3)) + ')';
} else if (eval(eval('' + insimplecluepart) % 2) == 0) {
outhardpart='Find the number that equates to (' + ('' + eval(eval('' + insimplecluepart) * 1.5)) + ' - ' + ('' + eval(eval('' + insimplecluepart) * 0.5)) + ')';
} else {
outhardpart='Find the number that equates to (' + ('' + eval(eval('' + insimplecluepart) * 3)) + ' - ' + ('' + eval(eval('' + insimplecluepart) * 2)) + ')';
}
} else {
modefactor=0;
}
return outhardpart;
}

function changesel(osel) {
defv=osel.value;
if ((osel.value + ' ').substring(0,1).toLowerCase() == 'c') {
document.getElementById('sclue').style.display='inline';
document.getElementById('sclue').innerHTML='' + isithard('' + findings[eval(-1 + findings.length - thisq)]);
} else {
document.getElementById('sclue').style.display='none';
}
}

… in a changed textarea_find_numbers.html Find the Numbers game for your perusal.


Previous relevant Find Number Game Cloning Tutorial is shown below.

Find Number Game Cloning Tutorial

Find Number Game Cloning Tutorial

Around here we seem to find more use, as far as cloning one web application into another goes, cloning a game into another form of that game, perhaps changing a single data concept or mode of use. Today’s cloning …

  • takes our recent Finding the English Words game web application as a cloning base … for …
  • a new Find the Numbers game web application

… the great thing about cloning often being the transfer of those more advanced sharing functionalities straight over, via the cloning process, into the new web application. We can’t say this cloning process can be “cloned”, but global substitutions often play a part, today’s …

  • calling for a new “clue based” instigator process … we start the ball rolling with a computer decided “ask” … replacing …
  • those English Word dictionary lookups

… so, in a way, simpler, in this first draft … but we plan for more drafts, and the scoring needs more sophistication in versions to come.

Anyway, further to the recent Find English Word Game Collaboration Tutorial “clone source” we have for you today a “how we got there” textarea_find_numbers.html Find the Numbers game you might like to try for youself.


Previous relevant Find English Word Game Collaboration Tutorial is shown below.

Find English Word Game Collaboration Tutorial

Find English Word Game Collaboration Tutorial

Collaboration, regarding games, is synonymous with “level playing field”, and that is a principle upheld with today’s introduction of sharing and collaboration functionality into our Find the Word game, and further to yesterday’s Find English Mobile Clicked Word Ends Game Tutorial.

As such, we need to pick “common denominators”, so to speak, and that is, as of recent times, to encourage the use of …

  • tabular mode of use … when sharing via email or SMS … rather than …
  • textarea selectionchange event mode of use

… in the sense that we don’t know the arrangements for an email or SMS recipient as to whether they’ll be reading the communication on a mobile or non-mobile platform.

Once a communication is sent, the letters presented will match, and to get the competitive juices flowing, we add a timer aspect to the scoring. Much of the change relates to catering for email and SMS hashtagging arrangements …


var mode=(location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('mode=')[1] ? (decodeURIComponent((location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('mode=')[1].split('&')[0])) : '';
var tabularize=(location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('table=')[1] ? (decodeURIComponent((location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('table=')[1].split('&')[0])) : 'Null';
var minwordlength=(location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('min=')[1] ? Math.min(3,eval(decodeURIComponent((location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('min=')[1].split('&')[0]))) : 3;
var maxwordlength=(location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('max=')[1] ? eval(decodeURIComponent((location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('max=')[1].split('&')[0])) : 15;
var numlettersacross=(location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('across=')[1] ? eval(decodeURIComponent((location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('across=')[1].split('&')[0])) : (tabularize == 'Null' ? 50 : 80);
var numlettersdown=(location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('down=')[1] ? eval(decodeURIComponent((location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('down=')[1].split('&')[0])) : 40;
var fontpixels=(location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('pixels=')[1] ? eval(decodeURIComponent((location.search + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').replace(/^\#/g,'&')).split('pixels=')[1].split('&')[0])) : 13;

var firstdate=new Date();
var seconddate=new Date();
var updatehowlong=false, jhis='';

if (('' + window.localStorage.getItem('findwordcollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defemail=window.localStorage.getItem('findwordcollaboratoremailee');
}
if (('' + window.localStorage.getItem('findwordcollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defsms=window.localStorage.removeItem('findwordcollaboratorsmsno');
}


function doemail(inidea) {
////alert(3);
var zfrom='youllneverfindthis', zto='youllneverfindthis';
var azx=top.document.getElementById('xae' + 'mail');
//alert(33);
if (!azx) { azx=top.document.createElement("a"); }
//alert(3333);
//if (1 == 1) {
//document.getElementById('divas').appendChild(azx);
//} else {
top.document.body.appendChild(azx);
//}
//(334);
azx.style = "display: none";
//alert(2334);
azx.target = "_top";
//alert(6334);
azx.id = 'xae' + 'mail';
//if (1 == 6 && bihbig.indexOf('</he' + 'ad>') != -1 || bihbig.indexOf('<b' + 'o' + 'dy') != -1 || bihbig.indexOf('<h' + '1') == 0) {
//azx.href = 'mailto:' + inidea + '?subject=' + encodeURIComponent(document.getElementsByTagName('h2')[0].innerHTML.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#bih=' + encodeURIComponent(bihbig)); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
//} else {
var newurl=document.URL.split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(mode.trim()) + '&across=' + numlettersacross + '&down=' + numlettersdown + '&fontpixels=' + fontpixels + '&wordlenmin=' + minwordlength + '&wordlenmax=' + maxwordlength + '&table=' + tabularize + '#' + encodeURIComponent(jhis.replace(/\<br\>/g,''));
if (!oops && tabularize == 'Null' && !document.getElementById('tablemy')) {
zfrom=encodeURIComponent('Highlighting');
zto=encodeURIComponent('Click Start/End');
newurl=document.URL.split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(mode.trim()) + '&across=' + numlettersacross + '&down=' + numlettersdown + '&fontpixels=' + fontpixels + '&wordlenmin=' + minwordlength + '&wordlenmax=' + maxwordlength + '&table=y#' + encodeURIComponent(jhis.replace(/\<br\>/g,''));
}
if (sparewes) {
azx.href = 'mailto:' + inidea + '?subject=' + encodeURIComponent(sparewes.document.getElementsByTagName('h1')[0].innerText).replace(zfrom,zto) + '&body=' + encodeURIComponent(newurl); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + sparewes.document.body.innerHTML.split('<h2')[1]));
} else {
azx.href = 'mailto:' + inidea + '?subject=' + encodeURIComponent(document.getElementsByTagName('h1')[0].innerText).replace(zfrom,zto) + '&body=' + encodeURIComponent(newurl); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
}
//}
azx.click();
if (!oops && tabularize == 'Null' && !document.getElementById('tablemy')) {
location.href=newurl;
}
if (!updatehowlong) {
updatehowlong=true;
setInterval(upscore, 5000);
}
return '';
}

function dosms() {
if (('' + window.localStorage.getItem('findwordcollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defemail=window.localStorage.getItem('findwordcollaboratoremailee');
}
if (('' + window.localStorage.getItem('findwordcollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defsms=window.localStorage.removeItem('findwordcollaboratorsmsno');
}
//alert('' + eval('' + ('sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#bih=' + encodeURIComponent(parent.hfanalyze()))).length));
if (1 == 1 || eval('' + ('sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(mode.trim()) + '&across=' + numlettersacross + '&down=' + numlettersdown + '&fontpixels=' + fontpixels + '&wordlenmin=' + minwordlength + '&wordlenmax=' + maxwordlength + '&table=' + tabularize + '#' + encodeURIComponent(jhis.replace(/\<br\>/g,'')))).length) >= 18000) {
snum=('' + prompt('Please enter SMS number to send to. We suspect message is too long for an SMS and if you enter an email address here instead, we will try to send an email instead. Append space(s) to remember, whatever you enter, for next time.', snum)).replace(/^null/g, (defemail.indexOf('@') != -1 ? defemail : (defsms != '' ? defsms : '')) );
} else {
snum=('' + prompt('Please enter SMS number to send to. Append space(s) to remember for next time.', snum)).replace(/^null/g, (defsms != '' ? defsms : (defemail.indexOf('@') != -1 ? defemail : '')));
}
if (snum == null) { snum=''; }
if (snum.indexOf('@') != -1) {
if (snum.trim() != snum) {
snum=snum.trim();
if (('' + window.localStorage.getItem('findwordcollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('findwordcollaboratoremailee');
}
window.localStorage.setItem('findwordcollaboratoremailee', snum);
defemail=snum;
}
return doemail(snum);
} else if (snum.trim() != '' && snum.trim().replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'').trim() == '') {
//alert('Snum=' + snum + '?');
if (snum.trim() != snum) {
snum=snum.trim();
if (('' + window.localStorage.getItem('findwordcollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('findwordcollaboratorsmsno');
}
window.localStorage.setItem('findwordcollaboratorsmsno', snum);
defsms=snum;
}
var azx=top.document.getElementById('xas' + 'ms');
if (azx == null) { azx=top.document.createElement("a"); }
//if (1 == 1) {
// document.getElementById('divas').appendChild(azx);
//} else {
top.document.body.appendChild(azx);
// }
azx.id = 'xas' + 'ms';
azx.target = "_top";
azx.style = "display: none";
var newurl=document.URL.split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(mode.trim()) + '&across=' + numlettersacross + '&down=' + numlettersdown + '&fontpixels=' + fontpixels + '&wordlenmin=' + minwordlength + '&wordlenmax=' + maxwordlength + '&table=' + tabularize + '#' + encodeURIComponent(jhis.replace(/\<br\>/g,''));
if (!oops && tabularize == 'Null' && !document.getElementById('tablemy')) {
newurl=document.URL.split('?')[0].split('#')[0] + '?mode=' + encodeURIComponent(mode.trim()) + '&across=' + numlettersacross + '&down=' + numlettersdown + '&fontpixels=' + fontpixels + '&wordlenmin=' + minwordlength + '&wordlenmax=' + maxwordlength + '&table=y#' + encodeURIComponent(jhis.replace(/\<br\>/g,''));
}
azx.href = 'sms:' + snum + '&body=' + encodeURIComponent(newurl.replace('#','&').replace('?','#')); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
azx.click();
if (!oops && tabularize == 'Null' && !document.getElementById('tablemy')) {
location.href=newurl;
}
if (!updatehowlong) {
updatehowlong=true;
setInterval(upscore, 5000);
}
}
return '';
}

function emailaskit() {
if (defemail == defemail.trim()) {
defemail=defemail.trim() + ' ';
var emailm=prompt('Enter default email address.', defemail.trim());
if (emailm == null) { emailm=''; }
if (emailm.trim() != '' && emailm.trim().indexOf('@') != -1) {
defemail=emailm.trim() + ' ';
if (('' + window.localStorage.getItem('findwordcollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defemail=window.localStorage.removeItem('findwordcollaboratoremailee');
}
window.localStorage.setItem('findwordcollaboratoremailee', emailm.trim());
}
}
defemail=defemail.trim() + ' ';
}

function smsaskit() {
if (defsms == defsms.trim()) {
defsms=defsms.trim() + ' ';
var smsm=prompt('Enter default SMS number.', defsms.trim());
if (smsm == null) { smsm=''; }
if (smsm.trim() != '' && smsm.trim().replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'').trim() == '') {
defsms=smsm.trim() + ' ';
if (('' + window.localStorage.getItem('findwordcollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('findwordcollaboratorsmsno');
}
window.localStorage.setItem('findwordcollaboratorsmsno', smsm.trim());
}
}
defsms=defsms.trim() + ' ';
}

… with that “midair feeling” approach to the “a” “mailto:” and/or “sms:” links used via the 📧 (email) and/or 📟 (SMS) emoji buttons now available in the changed textarea_find_words.html Find the Words game.


Previous relevant Find English Mobile Clicked Word Ends Game Tutorial is shown below.

Find English Mobile Clicked Word Ends Game Tutorial

Find English Mobile Clicked Word Ends Game Tutorial

We tried making the mobile platforms work with the selectionchange event of yesterday’s Find English Highlighted Words Game Selection Tutorial‘s Find the Word game web application, but we decided, today …

  1. the default game operation for mobile platforms should be a new …
    • overlayed
    • table … based …
    • cell … onclick event based …
    • modus operandi … for each end of the user chosen words (as user clicked)

    … means by which to play the game … as well as …

  2. the default game operation for non-mobile platforms remains the old textarea selectionchange event methodology … but either above …
  3. defaults can be overridden by a new address bar URL argument

We made the selectionchange event range.start and range.end form the suffix of those “cell” element “IDs” above within the following document.body onload event function


var tabularize=location.search.split('table=')[1] ? (decodeURIComponent(location.search.split('table=')[1].split('&')[0])) : 'Null';

function pickletters() {
var valis='', randval=eval(Math.floor(Math.random() * 26) % 26), ihis='', lvalis='';
for (var ir=1; ir<=numlettersdown; ir++) {
lvalis='';
for (var ic=1; ic<=numlettersacross; ic++) {
valis+=String.fromCharCode(eval(randval + 'A'.charCodeAt(0)));
lvalis+=String.fromCharCode(eval(randval + 'A'.charCodeAt(0)));
if (eval(linesarr.length) < ir) {
linesarr.push(valis.slice(-1));
} else {
linesarr[eval(-1 + ir)]+=valis.slice(-1);
}
if (eval(colsarr.length) < ic) {
colsarr.push(valis.slice(-1));
} else {
colsarr[eval(-1 + ic)]+=valis.slice(-1);
}
ihis+=String.fromCharCode(eval(randval + 'A'.charCodeAt(0)));
randval=eval(Math.floor(Math.random() * 26) % 26);
}
origcomplines.push(lvalis);
lvalis='';
if (ir < 50) {
valis+=String.fromCharCode(10);
ihis+='<br>';
}
}
//alert(valis);
document.getElementById('myta').value=valis;
eol=document.getElementById('myta').value.substring(numlettersacross).split('A')[0].split('B')[0].split('C')[0].split('D')[0].split('E')[0].split('F')[0].split('G')[0].split('H')[0].split('I')[0].split('J')[0].split('K')[0].split('L')[0].split('M')[0].split('N')[0].split('O')[0].split('P')[0].split('Q')[0].split('R')[0].split('S')[0].split('T')[0].split('U')[0].split('V')[0].split('W')[0].split('X')[0].split('Y')[0].split('Z')[0];
oureol=eol;
var lris='ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
for (var ii=0; ii<lris.length; ii++) {
letteremojis.push(orflag(lris[ii]));
blankemojis.push(' '); // ' ';
loweremojis.push(lris[ii].toLowerCase()); // ' ';
upperemojis.push(lris[ii].toUpperCase()); // ' ';
}
firstval=document.getElementById('myta').value;
document.getElementById('mya').href=document.URL.split('#')[0];
if ((tabularize + 'n').toLowerCase().substring(0,1) == 'y' || (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i) && tabularize == 'Null')) {
document.getElementById('myh1').innerHTML=document.getElementById('myh1').innerHTML.replace('Highlighting', 'Click Start/End')
var rectta=document.getElementById('myta').getBoundingClientRect();
var trline='', ninis=0, icis=0, jicis=0, lettersare=[], tableouter=document.getElementsByTagName('textarea')[0].outerHTML.replace(' style="', ' style="position:absolute;z-index:92;opacity:1.0;background-color:rgba(0,255,0,0.6);top:0px;left:0px;margin:0 0 0 0;padding:0 0 0 0;').replace('myta', 'tablemy').replace(/textarea/g,'table');
for (icis=0; icis<origcomplines.length; icis++) {
lettersare=origcomplines[icis].split('');
trline='<tr></tr>';
for (jicis=0; jicis<lettersare.length; jicis++) {
trline=trline.replace('</tr>', '<td id=td' + ninis + ' onclick=tdanalyze(this);>' + lettersare[jicis] + '</td></tr>');
ninis++;
}
for (jicis=0; jicis<eol.length; jicis++) {
ninis++;
}
tableouter=tableouter.replace('</table>', trline + '</table>');
}
document.body.style.backgroundColor='white';
document.getElementById('myta').style.visibility='hidden';
if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
document.getElementById('tdright').style.textAlign='right';
}
document.getElementById('dtable').innerHTML=tableouter;
if (document.getElementById('mybut')) { document.getElementById('mybut').style.display='none'; }
tableih=document.getElementById('dtable').innerHTML;
}

if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
if (!document.getElementById('tablemy')) { ioff=10000; }
if (!document.getElementById('tablemy')) { clickthere=false; }
}
}

And that way we hived off most of the selectionchange event logic into a global variable sensitive new Javascript function hansel called by both methodologies above …


var tog=['lightgreen', 'olive'];

function hansel() {
var joff=rstart, koff=eval('' + eol.length);
lesssel=thesel;
var huheol=eol;
if (huheol == '') { huheol=String.fromCharCode(10); }
while (lesssel.indexOf(huheol) != -1) {
lesssel=lesssel.replace(huheol, '');
}
complines=(thesel + '~').replace(huheol + '~', '').replace('~','').split(huheol);
//diagl=eval('' + complines.length);
//diagl+=eval(eval(-1 + eval('' + complines.length)) * 80);
//document.title='' + eval('' + lesssel.length) + ' vs ' + eval(eval(eval(-1 + eval('' + complines.length)) * 80) + eval(2 - eval('' + complines.length)));
if (sofar.indexOf(';' + thesel + ';') != -1) {
document.title=document.title.replace('Score:','Score+'); //'Score :' + document.getElementById('score').innerHTML.split('Score:')[1] + ' ... Repeat selection ...';
} else if (sofar.indexOf(';' + thesel + ';') == -1 && eval('' + complines.length) >= minwordlength && eval('' + complines.length) <= maxwordlength && eval('' + lesssel.length) == eval(eval(eval('' + complines.length) + eval(eval(-1 + eval('' + complines.length)) * numlettersacross)))) {
// 3 goes with 163 (2x80 + 3) or 159 (2x80 - 1)
// 4 goes with 244 (3x80 + 4) or 238 (3x80 - 2)
// 5 goes with 325 (4x80 + 5) or 317 (4x80 - 3)
icols=0;
twowordstocheck=[lesssel.substring(icols).toUpperCase().substring(0,1), lesssel.substring(icols).toUpperCase().substring(0,1)];
tworesults=['',''];
//eol=complines[1].substring(numlettersacross);
xnumlettersacross=eval(eval('' + eol.length) + eval('' + numlettersacross));
altsel=thesel.substring(0,1).toLowerCase() + complines[0].substring(1).split(eol)[0] + eol;
//rstart=eval('' + range.start);
//rend=eval('' + range.end);
indxofinterest=eval(rstart % eval(1 * eval(eval('' + eol.length) + eval('' + numlettersacross))));
indxofinterest++;
oureol=eol;
for (ilines=1; ilines<eval('' + complines.length); ilines++) {
if (eval(1 + ilines) >= eval('' + complines.length)) { oureol=''; }
icols+=eval(1 + numlettersacross);
joff+=eval(1 + numlettersacross);
if (document.getElementById('td' + eval(joff + koff))) {
if (document.getElementById('td' + eval(joff + koff)).outerHTML.indexOf('pink') == -1) { lastpinks.push('td' + eval(joff + koff)); }
document.getElementById('td' + eval(joff + koff)).style.backgroundColor='pink';
koff+=eval('' + eol.length);
}
if (indxofinterest > 0) {
altsel+=complines[ilines].substring(0,indxofinterest).toUpperCase() + complines[ilines].substring(indxofinterest).substring(0,1).toLowerCase() + complines[ilines].substring(eval(1 + indxofinterest)).toUpperCase() + oureol;
} else {
altsel+=complines[ilines].substring(0,1).toLowerCase() + complines[ilines].substring(1).toUpperCase() + oureol;
}
indxofinterest++;
twowordstocheck[0]+=lesssel.substring(icols).toUpperCase().substring(0,1);
//alert('twowordstocheck_so_far=' + twowordstocheck[0] + ' ilines=' + ilines + ' rstart % xnumlettersacross+=' + eval(rstart % xnumlettersacross) + ' rstart % numlettersacross=' + eval(rstart % numlettersacross) + ' rstart=' + rstart + ' rend=' + rend + ' complines[ilines]=' + complines[ilines] + ' altsel_so_far=' + altsel);
twowordstocheck[1]=lesssel.substring(icols).toUpperCase().substring(0,1) + twowordstocheck[1];
}
altsel+=thesel.substring(rend);
//alert('twowordstocheck_so_far=' + twowordstocheck[0] + ' ilines=' + ilines + ' rstart % xnumlettersacross+=' + eval(rstart % xnumlettersacross) + ' rstart % numlettersacross=' + eval(rstart % numlettersacross) + ' rstart=' + rstart + ' rend=' + rend + ' complines[ilines]=' + complines[ilines] + ' altsel_so_far=' + altsel);
document.title='Left Diagonal words ' + twowordstocheck[0] + ' and ' + twowordstocheck[1] + ' being checked ...';
documenttitle=' ' + document.title;
document.getElementById('results').style.backgroundColor='pink';
document.getElementById('results').innerHTML=documenttitle.replace(' words ', ' words <br> ').replace(' being checked', ' <br> being checked');
document.getElementById('myta').style.backgroundColor='rgb(230,230,230)';
if (!document.getElementById('tablemy')) {
if (document.getElementById('mybut')) { document.getElementById('mybut').disabled=false; document.getElementById('mybut').style.display='block'; }
}
sofar+=thesel + ';';
//document.getElementById('myta').style.cursor='progress';
if (!showsel) { setTimeout(preshowthesel, eval(ioff + 4000)); setTimeout(showthesel, eval(ioff + 6000)); }
//rstart=eval('' + range.start);
//rend=eval('' + range.end);
isg1=true;
ish=false;
isd=false;
isg0=false;
showsel=true;
} else if (sofar.indexOf(';' + thesel + ';') == -1 && eval('' + complines.length) >= minwordlength && eval('' + complines.length) <= maxwordlength && eval('' + lesssel.length) == eval(eval(eval(-1 + eval('' + complines.length)) * numlettersacross) + eval(2 - eval('' + complines.length)))) {
// 3 goes with 163 (2x80 + 3) or 159 (2x80 - 1)
// 4 goes with 244 (3x80 + 4) or 238 (3x80 - 2)
// 5 goes with 325 (4x80 + 5) or 317 (4x80 - 3)
icols=0;
twowordstocheck=[lesssel.substring(icols).toUpperCase().substring(0,1), lesssel.substring(icols).toUpperCase().substring(0,1)];
tworesults=['',''];
sofar+=thesel + ';';
//eol=complines[1].substring(numlettersacross);
xnumlettersacross=eval(eval('' + eol.length) + eval('' + numlettersacross));
altsel=thesel.substring(0,1).toLowerCase() + complines[0].substring(1).split(eol)[0] + eol;
//rstart=eval('' + range.start);
//rend=eval('' + range.end);
indxofinterest=eval(rstart % eval(1 * eval(eval('' + eol.length) + eval('' + numlettersacross))));
indxofinterest--;
oureol=eol;
for (ilines=1; ilines<eval('' + complines.length); ilines++) {
if (eval(1 + ilines) >= eval('' + complines.length)) { oureol=''; }
icols+=eval(-1 + numlettersacross);
joff+=eval(-1 + numlettersacross);
if (document.getElementById('td' + eval(joff + koff))) {
if (document.getElementById('td' + eval(joff + koff)).outerHTML.indexOf('pink') == -1) { lastpinks.push('td' + eval(joff + koff)); }
document.getElementById('td' + eval(joff + koff)).style.backgroundColor='pink';
koff+=eval('' + eol.length);
}
if (indxofinterest > 0) {
altsel+=complines[ilines].substring(0,indxofinterest).toUpperCase() + complines[ilines].substring(indxofinterest).substring(0,1).toLowerCase() + complines[ilines].substring(eval(1 + indxofinterest)).toUpperCase() + oureol;
} else {
altsel+=complines[ilines].substring(0,1).toLowerCase() + complines[ilines].substring(1).toUpperCase() + oureol;
}
indxofinterest--;
twowordstocheck[0]+=lesssel.substring(icols).toUpperCase().substring(0,1);
//alert('Twowordstocheck_so_far=' + twowordstocheck[0] + ' ilines=' + ilines + ' rstart % xnumlettersacross+=' + eval(rstart % xnumlettersacross) + ' rstart % numlettersacross=' + eval(rstart % numlettersacross) + ' rstart=' + rstart + ' rend=' + rend + ' complines[ilines]=' + complines[ilines] + ' altsel_so_far=' + altsel);
twowordstocheck[1]=lesssel.substring(icols).toUpperCase().substring(0,1) + twowordstocheck[1];
}
altsel+=thesel.substring(rend);
document.title='Right Diagonal words ' + twowordstocheck[0] + ' and ' + twowordstocheck[1] + ' being checked ...';
documenttitle=' ' + document.title;
document.getElementById('results').style.backgroundColor='pink';
document.getElementById('results').innerHTML=documenttitle.replace(' words ', ' words <br> ').replace(' being checked', ' <br> being checked');
document.getElementById('myta').style.backgroundColor='rgb(245,245,245)';
if (!document.getElementById('tablemy')) {
if (document.getElementById('mybut')) { document.getElementById('mybut').disabled=false; document.getElementById('mybut').style.display='block'; }
}
//document.getElementById('myta').style.cursor='progress';
if (!showsel) { setTimeout(preshowthesel, eval(ioff + 4000)); setTimeout(showthesel, eval(ioff + 6000)); }
//rstart=eval('' + range.start);
//rend=eval('' + range.end);
isg0=true;
ish=false;
isd=false;
isg1=false;
showsel=true;
} else if (sofar.indexOf(';' + thesel + ';') == -1 && eval('' + complines.length) >= minwordlength && eval('' + complines.length) <= maxwordlength && eval(-1 + eval('' + lesssel.length)) == eval(eval(eval(-1 + eval('' + complines.length)) * numlettersacross) + eval(0 * eval('' + complines.length)))) {
// 6 goes with 401
// 4 goes with 241
icols=0;
twowordstocheck=[lesssel.substring(icols).toUpperCase().substring(0,1), lesssel.substring(icols).toUpperCase().substring(0,1)];
tworesults=['',''];
sofar+=thesel + ';';
//eol=complines[1].substring(numlettersacross);
xnumlettersacross=eval(eval('' + eol.length) + eval('' + numlettersacross));
altsel=thesel.substring(0,1).toLowerCase() + complines[0].substring(1).split(eol)[0] + eol;
//rstart=eval('' + range.start);
//rend=eval('' + range.end);
indxofinterest=eval(rstart % eval(1 * eval(eval('' + eol.length) + eval('' + numlettersacross))));
oureol=eol;
for (ilines=1; ilines<eval('' + complines.length); ilines++) {
icols+=numlettersacross;
joff+=numlettersacross;
if (document.getElementById('td' + eval(joff + koff))) {
if (document.getElementById('td' + eval(joff + koff)).outerHTML.indexOf('pink') == -1) { lastpinks.push('td' + eval(joff + koff)); }
document.getElementById('td' + eval(joff + koff)).style.backgroundColor='pink';
koff+=eval('' + eol.length);
}
if (eval(1 + ilines) >= eval('' + complines.length)) { oureol=''; }
if (indxofinterest > 0) {
altsel+=complines[ilines].substring(0,indxofinterest).toUpperCase() + complines[ilines].substring(indxofinterest).substring(0,1).toLowerCase() + complines[ilines].substring(eval(1 + indxofinterest)).toUpperCase() + oureol;
} else {
altsel+=complines[ilines].substring(0,1).toLowerCase() + complines[ilines].substring(1).toUpperCase() + oureol;
}
twowordstocheck[0]+=lesssel.substring(icols).toUpperCase().substring(0,1);
//alert('TWowordstocheck_so_far=' + twowordstocheck[0] + ' indxofinterest=' + indxofinterest + ' ilines=' + ilines + ' rstart % xnumlettersacross+=' + eval(rstart % xnumlettersacross) + ' rstart % numlettersacross=' + eval(rstart % numlettersacross) + ' rstart=' + rstart + ' rend=' + rend + ' complines[ilines]=' + complines[ilines] + ' altsel_so_far=' + altsel);
twowordstocheck[1]=lesssel.substring(icols).toUpperCase().substring(0,1) + twowordstocheck[1];
}
altsel+=thesel.substring(rend);
//alert('TWowordstocheck_so_far=' + twowordstocheck[0] + ' indxofinterest=' + indxofinterest + ' ilines=' + ilines + ' rstart % xnumlettersacross+=' + eval(rstart % xnumlettersacross) + ' rstart % numlettersacross=' + eval(rstart % numlettersacross) + ' rstart=' + rstart + ' rend=' + rend + ' complines[ilines]=' + complines[ilines] + ' altsel_so_far=' + altsel);
document.title='Down words ' + twowordstocheck[0] + ' and ' + twowordstocheck[1] + ' being checked ...';
documenttitle=' ' + document.title;
document.getElementById('results').style.backgroundColor='pink';
document.getElementById('results').innerHTML=documenttitle.replace(' words ', ' words <br> ').replace(' being checked', ' <br> being checked');
document.getElementById('myta').style.backgroundColor='rgb(230,230,230)';
if (!document.getElementById('tablemy')) {
if (document.getElementById('mybut')) { document.getElementById('mybut').disabled=false; document.getElementById('mybut').style.display='block'; }
}
//document.getElementById('myta').style.cursor='progress';
if (!showsel) { setTimeout(preshowthesel, eval(ioff + 4000)); setTimeout(showthesel, eval(ioff + 6000)); }
//rstart=eval('' + range.start);
//rend=eval('' + range.end);
isd=true;
ish=false;
isg1=false;
isg0=false;
showsel=true;
} else if (sofar.indexOf(';' + thesel + ';') == -1 && thesel.indexOf(String.fromCharCode(10)) == -1 && eval('' + thesel.length) >= minwordlength && eval('' + thesel.length) <= maxwordlength) {
//alert('Horizontal word ' + eval('' + thesel.length) + ' ... ' + thesel);
twowordstocheck=[lesssel.toUpperCase(), lesssel.split('').reverse().join('').toUpperCase()];
tworesults=['',''];
sofar+=thesel + ';';
document.title='Horizontal words ' + twowordstocheck[0] + ' and ' + twowordstocheck[1] + ' being checked ...';
documenttitle=' ' + document.title;
document.getElementById('results').style.backgroundColor='pink';
document.getElementById('results').innerHTML=documenttitle.replace(' words ', ' words <br> ').replace(' being checked', ' <br> being checked');
document.getElementById('myta').style.backgroundColor='rgb(230,230,230)';
if (document.getElementById('tablemy')) {
for (var iicols=rstart; iicols<=rend; iicols++) {
if (document.getElementById('td' + iicols)) {
if (document.getElementById('td' + iicols).outerHTML.indexOf('pink') == -1) { lastpinks.push('td' + iicols); }
document.getElementById('td' + iicols).style.backgroundColor='pink';
}
}
}
if (!document.getElementById('tablemy')) {
if (document.getElementById('mybut')) { document.getElementById('mybut').disabled=false; document.getElementById('mybut').style.display='block'; }
}
//document.getElementById('myta').style.cursor='progress';
if (!showsel) { setTimeout(preshowthesel, eval(ioff + 4000)); setTimeout(showthesel, eval(ioff + 6000)); }
showsel=true;
//rstart=eval('' + range.start);
//rend=eval('' + range.end);
ish=true;
isg1=false;
isd=false;
isg0=false;
} else {
document.title='Score:' + document.getElementById('score').innerHTML.split('Score:')[1] + ' ... Find the Words Highlighting Game - RJM Programming - March, 2024';
}
}

function handleSelection() { // thanks to https://stackoverflow.com/questions/46651479/reacting-to-selection-changes-in-an-html-textarea
const activeElement = document.activeElement;

// Make sure this is your textarea
if (activeElement && activeElement.outerHTML.indexOf('<textarea') == 0) {
const range = {
start: activeElement.selectionStart,
end: activeElement.selectionEnd
};
// Do something with your range
isvalid=true;
if (!document.getElementById('tablemy') && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
for (iiis=0; iiis<origcomplines.length; iiis++) {
if (thesel.indexOf(origcomplines[iiis]) == 0) {
isvalid=false;
}
}
}
if (isvalid && eval('' + range.end) > eval('' + range.start)) {
thesel=(activeElement.value.substring(range.start).substring(0, eval(eval('' + range.end) - eval('' + range.start) )));
rstart=eval('' + range.start);
rend=eval('' + range.end);
hansel();
}
}
}

document.addEventListener('selectionchange', handleSelection);

… in the changed textarea_find_words.html Find the Words game.


Previous relevant Find English Highlighted Words Game Selection Tutorial is shown below.

Find English Highlighted Words Game Selection Tutorial

Find English Highlighted Words Game Selection Tutorial

Thinking about yesterday’s Find English Highlighted Words Game Primer Tutorial‘s first draft of a Find the Word game web application, we found it easy to pinpoint where to improve it …

  • better informing the user when a textarea selection event detection caused an analysis of the word forwards and backwards to be analyzed … and flagging this better for them …

    function preshowthesel() {
    if (showsel) {
    if (rend >= 0 && rstart >= 0) {
    if (!clickthere) {
    setTimeout(preshowthesel, 5000);
    return '';
    }
    if (isd || isg0 || isg1) {
    if (altsel.trim() != '' && thesel != '') {
    //alert('here ' + document.getElementById('myta').value.indexOf(thesel) + ' ... ' + altsel)
    document.getElementById('myta').setAttribute('data-alt', encodeURIComponent(document.getElementById('myta').value.replace(thesel.substring(0,eval('' + altsel.length)), hlem(altsel))));
    document.getElementById('myta').value=ovlem(document.getElementById('myta').value.replace(thesel.substring(0,eval('' + altsel.length)), lem(altsel)));
    } else if (altsel.trim() != '' && lastsel != '') {
    //alert('hEre ' + document.getElementById('myta').value.indexOf(lastsel) + ' ... ' + altsel)
    document.getElementById('myta').setAttribute('data-alt', encodeURIComponent(document.getElementById('myta').value.replace(lastsel.substring(0,eval('' + altsel.length)), lem(altsel))));
    document.getElementById('myta').value=ovlem(document.getElementById('myta').value.replace(lastsel.substring(0,eval('' + altsel.length)), lem(altsel)));
    } // else {
    //alert('Why? ' + thesel);
    //}
    } else if (ish) {
    if (eval('' + rstart) > 0) {
    document.getElementById('myta').setAttribute('data-alt', encodeURIComponent(document.getElementById('myta').value.substring(0,rstart).toUpperCase() + hlem(document.getElementById('myta').value.substring(rstart).substring(0, eval(eval('' + rend) - eval('' + rstart) )).toLowerCase()) + document.getElementById('myta').value.substring(rend).toUpperCase()));
    document.getElementById('myta').value=togglelem(document.getElementById('myta').value.substring(0,rstart).toUpperCase() + hlem(document.getElementById('myta').value.substring(rstart).substring(0, eval(eval('' + rend) - eval('' + rstart) )).toLowerCase()) + document.getElementById('myta').value.substring(rend).toUpperCase());
    } else {
    document.getElementById('myta').setAttribute('data-alt', encodeURIComponent(hlem(document.getElementById('myta').value.substring(rstart).substring(0, eval(eval('' + rend) - eval('' + rstart) )).toLowerCase()) + document.getElementById('myta').value.substring(rend).toUpperCase()));
    document.getElementById('myta').value=togglelem(hlem(document.getElementById('myta').value.substring(rstart).substring(0, eval(eval('' + rend) - eval('' + rstart) )).toLowerCase()) + document.getElementById('myta').value.substring(rend).toUpperCase());
    }
    }
    }
    altsel=' ';
    }
    }

    … as your starting point …
  • parameterizations via ? and & address bar URL arguments … pretty self explanatory via …

    var minwordlength=location.search.split('min=')[1] ? Math.min(3,eval(decodeURIComponent(location.search.split('min=')[1].split('&')[0]))) : 3;
    var maxwordlength=location.search.split('max=')[1] ? eval(decodeURIComponent(location.search.split('max=')[1].split('&')[0])) : 15;
    var numlettersacross=location.search.split('across=')[1] ? eval(decodeURIComponent(location.search.split('across=')[1].split('&')[0])) : 76;
    var numlettersdown=location.search.split('down=')[1] ? eval(decodeURIComponent(location.search.split('down=')[1].split('&')[0])) : 40;
    var fontpixels=location.search.split('pixels=')[1] ? eval(decodeURIComponent(location.search.split('pixels=')[1].split('&')[0])) : 13;
  • regional indicator based emoji numerical display helpers for down and diagonal user guesses … in an overlayed textarea element … using …

    var letteremojis=[], blankemojis=[], loweremojis=[], upperemojis=[];

    var lris='ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
    for (var ii=0; ii<lris.length; ii++) {
    letteremojis.push(orflag(lris[ii]));
    blankemojis.push(' '); // ' ';
    loweremojis.push(lris[ii].toLowerCase()); // ' ';
    upperemojis.push(lris[ii].toUpperCase()); // ' ';
    }

    function orflag(thiscc) {
    var lri='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var dri=['127462','127463','127464','127465','127466','127467','127468','127469','127470','127471','127472','127473','127474','127475','127476','127477','127478','127479','127480','127481','127482','127483','127484','127485','127486','127487'];
    var ccsuff='', ccchar=' ', cde='';
    for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
    ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
    ccsuff+=String.fromCodePoint(dri[eval('' + lri.indexOf(ccchar))]); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
    cde='.';
    }
    return ccsuff;
    }

    … as an ascii letter to emoji mapping mechanism … or …
  • toggle the display text case for horizontal user guesses … in an overlayed textarea element … using …

    function togglelem(insg) {
    var outsg='';
    var inarr=insg.split('');
    for (var jin=0; jin<insg.length; jin++) {
    if (insg.substring(jin).substring(0,1) == insg.substring(jin).substring(0,1).toLowerCase() && insg.substring(jin).substring(0,1) != insg.substring(jin).substring(0,1).toUpperCase()) {
    outsg+=insg.substring(jin).substring(0,1).toUpperCase();
    } else if (insg.substring(jin).substring(0,1) != insg.substring(jin).substring(0,1).toLowerCase() && insg.substring(jin).substring(0,1) == insg.substring(jin).substring(0,1).toUpperCase()) {
    outsg+=insg.substring(jin).substring(0,1).toLowerCase();
    } else {
    outsg+=insg.substring(jin).substring(0,1)
    }
    }
    return outsg;
    }
  • add a very simple text CSS styling embellisher …
    <style>

    textarea {
    text-shadow: -1px 1px 1px #952dff;
    }

    </style>
  • use the webpage title (on web browser tab) to allow a synopsis without resorting to right hand information, perhaps … via …

    document.title='Score:' + document.getElementById('score').innerHTML.split('Score:')[1] + ' ... Find the Words Highlighting Game - RJM Programming - March, 2024';

… in the changed textarea_find_words.html Find the Words game.


Previous relevant Find English Highlighted Words Game Primer Tutorial is shown below.

Find English Highlighted Words Game Primer Tutorial

Find English Highlighted Words Game Primer Tutorial

Yesterday’s Event Calendar Collaboration Textarea Highlight Linking Tutorial gave us an idea for an English Word Game based on the use of the “/usr/share/dict/words” inbuilt, in our case, English, dictionary you get to look up for free on macOS and Linux web server systems.

This highlighting within a sea of letters presented in a textarea was the framework for users to play a game highlighting …

  • horizontally
  • vertically
  • diagonally

… words in left to right or top to bottom order, or reversed, to score in our “Find the Words” game presented today.

You might question the design here. Highlighting within a textarea element is easy to understand for the horizontal option above, but how does it work for the other two? Well, the textarea selection start position relative to the selection end position can differentiate between the last two options above, as well as for none of the above. And we hope to help with some better display smarts with future releases.

Take a look at the crucial selectionchange event logic for today’s Find the Word game …


function handleSelection() { // thanks to https://stackoverflow.com/questions/46651479/reacting-to-selection-changes-in-an-html-textarea
const activeElement = document.activeElement;

// Make sure this is your textarea
if (activeElement && activeElement.outerHTML.indexOf('<textarea') == 0) {
const range = {
start: activeElement.selectionStart,
end: activeElement.selectionEnd
};
// Do something with your range
if (eval('' + range.end) > eval('' + range.start)) {
thesel=(activeElement.value.substring(range.start).substring(0, eval(eval('' + range.end) - eval('' + range.start) )));
lesssel=thesel;
while (lesssel.indexOf(String.fromCharCode(10)) != -1) {
lesssel=lesssel.replace(String.fromCharCode(10), '');
}
complines=thesel.split(String.fromCharCode(10));
//diagl=eval('' + complines.length);
//diagl+=eval(eval(-1 + eval('' + complines.length)) * 80);
//document.title='' + eval('' + lesssel.length) + ' vs ' + eval(eval(eval(-1 + eval('' + complines.length)) * 80) + eval(2 - eval('' + complines.length)));
if (sofar.indexOf(';' + thesel + ';') != -1) {
document.title='Repeat selection ...';
} else if (sofar.indexOf(';' + thesel + ';') == -1 && eval('' + complines.length) >= 3 && eval('' + lesssel.length) == eval(eval(eval('' + complines.length) + eval(eval(-1 + eval('' + complines.length)) * 80)))) {
// 3 goes with 163 (2x80 + 3) or 159 (2x80 - 1)
// 4 goes with 244 (3x80 + 4) or 238 (3x80 - 2)
// 5 goes with 325 (4x80 + 5) or 317 (4x80 - 3)
icols=0;
twowordstocheck=[lesssel.substring(icols).substring(0,1), lesssel.substring(icols).substring(0,1)];
tworesults=['',''];
for (ilines=1; ilines<eval('' + complines.length); ilines++) {
icols+=81;
twowordstocheck[0]+=lesssel.substring(icols).substring(0,1);
twowordstocheck[1]=lesssel.substring(icols).substring(0,1) + twowordstocheck[1];
}
document.title='Left Diagonal words ' + twowordstocheck[0] + ' and ' + twowordstocheck[1] + ' being checked ...';
documenttitle=' ' + document.title;
document.getElementById('results').innerHTML=documenttitle;
sofar+=thesel + ';';
//document.getElementById('myta').style.cursor='progress';
if (!showsel) { setTimeout(showthesel, 5000); }
showsel=true;
} else if (sofar.indexOf(';' + thesel + ';') == -1 && eval('' + complines.length) >= 3 && eval('' + lesssel.length) == eval(eval(eval(-1 + eval('' + complines.length)) * 80) + eval(2 - eval('' + complines.length)))) {
// 3 goes with 163 (2x80 + 3) or 159 (2x80 - 1)
// 4 goes with 244 (3x80 + 4) or 238 (3x80 - 2)
// 5 goes with 325 (4x80 + 5) or 317 (4x80 - 3)
icols=0;
twowordstocheck=[lesssel.substring(icols).substring(0,1), lesssel.substring(icols).substring(0,1)];
tworesults=['',''];
sofar+=thesel + ';';
for (ilines=1; ilines<eval('' + complines.length); ilines++) {
icols+=79;
twowordstocheck[0]+=lesssel.substring(icols).substring(0,1);
twowordstocheck[1]=lesssel.substring(icols).substring(0,1) + twowordstocheck[1];
}
document.title='Right Diagonal words ' + twowordstocheck[0] + ' and ' + twowordstocheck[1] + ' being checked ...';
documenttitle=' ' + document.title;
document.getElementById('results').innerHTML=documenttitle;
//document.getElementById('myta').style.cursor='progress';
if (!showsel) { setTimeout(showthesel, 5000); }
showsel=true;
} else if (sofar.indexOf(';' + thesel + ';') == -1 && eval('' + complines.length) >= 3 && eval(-1 + eval('' + lesssel.length)) == eval(eval(eval(-1 + eval('' + complines.length)) * 80) + eval(0 * eval('' + complines.length)))) {
// 6 goes with 401
// 4 goes with 241
icols=0;
twowordstocheck=[lesssel.substring(icols).substring(0,1), lesssel.substring(icols).substring(0,1)];
tworesults=['',''];
sofar+=thesel + ';';
for (ilines=1; ilines<eval('' + complines.length); ilines++) {
icols+=80;
twowordstocheck[0]+=lesssel.substring(icols).substring(0,1);
twowordstocheck[1]=lesssel.substring(icols).substring(0,1) + twowordstocheck[1];
}
document.title='Down words ' + twowordstocheck[0] + ' and ' + twowordstocheck[1] + ' being checked ...';
documenttitle=' ' + document.title;
document.getElementById('results').innerHTML=documenttitle;
//document.getElementById('myta').style.cursor='progress';
if (!showsel) { setTimeout(showthesel, 5000); }
showsel=true;
} else if (sofar.indexOf(';' + thesel + ';') == -1 && thesel.indexOf(String.fromCharCode(10)) == -1 && eval('' + thesel.length) >= 3) {
//alert('Horizontal word ' + eval('' + thesel.length) + ' ... ' + thesel);
twowordstocheck=[lesssel, lesssel.split('').reverse().join('')];
tworesults=['',''];
sofar+=thesel + ';';
document.title='Horizontal words ' + twowordstocheck[0] + ' and ' + twowordstocheck[1] + ' being checked ...';
documenttitle=' ' + document.title;
document.getElementById('results').innerHTML=documenttitle;
//document.getElementById('myta').style.cursor='progress';
if (!showsel) { setTimeout(showthesel, 5000); }
showsel=true;
} else {
document.title='Find the Words Highlighting Game - RJM Programming - March, 2024';
}
}
}
}

document.addEventListener('selectionchange', handleSelection);

… in our first draft Find the Words game you can try below …


Previous relevant Event Calendar Collaboration Textarea Highlight Linking Tutorial is shown below.

Event Calendar Collaboration Textarea Highlight Linking Tutorial

Event Calendar Collaboration Textarea Highlight Linking Tutorial

For the first time we can remember, with our Events in Month web application of yesterday’s Event Calendar Collaboration Remembering Recipient Tutorial

  • we’re channelling how in emails “word strings” starting with “http” become links … and so …
  • in our event in month “blurb” textarea elements we allow user highlighted text containing such “http” “word strings” be opened in popup windows showing the content of those URLs, as available

Here is the relevant Javascript we ended up with, for this …


var thesel='', showsel=false, lastsel='';

function showthesel() {
var uwords=[], iuw=1, ils=0;
if (showsel) {
showsel=false;
if (lastsel != thesel && thesel.toLowerCase().replace('https:', 'http:').indexOf('http://') >= 0) {
lastsel=thesel;
thesel='';
}
if (lastsel != '' && thesel == '') {
uwords=lastsel.toLowerCase().split('http');
ils=eval(4 + eval('' + uwords[0].length));
for (iuw=1; iuw<uwords.length; iuw++) {
window.open('//' + lastsel.substring(ils).split('//')[1].split(' ')[0].split(String.fromCharCode(10))[0].split(String.fromCharCode(13))[0], '_blank', 'top=' + eval(10 * iuw + 50) + ',left=' + eval(10 * iuw + 50) + ',width=600,height=600');
ils+=eval(4 + eval('' + uwords[iuw].length));
}
}
}
}

function handleSelection() { // thanks to https://stackoverflow.com/questions/46651479/reacting-to-selection-changes-in-an-html-textarea
const activeElement = document.activeElement;

// Make sure this is your textarea
if (activeElement && activeElement.outerHTML.indexOf('<textarea') == 0) {
const range = {
start: activeElement.selectionStart,
end: activeElement.selectionEnd
};
// Do something with your range
if (eval('' + range.end) > eval('' + range.start)) {
thesel=(activeElement.value.substring(range.start).substring(0, eval(eval('' + range.end) - eval('' + range.start) )));
if (!showsel && thesel.toLowerCase().replace('https:', 'http:').indexOf('http://') >= 0) {
showsel=true;
setTimeout(showthesel, 5000);
}
}
}
}

document.addEventListener('selectionchange', handleSelection);

Also, today, we have a few CSS tweaks in the changed events_in_month.htm parent of the Events in Month web application. Feel free to try it for yourself.

Stop Press

Just briefly, delved into the wooooorrrrllllldddd of days of the week before 1582 debate … you had to be there … and in the words of Lleyton … Come on!!!! And we came out the other side. Good times! Anyway, thanks for all the interesting discussion, which we recommend you start at with this gem. Anyway, we now allow dates after 1582 (after this was previously set at 1970) in all respects and dates between 0000 and 1581 only via tweaks to the address bar URL you do yourself and we just hide the day of the week string. Otherwise … this could be needed?!


Previous relevant Event Calendar Collaboration Remembering Recipient Tutorial is shown below.

Event Calendar Collaboration Remembering Recipient Tutorial

Event Calendar Collaboration Remembering Recipient Tutorial

When doing our inhouse testing for Event Calendar Collaboration Tutorial the other day, it got us “peeved”, shall we say. We wanted a mechanism, with those “a” link “mailto:” emailing arrangements, of not having to fill out the email address in the “To:” field each time. First world problem alert! Still and all …

  • When it comes to procedures …
  • Aaaaaarrrrgggghhhh
  • Nuances count … regarding …
  • Errrrrrr
  • Saving time …
  • Saving frustration

… resulting in the “easy to remember” acronym WANESS … we rest our cases!

What can help here? Well, it is a personalization … so … anyone, anyone? Yes, Lou, back from holidays, a month late … yes, well, okay … we can see you’ve put some thought into this … HTTP Cookies could be used. Yes, Shwetank, you’ve had your hand up some time now. We agree, Web Storage window.localStorage allows for more data, so we’ll go with that, though either style of approach would work here.

Global variables initialization …

var defemail='', defsms='';
if (('' + window.localStorage.getItem('eventcollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defemail=window.localStorage.getItem('eventcollaboratoremailee');
}
if (('' + window.localStorage.getItem('eventcollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defsms=window.localStorage.removeItem('eventcollaboratorsmsno');
}
Within document.body onload event logic …

if (document.getElementById('semail') && document.getElementById('ssms')) {
document.getElementById('semail').oncontextmenu=function(){ emailaskit(); };
document.getElementById('semail').ontouchmove=function(){ emailaskit(); };
document.getElementById('ssms').oncontextmenu=function(){ smsaskit(); };
document.getElementById('ssms').ontouchmove=function(){ smsaskit(); };
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
document.getElementById('semail').title+=' Move gesture here can ask for new default remembered email address for collaboration purposes';
document.getElementById('ssms').title+=' Move gesture here can ask for new default remembered SMS number for collaboration purposes';
} else {
document.getElementById('semail').title+=' Right click here can ask for new default remembered email address for collaboration purposes';
document.getElementById('ssms').title+=' Right click here can ask for new default remembered SMS number for collaboration purposes';
}
}
Calling these two Javascript function helpers …

function emailaskit() {
if (defemail == defemail.trim()) {
defemail=defemail.trim() + ' ';
var emailm=prompt('Enter default email address.', defemail.trim());
if (emailm == null) { emailm=''; }
if (emailm.trim() != '' && emailm.trim().indexOf('@') != -1) {
defemail=emailm.trim() + ' ';
if (('' + window.localStorage.getItem('eventcollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defemail=window.localStorage.removeItem('eventcollaboratoremailee');
}
window.localStorage.setItem('eventcollaboratoremailee', emailm.trim());
}
}
defemail=defemail.trim() + ' ';
}

function smsaskit() {
if (defsms == defsms.trim()) {
defsms=defsms.trim() + ' ';
var smsm=prompt('Enter default SMS number.', defsms.trim());
if (smsm == null) { smsm=''; }
if (smsm.trim() != '' && smsm.trim().replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'').trim() == '') {
defsms=smsm.trim() + ' ';
if (('' + window.localStorage.getItem('eventcollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('eventcollaboratorsmsno');
}
window.localStorage.setItem('eventcollaboratorsmsno', smsm.trim());
}
}
defsms=defsms.trim() + ' ';
}
And allow control, as well, at the SMS prompt window logic

function dosms() {
if (('' + window.localStorage.getItem('eventcollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defemail=window.localStorage.getItem('eventcollaboratoremailee');
}
if (('' + window.localStorage.getItem('eventcollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defsms=window.localStorage.removeItem('eventcollaboratorsmsno');
}

//alert('' + eval('' + ('sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#bih=' + encodeURIComponent(parent.hfanalyze()))).length));
if (eval('' + ('sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#bih=' + encodeURIComponent(parent.hfanalyze()))).length) >= 18000) {
snum=('' + prompt('Please enter SMS number to send to. We suspect message is too long for an SMS and if you enter an email address here instead, we will try to send an email instead. Append space(s) to remember, whatever you enter, for next time.', snum)).replace(/^null/g, (defemail.indexOf('@') != -1 ? defemail : (defsms != '' ? defsms : '')) );
} else {
snum=('' + prompt('Please enter SMS number to send to. Append space(s) to remember for next time.', snum)).replace(/^null/g, (defsms != '' ? defsms : (defemail.indexOf('@') != -1 ? defemail : '')));
}
if (snum == null) { snum=''; }
if (snum.indexOf('@') != -1) {
if (snum.trim() != snum) {
snum=snum.trim();
if (('' + window.localStorage.getItem('eventcollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('eventcollaboratoremailee');
}
window.localStorage.setItem('eventcollaboratoremailee', snum);
defemail=snum;
}

return doemail(snum);
} else if (snum.trim() != '' && snum.trim().replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'').trim() == '') {
//alert('Snum=' + snum + '?');
if (snum.trim() != snum) {
snum=snum.trim();
if (('' + window.localStorage.getItem('eventcollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('eventcollaboratorsmsno');
}
window.localStorage.setItem('eventcollaboratorsmsno', snum);
defsms=snum;
}

var azx=top.document.getElementById('xas' + 'ms');
if (azx == null) { azx=top.document.createElement("a"); }
//if (1 == 1) {
// document.getElementById('divas').appendChild(azx);
//} else {
top.document.body.appendChild(azx);
// }
azx.id = 'xas' + 'ms';
azx.target = "_top";
azx.style = "display: none";
azx.href = 'sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#bih=' + encodeURIComponent(parent.hfanalyze()));
azx.click();
}
return '';
}

Also, today, we battled the logic to allow the textarea element onblur events also open the door to emailing and SMS “work in progress”. Believe it or not, this timing change was quite difficult in the changed events_in_month.htm parent of the Events in Month web application. Never a dull moment in web application I.T. we’d say!


Previous relevant Event Calendar Collaboration Tutorial is shown below.

Event Calendar Collaboration Tutorial

Event Calendar Collaboration Tutorial

The Event Calendar web application project, of Event Calendar PHP Bookmark Tutorial, from last year is worth a revisit, the reason being …

  • it did not have a fully fleshed out collaboration or sharing set of functionalities … at the time, probably, because …
  • each Monthly calendar filled out, and wanting to be saved, could involve much more than the 850 characters available to previous “mailto:” or “sms:” communication conduits, back to when we first tackled this project … but now …
  • hashtagging parts to the “mailto:” URLs (and maybe sometimes the “sms:” URL) might cover the data length needs

… so that this Event Calendar could be a web application at the center of a collaboration network of people working on that event organization. Much more useful, we figure!

Timing became really important with this integration of …

  • email
  • SMS

… communication conduit possibilities. With its design we have to wait until the point where the user is filling in textarea elements regarding a designated …

  1. Month
  2. Year

… of relevance, before we allow the email 📧 and SMS 📟 emoji buttons be shown. In the code …

Amended HTML h1 element static HTML to add, later shown, perhaps, email 📧 and SMS 📟 emoji buttons

<h1>Events in Month &nbsp;&nbsp;<button style=display:none; title='Share via Email' id=semail onclick="doemail('');">&#128231;</button> <button style=display:none; title='Share via SMS' id=ssms onclick=dosms();>&#128223;</button> </h1>
New static HTML div element placed to the bottom of the body element …

<div id=divas></div>
New Javascript global variables (picking up hashtagging parts of the address bar URL, perhaps linked off an email or SMS link clicked) …

var bigbih=('' + ('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'')).split('bih=')[1] ? (decodeURIComponent(('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'')).split('bih=')[1].split('&')[0]) : '';
if (bigbih != '' && bigbih.indexOf('xae' + 'mail') == -1) {
bigbih+='<a target=_blank id=xae' + 'mail style=display:none; href="mailto:"></a>';
}
if (bigbih != '' && bigbih.indexOf('xas' + 'ms') == -1) {
bigbih+='<a target=_blank id=xas' + 'ms style=display:none; href="sms:"></a>';
}
var viatext='', smallbih='', wes=null, sparewes=null;
On or around document.body onload event we can analyze any such location.hash hashtagging data …

if (bigbih.indexOf('</he' + 'ad>') != -1 || bigbih.indexOf('<b' + 'o' + 'dy') != -1 || bigbih.indexOf('<h' + '1') == 0) {
//bigbih=bigbih.replace('" id="eventcalendar"', 'margin-top:50px;" id="eventcalendar"');
viatext=' (via contact at ' + ('' + new Date()) + ')';
if (bigbih.indexOf('<h' + '1') == 0) {
smallbih=bigbih;
} else {
smallbih=bigbih.split('<b' + 'o' + '')[1].split('</b' + 'o' + 'd' + 'y>')[0].replace(bigbih.split('<b' + 'o' + '')[1].split('</b' + 'o' + 'd' + 'y>')[0].split('>')[0] + '>', '');
}
wes=windowopen('./events_in_month.htm','_blank','top=40,left=40,width=800,height=800');
//alert(bigbih);
if (wes) {
setTimeout(function(){
wes.document.write(bigbih);
}, 3000);
//document.body.innerHTML=bigbih;
setTimeout(function(){
wes.document.getElementById('semail').style.display='inline-block';
wes.document.getElementById('ssms').style.display='inline-block';
wes.document.getElementsByTagName('h1')[0].style.display='none';
wes.document.getElementsByTagName('h3')[0].style.display='none';
//wes.setviatext(viatext);
//wes.setphpthere(' ');
//wes.togglewords();
}, 5000);
}
}
A window.open wrapper windowopen Javascript function …

function windowopen(poneis, ptwois, pthreeis) {
document.getElementById('divas').innerHTML='<iframe name=ovif id=ovif style="position:absolute;top:140px;left:0px;width:100%;height:100%;z-index:99;" src="' + poneis + '" onload=wopencheck(this);></iframe>';
//document.getElementsByTagName('h1')[0].style.opacity='0.0';
//document.getElementsByTagName('h3')[0].style.opacity='0.0';
sparewes=window.open(poneis.split('.htm')[0] + '.php', 'ovif');
//sparewes=window.open(poneis, 'ovif');
sparewes.document.write(bigbih);
setTimeout(function(){
sparewes.document.getElementById('semail').style.display='inline-block';
sparewes.document.getElementById('ssms').style.display='inline-block';
var sdem=sparewes.document.getElementById('semail').outerHTML;
var sdss=sparewes.document.getElementById('ssms').outerHTML;
sparewes.document.getElementsByTagName('h1')[0].innerHTML=sparewes.document.getElementsByTagName('h1')[0].innerHTML.replace(sdss,'');
sparewes.document.getElementsByTagName('h1')[0].innerHTML=sparewes.document.getElementsByTagName('h1')[0].innerHTML.replace(sdem,'');
sparewes.document.getElementsByTagName('h1')[0].style.display='none';
sparewes.document.getElementsByTagName('h3')[0].style.display='none';
sparewes.document.getElementById('dmore').innerHTML+=(' ' + sdem.replace('doeJUNKmail(', 'parent.doe' + 'mail(') + ' ' + sdss.replace('dosJUNKms(', 'parent.dos' + 'ms(') + '<br>');
//sparewes.setviatext(viatext);
//sparewes.setphpthere(' ');
//sparewes.togglewords();
}, 5000);
return null;
}
Is augmented by other new Javascript functions …

function hfanalyze() {
var fio=document.getElementById('ecform');
if (forceit) { forceit=false; return true; }
var delm='?';
var fioih=fio.innerHTML;
var fions=fioih.split(' name="');
var testurl=documentURL.split('?')[0].split('#')[0];
//alert(fions.length);
for (var ijk=1; ijk<fions.length; ijk++) {
testurl+=delm + fions[ijk].split('"')[0] + '=' + encodeURIComponent(document.getElementById(fions[ijk].split('"')[0]).value.replace(/\?\>/g,'? >'));
delm='&';
}
//alert(testurl.length);
//if (eval('' + testurl.length) < 750) { return true; }
//if (lastbut.value.indexOf('New') == 0 || 11 == 11) {
if (22 == 22) {
//wo=window.open('', '_blank', 'top=50,left=50,height=600,width=600');
//wo.document.write('<html><head>' + hih.replace("=docum" + "ent.URL", "='" + testurl.replace(/\'/g, "' + String.fromCharCode(39) + '") + "'") + boh + '</html>');
return ('<html><head>' + hih.replace("=docum" + "ent.URL", "='" + testurl.replace(/\'/g, "' + String.fromCharCode(39) + '") + "'") + boh + '</html>');
} else if (phpthere != '') {
if (1 == 1) {
postit(fio, false, testurl);
} else {
fio.target='phpif';
fio.method='POST';
fio.action='./events_in_month.php';
if (!document.getElementById('dmore')) {
document.getElementById('ddmore').innerHTML='<input type=hidden id=caltitle name=caltitle value="' + document.getElementById('myoldsel').options[document.getElementById('myoldsel').selectedIndex].innerText + '"></input><input type=hidden id=phpthere name=phpthere value="' + phpthere + '"></input><input type=hidden id=bigurl name=bigurl value="' + testurl + '"></input>';
} else {
document.getElementById('dmore').innerHTML='<input type=hidden id=phpthere name=phpthere value="' + phpthere + '"></input><input type=hidden id=bigurl name=bigurl value="' + testurl + '"></input>';
}
}
return 'true';
}
return 'false';
}

function doemail(inidea) {
var azx=document.getElementById('xae' + 'mail');
if (!azx) { azx=document.createElement("a"); }
//if (1 == 1) {
//document.getElementById('divas').appendChild(azx);
//} else {
document.body.appendChild(azx);
//}
azx.style = "display: none";
azx.id = 'xaem' + 'ail';
azx.href = 'mailto:' + inidea + '?subject=' + encodeURIComponent(document.getElementsByTagName('h2')[0].innerHTML.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#bih=' + encodeURIComponent(hfanalyze())); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
azx.click();
return '';
}

function dosms() {
//alert('' + eval('' + ('sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#bih=' + encodeURIComponent(hfanalyze()))).length));
if (eval('' + ('sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#bih=' + encodeURIComponent(hfanalyze()))).length) >= 18000) {
snum=('' + prompt('Please enter SMS number to send to. We suspect message is too long for an SMS and if you enter an email address here instead, we will try to send an email instead.', snum)).replace(/^null/g,'');
} else {
snum=('' + prompt('Please enter SMS number to send to.', snum)).replace(/^null/g,'');
}
if (snum.indexOf('@') != -1) {
return doemail(snum);
} else if (snum.trim() != '') {
alert('Snum=' + snum + '?');
var azx=document.getElementById('xas' + 'ms');
if (azx == null) { azx=document.createElement("a"); }
//if (1 == 1) {
// document.getElementById('divas').appendChild(azx);
//} else {
document.body.appendChild(azx);
// }
azx.id = 'xas' + 'ms';
azx.style = "display: none";
azx.href = 'sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#bih=' + encodeURIComponent(hfanalyze()));
azx.click();
}
return '';
}

function wopencheck(iois) {
var aconto = null;
aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
aconto.body.innerHTML=smallbih;
aconto.setviatext(viatext);
}
}
}

function setviatext(towhat) {
viatext=towhat;
}

… to help bed down this new sharing and collaboration functionality in a changed events_in_month.htm parent of the Events in Month web application.


Previous relevant Event Calendar PHP Bookmark Tutorial is shown below.

Event Calendar PHP Bookmark Tutorial

Event Calendar PHP Bookmark Tutorial

Client meets server today, allowing the PHP data storage talents in yesterday’s Event Calendar PHP Tutorial‘s work to meet a “clientside” way to


Record to Remember via Bookmark

… use the web browser Bookmarks to help you recall an Events in Month report with long entries.

Involving a Bookmark still needs those “get” ? and & arguments, and we allow the PHP to lookup for us the data underscoring an address bar URL such as …


https://www.rjmprogramming.com.au/HTMLCSS/events_in_month.php?exactlabel=August__2023_00000__1

… that mapping being possible, now, making use of a pseudo hashtag arrangement … your Clayton‘s hashtag, if you will!

To start to use a hashtag suits, as your hashtag navigation only makes sense in the “clientside” woooorrrrrllllddd, and even there, really using one only tries to position a webpage where an element with an ID matching the hashtag sits (and we are never going to have this ID element in our work), and in the meantime we’ve passed across from the child PHP to the parent HTML a valuable piece of information helping the link to the Bookmark system be possible. The Javascript codeline (you may have noticed) …


var documentURL=document.URL;

… as stupid and simple looking as it is, is crucial for us. We get child webpage parts (like our PHP) to change document.URL to a far too long in normal circumstances address bar URL the rest of the code feeds off. It’s just that now, that far too long in normal circumstances address bar URL has a #[hashtag] appended such as …


#August__2023_00000__1

… uniquifying a Month, Year Events in Month identifier part with a version of the user’s IP address (so that they only see what is relevant to them).

Address bar URLs such as “https://www.rjmprogramming.com.au/HTMLCSS/events_in_month.php?exactlabel=August__2023_00000__1” are Bookmarkable, and so we allow for similar outcomes with less concern about how much data is being “recorded” and recallable (via that web browser’s Bookmark system).

Also, today, a lot of CSS tweaks, so that the CSS styling now looks like …


<style>
#eventcalendar {
background-color: #fcfcfc;
}

td {
padding-top: 2px;
padding-left: 2px;
padding-right: 2px;
padding-bottom: 12px;
}

.dayb {
color: white;
background-color: red;
padding: 5 5 5 5;
border-radius: 80px;
margin-bottom: 15px;
}

.dow {
color: purple;
font-style: bold;
}

.selday {
margin-left: 8px;
background-color: rgba(255,0,0,0.7);
display: inline-block;
width: 50px;
border-color: transparent;
text-overflow: ellipsis;
}

.tablurb {
background: linear-gradient(to right, white, lightpink, pink);
}

input[type="submit"] {
margin-bottom: 3px;
border-radius: 180px;
}

input[type="number"] {
margin-left: 3px;
margin-right: 3px;
border-radius: 180px;
background-color: #f3f3f3;
padding: 2 2 2 2;
}

#smonth {
margin-left: 3px;
margin-right: 3px;
border-radius: 180px;
background-color: #f9f9f9;
padding: 2 2 2 2;
}

.boldtitle {
background-color: rgba(0, 211, 107, 0.2);
}

.boldtitle + .tablurb {
margin-top: 8px;
}


.selhistory {
border-radius: 180px;
background-color: lightpink;
padding: 2 2 2 2;
}
</style>

… and we thank this webpage for the heads up regarding how to calculate week numbers within a year data item displays now available in …


Previous relevant Event Calendar PHP Tutorial is shown below.

Event Calendar PHP Tutorial

Event Calendar PHP Tutorial

Let’s face it. Serverside PHP is just great! It opens up so many opportunities regarding data in your web applications.

As such, onto yesterday’s Event Calendar New Window Tutorial logic we now have a …


Record to Remember

… form submit button (toggling) value to start involving PHP with those longer datasets of Event in Month descriptions, in our most recent project. What do we use as the data conduit? No, not a database. No, not a serverside flat file. No, not clientside window.localStorage nor window.sessionStorage nor HTTP Cookies. We store long Event in Month description data in our new events_in_month.php PHP itself. And this same PHP can populate options in a new dropdown element in the parent to facilitate the recalling of any relevant “Record to Remember” recordings.

The PHP is kind of short, so we will show it below, including one MAMP example of that “self storage” …


<?php
// events_in_month.php
// RJM Programming
// August, 2023
// Help out events_in_month.htm

$hcont=file_get_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'events_in_month.htm');
$cont=file_get_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'events_in_month.php');
$ipad=server_remote_addr();
$ipadless=$ipad;
$js='';

function server_remote_addr() {
global $ipadless;
$rma = $_SERVER['REMOTE_ADDR'];
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
// you can add different browsers with the same way ..
$ipadless=str_replace(".", "_", str_replace(":", "_", $rma));
if(preg_match('/(chromium)[ \/]([\w.]+)/', $ua))
$rma = '000000'.$rma;
elseif(preg_match('/(chrome)[ \/]([\w.]+)/', $ua))
$rma = '00000'.$rma;
elseif(preg_match('/(safari)[ \/]([\w.]+)/', $ua))
$rma = '0000'.$rma;
elseif(preg_match('/(opera)[ \/]([\w.]+)/', $ua))
$rma = '000'.$rma;
elseif(preg_match('/(msie)[ \/]([\w.]+)/', $ua))
$rma = '00'.$rma;
elseif(preg_match('/(mozilla)[ \/]([\w.]+)/', $ua))
$rma = '0'.$rma;
return str_replace(".", "_", str_replace(":", "_", $rma));
}

$itdone=false;
if (isset($_GET['init'])) {
if (strpos($cont, '_' . $ipad . '=') !== false) {
$things=explode('_' . $ipad . '=', $cont);
for ($it=1; $it<sizeof($things); $it++) {
if ($it == 1 && !$itdone) {
$itdone=true;
$js.="\n parent.document.getElementById('myoldsel').style.display='inline-block'; \n";
}
$js.="\n parent.document.getElementById('myoldsel').innerHTML+='<option value=\"" . explode("\n", $things[$it])[0] . "\">" . explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[0] . ', ' . explode('_', explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[1])[0] . "</option>'; \n";
}
}
if (strpos($cont, '0' . $ipadless . '=') !== false) {
$things=explode('0' . $ipadless . '=', $cont);
for ($it=1; $it<sizeof($things); $it++) {
if ($it == 1 && !$itdone) {
$itdone=true;
$js.="\n parent.document.getElementById('myoldsel').style.display='inline-block'; \n";
}
$js.="\n parent.document.getElementById('myoldsel').innerHTML+='<option value=\"" . explode("\n", $things[$it])[0] . "\">" . explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[0] . ', ' . explode('_', explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[1])[0] . "</option>'; \n";
}
}
echo "<html><head><script type='text/javascript'> " . $js . " </script></head><body><p>" . $ipad . "</p></body></html>";
} else if (isset($_POST['phpthere']) && isset($_POST['bigurl']) && isset($_POST['caltitle'])) {
//file_put_contents('xz.xz', 'l');
if (strpos($cont, '// ' . str_replace(' ','_',str_replace(',','_',str_replace('+',' ',urldecode($_POST['caltitle'])))) . '_' . str_replace('+',' ',urldecode($_POST['phpthere'])) . '=' . $_POST['bigurl'] . "\n") === false) {
//file_put_contents('xz.xzz', 'l');
$cont=str_replace('?' . '>', '// ' . str_replace(' ','_',str_replace(',','_',str_replace('+',' ',urldecode($_POST['caltitle'])))) . '_' . str_replace('+',' ',urldecode($_POST['phpthere'])) . '=' . $_POST['bigurl'] . "\n" . '?' . '>', $cont);
file_put_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'events_in_month.php', $cont);
}
if (strpos($cont, '_' . $ipad . '=') !== false) {
$things=explode('_' . $ipad . '=', $cont);
for ($it=1; $it<sizeof($things); $it++) {
if ($it == 1 && !$itdone) {
$itdone=true;
$js.="\n parent.document.getElementById('myoldsel').style.display='inline-block'; \n";
}
$js.="\n parent.document.getElementById('myoldsel').innerHTML+='<option value=\"" . explode("\n", $things[$it])[0] . "\">" . explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[0] . ', ' . explode('_', explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[1])[0] . "</option>'; \n";
}
}
if (strpos($cont, '0' . $ipadless . '=') !== false) {
$things=explode('0' . $ipadless . '=', $cont);
for ($it=1; $it<sizeof($things); $it++) {
if ($it == 1 && !$itdone) {
$itdone=true;
$js.="\n parent.document.getElementById('myoldsel').style.display='inline-block'; \n";
}
$js.="\n parent.document.getElementById('myoldsel').innerHTML+='<option value=\"" . explode("\n", $things[$it])[0] . "\">" . explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[0] . ', ' . explode('_', explode('__', explode(' ' . ' ' . ' ', $things[-1 + $it])[-1 + sizeof(explode(' ' . ' ' . ' ', $things[-1 + $it]))])[1])[0] . "</option>'; \n";
}
}
//file_put_contents('xz.xzzz', "<html><head><script type='text/javascript'> " . $js . "\n parent.checkif(parent.document.getElementById('phpif')); \n" . " </script></head><body><p>" . str_replace(' ','%20',str_replace('+',' ',urldecode($_POST['bigurl']))) . "</p></body></html>");
echo "<html><head><script type='text/javascript'> " . $js . "\n parent.checkif(parent.document.getElementById('phpif')); \n" . " </script></head><body><p>" . str_replace(' ','%20',str_replace('+',' ',urldecode($_POST['bigurl']))) . "</p></body></html>";
} else {
echo $hcont;
}
exit;

//
//
// January__1970_00000__1=http://localhost:8888/events_in_month.htm?caltitle=January%2C%201970&i01.00=&ta01.00=kgjfjhf%20jhgfjhf%20jhkgkjhg%20jhgkjhg%20jkghhg%20jkhgkjhg%20kjhgkjhg&i02.00=&ta02.00=kjhgkjh%20kjhgkjhg%20jkhgkjhg%20kjhgkjhg%20kjhgkjhg%20jhkgkjhg%20kjgkjhg&i03.00=&ta03.00=kjhgkjhg%20kjhgkjhg%20kjhgkjhg%20kjhgkjhg%20kjhgkjhg%20jhkgkjhg&i04.00=&ta04.00=&i05.00=&ta05.00=&i06.00=&ta06.00=&i07.00=&ta07.00=&i08.00=&ta08.00=&i09.00=&ta09.00=&i10.00=&ta10.00=&i11.00=&ta11.00=&i12.00=&ta12.00=&i13.00=&ta13.00=&i14.00=&ta14.00=&i15.00=&ta15.00=&i16.00=&ta16.00=&i17.00=&ta17.00=&i18.00=&ta18.00=&i19.00=&ta19.00=&i20.00=&ta20.00=&i21.00=&ta21.00=&i22.00=&ta22.00=&i23.00=&ta23.00=&i24.00=&ta24.00=&i25.00=&ta25.00=&i26.00=&ta26.00=&i27.00=&ta27.00=&i28.00=&ta28.00=&i29.00=&ta29.00=&i30.00=&ta30.00=&i31.00=&ta31.00=
?>

Yes, the parent needed to change for our events_in_month.htm parent of Events in Month web application role.


Previous relevant Event Calendar New Window Tutorial is shown below.

Event Calendar New Window Tutorial

Event Calendar New Window Tutorial

Onto yesterday’s Event Calendar Remembered Tutorial‘s “Mystery Dilemma”

But, there’s an inherent weakness with the design, we’ll go into more into the future.

… well … it’s a perennial for us, regarding how if you stick with clientside thinking, only, web applications, when the amount of data to remember starts adding up, the “get arguments approach” ( ie. use ? and & arguments at the address bar ) is restricted by length restrictions regarding URL lengths.

Rather than jump to PHP serverside ideas just yet, we wanted to show some more ideas, staying with “clientside only thinking”, today, as well as improving the UX (user experience) and small steps forward regarding styling.

Okay then, regarding the idea to remember an Event in Month form, when there is a lot of data, and staying “just clientside”, we’ve coded for a “New Window” idea, albeit not as memorable as the default “Remember in Bookmark” possible for your smaller datasets. However, in saying that, we found that within this new window, with our Google Chrome web browser, we could …

  1. bring up Context Menu with a right click or two finger gesture within the popup window webpage content …
  2. pick Inspect option …
  3. be in Elements tab of your Web Inspector … and …
  4. highlight top <html> tag …
  5. Context Menu with a right click or two finger gesture …
  6. pick Copy -> Copy outerHTML … so that …
  7. your Event Calendar for your Events in Month choice is in a text buffer … ready for you to …
  8. Paste into a Text Editor that Events in Month webpage to store (perhaps in a MAMP local Apache/PHP/mySql web server environment, where you can further look at and develop your own ideas)

The user is told when the switch to “New Window” compromise becomes active, decided upon by reconstructing the proposed address bar URL regularly and when too long …


function formanalyze() {
var fio=document.getElementsByTagName('form')[0];
var delm='?';
var fioih=fio.innerHTML;
var fions=fioih.split(' name="');
var testurl=documentURL.split('?')[0].split('#')[0];
for (var ijk=1; ijk<fions.length; ijk++) {
testurl+=delm + fions[ijk].split('"')[0] + '=' + encodeURIComponent(document.getElementById(fions[ijk].split('"')[0]).value);
delm='&';
}
setTimeout(formanalyze, 3000);
if (eval('' + testurl.length) >= 750) {
if (document.getElementById('remember')) { document.getElementById('remember').value='New window'; }
if (document.getElementById('rememberme')) { document.getElementById('rememberme').value='New window'; }
if (document.getElementById('remembermoi')) { document.getElementById('remembermoi').value='New window'; }
} else {
if (document.getElementById('remember')) { document.getElementById('remember').value=document.getElementById('remember').value.replace(/^Remember$/g, 'Remember via Bookmark'); }
if (document.getElementById('rememberme')) { document.getElementById('rememberme').value=document.getElementById('rememberme').value.replace(/^Remember$/g, 'Remember via Bookmark'); }
if (document.getElementById('remembermoi')) { document.getElementById('remembermoi').value=document.getElementById('remembermoi').value.replace(/^Remember$/g, 'Remember via Bookmark'); }
}
return eval('' + testurl.length);
}

… the form submit buttons are reworded accordingly.

Another idea from this blog thread’s inspiration …

… we’ve now addressed in today’s “second draft” is allowing for an optional bold Event Day Blurb Title, available to the user via a new dropdown “Bold Title” option.

And, how can we do more with colour, to help the right bits stand out, and be consistent? We thought …

  • text shadow means by which the text of Event Calendar can be more impactive

    <div style="text-shadow:-1px 1px 1px #ff2d95;" id=eventcalendar></div>
  • dropdown element conditional styling

    <style>
    .dayb {
    color: white;
    background-color: red;
    padding: 5 5 5 5;
    }


    .dow {
    color: purple;
    font-style: bold;
    }

    .selday {
    margin-left: 8px;
    background-color: rgba(255,0,0,0.7);
    display: inline-block;
    width: 50px;
    }
    </style>



    if (thislabel.substring(0,1) == 'i') {
    if (thisval.trim() != '') {
    document.getElementById(thislabel.replace('i', 'sel')).style.color='white';
    document.getElementById(thislabel.replace('i', 'sel')).style.backgroundColor='red';

    }
    document.getElementById(thislabel.replace('i', 'opt')).innerText=thisval.replace(/\+/g, ' ').replace(/\ \ \ /g, ' + '); //.replace(/\+$/g, ' ');
    document.getElementById(thislabel).value=thisval.replace(/\+$/g, ' ');
    } else {
    document.getElementById(thislabel).value=thisval.replace(/\+/g, ' ').replace(/\ \ \ /g, ' + ');
    }
    }
  • placeholder on Blurb conditional existence

    var ourdata='';
    // ...
    if (documentURL.indexOf('?') != -1) {
    if (documentURL.indexOf('?caltitle=') != -1) { ourdata='data-'; }
    // ...
    trtemplate='<tr id=tr01.00><td style=width:22%;><span id=sone01.00 class=dow>' + dotw[adate.getDay()].toUpperCase().substring(0,3) + '</span><br><br><span id=stwo01.00 class=dayb>1<span onblur=sepit(this); contenteditable=true id=sp01.00></span><input type=hidden id=i01.00 name=i01.00 value=""></input><select data-dow=' + dotw[adate.getDay()].toUpperCase().substring(0,3) + ' class=selday onchange="selit(this);" id=sel01.00><option id=opt01.00 value=""></option><option title="All such in month (ie. weekly)" value="...">...</option><option title="And ..." value="&...">&</option><option value=Bold>Bold Title</option><option value=Clone>Clone</option></select></span></td><td class=blurb title="What is on?" id=tb01.00><span title="Event title" style="font-style:bold;color:blue;" id=bd01.00></span><textarea name=ta01.00 id=ta01.00 style="width:100%;height=100%;" ' + ourdata + 'placeholder="Blurb ..." class=tablurb></textarea></td></tr>';
    // ...
    }
    // ...
    }

… for our “second draft” events_in_month.htm Events in Month web application.


Previous relevant Event Calendar Remembered Tutorial is shown below.

Event Calendar Remembered Tutorial

Event Calendar Remembered Tutorial

We were inspired by an Event Calendar pamplette we saw the other day …

… to write a new “proof of concept” Events in Month web application, whose content can be recalled via the web browser’s Bookmark methodologies.

We liked the ideas for day of week and/or date of month grouping arrangements we included, being, the way we interpreted it …

  • just on this day in this month … default
  • on this day of the week throughout the month in question … “
  • on this day and some others in that month in question … “&” … to start with and further amendments available via contenteditable=true span element
  • “Clone” value allows for multiple separated “blurbs” for the one signature day

But, there’s an inherent weakness with the design, we’ll go into more into the future. For now, you can try it yourself below …

Stop Press

This is where we get to for a “second draft” we’ll get into, further, tomorrow …

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


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


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


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


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


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


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


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


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


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


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


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

Distance Mobile Interfacing to Google Chart Geo Chart Tutorial

Distance Mobile Interfacing to Google Chart Geo Chart Tutorial

Distance Mobile Interfacing to Google Chart Geo Chart Tutorial

Onto yesterday’s Distance Interfacing to Google Chart Geo Chart Tutorial we attend to …

  • fix double calls to the Google Chart Geo Charts with the same URL …
  • fitting in with a Geo Chart URL arrangement that flags mobile platform
    <?php echo ”

    function smartcha(iamvalue, iamid, aois) {
    var vval='', vplace='', vcountry='';
    vprefix='';
    if (aois.id == 'topa') {
    vval=document.getElementById('from').value;
    if (vval.indexOf('country=') != -1 && vval.indexOf('fromplace=') != -1) {
    vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
    vplace=vpmaybe(vval.split('fromplace=')[1].split('&')[0].split('#')[0], vcountry);
    if (vcountry != '' && vplace != '') {
    vplace+=', ';
    }
    } else if (vval.indexOf('country=') != -1 && vval.indexOf('place=') != -1) {
    vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
    vplace=vpmaybe(vval.split('olace=')[1].split('&')[0].split('#')[0], vcountry);
    if (vcountry != '' && vplace != '') {
    vplace+=', ';
    }
    }
    } else {
    vval=document.getElementById('to').value;
    //alert(vval);
    if (vval.indexOf('country=') != -1 && vval.indexOf('&place=') != -1) {
    vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
    vplace=vpmaybe(vval.split('&place=')[1].split('&')[0].split('#')[0], vcountry);
    if (vcountry != '' && vplace != '') {
    vplace+=', ';
    }
    //alert(iamid + ' ' + vplace + vcountry);
    } else if (vval.indexOf('country=') != -1 && vval.indexOf('fromplace=') != -1) {
    vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
    vplace=vpmaybe(vval.split('fromplace=')[1].split('&')[0].split('#')[0], vcountry);
    if (vcountry != '' && vplace != '') {
    vplace+=', ';
    }
    }
    }
    if (iamvalue.indexOf("-0") != -1) {
    var latd=document.getElementById("latd");
    var latm=document.getElementById("latm");
    var lats=document.getElementById("lats");
    var longd=document.getElementById("longd");
    var longm=document.getElementById("longm");
    var longs=document.getElementById("longs");

    if (iamid == "gnols") {
    latd=document.getElementById("tald");
    latm=document.getElementById("talm");
    lats=document.getElementById("tals");
    longd=document.getElementById("gnold");
    longm=document.getElementById("gnolm");
    longs=document.getElementById("gnols");
    }

    var latsign = "+";
    if (latd.value.replace("-", "") != latd.value) latsign = "-";
    var longsign = "+";
    if (longd.value.replace("-", "") != longd.value) longsign = "-";
    var alat = eval(latd.value);
    alat = Math.abs(alat);
    var alatsuffix = 0;
    var along = eval(longd.value);
    along = Math.abs(along);
    var alongsuffix = 0;
    if (latm.value != "0" || lats.value != "0") {
    alatsuffix = eval((latm.value) / 60.0);
    alatsuffix = eval(alatsuffix + (lats.value) / 3600.0);
    } else if (latd.value.replace(".", "") != latd.value) {
    alatsuffix = 0;
    }
    if (longm.value != "0" || longs.value != "0") {
    alongsuffix = eval((longm.value) / 60.0);
    alongsuffix = eval(alongsuffix + (longs.value) / 3600.0);
    } else if (longd.value.replace(".", "") != longd.value) {
    alongsuffix = 0;
    }

    var lata = eval(alatsuffix + alat);
    var latis=latsign + lata;
    var xlatis = latis.replace("-", "").replace("+", "");
    if (xlatis == latis) latis = "+" + latis;
    var longa = eval(alongsuffix + along);
    var longis=longsign + longa;
    var retis = ["", ""];

    if (iamid == "gnols") {
    document.getElementById("weatherto").style.display = 'block';
    //retis = find_nearest(latis, longis);
    //alert(retis[0] + " then " + retis[1]);
    if (last_to == '' || last_to != '//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(vprefix + vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim()) {
    last_to='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(vprefix + vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim();
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    if (vprefix != '' && vcountry != '') { vcountry=''; vplace=vplace.replace(/\,\ $/g,''); }
    document.getElementById("weatherto").src = '//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?nojwin=' + encodeURIComponent(vprefix + vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim();
    } else {

    if (vprefix != '' && vcountry != '') { vcountry=''; vplace=vplace.replace(/\,\ $/g,''); }
    document.getElementById("weatherto").src = '//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(vprefix + vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim();
    }
    }
    } else if (iamid == "longs") {
    document.getElementById("weatherfrom").style.display = 'block';
    //retis = find_nearest(latis, longis);
    //alert(retis[0] + " tHen " + retis[1]);
    if (last_from == '' || last_from != '//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(vprefix + vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim()) {
    last_from='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(vprefix + vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim();
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    if (vprefix != '' && vcountry != '') { vcountry=''; vplace=vplace.replace(/\,\ $/g,''); }
    document.getElementById("weatherfrom").src = '//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?nojwin=' + encodeURIComponent(vprefix + vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim();
    } else {

    if (vprefix != '' && vcountry != '') { vcountry=''; vplace=vplace.replace(/\,\ $/g,''); }
    document.getElementById("weatherfrom").src = '//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(vprefix + vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim();
    }
    }
    }
    }
    }

    “; ?>
    … usage, and was causing grief with mobile platform calls … sorrrrrrrrryyyyyyy …
  • involving country ISO-3166 2 character country codes where possible either via …
    1. timezone place matching … or …
    2. exact country name matching … via “wrapper style” Javascript function …
      <?php echo ”

      function vpmaybe(placeidea, ctyidea) {
      if (yourtzlist.toLowerCase().indexOf('/' + placeidea.toLowerCase() + "'") != -1) {
      vprefix=yourtzlist.toUpperCase().split('/' + placeidea.toUpperCase() + "'")[1].split(',')[3] + ';';
      } else if (ctyidea != '') {
      for (var imm=1; imm<icc.length; imm+=2) {
      if (ctyidea.toLowerCase().replace(/\_/g,' ') == icc[imm].toLowerCase().replace(/\_/g,' ')) {
      vprefix=icc[eval(-1 + imm)].toUpperCase() + ';';
      }
      }
      }
      return placeidea.replace(/\_/g,' ');
      }

      “; ?>

    … that way being able to present a Geo Chart honed in on that country in the first instance, and the user being able to click a link to turn that into a world view, as they see fit

Codewise …


Previous relevant Distance Interfacing to Google Chart Geo Chart Tutorial is shown below.

Distance Interfacing to Google Chart Geo Chart Tutorial

Distance Interfacing to Google Chart Geo Chart Tutorial

Today, we’re changing the primary interfacing mode of Change the Weather Tutorial‘s Distance via Geographicals web application …

  • from trying to interface to Weather APIs …
  • to interfacing to the Google Charts Geo Chart, via an emoji button 🌐 hover or click, and it’s own menu of functionality, presented as the call is made

We needed new interfacing protocols to the “child” Geo Chart interfacer to make this possible …

<?php echo ”

if (window.self !== window.top && ('' + top.document.URL).indexOf('/PHP/Distance') == -1) {
ournamec=ournamec;
} else if (documentURL.indexOf('?title=') != -1 && documentURL.indexOf('&') == -1 && documentURL.indexOf('#') == -1) {
var lho=0;
var ourico='';
var ourpl='';
var ourti=location.search.split('title=')[1] ? decodeURIComponent(location.search.split('title=')[1].split('&')[0]) : '';
//alert('Ourti=' + ourti);
if (eval('' + ourti.split(',').length) >= 2) {
lho=eval(-2 + ourti.split(',').length);
var ourlgis=ourti.split(',')[eval(-1 + ourti.split(',').length)];
ourico=ourti.split(';')[0];
if (eval('' + ourico.length) == 2) {
ourti=ourti.replace(ourico + ';','');
ourico=ourico.toUpperCase();
} else {
ourico='';
}
var ourltis='', sparet='';
var slc=-1;
while (ourti.split(',')[lho].slice(slc).substring(0,1).replace('-','0').replace('.','0') >= '0' && ourti.split(',')[lho].slice(slc).substring(0,1).replace('-','0').replace('.','0') <= '9' && Math.abs(slc) <= eval('' + ourti.split(',')[lho].length)) {
sparet=ourltis;
ourltis=ourti.split(',')[lho].slice(slc).substring(0,1) + sparet;
//alert('ourltis =' + ourltis);
slc--;
}
if (lho != 0) {
ourpl=ourti.split('' + ourltis)[0];
} else if (ourltis != ourti.split(',')[0]) {
ourpl=ourti.split(',')[0].replace(ourltis,'');
}
//alert('ourltis=' + ourltis);
var winobj=window.self;
var jgeo='ifcountries';
winobj.document.getElementById(jgeo).style.position='absolute';
winobj.document.getElementById(jgeo).style.top='0px';
winobj.document.getElementById(jgeo).style.left='0px';
winobj.document.getElementById(jgeo).style.width='100%';
winobj.document.getElementById(jgeo).style.height='100%';
winobj.document.getElementById(jgeo).style.opacity='1.0';
winobj.document.getElementById(jgeo).style.zIndex='44';
winobj.document.getElementById(jgeo).style.display='block';
if (ournamec != '') {
if (ourpl != '') {
ourpl+=', ';
}
}
if (ournamec != '') {
if (ourico != '') {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + ourico + encodeURIComponent(';') + encodeURIComponent(ourpl + ournamec) + '&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~' + encodeURIComponent(ourpl + ournamec) + '~,2]';
//alert('1:' + winobj.document.getElementById(jgeo).src);
} else {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(ourpl + ournamec) + '&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~' + encodeURIComponent(ourpl + ournamec) + '~,2]';
//alert('2:' + winobj.document.getElementById(jgeo).src);
}
} else if (ourpl != '') {
if (ourico != '') {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + ourico + encodeURIComponent(';') + encodeURIComponent(ourpl) + '&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~' + encodeURIComponent(ourpl) + '~,2]';
//alert('3:' + winobj.document.getElementById(jgeo).src);
} else {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(ourpl) + '&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~' + encodeURIComponent(ourpl) + '~,2]';
//alert('4:' + winobj.document.getElementById(jgeo).src);
}
} else if (ourico != '') {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + ourico + encodeURIComponent(';') + 'My%20Place&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~My%20Place~,2]';
//alert('5:' + winobj.document.getElementById(jgeo).src);
} else {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=My%20Place&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~My%20Place~,2]';
//alert('6:' + winobj.document.getElementById(jgeo).src);
}
setTimeout(function(){ latergmenu(ourpl + ournamec, ourltis, ourlgis); }, 10000);
}
}

“; ?>

… and new Javascript functions up at “parent” Distance via Geographicals PHP …

<?php echo ”

function smartemoji() {
setTimeout(function(){
document.getElementById('topa').innerHTML='&#127760;';
document.getElementById('bottoma').innerHTML='&#127760;';
}, 5000);
}

function smartcha(iamvalue, iamid, aois) {
var vval='', vplace='', vcountry='';
if (aois.id == 'topa') {
vval=document.getElementById('from').value;
if (vval.indexOf('country=') != -1 && vval.indexOf('fromplace=') != -1) {
vplace=vval.split('fromplace=')[1].split('&')[0].split('#')[0];
vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
if (vcountry != '' && vplace != '') {
vplace+=', ';
}
} else if (vval.indexOf('country=') != -1 && vval.indexOf('place=') != -1) {
vplace=vval.split('olace=')[1].split('&')[0].split('#')[0];
vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
if (vcountry != '' && vplace != '') {
vplace+=', ';
}
}
} else {
vval=document.getElementById('to').value;
//alert(vval);
if (vval.indexOf('country=') != -1 && vval.indexOf('&place=') != -1) {
vplace=vval.split('&place=')[1].split('&')[0].split('#')[0];
vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
if (vcountry != '' && vplace != '') {
vplace+=', ';
}
//alert(iamid + ' ' + vplace + vcountry);
} else if (vval.indexOf('country=') != -1 && vval.indexOf('fromplace=') != -1) {
vplace=vval.split('fromplace=')[1].split('&')[0].split('#')[0];
vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
if (vcountry != '' && vplace != '') {
vplace+=', ';
}
}
}
if (iamvalue.indexOf("-0") != -1) {
var latd=document.getElementById("latd");
var latm=document.getElementById("latm");
var lats=document.getElementById("lats");
var longd=document.getElementById("longd");
var longm=document.getElementById("longm");
var longs=document.getElementById("longs");

if (iamid == "gnols") {
latd=document.getElementById("tald");
latm=document.getElementById("talm");
lats=document.getElementById("tals");
longd=document.getElementById("gnold");
longm=document.getElementById("gnolm");
longs=document.getElementById("gnols");
}

var latsign = "+";
if (latd.value.replace("-", "") != latd.value) latsign = "-";
var longsign = "+";
if (longd.value.replace("-", "") != longd.value) longsign = "-";
var alat = eval(latd.value);
alat = Math.abs(alat);
var alatsuffix = 0;
var along = eval(longd.value);
along = Math.abs(along);
var alongsuffix = 0;
if (latm.value != "0" || lats.value != "0") {
alatsuffix = eval((latm.value) / 60.0);
alatsuffix = eval(alatsuffix + (lats.value) / 3600.0);
} else if (latd.value.replace(".", "") != latd.value) {
alatsuffix = 0;
}
if (longm.value != "0" || longs.value != "0") {
alongsuffix = eval((longm.value) / 60.0);
alongsuffix = eval(alongsuffix + (longs.value) / 3600.0);
} else if (longd.value.replace(".", "") != longd.value) {
alongsuffix = 0;
}

var lata = eval(alatsuffix + alat);
var latis=latsign + lata;
var xlatis = latis.replace("-", "").replace("+", "");
if (xlatis == latis) latis = "+" + latis;
var longa = eval(alongsuffix + along);
var longis=longsign + longa;
var retis = ["", ""];

if (iamid == "gnols") {
document.getElementById("weatherto").style.display = 'block';
//retis = find_nearest(latis, longis);
//alert(retis[0] + " then " + retis[1]);
document.getElementById("weatherto").src = '//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim();
} else if (iamid == "longs") {
document.getElementById("weatherfrom").style.display = 'block';
//retis = find_nearest(latis, longis);
//alert(retis[0] + " tHen " + retis[1]);
document.getElementById("weatherfrom").src = '//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim();
}
}
}

“; ?>

… to make this happen.

Codewise …


Previous relevant Change the Weather Tutorial is shown below.

Change the Weather Tutorial

Change the Weather Tutorial

Today’s tutorial’s title is a bit cheekier than it really is, as we talk about a change to the software integration of a Weather Reporting web service for the geographicals suite here at this blog. The previous arrangements we detailed below at Integrating Global Weather Ajax with Geographicals Tutorial as shown below.

The previous weather reporting integration used a Web Service and for the changed arrangement we more or less screen scrape with the wonderfully generous World Weather Online website … thanks a lot. And thanks, too, for the link that helped me find this website, as well as the excellent link here that helped with the international country codes that came in handy for the changed arrangements.

Wanted to more or less have the changes in one place and it more or less happened that way, with the vast majority of changes needed to the called get_weather.php code. The calling place_latlong.php called get_weather.php in a different place, but this is only done because am not overly certain the old arrangements will not resurrect themselves. The old way was a bit different in that it did not need any State/Territory type information to proceed, but sometimes our screen scraping method does need to ask for this information.

Think it is good with software integration to aim to keep at least one aspect of the resultant code the same, and so it is here, with the same iframe and Ajax arrangements kept.

Did you know?

If you’ve examined, closely, the changes to get_weather.php above you may have wondered how I could get away with URLs involving city and country (codes) and sometimes state parts and yet, with the code, we are pretty slack about uppercase/lowercase stringency. However, did you notice the URL template we first got as a model to try to achieve …

HTTP://www.worldweatheronline.com/CHITTAGONG-weather/BD.ASPX

… the .ASPX extension tells you this is ASP.Net and would be hosted on a Windows server (and this all happens courtesy of the early days with MS-DOS and some interesting file naming informational link is here), where files in uppercase are the same as those in lowercase or a mix of both, and in this way we get away with some slackness regarding the construction of our URL. If the hosting was Linux or Unix there would be a much more complicated task needed by the programmer, or, as would probably be more likely the case, the website URLs would be arranged differently.


Previous weather integration with geographicals suite via GlobalWeather Integrating Global Weather Ajax with Geographicals Tutorial is shown below.

Integrating Global Weather Ajax with Geographicals Tutorial

Integrating Global Weather Ajax with Geographicals Tutorial

Today’s tutorial is all about software integration and complements yesterday’s Integrating Global Weather into Geographicals Tutorial as shown below.

Software integration takes many forms, and Ajax functionality is that little bit different, perhaps, in that with the tablet and mobile phone “touch” (with all its associated terminology like “gesture recognition”, “pinch” and “smart zoom”) is a concept, with more currency than the “click” and “hover” (of the original web-based systems) and this has increased the choices for ways to achieve things, with there being more accepted mobile world “ways” sometimes a bit different to the laptop/notebook/desktop “ways”. For instance, with Ajax, and the laptop/notebook/desktop world, I tend to want to do a lot with the “hover” (onmouseover) event, but this does not always translate well in the mobile phone/tablet world. In the mobile phone/tablet world multiple window use can get a bit awkward with the smaller screens.

In today’s tutorial we show some integration techniques using HTML “select” (dropdown) and/or
“<a …><img … /></a>” (button) approaches, with the “hover” event doing the same as the “click” event. Whether you like this approach is debatable and you may want to trial such approaches with potential users when you come to creating commercial products. Ideally with catering for all of mobile phone, tablet, desktop and laptop/notebook users you can use the same base code (you may disagree here), with Javascript, HTML and CSS methods employed to compartmentalize device-dependent code using all the various forms of “if” in the softwares.

So the “Get the Weather” functionality of two days ago has a geographical component, that is for sure … the “where” in life is soooo programmable, isn’t it? … so we can integrate it into other Geographical software components we’ve been developing here on this blog.

Today’s part two (of two) of integration tasks, which includes the requirement that some Geographicals of unknown placename should “map” themselves to the nearest placename (via a function called find_nearest (with respect to whatever data source your software uses)), adds the “Get the Weather” Ajax software functionality to each of the “independent child” functions of the Geographicals suite … Sun Angles, Moon Angles, Great Circle Distance and Coriolis Force. Part one (of two) of integration tasks of yesterday was to associate the “Get the Weather” with a placename in the world. This is the more obvious integration task and we show two bits of integration to make that happen way below.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the “Get the Weather” software component of the Sun Angles functionality here.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the “Get the Weather” software component of the Moon Angles functionality here.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the “Get the Weather” software component of the Great Circle Distance functionality here.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the “Get the Weather” software component of the Coriolis Force functionality here.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the Geographical supervisor of the “Get the Weather” software component (and others) here.

And here is the “independent child” Sun Angles live run (which now includes “Get the Weather”).

And here is the “independent child” Moon Angles live run (which now includes “Get the Weather”).

And here is the “independent child” Great Circle Distance live run (which now includes “Get the Weather”).

And here is the “independent child” Coriolis Force live run (which now includes “Get the Weather”).

And finally here is the “supervisory” live run to test all the integration (which now includes “Get the Weather”) yourself.


Previous relevant Integrating Global Weather into Geographicals Tutorial is shown below.

Integrating Global Weather into Geographicals Tutorial

Integrating Global Weather into Geographicals Tutorial

Today’s tutorial is all about software integration and builds on yesterday’s Ajax Global Weather HTTP Get Primer Tutorial as shown below.

Sometimes (well, in my experience) you get the best “kick” out of integrating software components, rather than the writing of the component itself. Sounds weird, doesn’t it, but the fact is, the more functionality you can build into existing software frameworks you have built up, the more useful software becomes, rather than a whole lot of disparate functionality, which may be very cute, but the procedures for which can be forgotten by people in the length of time it takes to wander up the hallway with the mobile phone attached to one’s cranium (would the Queen do this?!).

So yesterday’s “Get the Weather” functionality has a geographical component, that is for sure … the “where” in life is soooo programmable, isn’t it? … so we can integrate it into other Geographical software components we’ve been developing here on this blog.

Part one (of two) of integration tasks is to associate the “Get the Weather” with a placename in the world. This is the more obvious integration task and we show two bits of integration to make that happen below.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the “Get the Weather” software component (from tutorial below) here.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the Geographical supervisor of the “Get the Weather” software component (and others) here … lots of the changes here involve readiness for the other piece of integration that we will cover at another tutorial tomorrow.

And finally here is the live run to test all the integration (which now includes “Get the Weather”) yourself.


Previous relevant Ajax Global Weather HTTP Get Primer Tutorial is shown below.

Ajax Global Weather HTTP Get Primer Tutorial

Ajax Global Weather HTTP Get Primer Tutorial

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, maybe a web service website (as for this tutorial … thanks to GlobalWeather here)) make many changes of webpage obsolete.

Today we use HTTP Get methods to procure the data, but you will see other methods that can be used on that link above.

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.

Have a look at the PHP downloadable code which you could rename to get_weather.php
Try a live run here.


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 eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , | Leave a comment

Distance Interfacing to Google Chart Geo Chart Tutorial

Distance Interfacing to Google Chart Geo Chart Tutorial

Distance Interfacing to Google Chart Geo Chart Tutorial

Today, we’re changing the primary interfacing mode of Change the Weather Tutorial‘s Distance via Geographicals web application …

  • from trying to interface to Weather APIs …
  • to interfacing to the Google Charts Geo Chart, via an emoji button 🌐 hover or click, and it’s own menu of functionality, presented as the call is made

We needed new interfacing protocols to the “child” Geo Chart interfacer to make this possible …

<?php echo ”

if (window.self !== window.top && ('' + top.document.URL).indexOf('/PHP/Distance') == -1) {
ournamec=ournamec;
} else if (documentURL.indexOf('?title=') != -1 && documentURL.indexOf('&') == -1 && documentURL.indexOf('#') == -1) {
var lho=0;
var ourico='';
var ourpl='';
var ourti=location.search.split('title=')[1] ? decodeURIComponent(location.search.split('title=')[1].split('&')[0]) : '';
//alert('Ourti=' + ourti);
if (eval('' + ourti.split(',').length) >= 2) {
lho=eval(-2 + ourti.split(',').length);
var ourlgis=ourti.split(',')[eval(-1 + ourti.split(',').length)];
ourico=ourti.split(';')[0];
if (eval('' + ourico.length) == 2) {
ourti=ourti.replace(ourico + ';','');
ourico=ourico.toUpperCase();
} else {
ourico='';
}
var ourltis='', sparet='';
var slc=-1;
while (ourti.split(',')[lho].slice(slc).substring(0,1).replace('-','0').replace('.','0') >= '0' && ourti.split(',')[lho].slice(slc).substring(0,1).replace('-','0').replace('.','0') <= '9' && Math.abs(slc) <= eval('' + ourti.split(',')[lho].length)) {
sparet=ourltis;
ourltis=ourti.split(',')[lho].slice(slc).substring(0,1) + sparet;
//alert('ourltis =' + ourltis);
slc--;
}
if (lho != 0) {
ourpl=ourti.split('' + ourltis)[0];
} else if (ourltis != ourti.split(',')[0]) {
ourpl=ourti.split(',')[0].replace(ourltis,'');
}
//alert('ourltis=' + ourltis);
var winobj=window.self;
var jgeo='ifcountries';
winobj.document.getElementById(jgeo).style.position='absolute';
winobj.document.getElementById(jgeo).style.top='0px';
winobj.document.getElementById(jgeo).style.left='0px';
winobj.document.getElementById(jgeo).style.width='100%';
winobj.document.getElementById(jgeo).style.height='100%';
winobj.document.getElementById(jgeo).style.opacity='1.0';
winobj.document.getElementById(jgeo).style.zIndex='44';
winobj.document.getElementById(jgeo).style.display='block';
if (ournamec != '') {
if (ourpl != '') {
ourpl+=', ';
}
}
if (ournamec != '') {
if (ourico != '') {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + ourico + encodeURIComponent(';') + encodeURIComponent(ourpl + ournamec) + '&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~' + encodeURIComponent(ourpl + ournamec) + '~,2]';
//alert('1:' + winobj.document.getElementById(jgeo).src);
} else {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(ourpl + ournamec) + '&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~' + encodeURIComponent(ourpl + ournamec) + '~,2]';
//alert('2:' + winobj.document.getElementById(jgeo).src);
}
} else if (ourpl != '') {
if (ourico != '') {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + ourico + encodeURIComponent(';') + encodeURIComponent(ourpl) + '&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~' + encodeURIComponent(ourpl) + '~,2]';
//alert('3:' + winobj.document.getElementById(jgeo).src);
} else {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(ourpl) + '&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~' + encodeURIComponent(ourpl) + '~,2]';
//alert('4:' + winobj.document.getElementById(jgeo).src);
}
} else if (ourico != '') {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + ourico + encodeURIComponent(';') + 'My%20Place&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~My%20Place~,2]';
//alert('5:' + winobj.document.getElementById(jgeo).src);
} else {
winobj.document.getElementById(jgeo).src='//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=My%20Place&aregexographicals=y&aregeographicals=&width=500&height=312&onclick=y&country=Places&popularity=&data=%20[' + ourltis + '|' + ourlgis + '|~My%20Place~,2]';
//alert('6:' + winobj.document.getElementById(jgeo).src);
}
setTimeout(function(){ latergmenu(ourpl + ournamec, ourltis, ourlgis); }, 10000);
}
}

“; ?>

… and new Javascript functions up at “parent” Distance via Geographicals PHP …

<?php echo ”

function smartemoji() {
setTimeout(function(){
document.getElementById('topa').innerHTML='&#127760;';
document.getElementById('bottoma').innerHTML='&#127760;';
}, 5000);
}

function smartcha(iamvalue, iamid, aois) {
var vval='', vplace='', vcountry='';
if (aois.id == 'topa') {
vval=document.getElementById('from').value;
if (vval.indexOf('country=') != -1 && vval.indexOf('fromplace=') != -1) {
vplace=vval.split('fromplace=')[1].split('&')[0].split('#')[0];
vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
if (vcountry != '' && vplace != '') {
vplace+=', ';
}
} else if (vval.indexOf('country=') != -1 && vval.indexOf('place=') != -1) {
vplace=vval.split('olace=')[1].split('&')[0].split('#')[0];
vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
if (vcountry != '' && vplace != '') {
vplace+=', ';
}
}
} else {
vval=document.getElementById('to').value;
//alert(vval);
if (vval.indexOf('country=') != -1 && vval.indexOf('&place=') != -1) {
vplace=vval.split('&place=')[1].split('&')[0].split('#')[0];
vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
if (vcountry != '' && vplace != '') {
vplace+=', ';
}
//alert(iamid + ' ' + vplace + vcountry);
} else if (vval.indexOf('country=') != -1 && vval.indexOf('fromplace=') != -1) {
vplace=vval.split('fromplace=')[1].split('&')[0].split('#')[0];
vcountry=vval.split('country=')[1].split('&')[0].split('#')[0];
if (vcountry != '' && vplace != '') {
vplace+=', ';
}
}
}
if (iamvalue.indexOf("-0") != -1) {
var latd=document.getElementById("latd");
var latm=document.getElementById("latm");
var lats=document.getElementById("lats");
var longd=document.getElementById("longd");
var longm=document.getElementById("longm");
var longs=document.getElementById("longs");

if (iamid == "gnols") {
latd=document.getElementById("tald");
latm=document.getElementById("talm");
lats=document.getElementById("tals");
longd=document.getElementById("gnold");
longm=document.getElementById("gnolm");
longs=document.getElementById("gnols");
}

var latsign = "+";
if (latd.value.replace("-", "") != latd.value) latsign = "-";
var longsign = "+";
if (longd.value.replace("-", "") != longd.value) longsign = "-";
var alat = eval(latd.value);
alat = Math.abs(alat);
var alatsuffix = 0;
var along = eval(longd.value);
along = Math.abs(along);
var alongsuffix = 0;
if (latm.value != "0" || lats.value != "0") {
alatsuffix = eval((latm.value) / 60.0);
alatsuffix = eval(alatsuffix + (lats.value) / 3600.0);
} else if (latd.value.replace(".", "") != latd.value) {
alatsuffix = 0;
}
if (longm.value != "0" || longs.value != "0") {
alongsuffix = eval((longm.value) / 60.0);
alongsuffix = eval(alongsuffix + (longs.value) / 3600.0);
} else if (longd.value.replace(".", "") != longd.value) {
alongsuffix = 0;
}

var lata = eval(alatsuffix + alat);
var latis=latsign + lata;
var xlatis = latis.replace("-", "").replace("+", "");
if (xlatis == latis) latis = "+" + latis;
var longa = eval(alongsuffix + along);
var longis=longsign + longa;
var retis = ["", ""];

if (iamid == "gnols") {
document.getElementById("weatherto").style.display = 'block';
//retis = find_nearest(latis, longis);
//alert(retis[0] + " then " + retis[1]);
document.getElementById("weatherto").src = '//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim();
} else if (iamid == "longs") {
document.getElementById("weatherfrom").style.display = 'block';
//retis = find_nearest(latis, longis);
//alert(retis[0] + " tHen " + retis[1]);
document.getElementById("weatherfrom").src = '//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=' + encodeURIComponent(vplace + vcountry) + encodeURIComponent(latsign.replace('+','')) + ('' + latis).replace('-','').replace('+','').trim() + encodeURIComponent(',') + encodeURIComponent(longsign.replace('+','')) + ('' + longis).replace('-','').replace('+','').trim();
}
}
}

“; ?>

… to make this happen.

Codewise …


Previous relevant Change the Weather Tutorial is shown below.

Change the Weather Tutorial

Change the Weather Tutorial

Today’s tutorial’s title is a bit cheekier than it really is, as we talk about a change to the software integration of a Weather Reporting web service for the geographicals suite here at this blog. The previous arrangements we detailed below at Integrating Global Weather Ajax with Geographicals Tutorial as shown below.

The previous weather reporting integration used a Web Service and for the changed arrangement we more or less screen scrape with the wonderfully generous World Weather Online website … thanks a lot. And thanks, too, for the link that helped me find this website, as well as the excellent link here that helped with the international country codes that came in handy for the changed arrangements.

Wanted to more or less have the changes in one place and it more or less happened that way, with the vast majority of changes needed to the called get_weather.php code. The calling place_latlong.php called get_weather.php in a different place, but this is only done because am not overly certain the old arrangements will not resurrect themselves. The old way was a bit different in that it did not need any State/Territory type information to proceed, but sometimes our screen scraping method does need to ask for this information.

Think it is good with software integration to aim to keep at least one aspect of the resultant code the same, and so it is here, with the same iframe and Ajax arrangements kept.

Did you know?

If you’ve examined, closely, the changes to get_weather.php above you may have wondered how I could get away with URLs involving city and country (codes) and sometimes state parts and yet, with the code, we are pretty slack about uppercase/lowercase stringency. However, did you notice the URL template we first got as a model to try to achieve …

HTTP://www.worldweatheronline.com/CHITTAGONG-weather/BD.ASPX

… the .ASPX extension tells you this is ASP.Net and would be hosted on a Windows server (and this all happens courtesy of the early days with MS-DOS and some interesting file naming informational link is here), where files in uppercase are the same as those in lowercase or a mix of both, and in this way we get away with some slackness regarding the construction of our URL. If the hosting was Linux or Unix there would be a much more complicated task needed by the programmer, or, as would probably be more likely the case, the website URLs would be arranged differently.


Previous weather integration with geographicals suite via GlobalWeather Integrating Global Weather Ajax with Geographicals Tutorial is shown below.

Integrating Global Weather Ajax with Geographicals Tutorial

Integrating Global Weather Ajax with Geographicals Tutorial

Today’s tutorial is all about software integration and complements yesterday’s Integrating Global Weather into Geographicals Tutorial as shown below.

Software integration takes many forms, and Ajax functionality is that little bit different, perhaps, in that with the tablet and mobile phone “touch” (with all its associated terminology like “gesture recognition”, “pinch” and “smart zoom”) is a concept, with more currency than the “click” and “hover” (of the original web-based systems) and this has increased the choices for ways to achieve things, with there being more accepted mobile world “ways” sometimes a bit different to the laptop/notebook/desktop “ways”. For instance, with Ajax, and the laptop/notebook/desktop world, I tend to want to do a lot with the “hover” (onmouseover) event, but this does not always translate well in the mobile phone/tablet world. In the mobile phone/tablet world multiple window use can get a bit awkward with the smaller screens.

In today’s tutorial we show some integration techniques using HTML “select” (dropdown) and/or
“<a …><img … /></a>” (button) approaches, with the “hover” event doing the same as the “click” event. Whether you like this approach is debatable and you may want to trial such approaches with potential users when you come to creating commercial products. Ideally with catering for all of mobile phone, tablet, desktop and laptop/notebook users you can use the same base code (you may disagree here), with Javascript, HTML and CSS methods employed to compartmentalize device-dependent code using all the various forms of “if” in the softwares.

So the “Get the Weather” functionality of two days ago has a geographical component, that is for sure … the “where” in life is soooo programmable, isn’t it? … so we can integrate it into other Geographical software components we’ve been developing here on this blog.

Today’s part two (of two) of integration tasks, which includes the requirement that some Geographicals of unknown placename should “map” themselves to the nearest placename (via a function called find_nearest (with respect to whatever data source your software uses)), adds the “Get the Weather” Ajax software functionality to each of the “independent child” functions of the Geographicals suite … Sun Angles, Moon Angles, Great Circle Distance and Coriolis Force. Part one (of two) of integration tasks of yesterday was to associate the “Get the Weather” with a placename in the world. This is the more obvious integration task and we show two bits of integration to make that happen way below.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the “Get the Weather” software component of the Sun Angles functionality here.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the “Get the Weather” software component of the Moon Angles functionality here.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the “Get the Weather” software component of the Great Circle Distance functionality here.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the “Get the Weather” software component of the Coriolis Force functionality here.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the Geographical supervisor of the “Get the Weather” software component (and others) here.

And here is the “independent child” Sun Angles live run (which now includes “Get the Weather”).

And here is the “independent child” Moon Angles live run (which now includes “Get the Weather”).

And here is the “independent child” Great Circle Distance live run (which now includes “Get the Weather”).

And here is the “independent child” Coriolis Force live run (which now includes “Get the Weather”).

And finally here is the “supervisory” live run to test all the integration (which now includes “Get the Weather”) yourself.


Previous relevant Integrating Global Weather into Geographicals Tutorial is shown below.

Integrating Global Weather into Geographicals Tutorial

Integrating Global Weather into Geographicals Tutorial

Today’s tutorial is all about software integration and builds on yesterday’s Ajax Global Weather HTTP Get Primer Tutorial as shown below.

Sometimes (well, in my experience) you get the best “kick” out of integrating software components, rather than the writing of the component itself. Sounds weird, doesn’t it, but the fact is, the more functionality you can build into existing software frameworks you have built up, the more useful software becomes, rather than a whole lot of disparate functionality, which may be very cute, but the procedures for which can be forgotten by people in the length of time it takes to wander up the hallway with the mobile phone attached to one’s cranium (would the Queen do this?!).

So yesterday’s “Get the Weather” functionality has a geographical component, that is for sure … the “where” in life is soooo programmable, isn’t it? … so we can integrate it into other Geographical software components we’ve been developing here on this blog.

Part one (of two) of integration tasks is to associate the “Get the Weather” with a placename in the world. This is the more obvious integration task and we show two bits of integration to make that happen below.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the “Get the Weather” software component (from tutorial below) here.

Here is a new link to some downloadable PHP programming source code explaining changes made specifically for the Geographical supervisor of the “Get the Weather” software component (and others) here … lots of the changes here involve readiness for the other piece of integration that we will cover at another tutorial tomorrow.

And finally here is the live run to test all the integration (which now includes “Get the Weather”) yourself.


Previous relevant Ajax Global Weather HTTP Get Primer Tutorial is shown below.

Ajax Global Weather HTTP Get Primer Tutorial

Ajax Global Weather HTTP Get Primer Tutorial

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, maybe a web service website (as for this tutorial … thanks to GlobalWeather here)) make many changes of webpage obsolete.

Today we use HTTP Get methods to procure the data, but you will see other methods that can be used on that link above.

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.

Have a look at the PHP downloadable code which you could rename to get_weather.php
Try a live run here.


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.

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

English Translated Verb Conjugation Countdown Timer Tutorial

English Translated Verb Conjugation Countdown Timer Tutorial

English Translated Verb Conjugation Countdown Timer Tutorial

We had occasion to revisit our inhouse Italian/French/Spanish Verb Conjugation web application “redirector” (in that it is third parties doing the bulk of the work, thanks), further to the English Translated Verb Conjugation Emoji Tutorial‘s last mention.

It struck us, that what could improve the user experience, could be a …

  • 30 second (timed for) …
  • automated click piece of functionality … that is flagged to the user via a …
  • countdown timer (presented as an HTML progress …

    <progress id=myprog title="Click to stop the automated countdown to clicking for conjugations screen" data-allow="y" onclick="this.setAttribute('data-allow','');" style=visibility:hidden; value=30 max=30 min=0></progress>

    … element) …
  • that if clicked, holds off on the automation ideas regarding the Conjugation Emoji Button 📖 clicking …

    function backin() {
    if (myxhr.readyState == 4) {
    if (myxhr.status == 200) {
    if (myxhr.responseText) {
    var towrds=myxhr.responseText.split('"translatedText":"');
    //alert('' + myxhr.responseText);
    if (eval('' + towrds.length) >= 2) {
    //if (myxhr.responseText.indexOf('correre') != -1) { alert(towrds[2]); alert(towrds[1]); alert(towrds[3]); alert(towrds[4]); }
    document.getElementById('ini').value='';
    document.getElementById('ini').placeholder=towrds[1].split('"')[0].split('.')[0].split('!')[0].split('?')[0].replace(/\'/g,'');
    document.getElementById('emojiconjugate').innerHTML='&#128214;'; //' <progress id=myprog title="Click to stop the automated countdown to clicking for conjugations screen" data-allow="y" onclick="event.stopProgagation(); this.setAttribute(' + "'data-allow',''" + '); return false;" style=display:inline-block; value=30 max=30 min=0></progress>';
    document.getElementById('myprog').value=30;
    document.getElementById('myprog').setAttribute('data-allow','y');
    if (1 == 1) {
    document.getElementById('myprog').style.visibility='visible';
    } else {
    document.getElementById('myprog').style.display='inline-block';
    }
    setTimeout(myprogit, 1000);
    setTimeout(function(){
    if (eval('' + ('' + document.getElementById('myprog').getAttribute('data-allow').length)) > 0) {
    document.getElementById('emojiconjugate').click();
    }
    }, 30000);

    }
    }
    }
    }
    }

    function myprogit() {
    if (document.getElementById('myprog')) {
    if (eval('' + ('' + document.getElementById('myprog').getAttribute('data-allow').length)) == 0) {
    if (1 == 1) {
    document.getElementById('myprog').style.visibility='hidden';
    } else {
    document.getElementById('myprog').style.display='none';
    }
    }
    if (eval('' + document.getElementById('myprog').value) > 0) {
    document.getElementById('myprog').value=eval(-1 + eval('' + document.getElementById('myprog').value));
    setTimeout(myprogit, 1000);
    } else {
    if (1 == 1) {
    document.getElementById('myprog').style.visibility='hidden';
    } else {
    document.getElementById('myprog').style.display='none';
    }
    }
    }
    }


    function twofocus(ih) {
    if (ih != '') {
    document.getElementById('ini').focus();
    document.getElementById('ine').focus();
    document.getElementById('emojiconjugate').innerHTML='&nbsp;';
    document.getElementById('myprog').value=30;
    document.getElementById('myprog').setAttribute('data-allow','y');
    if (1 == 1) {
    document.getElementById('myprog').style.visibility='hidden';
    } else {
    document.getElementById('myprog').style.display='none';
    }

    }
    }

… in italian_conjugation.html‘s changed code, can be tried with this live run link, or below.

This change highlights the difference between two CSS approaches to hiding a webpage element …

We chose the latter methodology for today’s work because visibility: hidden; still allows for the room that element would have taken up, so by the time we do apply visibility: visible; there is less annoying jiggering around going on with the webpage look when this happens.


Previous relevant English Translated Verb Conjugation Emoji Tutorial is shown below.

English Translated Verb Conjugation Emoji Tutorial

English Translated Verb Conjugation Emoji Tutorial

When retrying Italian French Spanish Verb Conjugation Emoji Image Tutorial‘s web application recently it struck us that an improvement could be …

  • if the user is entering an English verb to the top left … we could start …
  • filling in the Italian or French or Spanish verb translation (via the textbox’s placeholder attribute, hence, faintly) over to the top right … as well as …
  • add an emoji (button) 📖 (&#128214;) in that top right area too … in addition to the usual …
  • brilliant WordReference.com information presented below this top row in the table

Clicking that emoji (button) 📖 (&#128214;) in that top right area (or merely moving or tabbing in and out of focus at that top right textbox) would link up with WordReference.com verb conjugations better, we think, simulating what happens if the user starts their quest with the top right non-English verb textbox.

You can try this out for yourself in italian_conjugation.html‘s changed code, can be tried with this live run link, or below …


Previous relevant Italian French Spanish Verb Conjugation Emoji Image Tutorial is shown below.

Italian French Spanish Verb Conjugation Emoji Image Tutorial

Italian French Spanish Verb Conjugation Emoji Image Tutorial

We used the combining of …

… to find some practical improvements to some of our existent web applications regarding the use of Emoji Image (in today’s case in the form of background images).

We think the existent French and Italian and Spanish flags as background images are a bit too imposing and so we intervened as per the Javascript …


function emoji_images_maybe(inlineurl) {
switch (inlineurl) {
case "url('it.jpg')":
document.getElementById('mybodtr').style.height='90px';
document.getElementById('englishtoitalian').style.height='90px';
return "linear-gradient(rgba(255,255,255,0.6),rgba(255,255,255,0.6)),url([italianFlagEmojiImageDataURIGoesHere]);
break;


case "url('fr.jpg')":
document.getElementById('mybodtr').style.height='90px';
document.getElementById('englishtoitalian').style.height='90px';
return "linear-gradient(rgba(255,255,255,0.6),rgba(255,255,255,0.6)),url([frenchFlagEmojiImageDataURIGoesHere]);
break;


case "url('es.jpg')":
document.getElementById('mybodtr').style.height='90px';
document.getElementById('englishtoitalian').style.height='90px';
return "linear-gradient(rgba(255,255,255,0.6),rgba(255,255,255,0.6)),url([spanishFlagEmojiImageDataURIGoesHere]);
break;


default:
break;
}
return inlineurl;
}


function fixall(iti) {
was='';
otv='';
document.getElementById('conjugationcell').innerHTML='';
document.getElementById('sl').value=iti;
document.getElementById('sltwo').value=iti;
document.getElementById('slto').value=iti;
document.getElementById('slito').value=iti;
document.getElementById('slverb').value=iti;
document.getElementById('slconj').value=iti;
document.getElementById('mybodtr').style.backgroundImage=emoji_images_maybe("url('" + iti + ".jpg')");
document.getElementById('englishtoitalian').style.backgroundImage=emoji_images_maybe("url('" + iti + ".jpg')");
return iti;
}

Here’s a reminder of how you might derive

Flag
Italian
[italianFlagEmojiImageDataURIGoesHere]
IT 🇮🇹
French
[frenchFlagEmojiImageDataURIGoesHere]
FR 🇫🇷
Spanish
[spanishFlagEmojiImageDataURIGoesHere]
ES 🇪🇸
Navigate to Emoji Image Creator
… into textbox enter (where, regarding an ISO two character code
relating to flag country A=127462 CodePoint to Z=127487 CodePoint) …
127470.127481 127467.127479 127466.127480
… Click “Create Image” button (though use of links above do this for you)
… “Copy Image” the flag at Google Pagespeed
… “Paste” back at Emoji Image Creator …
… Highlight and “Copy” the data uri shown (relevant to flags above)

This mini-makeover for italian_conjugation.html‘s changed code, can be tried with this live run link.


Previous relevant Italian French Spanish Verb Conjugation Text to Speech Tutorial is shown below.

Italian French Spanish Verb Conjugation Text to Speech Tutorial

Italian French Spanish Verb Conjugation Text to Speech Tutorial

In following up on Italian and French and Spanish Verb Conjugation Event Tutorial as shown below we’ve increased functionality of English translations by adding Google Translate Text to Speech capabilities to …

  • Italian
  • French
  • Spanish

… via a new “loudspeaker” icon.

Some of the talking points with today’s changes involve …

  • a “reveal” idea whereby the showing of an HTML element is controlled by its Javascript DOM [element].style.width CSS property, whereby the element is effectively invisible at width:1px and in our case today becomes visible, at width:20px, and, thus, clickable, for Google Translate popup window translation and text to speech capabilities via the control of …
  • binary decision making GUI ease of using HTML input tag type=checkbox and the associated Javascript DOM document.getElementById([element]).checked … because …
  • UX-wise it is good to forewarn users with an option when it comes to functionality involving sound
  • use of Javascript DOM document.getElementsByTagName(‘img’) as a means by which to manipulate HTML elements that are not necessarily provided with an ID global property

As per the other tutorials in this thread, even with new Google Translate Text to Speech and Translation capabilities, nothing changes today about the techniques used today doing away with any need for a server side language by channelling the Ajax jQuery thoughts we presented with Ajax jQuery Primer Tutorial to make the most of the great resource that WordReference.com is. This happens in our HTML and Javascript programming source code you could call italian_conjugation.html, which changed to add in French and Spanish tense contextual verb conjugations in this way, with this live run link.


Previous relevant Italian and French and Spanish Verb Conjugation Event Tutorial is shown below.

Italian and French and Spanish Verb Conjugation Event Tutorial

Italian and French and Spanish Verb Conjugation Event Tutorial

In following up on Italian and French and Spanish Verb Conjugation Tense Tutorial as shown below we’ve increased functionality of English translations to …

  • Italian
  • French
  • Spanish

… and the conjugations from WordReference.com by offering onmouseover (ie. hover) or onclick (or mobile touch) event logic for conjugations offered by using the wonderful MyMemory resource to translate these verb conjugations back into English, and present them in an additional column with a different background colour.

You may recall us using MyMemory once before when we presented HTML/Javascript Hearing and Listening Primer Tutorial earlier on.

As per the other tutorials in this thread, but even more so with gleaning information from the MyMemory API via a get method, nothing changes about the techniques used today doing away with any need for a server side language by channelling the Ajax jQuery thoughts we presented with Ajax jQuery Primer Tutorial to make the most of the great resource that WordReference.com is. This happens in our HTML and Javascript programming source code you could call italian_conjugation.html, which changed to add in French and Spanish tense contextual verb conjugations in this way, with this live run link.

Hope you try out this new functionality.


Previous relevant Italian and French and Spanish Verb Conjugation Tense Tutorial is shown below.

Italian and French and Spanish Verb Conjugation Tense Tutorial

Italian and French and Spanish Verb Conjugation Tense Tutorial

We’ve followed up on Italian Verb Conjugation and Tense Tutorial as shown below with “tense” context to some of the conjugations of …

  • Italian
  • French
  • Spanish

Say “some of the” because …

Even amongst the conjugating language “triplets” above, noticed that when it comes to the “tense” involved, there can be variations, but don’t need to tell a lot of you this old news. Did set me to thinking a bit about the The Tower of Babel story from the Bible, though. What would the world be like if we all spoke the one language? Esperanto, everyone?

There’s a link between “language” and “life”. That’s why a language without “verbs” is not a language. And the Earth back in those dark days before any life, had no conduits for “language”. And it’s hard to see how “life” sort of started up? But I guess chemistry experts might be able to tell us how this might have come about.

“Language” is all about patterns, and mirrors human progress with its “pattern” and “organization” and “flexibility” as a huge part of why we as “humans” got to be such agents of change on Earth. Just wish there had really been a more successful Doctor Dolittle in human history that could have got the “inside goss” (so to speak) on what we could have done better to protect the world’s environments.

As per the other tutorials in this thread, nothing changes about the techniques used today doing away with any need for a server side language by channelling the Ajax jQuery thoughts we presented with Ajax jQuery Primer Tutorial to make the most of the great resource that WordReference.com is. This happens in our HTML and Javascript programming source code you could call italian_conjugation.html, which changed to add in French and Spanish tense contextual verb conjugations in this way, with this live run link.

Hope you try it out, and even contemplate sending us some feedback.


Previous relevant Italian Verb Conjugation and Tense Tutorial is shown below.

Italian Verb Conjugation and Tense Tutorial

Italian Verb Conjugation and Tense Tutorial

Again, we saw that we could extend the functionality of the recent Italian and French and Spanish Verb Conjugation Tutorial as shown below, by, for Italian, to start with, trying to help the native English speaker out for where to look on the “conjugation” table presented for the English verb of interest, regarding conjugation information that might match their (verb) tense of interest.

As you probably well know, every language on Earth has its peculiarities regarding how we express ourselves with regard to time, and a lot of that is associated with the verbs, or action words we use, and in the case of …

  • Italian
  • French
  • Spanish

… that expression of the context of time in the grammatical usage, especially for people speaking the language, is reflected by conjugations made to the verb. Conversely, as I, a native English speaker, got to think about as this web application proceeded, English has words like “am” and “have” and “having” and “been” and “will” and “shall” and “is” and “are” and “was” and “were” and “would” and “should” and “has” and “had” and “to” and ‘”be” and “being” preceeding verbs, which can have, basically, two suffixes “-ing” and “-ed” (expressing present participles and past participles respectively) to try to do what conjugation does for Italian (we program for today) and French and Spanish languages.

But there’s more to “tense” than Past, Present and Future as you well can imagine should you learn a language other than your native tongue, which you tend to “go along with the flow” perhaps unaware that “tense” exists, for some learners. There are concepts as layers on top about the context of the time the person is speaking relative to the time they are or were talking about … it gets complex … so you get concepts like “Present Perfect Progressive” (which we did a tutorial about at HTML/Javascript Present Perfect Progressive Primer Tutorial) if you get right into the ins and outs of all this grammar … which you might need to do to master that second language.

Yet again, nothing changes about the techniques used today doing away with any need for a server side language by channelling the Ajax jQuery thoughts we presented with Ajax jQuery Primer Tutorial to make the most of the great resource that WordReference.com is. This happens in our HTML and Javascript programming source code you could call italian_conjugation.html, which changed to add in Italian “tense” thoughts in this way, with this live run link.

Again, we hope you try some Italian, with specified “tense” prefix words and suffix endings, to see how the new functionality helps you out with Italian verb conjugations.


Previous relevant Italian and French and Spanish Verb Conjugation Tutorial is shown below.

Italian and French and Spanish Verb Conjugation Tutorial

Italian and French and Spanish Verb Conjugation Tutorial

We saw that we could extend the functionality of yesterday’s Italian Verb Conjugation Primer Tutorial as shown below, by accessing other resources from the great WordReference.com, adding French and Spanish verb conjugation to yesterday’s Italian verb conjugation.

As a rule we tend to find that replacing text with HTML select “dropdown” menus can help out this adaption pretty effectively. The other feature of today’s Javascript coding is the use of eval to team with the language code to direct user traffic to the correct parts of the WordReference.com website.

Along the way we added some background “flag” imagery we found at Science Kids … thanks, heaps.

Down the little brick road we also added a couple of hashtag navigators, HTML a links that just navigate within the page, allowing the user to move from the conjugation yellow zone to the translation zone (if you translated from English), as much as anything because the conjugation may need to be prompted by picking the “verb” amongst the list of “translated” possibilities, which you can then feed into the rightmost HTML input type=text textbox to, more than likely, get the (verb) conjugation you may have missed with the first pass.

Nothing changes about the techniques used today doing away with any need for a server side language by channelling the Ajax jQuery thoughts we presented with Ajax jQuery Primer Tutorial to make the most of the great resource that WordReference.com is. This happens in our HTML and Javascript programming source code you could call italian_conjugation.html, which changed to add in French and Spanish in this way, with this live run link.

Hope you try it out.


Previous relevant Italian Verb Conjugation Primer Tutorial is shown below.

Italian Verb Conjugation Primer Tutorial

Italian Verb Conjugation Primer Tutorial

Learning Italian as a native English speaker is best done when you are young, and beginning recently on this quest, I learnt a bit of this.

To me, what stuck out, was how easy we get it in English with regard to (the lack of) conjugating verbs, or articles, or adjectives, in our grammar.

Is it that, in English, we can say something in a hurry and, sort of, wait to fix it up later, because we don’t conjugate verbs in our mind, or is this not how it works in other languages? Actually, am pretty sure no, because conjugation is done so fast in the minds of Italian speakers that it is no issue … hard to imagine, though, from where I’m standing … well, actually, sitting. Am not here to say, but know it is this, that teachers of Italian to English native speakers, concentrate on in early lessons.

With this in mind, we don’t for one second pretend we are not using the wonderful resources at WordReference.com with today’s web application, but we thank them for their brilliance, and just rearrange things that you could glean perfectly well from here but need to take a few more steps to reach the conjugation (today it’s just verbs) web page bits, whereas we throw the conjugation bits straight at you. And yes, we do try to cater for the irregular verbs, and where they are regular you should see the word “regular” mentioned in the yellow zone conjugation areas … because we all know … well, you know what we mean?!

The techniques used today do away with any need for a server side language by channelling the Ajax jQuery thoughts we presented with Ajax jQuery Primer Tutorial to make the most of the great resource that WordReference.com is. This happens in our HTML and Javascript programming source code you could call italian_conjugation.html with this live run link.

So we hope you enjoy this break from our usual (other way around) ESL game (if it’s a game) to some “Conjugate, Italian Style” play.

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 eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment