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

Multipurpose Buttons Email Attachment Download Tutorial

Multipurpose Buttons Email Attachment Download Tutorial

Multipurpose Buttons Email Attachment Download Tutorial

Most of the time developing webpages for a public URL on the World Wide Web we’d suggest and encourage Relative URLs rather than Absolute URLs for …

  • brevity
  • avoids mixed content issues

… but there are some occasions where it is the other way around. Think …

  • web browser File -> Open File… (some HTML file) type of functionality … and what amounts to a similar thing is …
  • email attachment of HTML downloaded and opened

Why are these two in any way similar? They both end up at a web browser address bar using a URL with the file: protocol (ie. not http: nor https: nor sftp: nor ftp: protocols). In this environment, if you want a more seamless progression with this attached email HTML content downloaded and opened into a file: protocol web browser URL arrangement to still support links and form navigations, you are going to suddenly hanker for Absolute URLs in the HTML and Javascript and CSS code, believe me! That is because a Relative URL will suddenly be based on some awkward client device download folder (we’re guessing), rather than a public URL place pointing to a http: or https: protocol place on a public web server, the arrangement most of us deal with a great deal of the time surfing the net.

We create these email attachments using Ajax/FormData techniques? What is the biggest issue sending whole webpage content to an attached HTML content attachment and relying on the Javascript to work within that HTML? We think the “+” character encoding is the most annoying thing. We can handle it within a data URL but within Javascript? Wow!!! How annoying is the way the “+” will map to a space ” ” and wreck the Javascript logic. We rearranged the Javascript to sit in a new external Javascript http: or https: protocol place called multipurpose_buttons.js to get around a lot of this as of today. We also where we might have had a …


Relative URL such as ./multipurpose_buttons.html

… now say, in the static Javascript external Javascript …


Absolute (but no defined protocol) URL such as //www.rjmprogramming.com.au/HTMLCSS/multipurpose_buttons.html

… which maintains Mixed Content friendly code, while in the public parts of the net, which is amended just before the Ajax/FormData sends off the email HTML content attachment to be sent as …


Absolute URL such as HTTP://www.rjmprogramming.com.au/HTMLCSS/multipurpose_buttons.html

… so that the file: protocol execution of the HTML is not confused nor causing problems.

And so, improving on yesterday’s Multipurpose Buttons Onclick Event Logic Tutorial‘s email communication abilities, please see this with the sixth draft multipurpose_buttons.html live run link.


Previous relevant Multipurpose Buttons Onclick Event Logic Tutorial is shown below.

Multipurpose Buttons Onclick Event Logic Tutorial

Multipurpose Buttons Onclick Event Logic Tutorial

The web would be a very boring woooooorrrrrlllllldddd without onclick logics. The number of thoughts regarding what to do when you click on an HTML element are more than the number of grains of sand on Bondi Beach, or the Sahara Desert. Yesterday’s Multipurpose Buttons Emoji Links Tutorial had a static arrangement as far as “onclick” event logic is concerned.

Today’s job is threefold in purpose …

  • facilitate a means by which a user can define onclick logic set(s) … and we’ve chosen for this …
  • ondblclick event for non-mobile and ontouchend event for mobile … and have it that …
  • renavigating back after a content change these onclick logics get restored, as required

Can you define an onclick event logic dynamically? You bet! You can addEventListener or rewrite an element within a nesting container element (that often being a div element) or you can go something like (with Javascript) …


document.getElementById('ix').onclick=function(event){ alert('We have clicked element called ' + ('' + event.target.id)); }

The nature of this is that it gets unwieldy to define the codeline above using some Javascript eval arrangement. Rather we allow the user definition to move along with the HTML element. Can you think how? Yes, global attributes, as per the Javascript code snippet, where “newcl” contains the user onclick event logic entered as they were prompted for it …


if (newcl.trim().indexOf('function') == 0) {
aspan.setAttribute('data-onclick', (newcl.trim() + '~`').replace('}~`','').replace('~`','').substring(eval(1 + newcl.trim().indexOf('{'))) + String.fromCharCode(9));
aspan.onclick=function(event){ eval(event.target.getAttribute('data-onclick')); }
} else {
aspan.setAttribute('data-onclick', newcl + String.fromCharCode(9));
aspan.onclick=function(event){ eval(event.target.getAttribute('data-onclick')); }
}

Please see this with the fifth draft multipurpose_buttons.html live run link.


Previous relevant Multipurpose Buttons Emoji Links Tutorial is shown below.

Multipurpose Buttons Media Content Tutorial

Multipurpose Buttons Emoji Links Tutorial

We’re adding emojis into the mix of Multipurpose Buttons Media Content Tutorial functionality today. We often describe such additional functionality as an “emoji button” but for the purposes of clarity, today, we describe …

  • “a” links … with a …
  • emoji innerHTML (ie. look) … eg. 🆕 🆕 “New” emoji we’re using as a “Restart” piece of functionality … button-like, in that they have styling …
  • style=”cursor:pointer;text-decoration:none;” … lacking the underlining “a” links typically have

… as new “emoji links” … for …

  • New (restart) 🆕
  • Email 📧
  • Circular borders ⭕
  • Glow 🌟

… as well as some new functionality that when you click outside characters and media within the “button” elements, a new popup window hones in on this clicked element.

All this can be set and moves with the web application as it recalls itself.

See this with the fourth draft multipurpose_buttons.html live run link.


Previous relevant Multipurpose Buttons Media Content Tutorial is shown below.

Multipurpose Buttons Media Content Tutorial

Multipurpose Buttons Media Content Tutorial

Were you around for the Window SessionStorage Client Versus Server Tutorial? We found a place where we could differentiate between …

… regarding the combination of …

  • sessionStorage‘s “ephemeral” storage suits … as well as a mechanism to …
  • not need (ie. be a functional replacement for) HTML form method=POST (instead, using method=GET with extra argument being the sessionStorage name used (for that tiny period of time)) for large amounts of data that normally require action=[somePHPserverPage]

… and so can remain a totally client facing web application even though we are doing similar work to what we did with Dynamic Timer Web Browser Reminder Media Tutorial when we added media file browsing into the mix by starting to interface with client_browsing.htm‘s File API talents within an HTML iframe “child” element.

And so on top of the progress up to yesterday’s Multipurpose Buttons Content Tutorial, today we allow users to be able to append …

  • img (image)
  • audio
  • video

… media data contents within the “button” (but not input type=button) element buttons.

Yet again, feel free to try the third draft multipurpose_buttons.html live run link to see what we mean by the use of sessionStorage to store (for that tiny length of time) and restore of these media data sets just within the “client facing wooooooorrrrrrllllllldddd”.


Previous relevant Multipurpose Buttons Content Tutorial is shown below.

Multipurpose Buttons Content Tutorial

Multipurpose Buttons Content Tutorial

Yesterday’s proof of concept “Multipurpose Buttons” web application of Multipurpose Buttons Primer Tutorial was pretty typical of many “proof of concept”s out there, not rocking the boat with the messy woooooorrrrllllllddd of what a user might enter as the “content” of those buttons. But that “proof of concept” idea is important to establish …

  • what is crucial … as well as …
  • what is important
  • what needs attention when genericizing (which is today’s work) … and up above all this …
  • whether the whole concept is feasible for controlled data content
  • whether the whole concept is feasible for user entered data content

… and happily, though there are some cross-browser tweaks (always a bit of a genericization “sour puss” for us), we think that last option above is indeed possible. The whole exercise has certainly borne out how much more powerful is the HTML “button” element for this multipurpose thinking, than is the “input type=button” (older) HTML element type, that “button” element now truly a “container” type of element (for us, the HTML elements where the property innerHTML has a proper meaning).

Proof of this is that this genericization drive today hardly concerned itself with any HTML “button” element concerns, rather it was a constant battle to make the HTML “input type=button” “hang in there”.

Okay then, if we are allowing a “vertical dimension” to our contents and we offer you the choice of …

  • textarea … versus …
  • div contenteditable=true

… as your user interaction HTML element of choice, which do you think is better? Well, our choice was a no brainer, as we had decided the reasoning would be …

  • encase …
  • whatever element above is used …
  • within an HTML form action=[here’sLookingAtYouKid] method=GET navigational arrangement

… as our means of passing through user interaction findings. Well, this rules out “div contenteditable=true” as the “name” property of HTML “form” elements map from that element’s “value” property, something a “div contenteditable=true” lacks but a “textarea” element excels at (as well as its “innerHTML” initializing of data (ie. value) talents, as well).

This genericization drive also taught us that even if a monospaced font such as Courier New is enforced for the HTML “input type=button” there can be different “display looks” between data containing …

  • space (” “) character (as whitespace) … versus …
  • non-breaking space (“ ”) character

… the latter crucial for us to even up record lengths of the underlying “display data” used to make the “input type=button” elements “look” as the user would have intended, meaning that the non-breaking whitespace character (as one character) above is used for “display data” that is a “square block of text” so that “display:block” can work with CSS “font-size” and “width” and “height” to facilitate this HTML “input type=button” display look.

As you’d expect, coming back (ie. callback) via “action=[here’sLookingAtYouKid]” form navigation above means we need a document.body “onload” event function as way below to set up display settings and the creation of that “onclick” logic evaled “if logic” setting the global variable “gval” …


if (cnum != ("1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ")) { // true user interaction data here
gval='';
eval(ifstr); // for Horizontal and Vertical input type=button ... just Horizontal uses "ifstrone" variable instead
if (gval != '') { setTimeout(agval, 1000); }
}

… is set up at global initializations followed by the “function onl” document.body “onload” event logic below …


var gval='';
var cnum=location.search.split('content=')[1] ? decodeURIComponent(location.search.split('content=')[1].split('&')[0]).replace(/\+/g,' ') : "1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ";
while (cnum.indexOf(' ' + String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(13) + String.fromCharCode(10), ' [13][10]');
}
while (cnum.indexOf(' ' + String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(10) + String.fromCharCode(13), ' [10][13]');
}
while (cnum.indexOf(' ' + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(10), ' [10]');
}
while (cnum.indexOf(' ' + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(13), ' [13]');
}


