Audio Card Background Image Quality Tutorial

Audio Card Background Image Quality Tutorial

Audio Card Background Image Quality Tutorial

This current project may be about YouTube basis “audio cards”, but inevitably, if we offer background image possibilities, some users may turn it’s functionality, more, into a “postcard” feeling presentation. But, with yesterday’s Audio Card Circular Wording Text Tutorial only a much restricted range of image elements could be handled because of the amount of data involved, whether that be because of …

  • density of pixels … and/or …
  • dimensions … for instance, a Take Photo dimension on our iPhone results in an image of more than 3000×2000 … which is not going to fly

… and so, except for GIFs we reduce to JPEGs of potentially lower quality via the HTML5 canvas ( ie. <canvas id=canvaselement style=display:none;></canvas> ) using …


function reduceimsize() {
var imgl=new Image();


imgl.onload = function() {
var c = document.getElementById('canvaselement'); //querySelector('canvas'), // see Example 4
var factor=1.0;
var propw=eval('' + imgl.width);
var proph=eval('' + imgl.height);
while (propw > 1000 || proph > 1000) {
propw=eval(0.9 * propw);
proph=eval(0.9 * proph);
}
c.width = propw;
c.height = proph;
var ctx = c.getContext('2d');
if (propw == eval('' + imgl.width) && proph == eval('' + imgl.height)) {
ctx.drawImage(imgl, 0, 0);
} else {
ctx.drawImage(imgl, 0, 0, eval('' + imgl.width), eval('' + imgl.height), 0, 0, propw, proph);
}
twocontocont=c.toDataURL('image/jpeg',0.5).replace(";base64,",";charset=utf-8;base64,").replace(/^daXta:image\/(png|jpg|jpeg);base64,/, "");
document.getElementById('background').value=twocontocont;
};


imgl.src = twocontocont;
}

… allowing for many more image scenarios, including the iPhone Camera app “Take Photo” one, to start working. Bit more like a “postcard” now?!

We also thought the one mandatory textbox should be up the top, and so we made that happen, today.

And for the first time we can remember we handled some yellow background colour to the “clicking” parts of the form’s left hand side, via …


<div id=divyellow style=z-index:-456;background-color:yellow;></div>

… accessed via document.body “onload” event logic …


<body onload='checkdiv(); setInterval(checkdiv,10000);'>

… calling …


function checkdiv() {
var trrect=document.getElementById('oversee').getBoundingClientRect();
var mrrect=document.getElementById('cbi').getBoundingClientRect();
var bbrect=document.getElementById('bab').getBoundingClientRect();
document.getElementById('divyellow').style.position='absolute';
document.getElementById('divyellow').style.top='' + eval(-3 + trrect.top) + 'px';
document.getElementById('divyellow').style.left='' + eval(-3 + trrect.left) + 'px';
document.getElementById('divyellow').style.width='' + eval(6 + mrrect.width) + 'px';
document.getElementById('divyellow').style.height='' + eval(6 + eval(bbrect.bottom - trrect.top)) + 'px';
}

… the overlayunderlay hugely negative CSS z-index property the key to its aesthetic, but no other (as pleases us greatly), talents, in our third draft audio_card.html Audio Card creator.

Oddly, an earlier more straightforward approach of involving an HTML table element to this idea stuffed up the alignment of the created Audio Cards … very odd?!


Previous relevant Audio Card Circular Wording Text Tutorial is shown below.

Audio Card Circular Wording Text Tutorial

Audio Card Circular Wording Text Tutorial

Yesterday’s Audio Card Primer Tutorial offered a means of delimiting any optional Audio Card text wording as entered by the user, but as of today it means more because …

  • we start supplying a YouTube supplied title as the wording more often (ie. until you ever use the keyboard in that topmost textbox, detected via the onkeydown event) … though when this happens the is usually not there … and so …
  • when the user adds in a delimiter to the Audio Card wording text, that now …
  • results in any prefixing wording parts before the be shown as Circular Text … and regarding the circle that creates …
  • any background image will apply to, in order of priority …
    1. the circle, as above, background image … or …
    2. body background image

