Yesterday’s Daylight Saving Time Google Geo Chart Tooltips Tutorial work on our Daylight Saving web application could result in navigation to a …
about:blank#blocked
… URL up at the web browser address bar. This can happen when combining HTML iframe “srcdoc” attribute usage (possibly in combination with “src” attribute usage). The research we undertook into this issue got us to …
- The iframe element … W3C
- Play safely in sandboxed IFrames … and …
- Add a new ‘allow-top-navigation-by-user-activation’ flag to iframe sandbox to require a user activation for top-level page navigation
… got us to a moderately changed to daylight_saving_time.php adding a “sandbox” attribute to the “mapif” HTML iframe we use with both “srcdoc” and “src” navigational attributes as per …
<?php
$formbit="</td>" . "<td rowspan=" . $datacnt . " id=gmh style=display:block;><form target=mapif action=" . $mapurl . " method=POST id=myform><input type=hidden id=title name=title value='" . urldecode($ourtitle) . "'></input><input type=hidden id=label name=label " . " value=\"['Lat','\" " . "></input><input type=hidden id=value name=value " . " value=\"'Lon','Name']\" " . "></input><textarea style=display:none; name=data id=data row=56 col=50></textarea><input " . ' onclick="document.getElementById(' . "'mapif'" . ').style.display=' . "'inline'" . ';" style="display:none;" type="submit" id="mapsubmit" value="Submit"></input></form><span id="thgm"><b>Optional Google Map May Go Below</b></span><br><iframe style="border:6px solid teal;display:none;width:430px;height:400px;" sandbox="allow-top-navigation-by-user-activation allow-same-origin allow-scripts allow-popups allow-forms" data-srcdoc="" src="' . $mapurl . "?title=Timezone+Places&label=['Lat'%2C&value='Lon'%2C'Name']&data=%2C[12.65%2C-8%2C~Africa%2FBamako~]%2C[-6.8%2C39.28333%2C~Africa%2FDar_es_Salaam~]" . '"' . ' id="mapif" name="mapif"></iframe><br></td>';
?>
… to improve the situation, caused in the first place, by the security concerns surrounding HTML iframe usage.
The changes we made to daylight_saving_time.html live run link reflect this move to large HTML iframes positioned to the right.
Also to improve, am sure you’d agree, is to change those large scale Geo Charts we could present when the user picks TimeZone Places all within the one continent, from being navigated to in a popup window.open window, to being sent in an HTML “src” attribute iframe element (for short URLs) and to HTML “srcdoc” attribute iframe element via Ajax/FormDate methodologies (for longer URLs (ie. those too long for web address bar URLs)).
Previous relevant Daylight Saving Time Google Geo Chart Tooltips Tutorial is shown below.
Yesterday’s Daylight Saving Time Emoji Country Flag Dropdown Tutorial established the interface to Google Chart Geo Chart for our Daylight Saving Time web application allowing for the emoji clocks presented there be hovered (or mobile platform “touched”) to reveal a Google Charts tooltip.
There is a global Google Charts capability to accept the tooltip content here as being in HTML form, as an alternative to (the default) text form.
Why bother with HTML tooltips? Well, it is the way to lessen the width (at the expense of height) of the Geo Chart tooltip displays, which we’re housing in a relatively small (but scrollable) HTML iframe element. Rather than ask for more width from the HTML iframe, let’s see whether we can make these HTML tooltips happen. For this, we need to meet the issue from two sides, those being …
- the bulk of the task lies with getting our interface to Google Chart Geo Chart to be able to accept HTML as input with the “data” item … by involving the option …
var options = {
tooltip: {isHtml: true},
legend: 'none'
};
… and then adding an additional Geo Chart data column accepting that data as a <p> paragraph </p> element as per …
data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
… then a data item snippet like …
The rain<p>in Spain<p>falls mainly<p>on the plain.
… displays as a tooltip like …The rain
in Spain
falls mainly
on the plain.… reflected by the changed PHP code geo_chart.php‘s changed PHP code live run link … and then there is …
- the sender of the message needs to massage the “data” item it sends as per …
zform.append('data', newdatabit.replace(/\+/g,' ').replace(/\ in\ /g, ',"<br>in ').replace(/\ on\ /g, '<br>on ').replace(/\~\,/g, '"~,'));
… reflected by the changes we made to daylight_saving_time.html live run link
Along the way, as you may notice with the differences link just above, we also added code whereby the user does not always have to (perhaps reach “above the fold”) to instigate this Geo Chart (with clock emojis) functionality by adding more navigational “smarts” within those “fixed” elements by allowing the user to click on the emoji clock (now effectively button) elements within the Android “toast” “fixed” ones, as an alternative way to make this happen. Users in the know will save on “scroll time”, perhaps, this way.
Previous relevant Daylight Saving Time Emoji Country Flag Dropdown Tutorial is shown below.
The incorporation of emoji country flags into our Daylight Saving web application was started with yesterday’s Daylight Saving Time Emoji Country Flag Fixed Tutorial and today …
- we continue on adding emoji country flags into HTML select (dropdown) element innerHTML properties (ie. what you see) …and today while in the emoji mood …
- we allow the user to choose to display the map data temporarily in the form of a Google Chart Geo Chart with emoji clock pointers, because the user chose to do so at a new dropdown element
The onmouseover and ontouchstart events appending to the datasets that make up these Google Charts can get quite verbose, you might know from practice. So our plan is to …
- continue using the same HTML iframe hoster of the Geo Charts that the Map Charts use …
- and when Map Charts require it because the GET URL lengths would become too big, we work it that an HTML form action=[MapChartURL] target=[theIframeName] method=POST makes it happen … the one additional codeline in that logic going (where variable mysrc contains that accumulated URL) …
if (mysrc.length < 800) {
document.getElementById('mapif').style.display='block';
document.getElementById('mapif').src=mysrc;
} else {
document.getElementById('mapif').title=mysrc;
document.getElementById('mapsubmit').click();
}
… the title property not held to those same restrictions to length as GET URL (address bar) navigations … and that is used below … - the Geo Chart logic is based around the global var thgm=false; initialized variable and this initialized HTML select (dropdown) element …
<select id=sthgm onchange=" if (this.value.length == 1) { thgm=false; } else { thgm=true; } if (thgm) { maptogeohere(); } "><option value=" ">Map Chart</option><option value=" ">Geo Chart (with clocks)</option></select>
… calling as user designated (and take a look out for the Ajax/FormData/IframeSrcdoc alternative approach to the navigation) …
var zhr=null, zform=null;
function maptogeohere() {
var thismu='', newdatabit='', newpeninfo='', ijk=0, areg='';
if (document.getElementById('mapif')) {
if (('' + document.getElementById('mapif').title).length > ('' + document.getElementById('mapif').src).length && ('' + document.getElementById('mapif').title).indexOf('&') != -1) {
thismu=('' + document.getElementById('mapif').title);
} else {
thismu=('' + document.getElementById('mapif').src);
}
if (thismu != lastmapurl && (thismu + '~').indexOf('&data=') != -1 && (thismu + '~').indexOf('&data=~') == -1) {
lastmapurl=thismu;
thismu=decodeURIComponent(lastmapurl.split('&data=')[1]);
newpeninfo=thismu.replace(/\]\,\[/g, ',').replace(/\,\[/g, '').replace(/\~\]/g, '').replace(/\,\~/g, '|').replace(/\,/g, '|').replace(/\ /g,'_'); //.replace(/\~\|/g,',');
for (ijk=0; ijk<fromtos.length; ijk++) {
if (newpeninfo.indexOf(fromtos[ijk].split('_')[eval(-1 + fromtos[ijk].split('_').length)]) != -1) {
if (areg == '') {
areg='&aregeographicals=HTTP.' + fromtos[ijk].split('_')[eval(-1 + fromtos[ijk].split('_').length)];
} else {
areg+=',http.' + fromtos[ijk].split('_')[eval(-1 + fromtos[ijk].split('_').length)];
}
newpeninfo=newpeninfo.replace(fromtos[ijk].split('_')[eval(-1 + fromtos[ijk].split('_').length)], fromtos[ijk]);
} else {
newpeninfo=newpeninfo.replace(fromtos[ijk].split('_')[eval(-1 + fromtos[ijk].split('_').length)], fromtos[ijk]);
}
}
newdatabit=" " + thismu.substring(1).replace(/\~\]/g, '~,2]');
lastgeourl=lastmapurl.split('&')[0].replace('/PHP/Map/map.php', '/PHP/GeoChart/geo_chart.php') + '&onclick=y&arexgeographicals=y' + areg + '&width=834&height=520&peninfo=' + encodeURIComponent(newpeninfo.replace(/\~\|/g,',').replace(/\+/g,' ')) + '&country=Places&popularity=&data=' + encodeURIComponent(newdatabit).replace(/\ /g, '%20');
if (document.getElementById('thgm')) {
if (document.getElementById('thgm').innerHTML.indexOf('Optional Google Map May Go Below') != -1) {
document.getElementById('thgm').innerHTML=document.getElementById('thgm').innerHTML.replace('Optional Google Map May Go Below', 'Optional Google <select id=sthgm onchange=" if (this.value.length == 1) { thgm=false; } else { thgm=true; } if (thgm) { maptogeohere(); } "><option value=" ">Map Chart</option><option value=" ">Geo Chart (with clocks)</option></select> May Go Below');
}
}
if ((lastgeourl.length > 800 || thgm) && areg != "" && thgm) {
if (wingeo) {
wingeo.close();
wingeo=null;
}
zhr = new XMLHttpRequest();
zform=new FormData();
zform.append('title', decodeURIComponent(lastmapurl.split('=')[1].split('&')[0]));
zform.append('onclick', 'y');
zform.append('width', '834');
zform.append('height', '520');
zform.append('wouldlikeyoutoseekpermission', 'y');
zform.append('arexgeographicals', 'y');
zform.append('aregeographicals', areg);
zform.append('peninfo', newpeninfo.replace(/\~\|/g,',').replace(/\+/g,' '));
zform.append('country', 'Places');
zform.append('popularity', '');
zform.append('data', newdatabit);
zhr.open('post', lastgeourl.split('?')[0].split('#')[0], true);
zhr.onreadystatechange = showStuff;
document.getElementById('sthgm').value=' ';
thgm=false;
zhr.send(zform);
document.getElementById('sthgm').style.cursor='progress';
document.getElementById('mapif').style.cursor='progress';
} else if (areg != "" && thgm) {
if (wingeo) {
wingeo.close();
wingeo=null;
}
wingeo=window.open(lastgeourl, '_blank','top=50,left=50,width=950,height=625');
thgm=false;
document.getElementById('sthgm').value=' ';
}
}
}
}
function showStuff() {
if (zhr != null) {
if (zhr.readyState == 4) {
if (zhr.status == 200) {
document.getElementById('mapif').srcdoc=zhr.responseText;
document.getElementById('sthgm').value=' ';
document.getElementById('sthgm').style.cursor='pointer';
document.getElementById('mapif').style.cursor='pointer';
thgm=false;
}
}
}
}
… that srcdoc (content) alternative to src (URL (gets to the content)) a useful HTML iframe approach we first talked about at HTML Iframe Srcdoc Attribute Primer Tutorial
You can try this with the changes we made to daylight_saving_time.html live run link, as we leave you with the dropdown emoji country flag incorporation Javascript code …
function augmentselects() {
var aftersp='', optbitshere=[], jopts, thisoptih='', findings=[], jfindings, isotwois='', afteri='', adone='';
var selihis=document.getElementById('timezone').innerHTML;
aftersp=selihis;
optbitshere=selihis.split('</option>');
for (jopts=0; jopts<optbitshere.length; jopts++) {
thisoptih=optbitshere[jopts].split('>')[eval(-1 + optbitshere[jopts].split('>').length)];
if (thisoptih.trim() != '') {
afteri='';
adone='';
findings=seleih.split((',+' + thisoptih.replace('Greenwich Mean Time', '0') + '"').replace('+-','-'));
for (jfindings=0; jfindings<findings.length; jfindings++) {
isotwois=findings[jfindings].split(',')[eval(-1 + findings[jfindings].split(',').length)];
if (('' + isotwois).length == 2) {
if (adone.indexOf(isotwois + ',') == -1) {
adone+=isotwois + ',';
afteri+=' ' + orflag(isotwois);
}
}
}
if (afteri != '') {
aftersp=aftersp.replace('>' + thisoptih + '<', '>' + thisoptih + afteri + '<');
}
}
}
afters[0]=aftersp;
document.getElementById('timezone').innerHTML=aftersp;
selihis=document.getElementById('region').innerHTML;
aftersp=selihis;
optbitshere=selihis.split('</option>');
for (jopts=0; jopts<optbitshere.length; jopts++) {
thisoptih=optbitshere[jopts].split('>')[eval(-1 + optbitshere[jopts].split('>').length)];
if (thisoptih.trim() != '') {
afteri='';
adone='';
findings=seleih.split((' value="' + thisoptih + '/'));
if (eval('' + findings.length) >= 2) {
for (jfindings=1; jfindings<findings.length; jfindings++) {
isotwois=findings[jfindings].split(',')[3];
if (('' + isotwois).length == 2) {
if (adone.indexOf(isotwois + ',') == -1) {
adone+=isotwois + ',';
afteri+=' ' + orflag(isotwois);
}
}
}
}
if (afteri != '') {
aftersp=aftersp.replace('>' + thisoptih + '<', '>' + thisoptih + afteri + '<');
}
}
}
document.getElementById('region').innerHTML=aftersp;
afters[1]=aftersp;
selihis=document.getElementById('sfrom').innerHTML;
aftersp=selihis;
optbitshere=selihis.split('</option>');
for (jopts=0; jopts<optbitshere.length; jopts++) {
thisoptih=optbitshere[jopts].split('>')[eval(-1 + optbitshere[jopts].split('>').length)];
if (thisoptih.trim() != '') {
afteri='';
findings=seleih.split((' value="' + thisoptih + '"'));
if (findings.length >= 2) {
isotwois=findings[1].split(',')[3];
if (('' + isotwois).length == 2) {
if (selceqih.indexOf('"' + isotwois + '">') != -1) {
afteri+=' in ' + orflag(isotwois) + ' ' + selceqih.split('"' + isotwois + '">')[1].split('<')[0].replace(/\'/g, '`').replace(/\"/g, '`');
} else {
afteri+=' in ' + orflag(isotwois);
}
}
}
if (afteri != '') {
aftersp=aftersp.replace('>' + thisoptih + '<', '>' + thisoptih + afteri + '<');
}
}
}
document.getElementById('sfrom').innerHTML=aftersp;
afters[2]=aftersp;
document.getElementById('sto').innerHTML=aftersp.replace(' left', ' right');
afters[3]=aftersp.replace(' left', ' right');
}
Previous relevant Daylight Saving Time Emoji Country Flag Fixed Tutorial is shown below.
Building on yesterday’s Daylight Saving Time Emoji Country Flag TimeZone Tutorial improvements to a Daylight Saving Web Application the theme word today is “fixed”.
Normally, we’ve been lauding …
- CSS property position: absolute; with heaps of praise as your friend getting overlay functionalities happening … but today a useful property for us is …
- CSS property position: fixed;
What is the essential difference between position: absolute; and position: fixed;? Well, position: absolute; can be teamed with a …
- CSS property left: [intoWebPageX]px;
- CSS property top: [intoWebPageY]px;
… whereas position: fixed; can be teamed with a …
- CSS property left: [fromScreenLeftX]px;
- CSS property top: [fromScreenTopY]px;
… meaning that if you have a web page where scrolling is involved to clickable links “below the fold”, but you want to keep some aspects of the webpage constantly “above the fold” you may benefit from position: fixed; thinking. We have two bits to today’s Daylight Saving web application’s display that we want to apply this position: fixed; thinking to …
- the HTML “Timezone Places Map” iframe … and, new to today’s work …
- temporary HTML div (informational dialog box) reminding us of Android “toast” (to inform the user of a TimeZone place’s country name)
In both cases above we do not start out with any static HTML mentioning “fixed” anything? Do you know why? Some of you will have guessed correctly …
- we wait for relative positioning to happen naturally …
- and when we are interested, and the relevant HTML element exists …
- we call out [thatElement].getBoundingClientRect().left (equates to CSS property left: [fromScreenLeftX]px;) and [thatElement].getBoundingClientRect().top (equates to CSS property top: [fromScreenTopY]px;) … in the case of the HTML iframe above … as per …
function fdoneis() {
if (!fixeddone && document.getElementById('gmh')) {
fixeddone=true;
var ifrect=document.getElementById('gmh').getBoundingClientRect();
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
document.getElementById('dstyle').innerHTML+='<style> #mapif { opacity:0.8; left: calc(100% - 500px; top: ' + eval(20 + eval('' + ifrect.top)) + 'px; position: fixed; z-index: 3000; } </style>';
} else {
document.getElementById('dstyle').innerHTML+='<style> #mapif { left: ' + eval(10 + eval('' + ifrect.left)) + 'px; top: ' + eval(20 + eval('' + ifrect.top)) + 'px; position: fixed; z-index: 3000; } </style>';
}
} else {
setTimeout(fdoneis, 200);
}
}
… give or take small pixel offsets, as good places to then freeze them on the screen henceforth. Or by coding (like for the Android “toast” looking temporary dialog boxes) …
if (('' + document.getElementById('custom-alert-1').style.position).toLowerCase().indexOf('absolute') != -1) {
document.getElementById('custom-alert-1').style.position='fixed';
document.getElementById('custom-alert-1').style.left='' + eval(40 + eval('' + thisx)) + 'px';
if (('' + window.scrollY) != '') {
document.getElementById('custom-alert-1').style.top='' + eval(-60 + eval('' + thisy) + Math.floor(eval(('' + window.scrollY).replace('px','') + '.0'))) + 'px';
} else {
document.getElementById('custom-alert-1').style.top='' + eval(-60 + eval('' + thisy)) + 'px';
}
}
… in an apt position the user will have decided by their (non-mobile only, alas, but see) hover (onmouseover event (logic created on the fly)) of one of the TimeZone place “a” links (flanked by the static emoji and dynamic country flag emoji)) …
asis[iasis].onmouseover=function(event) {
if (document.getElementById('result')) { document.getElementById('result').title='Timezone and Latitude and Longitude and Trip Planner functionalities (times as of screen creation)'; }
var jindex=eval('' + event.target.getAttribute('data-title'));
var thisx=0, thisy=0;
if (event.touches) {
thisx=event.changedTouches[0].clientX;
thisy=event.changedTouches[0].clientY;
} else if (event.clientX) {
thisx=event.clientX;
thisy=event.clientY;
} else {
thisx=event.pageX;
thisy=event.pageY;
}
if (('' + document.getElementById('custom-alert-1').style.position).toLowerCase().indexOf('absolute') != -1) {
document.getElementById('custom-alert-1').style.position='fixed';
document.getElementById('custom-alert-1').style.left='' + eval(40 + eval('' + thisx)) + 'px';
if (('' + window.scrollY) != '') {
document.getElementById('custom-alert-1').style.top='' + eval(-60 + eval('' + thisy) + Math.floor(eval(('' + window.scrollY).replace('px','') + '.0'))) + 'px';
} else {
document.getElementById('custom-alert-1').style.top='' + eval(-60 + eval('' + thisy)) + 'px';
}
}
inctyis=' in ' + beforectys[jindex];
var tzd = new Date(new Date().toLocaleString("en-US", {timeZone: event.target.title.split('~')[1].split('~')[0].split(' ')[0]}));
// 1 o'clock is 🕐
// 2 o'clock is 🕑
// 12 o'clock is 🕛
// 2:30 is 🕝
// 11:30 is 🕦
// 12:30 is 🕧
var bestemojicodepoint=0;
var hris=eval(('' + tzd).split(' GMT')[0].split(' ')[eval(-1 + ('' + tzd).split(' GMT')[0].split(' ').length)].split(':')[0]);
var spprefix='';
var spsuffix='';
if (hris >= 12) { hris-=12; spprefix="<span style='filter: invert(1); mix-blend-mode: difference;'>"; spsuffix="</span>"; }
var minis=eval(('' + tzd).split(' GMT')[0].split(' ')[eval(-1 + ('' + tzd).split(' GMT')[0].split(' ').length)].split(':')[1]);
var gmthris=hris;
var gmtminis=minis;
if (minis > 45 && hris == 12) {
bestemojicodepoint=128336;
} else if (minis >= 45) {
bestemojicodepoint=128336;
bestemojicodepoint+=hris;
} else if (minis <= 15) {
bestemojicodepoint=128335;
bestemojicodepoint+=hris;
} else if (minis > 15 && minis < 45 && eval(hris % 12) == 0) {
bestemojicodepoint=128359;
} else {
bestemojicodepoint=128347;
bestemojicodepoint+=hris;
}
if (event.target.title.indexOf(inctyis) == -1) { lastts=' on ' + ('' + tzd).split(' GMT')[0]; event.target.setAttribute('data-curdatetime', ('' + tzd).split(' GMT')[0]); event.target.title=event.target.title.replace('~]', inctyis + '~]'); }
document.getElementById('custom-alert-1').innerHTML=event.target.title.split('~')[1].split('~')[0] + ' <br>where time is <br>' + ('' + tzd).split(' GMT')[0] + ' ' + spprefix + String.fromCodePoint(bestemojicodepoint) + spsuffix;
document.getElementById('custom-alert-1').style.visibility='visible';
if (!within_hiding_fourfivehundred) {
within_hiding_fourfivehundred=true;
setTimeout(andt, hiding_fourfivehundred);
}
inctyis='';
if (eval('' + thisx) > eval(eval('' + beforerects[jindex].left) + eval('' + beforerects[jindex].width))) {
isok=2;
maxok=2;
event.target.click();
if (1 == 2) {
alert(beforectys[jindex] + ' will show on map to right');
}
}
};
// and then for mobile platform …
asis[iasis].ontouchstart=asis[iasis].onmouseover;
… a lot of what else we’d like to explain encapsulated in colour coded code above, that is placed in “the bigger picture” before where we add those dynamically placed emoji country flags.
- asis[iasis] represents a member of an array of “a” links that could “nest into …
var asis=document.getElementsByTagName('a');
for (var iasis=0; iasis<asis.length; iasis++) {
// member of an array of "a" link logic goes here
}
- user’s event object gets passed in, the most interesting data member being “event.target” that is the “a” HTML element object that got hovered over
- var jindex=eval(” + event.target.getAttribute(‘data-title’)); represents the index into the saved array of [element].getBoundingCliuentRect() result sets for each “a” link that contains a “/” (yes, those are TimeZone Place “a” elements) … helped out by the preceeding …
// part of member of an array of "a" link logic ... where "tcic" is a two letter ISO country code ...
asis[iasis].style.textAlign='left'; // we want it left aligned because we can then tell whether the user hovered over the "yet to be placed" emoji country flags ... via ... if (eval('' + thisx) > eval(eval('' + beforerects[jindex].left) + eval('' + beforerects[jindex].width))) { alert('Yes, they did hover over the emoji country flag'); }
beforeids=asis[iasis].id;
beforerects.push(asis[iasis].getBoundingClientRect()); // relevant to previous comment
if (selceqih.indexOf('"' + tcic + '">') != -1) {
ctynameis=selceqih.split('"' + tcic + '">')[1].split('<')[0].replace(/\"/g, '`').replace(/\'/g, '`'); beforectys.push(ctynameis); asis[iasis].setAttribute('data-title', '' + eval(-1 + beforerects.length)); // allow var jindex=eval('' + event.target.getAttribute('data-title')); above, work
// more member of an array of "a" link logic here
}
// end of part of member of an array of "a" link logic
- var tzd = new Date(new Date().toLocaleString(“en-US”, {timeZone: event.target.title.split(‘~’)[1].split(‘~’)[0].split(‘ ‘)[0]})); gets the datetime at relevant TimeZone place (of “a” link) now
- code to work out nearest quarter hour clock emoji we can append to Android “toast” dialog box, along with that timestamp wording, based on some PHP code we developed when we presented TimeZone Country Places Emoji Tutorial
- code to create and set up the later self destruction of the Android “toast” like dialog box …
- initially …
<style>
.custom-alert {
display: inline-block;
visibility: hidden;
background-color: #666;
color: #fff;
text-align: enter;
margin: 5% auto;
padding: 12px 48px;
opacity: 0.7;
font-size: 24px;
}
</style>
<div id='custom-alert-1' class="custom-alert" style="position:absolute;top:20;left:20;z-index:12;"></div>
- code above … and this …
document.getElementById('custom-alert-1').innerHTML=event.target.title.split('~')[1].split('~')[0] + ' <br>where time is <br>' + ('' + tzd).split(' GMT')[0] + ' ' + spprefix + String.fromCodePoint(bestemojicodepoint) + spsuffix;
document.getElementById('custom-alert-1').style.visibility='visible';
if (!within_hiding_fourfivehundred) {
within_hiding_fourfivehundred=true;
setTimeout(andt, hiding_fourfivehundred);
}
- self-destroyed by …
function andt() {
within_hiding_fourfivehundred=false;
document.getElementById('custom-alert-1').innerHTML="";
document.getElementById('custom-alert-1').style.visibility='hidden';
}
- initially …
- event.target.click(); as nested in if (eval(” + thisx) > eval(eval(” + beforerects[jindex].left) + eval(” + beforerects[jindex].width))) { alert(‘Yes, they did hover over the emoji country flag’); } “the user hovered over the emoji country flag” then we join in the old “onclick” logic of the “a” link that can populate the HTML iframe with a Google Charts Map Chart
- then, as an idea to allow for mobile platform functionality we tried …
asis[iasis].ontouchstart=asis[iasis].onmouseover;
… placed after the big onmouseover event logic definition above, and (the use of) it more or less worked on mobile
An interesting thing we found here was the thought that a CSS :after pseudo selector … as per Daylight Saving Time Emoji Country Flag TimeZone Tutorial‘s …
var proposedstyle='';
for (var iasis=0; iasis<asis.length; iasis++) {
if (('' + asis[iasis].id).indexOf('/') != -1) {
if (seleih.indexOf(asis[iasis].id) != -1) {
tcic=seleih.split(asis[iasis].id)[1].split(',')[3];
if (tcic.length == 2) {
proposedstyle='<style> a[title*="' + asis[iasis].id + '"]:after { content: "' + orflag(tcic) + '" } </style>';
if (document.getElementById('dstyle').innerHTML.indexOf(proposedstyle.split('{')[0]) == -1) {
document.getElementById('dstyle').innerHTML+=proposedstyle;
}
}
}
}
}
… placed after the onmouseover and
And so, you can see this with the changes we made to daylight_saving_time.html live run link for your perusal (and trial).
Previous relevant Daylight Saving Time Emoji Country Flag TimeZone Tutorial is shown below.
Today’s solution to a “smallish” display non-mission-critical issue regarding a web application (adding some “emoji country flags” to augmenting some pre-existant static CSS emoji arrangements embellishing a list of TimeZones in the web application of SVG Network Digital and Analogue Clock Local Time Tutorial) is being published because it combines a lot of interesting Javascript and CSS concepts we’d like to share, some of those being …
- the dynamic “at call” adding of …
- CSS styling …
- within document.body.innerHTML … via …
- within invisible HTML (initially empty) element
- CSS (:after) pseudo selector (and attribute selector) :after (augmenting static pre-ordained static CSS :before) styling …
- the content assisted by a new static string (via an invisible static HTML select element …
<select id="sele" style="display:none;"><option value="Africa/Abidjan" data-geo="5.31666,-4.03334,GMT,CI,+0">Africa/Abidjan</option><option value="Africa/Accra" data-geo="5.55,-0.21667,GMT,GH,+0">Africa/Accra</option><option value="Africa/Addis_Ababa" data-geo="9.03333,38.7,EAT,ET,+3">Africa/Addis_Ababa</option> ... </select>
… (we started using ever since the blog posting thread headed by Google Chart Geo Chart Windows Batch File Tutorial‘s (wls_vs_php.htm reference) used it via PHP TimeZone derived data) … and triggered to happen via … - iframe (as target of an HTML form element submission event) onload event … our “user on call” “intervention point” (=”function postipetc()”) (always an important integration consideration) … logic (as its last clause)
-
… featuring …
… that “at call” call (by us) saving bandwidth versus less speedy during execution “trade-off” decision we made on this project (because of new array above, there got to be this two-pronged approach choice available, forsaking a traversal of this new array to pre-populate the HTML div element (initially statically set to …
<div id="dstyle" style="display:none;"></div>
… mentioned above)).
Another reason for this decision, as well, for us, is due to our deep admiration for …
Javascript "adding on the fly" CSS styling into the webpage HTML
For us, it seems to always work, even for “after the HTML creation”, it seems to us, as in today’s work. We’re not going to test it, but perhaps the :after selector CSS is what’s helping out here, but anyway,it works.
Let’s let you know that the new Javascript to create the content consists of …
function orflag(thiscc) { // in is ISO 2 character code and return is String.fromCodePoint() derived emoji country flag CSS content
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;
}
function postipetc() { // called off the iframe onload event which represents a "user on call" intervention
var proposedstyle='', tcic='';
var asis=document.getElementsByTagName('a');
for (var iasis=0; iasis<asis.length; iasis++) {
if (('' + asis[iasis].id).indexOf('/') != -1) {
if (seleih.indexOf(asis[iasis].id) != -1) {
tcic=seleih.split(asis[iasis].id)[1].split(',')[3];
if (tcic.length == 2) {
proposedstyle='<style> a[title*="' + asis[iasis].id + '"]:after { content: "' + orflag(tcic) + '" } </style>';
if (document.getElementById('dstyle').innerHTML.indexOf(proposedstyle.split('{')[0]) == -1) {
document.getElementById('dstyle').innerHTML+=proposedstyle;
}
}
}
}
}
}
You can see this with the changes we made to daylight_saving_time.html live run link for your perusal (and trial).
Previous relevant SVG Network Digital and Analogue Clock Local Time Tutorial is shown below.
Off the list of TimeZones we offered on the first dropdown of SVG Network Digital and Analogue Clock Daylight Saving Tutorial‘s web application, you may have noticed one glaring omission. That’s right, we were missing …
- local time … and today we remedy that, as well as …
- improve a loading logic weakness that could result in our SVG object element returning null … and …
- add an onhover Country Name piece of display data
Leaving out the fairly straightforward last change above, let’s go into more detail regarding those other improvements.
- local time …
the issue here being that a “local time” is awkward, but possible (thanks to this useful link) in serverside PHP …
<?php
if (strpos(('' . $_SERVER['QUERY_STRING']), "localtime") !== false) {
echo "<html><body><div id=mydiv></div><script type='text/javascript'>
var asuff='" . $midbit . $csuff . "';
var adate = new Date();
var dow=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
var his=eval('' + adate.getHours());
var mis=eval('' + adate.getMinutes());
var sis=eval('' + adate.getSeconds());
var ssuff='';
if (('' + adate).indexOf(' GMT') != -1) { ssuff=' GMT' + ('' + adate).split(' GMT')[1]; }
if (1 == 1) {
document.getElementById('mydiv').innerHTML=dow[eval('' + adate.getDay())] + ' ' + ('0' + his).slice(-2) + ':' + ('0' + mis).slice(-2) + ':' + ('0' + sis).split('.')[0].slice(-2) + ' ' + ('0' + adate.getDate()).slice(-2) + ' ' + ('0' + eval(1 + eval('' + adate.getMonth()))).slice(-2).replace('01','Jan').replace('02','Feb').replace('03','Mar').replace('04','Apr').replace('05','May').replace('06','Jun').replace('07','Jul').replace('08','Aug').replace('09','Sep').replace('10','Oct').replace('11','Nov').replace('12','Dec') + ' ' + ('' + adate.getFullYear()) + ' ' + ssuff + asuff;
} else {
document.write(dow[eval('' + adate.getDay())] + ' ' + ('0' + his).slice(-2) + ':' + ('0' + mis).slice(-2) + ':' + ('0' + sis).split('.')[0].slice(-2) + ' ' + ('0' + adate.getDate()).slice(-2) + ' ' + ('0' + eval(1 + eval('' + adate.getMonth()))).slice(-2).replace('01','Jan').replace('02','Feb').replace('03','Mar').replace('04','Apr').replace('05','May').replace('06','Jun').replace('07','Jul').replace('08','Aug').replace('09','Sep').replace('10','Oct').replace('11','Nov').replace('12','Dec') + ' ' + ('' + adate.getFullYear()) + ' ' + ssuff + asuff);
}
</script></body></html>";
}
?>
… but patently more suited to the Javascript available to us with the “HTML supervisor” client facing web application component as per …
var loct='';
var adate = new Date();
var dow=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
var his=eval('' + adate.getHours());
var mis=eval('' + adate.getMinutes());
var sis=eval('' + adate.getSeconds());
var ssuff='';
if (('' + adate).indexOf(' GMT') != -1) { ssuff=' GMT' + ('' + adate).split(' GMT')[1]; }
var curts=dow[eval('' + adate.getDay())] + ' ' + ('0' + his).slice(-2) + ':' + ('0' + mis).slice(-2) + ':' + ('0' + sis).split('.')[0].slice(-2) + ' ' + ('0' + adate.getDate()).slice(-2) + ' ' + ('0' + eval(1 + eval('' + adate.getMonth()))).slice(-2).replace('01','Jan').replace('02','Feb').replace('03','Mar').replace('04','Apr').replace('05','May').replace('06','Jun').replace('07','Jul').replace('08','Aug').replace('09','Sep').replace('10','Oct').replace('11','Nov').replace('12','Dec') + ' ' + ('' + adate.getFullYear()) + ' ' + ssuff;
var loct='';
if (tz.indexOf('localtime') != -1) { loct=curts; }
… and, as such, to continue the process every second to update our clock, we set in play a navigational technique we’d never put into play before that we can remember, that being …
// Rather than reloading content in an HTML iframe element via [iFrameElementObject].src=[URLtoUseAsContentForTheIframe]; ... for SVG object ID=myclock we ...
function getmelt(iois) {
if (iois != null) {
var aconto = (iois.contentWindow || iois.contentDocument);
if (aconto != null) {
if (aconto.document) { aconto = aconto.document; }
if (aconto.body != null) {
if (tz.indexOf('localtime') != -1) {
if (aconto.body.innerHTML.indexOf('</div>') != -1) {
loct=aconto.body.innerHTML.split('</div>')[0].split('>')[eval(-1 + aconto.body.innerHTML.split('</div>')[0].split('>').length)];
} else {
loct=aconto.body.innerHTML;
}
if (uprefix.indexOf('&both=') > 0) {
uprefix='&both=' + uprefix.split('&both=')[1];
} else if (uprefix.indexOf('&analogue=') > 0) {
uprefix='&analogue=' + uprefix.split('&analogue=')[1];
} else if (uprefix.indexOf('&y=') > 0) {
uprefix='&y=' + uprefix.split('&y=')[1];
}
document.getElementById('myclock').data="svg_clock.php?timezone=" + encodeURIComponent(tz + loct) + uprefix;
setTimeout(morelt, 1000);
}
}
}
}
}
function morelt() {
document.getElementById('loces').src='cldate.php?localtime=' + Math.floor(Math.random() * 198765433);
}
// ... in an onload event function for an HTML iframe element, presenting "enough of a flag" to tell the other web application components we are wanting local time
… the downside being that the SVG tends to flash a bit (with activity) - improve a loading logic weakness that could result in our SVG object element returning null …
we actually had flawed code up until today not doing its job, but today the “HTML Supervisor”‘s “setTimeout(checkmyobject,4000);” checker of existence of the SVG object is better for …
function checkmyobject() {
if (!document.getElementById('myclock')) {
window.location.reload(true);
} else {
var t=document.querySelector("#myclock");
var htmlDocument=t.contentDocument;
if (('' + htmlDocument).replace(/\<p\>/g,'').replace(/\<\/p\>/g,'').replace(String.fromCharCode(10),'').replace('null','') == '') { window.location.reload(true); }
}
}
… in its approach to, for the first time we can remember doing, refreshing the webpage programmatically via “window.location.reload(true);” to eventually get such failed initially loaded SVG object data to succeed
… again, you can see within …
- SVG graphics display … calling on …
- the changed HTML supervisor svg_clock.html live run … of …
- the changed PHP helper supervisor svg_clock.php … of …
- the changed PHP (Digital Clock) content helper cldate.php
Previous relevant SVG Network Digital and Analogue Clock Daylight Saving Tutorial is shown below.
We were pondering how best to “value add” onto the web application of our recent SVG Network Digital and Analogue Clock Tutorial when we remembered that the “star codeline” of that project’s “PHP (Digital Clock) content helper” was …
<?php
$thedate=date('l H:i:s d M Y e');
?>
… and we leave this to be …
<?php
$thedate=date('l H:i:s d M Y e I~') . $emflag;
?>
… after today’s two streams of work …
- flag Daylight Saving clock times having noticed researching PHP date function’s “date ( string $format [, int $timestamp = time() ] ) : string” first format parameter the interesting switch …
format character Description Example returned values I (capital i) Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise. … we could use …
<?php
$midbit="";
if (isset($_GET['timezone'])) {
if (str_replace("+"," ",urldecode($_GET['timezone'])) == "") {
date_default_timezone_set("UTC");
} else {
$midbit="http://www.timezoneconverter.com/cgi-bin/zoneinfo?tz=" . urlencode(str_replace("+","_",urldecode($_GET['timezone'])));
date_default_timezone_set(str_replace("+"," ",urldecode($_GET['timezone'])));
}
} else {
date_default_timezone_set("UTC");
}
$thedate=date('l H:i:s d M Y e I~') . $emflag;
if (strpos($thedate, " 1~") !== false) {
$thedate=str_replace(" 1~", " ", $thedate);
} else if (strpos($thedate, " 0~") !== false) {
$midbit="";
$thedate=str_replace(" 0~", " ", $thedate);
}
if (isset($_GET['both'])) {
echo $thedate . $midbit . '</text>' . $midbit . '<circle id="cclock" cx="200" cy="200" r="150" fill="navy"/><text>';
} else if (isset($_GET['analogue'])) {
echo $thedate . $midbit . '</text>' . $midbit . '<circle id="cclock" cx="200" cy="200" r="150" fill="navy"/><text>';
} else {
echo $thedate . $midbit;
}
?>… as a means by which its compadre web application components can be helped out recognizing Daylight Saving clock (time) scenarios
- add some Internationalization improvement by adding some emoji flag improvements getting to this project’s “PHP (Digital Clock) content helper” as that $emflag variable as per …
<?php
$emflag="";
if (isset($_GET['emflag'])) {
$emflag=" " . urldecode($_GET['emflag']);
}
?>… and instigated back at the HTML supervisor as per …
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("");
}
}
// Thanks to https://stackoverflow.com/questions/35948102/how-to-create-a-border-bottom-in-css-using-a-text-character-such-as-a-dash-lett
var es="<style> " + String.fromCharCode(10);
es+="h4 { " + String.fromCharCode(10);
es+="position:relative; " + String.fromCharCode(10);
es+="overflow:hidden; " + String.fromCharCode(10);
es+=" padding-bottom:0.5em; " + String.fromCharCode(10);
es+=" } " + String.fromCharCode(10);
es+="h4:after { " + String.fromCharCode(10);
es+=" position:absolute; " + String.fromCharCode(10);
es+=" line-height:0.5em; " + String.fromCharCode(10);
es+=" bottom:0; " + String.fromCharCode(10);
es+=" left:0; " + String.fromCharCode(10);
es+=" right:0; " + String.fromCharCode(10);
es+=" white-space:pre; " + String.fromCharCode(10);
es+=" content:'- - - - - - - - - - - - - - - - '; " + String.fromCharCode(10);
es+=" text-shadow: 0.7em 0 transparent, 1.4em 0 transparent; " + String.fromCharCode(10);
es+=" } " + String.fromCharCode(10);
es+=" " + String.fromCharCode(10);
es+=" hr + h4:after { " + String.fromCharCode(10);
es+=" text-shadow: 0.7em 0.2em transparent, 1.4em -0.2em transparent; " + String.fromCharCode(10);
es+=" } " + String.fromCharCode(10);
es+=" </style> " + String.fromCharCode(10);
var froms='youllneverfindthis';
var tos='';
var prevfromefs='youllneverfindthis';
var fromefs='youllneverfindthis';
var toefs='';
var isotwois='';
var flagbit='';
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 ourtzlist="<option value=\"Africa/Abidjan\" data-geo=\"5.31666,-4.03334,GMT,CI,+0\">Africa/Abidjan</option><option value=\"Africa/Accra\" data-geo=\"5.55,-0.21667,GMT,GH,+0\">Africa/Accra</option><option value=\"Africa/Addis_Ababa\" data-geo=\"9.03333,38.7,EAT,ET,+3\">Africa/Addis_Ababa</option><option value=\"Africa/Algiers\" data-geo=\"36.78333,3.05,CET,DZ,+1\">Africa/Algiers</option><option value=\"Africa/Asmara\" data-geo=\"15.33333,38.88333,EAT,ER,+3\">Africa/Asmara</option><option value=\"Africa/Bamako\" data-geo=\"12.65,-8,GMT,ML,+0\">Africa/Bamako</option>"]; // etcetera etcetera etcetera
var parts;
var tz=location.search.split('timezone=')[1] ? decodeURIComponent(location.search.split('timezone=')[1].split('&')[0]).replace(/\+/g,' ') : '';
if (tz != '') { froms=location.search.split('timezone=')[1].split('&')[0]; parts=ourtzlist.split(decodeURIComponent(froms)); if (parts.length > 1) { isotwois=parts[1].split(',')[3]; if (isotwois.replace(/\?/g,'').length == 2) { if (document.URL.indexOf('?') != -1) { fromefs=encodeURIComponent(orccflag(isotwois.toUpperCase())); flagbit='&emflag=' + fromefs; } else { fromefs=encodeURIComponent(orccflag(isotwois.toUpperCase())); flagbit='?emflag=' + fromefs; } } } }
var uprefix=('?' + (document.URL + flagbit + '?#').split('#')[0].split('?')[1]).replace('?','&').replace('timezone=','prtimezoneev=').replace('emflag=','premflagev=').replace(froms,tos).replace(fromefs,toefs).replace('prtimezoneev=&','').replace('premflagev=&','');
function orccflag(thiscc) {
var ccsuff='', ccchar=' ', cde='', sfcp='';
for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
sfcp+=String.fromCodePoint(eval('' + dri[eval('' + lri.indexOf(ccchar))]));
ccsuff+=cde + ('' + dri[eval('' + lri.indexOf(ccchar))]); //'' + dri[eval('' + lri.indexOf(ccchar))] + ';';
cde='.';
}
es=es.replace(/\-\ \ \ \ \ /g, sfcp + ' ');
return sfcp; //ccsuff;
}
… and then later within the document.body part of the webpage that global variable es (helping create an emoji (flag) border) comes into play …
<script type='text/javascript'>
if (tz != "") {
document.write("<h1 id=myh1>SVG Network Clock</h1><h3>RJM Programming - January, 2020</h3><h4>Thanks to The PHP Anthology Volume II: Applications by Harry Fuecks</h4><p>The <select id=mysel onchange=gonext(this.value);>" + ("<option value=''>GMT</option>" + tzlist).replace('>' + tz + '<',' selected>' + tz + '<') + "</select> <select style='display:inline-block;' onchange=\"location.href=(document.URL.replace('analogue=','x=').replace('both=','y=') + ('&' + this.value + '=y').replace('&=y','')).replace('.html&','.html?');\"><option value=''>digital clock</option><option value=analogue" + analoguesuffix + ">analogue clock</option><option value=both" + bothsuffix + ">digital and analogue clock</option></select> sponsored by SVG is<br><hr style='height:3px;' title='Click here for any Daylight Saving Time information' onclick=\"window.open('http://www.timezoneconverter.com/cgi-bin/zoneinfo?tz=" + encodeURIComponent(tz) + "','_blank','top=50,left=50,width=500,height=500');\"><br><object id=myclock data='svg_clock.php?timezone=" + encodeURIComponent(tz) + uprefix + "' width='1200' height='530' type='image/svg+xml' /></p>" + es);
}
</script>
… you can see within …
- SVG graphics display … calling on …
- the changed HTML supervisor svg_clock.html live run … of …
- the changed PHP helper supervisor svg_clock.php … of …
- the changed PHP (Digital Clock) content helper cldate.php
Previous relevant SVG Network Digital and Analogue Clock Tutorial is shown below.
The recent SVG Network Clock Primer Tutorial work created …
- an SVG (text element) based network Digital clock … and today we extend functionality to add …
- an SVG (circle and line element) based network Analogue clock
… and allow for the SVG text element content also be a tooltip for the SVG circle element via SVG title subelement …
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt);">
<defs>
<radialGradient id="navyGradient"
cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
<stop offset="0%" stop-color="navy"/>
<stop offset="100%" stop-color="purple"/>
</radialGradient>
<radialGradient id="yellowGradient"
cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
<stop offset="0%" stop-color="yellow"/>
<stop offset="100%" stop-color="orange"/>
</radialGradient>
</defs>
<text id="sclock" x="30" y="30" fill="green" class="Rrrrr" text-anchor="left">
Time goes here
</text>
<g>
<circle id="cclock" cx="200" cy="200" r="150" fill="transparent">
<title></title>
</circle>
<line id="chour" x1="200" y1="200" x2="200" y2="100" style="stroke:transparent;stroke-width:3" />
<line id="cminute" x1="200" y1="200" x2="340" y2="200" style="stroke:transparent;stroke-width:2" />
<line id="csecond" x1="200" y1="200" x2="200" y2="320" style="stroke:transparent;stroke-width:1" />
</g>
</svg>
… referenced via …
var sclock;
var cclock, cclocktitle;
var chour;
var cminute;
var csecond;
function init(evt) {
if (window.svgDocument == null) {
svgDocument = evt.target.ownerDocument;
}
sclock = svgDocument.getElementById("sclock").firstChild;
cclock = svgDocument.getElementById("cclock");
cclocktitle = svgDocument.getElementById("cclock").firstElementChild;
chour = svgDocument.getElementById("chour");
cminute = svgDocument.getElementById("cminute");
csecond = svgDocument.getElementById("csecond");
gettime();
}
function gettime() {
getURL('<?php echo $turl; ?>', showtime);
}
function showtime(rsp) {
var tstmp=rsp.content.split('<')[0];
var hmsbit='';
if (rsp.content.indexOf('<circle') != -1) {
cclocktitle.innerHTML=tstmp;
hmsbit=eachsecond(tstmp.split(' ')[1]);
if (eval(tstmp.split(' ')[1].split(':')[0]) >= 12) {
cclock.style.fill = 'url(#navyGradient)'; // 'navy';
chour.style.stroke = 'white';
cminute.style.stroke = 'white';
csecond.style.stroke = 'white';
} else {
cclock.style.fill = 'url(#yellowGradient)'; // 'yellow';
chour.style.stroke = 'navy';
cminute.style.stroke = 'navy';
csecond.style.stroke = 'navy';
}
chour.setAttribute('x2', hmsbit.split(',')[0]);
chour.setAttribute('y2', hmsbit.split(',')[1]);
cminute.setAttribute('x2', hmsbit.split(',')[2]);
cminute.setAttribute('y2', hmsbit.split(',')[3]);
csecond.setAttribute('x2', hmsbit.split(',')[4]);
csecond.setAttribute('y2', hmsbit.split(',')[5]);
}
if (document.URL.indexOf('analogue=') != -1) {
sclock.data = ''; //rsp.content.split('<')[0];
} else {
sclock.data = tstmp; //rsp.content.split('<')[0];
}
setTimeout('gettime()', 1000);
}
… all changes regarding the svg_clock.php of SVG Network Clock web application of …
- SVG graphics display … calling on …
- the changed HTML supervisor svg_clock.html live run … of …
- the changed PHP helper supervisor svg_clock.php … of …
- the changed PHP (Digital Clock) content helper cldate.php
Previous relevant SVG Network Clock Primer Tutorial is shown below.
Another approach to a Digital Clock web application is off and running today, reminiscent of some of the concepts in Digital Clock Styling for Daylight Saving Tutorial. Today’s difference though is a significant one involving …
- SVG graphics display … calling on …
- HTML supervisor svg_clock.html … of …
- PHP helper supervisor svg_clock.php … of …
- PHP (Digital Clock) content helper cldate.php
… and we’d like to thank The PHP Anthology (Volume II: Applications) by Harry Fuecks (ISBN: 0-9579218-4-5) for the inspiration of methodologies used. We are encouraged to move on from this “proof of concept” beginning because we are enthusiastic to build on the very simple SVG text element beginnings with more advanced work in future blogs.
Feel free to try it yourself here or look below at (initially) a GMT digital clock …
Previous relevant Digital Clock Styling for Daylight Saving Tutorial is shown below.
The Daylight Saving Time web application we talked about with Daylight Saving Time TimeZone Emoji Tutorial starts out showing a digital clock displaying the time at various Timezone Places around the world. It occurred to us, this morning, looking over at the alarm clock (also digital) that it would be interesting to recreate that look, at least a bit. But what immediately seemed appealing was not any photography or media based work, but the really simple CSS idea to make use of …
- HTML table elements containing …
- two tr row elements per numeral (or digit) of time to define … each row containing a …
- single td cell with the content (ie. non-breaking space) … but working to define the numbers via the correct combinations of use of …
- style=’border-top:28px solid red;’
- style=’border-bottom:28px solid red;’
- style=’border-left:28px solid red;’
- style=’border-right:28px solid red;’
… for all the td cells involved
… reminding me of how incredible it is that just a few lines can be used by artists to have a viewer know exactly what they were depicting. More with faces, mind you, but even so, is an interesting part of how our brains work.
The code changes just involve a new array in the Javascript as per …
var dcborder=[
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-left:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid red;border-left:28px solid red;border-right:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid transparent;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid transparent;border-right:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid red;border-top:28px solid red;border-left:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-top:28px solid red;border-right:28px solid red;border-bottom:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid transparent;border-left:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid transparent;border-right:28px solid red;border-top:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-left:28px solid red;'> </td></tr><tr><td style='border-right:28px solid red;border-top:28px solid red;border-bottom:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-left:28px solid red;'> </td></tr><tr><td style='border-right:28px solid red;border-top:28px solid red;border-bottom:28px solid red;border-left:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-right:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-left:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid red;border-top:28px solid red;border-left:28px solid red;border-right:28px solid red;'> </td></tr></table>",
"<table style='padding:5px 5px 5px 5px;' cellpadding=12><tr><td style='border-top:28px solid red;border-left:28px solid red;border-right:28px solid red;'> </td></tr><tr><td style='border-bottom:28px solid red;border-top:28px solid red;border-right:28px solid red;'> </td></tr></table>"
];
… and modified code that writes out the digital clock numerals …
function dc(chuh, subclass) {
var retval="";
if (subclass == 'hour' && chuh.length == 1) chuh='0' + chuh;
for (var iy=0; iy<chuh.length; iy++) {
if (document.URL.indexOf('dcviaborder=') != -1) {
retval+='<td>' + dcborder[eval('' + chuh.substring(iy, eval(1 + iy)))] + '</td>';
} else {
retval+='<td><h1 class="a' + chuh.substring(iy, eval(1 + iy)) + ' ' + subclass + '"></h1></td>';
}
}
return retval;
}
… and the HTML means by which the user can toggle between the two digital clock looks …
<h1 align='center'>Daylight Saving Time Information <a style='text-decoration:underline;cursor:pointer;' onclick=" if (document.URL.indexOf('dcviaborder=') != -1) { location.href=document.URL.replace('dcviaborder=','dcviaXborder='); } else { location.href=(document.URL + '&dcviaborder=y').replace('.html&','.html?'); }" title="Toggle look of Digital Clock">💞</a> RJM Programming - September, 2015</h1>
You can see this new digital clock look and contrast it to the old digital clock look with the changes we made to daylight_saving_time.html for your perusal.
Previous relevant Daylight Saving Time TimeZone Emoji Tutorial is shown below.
The last time we added a change to our Daylight Saving TimeZone Information web application was during our Other Side of the World Google Chart Tutorial work, and then, so many things were going on with interfacing and integration we didn’t really revisit the Daylight Saving TimeZone Information web application for itself, as it is so good to do every now and then to …
- incorporate new things you’ve learnt
- check on functionality that has fallen by the wayside (or, sin of all sins, never got to the wayside)
Our recent perusals around the “wooooooooorrrrllldd” of CSS3 reminded us of the power of CSS Selectors, especially the ones that came in with CSS3. The “two out of three” that we use today are described on today’s tutorial picture as well as we’d want to do here … so here goes …
Featuring
CSS3 Selectors for element attributes
^= (starts with)
*= (contains)
$= (ends with … not used)
Thanks to
When you try to memorize syntax do you look for “linkages”? Yes, you can find anything on the net. But seriously, this CSS syntax can be remembered because it uses the characters of a lot of RegEx wildcarding systems. Another kind of “linkage” we saw between this CSS(3) Selector functionality, and where it would be useful, was that we’d noted that TimeZone identifiers have a name, and generally they take a form …
Region/Placename
… and that Region (plus or minus the “/“) felt to us like a good candidate for functionality enhancement via the CSS(3) Selectors above. You can judge for yourself way below, or by clicking today’s tutorial picture.
Three other “popular” items around here, featuring, today, are …
- emojis (some of which were multiple and so we wish to rethank Iemoji (multiple HTML entity information) and FileFormat Information (normal HTML entity information) and Emojipedia (finding them) for these emoji lookups, as well as the CSS syntax help from this webpage (needed, because, unbelievable to us, we’d only ever done this with Javascript, in the past)), and their role to help internationalization of your web applications, and to add a bit of colour, and cuteness
- HTML element alt attribute when a data busy HTML select element option tag (the tag that we get most satisfaction from, making busy … it has to be said) is already using …
- title
- value
- text (or innerHTML)
… and you come along later not wanting to clobber any good logic looking for another “data place” to populate with your new “data item” (of interest) … well, that could be the “oft neglected except perhaps with the HTML img tag” alt attribute
- CSS selector :before
Apart from that alt logic above the changes we made to daylight_saving_time.html amounted to changes adding in new CSS(3) Selectors (that just happen … the joy of CSS, we guess) …
<style>
a[title*="Africa/"]:before { content: '\01f30d' }
a[title*="Europe/"]:before { content: '\01f4b6' }
a[title*="America/"]:before { content: '\01f30e' }
a[title*="Asia/"]:before { content: '\01f30f' }
a[title*="Australia/"]:before { content: '\01f1e6\01f1fa' }
a[title*="Indian/"]:before { content: '\01f1ee\01f1f3' }
a[title*="Pacific/"]:before { content: '\01f3dd' }
a[title*="Arctic/"]:before { content: '\01f1ec\01f1f1' }
a[title*="Antarctica/"]:before { content: '\01f1e6\01f1f6' }
a[title*="Atlantic/"]:before { content: '\01f30a' }
option[value*="Africa"]:before { content: '\01f30d' }
option[value*="Europe"]:before { content: '\01f4b6' }
option[value*="America"]:before { content: '\01f30e' }
option[value*="Asia"]:before { content: '\01f30f' }
option[value*="Australia"]:before { content: '\01f1e6\01f1fa' }
option[value*="Indian"]:before { content: '\01f1ee\01f1f3' }
option[value*="Pacific"]:before { content: '\01f3dd' }
option[value*="Arctic"]:before { content: '\01f1ec\01f1f1' }
option[value*="Antarctica"]:before { content: '\01f1e6\01f1f6' }
option[value*="Atlantic"]:before { content: '\01f30a' }
option[alt^="Africa/"]:before { content: '\01f30d' }
option[alt^="Europe/"]:before { content: '\01f4b6' }
option[alt^="America/"]:before { content: '\01f30e' }
option[alt^="Asia/"]:before { content: '\01f30f' }
option[alt^="Australia/"]:before { content: '\01f1e6\01f1fa' }
option[alt^="Indian/"]:before { content: '\01f1ee\01f1f3' }
option[alt^="Pacific/"]:before { content: '\01f3dd' }
option[alt^="Arctic/"]:before { content: '\01f1ec\01f1f1' }
option[alt^="Antarctica/"]:before { content: '\01f1e6\01f1f6' }
option[alt^="Atlantic/"]:before { content: '\01f30a' }
</style>
You can see these predominantly CSS styling changes for yourself at this live run link.
Previous relevant Other Side of the World Google Chart Tutorial is shown below.
Google Charts provides great chart tools for various purposes. We already use the Map Chart heavily with our “Other Side of the World” recent web application we last talked about below with Other Side of the World Continents and Countries Tutorial. This is no surprise given the geolocation and positioning and mapping aspects to the project. But also apt is the …
- Geo Chart which displays nominated countries and/or regions on a world map … and we also thought it would be good to call on a …
- Bar Chart can display Great Circle distances between places the user identifies during an execution of the “Other Side of the World” web application session
Over time you get a feeling for what Google Chart suits what scenario of data arrangements. Perhaps, here it would be instructional to read Google’s miscellaneous examples if you are wondering what is possible with this great software suite. We interface to many of these charts here at this blog and to read through these you could visit this link.
Today, as far as this “feel” goes, we’d like to admire how the Google Chart “way” of being housed in an HTML div element leads itself to scaling ready for smaller format devices, so long as you, the coder above, “play the game” so to speak, trying to specify percentage values for HTML element width properties where possible. This came to play with today’s Google Chart Bar Chart “fitting in” with right column table cell (td) widths with today’s “Other Side of the World” web application.
These two code files were involved in these changes …
- other_side_of_the_world.htm (changed in this way) … and you can try a live run or Seattle live run
- tz_places.php (changed this way)
As per usual, we encourage you to try the web application, and compare the goings on with code, and a good web inspector tool.
Previous relevant Other Side of the World Continents and Countries Tutorial is shown below.
Today, as with WordPress 4.1.1’s Other Side of the World Continents and Countries Tutorial, we came across a scenario where there was a tiny advantage being Australian, in that our “Continent Name” equals our “Country Name” … which I suppose you could argue for Antarctica, maybe?!
We were amused by this at school, and now have the first real world “application” of this in that today’s task, much harder than we thought it would be, was, with our “Other Side of the World” web application (we last talked about with Other Side of the World Timezone Tutorial as shown below) to link the two bigger data sets up the top of the list of three datasets going on with our application …
- Weather Underground database via its API … thanks
- PHP TimeZone functionality … why thank you, kind Open Sourcers (and the plates as well)
- the useful webpage … thank you again
The Weather Underground tends to talk about Placenames and their Country Names whereas the PHP TimeZones tend to link Placenames with Continent (or region) Names … and the missing link between these two talking to each other a good percentage of the time involves the PHP’s getLocation() functionality we’ve talked about before as a method for the DateTimeZone class, along with some 2 character ISO Country code information you can read more about at //stackoverflow.com/questions/17842003/php-intl-country-code-2-chars-to-country-name.
Making this link has lots of benefits …
- our “closest to” lists now have more data to call on (supplementing the last of those datasets above) … and …
- we can now allow for searches by Country on that top HTML select (dropdown) element …
- we can fill in more specified places now that we can add in a Country so often and often reach a point with the Weather Underground scrutiny where there is only one returned value, at which point, some days ago, we added logic to say just go and display this on the Map Chart and the rest straight away to save some time
- people tend to think of a Country when they think of a place, at least on dry land, that is.
An unusual code threesome were involved in these changes …
- other_side_of_the_world.htm (changed in this way) … and you can try a live run or Johannesburg live run
- daylight_saving_time.html (changed this way)
- tz_places.php (changed this way)
… that last one getting a new calling method just for this purpose of …
- take a placename
- take its inputted Continent (or region) Name … and …
- have the supervisory codes send to tz_places.php a $_GET[] call for the purpose of …
- using getLocation() functionality find a 2 character ISO Country Code … and …
- link this to a full Country Name via various arrays we have in the PHP … and finish off by …
- sign off the PHP (in an HTML iframe element) by changing relevant fields in top.document or parent.document DOM HTML elements via a simple HTML body onload event method of making those changes and exiting the called PHP … allowing for …
- supervisors pick up their usual logic flows once we have a Placename,CountryName textbox scenario going
Of course “Australia” the continent name being the same as “Australia” the country name saves so much time I’ll think I’ll have that cup of coffee now. See ya!
Previous relevant Other Side of the World Timezone Tutorial is shown below.
We’ve got a lot of “where” functionality mixed in with “when” functionality with our “Other Side of the World” web application. To us, the easiest way to link “where” and “when” in the world is the concept of Earth’s timezones. We spent a lot of time looking into this with the blog thread ending with TimeZone Country Places Data Tutorial and then it went through another makeover when we tackled its integration into the Weather Underground API inspired blog postings culminating in Weather API via Iframe jQuery Ajax AutoComplete Tutorial
Reading down that first blog posting thread to its “Primer Tutorial” …
Into the mix of the logic here, we need to venture into the world of two letter ISO Country Codes, and we work this with help from //php.net/manual/en/datetimezone.getlocation.php and //stackoverflow.com/questions/17842003/php-intl-country-code-2-chars-to-country-name and //php.net/manual/en/function.timezone-identifiers-list.php and //www.timezoneconverter.com/ to “hardcode” our HTML select “dropdown” elements we create in the process, and offer TimeZone information HTML select “dropdown” elements as well.
… you can see how good PHP is, natively, with timezones, and how approachable all this is for all PHP programmers … exciting stuff!
And there’s another series of blog postings culminating in HTML/PHP Timezone Feed Function Keys Tutorial involved in this same realm of thinking, that we use today (as with WordPress 4.1.1’s Other Side of the World Timezone Tutorial), along with the … you guessed it … Client Pre-emptive Iframe technique approaches to making use of what it helps with. Integrating “what it helps with” is quite interesting, and quite “Ajax”y in its ways. We call its supervisory web application into a new HTML iframe element of our “Other Side of the World” web application and pluck out only its initial “Digital Clock” HTML table display, and transfer that HTML table and its modified CSS styling over into a new HTML div element within the “Other Side of the World” web application, initially style “display:none;” but capable of being called into play via the user selecting an “Hour Time of the Day” value of interest, that causes the iframed daylight_saving_time.html (changed this way).
What the user sees/does to use this new functionality looks like …
- they see the “Hour of the Day” dropdown
- they select an “Hour of the Day” value of interest … in today’s tutorial picture, here in AEST Australia (around about 8pm) we chose “07am”
- the “Digital Clock” flashes random current times of day from around the “TimeZone Places World” and when it lobs onto the first matching time between 07am and 08am (exclusive) …
- that matching “TimeZone Place” is copied into the “Other Side of the World” Place textbox … and …
- the “Weather Underground” (autocomplete) database is scrutinized for a match, and if so …
- the Map Chart shows the matched place as the base position along with its “Other Side of the World” counterpart, allowing for Google Chart click/touch (its “select”) event logic to allow for other functionalities that include a Weather link and TimeZone information (with a current time of day) … along with the …
- usual “packdrill” for TimeZone Places iframe table cell and YouTube API Embedded iframe table cell in the (now) bottom row of the “Other Side of the World” (big) table element
The code for these TimeZone integration changes, building on yesterday’s Other Side of the World Map Chart Styling Tutorial, remains as just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.htm (changed in this minor way for our HTML supervisor of additional TimeZone functionalities today) if you like, or want to try out (or try out for a specific (argument) location, such as Tokyo try out), again. The Client Pre-emptive Iframe reading and use of PHP continues today, making great use of its TimeZone code talents.
Previous relevant Other Side of the World Map Chart Styling Tutorial is shown below.
You’ll have noticed with our “Other Side of the World” web application of recent days … or maybe not, if you were dozing off … how much use we make of the Google Charts Map Chart functionality. Can’t do without it … thanks, Google.
Now if you go to read about the Google Chart Map Chart you may end up at this very interesting webpage, and even if it was some time back you were last there, it is always worth checking back in every now and then for information on changes, or to reread this functionality rich software suite documentation. We only touch the “tip of the iceberg” with the way we interface to Google Charts, but today we want to take some small steps to improving on that. Even taking small steps, when dealing with a third-party product so rich in possibilities, we try to be generic and be able to offer more to those adventurous users out there, both laptop and mobile (at least iPad only at this stage) users.
So we have set up a way for iPad users using the mobile app to be able to save their comma prefixed …
- localized Google Chart Map Chart styling ideas from here when they interactively enter Map Chart criteria … and for …
- all users of our “Other Side of the World” web application get an additional non-default Google Chart Map Chart “Styled Map” tab (in addition to their default “Map” and “Satellite” tabs), and some non-default Google Chart Map Chart icons … thanks to Icons-Land here
The new icons for that latter scenario also feature a different icon showing after a “pin” icon is selected (ie. the Google Chart click/touch “select” event is called into play).
The code for these Map Chart changes remains as just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.htm (changed in this minor way for our HTML supervisor of Google Chart Map Chart purposes today) if you like, or want to try out (or try out for a specific (argument) location, such as Beijing try out), again. The major changes related to in the Google Chart Map Chart web application PHP you could call map.php, and which changed in this way, starting down our long path towards more Map Chart styling possibilities.
Previous relevant Other Side of the World Iframe Tutorial is shown below.
Our “Other Side of the World” web application we’ve been developing lately has made extensive use of the HTML iframe element, mainly as a “reader” of data in that Client Pre-emptive Iframe technique way. But the HTML iframe element is probably better known for its data integration and display talents, and it is these that we call upon today, to (software) integrate two other existing sources of data so that, display-wise we have four table (td) cells in play now those being the original …
- top left cell where the user interacts to show latitude and longitudes and placenames of interest
- top right cell showing these “latitude and longitudes and placenames of interest” paired with their “Other Side of the World” counterparts within a Google Charts Map Chart (software) integration … and, as of today we add into the equation …
- bottom left cell where depending on whether we’ve derived our “latitude and longitudes and placenames of interest” from …
- the Weather Underground HTML select (dropdown) element results in an HTML iframe element hosting a Weather API via Iframe jQuery Ajax Autocomplete Tutorial‘s TimeZone Places dataset … or …
- the useful webpage (thanks) HTML select (dropdown) element results in an HTML iframe element hosting a YouTube Embedded Video in Iframe API RegEx Tutorial ‘s YouTube (embedded) video integrator
- bottom right cell where the user’s “latitude and longitudes and placenames of interest”‘s “Other Side of the World” interfaces to the useful webpage (thanks) HTML select (dropdown) element results in an HTML iframe element hosting a YouTube Embedded Video in Iframe API RegEx Tutorial ‘s YouTube (embedded) video integrator
We now think the use of all this can have you hopping around the world discovering lots of geographical based, video based and timezone based information about lots of places around the world, lots of which you may never have known much about.
We’ve software integrated today, as well as integrated “where” web application thoughts with “when” web application thoughts.
Another feature of today’s changes involves the geolocation features of the Javascript …
navigator.geolocation.getCurrentPosition(success[, error[, options]])
… syntax method of allowing Location Services, if allowed by the user, return a latitude and longitude position of the user themselves, information used at the instigation of the web application, and which we also used with HTML/Javascript Where Does It Get Me To Primer Tutorial and Google Chart Map Chart Select Event Primer Tutorial in the past.
The code for this remains as just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.htm (changed in this way for our HTML iframe (software) integration purposes today) if you like, or want to try out (or try out for a specific (argument) location, such as Alice Springs try out), again. It also required small changes to …
- HTML of the YouTube embedded iframe video integrator’s supervisory karaoke_youtube_api.htm changed in this way and with this live run link
We hope you try it out and discover some new things!
Previous relevant Other Side of the World Onblur Tutorial is shown below.
The onblur event in web programming is a very important event regarding interactive keyboard entries made by the user. We base new functionality, today, with our “Other Side of the World” web application, by allowing a user who enters in their own “place” information, can have that information filtered through the same “autocomplete” database provided by the wonderful Weather Underground and its great API service.
When we presented the last Weather Underground related blog posting we even used this functionality also interfacing to the onkeyup keyboard event, making it look up the database after just a few characters typed into the associated HTML input type=text text box, but today we lessen the interaction, presuming the user knows a location of interest and will only want information after tabbing out of this text box … hence the onblur event, only, logic interface to new functionality that creates an additional HTML select (dropdown) element of use to populate those same …
- placename
- country … linked to …
- latitude
- longitude
… fields as talked about yesterday when we presented Other Side of the World Places Tutorial as shown below.
So that’s the idea, but making it happen involved some tweaking of the parts to the Weather Underground blog posting Weather API via Iframe jQuery Ajax AutoComplete Tutorial from some time back, the changes for which we’ll explain later.
Again we call on Client Pre-emptive Iframe techniques for this, telling us that you can just keep on adding HTML iframe elements to make this technique happen for several different sources of information, as necessary.
The code for this is just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.htm (changed in this way for our onblur event purposes today) if you like, or want to try out (or try out for a specific (argument) location, such as Darwin try out), again. It also required small changes to …
- HTML of the “parent” you could call autocomplete.htm changed in this way and with this live run link (or specific place argument calls like the one here for live run for Darwin link) … and its …
- PHP autocomplete jQuery Ajax engined helper you could call using_key.php and tweaked in this way
Previous relevant Other Side of the World Places Tutorial is shown below.
A fair while ago now we were in the midst of writing a Geographicals Suite of web applications that, given Latitude and Longitude pairs you could calculate things like …
- Sun Angle at noon
- Moon Angle at noon
- Coriolis Effect
- Distance between Geographical Locations
- Weather at Geographical Location
… and that we eventually added some “placename” capabilities to all this, introduced with PHP/Javascript/HTML Sun Angle Tutorial, which harnessed all this useful goodwill of this useful webpage (thanks) publishing some placename geographicals data.
- placename
- country … linked to …
- latitude
- longitude
… and that we “channel” today, via our beloved Client Pre-emptive Iframe techniques, so that we reuse PHP, rather than having to create new PHP, as an aid to the modularization for added “placename” functionality to our “Other Side of the World” web application we started presenting yesterday with Other Side of the World Primer Tutorial as shown below.
Another thing we are trialling today is a concept (that admittedly seems to need more work in Firefox) of an HTML select (dropdown) element having an onclick event (after an onchange event that changes that select element value to a non-nothing value) having a logic whereby that select element value is used to repopulate the …
- placename (, country) (Great Circle Distance in km away)
- latitude
- longitude
… HTML input type=text and type=number fields automatically. In the normal case of events in non-Firefox web browsers an onchange event change of value to a non-nothing value just causes that select element value to be one of the places shown on the Google Charts Map Chart that we display.
The default is to show five of the nearest placenames in the derived list, but a “+” button can increase that number of “nearest”s as required.
The code for this is just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.htm (changed in this way for our purposes today) if you like, or want to try out, again perhaps?
Previous relevant Other Side of the World Primer Tutorial is shown below.
Today we’ve written a first draft of an “Other Side of the World” web application using a Google Chart Map Chart embedded into an HTML iframe element to show the user …
- the position of the place that they enter in for their latitude and longitude … as well as …
- “the other side of the world” to the position of the place that they enter in for their latitude and longitude, calculated by imagining you take a trip from your original location through the middle of the Earth and straight through onto the other location
Is this our “sister” location? Am not sure. But somebody was telling “Porkies” to me as a child where we were told “China” as being on the other side.
The code for this is just HTML (apart from the supervised PHP for the Google Chart interface) that you could call other_side_of_the_world.html if you like, or want to try out.
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.
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.