while (cnum.indexOf(String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(String.fromCharCode(13) + String.fromCharCode(10), ' [13][10]');
}
while (cnum.indexOf(String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(String.fromCharCode(10) + String.fromCharCode(13), ' [10][13]');
}
while (cnum.indexOf(String.fromCharCode(10)) != -1) {
cnum=cnum.replace(String.fromCharCode(10), ' [10]');
}
while (cnum.indexOf(String.fromCharCode(13)) != -1) {
cnum=cnum.replace(String.fromCharCode(13), ' [13]');
}
cnum=cnum.replace(/\[13\]\[10\]/g, String.fromCharCode(13) + String.fromCharCode(10));
cnum=cnum.replace(/\[10\]\[13\]/g, String.fromCharCode(10) + String.fromCharCode(13));
cnum=cnum.replace(/\[13\]/g, String.fromCharCode(13));
cnum=cnum.replace(/\[10\]/g, String.fromCharCode(10));

var origcnumx=cnum; //.trim();
var cnumx=cnum; //.trim();

function onl() {
var ih='', jh=0, kh=0, lh=0, onelh=0, zero=0, eight=0;
maxlh=0;
if (cnum != ("1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ")) { // true user interaction data here
var ccnums=[];
if (origcnumx.indexOf(String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(13) + String.fromCharCode(10));
document.getElementById('content').rows='' + ccnums.length;
} else if (origcnumx.indexOf(String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(10) + String.fromCharCode(13));
document.getElementById('content').rows='' + ccnums.length;
} else if (origcnumx.indexOf(String.fromCharCode(13)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(13));
document.getElementById('content').rows='' + ccnums.length;
} else {
ccnums=origcnumx.split(String.fromCharCode(10));
document.getElementById('content').rows='' + ccnums.length;
}
//alert(ccnums.length);
for (jh=1; jh<=ccnums.length; jh++) {
if (eval('' + ccnums[eval(-1 + jh)].length) > eval('' + maxlh)) { maxlh=ccnums[eval(-1 + jh)].length; }
}
for (jh=1; jh<=cnumx.length; jh++) {
ih+="<span class=bxandy onclick='gval=this.innerHTML;'>" + cnumx.substring(eval(-1 + jh)).substring(0,1) + "</span>";
//if (lh == 0) { alert(cnumx.substring(eval(-1 + jh)).substring(0,1)); }
if ((cnumx + ' ').substring(eval(0 + jh)).substring(0,1)) {
zero=eight;
if (eight > 0) { eight--; }
} else {
zero=0;
}
if (ifstrone.indexOf('if ') == -1) {
ifstrone+=" if (eval(propx) <= eval(" + eval(1 + onelh) + "." + zero + " / " + cnumx.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstrone+=" else if (eval(propx) <= eval(" + eval(1 + onelh) + "." + zero + " / " + cnumx.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
if (ccnums.length == 1) {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
} else {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
}
lh++;
onelh++;
if (lh == ccnums[kh].length && kh < ccnums.length) {
if (lh < maxlh) {
while (lh < maxlh) {
ih+="<span class=bxandy onclick='gval=this.innerHTML;'> </span>";
if (ccnums.length == 1) {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ")) { gval=' '; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ")) { gval=' '; } ";
}
} else {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval=' '; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval=' '; } ";
}
}
lh++;
}
}
ih+="<br>";
kh++;
lh=0;
}
}
if (maxlh == 0) { maxlh=lh; }
//alert(ifstrone);
document.getElementById('ix').style.marginLeft='1px';
document.getElementById('ix').style.marginRight='3px';
if (/chrome/i.test( navigator.userAgent )) {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 8.0) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + maxlh) * 7.5) + 'px';
} else {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 6.75) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + maxlh) * 8.0) + 'px';
}
document.getElementById('ixandy').style.height='' + Math.floor(eval(eval('' + ccnums.length) * 14) + 4) + 'px';
document.getElementById('bxandy').innerHTML=ih.replace(/\>\ \<\/span\>/g, '>&nbsp;</span>');
document.getElementById('bx').innerHTML=ih.replace(/\<br\>/g,'');
document.getElementById('ix').title='Please click a character.';
document.getElementById('ixandy').title='Please click a character.';
} else {
document.getElementById('ix').style.marginLeft='1px';
document.getElementById('ix').style.marginRight='3px';
if (/chrome/i.test( navigator.userAgent )) {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 8.0) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + 6) * 7.5) + 'px';
} else {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 6.75) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + 6) * 8.0) + 'px';
}
document.getElementById('ixandy').style.height='' + Math.floor(eval(eval('' + '3') * 14) + 4) + 'px';
}
}

So, feel free to “use” the second draft multipurpose_buttons.html live run link to see what we mean.


Previous relevant Multipurpose Buttons Primer Tutorial is shown below.

Multipurpose Buttons Primer Tutorial

Multipurpose Buttons Primer Tutorial

At this blog we go hard at spruiking the qualities of HTML dropdown (ie. select) elements to do with …

  • the display brevity … as well as …
  • richness of content possibilities

… they can infer upon a webpage. At the expense of “the display brevity” we are keen to use a dropdown attribute “size” set so as to display all the content on the screen where …

  • it can sensibly fit on the screen … and …
  • it does not matter that mobile platforms do not recognize the “size” attribute “vertical expansion” of a dropdown that takes place on non-mobile platforms

Today, though, we’re here to show you that, with a bit of Javascript event logic, a …

  • button element … even better than an …
  • input type=button element

… can go some of the way to mimicking those qualities we like so much above, doing even better than the x (ie. horizontal) dimension limit of one that a dropdown has, to be able to fit more data content in horizontally, as a display mechanism you might say has “the display brevity” combined with content complexity you are after.

We wrote a proof of concept multipurpose_buttons.html, featuring the one Javascript “onclick” logic function as per …


var x=0, y=0, lastx=0,lasty=0;
var propx=0.0, propy=0.0;

function iclicked(event) {
var rectis=null, isok=true;;
if (('' + event.target.id) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'ixandy') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.333 && eval(propy) <= 0.333) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.333) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333 && eval(propy) <= 0.666) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.666) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666) {
gval='9';
setTimeout(agval, 1000);
} else {
gval='8';
setTimeout(agval, 1000);
}
}
} else if (('' + event.target.id) == 'ix') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.111) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.222) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.444) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.555) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.777) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.888) {
gval='8';
setTimeout(agval, 1000);
} else {
gval='9';
setTimeout(agval, 1000);
}
}
}
}

function agval() {
if (gval != '') {
alert('You clicked ' + gval);
gval='';
}
}

live run linked web application you can try for yourself regarding this, or see, in action, below …

Did you know?

Regarding the input type=button “Horizontal and Vertical Dimensions” element “look” above we needed help from the internet, thanks, to stop some web browsers such as Firefox, Chrome and Opera not “fattening out” the element height so as to show three lines of numbers, as per the CSS (thanks to html – word-wrap break-word does not work in this example – Stack Overflow and Wrapping an HTML input button's text value over multiple lines – Stack Overflow and html – Button height on Chrome – Stack Overflow) …


<style>
#ixandy {
font-size: 12px;
width: 36px;
height: 44px;

overflow-wrap: break-word;
word-wrap: break-word;

-ms-word-break: break-all;
/* This is the dangerous one in WebKit, as it breaks things wherever */
word-break: break-all;
/* Instead use this non-standard one: */
word-break: break-word;

/* Adds a hyphen where the word breaks, if supported (No Blink) */
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;

white-space: normal;

box-sizing: content-box;
-moz-box-sizing: content-box;
-ms-box-sizing: content-box;
-webkit-box-sizing: content-box;
}
</style>

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

Multipurpose Buttons Onclick Event Logic Tutorial

Multipurpose Buttons Onclick Event Logic Tutorial

Multipurpose Buttons Onclick Event Logic Tutorial

The web would be a very boring woooooorrrrrlllllldddd without onclick logics. The number of thoughts regarding what to do when you click on an HTML element are more than the number of grains of sand on Bondi Beach, or the Sahara Desert. Yesterday’s Multipurpose Buttons Emoji Links Tutorial had a static arrangement as far as “onclick” event logic is concerned.

Today’s job is threefold in purpose …

  • facilitate a means by which a user can define onclick logic set(s) … and we’ve chosen for this …
  • ondblclick event for non-mobile and ontouchend event for mobile … and have it that …
  • renavigating back after a content change these onclick logics get restored, as required

Can you define an onclick event logic dynamically? You bet! You can addEventListener or rewrite an element within a nesting container element (that often being a div element) or you can go something like (with Javascript) …


document.getElementById('ix').onclick=function(event){ alert('We have clicked element called ' + ('' + event.target.id)); }

The nature of this is that it gets unwieldy to define the codeline above using some Javascript eval arrangement. Rather we allow the user definition to move along with the HTML element. Can you think how? Yes, global attributes, as per the Javascript code snippet, where “newcl” contains the user onclick event logic entered as they were prompted for it …


if (newcl.trim().indexOf('function') == 0) {
aspan.setAttribute('data-onclick', (newcl.trim() + '~`').replace('}~`','').replace('~`','').substring(eval(1 + newcl.trim().indexOf('{'))) + String.fromCharCode(9));
aspan.onclick=function(event){ eval(event.target.getAttribute('data-onclick')); }
} else {
aspan.setAttribute('data-onclick', newcl + String.fromCharCode(9));
aspan.onclick=function(event){ eval(event.target.getAttribute('data-onclick')); }
}

Please see this with the fifth draft multipurpose_buttons.html live run link.


Previous relevant Multipurpose Buttons Emoji Links Tutorial is shown below.

Multipurpose Buttons Media Content Tutorial

Multipurpose Buttons Emoji Links Tutorial

We’re adding emojis into the mix of Multipurpose Buttons Media Content Tutorial functionality today. We often describe such additional functionality as an “emoji button” but for the purposes of clarity, today, we describe …

  • “a” links … with a …
  • emoji innerHTML (ie. look) … eg. &#127381; 🆕 “New” emoji we’re using as a “Restart” piece of functionality … button-like, in that they have styling …
  • style=”cursor:pointer;text-decoration:none;” … lacking the underlining “a” links typically have

… as new “emoji links” … for …

  • New (restart) 🆕
  • Email 📧
  • Circular borders ⭕
  • Glow 🌟

… as well as some new functionality that when you click outside characters and media within the “button” elements, a new popup window hones in on this clicked element.

All this can be set and moves with the web application as it recalls itself.

See this with the fourth draft multipurpose_buttons.html live run link.


Previous relevant Multipurpose Buttons Media Content Tutorial is shown below.

Multipurpose Buttons Media Content Tutorial

Multipurpose Buttons Media Content Tutorial

Were you around for the Window SessionStorage Client Versus Server Tutorial? We found a place where we could differentiate between …

… regarding the combination of …

  • sessionStorage‘s “ephemeral” storage suits … as well as a mechanism to …
  • not need (ie. be a functional replacement for) HTML form method=POST (instead, using method=GET with extra argument being the sessionStorage name used (for that tiny period of time)) for large amounts of data that normally require action=[somePHPserverPage]

… and so can remain a totally client facing web application even though we are doing similar work to what we did with Dynamic Timer Web Browser Reminder Media Tutorial when we added media file browsing into the mix by starting to interface with client_browsing.htm‘s File API talents within an HTML iframe “child” element.