… and, for your auditory learners with a slight visual “bent”, maybe that background imagery could be an animated GIF (which can be an aid to concentration, we find, if the right style of animated GIF is selected … we found today’s presentation one at https://au.pinterest.com/pin/316096467588365493/, thanks). Might sound strange, but preparing for a trip, aren’t you more interested in the auditory advice, rather than spoiling the anticipation seeing everything ahead of actually seeing it … hopefully!?

So this second draft audio_card.html Audio Card creator helped out by a changed circular_text.html inhouse Circular Text assistant is definitely worth a revisit.


Previous relevant Audio Card Primer Tutorial is shown below.

Audio Card Primer Tutorial

Audio Card Primer Tutorial

We’re starting a new project today. It’s not a “postcard” today, it’s an “audio card”, building on those “in place” YouTube (audio stream of) video referencing links of class “audioytplay” we talked about recently with External Javascript YouTube Audio of Video Numericals Tutorial.

The external Javascript of that project can help out here in amongst the hashtag organized sharing mechanisms there for …

  • Email 📧
  • SMS 📟
  • Iframe (below) ⬇

… sharing means. What the user is asked for to create this online “audio card” is …

  • a mandatory YouTube video 11 character ID (whose audio stream, only, will be playable for the user or communication recipient) …
    1. optional start (in seconds) of an audio (stream of video) snippet
    2. optional end (in seconds) of an audio (stream of video) snippet
  • optional “audio card” wording
  • optional “audio card” background image

… appearing in this “proof of concept” first draft Audio Card creator helped out by the changed karaoke_youtube_api.htm inhouse YouTube video interfacer.

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

Audio Card Circular Wording Text Tutorial

Audio Card Circular Wording Text Tutorial

Audio Card Circular Wording Text Tutorial

Yesterday’s Audio Card Primer Tutorial offered a means of delimiting any optional Audio Card text wording as entered by the user, but as of today it means more because …

  • we start supplying a YouTube supplied title as the wording more often (ie. until you ever use the keyboard in that topmost textbox, detected via the onkeydown event) … though when this happens the is usually not there … and so …
  • when the user adds in a delimiter to the Audio Card wording text, that now …
  • results in any prefixing wording parts before the be shown as Circular Text … and regarding the circle that creates …
  • any background image will apply to, in order of priority …
    1. the circle, as above, background image … or …
    2. body background image

… and, for your auditory learners with a slight visual “bent”, maybe that background imagery could be an animated GIF (which can be an aid to concentration, we find, if the right style of animated GIF is selected … we found today’s presentation one at https://au.pinterest.com/pin/316096467588365493/, thanks). Might sound strange, but preparing for a trip, aren’t you more interested in the auditory advice, rather than spoiling the anticipation seeing everything ahead of actually seeing it … hopefully!?

So this second draft audio_card.html Audio Card creator helped out by a changed circular_text.html inhouse Circular Text assistant is definitely worth a revisit.


Previous relevant Audio Card Primer Tutorial is shown below.

Audio Card Primer Tutorial

Audio Card Primer Tutorial

We’re starting a new project today. It’s not a “postcard” today, it’s an “audio card”, building on those “in place” YouTube (audio stream of) video referencing links of class “audioytplay” we talked about recently with External Javascript YouTube Audio of Video Numericals Tutorial.

The external Javascript of that project can help out here in amongst the hashtag organized sharing mechanisms there for …

  • Email 📧
  • SMS 📟
  • Iframe (below) ⬇

… sharing means. What the user is asked for to create this online “audio card” is …

  • a mandatory YouTube video 11 character ID (whose audio stream, only, will be playable for the user or communication recipient) …
    1. optional start (in seconds) of an audio (stream of video) snippet
    2. optional end (in seconds) of an audio (stream of video) snippet
  • optional “audio card” wording
  • optional “audio card” background image

… appearing in this “proof of concept” first draft Audio Card creator helped out by the changed karaoke_youtube_api.htm inhouse YouTube video interfacer.

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

Audio Card Primer Tutorial

Audio Card Primer Tutorial

Audio Card Primer Tutorial

We’re starting a new project today. It’s not a “postcard” today, it’s an “audio card”, building on those “in place” YouTube (audio stream of) video referencing links of class “audioytplay” we talked about recently with External Javascript YouTube Audio of Video Numericals Tutorial.

The external Javascript of that project can help out here in amongst the hashtag organized sharing mechanisms there for …

  • Email 📧
  • SMS 📟
  • Iframe (below) ⬇

… sharing means. What the user is asked for to create this online “audio card” is …

  • a mandatory YouTube video 11 character ID (whose audio stream, only, will be playable for the user or communication recipient) …
    1. optional start (in seconds) of an audio (stream of video) snippet
    2. optional end (in seconds) of an audio (stream of video) snippet
  • optional “audio card” wording
  • optional “audio card” background image

… appearing in this “proof of concept” first draft Audio Card creator helped out by the changed karaoke_youtube_api.htm inhouse YouTube video interfacer.

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

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

Code Download Table Static HTML Event Definition Tutorial

Code Download Table Static HTML Event Definition Tutorial

Code Download Table Static HTML Event Definition Tutorial

Yesterday’s Code Download Table Long Hover and Right Click Tutorial used a means of …

  • creating some new, and not used previously, Javascript webpage event logics dynamically … but we’ve found, especially regarding the oncontextmenu event logics that way, it’s asking less of the webpage to, instead, and if possible …
  • create new, and not used previously, Javascript webpage event logics within the static HTML code defining that webpage

… and you’ve probably guessed in the case of our inhouse Code Download Table, it’s contents happen, once a day, in a scheduled crontab/curl arrangement, via a PHP script, and so this transference of workload is a matter of …

  • in the external Javascript, leave it seeing whether it’s efforts are required, but now use if codeline checks to cool it should …
  • within the PHP creator of HTML webpage content has already set up some/all of these event logic definitions within the static webpage HTML (which is serving to improve webpage performance)

… which is checkable via the scrutiny of an HTML element’s outerHTML (not so much an attribute as a) guise using Javascript DOM syntax …


setTimeout(function(){
var asis=document.getElementsByTagName('a');
for (var iasis=0; iasis<asis.length; iasis++) {
if (('' + asis[iasis].title).indexOf('lick/tap') == -1 && ('' + asis[iasis].href) != '' && asis[iasis].innerHTML != '.') {
if (asis[iasis].outerHTML.indexOf(' oncontextmenu=') == -1) {
asis[iasis].oncontextmenu=function(event){ onrightclickask(event); };
}

if (('' + asis[iasis].href + '~').indexOf('/' + asis[iasis].innerHTML + '~') != -1) {
if (('' + document.body.title) == '') {
document.body.title='Please note that for column 2 links Long Hover of 10 seconds and Right click functionalities can apply ';
}
if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
asis[iasis].title+=' Click/tap navigates to ' + asis[iasis].href + ' ... and please note Long Hover of 10 seconds and Right click functionalities can apply for this link ';
} else {
asis[iasis].title+=' Click/tap navigates to ' + asis[iasis].href + ' ... and please note Spread or Pinch gesture functionalities can apply for this link ';
}
} else {
if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
asis[iasis].title+=' Click/tap navigates to ' + asis[iasis].href + ' ... and please note Long Hover of 10 seconds and Right click functionalities can apply for this link ';
} else {
asis[iasis].title+=' Click/tap navigates to ' + asis[iasis].href + ' ... and please note Spread or Pinch gesture functionalities can apply for this link ';
}
}
asis[iasis].onmouseout=function(event){ startcounter=0; event.target.setAttribute('data-ston','y'); if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } };
asis[iasis].onmouseover=function(event){ if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'y') { event.target.setAttribute('data-ston','Y'); startcounter=1; } if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == '') { event.target.setAttribute('data-ston','y'); startcounter=1; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ' '; event.target.setAttribute('data-ston','Y'); } setInterval(function(){ if (startcounter > 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'Y') { startcounter++; event.target.title+=' '; if (startcounter >= 10) { event.target.getAttribute('data-ston','y'); startcounter=0; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } window.open(event.target.href,'_blank','top=50,left=150,width=600,height=600'); } } }, 1000); } };
} else if (('' + asis[iasis].title).indexOf('lick/tap navigates to ') == -1) {
asis[iasis].title=' Click/tap navigates to ' + asis[iasis].href;
}
} else if (asis[iasis].innerHTML == '.' && ('' + asis[iasis].id + ' ').substring(0,2) == 'ah') {
if (asis[iasis].outerHTML.indexOf(' oncontextmenu=') == -1) {
asis[iasis].oncontextmenu=function(event){ population_at_date(event); };
}

if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
asis[iasis].title+=' Click/tap navigates to ' + asis[iasis].href + ' ... and please note World Population click functionalities can apply for this link ';
} else {
asis[iasis].title+=' Click/tap navigates to ' + asis[iasis].href + ' ... and please note World Population tap functionalities can apply for this link ';
}
} else if (('' + asis[iasis].title).indexOf('lick/tap navigates to ') == -1 && ('' + asis[iasis].href) != '') {
asis[iasis].oncontextmenu=function(event){ onrightclickask(event); };
if (('' + asis[iasis].href + '~').indexOf('/' + asis[iasis].innerHTML + '~') != -1) {
if (('' + document.body.title) == '') {
document.body.title='Please note that for column 2 links Long Hover of 10 seconds and Right click functionalities can apply ';
}
if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
asis[iasis].title+=' ... Click/tap navigates to ' + asis[iasis].href + ' ... and please note Long Hover of 10 seconds and Right click functionalities can apply for this link ';
} else {
asis[iasis].title+=' ... Click/tap navigates to ' + asis[iasis].href + ' ... and please note Spread or Pinch gesture functionalities can apply for this link ';
}
asis[iasis].onmouseout=function(event){ startcounter=0; event.target.setAttribute('data-ston','y'); if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } };
asis[iasis].onmouseover=function(event){ if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'y') { event.target.setAttribute('data-ston','Y'); startcounter=1; } if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == '') { event.target.setAttribute('data-ston','y'); startcounter=1; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ' '; event.target.setAttribute('data-ston','Y'); } setInterval(function(){ if (startcounter > 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'Y') { startcounter++; event.target.title+=' '; if (startcounter >= 10) { event.target.getAttribute('data-ston','y'); startcounter=0; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } window.open(event.target.href,'_blank','top=50,left=150,width=600,height=600'); } } }, 1000); } };
} else if (('' + asis[iasis].title).indexOf('lick/tap navigates to ') == -1) {
asis[iasis].title+=' ... Click/tap navigates to ' + asis[iasis].href;
}
}
}
}, 5000); // was 12000

We’ve also taken this rearrangement possibility to add some new quirky onmousedown and ontouchdown (events separate to onclick) event logic to the decimal point “a” links in column 1 guesstimating World Populations at that point of time of that code’s creation/modification date thanks to United Nations, Department of Economic and Social Affairs, Population Division (2024) World Population Prospects 2024, Online Edition in our changed getmelist.js external Javascript code file which goes towards the make up of our inhouse Code Download Table better constructed now via our changed getmelist.php.


Previous relevant Code Download Table Long Hover and Right Click Tutorial is shown below.

Code Download Table Long Hover and Right Click Tutorial

Code Download Table Long Hover and Right Click Tutorial

We’re revisiting the inhouse Code Download Table mentioned in Code Download Table Difference Functional Hover Tutorial and in the time between postings we’ve noticed new functionality to try to achieve, and new methods to get to that functionality, and new ways to do that functionality.

When adding new functionality, unless it has to interface to older functionalities, why risk those older working functionalities, if it’s possible to introduce …

event independent methodologies

… relating to event types not within the scope of the older working work? With this in mind, we’ve introduced …

  • non-mobile oncontextmenu (ie. right click)
  • non-mobile “inhouse long hover (of 10 seconds)” (ie. combination of onmouseover and onmouseout)
  • mobile ontouchend (ie. spread or pinch gesture)

… isolated in scope to the column 2 GETME “a” links, via …


