Favourites Poll Email Moderation Ajax Tutorial

Favourites Poll Email Moderation Ajax Tutorial

Favourites Poll Email Moderation Ajax Tutorial

We’ve added to the Favourites Poll functionality of yesterday’s Favourites Poll Email Moderation Contenteditable Tutorial by …

  • preparing the ground for non-mobile “onmouseover” event Ajax logics associated with our “a” link href attributes that start with “HTTP” … but more likely is that logic will direct any …
  • what we like to call “long hover” (ie. wait a few seconds before deciding to instigate, where both an “onmouseout” event or “onclick” event within those few seconds nullifying “long hover” and “onmouseover” logics) “onmouseover” actions to display where an “onclick” event would take us content-wise into an “overlay” div element placed near to the “a” element of interest … to …
  • our “Ajax fallback” position, which is again, better for non-mobile (…. sorrryyy, mobile users), that being to display the content that an “a” link “onclick” event would show, but in a Javascript popup window in front of the rest of the content (noting, for mobile, will open a new web browser tab, most likely)

… effectively creating a preview before clicking piece of functionality (at least for those non-mobile users).

Is this Ajax feel to “a” links part of the static HTML or added dynamically? Here is the code snippet of relevance in Javascript function called by document.body “onload” event …

<?php echo ”

var inurl='';
var lastinurl=' ';
var ourwo=null;
var alm='Sent for moderation to RJM Programming';
var arect=null;
var lastain=null;
var zhr=null;

function ol() { // called by document.body "onload" event
" . $proposedemail . "
var sv=new Date().toDateInputValue();
prevh=document.getElementById('htimestamp').value;
selcon=document.getElementById('favouritetype').outerHTML;
selconv=document.getElementById('favouritetype').value;
//alert(sv);
document.getElementById('favouritetimestamp').value='' + sv;
document.getElementById('htimestamp').value='' + sv + '.' + '" . str_replace("|","",$rval) . "';
prevh=document.getElementById('htimestamp').value;
document.getElementById('favouritename').focus();
var asis=document.getElementsByTagName('a');
for (var ia=0; ia<asis.length; ia++) {
if (('' + asis[ia].href).toLowerCase().indexOf('http') == 0) {
asis[ia].onmouseover = function(evt) { lastain=evt.target; setTimeout(preajaxit,5000); }
asis[ia].onmouseout = function(evt) { lastinurl=' '; lastain=null; }
asis[ia].onclick = function(evt) { lastain=null; }
}
}

}

“; ?>

Yes, to improve genericity, we add the event logics dynamically (and independently to the collection of data). Here is the Ajax attempt code …


function maybeshowStuff(evt) {
if (zhr != null) {
if (zhr.readyState == 4) {
if (zhr.status == 200) {
alm=zhr.responseText;
if (ourwo) {
if (!ourwo.closed) {
ourwo.close();
ourwo=null;
} else {
ourwo=null;
}
}
document.getElementById('ajaxd').innerHTML=alm;
document.getElementById('ajaxd').style.top='' + arect.top + 'px';
document.getElementById('ajaxd').style.left='' + eval(100 + eval('' + arect.left)) + 'px';
document.getElementById('ajaxd').style.display='block';
}
}
}
}

function postalm() {
if (alm == '') {
if (ourwo) {
if (!ourwo.closed) {
ourwo.close();
ourwo=null;
} else {
ourwo=null;
}
}
ourwo=window.open(inurl, '_blank', 'top=' + arect.top + ',left=' + eval(100 + eval('' + arect.left)) + ',width=600,height=600');
}
}

function preajaxit() {
if (lastain) {
ajaxit(lastain);
lastain=null;
}
}

function ajaxit(ain) {
alm='';
inurl=ain.href;
if (inurl != lastinurl) {
if (document.getElementById('ajaxd').innerHTML != '') {
document.getElementById('ajaxd').innerHTML='';
document.getElementById('ajaxd').style.top='-2000' + 'px';
document.getElementById('ajaxd').style.left='-2000' + 'px';
document.getElementById('ajaxd').style.display='none;';
}
arect=ain.getBoundingClientRect();
lastinurl=inurl;
setTimeout(postalm, 2000);
zhr = new XMLHttpRequest();
zhr.open('get', ain.href, true);
zhr.onreadystatechange = maybeshowStuff;
zhr.send(null);
}
}

So, why is this logic more likely to fall back to Javascript popup window methodologies rather than embedded “overlay” div elements? Well, most URLs from non-rjmprogramming.com.au domains are likely to fail with the Ajax call above resulting in an error message of the ilk …

