Walking Trip …

Walking Trip

Walking Trip

Offenbach's Suite ... Warts 'n All

Offenbach's Suite ... Warts 'n All

 📅  

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

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

Colouring In Drag and Drop Undo and Redo Tutorial

Colouring In Drag and Drop Undo and Redo Tutorial

Colouring In Drag and Drop Undo and Redo Tutorial

We all make mistakes. Especially with any colouring in of a Clip Art background image, which might be happening for users of our Colouring In web application we last talked about with yesterday’s Colouring In Drag and Drop Background Image Tutorial.

So we’ve decided to help out via …

  • provide Undo and Redo button …

    var cursnap=0, snapshs=[''], cich=null, woca=null, lastundo='';

    function undosnapshot() {
    if (snapshs[0] != '') {
    //alert('cursnap=' + cursnap + ' and jsundo att=' + document.getElementById('jsundo').getAttribute('data-ssn') + ' and length=' + snapshs[eval('' + document.getElementById('jsundo').getAttribute('data-ssn'))].length);
    lastundo=document.getElementById('mytable').innerHTML;
    document.getElementById('mytable').innerHTML=snapshs[eval('' + document.getElementById('jsundo').getAttribute('data-ssn'))];
    if (eval('' + document.getElementById('jsundo').getAttribute('data-ssn')) > 0) {
    document.getElementById('jsredo').setAttribute('data-ssn', '' + eval(0 + eval('' + document.getElementById('jsundo').getAttribute('data-ssn'))));
    document.getElementById('jsundo').setAttribute('data-ssn', '' + eval(-1 + eval('' + document.getElementById('jsundo').getAttribute('data-ssn'))));
    }
    }
    }

    function redosnapshot() {
    if (snapshs[0] != '') {
    //alert('Cursnap=' + cursnap + ' and jsredo att=' + document.getElementById('jsredo').getAttribute('data-ssn') + ' and length=' + snapshs[eval('' + document.getElementById('jsredo').getAttribute('data-ssn'))].length);
    if (lastundo != '') {
    document.getElementById('mytable').innerHTML=lastundo;
    lastundo='';
    } else {
    document.getElementById('mytable').innerHTML=snapshs[eval('' + document.getElementById('jsredo').getAttribute('data-ssn'))];
    }
    }
    }

    function updatesnaps() {
    if (document.getElementById('mytable').innerHTML != snapshs[cursnap]) {
    if (eval('' + snapshs.length) < 5) {
    lastundo='';
    cursnap++;
    snapshs.push(document.getElementById('mytable').innerHTML);
    document.getElementById('jsundo').setAttribute('data-ssn', '' + eval(-1 + cursnap));
    document.getElementById('jsredo').setAttribute('data-ssn', '' + cursnap);
    } else {
    lastundo='';
    cursnap=4;
    snapshs[1]=snapshs[2];
    snapshs[2]=snapshs[3];
    snapshs[3]=snapshs[4];
    snapshs[4]=document.getElementById('mytable').innerHTML;
    document.getElementById('jsundo').setAttribute('data-ssn', '' + eval(-1 + cursnap));
    document.getElementById('jsredo').setAttribute('data-ssn', '' + cursnap);
    }
    }
    setTimeout(updatesnaps, 15000);
    }

    … functionality … and …
  • a click in the pink area allows a Google clip art image search webpage be displayed … and these …
  • being right clicked might show a Copy Image Address option which copies into the clipboard …
  • data suitable for pasting into the Image URL textbox we introduced yesterday

… whether that be an image data URL or perhaps even an absolute image URL, to use as the “canvas” (ie. palette) background image. In this scenario, if the default 99 (pixels across and down) is still happening we open a new window with an incarnation of the webpage for that setting being 200 (pixels across and down).

Codewise …

… helped with these improvements.


Previous relevant Colouring In Drag and Drop Background Image Tutorial is shown below.

Colouring In Drag and Drop Background Image Tutorial

Colouring In Drag and Drop Background Image Tutorial

So far it might have been hard for some users to visualize “colouring in” a blank canvas. As such, today, onto yesterday’s Colouring In Drag and Drop Mobile Tutorial we’re now offering …

  • ability to define a tabular background image via a browsed for image … or …
  • ability to define a tabular background image via a user defined image URL

… and add a new “opacity” setting …


function torgba(inc, opa) {
var i, j=0, csess="rgba(:::1.0)", alp="0123456789abcdef", factor=16;
for (i=0; i<=inc.replace('#','').length; i++) {
if (i == 1) {
csess=csess.replace('rgba(:','rgba(' + (j + alp.toLowerCase().indexOf(inc.toLowerCase().replace('#','').substring(i,(i + 1)))) + ':');
j=0;
} else if (i == 3) {
csess=csess.replace('::',':' + (j + alp.toLowerCase().indexOf(inc.toLowerCase().replace('#','').substring(i,(i + 1)))) + ':');
j=0;
} else if (i == 5) {
csess=csess.replace('::',':' + (j + alp.toLowerCase().indexOf(inc.toLowerCase().replace('#','').substring(i,(i + 1)))) + ':');
j=0;
} else {
j=j + (factor * alp.toLowerCase().indexOf(inc.toLowerCase().replace('#','').substring(i,(i + 1))));
}
csess = csess.replace(":1.0)",":" + opa + ")");
}
return csess.replace(/\:/g,',');
}

function opit(ijval) {
if (document.getElementById('opmeter')) {
if (eval(1.00 - document.getElementById('opmeter').value) != 0.00) {
return torgba(ijval, document.getElementById('opmeter').value);
}
}
return ijval;
}

… all of which we can envisage could have users, at the very least, using this “Colouring In” web application for …

  • a scribbling or doodling mechanism (on a blank canvas)
  • colouring in via a background image with clip art linework, perhaps …
  • create a postcard (type of creation) via a background image, perhaps browsed for (or using the Take Photo or Video option for mobile) on your device, and overlay some scribbled (or doodled) wording

Codewise …

… helped with these mobile platform tweaks. We thank https://i.pinimg.com/736x/86/98/2d/86982d9ee1582bb7a4e730f11ebed3f4.jpg for the background image used (and fed into that image URL textbox to make happen) in today’s tutorial animated GIF presentation.


Previous relevant Colouring In Drag and Drop Mobile Tutorial is shown below.

Colouring In Drag and Drop Mobile Tutorial

Colouring In Drag and Drop Mobile Tutorial

Yesterday’s Colouring In Drag and Drop Sharing Tutorial sharing and collaboration code for our latest Colouring In web application was tested on our MacBook Air laptop only. As you can imagine, that can mean that code working there is not always going to work the same way on mobile touch devices, but it was not, as it panned out for us, regarding the reason we thought it would be about. We thought …

  • it’s bound to be an issue with dragging event workings regarding mobile … but it took us quite some time to stop burying our head in the sand and, instead, “keeping it simple, Señor” (ie. the KISS principle, and yes, Señor is not a spelling mistake, thank you very much for your concern) … and testing another “dumber sounding” but panning out to be true, in this case …
  • issue was to do with table cell widths and heights for table cells with no content acts differently for mobile than non-mobile (effectively scrunching cells up)

… the trigger for us being that the “drop” event.target.id kept on showing up as “mytable”. That happened hours ago! We beavered away with x,y proportional co-ordinate calculations and eventually after all that not helping (for 2 maybe 3 hours), started applying a table cell border, which gave crazy results, and then it tweaked?! Sheeeeesssshhhhh!

Can you teach yourself the KISS principle? Maybe you get better over time. Another opinion can be great, though, with that alternative view, you hadn’t even thought of, often the result of such conversations.

Back to today, we …

Made sure table “tr” row elements were for a better defined (proportionate to table) width
<?php

for ($thisrow=1; $thisrow<=$across; $thisrow++) {
$cthisrow='0000000000' . $thisrow;
$rowsofar='<tr style="width:100%;" id=tr' . substr($cthisrow, -$iacross, $iacross) . '></tr>';
$thistdid='td' . substr($cthisrow, -$iacross, $iacross) . '_';
for ($thiscol=1; $thiscol<=$across; $thiscol++) {
$cthiscol='0000000000' . $thiscol;
$thistdidsuffix='' . substr($cthiscol, -$iacross, $iacross) . '';
$rowsofar=str_replace('></tr>', '><td class="tdone" id=' . $thistdid . $thistdidsuffix . ' style=text-align:center; data-answer=' . $ttcnt . '></td></tr>', $rowsofar);
}
$newih=str_replace('</tbody>', $rowsofar . '</tbody>', $newih);
}

?>
Made sure table “td” cell elements were proportional … initially, expressed in “viewport” (percentage style) dimension terms …
<style>

td.tdone {
width: 1vw;
height: 1vh;
}

</style>
… and if not the default number of cells across and down …

function overdover() {
if (document.getElementById('dragoverdelay') && document.getElementById('dragovercountdown')) {
if (document.getElementById('numacross')) {
if (('' + document.getElementById('numacross').value) != '99') {
document.getElementById('dstyle').innerHTML+='<st' + 'yle> td { width: ' + eval(eval('' + document.getElementById('numacross').value) /100) + 'vw; height: ' + eval(eval('' + document.getElementById('numacross').value) /100) + 'vh; } </st' + 'yle>';
}
}

if (Math.abs(doverd) != eval('' + document.getElementById('dragoverdelay').value)) { doverd=eval('' + document.getElementById('dragoverdelay').value); }
if (doverc == 0 && eval('' + document.getElementById('dragovercountdown').value) == 0) { doverc=doverd; document.getElementById('dragovercountdown').value='' + doverc; document.getElementById('dragovercountdown').style.display='inline-block'; }
}
}

Codewise …

… helped with these mobile platform tweaks.


Previous relevant Colouring In Drag and Drop Sharing Tutorial is shown below.

Colouring In Drag and Drop Sharing Tutorial

Colouring In Drag and Drop Sharing Tutorial

We’re hoping yesterday’s Colouring In Drag and Drop Settings Tutorial new Colouring In web application is seen as a creative’s tool. As such, you’re going to want to share and collaborate … some of you, that is?!

You’re going to want to hashtag … oops … we’re going to want to hashtag. Yes, there is lots of data to share, but it worries us even involving hashtagging, how much there is, underlying, regarding that table element acting a bit like a television’s pixels. How do you effectively share even a snapshot of that?

But the difference between us and the television is, at least for a lot of people’s creations, the table is likely to be untouched, so can’t we “nickname” these repeated table cell scenarios? If you just said “indeed”, we’d concur! Take a look at some global Javascript variables we thought might help


var defemail='';
var defsms='', snum=null, sparewes=null;
var prefixnickchar='.';
var prefixfor='<td class="tdone" id="';
var suffixnickchar='-';
var suffixfor='" class="tdone" style="text-align:center;" data-answer="1"></td>';

… and for those untouched cells you’re saving more than (because of encryption) the length difference between the “nickchars” above and their “fixfor” counterparts for each “boring” table cell encountered. And all this eases our mind somewhat, as a design, realized, on the way to the emailee or smsee this way