setTimeout(function(){
var asis=document.getElementsByTagName('a');
for (var iasis=0; iasis<asis.length; iasis++) {
if (('' + asis[iasis].title) == '' && ('' + asis[iasis].href) != '') {
asis[iasis].title='Click/tap navigates to ' + asis[iasis].href;
asis[iasis].oncontextmenu=function(event){ onrightclickask(event); };
if (('' + asis[iasis].href + '~').indexOf('/' + asis[iasis].innerHTML + '~') != -1) {
asis[iasis].onmouseout=function(event){ startcounter=0; event.target.setAttribute('data-ston','y'); if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } };
asis[iasis].onmouseover=function(event){ if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'y') { event.target.setAttribute('data-ston','Y'); startcounter=1; } if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == '') { event.target.setAttribute('data-ston','y'); startcounter=1; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ' '; event.target.setAttribute('data-ston','Y'); } setInterval(function(){ if (startcounter > 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'Y') { startcounter++; event.target.title+=' '; if (startcounter >= 10) { event.target.getAttribute('data-ston','y'); startcounter=0; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } window.open(event.target.href,'_blank','top=50,left=150,width=600,height=600'); } } }, 1000); } };
}
} else if (('' + asis[iasis].title).indexOf('lick/tap navigates to ') == -1 && ('' + asis[iasis].href) != '') {
asis[iasis].title+=' ... Click/tap navigates to ' + asis[iasis].href;
asis[iasis].oncontextmenu=function(event){ onrightclickask(event); };
if (('' + asis[iasis].href + '~').indexOf('/' + asis[iasis].innerHTML + '~') != -1) {
asis[iasis].onmouseout=function(event){ startcounter=0; event.target.setAttribute('data-ston','y'); if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } };
asis[iasis].onmouseover=function(event){ if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'y') { event.target.setAttribute('data-ston','Y'); startcounter=1; } if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == '') { event.target.setAttribute('data-ston','y'); startcounter=1; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ' '; event.target.setAttribute('data-ston','Y'); } setInterval(function(){ if (startcounter > 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'Y') { startcounter++; event.target.title+=' '; if (startcounter >= 10) { event.target.getAttribute('data-ston','y'); startcounter=0; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } window.open(event.target.href,'_blank','top=50,left=150,width=600,height=600'); } } }, 1000); } };
}
}
}
}, 5000); // was 12000

function onrightclickask(evt) {
// <a target="_blank" title="1.html_GETME ... Click/tap navigates to https://www.rjmprogramming.com.au/NetBeans/HTML5/BackBone/public_html/1.html_GETME" href="NetBeans/HTML5/BackBone/public_html/1.html_GETME">1.html_GETME</a>
// <a target="_blank" title="Breadcrumb tag (may not be found)" href="//www.rjmprogramming.com.au/wordpress/?tag=NetBeans">NetBeans</a>
if (('' + evt.target.href + '~').indexOf('/' + evt.target.innerHTML + '~') != -1) {
//alert('Right click detected for ' + evt.target.href + '~ finding /' + evt.target.innerHTML + '~');
//var sx=prompt('https://www.rjmprogramming.com.au/PHP/Geographicals/diff.php?one=' + encodeURIComponent(evt.target.href) + '&two=' + encodeURIComponent(evt.target.href), 'https://www.rjmprogramming.com.au/PHP/Geographicals/diff.php?one=' + encodeURIComponent(evt.target.href) + '&two=' + encodeURIComponent(evt.target.href));
if (evt.target.innerHTML.indexOf('-GETME') != -1) {
setTimeout(function(){ window.open('//www.rjmprogramming.com.au/PHP/Geographicals/diff.php?one=' + ('//' + evt.target.href.split('//')[1]) + '#&two=' + ('//' + evt.target.href.split('//')[1]),'_blank','top=60,left=160,width=600,height=600'); }, 4000);
} else {
setTimeout(function(){ window.open(('//' + evt.target.href.split('//')[1]) + '#&two=' + ('//' + evt.target.href.split('//')[1]),'_blank','top=40,left=140,width=600,height=600'); }, 4000);
}
}
}

if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
setTimeout(function(){
document.ontouchend=function(e){
if (e.target.outerHTML.indexOf('<a ') == 0) {
if (('' + e.target.href + '~').indexOf('/' + e.target.innerHTML + '~') != -1) {
onrightclickask(e);
}
}
};
}, 4000);
}

… in our changed getmelist.js external Javascript code file which go to make up part of our inhouse Code Download Table.


Previous relevant Code Download Table Difference Functional Hover Tutorial is shown below.

Code Download Table Difference Functional Hover Tutorial

Code Download Table Difference Functional Hover Tutorial

Is it worth adding “onmouseover” event logic onto yesterday’s Code Download Table Difference Functional Linking Tutorial? You bet it is! Just because “onmouseover” has no relevance to mobile platforms, so, obversely, developing software with version control systems is irrelevant to mobile platforms.

a place for everything and everything in its place

… we figure. But this is of relevance to the programmer. Sometimes, rather than cater for all the platforms, settling on a subset (of those platforms) can be apt because …

  • one of mobile or non-mobile subsets of platforms is irrelevant to the scenario … as for today … or …
  • you try to reinvent the wheel on the pretext that you are waiting for a particular web browser or platform to allow the functionality in, into the future … you could be waiting a while, with the complexity of app arrangements going on around the net these days

Anyway, back to the “onmouseover” event on non-mobile platforms … it was the case that this event was a favourite for the conduit towards Ajax (client) functionality. And thinking on what we do today to nuance our Code Differences PHP web application, we were thinking …

What would Ajax (like to) do?

… and we decided Ajax would really like to …

  • populate a “div” style=display:inline-block; element adjacent to the functional detail to inform about … but this was not possible … so, instead, we …
  • populate a popup window near to the functional detail to inform about

… for a non-mobile “hover” (ie. “onmouseover”) event.

Along the way we add some more hashtag navigations and set up more colour coding to the output of (the optional) “functional links” Code Difference reporting.

So take a look at our changed diff.php Code Differences helper applied to itself below …


Previous relevant Code Download Table Multiple Row Email Report Tutorial is shown below.

Code Download Table Multiple Row Email Report Tutorial

Code Download Table Multiple Row Email Report Tutorial

Before leaving yesterday’s Download and Copy or Move Code Download Table Tutorial extensions to our Code Download Table functionality …

  • add copy onto a download functionality to the Code Download Table … today, we …
  • add a Multiple Row selection basis for a personalized Email Report for the user

… as we saw that there was scope for this as a sharing mechanism for project discussions and ideas, we hope.

Today’s tutorial picture tries to show the steps to emailing off a report of interest to a user …

  1. User clicks the “Allow Multiple Row Clicks” checkbox …

    prefixask=prefixask.replace('</div>', '<div id=divawrc style=display:inline-block;>  Allow Multiple Row Clicks <input onchange="domrows();" id=awrc style=inline-block; type=checkbox></input> <div id=dawrc style=display:inline-block;></div></div></div>');

    … which causes …
  2. “Report” button shows to its right …

    function domrows() {
    document.getElementById('dawrc').innerHTML='<input style=inline-block; type=button onclick=treportdo(); value=Report></input>';
    var trsis=document.getElementsByTagName('tr');
    for (var itrsis=0; itrsis<trsis.length; itrsis++) {
    trsis[itrsis].onclick = function(e) { if (e.target.innerHTML != '') { var trs=document.getElementsByTagName('tr'); for (var itrs=0; itrs<trs.length; itrs++) { if (trs[itrs].outerHTML.indexOf(e.target.innerHTML) != -1) { trs[itrs].style.border='2px dotted red'; } } } };
    }
    }

    … and table row onclick logic is dynamically applied to those “tr” elements
  3. User clicks somewhere within rows they are interested in seeing be included in a report (which is a snippet of the whole Code Download Table, perhaps to do with a project of interest, or a learning topic of interest)
  4. User optionally clicks the “Report” button …

    function treportdo() {
    var trsis=document.getElementsByTagName('tr');
    webc='<html><head><script type="text/javascript"> function emailto(eto) { window.opener.parentemailto(eto); } function xemailto(eto) { if (eto.indexOf("@") != -1) { var zhr=new XMLHttpRequest(); var zform=new FormData(); zform.append("inline",""); zform.append("to",eto); zform.append("subj","Code Download Table part"); zform.append("body",document.getElementById("mytable").outerHTML); zhr.open("post", "//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php", true); zhr.send(zform); alert("Email sent to " + eto); } } </script></head><body><table id=mytable></table><br><br><br><input onblur=emailto(this.value); placeholder="Email to" type=email></input></body></html>';
    for (var itrsis=0; itrsis<trsis.length; itrsis++) {
    if (itrsis == 0) {
    webc=webc.replace('</table>', trsis[itrsis].outerHTML + '</table>');
    }
    if (trsis[itrsis].outerHTML.indexOf('>') > trsis[itrsis].outerHTML.indexOf('border:')) {
    if (trsis[itrsis].outerHTML.indexOf('dotted') > trsis[itrsis].outerHTML.indexOf('border:')) {
    webc=webc.replace('</table>', trsis[itrsis].outerHTML + '</table>');
    }
    }
    }
    var woois=window.open('','_blank','top=20,left=20,width=600,height=600');
    woois.document.write(webc);
    }

    … which causes a …
  5. New popup window opens showing the relevant snippet of Code Download Table of interest to the user … including …
  6. Textbox for an optional emailee entry that can be filled in … to …
  7. Set off Ajax/FormData methodology means …

    function parentemailto(eto) {
    if (eto.indexOf("@") != -1) {
    var zhr=new XMLHttpRequest();
    var zform=new FormData();
    zform.append("inline","");
    zform.append("to",eto);
    zform.append("subj","RJM Programming Code Download Table part");
    zform.append("body", reltoabs('<table' + webc.split('</table>')[0].split('<table')[1] + '</table>'));
    zhr.open("post", "//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php", true);
    zhr.send(zform);
    alert("Email sent to " + eto);
    }
    }

    … to send off an Inline HTML Email report to the emailee … including …
  8. Links of email can be clicked to get back to source code and other links back at the RJM Programming domain web server