And so on top of the progress up to yesterday’s Multipurpose Buttons Content Tutorial, today we allow users to be able to append …

  • img (image)
  • audio
  • video

… media data contents within the “button” (but not input type=button) element buttons.

Yet again, feel free to try the third draft multipurpose_buttons.html live run link to see what we mean by the use of sessionStorage to store (for that tiny length of time) and restore of these media data sets just within the “client facing wooooooorrrrrrllllllldddd”.


Previous relevant Multipurpose Buttons Content Tutorial is shown below.

Multipurpose Buttons Content Tutorial

Multipurpose Buttons Content Tutorial

Yesterday’s proof of concept “Multipurpose Buttons” web application of Multipurpose Buttons Primer Tutorial was pretty typical of many “proof of concept”s out there, not rocking the boat with the messy woooooorrrrllllllddd of what a user might enter as the “content” of those buttons. But that “proof of concept” idea is important to establish …

  • what is crucial … as well as …
  • what is important
  • what needs attention when genericizing (which is today’s work) … and up above all this …
  • whether the whole concept is feasible for controlled data content
  • whether the whole concept is feasible for user entered data content

… and happily, though there are some cross-browser tweaks (always a bit of a genericization “sour puss” for us), we think that last option above is indeed possible. The whole exercise has certainly borne out how much more powerful is the HTML “button” element for this multipurpose thinking, than is the “input type=button” (older) HTML element type, that “button” element now truly a “container” type of element (for us, the HTML elements where the property innerHTML has a proper meaning).

Proof of this is that this genericization drive today hardly concerned itself with any HTML “button” element concerns, rather it was a constant battle to make the HTML “input type=button” “hang in there”.

Okay then, if we are allowing a “vertical dimension” to our contents and we offer you the choice of …

  • textarea … versus …
  • div contenteditable=true

… as your user interaction HTML element of choice, which do you think is better? Well, our choice was a no brainer, as we had decided the reasoning would be …

  • encase …
  • whatever element above is used …
  • within an HTML form action=[here’sLookingAtYouKid] method=GET navigational arrangement

… as our means of passing through user interaction findings. Well, this rules out “div contenteditable=true” as the “name” property of HTML “form” elements map from that element’s “value” property, something a “div contenteditable=true” lacks but a “textarea” element excels at (as well as its “innerHTML” initializing of data (ie. value) talents, as well).

This genericization drive also taught us that even if a monospaced font such as Courier New is enforced for the HTML “input type=button” there can be different “display looks” between data containing …

  • space (” “) character (as whitespace) … versus …
  • non-breaking space (“&nbsp;”) character

… the latter crucial for us to even up record lengths of the underlying “display data” used to make the “input type=button” elements “look” as the user would have intended, meaning that the non-breaking whitespace character (as one character) above is used for “display data” that is a “square block of text” so that “display:block” can work with CSS “font-size” and “width” and “height” to facilitate this HTML “input type=button” display look.

As you’d expect, coming back (ie. callback) via “action=[here’sLookingAtYouKid]” form navigation above means we need a document.body “onload” event function as way below to set up display settings and the creation of that “onclick” logic evaled “if logic” setting the global variable “gval” …


if (cnum != ("1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ")) { // true user interaction data here
gval='';
eval(ifstr); // for Horizontal and Vertical input type=button ... just Horizontal uses "ifstrone" variable instead
if (gval != '') { setTimeout(agval, 1000); }
}

… is set up at global initializations followed by the “function onl” document.body “onload” event logic below …


var gval='';
var cnum=location.search.split('content=')[1] ? decodeURIComponent(location.search.split('content=')[1].split('&')[0]).replace(/\+/g,' ') : "1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ";
while (cnum.indexOf(' ' + String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(13) + String.fromCharCode(10), ' [13][10]');
}
while (cnum.indexOf(' ' + String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(10) + String.fromCharCode(13), ' [10][13]');
}
while (cnum.indexOf(' ' + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(10), ' [10]');
}
while (cnum.indexOf(' ' + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(13), ' [13]');
}


while (cnum.indexOf(String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(String.fromCharCode(13) + String.fromCharCode(10), ' [13][10]');
}
while (cnum.indexOf(String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(String.fromCharCode(10) + String.fromCharCode(13), ' [10][13]');
}
while (cnum.indexOf(String.fromCharCode(10)) != -1) {
cnum=cnum.replace(String.fromCharCode(10), ' [10]');
}
while (cnum.indexOf(String.fromCharCode(13)) != -1) {
cnum=cnum.replace(String.fromCharCode(13), ' [13]');
}
cnum=cnum.replace(/\[13\]\[10\]/g, String.fromCharCode(13) + String.fromCharCode(10));
cnum=cnum.replace(/\[10\]\[13\]/g, String.fromCharCode(10) + String.fromCharCode(13));
cnum=cnum.replace(/\[13\]/g, String.fromCharCode(13));
cnum=cnum.replace(/\[10\]/g, String.fromCharCode(10));

var origcnumx=cnum; //.trim();
var cnumx=cnum; //.trim();

function onl() {
var ih='', jh=0, kh=0, lh=0, onelh=0, zero=0, eight=0;
maxlh=0;
if (cnum != ("1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ")) { // true user interaction data here
var ccnums=[];
if (origcnumx.indexOf(String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(13) + String.fromCharCode(10));
document.getElementById('content').rows='' + ccnums.length;
} else if (origcnumx.indexOf(String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(10) + String.fromCharCode(13));
document.getElementById('content').rows='' + ccnums.length;
} else if (origcnumx.indexOf(String.fromCharCode(13)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(13));
document.getElementById('content').rows='' + ccnums.length;
} else {
ccnums=origcnumx.split(String.fromCharCode(10));
document.getElementById('content').rows='' + ccnums.length;
}
//alert(ccnums.length);
for (jh=1; jh<=ccnums.length; jh++) {
if (eval('' + ccnums[eval(-1 + jh)].length) > eval('' + maxlh)) { maxlh=ccnums[eval(-1 + jh)].length; }
}
for (jh=1; jh<=cnumx.length; jh++) {
ih+="<span class=bxandy onclick='gval=this.innerHTML;'>" + cnumx.substring(eval(-1 + jh)).substring(0,1) + "</span>";
//if (lh == 0) { alert(cnumx.substring(eval(-1 + jh)).substring(0,1)); }
if ((cnumx + ' ').substring(eval(0 + jh)).substring(0,1)) {
zero=eight;
if (eight > 0) { eight--; }
} else {
zero=0;
}
if (ifstrone.indexOf('if ') == -1) {
ifstrone+=" if (eval(propx) <= eval(" + eval(1 + onelh) + "." + zero + " / " + cnumx.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstrone+=" else if (eval(propx) <= eval(" + eval(1 + onelh) + "." + zero + " / " + cnumx.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
if (ccnums.length == 1) {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
} else {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
}
lh++;
onelh++;
if (lh == ccnums[kh].length && kh < ccnums.length) {
if (lh < maxlh) {
while (lh < maxlh) {
ih+="<span class=bxandy onclick='gval=this.innerHTML;'> </span>";
if (ccnums.length == 1) {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ")) { gval=' '; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ")) { gval=' '; } ";
}
} else {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval=' '; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval=' '; } ";
}
}
lh++;
}
}
ih+="<br>";
kh++;
lh=0;
}
}
if (maxlh == 0) { maxlh=lh; }
//alert(ifstrone);
document.getElementById('ix').style.marginLeft='1px';
document.getElementById('ix').style.marginRight='3px';
if (/chrome/i.test( navigator.userAgent )) {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 8.0) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + maxlh) * 7.5) + 'px';
} else {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 6.75) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + maxlh) * 8.0) + 'px';
}
document.getElementById('ixandy').style.height='' + Math.floor(eval(eval('' + ccnums.length) * 14) + 4) + 'px';
document.getElementById('bxandy').innerHTML=ih.replace(/\>\ \<\/span\>/g, '>&nbsp;</span>');
document.getElementById('bx').innerHTML=ih.replace(/\<br\>/g,'');
document.getElementById('ix').title='Please click a character.';
document.getElementById('ixandy').title='Please click a character.';
} else {
document.getElementById('ix').style.marginLeft='1px';
document.getElementById('ix').style.marginRight='3px';
if (/chrome/i.test( navigator.userAgent )) {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 8.0) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + 6) * 7.5) + 'px';
} else {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 6.75) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + 6) * 8.0) + 'px';
}
document.getElementById('ixandy').style.height='' + Math.floor(eval(eval('' + '3') * 14) + 4) + 'px';
}
}

So, feel free to “use” the second draft multipurpose_buttons.html live run link to see what we mean.


Previous relevant Multipurpose Buttons Primer Tutorial is shown below.

Multipurpose Buttons Primer Tutorial

Multipurpose Buttons Primer Tutorial

At this blog we go hard at spruiking the qualities of HTML dropdown (ie. select) elements to do with …

  • the display brevity … as well as …
  • richness of content possibilities

… they can infer upon a webpage. At the expense of “the display brevity” we are keen to use a dropdown attribute “size” set so as to display all the content on the screen where …

  • it can sensibly fit on the screen … and …
  • it does not matter that mobile platforms do not recognize the “size” attribute “vertical expansion” of a dropdown that takes place on non-mobile platforms

Today, though, we’re here to show you that, with a bit of Javascript event logic, a …

  • button element … even better than an …
  • input type=button element

… can go some of the way to mimicking those qualities we like so much above, doing even better than the x (ie. horizontal) dimension limit of one that a dropdown has, to be able to fit more data content in horizontally, as a display mechanism you might say has “the display brevity” combined with content complexity you are after.

We wrote a proof of concept multipurpose_buttons.html, featuring the one Javascript “onclick” logic function as per …


var x=0, y=0, lastx=0,lasty=0;
var propx=0.0, propy=0.0;

function iclicked(event) {
var rectis=null, isok=true;;
if (('' + event.target.id) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'ixandy') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.333 && eval(propy) <= 0.333) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.333) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333 && eval(propy) <= 0.666) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.666) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666) {
gval='9';
setTimeout(agval, 1000);
} else {
gval='8';
setTimeout(agval, 1000);
}
}
} else if (('' + event.target.id) == 'ix') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.111) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.222) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.444) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.555) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.777) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.888) {
gval='8';
setTimeout(agval, 1000);
} else {
gval='9';
setTimeout(agval, 1000);
}
}
}
}

function agval() {
if (gval != '') {
alert('You clicked ' + gval);
gval='';
}
}

live run linked web application you can try for yourself regarding this, or see, in action, below …

Did you know?