Access to XMLHttpRequest at ‘https://www.elitereaders.com/axolotl-mexico-cutest-amphibian/’ from origin ‘http://www.rjmprogramming.com.au’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Yet again, we hope you’re now more tempted to try the changed PHP favourites_midair.php code for (the obviously optional) Favourites Poll web application.


Previous relevant Favourites Poll Email Moderation Contenteditable Tutorial is shown below.

Favourites Poll Email Moderation Contenteditable Tutorial

Favourites Poll Email Moderation Contenteditable Tutorial

We think today’s blog posting title gives hints, but doesn’t completely give the game away to ask you, on top of the progress with our Favourites Poll up to yesterday’s Favourites Poll Email Moderation Client Validation Tutorial

What could be a layer of moderation and user experience improvement to apply to this web application?

Anyone, anyone? Yes, Stella Pajunas-Garnand, open up the “Type” data item to be able to be defined by a user. And continuing that line of thinking (and not looking at today’s blog posting title), what might be a cute idea in HTML (via PHP) to achieve this?

Anyone, anyone? Yes, you next to R2D2 … is it … W3C, yes, splash the code with …

contenteditable global attribute magic

… such as …


<th id='thfavouritetype'><div onblur='newtype(this);' title='Can moderate a new type you define via your keyboard here, as required' contenteditable=true id=thtype>Type</div></th>

… and even …

<?php echo ”

<td id='tdfavouritetype'><div title='Use keyboard to enter your own new type' onblur=dnewtype(this); onkeydown=dotdtypek(event); contenteditable=true id=tdtype><select onchange='selconv=huhit(this.value);' id=favouritetype name=favouritetype><option value=Book>Book</option><option value=Movie>Movie</option><option value=Play>Play</option><option value=Song>Song</option><option value=Video>Video</option><option value=Audio>Audio</option>" . $anyextras . "</select></div></td>

“; ?>

… that last one a first for us here at RJM Programming allowing an embedded dropdown (select element) be temporary clobbered via HTML div keyboard “onkeydown” action and “onblur” event resurrection, perhaps with a new option element added, perhaps, via a new user entered Favourites Poll “Type” (data item) value, sent off to RJM Programming for moderation along with the accompanying “Title” (data item) value. See the new Javascript below regarding these event logics …

<?php
$anyextras=””;
$ourlistc=”Book,Movie,Play,Song,Video,Audio”;
$ourlist=[“Book”,”Movie”,”Play”,”Song”,”Video”,”Audio”];
$mytype=””;
$umytype=””;

// PHP updates global variables above
// End of … PHP updates global variables above

echo ”

var dou=false;
var mytype='" . $mytype . "';
var umytype='" . $umytype . "';
var alltogether=\"" . $ourlistc . str_replace('"','',$anyextras) . "\";

function newtype(odiv) {
if ((odiv.innerText || odiv.contentWindow || odiv.contentDocument).trim() == '') {
odiv.innerHTML='Type';
} else {
mytype=(odiv.innerText || odiv.contentWindow || odiv.contentDocument);
umytype=mytype;
if (umytype.substring(0,1) == umytype.substring(0,1).toLowerCase()) {
umytype=umytype.replace(umytype.substring(0,1).toLowerCase(), umytype.substring(0,1).toUpperCase());
}
if (alltogether.indexOf(umytype) == -1) {
document.getElementById('favouritetype').innerHTML+='<option value=\"' + umytype + '\">' + umytype + '</option>';
document.getElementById('favouritetype').value=umytype;
dou=true;
selcon=document.getElementById('favouritetype').outerHTML;
selconv=document.getElementById('favouritetype').value;
prevh=document.getElementById('htimestamp').value;
document.getElementById('htimestamp').value+=umytype;
}
odiv.innerHTML='Type';
}
}

function dnewtype(odiv) {
if ((odiv.innerText || odiv.contentWindow || odiv.contentDocument).trim() == '') {
odiv.innerHTML=selcon;
document.getElementById('favouritetype').value=selconv;
} else {
mytype=(odiv.innerText || odiv.contentWindow || odiv.contentDocument);
umytype=mytype;
if (umytype.substring(0,1) == umytype.substring(0,1).toLowerCase()) {
umytype=umytype.replace(umytype.substring(0,1).toLowerCase(), umytype.substring(0,1).toUpperCase());
}
if (alltogether.indexOf(umytype) == -1) {
odiv.innerHTML=selcon;
document.getElementById('favouritetype').innerHTML+='<option value=\"' + umytype + '\">' + umytype + '</option>';
document.getElementById('favouritetype').value=umytype;
dou=true;
selcon=document.getElementById('favouritetype').outerHTML;
selconv=document.getElementById('favouritetype').value;
document.getElementById('htimestamp').value+=umytype;
} else {
selconv=umytype;
}
odiv.innerHTML=selcon;
document.getElementById('favouritetype').value=selconv;
}
}