… in our changed getmelist.js external Javascript code file (that you can try out for yourself at this live run link).


Previous relevant Download and Copy or Move Code Download Table Tutorial is shown below.

Download and Copy or Move Code Download Table Tutorial

Download and Copy or Move Code Download Table Tutorial

After the “goings on” with the relatively recent PHP Blog Summary Fixed Title Events Tutorial we thought we were finished with “Code Download Table” functionality … but then …

along came Jones yesterday’s Download and Copy or Move Server Tutorial

… and … lo and behold … we saw a good use for the idea of …

  1. download from “the net” to a Downloads folder on your computer or device … and more often than not …
  2. you, the user, copies or renames this data to another location on your computer or device with command line or with operating system GUI

… and allowing for that second step above be programmatical with the most apt functionality that had ever passed our cotton pickin’ mind … our Code Download Table … wi’ all tho’ GETME’s!

But we don’t want to interfere too much with the Code Download Table “flow” here, so create up the top left 20 seconds worth of time (extendable by their actions) available to the user to create “download” attributes on all …

  • “a” links … with …
  • “href” attribute containing “GETME” …
  • but not “diff.php” … and …
  • “download” attribute (the attribute necessary to “download” rather than our default displaying of source code in a new webpage)

… plus no href attribute containing “?s=” either, for today’s purposes with a changed getmelist.js external Javascript code file (that you can try out for yourself at this live run link) … via its new …


var dnprefix=decodeURIComponent(('' + localStorage.getItem('download_copy_to_folder')).replace(/^null$/g,'')); //.replace(/\+/g,' ').replace(/\\\\/g, '_').replace(/\//g, '_').replace(/\:/g, '_');
var delaymore=0;
var prefixask='<div id=firstask style="position:absolute;top:0px;left:0px;"> Download GETME? <input id=dpccb style=inline-block; type=checkbox onchange="dogetmes(document.getElementById(' + "'" + 'dpcis' + "'" + ').value);"></input> <input style=inline-block;width:300px; onclick="delaymore+=20000;" onblur="if (document.getElementById(' + "'" + 'dpccb' + "'" + ').checked) { dogetmes(document.getElementById(this.value); }" type=text id=dpcis placeholder="Optional Download Folder Later Copy to Place via Listener" value="' + dnprefix + '"></input></div>';

