Yesterday’s PHP Blog Summary Fixed Titles Tutorial dealt with …
- the look (ie. the aesthetics) of the newly introduced Fixed Titles into our Code Download Table here at this blog … and today we turn our attention to …
- making the event logics equivalent for the newly introduced Fixed Titles when they are z-index’ed to the foreground
… and we now indicate (for non-mobile users) when the newly introduced Fixed Titles are to the forefront because they’ll have an onmouseover event revealing title …
Click sorts and double click also navigates back up to the top
Yes, those event logics hook into the wonderful jQuery “tablesorter” table column sort logic so many users come to expect now when a table of data is headed by a differently coloured header row of (th) header row cells for each table column.
We initially thought we’d have to recreate a second set of jQuery logic references (in our local and/or inhouse external Javascript code), but found it was less involved than that to do. We preferred to handle the two scenarios in two ways …
- user clicks a table header row header row cell (to sort a column of data)
- we want to introduce our own independent “level” of event logic (to the jQuery “tablesorter”‘s onclick event logic) … so independent, but occurring “near” the same time, to onclick event logic are (the onmousedown and ontouchdown event logics) of …
function placefixedtable() {
if (document.URL.toLowerCase().indexOf('https:') == 0) { location.href='http:' + document.URL.substring(6); }
var hassortDown=-1, thsws=[], ith, kth=0;
var ths=document.getElementsByTagName('th');
for (ith=0; ith<ths.length; ith++) {
thsws.push(ths[ith].getBoundingClientRect().width);
kth++;
}
var fixedtrrect=document.getElementById('myt').getBoundingClientRect();
var fixedtableoh='<table id=fttop class=fixedtable style=\"visibility:hidden;position:fixed;opacity:0.5;z-index:-50;top:' + eval(100 + eval('' + fixedtrrect.top)) + 'px;left:' + fixedtrrect.left + 'px;width:' + document.getElementById('myt').getBoundingClientRect().width + 'px;\"><tr style=width:' + fixedtrrect.width + 'px;><th>Date (GMT)</th><th>File</th><th>Path off http://www.rjmprogramming.com.au/</th><th>Extension</th><th>Blog Search Link</th><th>Code Difference Link</th></tr></table>';
for (ith=0; ith<ths.length; ith++) {
hassortDown=ths[ith].outerHTML.indexOf('sortDown');
switch (ith) {
case 0:
ths[ith].onmousedown = function(event){ par_1=0; par_2=event.target; setTimeout(andlaterclickth,2000); };
ths[ith].ontouchdown = function(event){ par_1=0; par_2=event.target; setTimeout(andlaterclickth,2000); };
break;
case 1:
ths[ith].onmousedown = function(event){ par_1=1; par_2=event.target; setTimeout(andlaterclickth,2000); };
ths[ith].ontouchdown = function(event){ par_1=1; par_2=event.target; setTimeout(andlaterclickth,2000); };
break;
case 2:
ths[ith].onmousedown = function(event){ par_1=2; par_2=event.target; setTimeout(andlaterclickth,2000); };
ths[ith].ontouchdown = function(event){ par_1=2; par_2=event.target; setTimeout(andlaterclickth,2000); };
break;
case 3:
ths[ith].onmousedown = function(event){ par_1=3; par_2=event.target; setTimeout(andlaterclickth,2000); };
ths[ith].ontouchdown = function(event){ par_1=3; par_2=event.target; setTimeout(andlaterclickth,2000); };
break;
case 4:
ths[ith].onmousedown = function(event){ par_1=4; par_2=event.target; setTimeout(andlaterclickth,2000); };
ths[ith].ontouchdown = function(event){ par_1=4; par_2=event.target; setTimeout(andlaterclickth,2000); };
break;
case 5:
ths[ith].onmousedown = function(event){ par_1=5; par_2=event.target; setTimeout(andlaterclickth,2000); };
ths[ith].ontouchdown = function(event){ par_1=5; par_2=event.target; setTimeout(andlaterclickth,2000); };
break;
default:
break;
}
if (hassortDown != -1) {
fixedtableoh=fixedtableoh.replace('<th', '<TH title="" id="in_' + ths[ith].innerHTML.split(' ')[0] + '" data-title="Click sorts and double click also navigates back up to the top" class="sortDown" ondblclick=clickth(' + ith + ',this,true,true); onclick=clickth(' + ith + ',this,false,true); style=background-color:#626975;color:#FFF;width:' + thsws[ith] + 'px;');
} else {
fixedtableoh=fixedtableoh.replace('<th', '<TH title="" id="in' + ths[ith].innerHTML.split(' ')[0] + '" data-title="Click sorts and double click also navigates back up to the top" ondblclick=clickth(' + ith + ',this,true,true); onclick=clickth(' + ith + ',this,false,true); style=background-color:#626975;color:#FFF;width:' + thsws[ith] + 'px;');
}
}
document.getElementById('lastdiv').innerHTML=fixedtableoh.replace(/\<TH/g, '<td').replace(/\<\/th\>/g, '</td>');
if (document.getElementById('in_File')) { lasttobesd=document.getElementById('in_File'); }
}
- we want to introduce our own independent “level” of event logic (to the jQuery “tablesorter”‘s onclick event logic) … so independent, but occurring “near” the same time, to onclick event logic are (the onmousedown and ontouchdown event logics) of …
- user clicks a newly introduced Fixed Title header row cell (to sort a column of data) setting the Javascript function below to click its corresponding table header row header row cell programmatically (in a way very interesting to us)
… converging on the one Javascript function (where realc=false is scenario 1 above and realc=true is scenario 2 above) …
function clickth(ithis,ththis,dblc,realc) {
var ith=0, tdo=null;
if (!realc) {
tdo=document.getElementById('in_' + ththis.innerHTML.split(' ')[0]);
if (tdo == null) { tdo=document.getElementById('in' + ththis.innerHTML.split(' ')[0]); }
ththis=tdo;
}
if (ththis == null) {
ththis=ththis;
} else {
var hassortDown=-1, thisclassbit='';
var ths=document.getElementsByTagName('th');
for (ith=0; ith<ths.length; ith++) {
if (ithis == ith) {
hassortDown=ths[ith].outerHTML.indexOf('sortDown');
if (realc) { ths[ith].click(); }
thisclassbit=('' + ththis.className);
if (hassortDown == -1) {
if (!realc) {
if (lasttobesd != null) {
lasttobesd.className=('' + lasttobesd.className).replace('sortDown','').trim();
lasttobesd=null;
}
ththis.className=('' + ththis.className).replace('sortDown','').trim();
if (dblc) { location.hash='#myt'; }
} else {
if (lasttobesd != null) {
lasttobesd.className=('' + lasttobesd.className).replace('sortDown','').trim();
lasttobesd=null;
}
ththis.className=(('' + ththis.className).replace('sortDown','') + ' sortDown').trim();
thso=ths[ith];
setTimeout(ylater, 2000);
lasttobesd=ththis;
if (dblc) { location.hash='#myt'; }
}
} else {
if (!realc) {
if (lasttobesd != null) {
lasttobesd.className=('' + lasttobesd.className).replace('sortDown','').trim();
lasttobesd=null;
}
ththis.className=(('' + ththis.className).replace('sortDown','') + ' sortDown').trim();
lasttobesd=ththis;
} else {
if (lasttobesd != null) {
lasttobesd.className=('' + lasttobesd.className).replace('sortDown','').trim();
lasttobesd=null;
}
ththis.className=('' + ththis.className).replace('sortDown','').trim();
thso=ths[ith];
setTimeout(xlater, 2000);
if (dblc) { location.hash='#myt'; }
}
}
}
}
}
}
… to respect the great jQuery tablesorter logic in the one place we programmatically click to activate (in scenario 2) and display appropriately (in scenario 1).
Again, to make this happen, the PHP that dovetails with RJM Programming web server’s once a day crontab/curl report update needed to start calling some new document.body (delayed) onload event Javascript logic contained in the changed getmelist.js (called by the changed getmelist.php).
Did you know?
We like to programmatically click HTML elements. We’re doing it a lot, and often, but have rarely, if ever, clicked elements with no ID property defined. We’ve gotten used to code like ” document.getElementById(‘eletoclickid’).click(); ” or some such. But you can click elements with no ID by using good ol’ (and hugely useful) …
var ths=document.getElementsByTagName('th');
… giving us an array of element objects … leaving us able to programmatically click the ith one (for example) via …
ths[ith].click();
… with no reference to any HTML element ID property, whether one exists or not.
Stop Press
So, did you know there’d be a Stop Press? We found we needed better work for mobile device platforms that can use a viewport, as introduced with the code change outlined below. In exploring this, we found our first time ever use for the CSS viewport units “vx” (ie. 100vx full width of viewport) … but you’ll just have to believe our empirical approach (seeing it with our own eyes on an iPhone) because we can’t find a useful link for you here … (not “%” nor “vw” nor “vmax”) nor the “vh” (viewport height) unit we often turn to. Again, to make this happen better for mobile devices, the PHP that dovetails with RJM Programming web server’s once a day crontab/curl report update needed to start calling some new document.body (delayed) onload event Javascript logic contained in the changed getmelist.js (called by the changed getmelist.php).
Previous relevant PHP Blog Summary Fixed Titles Tutorial is shown below.
Sometimes with a webpage depicting a long tabular report such as our RJM Programming GETME Report one used by this blog’s All Posts menu’s Code Download Table submenu link (you can read more about with PHP Blog Summary Follow Up Tutorial), if the column titles were up the top, and not repeated, a user can “lose their way”. There are two approaches to remedying this, to our minds …
- in the tabular data repeat the (perhaps “th” tag) cells of the header row, regularly, in rows further down the tabular report … or …
- detect the position of tabular report’s header row and use that to create new “table element with the one row with the one header set in columns of the same width” that can effectively float in front of the users of the user as they scroll through the report
… and we decided on the latter strategy above.
That latter strategy works in two methodologies for the two dimensions (unusually) …
- x (or left) aligns document.body.scrollLeft to a negative CSS [element].style.marginLeft application (though for the existent “in your face” dropdown it becomes a positive CSS [element].style.marginLeft application) catering for any user horizontal scrolling performed as they peruse the tabular report
- y (or top) works with (CSS position:fixed) or Javascript DOM [element].style.position=’fixed’ (as we discussed with Fixed Sticky Header Top Window Document Tutorial) keeping the header row at a consistent y (or top) position as the user does any vertical scrolling through the tabular report
To make this happen, the PHP that dovetails with RJM Programming web server’s once a day crontab/curl report update needed to start calling some new document.body (delayed) onload event Javascript logic contained in getmelist.js (called by the changed getmelist.php) …
function placefixedtable() {
if (document.URL.toLowerCase().indexOf('https:') == 0) { location.href='http:' + document.URL.substring(6); }
var thsws=[], ith, kth=0;
var ths=document.getElementsByTagName('th');
for (ith=0; ith<ths.length; ith++) {
thsws.push(ths[ith].getBoundingClientRect().width);
kth++;
}
var fixedtrrect=document.getElementById('myt').getBoundingClientRect();
var fixedtableoh='<table id=fttop class=fixedtable style=\"visibility:hidden;position:fixed;opacity:0.5;z-index:-50;top:' + eval(100 + eval('' + fixedtrrect.top)) + 'px;left:' + fixedtrrect.left + 'px;width:' + document.getElementById('myt').getBoundingClientRect().width + 'px;\"><tr style=width:' + fixedtrrect.width + 'px;><th>Date (GMT)</th><th>File</th><th>Path off http://www.rjmprogramming.com.au/</th><th>Extension</th><th>Blog Search Link</th><th>Code Difference Link</th></tr></table>';
for (ith=0; ith<ths.length; ith++) {
fixedtableoh=fixedtableoh.replace('<th', '<TH style=background-color:#626975;color:#FFF;width:' + thsws[ith] + 'px;');
}
document.getElementById('lastdiv').innerHTML=fixedtableoh.replace(/\<TH/g, '<td').replace(/\<\/th\>/g, '</td>');
}
… and have the scrolling watcher code change as per …
function everysecond() {
document.getElementById('ourselabs').style.top = eval(eval(f400) + document.body.scrollTop) + 'px';
if (document.getElementById('fttop')) {
document.getElementById('fttop').style.visibility='visible';
document.getElementById('fttop').style.marginLeft='-0' + document.body.scrollLeft + 'px';
if (('' + lastl) != ('' + document.body.scrollLeft)) {
lastl=('' + document.body.scrollLeft);
document.getElementById('ourselabs').style.marginLeft='0' + document.body.scrollLeft + 'px';
document.getElementById('fttop').style.zIndex=('-' + document.getElementById('fttop').style.zIndex).replace('--','');
}
}
}
We wanted the overlayed column headers be unobtrusive as a default, and yet be able to be brought forward (in Z) via CSS z-index property (or Javascript DOM [element].style.zIndex=[plusMinusZindexIntegerValue]) at the user’s discretion. Did you notice with …
document.getElementById('fttop').style.zIndex=('-' + document.getElementById('fttop').style.zIndex).replace('--','');
… how this toggling of column header overlays was achieved? Yes, for the first time we can remember, we used (the detection of) a scrolling action (a horizontal one) to allow the user this subtle control.
Previous relevant PHP Blog Summary Follow Up Tutorial is shown below.
To my mind there are two big advantages to the use of the id= HTML parameter usage:
- you can manipulate HTML via Javascript DOM in terms of individual HTML objects or elements (or tags, if you like)
- you can use them to navigate in a “hashtag” way via #[id] syntax … by repositioning yourself on your current webpage (as is so readily used in online essays or books in their Table of Contents, perhaps)
We probably learn to think that the id=‘s we define should all be unique, and who am I to argue … but … and this is a pragmatic but … if we have a webpage exhausted of usage for individual HTML Javascript DOM manipulation possibilities, and there is sorting going on in a table, like we’ve been doing recently here at this blog with its Blog Summary, as we talked about with PHP Blog Summary Primer Tutorial as seen below, couldn’t we open up the possibility for id=‘s being repeated so that you can still go places despite the fact that you just used one of the (jQuery) sortable table methods to change the order of everything?
Okay, let me put it this way, we know our filename of interest in our Blog Summary starts with a “j” and it is very recent, so we’ve first done a (jQuery) sort via date, but don’t immediately see our “j” file in our field of view, it would be good to use a hashtag search of #j and lob at the most recent one … that is what we are trying to achieve, and it is achieved here, today, by ditching the idea that all id=‘s should be unique and allowing the navigation aspects of id=‘s to take precedence (because we will not be needing this particular id= (repeated) system to be used for any Javascript DOM purposes).
All of this is best seen by using the live run, and hopefully you noticed improved navigation aspects to this webpage’s functionality. If you’re looking for north, though, think maybe you should get a compass … chortle, chortle.
The HTML programming source code for this now could be called getmelist.php and the differences link shows how we got there from the tutorial below.
Previous relevant PHP Blog Summary Primer Tutorial is shown below.
There are two things that often happen for programmers:
- they break a job into its components (often immediately jumping to list the biggest “worry”)
- they look for ways to achieve the job faster and more reliably (ideas regarding code reuse both internally or externally)
With this in mind today’s job, which is a GETME code lister for this blog (like a blog summary (updated every day, via cron/curl)) had (or I wanted):
- sortable HTML tables
- data from Linux operating system
To me the biggest “worry” with this job is the “sortable HTML tables” (spend far more time on client side work (“front end”) per unit of time of productivity than server-side work (“back end”)). So, how about we start with a good code basis of “sortable HTML tables” … that’s why we’re showing you the PHP/Javascript JSON Feed or Array Data Primer Tutorial below that we are. Although it looks off-topic, it is very close code-wise, and this leads to another quality (or not) you may want, or not, to do with programming:
- do you mind the old
if (1 == 1) { }
(for code you show to be “back in favour”) vsif (7 != 7) { }
orif (("to be" || "not to be") == "that is the question") { }
perhaps (for code that is “deliberately out of favour, but may be of interest, or come back into play later”) ? … lots of programmers will not like this, some will be fine with this … am in the latter group, because, to me, it is like “the comment you make when you’re not making a comment”
Back to the idea … we do a lot of code download offers with *GETME files here at this blog … so why not summarize all this in a sortable table?
Link to some downloadable PHP programming code … rename to getmelist.php as you wish and here is a link to the live run and will leave you with the difference in code between this idea and the one of the code below with getmelist.php.
Previous code-relevant tutorial called PHP/Javascript JSON Feed or Array Data Primer Tutorial is shown below.
JSON is a very useful protocol because:
- There is a lot of support in Javascript and the server-side languages, such as PHP or ASP.Net, for JSON-friendly functionality.
- Many website feeds use JSON as their protocol (format) of choice.
Today‘s live run is a simple interface to JSON incoming data and its presentation back to you, either as an HTML table element, or as a validator. Of interest, are the two previous tutorials below. We use an optional method of the first, and the same default input data (via Google Charts) as the second:
- jQuery Sortable Table Primer Tutorial
- PHP/Javascript/HTML Google Chart JSON Data Table Event Tutorial
Along the way, wanted to point out use of:
- Format of JSON data regarding array data … eg.
'{"a":1,"b":2,"c":3,"d":4,"e":5}'
- PHP json_decode() method
- PHP http_build_query() method
- PHP urldecode() method
- Use of an HTML onload Javascript click of an HTML form’s submit button to automate the use of posted data … why post rather than get? … two reasons:
- better security
- there are limits to the amount of get data applied to your address bar urls that comes into play with get scenarios, but not with post scenarios
- Usefulness of online resources such as the JSONLint validator
- The attempts at genericity in the interface by converting posted feed url data into an HTML table presentation (with sortable column data) via the recognition of search specifications for:
- table ID
- table heading data
- table cell data
Here is a download link for some PHP programming source code you could call json_array_post.php
Perhaps Ajax functionality with local JSON data sources is of interest to you, and if this is the case, have a peruse of Ajax Local JSON Primer Tutorial … anyway, hope something here is of interest to you.
Previous relevant jQuery Sortable Table Primer Tutorial is shown below.
A lot of the things people like about the Web are to do with JavaScript and client-side activities. Adding to that experience are Javascript libraries packed full of features. Probably the best known of these is jQuery.
Read more about the powerful jQuery Javascript library here (at its spiritual home) and here (at Wikipedia).
Regarding this topic I really like “JavaScript & Ajax” seventh edition by Tom Negrino and Dori Smith pages 437 to 441. The code in this book was followed with quite a few changes. Why change a good thing … welllllll, want to show you some concepts/ideas/buffoonery which we’d like to present in pointy form below (you thought we were going to say “above” didn’t you? … go on! … admit it):
- Can include “old style” Javascript “body onload” code within jQuery ready functionality (just checking … because, personally, feel shy about combining the two worlds, but there is nothing wrong doing this, as we do today) …
- Function onloading() which is “old style” Javascript is the first thing called from jQuery ready code … why?
- First off please refer to today’s downloadable HTML/Javascript/jQuery code you could call conjunction_sortable_table.html
- Sometimes you want to use Javascript DOM techniques to dynamically load your document.body.innerHTML contents … so that, perhaps, you can read off a data source of some kind … wouldn’t PHP be sooooo great here?! … Subtext translation: the programmer is lazy and wanted to save coding time by taking an array from the previous tutorial called HTML/Javascript Sentence Conjunction Game Tutorial
- The jQuery ready code fires at the webpage’s body onload event, and you lose the ability to go <body onload=’onloading();’> but this doesn’t stop you plugging in onloading() up the top of your ready code … are you still awake?!
- Alternative approach is static HTML, and this is presented to you, but is commented out down the bottom of our code provided today … by the way, HTML comment goes <!– … –>
- … and how was this derived when a View->Page Source doesn’t show it? …
- … use Firebug (or something like it) and point at the body tag and use “Copy innerHTML” to derive this (as per the tutorial’s picture)
- Use of cursor:pointer style property to make a span tag, within an h1 tag act like an a tag
- Recall of ready function for the addsome() Javascript bit awkward, in that code is repeated
- Maybe start reading http://stackoverflow.com/questions/999092/can-i-call-the-function-ready-again-in-jquery to see if you can do better
Click on picture above to go to jQuery page for a (live run) tutorial on the jQuery concept called Sortable Table.
Link to jQuery information … via Wikipedia.
Link to jQuery spiritual home page … via jQuery Foundation.
Link to the great third-party jQuery Sortable Table code is available from the GitHub source control resource here which is a link from here … thanks heaps … isn’t Open Source great?!
Did you know?
The tutorial picture today features the Firefox web browser and a very useful add-on called Firebug which you may want more information about here, which is commonly used to debug client-side Javascript and HTML. As for today’s usage, Firebug is also extremely useful in deconstructing how a web page was created. The other simple wonderful tool for this is the web browser’s equivalent menu command like View->Page Source (or sometimes equivalent of right-click Page Source). Firebug has a sister product called FirePHP which helps debug server-side PHP and Ajax work.
If this was interesting you may be interested in this too.
Previous relevant PHP/Javascript/HTML Google Chart JSON Data Table Event Tutorial is shown below.
Here is a tutorial that re-introduces you to Google Graphs API, or Google Chart Tools, and its JSON Data Table functionality which we talked about last time with PHP/Javascript/HTML Google Chart JSON Data Table Import of CSV Tutorial as shown below. Today we extend the functionality talk by adding some event logic for when we click on a table row.
Google Chart Tools provide a perfect way to visualize data on your website. From simple line charts to complex hierarchical tree maps, the chart galley provides a large number of well-designed chart types. Populating your data is easy using the provided client- and server-side tools.
Thanks to the World Bank for some statistics which helped a lot.
Let’s see some PHP code in live action for this tutorial where you see a JSON Data Table derived from a filename passed as a parameter in the URL. The data shown is based on a CSV file of a previous PHP/Javascript/HTML Google Chart Intensity Map Tutorial shown below.
Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools JSON Data Table information … via Google.
Link to Google Chart Tools Event information … via Google.
Link to some downloadable PHP programming code … rename to chart_editor_in.php.
Link to some downloadable PHP programming code … rename to json_data_table_events.php.
Link to some downloadable input CSV data … rename to Google_Chart_Intensity_Chart_Tutorial_as.CSV.
Here is the way we got from the tutorial logic below to this tutorial’s source code’s logic here.
Previous PHP/Javascript/HTML Google Chart JSON Data Table Import of CSV Tutorial is shown below.
Here is a tutorial that introduces you to Google Graphs API, or Google Chart Tools, and its JSON Data Table functionality.
Google Chart Tools provide a perfect way to visualize data on your website. From simple line charts to complex hierarchical tree maps, the chart galley provides a large number of well-designed chart types. Populating your data is easy using the provided client- and server-side tools.
Thanks to the World Bank for some statistics which helped a lot.
Let’s see some PHP code in live action for this tutorial where you see a JSON Data Table derived from a filename passed as a parameter in the URL. The data shown is based on a CSV file of a previous PHP/Javascript/HTML Google Chart Intensity Map Tutorial shown below.
Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools JSON Data Table information … via Google.
Link to some downloadable PHP programming code … rename to chart_editor_in.php.
Link to some downloadable PHP programming code … rename to json_data_table.php.
Link to some downloadable input CSV data … rename to Google_Chart_Intensity_Chart_Tutorial_as.CSV.
Previous PHP/Javascript/HTML Google Chart Intensity Map Tutorial below …
Here is a tutorial that introduces you to Google Graphs API, or Google Chart Tools, and its Intensity Map functionality.
Google Chart Tools provide a perfect way to visualize data on your website. From simple line charts to complex hierarchical tree maps, the chart galley provides a large number of well-designed chart types. Populating your data is easy using the provided client- and server-side tools.
Thanks to the World Bank for some statistics which helped a lot.
Let’s see some PHP code in live action for this tutorial where you define your intensity map characteristics and data.
Now part of an Android App called Geo Chart++ in July 2013.
Link to Google Chart Tools “spiritual home” … via Google.
Link to Google Chart Tools Intensity Map information … via Google.
Link to some downloadable PHP programming code … rename to intensity_chart.php.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.