Regarding the input type=button “Horizontal and Vertical Dimensions” element “look” above we needed help from the internet, thanks, to stop some web browsers such as Firefox, Chrome and Opera not “fattening out” the element height so as to show three lines of numbers, as per the CSS (thanks to html – word-wrap break-word does not work in this example – Stack Overflow and Wrapping an HTML input button's text value over multiple lines – Stack Overflow and html – Button height on Chrome – Stack Overflow) …


<style>
#ixandy {
font-size: 12px;
width: 36px;
height: 44px;

overflow-wrap: break-word;
word-wrap: break-word;

-ms-word-break: break-all;
/* This is the dangerous one in WebKit, as it breaks things wherever */
word-break: break-all;
/* Instead use this non-standard one: */
word-break: break-word;

/* Adds a hyphen where the word breaks, if supported (No Blink) */
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;

white-space: normal;

box-sizing: content-box;
-moz-box-sizing: content-box;
-ms-box-sizing: content-box;
-webkit-box-sizing: content-box;
}
</style>

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

Multipurpose Buttons Emoji Links Tutorial

Multipurpose Buttons Media Content Tutorial

Multipurpose Buttons Emoji Links Tutorial

We’re adding emojis into the mix of Multipurpose Buttons Media Content Tutorial functionality today. We often describe such additional functionality as an “emoji button” but for the purposes of clarity, today, we describe …

  • “a” links … with a …
  • emoji innerHTML (ie. look) … eg. &#127381; 🆕 “New” emoji we’re using as a “Restart” piece of functionality … button-like, in that they have styling …
  • style=”cursor:pointer;text-decoration:none;” … lacking the underlining “a” links typically have

… as new “emoji links” … for …

  • New (restart) 🆕
  • Email 📧
  • Circular borders ⭕
  • Glow 🌟

… as well as some new functionality that when you click outside characters and media within the “button” elements, a new popup window hones in on this clicked element.

All this can be set and moves with the web application as it recalls itself.

See this with the fourth draft multipurpose_buttons.html live run link.


Previous relevant Multipurpose Buttons Media Content Tutorial is shown below.

Multipurpose Buttons Media Content Tutorial

Multipurpose Buttons Media Content Tutorial

Were you around for the Window SessionStorage Client Versus Server Tutorial? We found a place where we could differentiate between …

… regarding the combination of …

  • sessionStorage‘s “ephemeral” storage suits … as well as a mechanism to …
  • not need (ie. be a functional replacement for) HTML form method=POST (instead, using method=GET with extra argument being the sessionStorage name used (for that tiny period of time)) for large amounts of data that normally require action=[somePHPserverPage]

… and so can remain a totally client facing web application even though we are doing similar work to what we did with Dynamic Timer Web Browser Reminder Media Tutorial when we added media file browsing into the mix by starting to interface with client_browsing.htm‘s File API talents within an HTML iframe “child” element.

And so on top of the progress up to yesterday’s Multipurpose Buttons Content Tutorial, today we allow users to be able to append …

  • img (image)
  • audio
  • video

… media data contents within the “button” (but not input type=button) element buttons.

Yet again, feel free to try the third draft multipurpose_buttons.html live run link to see what we mean by the use of sessionStorage to store (for that tiny length of time) and restore of these media data sets just within the “client facing wooooooorrrrrrllllllldddd”.


Previous relevant Multipurpose Buttons Content Tutorial is shown below.

Multipurpose Buttons Content Tutorial

Multipurpose Buttons Content Tutorial

Yesterday’s proof of concept “Multipurpose Buttons” web application of Multipurpose Buttons Primer Tutorial was pretty typical of many “proof of concept”s out there, not rocking the boat with the messy woooooorrrrllllllddd of what a user might enter as the “content” of those buttons. But that “proof of concept” idea is important to establish …

  • what is crucial … as well as …
  • what is important
  • what needs attention when genericizing (which is today’s work) … and up above all this …
  • whether the whole concept is feasible for controlled data content
  • whether the whole concept is feasible for user entered data content

… and happily, though there are some cross-browser tweaks (always a bit of a genericization “sour puss” for us), we think that last option above is indeed possible. The whole exercise has certainly borne out how much more powerful is the HTML “button” element for this multipurpose thinking, than is the “input type=button” (older) HTML element type, that “button” element now truly a “container” type of element (for us, the HTML elements where the property innerHTML has a proper meaning).

Proof of this is that this genericization drive today hardly concerned itself with any HTML “button” element concerns, rather it was a constant battle to make the HTML “input type=button” “hang in there”.

Okay then, if we are allowing a “vertical dimension” to our contents and we offer you the choice of …

  • textarea … versus …
  • div contenteditable=true

… as your user interaction HTML element of choice, which do you think is better? Well, our choice was a no brainer, as we had decided the reasoning would be …

  • encase …
  • whatever element above is used …
  • within an HTML form action=[here’sLookingAtYouKid] method=GET navigational arrangement

… as our means of passing through user interaction findings. Well, this rules out “div contenteditable=true” as the “name” property of HTML “form” elements map from that element’s “value” property, something a “div contenteditable=true” lacks but a “textarea” element excels at (as well as its “innerHTML” initializing of data (ie. value) talents, as well).

This genericization drive also taught us that even if a monospaced font such as Courier New is enforced for the HTML “input type=button” there can be different “display looks” between data containing …

  • space (” “) character (as whitespace) … versus …
  • non-breaking space (“&nbsp;”) character

… the latter crucial for us to even up record lengths of the underlying “display data” used to make the “input type=button” elements “look” as the user would have intended, meaning that the non-breaking whitespace character (as one character) above is used for “display data” that is a “square block of text” so that “display:block” can work with CSS “font-size” and “width” and “height” to facilitate this HTML “input type=button” display look.

As you’d expect, coming back (ie. callback) via “action=[here’sLookingAtYouKid]” form navigation above means we need a document.body “onload” event function as way below to set up display settings and the creation of that “onclick” logic evaled “if logic” setting the global variable “gval” …


if (cnum != ("1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ")) { // true user interaction data here
gval='';
eval(ifstr); // for Horizontal and Vertical input type=button ... just Horizontal uses "ifstrone" variable instead
if (gval != '') { setTimeout(agval, 1000); }
}

… is set up at global initializations followed by the “function onl” document.body “onload” event logic below …


var gval='';
var cnum=location.search.split('content=')[1] ? decodeURIComponent(location.search.split('content=')[1].split('&')[0]).replace(/\+/g,' ') : "1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ";
while (cnum.indexOf(' ' + String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(13) + String.fromCharCode(10), ' [13][10]');
}
while (cnum.indexOf(' ' + String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(10) + String.fromCharCode(13), ' [10][13]');
}
while (cnum.indexOf(' ' + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(10), ' [10]');
}
while (cnum.indexOf(' ' + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(13), ' [13]');
}


while (cnum.indexOf(String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(String.fromCharCode(13) + String.fromCharCode(10), ' [13][10]');
}
while (cnum.indexOf(String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(String.fromCharCode(10) + String.fromCharCode(13), ' [10][13]');
}
while (cnum.indexOf(String.fromCharCode(10)) != -1) {
cnum=cnum.replace(String.fromCharCode(10), ' [10]');
}
while (cnum.indexOf(String.fromCharCode(13)) != -1) {
cnum=cnum.replace(String.fromCharCode(13), ' [13]');
}
cnum=cnum.replace(/\[13\]\[10\]/g, String.fromCharCode(13) + String.fromCharCode(10));
cnum=cnum.replace(/\[10\]\[13\]/g, String.fromCharCode(10) + String.fromCharCode(13));
cnum=cnum.replace(/\[13\]/g, String.fromCharCode(13));
cnum=cnum.replace(/\[10\]/g, String.fromCharCode(10));

var origcnumx=cnum; //.trim();
var cnumx=cnum; //.trim();

function onl() {
var ih='', jh=0, kh=0, lh=0, onelh=0, zero=0, eight=0;
maxlh=0;
if (cnum != ("1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ")) { // true user interaction data here
var ccnums=[];
if (origcnumx.indexOf(String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(13) + String.fromCharCode(10));
document.getElementById('content').rows='' + ccnums.length;
} else if (origcnumx.indexOf(String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(10) + String.fromCharCode(13));
document.getElementById('content').rows='' + ccnums.length;
} else if (origcnumx.indexOf(String.fromCharCode(13)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(13));
document.getElementById('content').rows='' + ccnums.length;
} else {
ccnums=origcnumx.split(String.fromCharCode(10));
document.getElementById('content').rows='' + ccnums.length;
}
//alert(ccnums.length);
for (jh=1; jh<=ccnums.length; jh++) {
if (eval('' + ccnums[eval(-1 + jh)].length) > eval('' + maxlh)) { maxlh=ccnums[eval(-1 + jh)].length; }
}
for (jh=1; jh<=cnumx.length; jh++) {
ih+="<span class=bxandy onclick='gval=this.innerHTML;'>" + cnumx.substring(eval(-1 + jh)).substring(0,1) + "</span>";
//if (lh == 0) { alert(cnumx.substring(eval(-1 + jh)).substring(0,1)); }
if ((cnumx + ' ').substring(eval(0 + jh)).substring(0,1)) {
zero=eight;
if (eight > 0) { eight--; }
} else {
zero=0;
}
if (ifstrone.indexOf('if ') == -1) {
ifstrone+=" if (eval(propx) <= eval(" + eval(1 + onelh) + "." + zero + " / " + cnumx.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstrone+=" else if (eval(propx) <= eval(" + eval(1 + onelh) + "." + zero + " / " + cnumx.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
if (ccnums.length == 1) {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
} else {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
}
lh++;
onelh++;
if (lh == ccnums[kh].length && kh < ccnums.length) {
if (lh < maxlh) {
while (lh < maxlh) {
ih+="<span class=bxandy onclick='gval=this.innerHTML;'> </span>";
if (ccnums.length == 1) {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ")) { gval=' '; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ")) { gval=' '; } ";
}
} else {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval=' '; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval=' '; } ";
}
}
lh++;
}
}
ih+="<br>";
kh++;
lh=0;
}
}
if (maxlh == 0) { maxlh=lh; }
//alert(ifstrone);
document.getElementById('ix').style.marginLeft='1px';
document.getElementById('ix').style.marginRight='3px';
if (/chrome/i.test( navigator.userAgent )) {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 8.0) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + maxlh) * 7.5) + 'px';
} else {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 6.75) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + maxlh) * 8.0) + 'px';
}
document.getElementById('ixandy').style.height='' + Math.floor(eval(eval('' + ccnums.length) * 14) + 4) + 'px';
document.getElementById('bxandy').innerHTML=ih.replace(/\>\ \<\/span\>/g, '>&nbsp;</span>');
document.getElementById('bx').innerHTML=ih.replace(/\<br\>/g,'');
document.getElementById('ix').title='Please click a character.';
document.getElementById('ixandy').title='Please click a character.';
} else {
document.getElementById('ix').style.marginLeft='1px';
document.getElementById('ix').style.marginRight='3px';
if (/chrome/i.test( navigator.userAgent )) {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 8.0) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + 6) * 7.5) + 'px';
} else {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 6.75) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + 6) * 8.0) + 'px';
}
document.getElementById('ixandy').style.height='' + Math.floor(eval(eval('' + '3') * 14) + 4) + 'px';
}
}