function dogetmes(dpprefix) {
delaymore+=20000;
var asis=document.getElementsByTagName('a');
if (dpprefix != dnprefix && 1 == 7) {
localStorage.setItem('download_copy_to_folder', dpprefix);
}
for (var iasis=0; iasis<asis.length; iasis++) {
if (asis[iasis].href.indexOf('diff.php') == -1 && asis[iasis].href.indexOf('?s=') == -1 && asis[iasis].href.indexOf('GETME') != -1) {
asis[iasis].download=dpprefix.replace(/\//g,'_').replace(/\\\\/g,'_').replace(/\:/g,'_') + asis[iasis].href.split('/')[eval(-1 + asis[iasis].href.split('/').length)];
}
}
}

function nomorepa() {
if (eval('' + delaymore) == 0) {
if (document.getElementById('firstask')) {
document.getElementById('firstask').innerHTML='';
}
} else {
setTimeout(nomorepa, eval('' + delaymore));
delaymore=0;
}
}

function lastdivpop() {
var wasih='';
if (document.getElementById('lastdiv')) {
if (document.getElementById('lastdiv').innerHTML == '') {
wasih=wasih;
setTimeout(lastdivpop, 3000);
} else if (document.getElementById('lastdiv').innerHTML.indexOf('firstask') == -1) {
wasih=document.getElementById('lastdiv').innerHTML;
document.getElementById('lastdiv').innerHTML=prefixask + wasih;
prefixask='';
setTimeout(nomorepa, 20000);
} else {
setTimeout(lastdivpop, 3000);
}
}
}

setTimeout(lastdivpop, 8000);


Previous relevant Download and Copy or Move Server Tutorial is shown below.

Download and Copy or Move Server Tutorial

Download and Copy or Move Server Tutorial

Yesterday’s Download and Copy or Move Primer Tutorial was all about the “client side” of …

… and we’ve just “tweaked” (albeit, very importantly, in our books (… but the pamphlettes are still not playing ball)) to ensure no “file clobbering” takes place so that the Korn Shell now does …


suf=""
isuf=-1
while [ -f "${dpath}/${brest}${suf}" ]; do
((isuf=isuf+1))
suf="_${isuf}"
done
if [ ! -z "$suf" ]; then
echo "mv ${dpath}/${brest} ${dpath}/${brest}${suf} # `date`" >> download_to_place.out
mv ${dpath}/${brest} ${dpath}/${brest}${suf} >> download_to_place.out 2>> download_to_place.err
fi

… in download_copier.ksh download_copier.ksh Korn Shell scripting on our macOS operating system “client”.

But today is mainly about filling in the missing bits on the “server” side. This (need for a) “conduit” we referred to yesterday is because we accept no folder paths can be mentioned at the “server” end. Suppose, though, that the “non-pathed” filename we supply to an “a” link’s “download” attribute can be prefixed by a mildly mashed up version of that path we copy to from the Downloads folder of your “client” computer or device, as you perform a “download” via the clicking of an “a” link.

Well, at this blog we’d already started functionality to toggle the use or not of …

  • “a” links … with …
  • “href” attribute containing “GETME” …
  • but not “diff.php” … and …
  • “download” attribute (the attribute necessary to “download” rather than our default displaying of source code in a new webpage)

Were you here, then, when we published WordPress Blog Download Mode Toggler Primer Tutorial (or were you indisposed again?!) There we established an “All Posts” menu “Toggle Download Mode from GETME” option piece of functionality to toggle between …

  • displaying of source code in a new webpage for GETME “a” links … versus …
  • use the changed PHP toggle_download.php in conjunction with a changed good ‘ol TwentyTen Theme header.php as below …
    <?php

    if (outs == null) {
    var dnprefix=decodeURIComponent(('' + localStorage.getItem('download_copy_to_folder')).replace(/^null$/g,'')).replace(/\+/g,' ').replace(/\\\\/g, '_').replace(/\//g, '_').replace(/\:/g, '_');
    for (idmjk=0; idmjk<admjk.length; idmjk++) {
    if (admjk[idmjk].href.indexOf('GETME') != -1 && admjk[idmjk].href.indexOf('diff.php') == -1) {

    if (origcafd < 0) { //!cafd) {
    xp=admjk[idmjk].href.split("GETME");
    prexp=xp[0].split("/");
    postprexp=prexp[-1 + prexp.length].split(".");
    extis = postprexp[-1 + postprexp.length].replace(/_/g,"").replace(/-/g,"").replace(/GETME/g,"");
    outs="//www.rjmprogramming.com.au/getmelist.htm?topoff=150&tsp=" + (Math.floor(Math.random() * 1999900) + 100) + "#" + postprexp[0] + "." + postprexp[-1 + postprexp.length].replace(extis,"").replace(extis,"").replace(extis,"") + "GETME" + extis;
    aorig=admjk[idmjk].innerHTML;
    admjk[idmjk].innerHTML=admjk[idmjk].innerHTML.replace(".","<span data-alt='" + outs + "' id='spn" + cafd + "' title=\" + Code Download Table\" onclick=\"if (cafd == cafd) { cafd=" + cafd + "; changeasfordownload(); } else { window.open('" + outs + "','_blank','top=100,left=100,width=500,height=500'); } return false; \">⚫</span>");
    if (aorig == admjk[idmjk].innerHTML && admjk[idmjk].innerHTML.indexOf('er posts') == -1) admjk[idmjk].innerHTML=admjk[idmjk].innerHTML.replace(" ","<span data-alt='" + outs + "' id='spn" + cafd + "' title=\" + Code Download Table\" onclick=\"if (cafd == cafd) { cafd=" + cafd + "; changeasfordownload(); } else { window.open('" + outs + "','_blank','top=100,left=100,width=500,height=500'); } return false; \">⚪</span>");
    cafd++;
    } else {
    prestuffs = admjk[idmjk].href.split('/');
    newaspare = admjk[idmjk].href.replace('_-GETME', '').replace('__GETME', '').replace('_GETME', '').replace(big, '');

    while (big.indexOf('-') != -1) {

    big = big.replace('-', '');

    newaspare = newaspare.replace(big, '');

    }

    big = '----------------------GETME';
    stuffs = newaspare.split('/');
    if (dnprefix != '') {
    admjk[idmjk].download = dnprefix + prestuffs[stuffs.length - 1];
    } else {

    admjk[idmjk].download = dnprefix + stuffs[stuffs.length - 1];
    }
    admjk[idmjk].title = "(Really download) " + admjk[idmjk].title + ' ... welcome to the long hover functionality that shows allows for a Download Mode for the blog that can be toggled';
    admjk[idmjk].onmouseover = " getDownloadMode(); ";
    admjk[idmjk].onmouseout = " yehBut(); ";
    admjk[idmjk].ontouchstart = " getDownloadMode(); ";
    admjk[idmjk].ontouchend = " yehBut(); ";
    }
    } else if (admjk[idmjk].href.indexOf('GETME') != -1 && origcafd < 0) { //!cafd) {
    xp=admjk[idmjk].href.split("GETME");
    prexp=xp[0].split("/");
    postprexp=prexp[-1 + prexp.length].split(".");
    extis = postprexp[-1 + postprexp.length].replace(/_/g,"").replace(/-/g,"").replace(/GETME/g,"");
    outs="//www.rjmprogramming.com.au/getmelist.htm?topoff=150&tsp=" + (Math.floor(Math.random() * 1999900) + 100) + "#" + postprexp[0] + "." + postprexp[-1 + postprexp.length].replace(extis,"").replace(extis,"").replace(extis,"") + "GETME" + extis;
    aorig=admjk[idmjk].innerHTML;
    selbitis=allthecombos((admjk[idmjk].href + '=').split('=')[1].split('&')[0]);
    admjk[idmjk].innerHTML=admjk[idmjk].innerHTML.replace(".","<span data-alt='" + outs + "' id='spn" + cafd + "' title=\" + Code Download Table\" onclick=\"if (cafd == cafd) { cafd=" + cafd + "; changeasfordownload(); } else { window.open('" + outs + "','_blank','top=100,left=100,width=500,height=500'); } return false; \"><select onchange=\" if (this.value.length > 0) { window.open(this.value,'_blank'); } return false; \" style='margin-bottom:0px;width:40px;' id='sel" + cafd + "'><option value=>⚫</option>" + selbitis + "</select></span>");
    if (aorig == admjk[idmjk].innerHTML && admjk[idmjk].innerHTML.indexOf('er posts') == -1) admjk[idmjk].innerHTML=admjk[idmjk].innerHTML.replace(" ","<span data-alt='" + outs + "' id='spn" + cafd + "' title=\" + Code Download Table\" onclick=\"if (cafd == cafd) { cafd=" + cafd + "; changeasfordownload(); } else { window.open('" + outs + "','_blank','top=100,left=100,width=500,height=500'); } return false; \"><select onchange=\" if (this.value.length > 0) { window.open(this.value,'_blank'); } return false; \" style='margin-bottom:0px;width:40px;' id='sel" + cafd + "'><option value=>⚪</option>" + selbitis + "</select></span>");
    cafd++;
    } else if ((admjk[idmjk].innerHTML.indexOf('live run') != -1 || admjk[idmjk].title.toLowerCase().indexOf('click picture') != -1) && origcafd < 0) { //!cafd) {
    outs="//www.rjmprogramming.com.au/slideshow.html#tuts";
    admjk[idmjk].innerHTML=admjk[idmjk].innerHTML.replace(" ","<span data-alt='" + outs + "' id='spn" + cafd + "' title=\" + Cut to the Chase ... see the blog post list related to live runs and slideshows ... ie. the main point of the blog posting\" onclick=\"if (cafd == cafd) { cafd=" + cafd + "; changeasfordownload(); } else { window.open('" + outs + "','_blank','top=100,left=100,width=650,height=100'); } return false; \">✂</span>");
    cafd++;
    }
    }
    }

    ?>
    … to, depending on whether the user specifies in the “All Posts” toggling’s Javascript prompt window presented, specifies a new comma separated “client folder of interest to copy to” place (stored in window.localStorage), will …

    1. download with the GETME to the Downloads folder and copy off to the specified folder of interest (backing up as necessary) … versus …
    2. the default download mode downloads to the Downloads folder without the GETME parts

See these changes in action below, contextualizing “server” and “client” codes in the full picture of assisted Downloads (copied on to a folder of the user’s interest) …


Previous relevant Download and Copy or Move Primer Tutorial is shown below.

Download and Copy or Move Primer Tutorial

Download and Copy or Move Primer Tutorial

Downloading from “the net” (“server land”) to your computer or device (“client land”) is a big part of the online experience and the sharing of data over the world wide web. But have you ever wondered about the two step design of …

  1. download from “the net” to a Downloads folder on your computer or device … and more often than not …
  2. you, the user, copies or renames this data to another location on your computer or device with command line or with operating system GUI

… ? Why not allow the “server” side define where it can download to on the “client”? Well, that would be a security nightmare, allowing a highjacking of mission critical files on your computer or device. So, I get it, that is a “no no”. But could we have a controlled “arrangement” between …

… ? We think that sounds reasonable and so, today, we start our (two parts or more) mini-project (making step 2 above be considered to be programmatically handled, sometimes) designing a Korn Shell (“client” side) listener to suit our macOS “client” computer, executed as a background process via …


ksh download_copier.ksh &

But what is the conduit, if the “server” web applications/pages cannot define a destination folder other than the macOS Downloads folder for the user involved? Well, that is where we need either …

… to define a “client land” folder to copy to (from the user’s Download folder (receiving the downloaded data).

That first Korn Shell read command interactive input was interesting to us for a command backgrounded via the “&” command suffix. But if stdin and stdout are not mentioned in the command you can answer this interactive input and then the processing the Korn Shell performs proceeds in the background. Exactly what we were hoping for, but weren’t sure that this was the case!

The picture is filled in better tomorrow as we discuss the conduit in more detail 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.

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

Code Download Table Long Hover and Right Click Tutorial

Code Download Table Long Hover and Right Click Tutorial

Code Download Table Long Hover and Right Click Tutorial

We’re revisiting the inhouse Code Download Table mentioned in Code Download Table Difference Functional Hover Tutorial and in the time between postings we’ve noticed new functionality to try to achieve, and new methods to get to that functionality, and new ways to do that functionality.

When adding new functionality, unless it has to interface to older functionalities, why risk those older working functionalities, if it’s possible to introduce …

event independent methodologies

… relating to event types not within the scope of the older working work? With this in mind, we’ve introduced …

  • non-mobile oncontextmenu (ie. right click)
  • non-mobile “inhouse long hover (of 10 seconds)” (ie. combination of onmouseover and onmouseout)
  • mobile ontouchend (ie. spread or pinch gesture)

… isolated in scope to the column 2 GETME “a” links, via …


setTimeout(function(){
var asis=document.getElementsByTagName('a');
for (var iasis=0; iasis<asis.length; iasis++) {
if (('' + asis[iasis].title) == '' && ('' + asis[iasis].href) != '') {
asis[iasis].title='Click/tap navigates to ' + asis[iasis].href;
asis[iasis].oncontextmenu=function(event){ onrightclickask(event); };
if (('' + asis[iasis].href + '~').indexOf('/' + asis[iasis].innerHTML + '~') != -1) {
asis[iasis].onmouseout=function(event){ startcounter=0; event.target.setAttribute('data-ston','y'); if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } };
asis[iasis].onmouseover=function(event){ if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'y') { event.target.setAttribute('data-ston','Y'); startcounter=1; } if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == '') { event.target.setAttribute('data-ston','y'); startcounter=1; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ' '; event.target.setAttribute('data-ston','Y'); } setInterval(function(){ if (startcounter > 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'Y') { startcounter++; event.target.title+=' '; if (startcounter >= 10) { event.target.getAttribute('data-ston','y'); startcounter=0; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } window.open(event.target.href,'_blank','top=50,left=150,width=600,height=600'); } } }, 1000); } };
}
} else if (('' + asis[iasis].title).indexOf('lick/tap navigates to ') == -1 && ('' + asis[iasis].href) != '') {
asis[iasis].title+=' ... Click/tap navigates to ' + asis[iasis].href;
asis[iasis].oncontextmenu=function(event){ onrightclickask(event); };
if (('' + asis[iasis].href + '~').indexOf('/' + asis[iasis].innerHTML + '~') != -1) {
asis[iasis].onmouseout=function(event){ startcounter=0; event.target.setAttribute('data-ston','y'); if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } };
asis[iasis].onmouseover=function(event){ if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'y') { event.target.setAttribute('data-ston','Y'); startcounter=1; } if (startcounter == 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == '') { event.target.setAttribute('data-ston','y'); startcounter=1; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ' '; event.target.setAttribute('data-ston','Y'); } setInterval(function(){ if (startcounter > 0 && ('' + event.target.getAttribute('data-ston')).replace(/^undefined/g,'').replace(/^null/g,'') == 'Y') { startcounter++; event.target.title+=' '; if (startcounter >= 10) { event.target.getAttribute('data-ston','y'); startcounter=0; if (event.target.title.indexOf(event.target.href) != -1) { event.target.title=event.target.title.split(event.target.href)[0] + event.target.href + ''; } window.open(event.target.href,'_blank','top=50,left=150,width=600,height=600'); } } }, 1000); } };
}
}
}
}, 5000); // was 12000

function onrightclickask(evt) {
// <a target="_blank" title="1.html_GETME ... Click/tap navigates to https://www.rjmprogramming.com.au/NetBeans/HTML5/BackBone/public_html/1.html_GETME" href="NetBeans/HTML5/BackBone/public_html/1.html_GETME">1.html_GETME</a>
// <a target="_blank" title="Breadcrumb tag (may not be found)" href="//www.rjmprogramming.com.au/wordpress/?tag=NetBeans">NetBeans</a>
if (('' + evt.target.href + '~').indexOf('/' + evt.target.innerHTML + '~') != -1) {
//alert('Right click detected for ' + evt.target.href + '~ finding /' + evt.target.innerHTML + '~');
//var sx=prompt('https://www.rjmprogramming.com.au/PHP/Geographicals/diff.php?one=' + encodeURIComponent(evt.target.href) + '&two=' + encodeURIComponent(evt.target.href), 'https://www.rjmprogramming.com.au/PHP/Geographicals/diff.php?one=' + encodeURIComponent(evt.target.href) + '&two=' + encodeURIComponent(evt.target.href));
if (evt.target.innerHTML.indexOf('-GETME') != -1) {
setTimeout(function(){ window.open('//www.rjmprogramming.com.au/PHP/Geographicals/diff.php?one=' + ('//' + evt.target.href.split('//')[1]) + '#&two=' + ('//' + evt.target.href.split('//')[1]),'_blank','top=60,left=160,width=600,height=600'); }, 4000);
} else {
setTimeout(function(){ window.open(('//' + evt.target.href.split('//')[1]) + '#&two=' + ('//' + evt.target.href.split('//')[1]),'_blank','top=40,left=140,width=600,height=600'); }, 4000);
}
}
}

if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
setTimeout(function(){
document.ontouchend=function(e){
if (e.target.outerHTML.indexOf('<a ') == 0) {
if (('' + e.target.href + '~').indexOf('/' + e.target.innerHTML + '~') != -1) {
onrightclickask(e);
}
}
};
}, 4000);
}

… in our changed getmelist.js external Javascript code file which go to make up part of our inhouse Code Download Table.


Previous relevant Code Download Table Difference Functional Hover Tutorial is shown below.

Code Download Table Difference Functional Hover Tutorial

Code Download Table Difference Functional Hover Tutorial

Is it worth adding “onmouseover” event logic onto yesterday’s Code Download Table Difference Functional Linking Tutorial? You bet it is! Just because “onmouseover” has no relevance to mobile platforms, so, obversely, developing software with version control systems is irrelevant to mobile platforms.

a place for everything and everything in its place

… we figure. But this is of relevance to the programmer. Sometimes, rather than cater for all the platforms, settling on a subset (of those platforms) can be apt because …

  • one of mobile or non-mobile subsets of platforms is irrelevant to the scenario … as for today … or …
  • you try to reinvent the wheel on the pretext that you are waiting for a particular web browser or platform to allow the functionality in, into the future … you could be waiting a while, with the complexity of app arrangements going on around the net these days

Anyway, back to the “onmouseover” event on non-mobile platforms … it was the case that this event was a favourite for the conduit towards Ajax (client) functionality. And thinking on what we do today to nuance our Code Differences PHP web application, we were thinking …

What would Ajax (like to) do?

… and we decided Ajax would really like to …

  • populate a “div” style=display:inline-block; element adjacent to the functional detail to inform about … but this was not possible … so, instead, we …
  • populate a popup window near to the functional detail to inform about

… for a non-mobile “hover” (ie. “onmouseover”) event.

Along the way we add some more hashtag navigations and set up more colour coding to the output of (the optional) “functional links” Code Difference reporting.

So take a look at our changed diff.php Code Differences helper applied to itself below …


Previous relevant Code Download Table Multiple Row Email Report Tutorial is shown below.

Code Download Table Multiple Row Email Report Tutorial

Code Download Table Multiple Row Email Report Tutorial

Before leaving yesterday’s Download and Copy or Move Code Download Table Tutorial extensions to our Code Download Table functionality …

  • add copy onto a download functionality to the Code Download Table … today, we …
  • add a Multiple Row selection basis for a personalized Email Report for the user

… as we saw that there was scope for this as a sharing mechanism for project discussions and ideas, we hope.

Today’s tutorial picture tries to show the steps to emailing off a report of interest to a user …

  1. User clicks the “Allow Multiple Row Clicks” checkbox …

    prefixask=prefixask.replace('</div>', '<div id=divawrc style=display:inline-block;>  Allow Multiple Row Clicks <input onchange="domrows();" id=awrc style=inline-block; type=checkbox></input> <div id=dawrc style=display:inline-block;></div></div></div>');

    … which causes …
  2. “Report” button shows to its right …

    function domrows() {
    document.getElementById('dawrc').innerHTML='<input style=inline-block; type=button onclick=treportdo(); value=Report></input>';
    var trsis=document.getElementsByTagName('tr');
    for (var itrsis=0; itrsis<trsis.length; itrsis++) {
    trsis[itrsis].onclick = function(e) { if (e.target.innerHTML != '') { var trs=document.getElementsByTagName('tr'); for (var itrs=0; itrs<trs.length; itrs++) { if (trs[itrs].outerHTML.indexOf(e.target.innerHTML) != -1) { trs[itrs].style.border='2px dotted red'; } } } };
    }
    }

    … and table row onclick logic is dynamically applied to those “tr” elements
  3. User clicks somewhere within rows they are interested in seeing be included in a report (which is a snippet of the whole Code Download Table, perhaps to do with a project of interest, or a learning topic of interest)
  4. User optionally clicks the “Report” button …

    function treportdo() {
    var trsis=document.getElementsByTagName('tr');
    webc='<html><head><script type="text/javascript"> function emailto(eto) { window.opener.parentemailto(eto); } function xemailto(eto) { if (eto.indexOf("@") != -1) { var zhr=new XMLHttpRequest(); var zform=new FormData(); zform.append("inline",""); zform.append("to",eto); zform.append("subj","Code Download Table part"); zform.append("body",document.getElementById("mytable").outerHTML); zhr.open("post", "//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php", true); zhr.send(zform); alert("Email sent to " + eto); } } </script></head><body><table id=mytable></table><br><br><br><input onblur=emailto(this.value); placeholder="Email to" type=email></input></body></html>';
    for (var itrsis=0; itrsis<trsis.length; itrsis++) {
    if (itrsis == 0) {
    webc=webc.replace('</table>', trsis[itrsis].outerHTML + '</table>');
    }
    if (trsis[itrsis].outerHTML.indexOf('>') > trsis[itrsis].outerHTML.indexOf('border:')) {
    if (trsis[itrsis].outerHTML.indexOf('dotted') > trsis[itrsis].outerHTML.indexOf('border:')) {
    webc=webc.replace('</table>', trsis[itrsis].outerHTML + '</table>');
    }
    }
    }
    var woois=window.open('','_blank','top=20,left=20,width=600,height=600');
    woois.document.write(webc);
    }

    … which causes a …
  5. New popup window opens showing the relevant snippet of Code Download Table of interest to the user … including …
  6. Textbox for an optional emailee entry that can be filled in … to …
  7. Set off Ajax/FormData methodology means …

    function parentemailto(eto) {
    if (eto.indexOf("@") != -1) {
    var zhr=new XMLHttpRequest();
    var zform=new FormData();
    zform.append("inline","");
    zform.append("to",eto);
    zform.append("subj","RJM Programming Code Download Table part");
    zform.append("body", reltoabs('<table' + webc.split('</table>')[0].split('<table')[1] + '</table>'));
    zhr.open("post", "//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php", true);
    zhr.send(zform);
    alert("Email sent to " + eto);
    }
    }

    … to send off an Inline HTML Email report to the emailee … including …
  8. Links of email can be clicked to get back to source code and other links back at the RJM Programming domain web server

… in our changed getmelist.js external Javascript code file (that you can try out for yourself at this live run link).


Previous relevant Download and Copy or Move Code Download Table Tutorial is shown below.

Download and Copy or Move Code Download Table Tutorial

Download and Copy or Move Code Download Table Tutorial

After the “goings on” with the relatively recent PHP Blog Summary Fixed Title Events Tutorial we thought we were finished with “Code Download Table” functionality … but then …

along came Jones yesterday’s Download and Copy or Move Server Tutorial

… and … lo and behold … we saw a good use for the idea of …

  1. download from “the net” to a Downloads folder on your computer or device … and more often than not …
  2. you, the user, copies or renames this data to another location on your computer or device with command line or with operating system GUI

… and allowing for that second step above be programmatical with the most apt functionality that had ever passed our cotton pickin’ mind … our Code Download Table … wi’ all tho’ GETME’s!

But we don’t want to interfere too much with the Code Download Table “flow” here, so create up the top left 20 seconds worth of time (extendable by their actions) available to the user to create “download” attributes on all …

  • “a” links … with …
  • “href” attribute containing “GETME” …
  • but not “diff.php” … and …
  • “download” attribute (the attribute necessary to “download” rather than our default displaying of source code in a new webpage)

… plus no href attribute containing “?s=” either, for today’s purposes with a changed getmelist.js external Javascript code file (that you can try out for yourself at this live run link) … via its new …


var dnprefix=decodeURIComponent(('' + localStorage.getItem('download_copy_to_folder')).replace(/^null$/g,'')); //.replace(/\+/g,' ').replace(/\\\\/g, '_').replace(/\//g, '_').replace(/\:/g, '_');
var delaymore=0;
var prefixask='<div id=firstask style="position:absolute;top:0px;left:0px;"> Download GETME? <input id=dpccb style=inline-block; type=checkbox onchange="dogetmes(document.getElementById(' + "'" + 'dpcis' + "'" + ').value);"></input> <input style=inline-block;width:300px; onclick="delaymore+=20000;" onblur="if (document.getElementById(' + "'" + 'dpccb' + "'" + ').checked) { dogetmes(document.getElementById(this.value); }" type=text id=dpcis placeholder="Optional Download Folder Later Copy to Place via Listener" value="' + dnprefix + '"></input></div>';