function dotdtypek(event) {
if (event.target.innerHTML.indexOf('<') != -1) {
event.target.innerHTML='';
}
}

function huhit(selval) {
if (selval != '' && umytype != '' && selval.toLowerCase() != umytype.toLowerCase()) {
dou=false;
} else if (selval != '' && umytype != '' && selval.toLowerCase() == umytype.toLowerCase()) {
dou=true;
}
}

“; ?>

So we hope you’re now more tempted to try the changed PHP favourites_midair.php code for (the obviously optional) Favourites Poll web application.


Previous relevant Favourites Poll Email Moderation Client Validation Tutorial is shown below.

Favourites Poll Email Moderation Client Validation Tutorial

Favourites Poll Email Moderation Client Validation Tutorial

Yesterday’s Favourites Poll web application of Favourites Poll Email Moderation Primer Tutorial involves client-side HTML textboxes asking for interactive entry using an HTML form methodology. Not with all such projects with HTML form textboxes do we apply any client-side Javascript validation logic but today we are for the following reasons …

  • not all the textboxes represent mandatory fields (ie. ones we’d like an answer for) … and the client-side Javascript validation can show …
  • the user can see that this poll is not being nosey, just curious, because it becomes apparent the only mandatory textbox is that “Title” one … as well as …
  • the “Link” and “Email” textbox data requirement information presented to the user can enhance their understanding of how they can define their “Favourite” data via new dropdown elements … and so …
  • considerably improve the user experience … we think

With those aims in mind we looked for a “fresh look” at client-side form textbox validation and arrived at this wonderful link‘s excellent ideas …

  1. Basic validation can be performed by choosing the type attribute of input elements. For example: <input type=”email” />
    <input type=”URL” />
    <input type=”number” />
  2. using pattern attribute like: <input type=”text” pattern=”[1-4]{5}” />
  3. required attribute <input type=”text” required />
  4. maxlength: <input type=”text” maxlength=”20″ />
  5. min & max: <input type=”number” min=”1″ max=”4″ />

… and we use Javascript DOM methodologies to achieve a lot of these validations “dynamically depending” on those new dropdown element selections and “onchange” Javascript function logics below


function dosfe(selo) { // "Email" textbox dropdown "onchange" event logic
if (selo.value != '') {
document.getElementById('femail').innerHTML=selo.value;
document.getElementById('oemail').innerHTML=' (required)';
if (selo.value == 'Email') {
document.getElementById('favouriteemail').type='email';
document.getElementById('favouriteemail').required=true;
} else if (selo.value == 'SMS') {
document.getElementById('favouriteemail').type='tel';
document.getElementById('favouriteemail').required=true;
}
}
selo.value='';
}