So, feel free to “use” the second draft multipurpose_buttons.html live run link to see what we mean.


Previous relevant Multipurpose Buttons Primer Tutorial is shown below.

Multipurpose Buttons Primer Tutorial

Multipurpose Buttons Primer Tutorial

At this blog we go hard at spruiking the qualities of HTML dropdown (ie. select) elements to do with …

  • the display brevity … as well as …
  • richness of content possibilities

… they can infer upon a webpage. At the expense of “the display brevity” we are keen to use a dropdown attribute “size” set so as to display all the content on the screen where …

  • it can sensibly fit on the screen … and …
  • it does not matter that mobile platforms do not recognize the “size” attribute “vertical expansion” of a dropdown that takes place on non-mobile platforms

Today, though, we’re here to show you that, with a bit of Javascript event logic, a …

  • button element … even better than an …
  • input type=button element

… can go some of the way to mimicking those qualities we like so much above, doing even better than the x (ie. horizontal) dimension limit of one that a dropdown has, to be able to fit more data content in horizontally, as a display mechanism you might say has “the display brevity” combined with content complexity you are after.

We wrote a proof of concept multipurpose_buttons.html, featuring the one Javascript “onclick” logic function as per …


var x=0, y=0, lastx=0,lasty=0;
var propx=0.0, propy=0.0;

function iclicked(event) {
var rectis=null, isok=true;;
if (('' + event.target.id) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'ixandy') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.333 && eval(propy) <= 0.333) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.333) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333 && eval(propy) <= 0.666) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.666) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666) {
gval='9';
setTimeout(agval, 1000);
} else {
gval='8';
setTimeout(agval, 1000);
}
}
} else if (('' + event.target.id) == 'ix') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.111) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.222) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.444) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.555) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.777) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.888) {
gval='8';
setTimeout(agval, 1000);
} else {
gval='9';
setTimeout(agval, 1000);
}
}
}
}

function agval() {
if (gval != '') {
alert('You clicked ' + gval);
gval='';
}
}

live run linked web application you can try for yourself regarding this, or see, in action, below …

Did you know?

Regarding the input type=button “Horizontal and Vertical Dimensions” element “look” above we needed help from the internet, thanks, to stop some web browsers such as Firefox, Chrome and Opera not “fattening out” the element height so as to show three lines of numbers, as per the CSS (thanks to html – word-wrap break-word does not work in this example – Stack Overflow and Wrapping an HTML input button's text value over multiple lines – Stack Overflow and html – Button height on Chrome – Stack Overflow) …


<style>
#ixandy {
font-size: 12px;
width: 36px;
height: 44px;

overflow-wrap: break-word;
word-wrap: break-word;

-ms-word-break: break-all;
/* This is the dangerous one in WebKit, as it breaks things wherever */
word-break: break-all;
/* Instead use this non-standard one: */
word-break: break-word;

/* Adds a hyphen where the word breaks, if supported (No Blink) */
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;

white-space: normal;

box-sizing: content-box;
-moz-box-sizing: content-box;
-ms-box-sizing: content-box;
-webkit-box-sizing: content-box;
}
</style>

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

QR Code Covid Safe Check-in App Camera Tutorial

QR Code Covid Safe Check-in App Camera Tutorial

QR Code Covid Safe Check-in App Camera Tutorial

For us here in the New South Wales state of Australia regarding tracking movements in the time of Covid all the installation of the “Service NSW app” of QR Code Covid Safe Check-in App Tutorial is still all relevant, but we felt compelled to write this very brief blog posting to then bring the “QR” into the conversation. Why? Well, whenever QR Codes are discussed, it is useful to remember as a general principle, they were designed for the Camera apps of our modern day mobile devices. The advice of that previous blog posting had the Camera app within it, but we are here to tell you, once the apps are established on your mobile device, it is better to see the Camera app of your mobile device as the central player in your Covid Safe Check-In procedures (rather than the “Service NSW app” (in the case of NSW, Australia users)).

With this thinking as an optional, but advisable layer on top of the posting advice below, Covid Safe Check-In becomes as easy as …

  1. in establishment you want to Check In to …
  2. find their QR Code laminated set up …
  3. whip out your smart device (no dumb devices were harmed in the making of this blog posting)
  4. tap the Camera app …
  5. in that Camera app’s Photo mode of use focus to the QR Code …
  6. up the top a notification window opens as a link to whatever app helps out with the Covid Safe Check-In procedure, that today being the “Service NSW app”, so please tap that now … and …
  7. the rest is the same as previously described (which only would involve something like a single click of a “Check In” button for non first time users) …
  8. enjoy!
  9. don’t forget to tap the “Check Out” button on leaving the establishment (a lot like here in NSW we use our Opal transport card)

This centring of the Camera app in the procedure is both more intuitive as well as getting you used to how the future looks regarding the rise of QR Codes in our lives.


Previous relevant QR Code Covid Safe Check-in App Tutorial is shown below.

QR Code Covid Safe Check-in App Tutorial

QR Code Covid Safe Check-in App Tutorial

In this jurisdiction as far as Covid is concerned, the New South Wales state of Australia, many coffee shops and pubs and restaurants and other small businesses have opted to be able to say they are …

Covid Safe

… businesses. And though this can be achieved with …

  • good ol’ pen and paper logging of customers (on an honour system) … it has also been facilitated by …
  • in our increasingly online wooooorrrrllllld the use of a “Service NSW” app (for iOS and Android etcetera) section (on an honour system) called …

    COVID Safe Check-in

    … using QR Codes as the conduit to log a customer’s visit without the need for pen and paper

And so we see QR Code usage increase on when QR Codes Writer Primer Tutorial talked about them. In amongst the groceries at our supermarket, too, have noticed QR Codes used for some items, causing my “hinge swing” scan actions to be the go!

Today’s animated GIF presentation sees us installing the “Service NSW app” on our iPhone and using the “COVID Safe Check-in” functionality of that app to register my visit to a business registered to be a “COVID Safe business”. As a customer logging their presence …

  • arrange on your smart mobile device the installation of the “Service NSW app” (via, on iOS, in App Store app search for “Service NSW”) … Get … Open … the usual drill
  • tap “COVID Safe Check-in” section of app
  • tap OK button in response to …

    “Service NSW” Would Like to Access the Camera

  • Scan COVID Safe code

    Put your Camera up to the venue’s COVID Safe Check-in QR Code.

… as easy as falling off a log (or perhaps into a log … get it? tee hee).


Previous relevant QR Codes Writer Primer Tutorial is shown below.

QR Codes Writer Primer Tutorial

QR Codes Writer Primer Tutorial

There’s a good reason we read and/or listen before we write, generally. To understand something new, before you write anything, it is generally best to ask the question “Do I understand this concept?” ahead of using it. People who have “guessed” on a powerful command line statement that has fairly complex and important switches involved with its use, and you happened across a bad “simplification”, based on a guess, will know the “sinking feeling” this sometimes involves … and, of course, will swear to never do such a thing again?!

Okay, so regarding QR Code usage the reading aspects to it presented with QR Codes Reader Primer Tutorial as shown below were a good precursor to the “write a QR Code image” lesson of today’s tutorial. Happily, also, for our case, we are not using any of this QR Code in a mission critical scenario, which isn’t to say that there are Point of Sale (POS) systems out there on the net where everything going smoothly regarding the practicalities of QR Code usage is mission critical. We’re going to use it as an alternative navigation tool to the “Robert James Metcalfe Blog” in the RJM Programming landing page.

The QR Code reading discussion of the tutorial below worked off the fact that somebody had placed a QR Code image onto hardcopy or perhaps into a PDF file on the net, or perhaps somewhere else on the net. Where do you create such QR Code images that have this “navigational” relationship? We got our relationship between a …

  • QR Code image … later clickable and navigating to a …
  • URL

… via the use of this online free resource QRStuff.com … thanks. Its method is that the user types in a URL of interest and the website creates a downloadable QR Code image for that URL, that you “plonk” on your own website, and wait for the thousands and thousands of QR Code Reader users out there, to notice it, and use their QR Code Reader app software to scan the QR Code image, and navigate to the URL you defined above. Cute, huh?!

And so, presumably, that is why we are increasingly seeing QR Code images appear on billboards, presumably low enough down that we mere mortals … the “thousands and thousands of QR Code Reader users out there” … can get out our mobile device, with the continuous Internet access, and with QR Code Reader apps to scan (or photograph) away … possibly, some of us acting as though we’re just prejudging the winner of next year’s Archibald, and being able to claim that you were there before it became famous … but we digress.

We hope you get the gist of the tutorial picture today involving creating QR Code images and their use on the net.


Previous relevant QR Codes Reader Primer Tutorial is shown below.

QR Codes Reader Primer Tutorial

QR Codes Reader Primer Tutorial

Are you like me, and got told about QR Codes (those square curious looking barcodes) ages ago, and “let it ride” in your mind as “another fad” perhaps, rather than giving it a go. Well, today, finally we “gave it a go”? And it was really worth it.

Actually, though, it seems to still be the case that “supply” (of websites that deploy it) is the major stumbling block here. We “deployed” QR Code Reader functionality here on an iPad by downloading and installing a mobile app. So far not too hard. But let me take you to “why now?”. Well, it was a “where” of life scenario, the sucker punch for me … a map with QR Codes next to places on the map whereby that QR Code read by a QR Code Reader app, effectively photographing it, leads you to “further reading” webpages.

So, yes, QR Code usage is asking, in all practicalities of usage, for hard copy input, or another computer device screen with a QR Code showing, separate to the device you are using with the QR Code Reader app, that you photograph, to make all this functionality “shine” … but shine it did, in a “woh” moment, at least for us, and maybe for you?!

So we show you a stream of consciousness presentation of us finding out about “side stories” to the Great North Trail, here, in Sydney, bushwalking out of the Lane Cove River National Park heading north, and investigations halfway up the track on the way through to Newcastle.

To summarise QR Code functionality usage the “ingredients” required are …

  • Connection to the Internet
  • QR Code Reader software
  • Hard copy with QR Codes showing or another computer device screen with QR Codes showing, perhaps via a PDF file sent to you in an email, maybe
  • Photographing QR Codes via the QR Code Reader app’s scanner … from there the fun continues