function dogetmes(dpprefix) {
delaymore+=20000;
var asis=document.getElementsByTagName('a');
if (dpprefix != dnprefix && 1 == 7) {
localStorage.setItem('download_copy_to_folder', dpprefix);
}
for (var iasis=0; iasis<asis.length; iasis++) {
if (asis[iasis].href.indexOf('diff.php') == -1 && asis[iasis].href.indexOf('?s=') == -1 && asis[iasis].href.indexOf('GETME') != -1) {
asis[iasis].download=dpprefix.replace(/\//g,'_').replace(/\\\\/g,'_').replace(/\:/g,'_') + asis[iasis].href.split('/')[eval(-1 + asis[iasis].href.split('/').length)];
}
}
}

function nomorepa() {
if (eval('' + delaymore) == 0) {
if (document.getElementById('firstask')) {
document.getElementById('firstask').innerHTML='';
}
} else {
setTimeout(nomorepa, eval('' + delaymore));
delaymore=0;
}
}

function lastdivpop() {
var wasih='';
if (document.getElementById('lastdiv')) {
if (document.getElementById('lastdiv').innerHTML == '') {
wasih=wasih;
setTimeout(lastdivpop, 3000);
} else if (document.getElementById('lastdiv').innerHTML.indexOf('firstask') == -1) {
wasih=document.getElementById('lastdiv').innerHTML;
document.getElementById('lastdiv').innerHTML=prefixask + wasih;
prefixask='';
setTimeout(nomorepa, 20000);
} else {
setTimeout(lastdivpop, 3000);
}
}
}

setTimeout(lastdivpop, 8000);


Previous relevant Download and Copy or Move Server Tutorial is shown below.

Download and Copy or Move Server Tutorial

Download and Copy or Move Server Tutorial

Yesterday’s Download and Copy or Move Primer Tutorial was all about the “client side” of …

… and we’ve just “tweaked” (albeit, very importantly, in our books (… but the pamphlettes are still not playing ball)) to ensure no “file clobbering” takes place so that the Korn Shell now does …


suf=""
isuf=-1
while [ -f "${dpath}/${brest}${suf}" ]; do
((isuf=isuf+1))
suf="_${isuf}"
done
if [ ! -z "$suf" ]; then
echo "mv ${dpath}/${brest} ${dpath}/${brest}${suf} # `date`" >> download_to_place.out
mv ${dpath}/${brest} ${dpath}/${brest}${suf} >> download_to_place.out 2>> download_to_place.err
fi

… in download_copier.ksh download_copier.ksh Korn Shell scripting on our macOS operating system “client”.

But today is mainly about filling in the missing bits on the “server” side. This (need for a) “conduit” we referred to yesterday is because we accept no folder paths can be mentioned at the “server” end. Suppose, though, that the “non-pathed” filename we supply to an “a” link’s “download” attribute can be prefixed by a mildly mashed up version of that path we copy to from the Downloads folder of your “client” computer or device, as you perform a “download” via the clicking of an “a” link.

Well, at this blog we’d already started functionality to toggle the use or not of …

  • “a” links … with …
  • “href” attribute containing “GETME” …
  • but not “diff.php” … and …
  • “download” attribute (the attribute necessary to “download” rather than our default displaying of source code in a new webpage)

Were you here, then, when we published WordPress Blog Download Mode Toggler Primer Tutorial (or were you indisposed again?!) There we established an “All Posts” menu “Toggle Download Mode from GETME” option piece of functionality to toggle between …

  • displaying of source code in a new webpage for GETME “a” links … versus …
  • use the changed PHP toggle_download.php in conjunction with a changed good ‘ol TwentyTen Theme header.php as below …
    <?php

    if (outs == null) {
    var dnprefix=decodeURIComponent(('' + localStorage.getItem('download_copy_to_folder')).replace(/^null$/g,'')).replace(/\+/g,' ').replace(/\\\\/g, '_').replace(/\//g, '_').replace(/\:/g, '_');
    for (idmjk=0; idmjk<admjk.length; idmjk++) {
    if (admjk[idmjk].href.indexOf('GETME') != -1 && admjk[idmjk].href.indexOf('diff.php') == -1) {

    if (origcafd < 0) { //!cafd) {
    xp=admjk[idmjk].href.split("GETME");
    prexp=xp[0].split("/");
    postprexp=prexp[-1 + prexp.length].split(".");
    extis = postprexp[-1 + postprexp.length].replace(/_/g,"").replace(/-/g,"").replace(/GETME/g,"");
    outs="//www.rjmprogramming.com.au/getmelist.htm?topoff=150&tsp=" + (Math.floor(Math.random() * 1999900) + 100) + "#" + postprexp[0] + "." + postprexp[-1 + postprexp.length].replace(extis,"").replace(extis,"").replace(extis,"") + "GETME" + extis;
    aorig=admjk[idmjk].innerHTML;
    admjk[idmjk].innerHTML=admjk[idmjk].innerHTML.replace(".","<span data-alt='" + outs + "' id='spn" + cafd + "' title=\" + Code Download Table\" onclick=\"if (cafd == cafd) { cafd=" + cafd + "; changeasfordownload(); } else { window.open('" + outs + "','_blank','top=100,left=100,width=500,height=500'); } return false; \">⚫</span>");
    if (aorig == admjk[idmjk].innerHTML && admjk[idmjk].innerHTML.indexOf('er posts') == -1) admjk[idmjk].innerHTML=admjk[idmjk].innerHTML.replace(" ","<span data-alt='" + outs + "' id='spn" + cafd + "' title=\" + Code Download Table\" onclick=\"if (cafd == cafd) { cafd=" + cafd + "; changeasfordownload(); } else { window.open('" + outs + "','_blank','top=100,left=100,width=500,height=500'); } return false; \">⚪</span>");
    cafd++;
    } else {
    prestuffs = admjk[idmjk].href.split('/');
    newaspare = admjk[idmjk].href.replace('_-GETME', '').replace('__GETME', '').replace('_GETME', '').replace(big, '');

    while (big.indexOf('-') != -1) {

    big = big.replace('-', '');

    newaspare = newaspare.replace(big, '');

    }

    big = '----------------------GETME';
    stuffs = newaspare.split('/');
    if (dnprefix != '') {
    admjk[idmjk].download = dnprefix + prestuffs[stuffs.length - 1];
    } else {

    admjk[idmjk].download = dnprefix + stuffs[stuffs.length - 1];
    }
    admjk[idmjk].title = "(Really download) " + admjk[idmjk].title + ' ... welcome to the long hover functionality that shows allows for a Download Mode for the blog that can be toggled';
    admjk[idmjk].onmouseover = " getDownloadMode(); ";
    admjk[idmjk].onmouseout = " yehBut(); ";
    admjk[idmjk].ontouchstart = " getDownloadMode(); ";
    admjk[idmjk].ontouchend = " yehBut(); ";
    }
    } else if (admjk[idmjk].href.indexOf('GETME') != -1 && origcafd < 0) { //!cafd) {
    xp=admjk[idmjk].href.split("GETME");
    prexp=xp[0].split("/");
    postprexp=prexp[-1 + prexp.length].split(".");
    extis = postprexp[-1 + postprexp.length].replace(/_/g,"").replace(/-/g,"").replace(/GETME/g,"");
    outs="//www.rjmprogramming.com.au/getmelist.htm?topoff=150&tsp=" + (Math.floor(Math.random() * 1999900) + 100) + "#" + postprexp[0] + "." + postprexp[-1 + postprexp.length].replace(extis,"").replace(extis,"").replace(extis,"") + "GETME" + extis;
    aorig=admjk[idmjk].innerHTML;
    selbitis=allthecombos((admjk[idmjk].href + '=').split('=')[1].split('&')[0]);
    admjk[idmjk].innerHTML=admjk[idmjk].innerHTML.replace(".","<span data-alt='" + outs + "' id='spn" + cafd + "' title=\" + Code Download Table\" onclick=\"if (cafd == cafd) { cafd=" + cafd + "; changeasfordownload(); } else { window.open('" + outs + "','_blank','top=100,left=100,width=500,height=500'); } return false; \"><select onchange=\" if (this.value.length > 0) { window.open(this.value,'_blank'); } return false; \" style='margin-bottom:0px;width:40px;' id='sel" + cafd + "'><option value=>⚫</option>" + selbitis + "</select></span>");
    if (aorig == admjk[idmjk].innerHTML && admjk[idmjk].innerHTML.indexOf('er posts') == -1) admjk[idmjk].innerHTML=admjk[idmjk].innerHTML.replace(" ","<span data-alt='" + outs + "' id='spn" + cafd + "' title=\" + Code Download Table\" onclick=\"if (cafd == cafd) { cafd=" + cafd + "; changeasfordownload(); } else { window.open('" + outs + "','_blank','top=100,left=100,width=500,height=500'); } return false; \"><select onchange=\" if (this.value.length > 0) { window.open(this.value,'_blank'); } return false; \" style='margin-bottom:0px;width:40px;' id='sel" + cafd + "'><option value=>⚪</option>" + selbitis + "</select></span>");
    cafd++;
    } else if ((admjk[idmjk].innerHTML.indexOf('live run') != -1 || admjk[idmjk].title.toLowerCase().indexOf('click picture') != -1) && origcafd < 0) { //!cafd) {
    outs="//www.rjmprogramming.com.au/slideshow.html#tuts";
    admjk[idmjk].innerHTML=admjk[idmjk].innerHTML.replace(" ","<span data-alt='" + outs + "' id='spn" + cafd + "' title=\" + Cut to the Chase ... see the blog post list related to live runs and slideshows ... ie. the main point of the blog posting\" onclick=\"if (cafd == cafd) { cafd=" + cafd + "; changeasfordownload(); } else { window.open('" + outs + "','_blank','top=100,left=100,width=650,height=100'); } return false; \">✂</span>");
    cafd++;
    }
    }
    }

    ?>
    … to, depending on whether the user specifies in the “All Posts” toggling’s Javascript prompt window presented, specifies a new comma separated “client folder of interest to copy to” place (stored in window.localStorage), will …

    1. download with the GETME to the Downloads folder and copy off to the specified folder of interest (backing up as necessary) … versus …
    2. the default download mode downloads to the Downloads folder without the GETME parts

See these changes in action below, contextualizing “server” and “client” codes in the full picture of assisted Downloads (copied on to a folder of the user’s interest) …


Previous relevant Download and Copy or Move Primer Tutorial is shown below.

Download and Copy or Move Primer Tutorial

Download and Copy or Move Primer Tutorial

Downloading from “the net” (“server land”) to your computer or device (“client land”) is a big part of the online experience and the sharing of data over the world wide web. But have you ever wondered about the two step design of …

  1. download from “the net” to a Downloads folder on your computer or device … and more often than not …
  2. you, the user, copies or renames this data to another location on your computer or device with command line or with operating system GUI

… ? Why not allow the “server” side define where it can download to on the “client”? Well, that would be a security nightmare, allowing a highjacking of mission critical files on your computer or device. So, I get it, that is a “no no”. But could we have a controlled “arrangement” between …

… ? We think that sounds reasonable and so, today, we start our (two parts or more) mini-project (making step 2 above be considered to be programmatically handled, sometimes) designing a Korn Shell (“client” side) listener to suit our macOS “client” computer, executed as a background process via …


ksh download_copier.ksh &

But what is the conduit, if the “server” web applications/pages cannot define a destination folder other than the macOS Downloads folder for the user involved? Well, that is where we need either …

… to define a “client land” folder to copy to (from the user’s Download folder (receiving the downloaded data).

That first Korn Shell read command interactive input was interesting to us for a command backgrounded via the “&” command suffix. But if stdin and stdout are not mentioned in the command you can answer this interactive input and then the processing the Korn Shell performs proceeds in the background. Exactly what we were hoping for, but weren’t sure that this was the case!

The picture is filled in better tomorrow as we discuss the conduit in more detail 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.

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

Google Lens Reverse Image Search Revisit Tutorial

Google Lens Reverse Image Search Revisit Tutorial

Google Lens Reverse Image Search Revisit Tutorial

We’re revisiting the Google Lens image matching (sometimes via Google search engine) themes of Google Lens Reverse Image Search Tutorial honing in on various ways to input, such as …

  • macOS Paste Item … via Paintbrush -> Select All -> Copy … Paste into awaiting Google Lens textbox …
  • macOS Drop file … via Finder file drops …
  • iOS Camera (take photo and save to) -> Photos app (via tap of thumbnail after taking and tapping Share bottom left icon) -> Share menu -> Search on Google option …

… just as three of a growing list of ways image matching is being integrated, in pretty seamless ways, into Surfing the Net and other mobile online work!


Previous relevant Google Lens Reverse Image Search Tutorial is shown below.

Google Lens Reverse Image Search Tutorial

Google Lens Reverse Image Search Tutorial

Have you ever wanted to follow up on an isolated image and see where else on the Google search engine, close graphic matches to that imagery are found? Most of us, right?!

Well, we tried out on iOS (on an iPad and iPhone) the other day the relevant Google Lens apps to do a reverse image search. It was very good, unsurprisingly!

We assembled a video about this, including a Google Lens install, here, with today’s tutorial video …

… in case you want to give this Reverse Image Search a go, yourself?

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