function doemail(inidea) {
var bihbig='';
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 (inidea.indexOf('@') == -1) {
inidea=('' + prompt('Please enter Email address to send to.', defemail));
if (inidea == null) { inidea=''; }
}
if (inidea.indexOf('@') == -1) { return ''; }

bihbig=document.body.innerHTML;
while (bihbig.indexOf(suffixfor) != -1) {
bihbig=bihbig.replace(suffixfor, suffixnickchar);
}
while (bihbig.indexOf(prefixfor + 'td') != -1) {
bihbig=bihbig.replace(prefixfor + 'td', prefixnickchar + 'td');
}

//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('h1')[0].innerText.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
//} else {
if (sparewes) {
azx.href = 'mailto:' + inidea + '?subject=' + encodeURIComponent(sparewes.document.getElementsByTagName('h1')[0].innerText.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //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.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
}
//}
azx.click();
return '';
}

function dosms() {
var bihbig='';
if (('' + window.localStorage.getItem('colouringincollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defemail=window.localStorage.getItem('colouringincollaboratoremailee');
}
if (('' + window.localStorage.getItem('colouringincollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defsms=window.localStorage.removeItem('colouringincollaboratorsmsno');
}
if (eval('' + ('sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#cibih=' + 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('colouringincollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('colouringincollaboratoremailee');
}
window.localStorage.setItem('colouringincollaboratoremailee', 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('colouringincollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('colouringincollaboratorsmsno');
}
window.localStorage.setItem('colouringincollaboratorsmsno', snum);
defsms=snum;
}

bihbig=document.body.innerHTML;
while (bihbig.indexOf(suffixfor) != -1) {
bihbig=bihbig.replace(suffixfor, suffixnickchar);
}
while (bihbig.indexOf(prefixfor + 'td') != -1) {
bihbig=bihbig.replace(prefixfor + 'td', prefixnickchar + 'td');
}

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.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig)));
azx.click();
}
return '';
}

… and when arriving back from an emailee’s or smsee’s link click …


function cibihcheck() {
var partslh=('' + location.hash).split('#ci' + 'bih=');
if (eval('' + partslh.length) > 1) {
var bihbig=decodeURIComponent(decodeURIComponent(partslh[1]));

bihbig=bihbig.replace(/\.td/g, prefixfor + 'td');
bihbig=bihbig.replace(/0\-/g, '0' + suffixfor);
bihbig=bihbig.replace(/1\-/g, '1' + suffixfor);
bihbig=bihbig.replace(/2\-/g, '2' + suffixfor);
bihbig=bihbig.replace(/3\-/g, '3' + suffixfor);
bihbig=bihbig.replace(/4\-/g, '4' + suffixfor);
bihbig=bihbig.replace(/5\-/g, '5' + suffixfor);
bihbig=bihbig.replace(/6\-/g, '6' + suffixfor);
bihbig=bihbig.replace(/7\-/g, '7' + suffixfor);
bihbig=bihbig.replace(/8\-/g, '8' + suffixfor);
bihbig=bihbig.replace(/9\-/g, '9' + suffixfor);

document.body.innerHTML=bihbig;
}
}

Codewise …

… helped with this sense of collaboration.


Previous relevant Colouring In Drag and Drop Settings Tutorial is shown below.

Colouring In Drag and Drop Settings Tutorial

Colouring In Drag and Drop Settings Tutorial

Onto the start for our Colouring In web application via yesterday’s Colouring In Canvas Clone of Numbers Guessing Game Tutorial we’re starting to enhance, on top of that “clone level” functionality, via two new settings with two approaches to the management of data, regarding, those being …

  • number of table cells across (that programmatically is made to be the same number of cells, as down) … we deal with via a get ? (or &) address line URL arrangement … whereas …
  • pen “width” can be 1 or 2 (where 2 colours in the 1+8=9 surrounding cells of a dragged over cell) … we deal with via a hashtag arrangement

Why the difference in approach? Let’s start with hashtag methodologies. This arrangement can leave everything about a webpage, in place, regarding the user actions on a webpage, while the Javascript can detect that change in …


location.hash

… dynamically. In other words some dragging canvas drawings with pen “width” 2 can be combined with some using pen “width” 1 in the same user creation.

But when the data management involves get ? (or &) address line URL arrangements, this involves navigation to a new incarnation of the webpage creation logic, effectively wiping the webpage slate clean. This is apt for the “number of table cells across” data item, because the HTML content of the table element is not just affected, but is totally structured, according to this user setting.

Lately, more and more, we’ve been hashtagging data to dynamically created “a” link “mailto:” email or “sms:” SMS communication body webpage URL links. An email link or SMS link, from the recipient’s point of view is a “brand new start” that can address either or both of these data conduit arrangements, we’re getting happier and happier to discover …


// ondragover event function code snippet below ...
ev.target.style.backgroundColor='' + document.getElementById('ddcolour').value;
if (decodeURIComponent(('' + location.hash)).indexOf('fontweight=') != -1) {
ifontweight=eval('' + ('' + decodeURIComponent(('' + location.hash))).split('fontweight=')[1].substring(0,1));
}
else if (document.getElementById('numfontweight')) {
ifontweight=eval('' + document.getElementById('numfontweight').value);
}
if (ifontweight == 2) { // colour in 8 surrounding cells, as applicable
var minusthree=-3;
if (document.getElementById('numacross')) {
minusthree=eval(-1 * eval('' + document.getElementById('numacross').value.length));
}
var tdx=eval(('' + ev.target.id).substring(2).split('_')[0].replace(/^0/g,'').replace(/^0/g,''));
var tdy=eval(('' + ev.target.id).split('_')[1].replace(/^0/g,'').replace(/^0/g,''));
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}

if (document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}

if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
}

Codewise …

Did you know?

Our recent Earth Scanner project was conducted during our “Hashtagging Enlightenment Period”, whereby, around here, the …

What the Hep?

… greeting, is code for “Have yourself a happy and fruitful hashtagging day” … but we digress. In amongst it’s code there was an example codeline …


var nontz=('' + location.search + ('' + location.hash).replace(/^\#/g,'')).split('nontz=')[1] ? decodeURIComponent(('' + location.search + ('' + location.hash).replace(/^\#/g,'')).split('nontz=')[1].split('&')[0].split('#')[0]) : '';

… exemplifying, how more and more, we’re happy with setting (or other types of incoming) data coming from get (? and & ( eg. ?nontz=Alice_Springs%7C133.8807%7C_23.6980%7C )) arguments via location.search and/or hashtagged data coming from location.hash ( eg. #nontz=Alice_Springs%7C133.8807%7C_23.6980%7C ) above, either or both, perhaps, used in an email or SMS body URL link.


Previous relevant Colouring In Canvas Clone of Numbers Guessing Game Tutorial is shown below.

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

As the blog posting title suggests, cloned from yesterday’s Numbers Guessing Game Dragover Tutorial

  • Numbers Guessing Game dragover “value add” proof of concept work … comes …
  • Colouring In Canvas drag and (faux) drop web application

… where a “canvas” palette (which is really an HTML table element made up of lots of table cells, rather than an HTML5 canvas element). Why this design? Well, each table cell element can be identified as an individual “dragged over” element. “Dragged over” by what? Well, we turn some “draggable” wording in the basis HTML into …

  • an emoji pen 🖌 piece of text … and next to that we add …
  • an input type=color Colour Picker to choose a pen colour … and because the “ondragover” event is so sensitive, we also add an optionally used, or not …
  • input type=number defining any delay (in seconds) before the “ondragover” colouring in kicks in, from when it could first of happened, as the pen crosses over into the palette … along with …
  • input type=number countdown of the delay
  • … so that the user can use “dragover” event means by which to create their own “colouring in creation”!

    Codewise …


    Previous relevant Numbers Guessing Game Dragover Tutorial is shown below.

    Numbers Guessing Game Dragover Tutorial

    Numbers Guessing Game Dragover Tutorial

    Today we’re honing in on …

    • drag and drop methodology …
    • dragover event … value adding where …
    • drop element(s) are cells of an HTML table element (also a drop element)

    … as our interest. We scouted around for the best “design match” and came up with the arrangements existing when we presented Numbers Guessing Game Tutorial some time ago now.

    And if we succeed with some form of value adding here, we have another idea for the ideas we’re presenting today. Spoiler alert! Yes, it can be made to be useful.

    As such we’ve …

    Added toggleable “show where contemplated” value added border where dragover logic
    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');
    if (isset($_GET['notice'])) {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a></span>', $templategame);
    } else {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a></span>', $templategame);
    }


    ?>
    Tweaked dragover logic

    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    if (ev.target.outerHTML.indexOf('<table') != 0 && ev.target.outerHTML.indexOf(' data-piece="') != -1) {
    if (ev.target.outerHTML.split(' data-piece="')[1].substring(0,1) == (itisthiscmove + ev.target.outerHTML.split(' data-piece="')[1].substring(0,1)).substring(0,1)) {
    lohfulloh=ev.target.outerHTML;
    console.log("LOHfulloh=" + lohfulloh);
    }
    }
    //console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    //if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    // document.title='ev.preventDefault(); //4';
    //}
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (document.getElementById('sdropz')) {
    if (document.getElementById('sdropz').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('sdropz').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('sdropz').innerHTML=document.getElementById('sdropz').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { ev.target.style.border='2px dashed yellow'; }
    }
    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';.id)
    });
    Flag any continued “show where contemplated” interest

    var secsmore='';
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { secsmore='&notice=y'; }

    if (document.URL.indexOf('rjmprogramming-com-au.translate.goog') != -1) {
    location.href=document.URL.split('&score=')[0] + '&score=' + score + '&secs=' + secs + secsmore;
    } else {
    location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs + secsmore;
    }

    … to, as the user requests, add some table cell border enhancements (as our “value adding“) to our tweaked third draft PHP game (helped out by the changed experimental_drag_and_drop.htm Experimental Drag and Drop clientside HTML and Javascript basis), as the user drags the draggable element over the table droppable element and its cohort table cell elements.


    Previous relevant Numbers Guessing Game Tutorial is shown below.

    Numbers Guessing Game Tutorial

    Numbers Guessing Game Tutorial

    We’ve been working on aspects to the genericity of the table that is …

    The Drop Zone

    … do do … do do … do do … do do … do do do do do do do do do do do do … yesterday’s threat “now so yesterday” being …

    • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
    • allow the number of cells across in a column not be 3

    … in a (very difficult) Numbers Guessing game for numbers from 1 to 99 that regular readers may be familiar with as the (same content (and mentioned at this link … thanks …) as the) Numbers Guessing game at this blog, but presented using a Drag and Drop modus operandi.

    Feel free to try our first draft PHP game, which leans on a changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    On your smaller devices we found the Numbers Guessing Game a bit hard to use. As such, we researched and played around with “drag and drop” cursor ideas unsuccessfully to end up, instead, not thinking about the cursor (albeit, we find that idea cuter) but rather styling the target table cell’s background colour and informing the user of that up at the top button wording in our changed second draft PHP game, which leans on our changed experimental_drag_and_drop.htm HTML and Javascript and CSS helper


    var lastbco=null;

    const target = document.querySelector("#target");
    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    }

    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';

    });


    Previous relevant Planet Moon Game Tutorial is shown below.

    Planet Moon Game Tutorial

    Planet Moon Game Tutorial

    Another thing that there is nine of (as contentious as it is regarding Pluto) is Planets in the Solar System, revolving around the Sun. And so, in keeping with a lot of the same design as yesterday’s Enneagram Type Game Tutorial we have a Planet Moon Game to present for you to play around with today.

    Again, PHP uses a framework of Experimental Drag and Drop HTML and Javascript and CSS, mainly via one PHP codeline …

    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');

    ?>

    … and, perhaps, your curiosity that we have not “passed” data via $_GET[] or $_POST[] arguments, but rather just the simple act of …

    • moulding and manipulating (eg. arranging “callback” logic means, as used below) that $templategame “template” for our purposes … nga ha ha ha ha ha ha ha ha … but we digress …
    • simply …
      <?php

      echo $templategame;

      ?>
      … outputs a webpage …
    • and on the way back to play again, we use $_GET[‘score’] and $_GET[‘secs’] (in experimental_drag_and_drop.html HTML and Javascript and CSS game web application) to keep the ball rolling back to the game specific PHP we use …

      location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;

    … in our first draft PHP game, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    We fully concur with any adage that goes …

    You learn most from your mistakes

    … just as we’re curious about “the things that go wrong”, and not having them repeat! Same with pooches!

    Take our first to second draft PHP game (to the opera, would be preferable). We wondered why, occasionally, with the “first draft” it would hang. It took us a half day to realize, as you could yourself have tweaked to a lot quicker if you had followed the adage …


    Hanging issues mostly team up with code within a loop

    The situation, we’ve reasoned, is that we had that PHP $badlist variable store a comma separated list of planets with either zero moons or more than one moon randomly selected representing it. We’d assumed, yesterday, not that we’d put it in words, but in logic, that this list would not (have the same length or) be the same as a (new $goodlist variable) list of planets with either zero moons or selected while collecting the random list of Moon/Planet combinations … ie. we assumed in the list would be a Planet with only one of its Moons randomly selected … mistake!!! Better is …

    <?php

    $goodlist=',Mercury,Venus,';
    $badlist=',Mercury,Venus,';


    while (strlen($goodlist) == strlen($badlist)) {
    $goodlist=',Mercury,Venus,';

    $badlist=',Mercury,Venus,';

    $correctans=rand(0,8);
    $sofar=';';
    for ($i=0; $i<9; $i++) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    if ($crandlist == '') {
    $crandlist='' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else if (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    while (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else {
    if (strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) { $badlist.=$wikidescriptions[$j] . ','; }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    }
    }
    }

    ?>


    Previous relevant Enneagram Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Enneagram Type Game Tutorial

    A lot of us wonder what goes towards making up our personalities. We remember doing a Myers-Briggs test for some job as part of the vetting process. We thought we’d write another experimental drag and drop game, like yesterday’s Australian Street Type Game Tutorial, regarding …

    Enneagram Types

    … of human personalities, and we found a webpage linking these categorizations to Hollywood Movie Stars for you to get the gist of the ideas. We also thank Wikipedia as our source for Movie Star images.

    It being a topic …

    1. beyond our ken
    2. outside our usual subject matter

    … you may be wondering how we stumbled upon the idea? We let Google autocomplete our …


    nine types of

    … search textbox typing, fully expecting “Carol”? to be at the top of the list when we saw …


    nine types of enneagram

    … to flesh out a family of “game interest”, we hope?!

    Our first draft PHP game is also playable below …


    Previous relevant Australian Street Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Australian Street Type Game Tutorial

    The experimental drag and drop theme continues on today, after Experimental Drag and Drop Game Tutorial‘s debut game application, with a Wikipedia inspired “Australian Street Type” game today.

    Huh?! Well, you know those street names that baffle? Or are we easily baffleable?! Anyway, you had to be there. And if you ever feel you’re alone with an interest, just look it up in Wikipedia or Google and you’re almost sure to find out …

    you are not alone

    Yes, our Wikipedia page mentioned Australian Street Type Designations with their lawyerly Australian Street Type Descriptions. Who could ask for more? Well?!

    To make this happen we wrote some PHP, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, or template, to mould and bend towards our purpose … nga ha ha!

    Our first draft PHP game is also playable below …


    Previous relevant Experimental Drag and Drop Game Tutorial is shown below.

    Experimental Drag and Drop Game Tutorial

    Experimental Drag and Drop Game Tutorial

    It can be interesting turning a “concept” (or even a “proof of concept” web application) into an, on the side, “game” web application, and that way, learn what’s possible via user action. This is how we felt about yesterday’s Experimental Drag and Drop Primer Tutorial and that teamed with the wonder about how we could add some useful complexity to our “Experimental Drag and Drop” web application’s …

    Drop Zone

    Can “inheritance” be harnessed to make it work for some complexity of nested HTML elements inside that “Drop Zone” element when the document.body’s onload event happens? We wondered whether a Brady Bunch style 3×3 table could be the go? And whether the nine cells could have a “score” associated with them, and that set of scores be changing over time to make the game more challenging and interesting? Well …

    Yes

    … is the answer regarding making a game out of a proof of concept with our experimental_drag_and_drop.html HTML and Javascript and CSS game web application (also shown below) using these techniques, about which we think some of you readers will be interested?!


    Previous relevant Experimental Drag and Drop Primer Tutorial is shown below.

    Experimental Drag and Drop Primer Tutorial

    Experimental Drag and Drop Primer Tutorial

    We’ve added the word experimental into today’s blog posting title, mainly because our first of two inspirational webpage sources (last modified on 23/02/2023) regarding somewhat alternative “Drag and Drop” functionalities told us, regarding the DataTransfer object informational “DataTransfer” webpage …

    Experimental: This is an experimental technology
    Check the Browser compatibility table carefully before using this in production.

    … but our testing of the methodologies on various platforms hasn’t totally failed yet on any of the several desktop and mobile platform scenarios we’ve tried. On mobile, we just held on for a sustained touch (down) to make it possible. So maybe the industry has caught up with the ideas? We’re hoping so, because “drag and drop” is a kind of natural thing online users think of to do, and people associate it with “getting things done” we reckon.

    Anyway, we relied on the great source code of the second of two inspirational webpages DataTransfer: setData() method, thanks …

    The DataTransfer.setData() method sets the drag operation’s drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type. If data for the given type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.

    … to get us going with our “proof of concept” web application (also shown below) using these techniques, about which we think some of you readers will be interested?!

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

Colouring In Drag and Drop Background Image Tutorial

Colouring In Drag and Drop Background Image Tutorial

Colouring In Drag and Drop Background Image Tutorial

So far it might have been hard for some users to visualize “colouring in” a blank canvas. As such, today, onto yesterday’s Colouring In Drag and Drop Mobile Tutorial we’re now offering …

  • ability to define a tabular background image via a browsed for image … or …
  • ability to define a tabular background image via a user defined image URL

… and add a new “opacity” setting …


function torgba(inc, opa) {
var i, j=0, csess="rgba(:::1.0)", alp="0123456789abcdef", factor=16;
for (i=0; i<=inc.replace('#','').length; i++) {
if (i == 1) {
csess=csess.replace('rgba(:','rgba(' + (j + alp.toLowerCase().indexOf(inc.toLowerCase().replace('#','').substring(i,(i + 1)))) + ':');
j=0;
} else if (i == 3) {
csess=csess.replace('::',':' + (j + alp.toLowerCase().indexOf(inc.toLowerCase().replace('#','').substring(i,(i + 1)))) + ':');
j=0;
} else if (i == 5) {
csess=csess.replace('::',':' + (j + alp.toLowerCase().indexOf(inc.toLowerCase().replace('#','').substring(i,(i + 1)))) + ':');
j=0;
} else {
j=j + (factor * alp.toLowerCase().indexOf(inc.toLowerCase().replace('#','').substring(i,(i + 1))));
}
csess = csess.replace(":1.0)",":" + opa + ")");
}
return csess.replace(/\:/g,',');
}

function opit(ijval) {
if (document.getElementById('opmeter')) {
if (eval(1.00 - document.getElementById('opmeter').value) != 0.00) {
return torgba(ijval, document.getElementById('opmeter').value);
}
}
return ijval;
}

… all of which we can envisage could have users, at the very least, using this “Colouring In” web application for …

  • a scribbling or doodling mechanism (on a blank canvas)
  • colouring in via a background image with clip art linework, perhaps …
  • create a postcard (type of creation) via a background image, perhaps browsed for (or using the Take Photo or Video option for mobile) on your device, and overlay some scribbled (or doodled) wording

Codewise …

… helped with these mobile platform tweaks. We thank https://i.pinimg.com/736x/86/98/2d/86982d9ee1582bb7a4e730f11ebed3f4.jpg for the background image used (and fed into that image URL textbox to make happen) in today’s tutorial animated GIF presentation.


Previous relevant Colouring In Drag and Drop Mobile Tutorial is shown below.

Colouring In Drag and Drop Mobile Tutorial

Colouring In Drag and Drop Mobile Tutorial

Yesterday’s Colouring In Drag and Drop Sharing Tutorial sharing and collaboration code for our latest Colouring In web application was tested on our MacBook Air laptop only. As you can imagine, that can mean that code working there is not always going to work the same way on mobile touch devices, but it was not, as it panned out for us, regarding the reason we thought it would be about. We thought …

  • it’s bound to be an issue with dragging event workings regarding mobile … but it took us quite some time to stop burying our head in the sand and, instead, “keeping it simple, Señor” (ie. the KISS principle, and yes, Señor is not a spelling mistake, thank you very much for your concern) … and testing another “dumber sounding” but panning out to be true, in this case …
  • issue was to do with table cell widths and heights for table cells with no content acts differently for mobile than non-mobile (effectively scrunching cells up)

… the trigger for us being that the “drop” event.target.id kept on showing up as “mytable”. That happened hours ago! We beavered away with x,y proportional co-ordinate calculations and eventually after all that not helping (for 2 maybe 3 hours), started applying a table cell border, which gave crazy results, and then it tweaked?! Sheeeeesssshhhhh!

Can you teach yourself the KISS principle? Maybe you get better over time. Another opinion can be great, though, with that alternative view, you hadn’t even thought of, often the result of such conversations.

Back to today, we …

Made sure table “tr” row elements were for a better defined (proportionate to table) width
<?php

for ($thisrow=1; $thisrow<=$across; $thisrow++) {
$cthisrow='0000000000' . $thisrow;
$rowsofar='<tr style="width:100%;" id=tr' . substr($cthisrow, -$iacross, $iacross) . '></tr>';
$thistdid='td' . substr($cthisrow, -$iacross, $iacross) . '_';
for ($thiscol=1; $thiscol<=$across; $thiscol++) {
$cthiscol='0000000000' . $thiscol;
$thistdidsuffix='' . substr($cthiscol, -$iacross, $iacross) . '';
$rowsofar=str_replace('></tr>', '><td class="tdone" id=' . $thistdid . $thistdidsuffix . ' style=text-align:center; data-answer=' . $ttcnt . '></td></tr>', $rowsofar);
}
$newih=str_replace('</tbody>', $rowsofar . '</tbody>', $newih);
}

?>
Made sure table “td” cell elements were proportional … initially, expressed in “viewport” (percentage style) dimension terms …
<style>

td.tdone {
width: 1vw;
height: 1vh;
}

</style>
… and if not the default number of cells across and down …

function overdover() {
if (document.getElementById('dragoverdelay') && document.getElementById('dragovercountdown')) {
if (document.getElementById('numacross')) {
if (('' + document.getElementById('numacross').value) != '99') {
document.getElementById('dstyle').innerHTML+='<st' + 'yle> td { width: ' + eval(eval('' + document.getElementById('numacross').value) /100) + 'vw; height: ' + eval(eval('' + document.getElementById('numacross').value) /100) + 'vh; } </st' + 'yle>';
}
}

if (Math.abs(doverd) != eval('' + document.getElementById('dragoverdelay').value)) { doverd=eval('' + document.getElementById('dragoverdelay').value); }
if (doverc == 0 && eval('' + document.getElementById('dragovercountdown').value) == 0) { doverc=doverd; document.getElementById('dragovercountdown').value='' + doverc; document.getElementById('dragovercountdown').style.display='inline-block'; }
}
}

Codewise …

… helped with these mobile platform tweaks.


Previous relevant Colouring In Drag and Drop Sharing Tutorial is shown below.

Colouring In Drag and Drop Sharing Tutorial

Colouring In Drag and Drop Sharing Tutorial

We’re hoping yesterday’s Colouring In Drag and Drop Settings Tutorial new Colouring In web application is seen as a creative’s tool. As such, you’re going to want to share and collaborate … some of you, that is?!

You’re going to want to hashtag … oops … we’re going to want to hashtag. Yes, there is lots of data to share, but it worries us even involving hashtagging, how much there is, underlying, regarding that table element acting a bit like a television’s pixels. How do you effectively share even a snapshot of that?

But the difference between us and the television is, at least for a lot of people’s creations, the table is likely to be untouched, so can’t we “nickname” these repeated table cell scenarios? If you just said “indeed”, we’d concur! Take a look at some global Javascript variables we thought might help


var defemail='';
var defsms='', snum=null, sparewes=null;
var prefixnickchar='.';
var prefixfor='<td class="tdone" id="';
var suffixnickchar='-';
var suffixfor='" class="tdone" style="text-align:center;" data-answer="1"></td>';

… and for those untouched cells you’re saving more than (because of encryption) the length difference between the “nickchars” above and their “fixfor” counterparts for each “boring” table cell encountered. And all this eases our mind somewhat, as a design, realized, on the way to the emailee or smsee this way


function doemail(inidea) {
var bihbig='';
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 (inidea.indexOf('@') == -1) {
inidea=('' + prompt('Please enter Email address to send to.', defemail));
if (inidea == null) { inidea=''; }
}
if (inidea.indexOf('@') == -1) { return ''; }

bihbig=document.body.innerHTML;
while (bihbig.indexOf(suffixfor) != -1) {
bihbig=bihbig.replace(suffixfor, suffixnickchar);
}
while (bihbig.indexOf(prefixfor + 'td') != -1) {
bihbig=bihbig.replace(prefixfor + 'td', prefixnickchar + 'td');
}

//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('h1')[0].innerText.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
//} else {
if (sparewes) {
azx.href = 'mailto:' + inidea + '?subject=' + encodeURIComponent(sparewes.document.getElementsByTagName('h1')[0].innerText.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //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.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
}
//}
azx.click();
return '';
}

function dosms() {
var bihbig='';
if (('' + window.localStorage.getItem('colouringincollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defemail=window.localStorage.getItem('colouringincollaboratoremailee');
}
if (('' + window.localStorage.getItem('colouringincollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defsms=window.localStorage.removeItem('colouringincollaboratorsmsno');
}
if (eval('' + ('sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#cibih=' + 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('colouringincollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('colouringincollaboratoremailee');
}
window.localStorage.setItem('colouringincollaboratoremailee', 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('colouringincollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('colouringincollaboratorsmsno');
}
window.localStorage.setItem('colouringincollaboratorsmsno', snum);
defsms=snum;
}

bihbig=document.body.innerHTML;
while (bihbig.indexOf(suffixfor) != -1) {
bihbig=bihbig.replace(suffixfor, suffixnickchar);
}
while (bihbig.indexOf(prefixfor + 'td') != -1) {
bihbig=bihbig.replace(prefixfor + 'td', prefixnickchar + 'td');
}

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.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig)));
azx.click();
}
return '';
}

… and when arriving back from an emailee’s or smsee’s link click …


function cibihcheck() {
var partslh=('' + location.hash).split('#ci' + 'bih=');
if (eval('' + partslh.length) > 1) {
var bihbig=decodeURIComponent(decodeURIComponent(partslh[1]));

bihbig=bihbig.replace(/\.td/g, prefixfor + 'td');
bihbig=bihbig.replace(/0\-/g, '0' + suffixfor);
bihbig=bihbig.replace(/1\-/g, '1' + suffixfor);
bihbig=bihbig.replace(/2\-/g, '2' + suffixfor);
bihbig=bihbig.replace(/3\-/g, '3' + suffixfor);
bihbig=bihbig.replace(/4\-/g, '4' + suffixfor);
bihbig=bihbig.replace(/5\-/g, '5' + suffixfor);
bihbig=bihbig.replace(/6\-/g, '6' + suffixfor);
bihbig=bihbig.replace(/7\-/g, '7' + suffixfor);
bihbig=bihbig.replace(/8\-/g, '8' + suffixfor);
bihbig=bihbig.replace(/9\-/g, '9' + suffixfor);

document.body.innerHTML=bihbig;
}
}

Codewise …

… helped with this sense of collaboration.


Previous relevant Colouring In Drag and Drop Settings Tutorial is shown below.

Colouring In Drag and Drop Settings Tutorial

Colouring In Drag and Drop Settings Tutorial

Onto the start for our Colouring In web application via yesterday’s Colouring In Canvas Clone of Numbers Guessing Game Tutorial we’re starting to enhance, on top of that “clone level” functionality, via two new settings with two approaches to the management of data, regarding, those being …

  • number of table cells across (that programmatically is made to be the same number of cells, as down) … we deal with via a get ? (or &) address line URL arrangement … whereas …
  • pen “width” can be 1 or 2 (where 2 colours in the 1+8=9 surrounding cells of a dragged over cell) … we deal with via a hashtag arrangement

Why the difference in approach? Let’s start with hashtag methodologies. This arrangement can leave everything about a webpage, in place, regarding the user actions on a webpage, while the Javascript can detect that change in …


location.hash

… dynamically. In other words some dragging canvas drawings with pen “width” 2 can be combined with some using pen “width” 1 in the same user creation.

But when the data management involves get ? (or &) address line URL arrangements, this involves navigation to a new incarnation of the webpage creation logic, effectively wiping the webpage slate clean. This is apt for the “number of table cells across” data item, because the HTML content of the table element is not just affected, but is totally structured, according to this user setting.

Lately, more and more, we’ve been hashtagging data to dynamically created “a” link “mailto:” email or “sms:” SMS communication body webpage URL links. An email link or SMS link, from the recipient’s point of view is a “brand new start” that can address either or both of these data conduit arrangements, we’re getting happier and happier to discover …


// ondragover event function code snippet below ...
ev.target.style.backgroundColor='' + document.getElementById('ddcolour').value;
if (decodeURIComponent(('' + location.hash)).indexOf('fontweight=') != -1) {
ifontweight=eval('' + ('' + decodeURIComponent(('' + location.hash))).split('fontweight=')[1].substring(0,1));
}
else if (document.getElementById('numfontweight')) {
ifontweight=eval('' + document.getElementById('numfontweight').value);
}
if (ifontweight == 2) { // colour in 8 surrounding cells, as applicable
var minusthree=-3;
if (document.getElementById('numacross')) {
minusthree=eval(-1 * eval('' + document.getElementById('numacross').value.length));
}
var tdx=eval(('' + ev.target.id).substring(2).split('_')[0].replace(/^0/g,'').replace(/^0/g,''));
var tdy=eval(('' + ev.target.id).split('_')[1].replace(/^0/g,'').replace(/^0/g,''));
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}

if (document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}

if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
}

Codewise …

Did you know?

Our recent Earth Scanner project was conducted during our “Hashtagging Enlightenment Period”, whereby, around here, the …

What the Hep?

… greeting, is code for “Have yourself a happy and fruitful hashtagging day” … but we digress. In amongst it’s code there was an example codeline …


var nontz=('' + location.search + ('' + location.hash).replace(/^\#/g,'')).split('nontz=')[1] ? decodeURIComponent(('' + location.search + ('' + location.hash).replace(/^\#/g,'')).split('nontz=')[1].split('&')[0].split('#')[0]) : '';

… exemplifying, how more and more, we’re happy with setting (or other types of incoming) data coming from get (? and & ( eg. ?nontz=Alice_Springs%7C133.8807%7C_23.6980%7C )) arguments via location.search and/or hashtagged data coming from location.hash ( eg. #nontz=Alice_Springs%7C133.8807%7C_23.6980%7C ) above, either or both, perhaps, used in an email or SMS body URL link.


Previous relevant Colouring In Canvas Clone of Numbers Guessing Game Tutorial is shown below.

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

As the blog posting title suggests, cloned from yesterday’s Numbers Guessing Game Dragover Tutorial

  • Numbers Guessing Game dragover “value add” proof of concept work … comes …
  • Colouring In Canvas drag and (faux) drop web application

… where a “canvas” palette (which is really an HTML table element made up of lots of table cells, rather than an HTML5 canvas element). Why this design? Well, each table cell element can be identified as an individual “dragged over” element. “Dragged over” by what? Well, we turn some “draggable” wording in the basis HTML into …

  • an emoji pen 🖌 piece of text … and next to that we add …
  • an input type=color Colour Picker to choose a pen colour … and because the “ondragover” event is so sensitive, we also add an optionally used, or not …
  • input type=number defining any delay (in seconds) before the “ondragover” colouring in kicks in, from when it could first of happened, as the pen crosses over into the palette … along with …
  • input type=number countdown of the delay
  • … so that the user can use “dragover” event means by which to create their own “colouring in creation”!

    Codewise …


    Previous relevant Numbers Guessing Game Dragover Tutorial is shown below.

    Numbers Guessing Game Dragover Tutorial

    Numbers Guessing Game Dragover Tutorial

    Today we’re honing in on …

    • drag and drop methodology …
    • dragover event … value adding where …
    • drop element(s) are cells of an HTML table element (also a drop element)

    … as our interest. We scouted around for the best “design match” and came up with the arrangements existing when we presented Numbers Guessing Game Tutorial some time ago now.

    And if we succeed with some form of value adding here, we have another idea for the ideas we’re presenting today. Spoiler alert! Yes, it can be made to be useful.

    As such we’ve …

    Added toggleable “show where contemplated” value added border where dragover logic
    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');
    if (isset($_GET['notice'])) {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a></span>', $templategame);
    } else {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a></span>', $templategame);
    }


    ?>
    Tweaked dragover logic

    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    if (ev.target.outerHTML.indexOf('<table') != 0 && ev.target.outerHTML.indexOf(' data-piece="') != -1) {
    if (ev.target.outerHTML.split(' data-piece="')[1].substring(0,1) == (itisthiscmove + ev.target.outerHTML.split(' data-piece="')[1].substring(0,1)).substring(0,1)) {
    lohfulloh=ev.target.outerHTML;
    console.log("LOHfulloh=" + lohfulloh);
    }
    }
    //console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    //if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    // document.title='ev.preventDefault(); //4';
    //}
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (document.getElementById('sdropz')) {
    if (document.getElementById('sdropz').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('sdropz').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('sdropz').innerHTML=document.getElementById('sdropz').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { ev.target.style.border='2px dashed yellow'; }
    }
    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';.id)
    });
    Flag any continued “show where contemplated” interest

    var secsmore='';
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { secsmore='&notice=y'; }

    if (document.URL.indexOf('rjmprogramming-com-au.translate.goog') != -1) {
    location.href=document.URL.split('&score=')[0] + '&score=' + score + '&secs=' + secs + secsmore;
    } else {
    location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs + secsmore;
    }

    … to, as the user requests, add some table cell border enhancements (as our “value adding“) to our tweaked third draft PHP game (helped out by the changed experimental_drag_and_drop.htm Experimental Drag and Drop clientside HTML and Javascript basis), as the user drags the draggable element over the table droppable element and its cohort table cell elements.


    Previous relevant Numbers Guessing Game Tutorial is shown below.

    Numbers Guessing Game Tutorial

    Numbers Guessing Game Tutorial

    We’ve been working on aspects to the genericity of the table that is …

    The Drop Zone

    … do do … do do … do do … do do … do do do do do do do do do do do do … yesterday’s threat “now so yesterday” being …

    • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
    • allow the number of cells across in a column not be 3

    … in a (very difficult) Numbers Guessing game for numbers from 1 to 99 that regular readers may be familiar with as the (same content (and mentioned at this link … thanks …) as the) Numbers Guessing game at this blog, but presented using a Drag and Drop modus operandi.

    Feel free to try our first draft PHP game, which leans on a changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    On your smaller devices we found the Numbers Guessing Game a bit hard to use. As such, we researched and played around with “drag and drop” cursor ideas unsuccessfully to end up, instead, not thinking about the cursor (albeit, we find that idea cuter) but rather styling the target table cell’s background colour and informing the user of that up at the top button wording in our changed second draft PHP game, which leans on our changed experimental_drag_and_drop.htm HTML and Javascript and CSS helper


    var lastbco=null;

    const target = document.querySelector("#target");
    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    }

    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';

    });


    Previous relevant Planet Moon Game Tutorial is shown below.

    Planet Moon Game Tutorial

    Planet Moon Game Tutorial

    Another thing that there is nine of (as contentious as it is regarding Pluto) is Planets in the Solar System, revolving around the Sun. And so, in keeping with a lot of the same design as yesterday’s Enneagram Type Game Tutorial we have a Planet Moon Game to present for you to play around with today.

    Again, PHP uses a framework of Experimental Drag and Drop HTML and Javascript and CSS, mainly via one PHP codeline …

    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');

    ?>

    … and, perhaps, your curiosity that we have not “passed” data via $_GET[] or $_POST[] arguments, but rather just the simple act of …

    • moulding and manipulating (eg. arranging “callback” logic means, as used below) that $templategame “template” for our purposes … nga ha ha ha ha ha ha ha ha … but we digress …
    • simply …
      <?php

      echo $templategame;

      ?>
      … outputs a webpage …
    • and on the way back to play again, we use $_GET[‘score’] and $_GET[‘secs’] (in experimental_drag_and_drop.html HTML and Javascript and CSS game web application) to keep the ball rolling back to the game specific PHP we use …

      location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;

    … in our first draft PHP game, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    We fully concur with any adage that goes …

    You learn most from your mistakes

    … just as we’re curious about “the things that go wrong”, and not having them repeat! Same with pooches!

    Take our first to second draft PHP game (to the opera, would be preferable). We wondered why, occasionally, with the “first draft” it would hang. It took us a half day to realize, as you could yourself have tweaked to a lot quicker if you had followed the adage …


    Hanging issues mostly team up with code within a loop

    The situation, we’ve reasoned, is that we had that PHP $badlist variable store a comma separated list of planets with either zero moons or more than one moon randomly selected representing it. We’d assumed, yesterday, not that we’d put it in words, but in logic, that this list would not (have the same length or) be the same as a (new $goodlist variable) list of planets with either zero moons or selected while collecting the random list of Moon/Planet combinations … ie. we assumed in the list would be a Planet with only one of its Moons randomly selected … mistake!!! Better is …

    <?php

    $goodlist=',Mercury,Venus,';
    $badlist=',Mercury,Venus,';


    while (strlen($goodlist) == strlen($badlist)) {
    $goodlist=',Mercury,Venus,';

    $badlist=',Mercury,Venus,';

    $correctans=rand(0,8);
    $sofar=';';
    for ($i=0; $i<9; $i++) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    if ($crandlist == '') {
    $crandlist='' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else if (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    while (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else {
    if (strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) { $badlist.=$wikidescriptions[$j] . ','; }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    }
    }
    }

    ?>


    Previous relevant Enneagram Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Enneagram Type Game Tutorial

    A lot of us wonder what goes towards making up our personalities. We remember doing a Myers-Briggs test for some job as part of the vetting process. We thought we’d write another experimental drag and drop game, like yesterday’s Australian Street Type Game Tutorial, regarding …

    Enneagram Types

    … of human personalities, and we found a webpage linking these categorizations to Hollywood Movie Stars for you to get the gist of the ideas. We also thank Wikipedia as our source for Movie Star images.

    It being a topic …

    1. beyond our ken
    2. outside our usual subject matter

    … you may be wondering how we stumbled upon the idea? We let Google autocomplete our …


    nine types of

    … search textbox typing, fully expecting “Carol”? to be at the top of the list when we saw …


    nine types of enneagram

    … to flesh out a family of “game interest”, we hope?!

    Our first draft PHP game is also playable below …


    Previous relevant Australian Street Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Australian Street Type Game Tutorial

    The experimental drag and drop theme continues on today, after Experimental Drag and Drop Game Tutorial‘s debut game application, with a Wikipedia inspired “Australian Street Type” game today.

    Huh?! Well, you know those street names that baffle? Or are we easily baffleable?! Anyway, you had to be there. And if you ever feel you’re alone with an interest, just look it up in Wikipedia or Google and you’re almost sure to find out …

    you are not alone

    Yes, our Wikipedia page mentioned Australian Street Type Designations with their lawyerly Australian Street Type Descriptions. Who could ask for more? Well?!

    To make this happen we wrote some PHP, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, or template, to mould and bend towards our purpose … nga ha ha!

    Our first draft PHP game is also playable below …


    Previous relevant Experimental Drag and Drop Game Tutorial is shown below.

    Experimental Drag and Drop Game Tutorial

    Experimental Drag and Drop Game Tutorial

    It can be interesting turning a “concept” (or even a “proof of concept” web application) into an, on the side, “game” web application, and that way, learn what’s possible via user action. This is how we felt about yesterday’s Experimental Drag and Drop Primer Tutorial and that teamed with the wonder about how we could add some useful complexity to our “Experimental Drag and Drop” web application’s …

    Drop Zone

    Can “inheritance” be harnessed to make it work for some complexity of nested HTML elements inside that “Drop Zone” element when the document.body’s onload event happens? We wondered whether a Brady Bunch style 3×3 table could be the go? And whether the nine cells could have a “score” associated with them, and that set of scores be changing over time to make the game more challenging and interesting? Well …

    Yes

    … is the answer regarding making a game out of a proof of concept with our experimental_drag_and_drop.html HTML and Javascript and CSS game web application (also shown below) using these techniques, about which we think some of you readers will be interested?!


    Previous relevant Experimental Drag and Drop Primer Tutorial is shown below.

    Experimental Drag and Drop Primer Tutorial

    Experimental Drag and Drop Primer Tutorial

    We’ve added the word experimental into today’s blog posting title, mainly because our first of two inspirational webpage sources (last modified on 23/02/2023) regarding somewhat alternative “Drag and Drop” functionalities told us, regarding the DataTransfer object informational “DataTransfer” webpage …

    Experimental: This is an experimental technology
    Check the Browser compatibility table carefully before using this in production.

    … but our testing of the methodologies on various platforms hasn’t totally failed yet on any of the several desktop and mobile platform scenarios we’ve tried. On mobile, we just held on for a sustained touch (down) to make it possible. So maybe the industry has caught up with the ideas? We’re hoping so, because “drag and drop” is a kind of natural thing online users think of to do, and people associate it with “getting things done” we reckon.

    Anyway, we relied on the great source code of the second of two inspirational webpages DataTransfer: setData() method, thanks …

    The DataTransfer.setData() method sets the drag operation’s drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type. If data for the given type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.

    … to get us going with our “proof of concept” web application (also shown below) using these techniques, about which we think some of you readers will be interested?!

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

Colouring In Drag and Drop Mobile Tutorial

Colouring In Drag and Drop Mobile Tutorial

Colouring In Drag and Drop Mobile Tutorial

Yesterday’s Colouring In Drag and Drop Sharing Tutorial sharing and collaboration code for our latest Colouring In web application was tested on our MacBook Air laptop only. As you can imagine, that can mean that code working there is not always going to work the same way on mobile touch devices, but it was not, as it panned out for us, regarding the reason we thought it would be about. We thought …

  • it’s bound to be an issue with dragging event workings regarding mobile … but it took us quite some time to stop burying our head in the sand and, instead, “keeping it simple, Señor” (ie. the KISS principle, and yes, Señor is not a spelling mistake, thank you very much for your concern) … and testing another “dumber sounding” but panning out to be true, in this case …
  • issue was to do with table cell widths and heights for table cells with no content acts differently for mobile than non-mobile (effectively scrunching cells up)

… the trigger for us being that the “drop” event.target.id kept on showing up as “mytable”. That happened hours ago! We beavered away with x,y proportional co-ordinate calculations and eventually after all that not helping (for 2 maybe 3 hours), started applying a table cell border, which gave crazy results, and then it tweaked?! Sheeeeesssshhhhh!

Can you teach yourself the KISS principle? Maybe you get better over time. Another opinion can be great, though, with that alternative view, you hadn’t even thought of, often the result of such conversations.

Back to today, we …

Made sure table “tr” row elements were for a better defined (proportionate to table) width
<?php

for ($thisrow=1; $thisrow<=$across; $thisrow++) {
$cthisrow='0000000000' . $thisrow;
$rowsofar='<tr style="width:100%;" id=tr' . substr($cthisrow, -$iacross, $iacross) . '></tr>';
$thistdid='td' . substr($cthisrow, -$iacross, $iacross) . '_';
for ($thiscol=1; $thiscol<=$across; $thiscol++) {
$cthiscol='0000000000' . $thiscol;
$thistdidsuffix='' . substr($cthiscol, -$iacross, $iacross) . '';
$rowsofar=str_replace('></tr>', '><td class="tdone" id=' . $thistdid . $thistdidsuffix . ' style=text-align:center; data-answer=' . $ttcnt . '></td></tr>', $rowsofar);
}
$newih=str_replace('</tbody>', $rowsofar . '</tbody>', $newih);
}

?>
Made sure table “td” cell elements were proportional … initially, expressed in “viewport” (percentage style) dimension terms …
<style>

td.tdone {
width: 1vw;
height: 1vh;
}

</style>
… and if not the default number of cells across and down …

function overdover() {
if (document.getElementById('dragoverdelay') && document.getElementById('dragovercountdown')) {
if (document.getElementById('numacross')) {
if (('' + document.getElementById('numacross').value) != '99') {
document.getElementById('dstyle').innerHTML+='<st' + 'yle> td { width: ' + eval(eval('' + document.getElementById('numacross').value) /100) + 'vw; height: ' + eval(eval('' + document.getElementById('numacross').value) /100) + 'vh; } </st' + 'yle>';
}
}

if (Math.abs(doverd) != eval('' + document.getElementById('dragoverdelay').value)) { doverd=eval('' + document.getElementById('dragoverdelay').value); }
if (doverc == 0 && eval('' + document.getElementById('dragovercountdown').value) == 0) { doverc=doverd; document.getElementById('dragovercountdown').value='' + doverc; document.getElementById('dragovercountdown').style.display='inline-block'; }
}
}

Codewise …

… helped with these mobile platform tweaks.


Previous relevant Colouring In Drag and Drop Sharing Tutorial is shown below.

Colouring In Drag and Drop Sharing Tutorial

Colouring In Drag and Drop Sharing Tutorial

We’re hoping yesterday’s Colouring In Drag and Drop Settings Tutorial new Colouring In web application is seen as a creative’s tool. As such, you’re going to want to share and collaborate … some of you, that is?!

You’re going to want to hashtag … oops … we’re going to want to hashtag. Yes, there is lots of data to share, but it worries us even involving hashtagging, how much there is, underlying, regarding that table element acting a bit like a television’s pixels. How do you effectively share even a snapshot of that?

But the difference between us and the television is, at least for a lot of people’s creations, the table is likely to be untouched, so can’t we “nickname” these repeated table cell scenarios? If you just said “indeed”, we’d concur! Take a look at some global Javascript variables we thought might help


var defemail='';
var defsms='', snum=null, sparewes=null;
var prefixnickchar='.';
var prefixfor='<td class="tdone" id="';
var suffixnickchar='-';
var suffixfor='" class="tdone" style="text-align:center;" data-answer="1"></td>';

… and for those untouched cells you’re saving more than (because of encryption) the length difference between the “nickchars” above and their “fixfor” counterparts for each “boring” table cell encountered. And all this eases our mind somewhat, as a design, realized, on the way to the emailee or smsee this way


function doemail(inidea) {
var bihbig='';
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 (inidea.indexOf('@') == -1) {
inidea=('' + prompt('Please enter Email address to send to.', defemail));
if (inidea == null) { inidea=''; }
}
if (inidea.indexOf('@') == -1) { return ''; }

bihbig=document.body.innerHTML;
while (bihbig.indexOf(suffixfor) != -1) {
bihbig=bihbig.replace(suffixfor, suffixnickchar);
}
while (bihbig.indexOf(prefixfor + 'td') != -1) {
bihbig=bihbig.replace(prefixfor + 'td', prefixnickchar + 'td');
}

//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('h1')[0].innerText.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
//} else {
if (sparewes) {
azx.href = 'mailto:' + inidea + '?subject=' + encodeURIComponent(sparewes.document.getElementsByTagName('h1')[0].innerText.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //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.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
}
//}
azx.click();
return '';
}

function dosms() {
var bihbig='';
if (('' + window.localStorage.getItem('colouringincollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defemail=window.localStorage.getItem('colouringincollaboratoremailee');
}
if (('' + window.localStorage.getItem('colouringincollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defsms=window.localStorage.removeItem('colouringincollaboratorsmsno');
}
if (eval('' + ('sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#cibih=' + 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('colouringincollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('colouringincollaboratoremailee');
}
window.localStorage.setItem('colouringincollaboratoremailee', 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('colouringincollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('colouringincollaboratorsmsno');
}
window.localStorage.setItem('colouringincollaboratorsmsno', snum);
defsms=snum;
}

bihbig=document.body.innerHTML;
while (bihbig.indexOf(suffixfor) != -1) {
bihbig=bihbig.replace(suffixfor, suffixnickchar);
}
while (bihbig.indexOf(prefixfor + 'td') != -1) {
bihbig=bihbig.replace(prefixfor + 'td', prefixnickchar + 'td');
}

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.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig)));
azx.click();
}
return '';
}

… and when arriving back from an emailee’s or smsee’s link click …


function cibihcheck() {
var partslh=('' + location.hash).split('#ci' + 'bih=');
if (eval('' + partslh.length) > 1) {
var bihbig=decodeURIComponent(decodeURIComponent(partslh[1]));

bihbig=bihbig.replace(/\.td/g, prefixfor + 'td');
bihbig=bihbig.replace(/0\-/g, '0' + suffixfor);
bihbig=bihbig.replace(/1\-/g, '1' + suffixfor);
bihbig=bihbig.replace(/2\-/g, '2' + suffixfor);
bihbig=bihbig.replace(/3\-/g, '3' + suffixfor);
bihbig=bihbig.replace(/4\-/g, '4' + suffixfor);
bihbig=bihbig.replace(/5\-/g, '5' + suffixfor);
bihbig=bihbig.replace(/6\-/g, '6' + suffixfor);
bihbig=bihbig.replace(/7\-/g, '7' + suffixfor);
bihbig=bihbig.replace(/8\-/g, '8' + suffixfor);
bihbig=bihbig.replace(/9\-/g, '9' + suffixfor);

document.body.innerHTML=bihbig;
}
}

Codewise …

… helped with this sense of collaboration.


Previous relevant Colouring In Drag and Drop Settings Tutorial is shown below.

Colouring In Drag and Drop Settings Tutorial

Colouring In Drag and Drop Settings Tutorial

Onto the start for our Colouring In web application via yesterday’s Colouring In Canvas Clone of Numbers Guessing Game Tutorial we’re starting to enhance, on top of that “clone level” functionality, via two new settings with two approaches to the management of data, regarding, those being …

  • number of table cells across (that programmatically is made to be the same number of cells, as down) … we deal with via a get ? (or &) address line URL arrangement … whereas …
  • pen “width” can be 1 or 2 (where 2 colours in the 1+8=9 surrounding cells of a dragged over cell) … we deal with via a hashtag arrangement

Why the difference in approach? Let’s start with hashtag methodologies. This arrangement can leave everything about a webpage, in place, regarding the user actions on a webpage, while the Javascript can detect that change in …


location.hash

… dynamically. In other words some dragging canvas drawings with pen “width” 2 can be combined with some using pen “width” 1 in the same user creation.

But when the data management involves get ? (or &) address line URL arrangements, this involves navigation to a new incarnation of the webpage creation logic, effectively wiping the webpage slate clean. This is apt for the “number of table cells across” data item, because the HTML content of the table element is not just affected, but is totally structured, according to this user setting.

Lately, more and more, we’ve been hashtagging data to dynamically created “a” link “mailto:” email or “sms:” SMS communication body webpage URL links. An email link or SMS link, from the recipient’s point of view is a “brand new start” that can address either or both of these data conduit arrangements, we’re getting happier and happier to discover …


// ondragover event function code snippet below ...
ev.target.style.backgroundColor='' + document.getElementById('ddcolour').value;
if (decodeURIComponent(('' + location.hash)).indexOf('fontweight=') != -1) {
ifontweight=eval('' + ('' + decodeURIComponent(('' + location.hash))).split('fontweight=')[1].substring(0,1));
}
else if (document.getElementById('numfontweight')) {
ifontweight=eval('' + document.getElementById('numfontweight').value);
}
if (ifontweight == 2) { // colour in 8 surrounding cells, as applicable
var minusthree=-3;
if (document.getElementById('numacross')) {
minusthree=eval(-1 * eval('' + document.getElementById('numacross').value.length));
}
var tdx=eval(('' + ev.target.id).substring(2).split('_')[0].replace(/^0/g,'').replace(/^0/g,''));
var tdy=eval(('' + ev.target.id).split('_')[1].replace(/^0/g,'').replace(/^0/g,''));
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}

if (document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}

if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
}

Codewise …

Did you know?

Our recent Earth Scanner project was conducted during our “Hashtagging Enlightenment Period”, whereby, around here, the …

What the Hep?

… greeting, is code for “Have yourself a happy and fruitful hashtagging day” … but we digress. In amongst it’s code there was an example codeline …


var nontz=('' + location.search + ('' + location.hash).replace(/^\#/g,'')).split('nontz=')[1] ? decodeURIComponent(('' + location.search + ('' + location.hash).replace(/^\#/g,'')).split('nontz=')[1].split('&')[0].split('#')[0]) : '';

… exemplifying, how more and more, we’re happy with setting (or other types of incoming) data coming from get (? and & ( eg. ?nontz=Alice_Springs%7C133.8807%7C_23.6980%7C )) arguments via location.search and/or hashtagged data coming from location.hash ( eg. #nontz=Alice_Springs%7C133.8807%7C_23.6980%7C ) above, either or both, perhaps, used in an email or SMS body URL link.


Previous relevant Colouring In Canvas Clone of Numbers Guessing Game Tutorial is shown below.

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

As the blog posting title suggests, cloned from yesterday’s Numbers Guessing Game Dragover Tutorial

  • Numbers Guessing Game dragover “value add” proof of concept work … comes …
  • Colouring In Canvas drag and (faux) drop web application

… where a “canvas” palette (which is really an HTML table element made up of lots of table cells, rather than an HTML5 canvas element). Why this design? Well, each table cell element can be identified as an individual “dragged over” element. “Dragged over” by what? Well, we turn some “draggable” wording in the basis HTML into …

  • an emoji pen 🖌 piece of text … and next to that we add …
  • an input type=color Colour Picker to choose a pen colour … and because the “ondragover” event is so sensitive, we also add an optionally used, or not …
  • input type=number defining any delay (in seconds) before the “ondragover” colouring in kicks in, from when it could first of happened, as the pen crosses over into the palette … along with …
  • input type=number countdown of the delay
  • … so that the user can use “dragover” event means by which to create their own “colouring in creation”!

    Codewise …


    Previous relevant Numbers Guessing Game Dragover Tutorial is shown below.

    Numbers Guessing Game Dragover Tutorial

    Numbers Guessing Game Dragover Tutorial

    Today we’re honing in on …

    • drag and drop methodology …
    • dragover event … value adding where …
    • drop element(s) are cells of an HTML table element (also a drop element)

    … as our interest. We scouted around for the best “design match” and came up with the arrangements existing when we presented Numbers Guessing Game Tutorial some time ago now.

    And if we succeed with some form of value adding here, we have another idea for the ideas we’re presenting today. Spoiler alert! Yes, it can be made to be useful.

    As such we’ve …

    Added toggleable “show where contemplated” value added border where dragover logic
    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');
    if (isset($_GET['notice'])) {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a></span>', $templategame);
    } else {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a></span>', $templategame);
    }


    ?>
    Tweaked dragover logic

    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    if (ev.target.outerHTML.indexOf('<table') != 0 && ev.target.outerHTML.indexOf(' data-piece="') != -1) {
    if (ev.target.outerHTML.split(' data-piece="')[1].substring(0,1) == (itisthiscmove + ev.target.outerHTML.split(' data-piece="')[1].substring(0,1)).substring(0,1)) {
    lohfulloh=ev.target.outerHTML;
    console.log("LOHfulloh=" + lohfulloh);
    }
    }
    //console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    //if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    // document.title='ev.preventDefault(); //4';
    //}
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (document.getElementById('sdropz')) {
    if (document.getElementById('sdropz').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('sdropz').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('sdropz').innerHTML=document.getElementById('sdropz').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { ev.target.style.border='2px dashed yellow'; }
    }
    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';.id)
    });
    Flag any continued “show where contemplated” interest

    var secsmore='';
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { secsmore='&notice=y'; }

    if (document.URL.indexOf('rjmprogramming-com-au.translate.goog') != -1) {
    location.href=document.URL.split('&score=')[0] + '&score=' + score + '&secs=' + secs + secsmore;
    } else {
    location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs + secsmore;
    }

    … to, as the user requests, add some table cell border enhancements (as our “value adding“) to our tweaked third draft PHP game (helped out by the changed experimental_drag_and_drop.htm Experimental Drag and Drop clientside HTML and Javascript basis), as the user drags the draggable element over the table droppable element and its cohort table cell elements.


    Previous relevant Numbers Guessing Game Tutorial is shown below.

    Numbers Guessing Game Tutorial

    Numbers Guessing Game Tutorial

    We’ve been working on aspects to the genericity of the table that is …

    The Drop Zone

    … do do … do do … do do … do do … do do do do do do do do do do do do … yesterday’s threat “now so yesterday” being …

    • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
    • allow the number of cells across in a column not be 3

    … in a (very difficult) Numbers Guessing game for numbers from 1 to 99 that regular readers may be familiar with as the (same content (and mentioned at this link … thanks …) as the) Numbers Guessing game at this blog, but presented using a Drag and Drop modus operandi.

    Feel free to try our first draft PHP game, which leans on a changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    On your smaller devices we found the Numbers Guessing Game a bit hard to use. As such, we researched and played around with “drag and drop” cursor ideas unsuccessfully to end up, instead, not thinking about the cursor (albeit, we find that idea cuter) but rather styling the target table cell’s background colour and informing the user of that up at the top button wording in our changed second draft PHP game, which leans on our changed experimental_drag_and_drop.htm HTML and Javascript and CSS helper


    var lastbco=null;

    const target = document.querySelector("#target");
    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    }

    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';

    });


    Previous relevant Planet Moon Game Tutorial is shown below.

    Planet Moon Game Tutorial

    Planet Moon Game Tutorial

    Another thing that there is nine of (as contentious as it is regarding Pluto) is Planets in the Solar System, revolving around the Sun. And so, in keeping with a lot of the same design as yesterday’s Enneagram Type Game Tutorial we have a Planet Moon Game to present for you to play around with today.

    Again, PHP uses a framework of Experimental Drag and Drop HTML and Javascript and CSS, mainly via one PHP codeline …

    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');

    ?>

    … and, perhaps, your curiosity that we have not “passed” data via $_GET[] or $_POST[] arguments, but rather just the simple act of …

    • moulding and manipulating (eg. arranging “callback” logic means, as used below) that $templategame “template” for our purposes … nga ha ha ha ha ha ha ha ha … but we digress …
    • simply …
      <?php

      echo $templategame;

      ?>
      … outputs a webpage …
    • and on the way back to play again, we use $_GET[‘score’] and $_GET[‘secs’] (in experimental_drag_and_drop.html HTML and Javascript and CSS game web application) to keep the ball rolling back to the game specific PHP we use …

      location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;

    … in our first draft PHP game, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    We fully concur with any adage that goes …

    You learn most from your mistakes

    … just as we’re curious about “the things that go wrong”, and not having them repeat! Same with pooches!

    Take our first to second draft PHP game (to the opera, would be preferable). We wondered why, occasionally, with the “first draft” it would hang. It took us a half day to realize, as you could yourself have tweaked to a lot quicker if you had followed the adage …


    Hanging issues mostly team up with code within a loop

    The situation, we’ve reasoned, is that we had that PHP $badlist variable store a comma separated list of planets with either zero moons or more than one moon randomly selected representing it. We’d assumed, yesterday, not that we’d put it in words, but in logic, that this list would not (have the same length or) be the same as a (new $goodlist variable) list of planets with either zero moons or selected while collecting the random list of Moon/Planet combinations … ie. we assumed in the list would be a Planet with only one of its Moons randomly selected … mistake!!! Better is …

    <?php

    $goodlist=',Mercury,Venus,';
    $badlist=',Mercury,Venus,';


    while (strlen($goodlist) == strlen($badlist)) {
    $goodlist=',Mercury,Venus,';

    $badlist=',Mercury,Venus,';

    $correctans=rand(0,8);
    $sofar=';';
    for ($i=0; $i<9; $i++) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    if ($crandlist == '') {
    $crandlist='' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else if (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    while (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else {
    if (strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) { $badlist.=$wikidescriptions[$j] . ','; }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    }
    }
    }

    ?>


    Previous relevant Enneagram Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Enneagram Type Game Tutorial

    A lot of us wonder what goes towards making up our personalities. We remember doing a Myers-Briggs test for some job as part of the vetting process. We thought we’d write another experimental drag and drop game, like yesterday’s Australian Street Type Game Tutorial, regarding …

    Enneagram Types

    … of human personalities, and we found a webpage linking these categorizations to Hollywood Movie Stars for you to get the gist of the ideas. We also thank Wikipedia as our source for Movie Star images.

    It being a topic …

    1. beyond our ken
    2. outside our usual subject matter

    … you may be wondering how we stumbled upon the idea? We let Google autocomplete our …


    nine types of

    … search textbox typing, fully expecting “Carol”? to be at the top of the list when we saw …


    nine types of enneagram

    … to flesh out a family of “game interest”, we hope?!

    Our first draft PHP game is also playable below …


    Previous relevant Australian Street Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Australian Street Type Game Tutorial

    The experimental drag and drop theme continues on today, after Experimental Drag and Drop Game Tutorial‘s debut game application, with a Wikipedia inspired “Australian Street Type” game today.

    Huh?! Well, you know those street names that baffle? Or are we easily baffleable?! Anyway, you had to be there. And if you ever feel you’re alone with an interest, just look it up in Wikipedia or Google and you’re almost sure to find out …

    you are not alone

    Yes, our Wikipedia page mentioned Australian Street Type Designations with their lawyerly Australian Street Type Descriptions. Who could ask for more? Well?!

    To make this happen we wrote some PHP, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, or template, to mould and bend towards our purpose … nga ha ha!

    Our first draft PHP game is also playable below …


    Previous relevant Experimental Drag and Drop Game Tutorial is shown below.

    Experimental Drag and Drop Game Tutorial

    Experimental Drag and Drop Game Tutorial

    It can be interesting turning a “concept” (or even a “proof of concept” web application) into an, on the side, “game” web application, and that way, learn what’s possible via user action. This is how we felt about yesterday’s Experimental Drag and Drop Primer Tutorial and that teamed with the wonder about how we could add some useful complexity to our “Experimental Drag and Drop” web application’s …

    Drop Zone

    Can “inheritance” be harnessed to make it work for some complexity of nested HTML elements inside that “Drop Zone” element when the document.body’s onload event happens? We wondered whether a Brady Bunch style 3×3 table could be the go? And whether the nine cells could have a “score” associated with them, and that set of scores be changing over time to make the game more challenging and interesting? Well …

    Yes

    … is the answer regarding making a game out of a proof of concept with our experimental_drag_and_drop.html HTML and Javascript and CSS game web application (also shown below) using these techniques, about which we think some of you readers will be interested?!


    Previous relevant Experimental Drag and Drop Primer Tutorial is shown below.

    Experimental Drag and Drop Primer Tutorial

    Experimental Drag and Drop Primer Tutorial

    We’ve added the word experimental into today’s blog posting title, mainly because our first of two inspirational webpage sources (last modified on 23/02/2023) regarding somewhat alternative “Drag and Drop” functionalities told us, regarding the DataTransfer object informational “DataTransfer” webpage …

    Experimental: This is an experimental technology
    Check the Browser compatibility table carefully before using this in production.

    … but our testing of the methodologies on various platforms hasn’t totally failed yet on any of the several desktop and mobile platform scenarios we’ve tried. On mobile, we just held on for a sustained touch (down) to make it possible. So maybe the industry has caught up with the ideas? We’re hoping so, because “drag and drop” is a kind of natural thing online users think of to do, and people associate it with “getting things done” we reckon.

    Anyway, we relied on the great source code of the second of two inspirational webpages DataTransfer: setData() method, thanks …

    The DataTransfer.setData() method sets the drag operation’s drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type. If data for the given type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.

    … to get us going with our “proof of concept” web application (also shown below) using these techniques, about which we think some of you readers will be interested?!

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

Colouring In Drag and Drop Sharing Tutorial

Colouring In Drag and Drop Sharing Tutorial

Colouring In Drag and Drop Sharing Tutorial

We’re hoping yesterday’s Colouring In Drag and Drop Settings Tutorial new Colouring In web application is seen as a creative’s tool. As such, you’re going to want to share and collaborate … some of you, that is?!

You’re going to want to hashtag … oops … we’re going to want to hashtag. Yes, there is lots of data to share, but it worries us even involving hashtagging, how much there is, underlying, regarding that table element acting a bit like a television’s pixels. How do you effectively share even a snapshot of that?

But the difference between us and the television is, at least for a lot of people’s creations, the table is likely to be untouched, so can’t we “nickname” these repeated table cell scenarios? If you just said “indeed”, we’d concur! Take a look at some global Javascript variables we thought might help


var defemail='';
var defsms='', snum=null, sparewes=null;
var prefixnickchar='.';
var prefixfor='<td class="tdone" id="';
var suffixnickchar='-';
var suffixfor='" style="text-align:center;" data-answer="1"></td>';

… and for those untouched cells you’re saving more than (because of encryption) the length difference between the “nickchars” above and their “fixfor” counterparts for each “boring” table cell encountered. And all this eases our mind somewhat, as a design, realized, on the way to the emailee or smsee this way


function doemail(inidea) {
var bihbig='';
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 (inidea.indexOf('@') == -1) {
inidea=('' + prompt('Please enter Email address to send to.', defemail));
if (inidea == null) { inidea=''; }
}
if (inidea.indexOf('@') == -1) { return ''; }

bihbig=document.body.innerHTML;
while (bihbig.indexOf(suffixfor) != -1) {
bihbig=bihbig.replace(suffixfor, suffixnickchar);
}
while (bihbig.indexOf(prefixfor + 'td') != -1) {
bihbig=bihbig.replace(prefixfor + 'td', prefixnickchar + 'td');
}

//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('h1')[0].innerText.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
//} else {
if (sparewes) {
azx.href = 'mailto:' + inidea + '?subject=' + encodeURIComponent(sparewes.document.getElementsByTagName('h1')[0].innerText.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //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.split('&')[0].split('<')[0].replace(/\`/g,'').replace(/^Events\ in\ /g, 'Events in Month ').substring(0)) + '&body=' + encodeURIComponent(document.URL.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig))); //encodeURIComponent(document.URL.split('#')[0] + '<h2' + document.body.innerHTML.split('<h2')[1]));
}
//}
azx.click();
return '';
}

function dosms() {
var bihbig='';
if (('' + window.localStorage.getItem('colouringincollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defemail=window.localStorage.getItem('colouringincollaboratoremailee');
}
if (('' + window.localStorage.getItem('colouringincollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
defsms=window.localStorage.removeItem('colouringincollaboratorsmsno');
}
if (eval('' + ('sms:' + snum + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#cibih=' + 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('colouringincollaboratoremailee')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('colouringincollaboratoremailee');
}
window.localStorage.setItem('colouringincollaboratoremailee', 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('colouringincollaboratorsmsno')).replace(/^null/g,'').replace(/^undefined/g,'') != '') {
window.localStorage.removeItem('colouringincollaboratorsmsno');
}
window.localStorage.setItem('colouringincollaboratorsmsno', snum);
defsms=snum;
}

bihbig=document.body.innerHTML;
while (bihbig.indexOf(suffixfor) != -1) {
bihbig=bihbig.replace(suffixfor, suffixnickchar);
}
while (bihbig.indexOf(prefixfor + 'td') != -1) {
bihbig=bihbig.replace(prefixfor + 'td', prefixnickchar + 'td');
}

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.replace('php#', 'php?').replace('#', '&') + '#cibih=' + encodeURIComponent(encodeURIComponent(bihbig)));
azx.click();
}
return '';
}

… and when arriving back from an emailee’s or smsee’s link click …


function cibihcheck() {
var partslh=('' + location.hash).split('#ci' + 'bih=');
if (eval('' + partslh.length) > 1) {
var bihbig=decodeURIComponent(decodeURIComponent(partslh[1]));

bihbig=bihbig.replace(/\.td/g, prefixfor + 'td');
bihbig=bihbig.replace(/0\-/g, '0' + suffixfor);
bihbig=bihbig.replace(/1\-/g, '1' + suffixfor);
bihbig=bihbig.replace(/2\-/g, '2' + suffixfor);
bihbig=bihbig.replace(/3\-/g, '3' + suffixfor);
bihbig=bihbig.replace(/4\-/g, '4' + suffixfor);
bihbig=bihbig.replace(/5\-/g, '5' + suffixfor);
bihbig=bihbig.replace(/6\-/g, '6' + suffixfor);
bihbig=bihbig.replace(/7\-/g, '7' + suffixfor);
bihbig=bihbig.replace(/8\-/g, '8' + suffixfor);
bihbig=bihbig.replace(/9\-/g, '9' + suffixfor);

document.body.innerHTML=bihbig;
}
}

Codewise …

… helped with this sense of collaboration.


Previous relevant Colouring In Drag and Drop Settings Tutorial is shown below.

Colouring In Drag and Drop Settings Tutorial

Colouring In Drag and Drop Settings Tutorial

Onto the start for our Colouring In web application via yesterday’s Colouring In Canvas Clone of Numbers Guessing Game Tutorial we’re starting to enhance, on top of that “clone level” functionality, via two new settings with two approaches to the management of data, regarding, those being …

  • number of table cells across (that programmatically is made to be the same number of cells, as down) … we deal with via a get ? (or &) address line URL arrangement … whereas …
  • pen “width” can be 1 or 2 (where 2 colours in the 1+8=9 surrounding cells of a dragged over cell) … we deal with via a hashtag arrangement

Why the difference in approach? Let’s start with hashtag methodologies. This arrangement can leave everything about a webpage, in place, regarding the user actions on a webpage, while the Javascript can detect that change in …


location.hash

… dynamically. In other words some dragging canvas drawings with pen “width” 2 can be combined with some using pen “width” 1 in the same user creation.

But when the data management involves get ? (or &) address line URL arrangements, this involves navigation to a new incarnation of the webpage creation logic, effectively wiping the webpage slate clean. This is apt for the “number of table cells across” data item, because the HTML content of the table element is not just affected, but is totally structured, according to this user setting.

Lately, more and more, we’ve been hashtagging data to dynamically created “a” link “mailto:” email or “sms:” SMS communication body webpage URL links. An email link or SMS link, from the recipient’s point of view is a “brand new start” that can address either or both of these data conduit arrangements, we’re getting happier and happier to discover …


// ondragover event function code snippet below ...
ev.target.style.backgroundColor='' + document.getElementById('ddcolour').value;
if (decodeURIComponent(('' + location.hash)).indexOf('fontweight=') != -1) {
ifontweight=eval('' + ('' + decodeURIComponent(('' + location.hash))).split('fontweight=')[1].substring(0,1));
}
else if (document.getElementById('numfontweight')) {
ifontweight=eval('' + document.getElementById('numfontweight').value);
}
if (ifontweight == 2) { // colour in 8 surrounding cells, as applicable
var minusthree=-3;
if (document.getElementById('numacross')) {
minusthree=eval(-1 * eval('' + document.getElementById('numacross').value.length));
}
var tdx=eval(('' + ev.target.id).substring(2).split('_')[0].replace(/^0/g,'').replace(/^0/g,''));
var tdy=eval(('' + ev.target.id).split('_')[1].replace(/^0/g,'').replace(/^0/g,''));
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}

if (document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}

if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
}

Codewise …

Did you know?

Our recent Earth Scanner project was conducted during our “Hashtagging Enlightenment Period”, whereby, around here, the …

What the Hep?

… greeting, is code for “Have yourself a happy and fruitful hashtagging day” … but we digress. In amongst it’s code there was an example codeline …


var nontz=('' + location.search + ('' + location.hash).replace(/^\#/g,'')).split('nontz=')[1] ? decodeURIComponent(('' + location.search + ('' + location.hash).replace(/^\#/g,'')).split('nontz=')[1].split('&')[0].split('#')[0]) : '';

… exemplifying, how more and more, we’re happy with setting (or other types of incoming) data coming from get (? and & ( eg. ?nontz=Alice_Springs%7C133.8807%7C_23.6980%7C )) arguments via location.search and/or hashtagged data coming from location.hash ( eg. #nontz=Alice_Springs%7C133.8807%7C_23.6980%7C ) above, either or both, perhaps, used in an email or SMS body URL link.


Previous relevant Colouring In Canvas Clone of Numbers Guessing Game Tutorial is shown below.

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

As the blog posting title suggests, cloned from yesterday’s Numbers Guessing Game Dragover Tutorial

  • Numbers Guessing Game dragover “value add” proof of concept work … comes …
  • Colouring In Canvas drag and (faux) drop web application

… where a “canvas” palette (which is really an HTML table element made up of lots of table cells, rather than an HTML5 canvas element). Why this design? Well, each table cell element can be identified as an individual “dragged over” element. “Dragged over” by what? Well, we turn some “draggable” wording in the basis HTML into …

  • an emoji pen 🖌 piece of text … and next to that we add …
  • an input type=color Colour Picker to choose a pen colour … and because the “ondragover” event is so sensitive, we also add an optionally used, or not …
  • input type=number defining any delay (in seconds) before the “ondragover” colouring in kicks in, from when it could first of happened, as the pen crosses over into the palette … along with …
  • input type=number countdown of the delay
  • … so that the user can use “dragover” event means by which to create their own “colouring in creation”!

    Codewise …


    Previous relevant Numbers Guessing Game Dragover Tutorial is shown below.

    Numbers Guessing Game Dragover Tutorial

    Numbers Guessing Game Dragover Tutorial

    Today we’re honing in on …

    • drag and drop methodology …
    • dragover event … value adding where …
    • drop element(s) are cells of an HTML table element (also a drop element)

    … as our interest. We scouted around for the best “design match” and came up with the arrangements existing when we presented Numbers Guessing Game Tutorial some time ago now.

    And if we succeed with some form of value adding here, we have another idea for the ideas we’re presenting today. Spoiler alert! Yes, it can be made to be useful.

    As such we’ve …

    Added toggleable “show where contemplated” value added border where dragover logic
    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');
    if (isset($_GET['notice'])) {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a></span>', $templategame);
    } else {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a></span>', $templategame);
    }


    ?>
    Tweaked dragover logic

    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    if (ev.target.outerHTML.indexOf('<table') != 0 && ev.target.outerHTML.indexOf(' data-piece="') != -1) {
    if (ev.target.outerHTML.split(' data-piece="')[1].substring(0,1) == (itisthiscmove + ev.target.outerHTML.split(' data-piece="')[1].substring(0,1)).substring(0,1)) {
    lohfulloh=ev.target.outerHTML;
    console.log("LOHfulloh=" + lohfulloh);
    }
    }
    //console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    //if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    // document.title='ev.preventDefault(); //4';
    //}
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (document.getElementById('sdropz')) {
    if (document.getElementById('sdropz').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('sdropz').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('sdropz').innerHTML=document.getElementById('sdropz').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { ev.target.style.border='2px dashed yellow'; }
    }
    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';.id)
    });
    Flag any continued “show where contemplated” interest

    var secsmore='';
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { secsmore='&notice=y'; }

    if (document.URL.indexOf('rjmprogramming-com-au.translate.goog') != -1) {
    location.href=document.URL.split('&score=')[0] + '&score=' + score + '&secs=' + secs + secsmore;
    } else {
    location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs + secsmore;
    }

    … to, as the user requests, add some table cell border enhancements (as our “value adding“) to our tweaked third draft PHP game (helped out by the changed experimental_drag_and_drop.htm Experimental Drag and Drop clientside HTML and Javascript basis), as the user drags the draggable element over the table droppable element and its cohort table cell elements.


    Previous relevant Numbers Guessing Game Tutorial is shown below.

    Numbers Guessing Game Tutorial

    Numbers Guessing Game Tutorial

    We’ve been working on aspects to the genericity of the table that is …

    The Drop Zone

    … do do … do do … do do … do do … do do do do do do do do do do do do … yesterday’s threat “now so yesterday” being …

    • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
    • allow the number of cells across in a column not be 3

    … in a (very difficult) Numbers Guessing game for numbers from 1 to 99 that regular readers may be familiar with as the (same content (and mentioned at this link … thanks …) as the) Numbers Guessing game at this blog, but presented using a Drag and Drop modus operandi.

    Feel free to try our first draft PHP game, which leans on a changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    On your smaller devices we found the Numbers Guessing Game a bit hard to use. As such, we researched and played around with “drag and drop” cursor ideas unsuccessfully to end up, instead, not thinking about the cursor (albeit, we find that idea cuter) but rather styling the target table cell’s background colour and informing the user of that up at the top button wording in our changed second draft PHP game, which leans on our changed experimental_drag_and_drop.htm HTML and Javascript and CSS helper


    var lastbco=null;

    const target = document.querySelector("#target");
    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    }

    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';

    });


    Previous relevant Planet Moon Game Tutorial is shown below.

    Planet Moon Game Tutorial

    Planet Moon Game Tutorial

    Another thing that there is nine of (as contentious as it is regarding Pluto) is Planets in the Solar System, revolving around the Sun. And so, in keeping with a lot of the same design as yesterday’s Enneagram Type Game Tutorial we have a Planet Moon Game to present for you to play around with today.

    Again, PHP uses a framework of Experimental Drag and Drop HTML and Javascript and CSS, mainly via one PHP codeline …

    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');

    ?>

    … and, perhaps, your curiosity that we have not “passed” data via $_GET[] or $_POST[] arguments, but rather just the simple act of …

    • moulding and manipulating (eg. arranging “callback” logic means, as used below) that $templategame “template” for our purposes … nga ha ha ha ha ha ha ha ha … but we digress …
    • simply …
      <?php

      echo $templategame;

      ?>
      … outputs a webpage …
    • and on the way back to play again, we use $_GET[‘score’] and $_GET[‘secs’] (in experimental_drag_and_drop.html HTML and Javascript and CSS game web application) to keep the ball rolling back to the game specific PHP we use …

      location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;

    … in our first draft PHP game, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    We fully concur with any adage that goes …

    You learn most from your mistakes

    … just as we’re curious about “the things that go wrong”, and not having them repeat! Same with pooches!

    Take our first to second draft PHP game (to the opera, would be preferable). We wondered why, occasionally, with the “first draft” it would hang. It took us a half day to realize, as you could yourself have tweaked to a lot quicker if you had followed the adage …


    Hanging issues mostly team up with code within a loop

    The situation, we’ve reasoned, is that we had that PHP $badlist variable store a comma separated list of planets with either zero moons or more than one moon randomly selected representing it. We’d assumed, yesterday, not that we’d put it in words, but in logic, that this list would not (have the same length or) be the same as a (new $goodlist variable) list of planets with either zero moons or selected while collecting the random list of Moon/Planet combinations … ie. we assumed in the list would be a Planet with only one of its Moons randomly selected … mistake!!! Better is …

    <?php

    $goodlist=',Mercury,Venus,';
    $badlist=',Mercury,Venus,';


    while (strlen($goodlist) == strlen($badlist)) {
    $goodlist=',Mercury,Venus,';

    $badlist=',Mercury,Venus,';

    $correctans=rand(0,8);
    $sofar=';';
    for ($i=0; $i<9; $i++) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    if ($crandlist == '') {
    $crandlist='' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else if (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    while (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else {
    if (strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) { $badlist.=$wikidescriptions[$j] . ','; }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    }
    }
    }

    ?>


    Previous relevant Enneagram Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Enneagram Type Game Tutorial

    A lot of us wonder what goes towards making up our personalities. We remember doing a Myers-Briggs test for some job as part of the vetting process. We thought we’d write another experimental drag and drop game, like yesterday’s Australian Street Type Game Tutorial, regarding …

    Enneagram Types

    … of human personalities, and we found a webpage linking these categorizations to Hollywood Movie Stars for you to get the gist of the ideas. We also thank Wikipedia as our source for Movie Star images.

    It being a topic …

    1. beyond our ken
    2. outside our usual subject matter

    … you may be wondering how we stumbled upon the idea? We let Google autocomplete our …


    nine types of

    … search textbox typing, fully expecting “Carol”? to be at the top of the list when we saw …


    nine types of enneagram

    … to flesh out a family of “game interest”, we hope?!

    Our first draft PHP game is also playable below …


    Previous relevant Australian Street Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Australian Street Type Game Tutorial

    The experimental drag and drop theme continues on today, after Experimental Drag and Drop Game Tutorial‘s debut game application, with a Wikipedia inspired “Australian Street Type” game today.

    Huh?! Well, you know those street names that baffle? Or are we easily baffleable?! Anyway, you had to be there. And if you ever feel you’re alone with an interest, just look it up in Wikipedia or Google and you’re almost sure to find out …

    you are not alone

    Yes, our Wikipedia page mentioned Australian Street Type Designations with their lawyerly Australian Street Type Descriptions. Who could ask for more? Well?!

    To make this happen we wrote some PHP, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, or template, to mould and bend towards our purpose … nga ha ha!

    Our first draft PHP game is also playable below …


    Previous relevant Experimental Drag and Drop Game Tutorial is shown below.

    Experimental Drag and Drop Game Tutorial

    Experimental Drag and Drop Game Tutorial

    It can be interesting turning a “concept” (or even a “proof of concept” web application) into an, on the side, “game” web application, and that way, learn what’s possible via user action. This is how we felt about yesterday’s Experimental Drag and Drop Primer Tutorial and that teamed with the wonder about how we could add some useful complexity to our “Experimental Drag and Drop” web application’s …

    Drop Zone

    Can “inheritance” be harnessed to make it work for some complexity of nested HTML elements inside that “Drop Zone” element when the document.body’s onload event happens? We wondered whether a Brady Bunch style 3×3 table could be the go? And whether the nine cells could have a “score” associated with them, and that set of scores be changing over time to make the game more challenging and interesting? Well …

    Yes

    … is the answer regarding making a game out of a proof of concept with our experimental_drag_and_drop.html HTML and Javascript and CSS game web application (also shown below) using these techniques, about which we think some of you readers will be interested?!


    Previous relevant Experimental Drag and Drop Primer Tutorial is shown below.

    Experimental Drag and Drop Primer Tutorial

    Experimental Drag and Drop Primer Tutorial

    We’ve added the word experimental into today’s blog posting title, mainly because our first of two inspirational webpage sources (last modified on 23/02/2023) regarding somewhat alternative “Drag and Drop” functionalities told us, regarding the DataTransfer object informational “DataTransfer” webpage …

    Experimental: This is an experimental technology
    Check the Browser compatibility table carefully before using this in production.

    … but our testing of the methodologies on various platforms hasn’t totally failed yet on any of the several desktop and mobile platform scenarios we’ve tried. On mobile, we just held on for a sustained touch (down) to make it possible. So maybe the industry has caught up with the ideas? We’re hoping so, because “drag and drop” is a kind of natural thing online users think of to do, and people associate it with “getting things done” we reckon.

    Anyway, we relied on the great source code of the second of two inspirational webpages DataTransfer: setData() method, thanks …

    The DataTransfer.setData() method sets the drag operation’s drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type. If data for the given type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.

    … to get us going with our “proof of concept” web application (also shown below) using these techniques, about which we think some of you readers will be interested?!

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

Colouring In Drag and Drop Settings Tutorial

Colouring In Drag and Drop Settings Tutorial

Colouring In Drag and Drop Settings Tutorial

Onto the start for our Colouring In web application via yesterday’s Colouring In Canvas Clone of Numbers Guessing Game Tutorial we’re starting to enhance, on top of that “clone level” functionality, via two new settings with two approaches to the management of data, regarding, those being …

  • number of table cells across (that programmatically is made to be the same number of cells, as down) … we deal with via a get ? (or &) address line URL arrangement … whereas …
  • pen “width” can be 1 or 2 (where 2 colours in the 1+8=9 surrounding cells of a dragged over cell) … we deal with via a hashtag arrangement

Why the difference in approach? Let’s start with hashtag methodologies. This arrangement can leave everything about a webpage, in place, regarding the user actions on a webpage, while the Javascript can detect that change in …


location.hash

… dynamically. In other words some dragging canvas drawings with pen “width” 2 can be combined with some using pen “width” 1 in the same user creation.

But when the data management involves get ? (or &) address line URL arrangements, this involves navigation to a new incarnation of the webpage creation logic, effectively wiping the webpage slate clean. This is apt for the “number of table cells across” data item, because the HTML content of the table element is not just affected, but is totally structured, according to this user setting.

Lately, more and more, we’ve been hashtagging data to dynamically created “a” link “mailto:” email or “sms:” SMS communication body webpage URL links. An email link or SMS link, from the recipient’s point of view is a “brand new start” that can address either or both of these data conduit arrangements, we’re getting happier and happier to discover …


// ondragover event function code snippet below ...
ev.target.style.backgroundColor='' + document.getElementById('ddcolour').value;
if (decodeURIComponent(('' + location.hash)).indexOf('fontweight=') != -1) {
ifontweight=eval('' + ('' + decodeURIComponent(('' + location.hash))).split('fontweight=')[1].substring(0,1));
}
else if (document.getElementById('numfontweight')) {
ifontweight=eval('' + document.getElementById('numfontweight').value);
}
if (ifontweight == 2) { // colour in 8 surrounding cells, as applicable
var minusthree=-3;
if (document.getElementById('numacross')) {
minusthree=eval(-1 * eval('' + document.getElementById('numacross').value.length));
}
var tdx=eval(('' + ev.target.id).substring(2).split('_')[0].replace(/^0/g,'').replace(/^0/g,''));
var tdy=eval(('' + ev.target.id).split('_')[1].replace(/^0/g,'').replace(/^0/g,''));
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(-1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}

if (document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(0 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}

if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(-1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(0 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
if (document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree))) {
document.getElementById('td' + ('000' + eval(1 + tdx)).slice(minusthree) + '_' + ('000' + eval(1 + tdy)).slice(minusthree)).style.backgroundColor='' + document.getElementById('ddcolour').value;
}
}

Codewise …

Did you know?

Our recent Earth Scanner project was conducted during our “Hashtagging Enlightenment Period”, whereby, around here, the …

What the Hep?

… greeting, is code for “Have yourself a happy and fruitful hashtagging day” … but we digress. In amongst it’s code there was an example codeline …


var nontz=('' + location.search + ('' + location.hash).replace(/^\#/g,'')).split('nontz=')[1] ? decodeURIComponent(('' + location.search + ('' + location.hash).replace(/^\#/g,'')).split('nontz=')[1].split('&')[0].split('#')[0]) : '';

… exemplifying, how more and more, we’re happy with setting (or other types of incoming) data coming from get (? and & ( eg. ?nontz=Alice_Springs%7C133.8807%7C_23.6980%7C )) arguments via location.search and/or hashtagged data coming from location.hash ( eg. #nontz=Alice_Springs%7C133.8807%7C_23.6980%7C ) above, either or both, perhaps, used in an email or SMS body URL link.


Previous relevant Colouring In Canvas Clone of Numbers Guessing Game Tutorial is shown below.

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

As the blog posting title suggests, cloned from yesterday’s Numbers Guessing Game Dragover Tutorial

  • Numbers Guessing Game dragover “value add” proof of concept work … comes …
  • Colouring In Canvas drag and (faux) drop web application

… where a “canvas” palette (which is really an HTML table element made up of lots of table cells, rather than an HTML5 canvas element). Why this design? Well, each table cell element can be identified as an individual “dragged over” element. “Dragged over” by what? Well, we turn some “draggable” wording in the basis HTML into …

  • an emoji pen 🖌 piece of text … and next to that we add …
  • an input type=color Colour Picker to choose a pen colour … and because the “ondragover” event is so sensitive, we also add an optionally used, or not …
  • input type=number defining any delay (in seconds) before the “ondragover” colouring in kicks in, from when it could first of happened, as the pen crosses over into the palette … along with …
  • input type=number countdown of the delay
  • … so that the user can use “dragover” event means by which to create their own “colouring in creation”!

    Codewise …


    Previous relevant Numbers Guessing Game Dragover Tutorial is shown below.

    Numbers Guessing Game Dragover Tutorial

    Numbers Guessing Game Dragover Tutorial

    Today we’re honing in on …

    • drag and drop methodology …
    • dragover event … value adding where …
    • drop element(s) are cells of an HTML table element (also a drop element)

    … as our interest. We scouted around for the best “design match” and came up with the arrangements existing when we presented Numbers Guessing Game Tutorial some time ago now.

    And if we succeed with some form of value adding here, we have another idea for the ideas we’re presenting today. Spoiler alert! Yes, it can be made to be useful.

    As such we’ve …

    Added toggleable “show where contemplated” value added border where dragover logic
    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');
    if (isset($_GET['notice'])) {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a></span>', $templategame);
    } else {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a></span>', $templategame);
    }


    ?>
    Tweaked dragover logic

    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    if (ev.target.outerHTML.indexOf('<table') != 0 && ev.target.outerHTML.indexOf(' data-piece="') != -1) {
    if (ev.target.outerHTML.split(' data-piece="')[1].substring(0,1) == (itisthiscmove + ev.target.outerHTML.split(' data-piece="')[1].substring(0,1)).substring(0,1)) {
    lohfulloh=ev.target.outerHTML;
    console.log("LOHfulloh=" + lohfulloh);
    }
    }
    //console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    //if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    // document.title='ev.preventDefault(); //4';
    //}
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (document.getElementById('sdropz')) {
    if (document.getElementById('sdropz').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('sdropz').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('sdropz').innerHTML=document.getElementById('sdropz').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { ev.target.style.border='2px dashed yellow'; }
    }
    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';.id)
    });
    Flag any continued “show where contemplated” interest

    var secsmore='';
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { secsmore='&notice=y'; }

    if (document.URL.indexOf('rjmprogramming-com-au.translate.goog') != -1) {
    location.href=document.URL.split('&score=')[0] + '&score=' + score + '&secs=' + secs + secsmore;
    } else {
    location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs + secsmore;
    }

    … to, as the user requests, add some table cell border enhancements (as our “value adding“) to our tweaked third draft PHP game (helped out by the changed experimental_drag_and_drop.htm Experimental Drag and Drop clientside HTML and Javascript basis), as the user drags the draggable element over the table droppable element and its cohort table cell elements.


    Previous relevant Numbers Guessing Game Tutorial is shown below.

    Numbers Guessing Game Tutorial

    Numbers Guessing Game Tutorial

    We’ve been working on aspects to the genericity of the table that is …

    The Drop Zone

    … do do … do do … do do … do do … do do do do do do do do do do do do … yesterday’s threat “now so yesterday” being …

    • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
    • allow the number of cells across in a column not be 3

    … in a (very difficult) Numbers Guessing game for numbers from 1 to 99 that regular readers may be familiar with as the (same content (and mentioned at this link … thanks …) as the) Numbers Guessing game at this blog, but presented using a Drag and Drop modus operandi.

    Feel free to try our first draft PHP game, which leans on a changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    On your smaller devices we found the Numbers Guessing Game a bit hard to use. As such, we researched and played around with “drag and drop” cursor ideas unsuccessfully to end up, instead, not thinking about the cursor (albeit, we find that idea cuter) but rather styling the target table cell’s background colour and informing the user of that up at the top button wording in our changed second draft PHP game, which leans on our changed experimental_drag_and_drop.htm HTML and Javascript and CSS helper


    var lastbco=null;

    const target = document.querySelector("#target");
    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    }

    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';

    });


    Previous relevant Planet Moon Game Tutorial is shown below.

    Planet Moon Game Tutorial

    Planet Moon Game Tutorial

    Another thing that there is nine of (as contentious as it is regarding Pluto) is Planets in the Solar System, revolving around the Sun. And so, in keeping with a lot of the same design as yesterday’s Enneagram Type Game Tutorial we have a Planet Moon Game to present for you to play around with today.

    Again, PHP uses a framework of Experimental Drag and Drop HTML and Javascript and CSS, mainly via one PHP codeline …

    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');

    ?>

    … and, perhaps, your curiosity that we have not “passed” data via $_GET[] or $_POST[] arguments, but rather just the simple act of …

    • moulding and manipulating (eg. arranging “callback” logic means, as used below) that $templategame “template” for our purposes … nga ha ha ha ha ha ha ha ha … but we digress …
    • simply …
      <?php

      echo $templategame;

      ?>
      … outputs a webpage …
    • and on the way back to play again, we use $_GET[‘score’] and $_GET[‘secs’] (in experimental_drag_and_drop.html HTML and Javascript and CSS game web application) to keep the ball rolling back to the game specific PHP we use …

      location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;

    … in our first draft PHP game, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    We fully concur with any adage that goes …

    You learn most from your mistakes

    … just as we’re curious about “the things that go wrong”, and not having them repeat! Same with pooches!

    Take our first to second draft PHP game (to the opera, would be preferable). We wondered why, occasionally, with the “first draft” it would hang. It took us a half day to realize, as you could yourself have tweaked to a lot quicker if you had followed the adage …


    Hanging issues mostly team up with code within a loop

    The situation, we’ve reasoned, is that we had that PHP $badlist variable store a comma separated list of planets with either zero moons or more than one moon randomly selected representing it. We’d assumed, yesterday, not that we’d put it in words, but in logic, that this list would not (have the same length or) be the same as a (new $goodlist variable) list of planets with either zero moons or selected while collecting the random list of Moon/Planet combinations … ie. we assumed in the list would be a Planet with only one of its Moons randomly selected … mistake!!! Better is …

    <?php

    $goodlist=',Mercury,Venus,';
    $badlist=',Mercury,Venus,';


    while (strlen($goodlist) == strlen($badlist)) {
    $goodlist=',Mercury,Venus,';

    $badlist=',Mercury,Venus,';

    $correctans=rand(0,8);
    $sofar=';';
    for ($i=0; $i<9; $i++) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    if ($crandlist == '') {
    $crandlist='' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else if (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    while (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else {
    if (strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) { $badlist.=$wikidescriptions[$j] . ','; }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    }
    }
    }

    ?>


    Previous relevant Enneagram Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Enneagram Type Game Tutorial

    A lot of us wonder what goes towards making up our personalities. We remember doing a Myers-Briggs test for some job as part of the vetting process. We thought we’d write another experimental drag and drop game, like yesterday’s Australian Street Type Game Tutorial, regarding …

    Enneagram Types

    … of human personalities, and we found a webpage linking these categorizations to Hollywood Movie Stars for you to get the gist of the ideas. We also thank Wikipedia as our source for Movie Star images.

    It being a topic …

    1. beyond our ken
    2. outside our usual subject matter

    … you may be wondering how we stumbled upon the idea? We let Google autocomplete our …


    nine types of

    … search textbox typing, fully expecting “Carol”? to be at the top of the list when we saw …


    nine types of enneagram

    … to flesh out a family of “game interest”, we hope?!

    Our first draft PHP game is also playable below …


    Previous relevant Australian Street Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Australian Street Type Game Tutorial

    The experimental drag and drop theme continues on today, after Experimental Drag and Drop Game Tutorial‘s debut game application, with a Wikipedia inspired “Australian Street Type” game today.

    Huh?! Well, you know those street names that baffle? Or are we easily baffleable?! Anyway, you had to be there. And if you ever feel you’re alone with an interest, just look it up in Wikipedia or Google and you’re almost sure to find out …

    you are not alone

    Yes, our Wikipedia page mentioned Australian Street Type Designations with their lawyerly Australian Street Type Descriptions. Who could ask for more? Well?!

    To make this happen we wrote some PHP, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, or template, to mould and bend towards our purpose … nga ha ha!

    Our first draft PHP game is also playable below …


    Previous relevant Experimental Drag and Drop Game Tutorial is shown below.

    Experimental Drag and Drop Game Tutorial

    Experimental Drag and Drop Game Tutorial

    It can be interesting turning a “concept” (or even a “proof of concept” web application) into an, on the side, “game” web application, and that way, learn what’s possible via user action. This is how we felt about yesterday’s Experimental Drag and Drop Primer Tutorial and that teamed with the wonder about how we could add some useful complexity to our “Experimental Drag and Drop” web application’s …

    Drop Zone

    Can “inheritance” be harnessed to make it work for some complexity of nested HTML elements inside that “Drop Zone” element when the document.body’s onload event happens? We wondered whether a Brady Bunch style 3×3 table could be the go? And whether the nine cells could have a “score” associated with them, and that set of scores be changing over time to make the game more challenging and interesting? Well …

    Yes

    … is the answer regarding making a game out of a proof of concept with our experimental_drag_and_drop.html HTML and Javascript and CSS game web application (also shown below) using these techniques, about which we think some of you readers will be interested?!


    Previous relevant Experimental Drag and Drop Primer Tutorial is shown below.

    Experimental Drag and Drop Primer Tutorial

    Experimental Drag and Drop Primer Tutorial

    We’ve added the word experimental into today’s blog posting title, mainly because our first of two inspirational webpage sources (last modified on 23/02/2023) regarding somewhat alternative “Drag and Drop” functionalities told us, regarding the DataTransfer object informational “DataTransfer” webpage …

    Experimental: This is an experimental technology
    Check the Browser compatibility table carefully before using this in production.

    … but our testing of the methodologies on various platforms hasn’t totally failed yet on any of the several desktop and mobile platform scenarios we’ve tried. On mobile, we just held on for a sustained touch (down) to make it possible. So maybe the industry has caught up with the ideas? We’re hoping so, because “drag and drop” is a kind of natural thing online users think of to do, and people associate it with “getting things done” we reckon.

    Anyway, we relied on the great source code of the second of two inspirational webpages DataTransfer: setData() method, thanks …

    The DataTransfer.setData() method sets the drag operation’s drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type. If data for the given type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.

    … to get us going with our “proof of concept” web application (also shown below) using these techniques, about which we think some of you readers will be interested?!

    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

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

Colouring In Canvas Clone of Numbers Guessing Game Tutorial

As the blog posting title suggests, cloned from yesterday’s Numbers Guessing Game Dragover Tutorial

  • Numbers Guessing Game dragover “value add” proof of concept work … comes …
  • Colouring In Canvas drag and (faux) drop web application

… where a “canvas” palette (which is really an HTML table element made up of lots of table cells, rather than an HTML5 canvas element). Why this design? Well, each table cell element can be identified as an individual “dragged over” element. “Dragged over” by what? Well, we turn some “draggable” wording in the basis HTML into …

  • an emoji pen 🖌 piece of text … and next to that we add …
  • an input type=color Colour Picker to choose a pen colour … and because the “ondragover” event is so sensitive, we also add an optionally used, or not …
  • input type=number defining any delay (in seconds) before the “ondragover” colouring in kicks in, from when it could first of happened, as the pen crosses over into the palette … along with …
  • input type=number countdown of the delay
  • … so that the user can use “dragover” event means by which to create their own “colouring in creation”!

    Codewise …


    Previous relevant Numbers Guessing Game Dragover Tutorial is shown below.

    Numbers Guessing Game Dragover Tutorial

    Numbers Guessing Game Dragover Tutorial

    Today we’re honing in on …

    • drag and drop methodology …
    • dragover event … value adding where …
    • drop element(s) are cells of an HTML table element (also a drop element)

    … as our interest. We scouted around for the best “design match” and came up with the arrangements existing when we presented Numbers Guessing Game Tutorial some time ago now.

    And if we succeed with some form of value adding here, we have another idea for the ideas we’re presenting today. Spoiler alert! Yes, it can be made to be useful.

    As such we’ve …

    Added toggleable “show where contemplated” value added border where dragover logic
    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');
    if (isset($_GET['notice'])) {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a></span>', $templategame);
    } else {
    $templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a></span>', $templategame);
    }


    ?>
    Tweaked dragover logic

    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    if (ev.target.outerHTML.indexOf('<table') != 0 && ev.target.outerHTML.indexOf(' data-piece="') != -1) {
    if (ev.target.outerHTML.split(' data-piece="')[1].substring(0,1) == (itisthiscmove + ev.target.outerHTML.split(' data-piece="')[1].substring(0,1)).substring(0,1)) {
    lohfulloh=ev.target.outerHTML;
    console.log("LOHfulloh=" + lohfulloh);
    }
    }
    //console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    //if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    // document.title='ev.preventDefault(); //4';
    //}
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (document.getElementById('sdropz')) {
    if (document.getElementById('sdropz').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('sdropz').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('sdropz').innerHTML=document.getElementById('sdropz').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { ev.target.style.border='2px dashed yellow'; }
    }
    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';.id)
    });
    Flag any continued “show where contemplated” interest

    var secsmore='';
    if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { secsmore='&notice=y'; }

    if (document.URL.indexOf('rjmprogramming-com-au.translate.goog') != -1) {
    location.href=document.URL.split('&score=')[0] + '&score=' + score + '&secs=' + secs + secsmore;
    } else {
    location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs + secsmore;
    }

    … to, as the user requests, add some table cell border enhancements (as our “value adding“) to our tweaked third draft PHP game (helped out by the changed experimental_drag_and_drop.htm Experimental Drag and Drop clientside HTML and Javascript basis), as the user drags the draggable element over the table droppable element and its cohort table cell elements.


    Previous relevant Numbers Guessing Game Tutorial is shown below.

    Numbers Guessing Game Tutorial

    Numbers Guessing Game Tutorial

    We’ve been working on aspects to the genericity of the table that is …

    The Drop Zone

    … do do … do do … do do … do do … do do do do do do do do do do do do … yesterday’s threat “now so yesterday” being …

    • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
    • allow the number of cells across in a column not be 3

    … in a (very difficult) Numbers Guessing game for numbers from 1 to 99 that regular readers may be familiar with as the (same content (and mentioned at this link … thanks …) as the) Numbers Guessing game at this blog, but presented using a Drag and Drop modus operandi.

    Feel free to try our first draft PHP game, which leans on a changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    On your smaller devices we found the Numbers Guessing Game a bit hard to use. As such, we researched and played around with “drag and drop” cursor ideas unsuccessfully to end up, instead, not thinking about the cursor (albeit, we find that idea cuter) but rather styling the target table cell’s background colour and informing the user of that up at the top button wording in our changed second draft PHP game, which leans on our changed experimental_drag_and_drop.htm HTML and Javascript and CSS helper


    var lastbco=null;

    const target = document.querySelector("#target");
    target.addEventListener("dragover", (ev) => {
    if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
    console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
    ev.preventDefault();
    if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
    //document.getElementById(sourceid).style.opacity='0.6';
    lastbco=ev.target;
    ev.target.style.backgroundColor='pink';
    if (document.getElementById('mybut')) {
    if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
    document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
    } else {
    document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
    }
    }
    }

    //document.getElementById(sourceid).style.cursor='progress';
    //ev.target.style.cursor='progress';
    //ev.target.dataTransfer.dropEffect = 'progress';

    });


    Previous relevant Planet Moon Game Tutorial is shown below.

    Planet Moon Game Tutorial

    Planet Moon Game Tutorial

    Another thing that there is nine of (as contentious as it is regarding Pluto) is Planets in the Solar System, revolving around the Sun. And so, in keeping with a lot of the same design as yesterday’s Enneagram Type Game Tutorial we have a Planet Moon Game to present for you to play around with today.

    Again, PHP uses a framework of Experimental Drag and Drop HTML and Javascript and CSS, mainly via one PHP codeline …

    <?php

    $templategame=file_get_contents('./experimental_drag_and_drop.htm');

    ?>

    … and, perhaps, your curiosity that we have not “passed” data via $_GET[] or $_POST[] arguments, but rather just the simple act of …

    • moulding and manipulating (eg. arranging “callback” logic means, as used below) that $templategame “template” for our purposes … nga ha ha ha ha ha ha ha ha … but we digress …
    • simply …
      <?php

      echo $templategame;

      ?>
      … outputs a webpage …
    • and on the way back to play again, we use $_GET[‘score’] and $_GET[‘secs’] (in experimental_drag_and_drop.html HTML and Javascript and CSS game web application) to keep the ball rolling back to the game specific PHP we use …

      location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;

    … in our first draft PHP game, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, is also playable below …

    Stop Press

    We fully concur with any adage that goes …

    You learn most from your mistakes

    … just as we’re curious about “the things that go wrong”, and not having them repeat! Same with pooches!

    Take our first to second draft PHP game (to the opera, would be preferable). We wondered why, occasionally, with the “first draft” it would hang. It took us a half day to realize, as you could yourself have tweaked to a lot quicker if you had followed the adage …


    Hanging issues mostly team up with code within a loop

    The situation, we’ve reasoned, is that we had that PHP $badlist variable store a comma separated list of planets with either zero moons or more than one moon randomly selected representing it. We’d assumed, yesterday, not that we’d put it in words, but in logic, that this list would not (have the same length or) be the same as a (new $goodlist variable) list of planets with either zero moons or selected while collecting the random list of Moon/Planet combinations … ie. we assumed in the list would be a Planet with only one of its Moons randomly selected … mistake!!! Better is …

    <?php

    $goodlist=',Mercury,Venus,';
    $badlist=',Mercury,Venus,';


    while (strlen($goodlist) == strlen($badlist)) {
    $goodlist=',Mercury,Venus,';

    $badlist=',Mercury,Venus,';

    $correctans=rand(0,8);
    $sofar=';';
    for ($i=0; $i<9; $i++) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    if ($crandlist == '') {
    $crandlist='' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else if (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    while (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
    $j=rand(0, (-1 + sizeof($wikidesignations)));
    }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    } else {
    if (strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) { $badlist.=$wikidescriptions[$j] . ','; }
    $crandlist.=',' . $j;
    $sofar.=$wikidescriptions[$j] . ';';
    if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
    }
    }
    }

    ?>


    Previous relevant Enneagram Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Enneagram Type Game Tutorial

    A lot of us wonder what goes towards making up our personalities. We remember doing a Myers-Briggs test for some job as part of the vetting process. We thought we’d write another experimental drag and drop game, like yesterday’s Australian Street Type Game Tutorial, regarding …

    Enneagram Types

    … of human personalities, and we found a webpage linking these categorizations to Hollywood Movie Stars for you to get the gist of the ideas. We also thank Wikipedia as our source for Movie Star images.

    It being a topic …

    1. beyond our ken
    2. outside our usual subject matter

    … you may be wondering how we stumbled upon the idea? We let Google autocomplete our …


    nine types of

    … search textbox typing, fully expecting “Carol”? to be at the top of the list when we saw …


    nine types of enneagram

    … to flesh out a family of “game interest”, we hope?!

    Our first draft PHP game is also playable below …


    Previous relevant Australian Street Type Game Tutorial is shown below.

    Australian Street Type Game Tutorial

    Australian Street Type Game Tutorial

    The experimental drag and drop theme continues on today, after Experimental Drag and Drop Game Tutorial‘s debut game application, with a Wikipedia inspired “Australian Street Type” game today.

    Huh?! Well, you know those street names that baffle? Or are we easily baffleable?! Anyway, you had to be there. And if you ever feel you’re alone with an interest, just look it up in Wikipedia or Google and you’re almost sure to find out …

    you are not alone

    Yes, our Wikipedia page mentioned Australian Street Type Designations with their lawyerly Australian Street Type Descriptions. Who could ask for more? Well?!

    To make this happen we wrote some PHP, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, or template, to mould and bend towards our purpose … nga ha ha!

    Our first draft PHP game is also playable below …


    Previous relevant Experimental Drag and Drop Game Tutorial is shown below.

    Experimental Drag and Drop Game Tutorial

    Experimental Drag and Drop Game Tutorial

    It can be interesting turning a “concept” (or even a “proof of concept” web application) into an, on the side, “game” web application, and that way, learn what’s possible via user action. This is how we felt about yesterday’s Experimental Drag and Drop Primer Tutorial and that teamed with the wonder about how we could add some useful complexity to our “Experimental Drag and Drop” web application’s …

    Drop Zone

    Can “inheritance” be harnessed to make it work for some complexity of nested HTML elements inside that “Drop Zone” element when the document.body’s onload event happens? We wondered whether a Brady Bunch style 3×3 table could be the go? And whether the nine cells could have a “score” associated with them, and that set of scores be changing over time to make the game more challenging and interesting? Well …

    Yes

    … is the answer regarding making a game out of a proof of concept with our experimental_drag_and_drop.html HTML and Javascript and CSS game web application (also shown below) using these techniques, about which we think some of you readers will be interested?!


    Previous relevant Experimental Drag and Drop Primer Tutorial is shown below.

    Experimental Drag and Drop Primer Tutorial

    Experimental Drag and Drop Primer Tutorial

    We’ve added the word experimental into today’s blog posting title, mainly because our first of two inspirational webpage sources (last modified on 23/02/2023) regarding somewhat alternative “Drag and Drop” functionalities told us, regarding the DataTransfer object informational “DataTransfer” webpage …

    Experimental: This is an experimental technology
    Check the Browser compatibility table carefully before using this in production.

    … but our testing of the methodologies on various platforms hasn’t totally failed yet on any of the several desktop and mobile platform scenarios we’ve tried. On mobile, we just held on for a sustained touch (down) to make it possible. So maybe the industry has caught up with the ideas? We’re hoping so, because “drag and drop” is a kind of natural thing online users think of to do, and people associate it with “getting things done” we reckon.

    Anyway, we relied on the great source code of the second of two inspirational webpages DataTransfer: setData() method, thanks …

    The DataTransfer.setData() method sets the drag operation’s drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type. If data for the given type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.

    … to get us going with our “proof of concept” web application (also shown below) using these techniques, about which we think some of you readers will be interested?!

    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

Numbers Guessing Game Dragover Tutorial

Numbers Guessing Game Dragover Tutorial

Numbers Guessing Game Dragover Tutorial

Today we’re honing in on …

  • drag and drop methodology …
  • dragover event … value adding where …
  • drop element(s) are cells of an HTML table element (also a drop element)

… as our interest. We scouted around for the best “design match” and came up with the arrangements existing when we presented Numbers Guessing Game Tutorial some time ago now.

And if we succeed with some form of value adding here, we have another idea for the ideas we’re presenting today. Spoiler alert! Yes, it can be made to be useful.

As such we’ve …

Added toggleable “show where contemplated” value added border where dragover logic
<?php

$templategame=file_get_contents('./experimental_drag_and_drop.htm');
if (isset($_GET['notice'])) {
$templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a></span>', $templategame);
} else {
$templategame=str_replace('>-</span>', '><a style="text-decoration:none;cursor:pointer;" title="Show where contemplated as well." onclick="location.href=' . "'#notice=y'" . ';">+</a><a style="text-decoration:none;cursor:pointer;" title="Stop showing where contemplated as well." onclick="location.href=' . "'#no_tice=y'" . ';">-</a></span>', $templategame);
}


?>
Tweaked dragover logic

target.addEventListener("dragover", (ev) => {
if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
if (ev.target.outerHTML.indexOf('<table') != 0 && ev.target.outerHTML.indexOf(' data-piece="') != -1) {
if (ev.target.outerHTML.split(' data-piece="')[1].substring(0,1) == (itisthiscmove + ev.target.outerHTML.split(' data-piece="')[1].substring(0,1)).substring(0,1)) {
lohfulloh=ev.target.outerHTML;
console.log("LOHfulloh=" + lohfulloh);
}
}
//console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
//if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
// document.title='ev.preventDefault(); //4';
//}
ev.preventDefault();
if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
//document.getElementById(sourceid).style.opacity='0.6';
lastbco=ev.target;
ev.target.style.backgroundColor='pink';
if (document.getElementById('mybut')) {
if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
} else {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
}
}
if (document.getElementById('sdropz')) {
if (document.getElementById('sdropz').innerHTML.indexOf(' .. ') == -1) {
document.getElementById('sdropz').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
} else {
document.getElementById('sdropz').innerHTML=document.getElementById('sdropz').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
}
}
if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { ev.target.style.border='2px dashed yellow'; }
}
//document.getElementById(sourceid).style.cursor='progress';
//ev.target.style.cursor='progress';
//ev.target.dataTransfer.dropEffect = 'progress';.id)
});
Flag any continued “show where contemplated” interest

var secsmore='';
if (('' + document.URL + decodeURIComponent('' + location.hash)).indexOf('notice=') != -1 && ('' + decodeURIComponent('' + location.hash)).indexOf('no_tice=') == -1) { secsmore='&notice=y'; }

if (document.URL.indexOf('rjmprogramming-com-au.translate.goog') != -1) {
location.href=document.URL.split('&score=')[0] + '&score=' + score + '&secs=' + secs + secsmore;
} else {
location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs + secsmore;
}

… to, as the user requests, add some table cell border enhancements (as our “value adding“) to our tweaked third draft PHP game (helped out by the changed experimental_drag_and_drop.htm Experimental Drag and Drop clientside HTML and Javascript basis), as the user drags the draggable element over the table droppable element and its cohort table cell elements.


Previous relevant Numbers Guessing Game Tutorial is shown below.

Numbers Guessing Game Tutorial

Numbers Guessing Game Tutorial

We’ve been working on aspects to the genericity of the table that is …

The Drop Zone

… do do … do do … do do … do do … do do do do do do do do do do do do … yesterday’s threat “now so yesterday” being …

  • allow for the number of table cells to be other than 9 (with Animal Mineral Vegetable Game Tutorial where it is 3 in total) … and today …
  • allow the number of cells across in a column not be 3

… in a (very difficult) Numbers Guessing game for numbers from 1 to 99 that regular readers may be familiar with as the (same content (and mentioned at this link … thanks …) as the) Numbers Guessing game at this blog, but presented using a Drag and Drop modus operandi.

Feel free to try our first draft PHP game, which leans on a changed experimental_drag_and_drop.htm HTML and Javascript and CSS game web application basis, is also playable below …

Stop Press

On your smaller devices we found the Numbers Guessing Game a bit hard to use. As such, we researched and played around with “drag and drop” cursor ideas unsuccessfully to end up, instead, not thinking about the cursor (albeit, we find that idea cuter) but rather styling the target table cell’s background colour and informing the user of that up at the top button wording in our changed second draft PHP game, which leans on our changed experimental_drag_and_drop.htm HTML and Javascript and CSS helper


var lastbco=null;

const target = document.querySelector("#target");
target.addEventListener("dragover", (ev) => {
if (lastbco) { lastbco.style.backgroundColor='white'; lastbco=null; }
console.log("dragOver " + ev.target.id + ' ' + ('' + ev.target.style.backgroundColor).replace('white','') + ' ' + document.body.innerHTML.indexOf('tab' + 'lece' + 'llb' + 'c'));
ev.preventDefault();
if (('' + ev.target.id).indexOf('td') == 0 && ('' + ev.target.style.backgroundColor).trim().replace('white','') == '' && document.body.innerHTML.indexOf('Numbe' + 'rs Guessi' + 'ng Ga' + 'me') != -1) {
//document.getElementById(sourceid).style.opacity='0.6';
lastbco=ev.target;
ev.target.style.backgroundColor='pink';
if (document.getElementById('mybut')) {
if (document.getElementById('mybut').innerHTML.indexOf(' .. ') == -1) {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.replace(' Game Game', ' Game');
document.getElementById('mybut').innerHTML+=' .. current guess is ' + ev.target.innerHTML;
} else {
document.getElementById('mybut').innerHTML=document.getElementById('mybut').innerHTML.split(' .. ')[0] + ' .. current guess is ' + ev.target.innerHTML;
}
}
}

//document.getElementById(sourceid).style.cursor='progress';
//ev.target.style.cursor='progress';
//ev.target.dataTransfer.dropEffect = 'progress';

});


Previous relevant Planet Moon Game Tutorial is shown below.

Planet Moon Game Tutorial

Planet Moon Game Tutorial

Another thing that there is nine of (as contentious as it is regarding Pluto) is Planets in the Solar System, revolving around the Sun. And so, in keeping with a lot of the same design as yesterday’s Enneagram Type Game Tutorial we have a Planet Moon Game to present for you to play around with today.

Again, PHP uses a framework of Experimental Drag and Drop HTML and Javascript and CSS, mainly via one PHP codeline …

<?php

$templategame=file_get_contents('./experimental_drag_and_drop.htm');

?>

… and, perhaps, your curiosity that we have not “passed” data via $_GET[] or $_POST[] arguments, but rather just the simple act of …

  • moulding and manipulating (eg. arranging “callback” logic means, as used below) that $templategame “template” for our purposes … nga ha ha ha ha ha ha ha ha … but we digress …
  • simply …
    <?php

    echo $templategame;

    ?>
    … outputs a webpage …
  • and on the way back to play again, we use $_GET[‘score’] and $_GET[‘secs’] (in experimental_drag_and_drop.html HTML and Javascript and CSS game web application) to keep the ball rolling back to the game specific PHP we use …

    location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;

… in our first draft PHP game, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, is also playable below …

Stop Press

We fully concur with any adage that goes …

You learn most from your mistakes

… just as we’re curious about “the things that go wrong”, and not having them repeat! Same with pooches!

Take our first to second draft PHP game (to the opera, would be preferable). We wondered why, occasionally, with the “first draft” it would hang. It took us a half day to realize, as you could yourself have tweaked to a lot quicker if you had followed the adage …


Hanging issues mostly team up with code within a loop

The situation, we’ve reasoned, is that we had that PHP $badlist variable store a comma separated list of planets with either zero moons or more than one moon randomly selected representing it. We’d assumed, yesterday, not that we’d put it in words, but in logic, that this list would not (have the same length or) be the same as a (new $goodlist variable) list of planets with either zero moons or selected while collecting the random list of Moon/Planet combinations … ie. we assumed in the list would be a Planet with only one of its Moons randomly selected … mistake!!! Better is …

<?php

$goodlist=',Mercury,Venus,';
$badlist=',Mercury,Venus,';


while (strlen($goodlist) == strlen($badlist)) {
$goodlist=',Mercury,Venus,';

$badlist=',Mercury,Venus,';

$correctans=rand(0,8);
$sofar=';';
for ($i=0; $i<9; $i++) {
$j=rand(0, (-1 + sizeof($wikidesignations)));
if ($crandlist == '') {
$crandlist='' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
} else if (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
while (strpos((',' . $crandlist . ','), (',' . $j . ',')) !== false) { // || strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) {
$j=rand(0, (-1 + sizeof($wikidesignations)));
}
$crandlist.=',' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
} else {
if (strpos($sofar, ';' . $wikidescriptions[$j] . ';') !== false) { $badlist.=$wikidescriptions[$j] . ','; }
$crandlist.=',' . $j;
$sofar.=$wikidescriptions[$j] . ';';
if (strpos($goodlist, $wikidescriptions[$j]) === false) { $goodlist.=$wikidescriptions[$j] . ','; }
}
}
}

?>


Previous relevant Enneagram Type Game Tutorial is shown below.

Australian Street Type Game Tutorial

Enneagram Type Game Tutorial

A lot of us wonder what goes towards making up our personalities. We remember doing a Myers-Briggs test for some job as part of the vetting process. We thought we’d write another experimental drag and drop game, like yesterday’s Australian Street Type Game Tutorial, regarding …

Enneagram Types

… of human personalities, and we found a webpage linking these categorizations to Hollywood Movie Stars for you to get the gist of the ideas. We also thank Wikipedia as our source for Movie Star images.

It being a topic …

  1. beyond our ken
  2. outside our usual subject matter

… you may be wondering how we stumbled upon the idea? We let Google autocomplete our …


nine types of

… search textbox typing, fully expecting “Carol”? to be at the top of the list when we saw …


nine types of enneagram

… to flesh out a family of “game interest”, we hope?!

Our first draft PHP game is also playable below …


Previous relevant Australian Street Type Game Tutorial is shown below.

Australian Street Type Game Tutorial

Australian Street Type Game Tutorial

The experimental drag and drop theme continues on today, after Experimental Drag and Drop Game Tutorial‘s debut game application, with a Wikipedia inspired “Australian Street Type” game today.

Huh?! Well, you know those street names that baffle? Or are we easily baffleable?! Anyway, you had to be there. And if you ever feel you’re alone with an interest, just look it up in Wikipedia or Google and you’re almost sure to find out …

you are not alone

Yes, our Wikipedia page mentioned Australian Street Type Designations with their lawyerly Australian Street Type Descriptions. Who could ask for more? Well?!

To make this happen we wrote some PHP, which leans on a changed experimental_drag_and_drop.html HTML and Javascript and CSS game web application basis, or template, to mould and bend towards our purpose … nga ha ha!

Our first draft PHP game is also playable below …


Previous relevant Experimental Drag and Drop Game Tutorial is shown below.

Experimental Drag and Drop Game Tutorial

Experimental Drag and Drop Game Tutorial

It can be interesting turning a “concept” (or even a “proof of concept” web application) into an, on the side, “game” web application, and that way, learn what’s possible via user action. This is how we felt about yesterday’s Experimental Drag and Drop Primer Tutorial and that teamed with the wonder about how we could add some useful complexity to our “Experimental Drag and Drop” web application’s …

Drop Zone

Can “inheritance” be harnessed to make it work for some complexity of nested HTML elements inside that “Drop Zone” element when the document.body’s onload event happens? We wondered whether a Brady Bunch style 3×3 table could be the go? And whether the nine cells could have a “score” associated with them, and that set of scores be changing over time to make the game more challenging and interesting? Well …

Yes

… is the answer regarding making a game out of a proof of concept with our experimental_drag_and_drop.html HTML and Javascript and CSS game web application (also shown below) using these techniques, about which we think some of you readers will be interested?!


Previous relevant Experimental Drag and Drop Primer Tutorial is shown below.

Experimental Drag and Drop Primer Tutorial

Experimental Drag and Drop Primer Tutorial

We’ve added the word experimental into today’s blog posting title, mainly because our first of two inspirational webpage sources (last modified on 23/02/2023) regarding somewhat alternative “Drag and Drop” functionalities told us, regarding the DataTransfer object informational “DataTransfer” webpage …

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

… but our testing of the methodologies on various platforms hasn’t totally failed yet on any of the several desktop and mobile platform scenarios we’ve tried. On mobile, we just held on for a sustained touch (down) to make it possible. So maybe the industry has caught up with the ideas? We’re hoping so, because “drag and drop” is a kind of natural thing online users think of to do, and people associate it with “getting things done” we reckon.

Anyway, we relied on the great source code of the second of two inspirational webpages DataTransfer: setData() method, thanks …

The DataTransfer.setData() method sets the drag operation’s drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type. If data for the given type already exists, the existing data is replaced in the same position. That is, the order of the types list is not changed when replacing data of the same type.

… to get us going with our “proof of concept” web application (also shown below) using these techniques, about which we think some of you readers will be interested?!

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

Find Number Game Clues Tutorial

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('//') >= 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('//') >= 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.

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