Hope you get something out of the presentation.


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

Multipurpose Buttons Media Content Tutorial

Multipurpose Buttons Media Content Tutorial

Multipurpose Buttons Media Content Tutorial

Were you around for the Window SessionStorage Client Versus Server Tutorial? We found a place where we could differentiate between …

… regarding the combination of …

  • sessionStorage‘s “ephemeral” storage suits … as well as a mechanism to …
  • not need (ie. be a functional replacement for) HTML form method=POST (instead, using method=GET with extra argument being the sessionStorage name used (for that tiny period of time)) for large amounts of data that normally require action=[somePHPserverPage]

… and so can remain a totally client facing web application even though we are doing similar work to what we did with Dynamic Timer Web Browser Reminder Media Tutorial when we added media file browsing into the mix by starting to interface with client_browsing.htm‘s File API talents within an HTML iframe “child” element.

And so on top of the progress up to yesterday’s Multipurpose Buttons Content Tutorial, today we allow users to be able to append …

  • img (image)
  • audio
  • video

… media data contents within the “button” (but not input type=button) element buttons.

Yet again, feel free to try the third draft multipurpose_buttons.html live run link to see what we mean by the use of sessionStorage to store (for that tiny length of time) and restore of these media data sets just within the “client facing wooooooorrrrrrllllllldddd”.


Previous relevant Multipurpose Buttons Content Tutorial is shown below.

Multipurpose Buttons Content Tutorial

Multipurpose Buttons Content Tutorial

Yesterday’s proof of concept “Multipurpose Buttons” web application of Multipurpose Buttons Primer Tutorial was pretty typical of many “proof of concept”s out there, not rocking the boat with the messy woooooorrrrllllllddd of what a user might enter as the “content” of those buttons. But that “proof of concept” idea is important to establish …

  • what is crucial … as well as …
  • what is important
  • what needs attention when genericizing (which is today’s work) … and up above all this …
  • whether the whole concept is feasible for controlled data content
  • whether the whole concept is feasible for user entered data content

… and happily, though there are some cross-browser tweaks (always a bit of a genericization “sour puss” for us), we think that last option above is indeed possible. The whole exercise has certainly borne out how much more powerful is the HTML “button” element for this multipurpose thinking, than is the “input type=button” (older) HTML element type, that “button” element now truly a “container” type of element (for us, the HTML elements where the property innerHTML has a proper meaning).

Proof of this is that this genericization drive today hardly concerned itself with any HTML “button” element concerns, rather it was a constant battle to make the HTML “input type=button” “hang in there”.

Okay then, if we are allowing a “vertical dimension” to our contents and we offer you the choice of …

  • textarea … versus …
  • div contenteditable=true

… as your user interaction HTML element of choice, which do you think is better? Well, our choice was a no brainer, as we had decided the reasoning would be …

  • encase …
  • whatever element above is used …
  • within an HTML form action=[here’sLookingAtYouKid] method=GET navigational arrangement

… as our means of passing through user interaction findings. Well, this rules out “div contenteditable=true” as the “name” property of HTML “form” elements map from that element’s “value” property, something a “div contenteditable=true” lacks but a “textarea” element excels at (as well as its “innerHTML” initializing of data (ie. value) talents, as well).

This genericization drive also taught us that even if a monospaced font such as Courier New is enforced for the HTML “input type=button” there can be different “display looks” between data containing …

  • space (” “) character (as whitespace) … versus …
  • non-breaking space (“&nbsp;”) character

… the latter crucial for us to even up record lengths of the underlying “display data” used to make the “input type=button” elements “look” as the user would have intended, meaning that the non-breaking whitespace character (as one character) above is used for “display data” that is a “square block of text” so that “display:block” can work with CSS “font-size” and “width” and “height” to facilitate this HTML “input type=button” display look.

As you’d expect, coming back (ie. callback) via “action=[here’sLookingAtYouKid]” form navigation above means we need a document.body “onload” event function as way below to set up display settings and the creation of that “onclick” logic evaled “if logic” setting the global variable “gval” …


if (cnum != ("1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ")) { // true user interaction data here
gval='';
eval(ifstr); // for Horizontal and Vertical input type=button ... just Horizontal uses "ifstrone" variable instead
if (gval != '') { setTimeout(agval, 1000); }
}

… is set up at global initializations followed by the “function onl” document.body “onload” event logic below …


var gval='';
var cnum=location.search.split('content=')[1] ? decodeURIComponent(location.search.split('content=')[1].split('&')[0]).replace(/\+/g,' ') : "1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ";
while (cnum.indexOf(' ' + String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(13) + String.fromCharCode(10), ' [13][10]');
}
while (cnum.indexOf(' ' + String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(10) + String.fromCharCode(13), ' [10][13]');
}
while (cnum.indexOf(' ' + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(10), ' [10]');
}
while (cnum.indexOf(' ' + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(13), ' [13]');
}


while (cnum.indexOf(String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(String.fromCharCode(13) + String.fromCharCode(10), ' [13][10]');
}
while (cnum.indexOf(String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(String.fromCharCode(10) + String.fromCharCode(13), ' [10][13]');
}
while (cnum.indexOf(String.fromCharCode(10)) != -1) {
cnum=cnum.replace(String.fromCharCode(10), ' [10]');
}
while (cnum.indexOf(String.fromCharCode(13)) != -1) {
cnum=cnum.replace(String.fromCharCode(13), ' [13]');
}
cnum=cnum.replace(/\[13\]\[10\]/g, String.fromCharCode(13) + String.fromCharCode(10));
cnum=cnum.replace(/\[10\]\[13\]/g, String.fromCharCode(10) + String.fromCharCode(13));
cnum=cnum.replace(/\[13\]/g, String.fromCharCode(13));
cnum=cnum.replace(/\[10\]/g, String.fromCharCode(10));

var origcnumx=cnum; //.trim();
var cnumx=cnum; //.trim();

function onl() {
var ih='', jh=0, kh=0, lh=0, onelh=0, zero=0, eight=0;
maxlh=0;
if (cnum != ("1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ")) { // true user interaction data here
var ccnums=[];
if (origcnumx.indexOf(String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(13) + String.fromCharCode(10));
document.getElementById('content').rows='' + ccnums.length;
} else if (origcnumx.indexOf(String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(10) + String.fromCharCode(13));
document.getElementById('content').rows='' + ccnums.length;
} else if (origcnumx.indexOf(String.fromCharCode(13)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(13));
document.getElementById('content').rows='' + ccnums.length;
} else {
ccnums=origcnumx.split(String.fromCharCode(10));
document.getElementById('content').rows='' + ccnums.length;
}
//alert(ccnums.length);
for (jh=1; jh<=ccnums.length; jh++) {
if (eval('' + ccnums[eval(-1 + jh)].length) > eval('' + maxlh)) { maxlh=ccnums[eval(-1 + jh)].length; }
}
for (jh=1; jh<=cnumx.length; jh++) {
ih+="<span class=bxandy onclick='gval=this.innerHTML;'>" + cnumx.substring(eval(-1 + jh)).substring(0,1) + "</span>";
//if (lh == 0) { alert(cnumx.substring(eval(-1 + jh)).substring(0,1)); }
if ((cnumx + ' ').substring(eval(0 + jh)).substring(0,1)) {
zero=eight;
if (eight > 0) { eight--; }
} else {
zero=0;
}
if (ifstrone.indexOf('if ') == -1) {
ifstrone+=" if (eval(propx) <= eval(" + eval(1 + onelh) + "." + zero + " / " + cnumx.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstrone+=" else if (eval(propx) <= eval(" + eval(1 + onelh) + "." + zero + " / " + cnumx.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
if (ccnums.length == 1) {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
} else {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
}
lh++;
onelh++;
if (lh == ccnums[kh].length && kh < ccnums.length) {
if (lh < maxlh) {
while (lh < maxlh) {
ih+="<span class=bxandy onclick='gval=this.innerHTML;'> </span>";
if (ccnums.length == 1) {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ")) { gval=' '; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ")) { gval=' '; } ";
}
} else {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval=' '; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval=' '; } ";
}
}
lh++;
}
}
ih+="<br>";
kh++;
lh=0;
}
}
if (maxlh == 0) { maxlh=lh; }
//alert(ifstrone);
document.getElementById('ix').style.marginLeft='1px';
document.getElementById('ix').style.marginRight='3px';
if (/chrome/i.test( navigator.userAgent )) {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 8.0) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + maxlh) * 7.5) + 'px';
} else {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 6.75) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + maxlh) * 8.0) + 'px';
}
document.getElementById('ixandy').style.height='' + Math.floor(eval(eval('' + ccnums.length) * 14) + 4) + 'px';
document.getElementById('bxandy').innerHTML=ih.replace(/\>\ \<\/span\>/g, '>&nbsp;</span>');
document.getElementById('bx').innerHTML=ih.replace(/\<br\>/g,'');
document.getElementById('ix').title='Please click a character.';
document.getElementById('ixandy').title='Please click a character.';
} else {
document.getElementById('ix').style.marginLeft='1px';
document.getElementById('ix').style.marginRight='3px';
if (/chrome/i.test( navigator.userAgent )) {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 8.0) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + 6) * 7.5) + 'px';
} else {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 6.75) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + 6) * 8.0) + 'px';
}
document.getElementById('ixandy').style.height='' + Math.floor(eval(eval('' + '3') * 14) + 4) + 'px';
}
}

So, feel free to “use” the second draft multipurpose_buttons.html live run link to see what we mean.


Previous relevant Multipurpose Buttons Primer Tutorial is shown below.

Multipurpose Buttons Primer Tutorial

Multipurpose Buttons Primer Tutorial

At this blog we go hard at spruiking the qualities of HTML dropdown (ie. select) elements to do with …

  • the display brevity … as well as …
  • richness of content possibilities

… they can infer upon a webpage. At the expense of “the display brevity” we are keen to use a dropdown attribute “size” set so as to display all the content on the screen where …

  • it can sensibly fit on the screen … and …
  • it does not matter that mobile platforms do not recognize the “size” attribute “vertical expansion” of a dropdown that takes place on non-mobile platforms

Today, though, we’re here to show you that, with a bit of Javascript event logic, a …

  • button element … even better than an …
  • input type=button element

… can go some of the way to mimicking those qualities we like so much above, doing even better than the x (ie. horizontal) dimension limit of one that a dropdown has, to be able to fit more data content in horizontally, as a display mechanism you might say has “the display brevity” combined with content complexity you are after.

We wrote a proof of concept multipurpose_buttons.html, featuring the one Javascript “onclick” logic function as per …


var x=0, y=0, lastx=0,lasty=0;
var propx=0.0, propy=0.0;

function iclicked(event) {
var rectis=null, isok=true;;
if (('' + event.target.id) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'ixandy') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.333 && eval(propy) <= 0.333) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.333) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333 && eval(propy) <= 0.666) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.666) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666) {
gval='9';
setTimeout(agval, 1000);
} else {
gval='8';
setTimeout(agval, 1000);
}
}
} else if (('' + event.target.id) == 'ix') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.111) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.222) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.444) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.555) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.777) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.888) {
gval='8';
setTimeout(agval, 1000);
} else {
gval='9';
setTimeout(agval, 1000);
}
}
}
}

function agval() {
if (gval != '') {
alert('You clicked ' + gval);
gval='';
}
}

live run linked web application you can try for yourself regarding this, or see, in action, below …

Did you know?

Regarding the input type=button “Horizontal and Vertical Dimensions” element “look” above we needed help from the internet, thanks, to stop some web browsers such as Firefox, Chrome and Opera not “fattening out” the element height so as to show three lines of numbers, as per the CSS (thanks to html – word-wrap break-word does not work in this example – Stack Overflow and Wrapping an HTML input button's text value over multiple lines – Stack Overflow and html – Button height on Chrome – Stack Overflow) …


<style>
#ixandy {
font-size: 12px;
width: 36px;
height: 44px;

overflow-wrap: break-word;
word-wrap: break-word;

-ms-word-break: break-all;
/* This is the dangerous one in WebKit, as it breaks things wherever */
word-break: break-all;
/* Instead use this non-standard one: */
word-break: break-word;

/* Adds a hyphen where the word breaks, if supported (No Blink) */
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;

white-space: normal;

box-sizing: content-box;
-moz-box-sizing: content-box;
-ms-box-sizing: content-box;
-webkit-box-sizing: content-box;
}
</style>

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

Multipurpose Buttons Content Tutorial

Multipurpose Buttons Content Tutorial

Multipurpose Buttons Content Tutorial

Yesterday’s proof of concept “Multipurpose Buttons” web application of Multipurpose Buttons Primer Tutorial was pretty typical of many “proof of concept”s out there, not rocking the boat with the messy woooooorrrrllllllddd of what a user might enter as the “content” of those buttons. But that “proof of concept” idea is important to establish …

  • what is crucial … as well as …
  • what is important
  • what needs attention when genericizing (which is today’s work) … and up above all this …
  • whether the whole concept is feasible for controlled data content
  • whether the whole concept is feasible for user entered data content

… and happily, though there are some cross-browser tweaks (always a bit of a genericization “sour puss” for us), we think that last option above is indeed possible. The whole exercise has certainly borne out how much more powerful is the HTML “button” element for this multipurpose thinking, than is the “input type=button” (older) HTML element type, that “button” element now truly a “container” type of element (for us, the HTML elements where the property innerHTML has a proper meaning).

Proof of this is that this genericization drive today hardly concerned itself with any HTML “button” element concerns, rather it was a constant battle to make the HTML “input type=button” “hang in there”.

Okay then, if we are allowing a “vertical dimension” to our contents and we offer you the choice of …

  • textarea … versus …
  • div contenteditable=true

… as your user interaction HTML element of choice, which do you think is better? Well, our choice was a no brainer, as we had decided the reasoning would be …

  • encase …
  • whatever element above is used …
  • within an HTML form action=[here’sLookingAtYouKid] method=GET navigational arrangement

… as our means of passing through user interaction findings. Well, this rules out “div contenteditable=true” as the “name” property of HTML “form” elements map from that element’s “value” property, something a “div contenteditable=true” lacks but a “textarea” element excels at (as well as its “innerHTML” initializing of data (ie. value) talents, as well).

This genericization drive also taught us that even if a monospaced font such as Courier New is enforced for the HTML “input type=button” there can be different “display looks” between data containing …

  • space (” “) character (as whitespace) … versus …
  • non-breaking space (“&nbsp;”) character

… the latter crucial for us to even up record lengths of the underlying “display data” used to make the “input type=button” elements “look” as the user would have intended, meaning that the non-breaking whitespace character (as one character) above is used for “display data” that is a “square block of text” so that “display:block” can work with CSS “font-size” and “width” and “height” to facilitate this HTML “input type=button” display look.

As you’d expect, coming back (ie. callback) via “action=[here’sLookingAtYouKid]” form navigation above means we need a document.body “onload” event function as way below to set up display settings and the creation of that “onclick” logic evaled “if logic” setting the global variable “gval” …


if (cnum != ("1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ")) { // true user interaction data here
gval='';
eval(ifstr); // for Horizontal and Vertical input type=button ... just Horizontal uses "ifstrone" variable instead
if (gval != '') { setTimeout(agval, 1000); }
}

… is set up at global initializations followed by the “function onl” document.body “onload” event logic below …


var gval='';
var cnum=location.search.split('content=')[1] ? decodeURIComponent(location.search.split('content=')[1].split('&')[0]).replace(/\+/g,' ') : "1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ";
while (cnum.indexOf(' ' + String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(13) + String.fromCharCode(10), ' [13][10]');
}
while (cnum.indexOf(' ' + String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(10) + String.fromCharCode(13), ' [10][13]');
}
while (cnum.indexOf(' ' + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(10), ' [10]');
}
while (cnum.indexOf(' ' + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(' ' + String.fromCharCode(13), ' [13]');
}


while (cnum.indexOf(String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
cnum=cnum.replace(String.fromCharCode(13) + String.fromCharCode(10), ' [13][10]');
}
while (cnum.indexOf(String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
cnum=cnum.replace(String.fromCharCode(10) + String.fromCharCode(13), ' [10][13]');
}
while (cnum.indexOf(String.fromCharCode(10)) != -1) {
cnum=cnum.replace(String.fromCharCode(10), ' [10]');
}
while (cnum.indexOf(String.fromCharCode(13)) != -1) {
cnum=cnum.replace(String.fromCharCode(13), ' [13]');
}
cnum=cnum.replace(/\[13\]\[10\]/g, String.fromCharCode(13) + String.fromCharCode(10));
cnum=cnum.replace(/\[10\]\[13\]/g, String.fromCharCode(10) + String.fromCharCode(13));
cnum=cnum.replace(/\[13\]/g, String.fromCharCode(13));
cnum=cnum.replace(/\[10\]/g, String.fromCharCode(10));

var origcnumx=cnum; //.trim();
var cnumx=cnum; //.trim();

function onl() {
var ih='', jh=0, kh=0, lh=0, onelh=0, zero=0, eight=0;
maxlh=0;
if (cnum != ("1 2 3 " + String.fromCharCode(10) + "4 5 6 " + String.fromCharCode(10) + "7 8 9 ")) { // true user interaction data here
var ccnums=[];
if (origcnumx.indexOf(String.fromCharCode(13) + String.fromCharCode(10)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(13) + String.fromCharCode(10));
document.getElementById('content').rows='' + ccnums.length;
} else if (origcnumx.indexOf(String.fromCharCode(10) + String.fromCharCode(13)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(10) + String.fromCharCode(13));
document.getElementById('content').rows='' + ccnums.length;
} else if (origcnumx.indexOf(String.fromCharCode(13)) != -1) {
ccnums=origcnumx.split(String.fromCharCode(13));
document.getElementById('content').rows='' + ccnums.length;
} else {
ccnums=origcnumx.split(String.fromCharCode(10));
document.getElementById('content').rows='' + ccnums.length;
}
//alert(ccnums.length);
for (jh=1; jh<=ccnums.length; jh++) {
if (eval('' + ccnums[eval(-1 + jh)].length) > eval('' + maxlh)) { maxlh=ccnums[eval(-1 + jh)].length; }
}
for (jh=1; jh<=cnumx.length; jh++) {
ih+="<span class=bxandy onclick='gval=this.innerHTML;'>" + cnumx.substring(eval(-1 + jh)).substring(0,1) + "</span>";
//if (lh == 0) { alert(cnumx.substring(eval(-1 + jh)).substring(0,1)); }
if ((cnumx + ' ').substring(eval(0 + jh)).substring(0,1)) {
zero=eight;
if (eight > 0) { eight--; }
} else {
zero=0;
}
if (ifstrone.indexOf('if ') == -1) {
ifstrone+=" if (eval(propx) <= eval(" + eval(1 + onelh) + "." + zero + " / " + cnumx.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstrone+=" else if (eval(propx) <= eval(" + eval(1 + onelh) + "." + zero + " / " + cnumx.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
if (ccnums.length == 1) {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
} else {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + "." + zero + " / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval='" + cnumx.substring(eval(-1 + jh)).substring(0,2) + "'; } ";
}
}
lh++;
onelh++;
if (lh == ccnums[kh].length && kh < ccnums.length) {
if (lh < maxlh) {
while (lh < maxlh) {
ih+="<span class=bxandy onclick='gval=this.innerHTML;'> </span>";
if (ccnums.length == 1) {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ")) { gval=' '; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ")) { gval=' '; } ";
}
} else {
if (ifstr.indexOf('if ') == -1) {
ifstr+=" if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval=' '; } ";
} else {
ifstr+=" else if (eval(propx) <= eval(" + eval(1 + lh) + ".0 / " + maxlh + ") && eval(propy) <= eval(" + eval(1 + kh) + ".0 / " + ccnums.length + ")) { gval=' '; } ";
}
}
lh++;
}
}
ih+="<br>";
kh++;
lh=0;
}
}
if (maxlh == 0) { maxlh=lh; }
//alert(ifstrone);
document.getElementById('ix').style.marginLeft='1px';
document.getElementById('ix').style.marginRight='3px';
if (/chrome/i.test( navigator.userAgent )) {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 8.0) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + maxlh) * 7.5) + 'px';
} else {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 6.75) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + maxlh) * 8.0) + 'px';
}
document.getElementById('ixandy').style.height='' + Math.floor(eval(eval('' + ccnums.length) * 14) + 4) + 'px';
document.getElementById('bxandy').innerHTML=ih.replace(/\>\ \<\/span\>/g, '>&nbsp;</span>');
document.getElementById('bx').innerHTML=ih.replace(/\<br\>/g,'');
document.getElementById('ix').title='Please click a character.';
document.getElementById('ixandy').title='Please click a character.';
} else {
document.getElementById('ix').style.marginLeft='1px';
document.getElementById('ix').style.marginRight='3px';
if (/chrome/i.test( navigator.userAgent )) {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 8.0) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + 6) * 7.5) + 'px';
} else {
document.getElementById('ix').style.width='' + Math.round(eval(0 + cnumx.length) * 6.75) + 'px';
document.getElementById('ixandy').style.width='' + Math.round(eval(0 + 6) * 8.0) + 'px';
}
document.getElementById('ixandy').style.height='' + Math.floor(eval(eval('' + '3') * 14) + 4) + 'px';
}
}

So, feel free to “use” the second draft multipurpose_buttons.html live run link to see what we mean.


Previous relevant Multipurpose Buttons Primer Tutorial is shown below.

Multipurpose Buttons Primer Tutorial

Multipurpose Buttons Primer Tutorial

At this blog we go hard at spruiking the qualities of HTML dropdown (ie. select) elements to do with …

  • the display brevity … as well as …
  • richness of content possibilities

… they can infer upon a webpage. At the expense of “the display brevity” we are keen to use a dropdown attribute “size” set so as to display all the content on the screen where …

  • it can sensibly fit on the screen … and …
  • it does not matter that mobile platforms do not recognize the “size” attribute “vertical expansion” of a dropdown that takes place on non-mobile platforms

Today, though, we’re here to show you that, with a bit of Javascript event logic, a …

  • button element … even better than an …
  • input type=button element

… can go some of the way to mimicking those qualities we like so much above, doing even better than the x (ie. horizontal) dimension limit of one that a dropdown has, to be able to fit more data content in horizontally, as a display mechanism you might say has “the display brevity” combined with content complexity you are after.

We wrote a proof of concept multipurpose_buttons.html, featuring the one Javascript “onclick” logic function as per …


var x=0, y=0, lastx=0,lasty=0;
var propx=0.0, propy=0.0;

function iclicked(event) {
var rectis=null, isok=true;;
if (('' + event.target.id) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'ixandy') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.333 && eval(propy) <= 0.333) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.333) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333 && eval(propy) <= 0.666) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.666) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666) {
gval='9';
setTimeout(agval, 1000);
} else {
gval='8';
setTimeout(agval, 1000);
}
}
} else if (('' + event.target.id) == 'ix') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.111) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.222) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.444) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.555) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.777) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.888) {
gval='8';
setTimeout(agval, 1000);
} else {
gval='9';
setTimeout(agval, 1000);
}
}
}
}

function agval() {
if (gval != '') {
alert('You clicked ' + gval);
gval='';
}
}

live run linked web application you can try for yourself regarding this, or see, in action, below …

Did you know?

Regarding the input type=button “Horizontal and Vertical Dimensions” element “look” above we needed help from the internet, thanks, to stop some web browsers such as Firefox, Chrome and Opera not “fattening out” the element height so as to show three lines of numbers, as per the CSS (thanks to html – word-wrap break-word does not work in this example – Stack Overflow and Wrapping an HTML input button's text value over multiple lines – Stack Overflow and html – Button height on Chrome – Stack Overflow) …


<style>
#ixandy {
font-size: 12px;
width: 36px;
height: 44px;

overflow-wrap: break-word;
word-wrap: break-word;

-ms-word-break: break-all;
/* This is the dangerous one in WebKit, as it breaks things wherever */
word-break: break-all;
/* Instead use this non-standard one: */
word-break: break-word;

/* Adds a hyphen where the word breaks, if supported (No Blink) */
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;

white-space: normal;

box-sizing: content-box;
-moz-box-sizing: content-box;
-ms-box-sizing: content-box;
-webkit-box-sizing: content-box;
}
</style>

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

Multipurpose Buttons Primer Tutorial

Multipurpose Buttons Primer Tutorial

Multipurpose Buttons Primer Tutorial

At this blog we go hard at spruiking the qualities of HTML dropdown (ie. select) elements to do with …

  • the display brevity … as well as …
  • richness of content possibilities

… they can infer upon a webpage. At the expense of “the display brevity” we are keen to use a dropdown attribute “size” set so as to display all the content on the screen where …

  • it can sensibly fit on the screen … and …
  • it does not matter that mobile platforms do not recognize the “size” attribute “vertical expansion” of a dropdown that takes place on non-mobile platforms

Today, though, we’re here to show you that, with a bit of Javascript event logic, a …

  • button element … even better than an …
  • input type=button element

… can go some of the way to mimicking those qualities we like so much above, doing even better than the x (ie. horizontal) dimension limit of one that a dropdown has, to be able to fit more data content in horizontally, as a display mechanism you might say has “the display brevity” combined with content complexity you are after.

We wrote a proof of concept multipurpose_buttons.html, featuring the one Javascript “onclick” logic function as per …


var x=0, y=0, lastx=0,lasty=0;
var propx=0.0, propy=0.0;

function iclicked(event) {
var rectis=null, isok=true;;
if (('' + event.target.id) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bxandy') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.className) == 'bx') {
setTimeout(agval, 1000);
} else if (('' + event.target.id) == 'ixandy') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.333 && eval(propy) <= 0.333) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.333) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333 && eval(propy) <= 0.666) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666 && eval(propy) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propy) <= 0.666) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) >= 0.666) {
gval='9';
setTimeout(agval, 1000);
} else {
gval='8';
setTimeout(agval, 1000);
}
}
} else if (('' + event.target.id) == 'ix') {
rectis=event.target.getBoundingClientRect();
if (event.touches) { // thanks to https://stackoverflow.com/questions/24567441/how-do-i-detect-two-fingers-at-touchstart-in-javascript
if (event.touches.length > 1) { isok=false; }
}
if (isok) {
if (event.touches) {
var touches1 = event.changedTouches;
var first1 = touches1[0];
x = first1.clientX;
y = first1.clientY;
} else if (event.clientX || event.clientY) {
x = event.clientX; // - elemLeft;
y = event.clientY; // - elemTop;
} else {
x = event.pageX; // - elemLeft;
y = event.pageY; // - elemTop;
}
lastx=x;
lasty=y;
propx=eval(eval(x - rectis.x) / rectis.width);
propy=eval(eval(y - rectis.y) / rectis.height);
if (eval(propx) <= 0.111) {
gval='1';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.222) {
gval='2';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.333) {
gval='3';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.444) {
gval='4';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.555) {
gval='5';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.666) {
gval='6';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.777) {
gval='7';
setTimeout(agval, 1000);
} else if (eval(propx) <= 0.888) {
gval='8';
setTimeout(agval, 1000);
} else {
gval='9';
setTimeout(agval, 1000);
}
}
}
}

function agval() {
if (gval != '') {
alert('You clicked ' + gval);
gval='';
}
}

live run linked web application you can try for yourself regarding this, or see, in action, below …

Did you know?

Regarding the input type=button “Horizontal and Vertical Dimensions” element “look” above we needed help from the internet, thanks, to stop some web browsers such as Firefox, Chrome and Opera not “fattening out” the element height so as to show three lines of numbers, as per the CSS (thanks to html – word-wrap break-word does not work in this example – Stack Overflow and Wrapping an HTML input button's text value over multiple lines – Stack Overflow and html – Button height on Chrome – Stack Overflow) …


<style>
#ixandy {
font-size: 12px;
width: 36px;
height: 44px;

overflow-wrap: break-word;
word-wrap: break-word;

-ms-word-break: break-all;
/* This is the dangerous one in WebKit, as it breaks things wherever */
word-break: break-all;
/* Instead use this non-standard one: */
word-break: break-word;

/* Adds a hyphen where the word breaks, if supported (No Blink) */
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;

white-space: normal;

box-sizing: content-box;
-moz-box-sizing: content-box;
-ms-box-sizing: content-box;
-webkit-box-sizing: content-box;
}
</style>

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

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

CentOS Exim Mail Server Sanity Check Testing Tutorial

CentOS Exim Mail Server Sanity Check Testing Tutorial

CentOS Exim Mail Server Sanity Check Testing Tutorial

To send an email often relies on a Mail Server and accompanying software and hardware and networking to support just such a Mail Server. Here at our Linux web server (CentOS) here at RJM Programming we oversee an Exim Mail Server we last talked about with CentOS Exim Advanced Configuration Primer Tutorial.

In the normal case of events “exim” does its job sending and receiving email related to email addresses ending in “@rjmprogramming.com.au” with little worry, and so we are usually not worried unduly concerning its running, but yesterday we had occasion to be curious, because to proceed with our coding we wanted to have an email “go through to the keeper” (so to speak). But they weren’t, and the issue concerned an email sent via PHP mail using a sender whose email address ended in “@rjmprogramming.com.au” so the Exim Mail Server comes into play (unlike a client email application mailto: type of email).

We were using Ajax/FormData techniques to send the email and according to error checking at this client end of things, “no worries”. PHP logs? No apparent issues. So what next?

Thanks, Gooooooooggggggllllllee led us to the incredibly useful send a testmail via exim – makandra Operations, thanks, getting us to


# exim -v rmetcalfe41@gmail.com
From: rmetcalfe@rjmprogramming.com.au
Subject: Foobar
Text Text Text

I like Pie!
<Command(Mac)/Ctrl(Windows)+D>

… the results of actions above helping us see what the issues were, holding up the email. Much later it (ie. the original email) arrived, as well as …


Previous relevant CentOS Exim Advanced Configuration Primer Tutorial is shown below.

CentOS Exim Advanced Configuration Primer Tutorial

CentOS Exim Advanced Configuration Primer Tutorial

There are two file resource aspects to watch out for regarding a web server hard disk storage …

  • hard disk space
  • hard disk inode count (for Linux and unix web servers)

… which can, respectively, be monitored by Linux commands …

  • df -k /
  • df -i /

On our CentOS rjmprogramming.com.au web server recently we had occasion to do a check of this, and wanted to improve the web server hard disk situation for both measures, picking the /var folder of our web server. So we executed, respectively …

  • find /var -xdev -type f -size +100M
  • find /var -mtime -1 -ls

… the latter one being a list of files on /var modified in the last day being our idea to try to see what daily log filing might be contributing big time to hard disk inode usage. And that’s where we found out this way that our Exim Mail Server logs extensively, and that we could do without those in folders off …


/var/spool/exim/msglog/

We tried the latter of two deletion ideas we show below …

  • all at once via …

    cd /var/spool/exim
    find msglog -type f -exec rm -rf {} \;
  • broken up … via a series of deletions of the ilk …

    cd /var/spool/exim/msglog
    rm -f A/*
    rm -f a/*

Then the next job was to stop Exim remaking these logs and wish to thank this useful link for great advice here, that led to this advice we give …

  1. log in to WHM cPanel
  2. in search bar type “Exim”
  3. click the “Exim Configuration Manager”
  4. click “Advanced Editor” tab (up the top)
  5. click the blue “Add additional configuration setting” button well down the webpage
  6. click “message_logs” in left hand drop down
  7. set value of this setting to “false”
  8. click blue “Save” button down the bottom of webpage to complete the steps here

You may find this is a web server configuration of interest to you too.

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


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

Posted in Ajax, eLearning, Hardware, Networking, Operating System, Software, Tutorials | Tagged , , , , , , , , , , , , , , , , | Leave a comment