function tlinkc(selo) { // "Link" textbox dropdown "onchange" event logic
if (selo.value == '') {
document.getElementById('favouritevalue').type='text';
document.getElementById('favouritevalue').required=false;
document.getElementById('htimestamp').value=document.getElementById('htimestamp').value.trim() + '';
document.getElementById('slink').innerHTML='';
document.getElementById('favouritevalue').pattern='';
document.getElementById('favouritevalue').placeholder='';
document.getElementById('favouritevalue').minlength=0;
document.getElementById('favouritevalue').maxlength=1000;
} else if (selo.value.trim() == '') { // URL
document.getElementById('favouritevalue').type='url';
document.getElementById('favouritevalue').required=true;
document.getElementById('htimestamp').value=document.getElementById('htimestamp').value.trim() + '';
document.getElementById('slink').innerHTML=' (required)';
document.getElementById('favouritevalue').pattern='';
document.getElementById('favouritevalue').placeholder='';
document.getElementById('favouritevalue').minlength=0;
document.getElementById('favouritevalue').maxlength=1000;
} else if (selo.value == '0') { // SMS
document.getElementById('favouritevalue').type='tel';
document.getElementById('htimestamp').value=document.getElementById('htimestamp').value.trim() + ' ';
document.getElementById('favouritevalue').required=true;
document.getElementById('slink').innerHTML=' (required)';
document.getElementById('favouritevalue').pattern='';
document.getElementById('favouritevalue').placeholder='';
document.getElementById('favouritevalue').minlength=0;
document.getElementById('favouritevalue').maxlength=1000;
} else if (selo.value == '@') { // Email
document.getElementById('favouritevalue').type='email';
document.getElementById('favouritevalue').required=true;
document.getElementById('htimestamp').value=document.getElementById('htimestamp').value.trim() + '';
document.getElementById('slink').innerHTML=' (required)';
document.getElementById('favouritevalue').pattern='';
document.getElementById('favouritevalue').placeholder='';
document.getElementById('favouritevalue').minlength=0;
document.getElementById('favouritevalue').maxlength=1000;
} else if (selo.value == '11') { // YouTube ID
// Q_qA89dmGco
document.getElementById('favouritevalue').type='text';
document.getElementById('htimestamp').value=document.getElementById('htimestamp').value.trim() + '';
document.getElementById('favouritevalue').required=true;
document.getElementById('slink').innerHTML=' (required)';
document.getElementById('favouritevalue').pattern='[a-zA-Z0-9-_]{11}$';
if (document.getElementById('favouritevalue').value == '') {
document.getElementById('favouritevalue').placeholder='Q_qA89dmGco';
}
document.getElementById('favouritevalue').minlength=11;
document.getElementById('favouritevalue').maxlength=11;
} else if (selo.value == '10') { // ISBN 10 digits
// 0-297-81242-4
document.getElementById('favouritevalue').type='text'; // 'number'
document.getElementById('htimestamp').value=document.getElementById('htimestamp').value.trim() + '';
document.getElementById('favouritevalue').required=true;
document.getElementById('slink').innerHTML=' (required)';
document.getElementById('favouritevalue').pattern='[0-9]{10}$';
if (document.getElementById('favouritevalue').value == '') {
document.getElementById('favouritevalue').placeholder='0-297-81242-4';
}
document.getElementById('favouritevalue').minlength=10;
document.getElementById('favouritevalue').maxlength=13;
} else if (selo.value == '13') { // ISBN 13 digits
// 9-781760-527334
document.getElementById('favouritevalue').type='text'; // 'number'
document.getElementById('htimestamp').value=document.getElementById('htimestamp').value.trim() + '';
document.getElementById('favouritevalue').required=true;
document.getElementById('slink').innerHTML=' (required)';
document.getElementById('favouritevalue').pattern='[0-9]{13}$';
if (document.getElementById('favouritevalue').value == '') {
document.getElementById('favouritevalue').placeholder='9-780297-812425';
}
document.getElementById('favouritevalue').minlength=13;
document.getElementById('favouritevalue').maxlength=15;
}
}

Perhaps you’re now more tempted to try the changed PHP favourites_midair.php code for (the obviously optional) Favourites Poll web application.


Previous relevant Favourites Poll Email Moderation Primer Tutorial is shown below.

Favourites Poll Email Moderation Primer Tutorial

Favourites Poll Email Moderation Primer Tutorial

Any web application that asks for user input and stores it from an online user via an online webpage …

  • will need to be coded in a serverside language … check … we’ll use PHP
  • ideally should have an interim “moderation mechanism” … check … we’ll use Email (for one administration user)
  • will need a “database type of storage mechanism” to store (the) too many entries (that may happen) for localStorage or Cookies (methodologies) … check … will not use a large database product such as MySql but will use …
    1. a flat file
    2. that is readable
    3. that is ascii
    4. that doubles as webpage content (ie. takes the form of HTML) … yet …
    5. of itself, is hidden to your non-administration user … just by virtue of …
    6. residing “outside the public domain parts of the RJM Programming domain” … in …
    7. a chosen $HOME (for an RJM Programming user account) folder on the RJM Programming web server … but …
    8. an administration user can use the PHP to pull in that “outside the public domain parts of the RJM Programming domain” file content, when asked for (which we’ve decided, is any time anyone from the public accesses our “Favourites Poll”)

Yes, this is a nuance of data storage we’ve never tried before, it’s weirdness being that if that content could be expressed in a web browser address bar URL, any web browser web inspector would have a field day telling you all about it, and yet it is not accessible directly by the usual online user. We realize there is nothing to accessing the PHP to effectively access it, but that is because of a genuine interest from an interested player, and we see this as a nuanced difference in data storage, at least for us here at RJM Programming.

Perhaps you’d like to examine the PHP favourites_midair.php code for (the obviously optional) Favourites Poll and/or see the animated GIF presentation of us polling ourself to get the ball rolling!

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.

This entry was posted in Ajax, eLearning, Event-Driven Programming, Tutorials and tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *