<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JavaScript &#8211; Johnny Morano&#039;s Tech Articles</title>
	<atom:link href="https://jmorano.moretrix.com/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>https://jmorano.moretrix.com</link>
	<description>Ramblings of an old-fashioned space cowboy</description>
	<lastBuildDate>Sat, 09 Apr 2022 07:32:55 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.2</generator>

<image>
	<url>https://jmorano.moretrix.com/wp-content/uploads/2022/04/cropped-jmorano_emblem-32x32.png</url>
	<title>JavaScript &#8211; Johnny Morano&#039;s Tech Articles</title>
	<link>https://jmorano.moretrix.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Datatables and Perl (and a little bit of jQuery)</title>
		<link>https://jmorano.moretrix.com/2013/10/datatables-perl-and-bit-jquery/</link>
					<comments>https://jmorano.moretrix.com/2013/10/datatables-perl-and-bit-jquery/#comments</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Wed, 09 Oct 2013 14:05:45 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Dev]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<guid isPermaLink="false">http://jmorano.moretrix.com/?p=1014</guid>

					<description><![CDATA[Recently I&#8217;ve stumbled on a pretty cool OpenSource project called &#8221;datatables&#8221; (http://datatables.net/), which allows to easily create tables&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Recently I&#8217;ve stumbled on a pretty cool OpenSource project called &#8221;datatables&#8221; (<a title="Datatables" href="http://datatables.net/" target="_blank" rel="noopener">http://datatables.net/</a>), which allows to easily create tables in HTML that can be:</p>



<ul class="wp-block-list"><li>sorted</li><li>searched</li><li>paginated</li><li>scroll infinitely</li><li>themed</li><li>&#8230;</li></ul>



<p>And most important: it&#8217;s for free! I&#8217;ve always wanted to create an infinite scrolling table and now it&#8217;s just too easy:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">$(document).ready( function() {
    oTable = $('#ip_data').dataTable( {
        "bProcessing":     true,
        "bServerSide":     true,
        "bPaginate":       true,  
        "bScrollInfinite": true,
        "bScrollCollapse": true,
        "sScrollY":        "200px",
        "sAjaxSource":     "get_ip_data.pl",
    } );
} );
</pre>



<p>And that&#8217;s it! Well, ok, you need to include the Javascript file and CSS files of the Datatables Project of course and you need to create the table in HTML.</p>



<p>For instance:</p>



<figure id="ip_data" class="wp-block-table"><table><thead><tr><th>IP</th><th>Country</th><th>City</th><th>Latitude</th><th>Longitude</th></tr></thead><tbody><tr><td>Loading data from server</td></tr></tbody><tfoot><tr><th>IP</th><th>Country</th><th>City</th><th>Latitude</th><th>Longitude</th></tr></tfoot></table></figure>



<pre class="wp-block-preformatted">&nbsp;</pre>



<p>And then you will need a Perl script providing you the data for the table.<br />The below example allows to</p>



<ul class="wp-block-list"><li>search the tables</li><li>scroll infinitely</li><li>sort on the columns</li></ul>



<p>It also supplies the Datatables table with a total amount or rows in the database table.</p>



<p>This following script will be saved as &#8221;get_ip_data.pl&#8221;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#!/usr/bin/perl
use strict; use warnings;
use DBI;
use JSON;
use CGI;

my @columns = qw/ip country_name city latitude longitude/;

my $q = CGI-&amp;gt;new;
my $db = DBI-&amp;gt;connect("dbi:mysql:host=localhost;db=testdb", 'testuser', 'xxxsecret');

my $params = $q-&amp;gt;Vars;

# Get the total count of rows in the table
my $sql_count = "select count(id) from geo_data";
my $count = $db-&amp;gt;selectrow_arrayref($sql_count)-&amp;gt;[0];

# Start building up the database query
my @values;
my $sql = "select ip,country_name,city,latitude,longitude from geo_data";

# if a search parameter was supplied in the AJAX call, build the WHERE part in the SQL statement
if( $params-&amp;gt;{sSearch} ){
    $sql .= ' WHERE ';
    $sql .= 'ip LIKE ? OR country_name LIKE ? or city LIKE ? or latitude LIKE ? or longitude LIKE ?';
    push @values, ('%'.$params-&amp;gt;{sSearch}.'%','%'.$params-&amp;gt;{sSearch}.'%','%'.$params-&amp;gt;{sSearch}.'%','%'.$params-&amp;gt;{sSearch}.'%','%'.$params-&amp;gt;{sSearch}.'%');
}

# if a sorting parameter was supplied in the AJAX call, build up the ORDER BY part in the SQL statement
if( $params-&amp;gt;{iSortingCols} ){
    $sql .= ' ORDER BY';
    foreach my $c (0 .. ( $params-&amp;gt;{iSortingCols} -1 )){
        $sql .= ' ' . $columns[ $params-&amp;gt;{"iSortCol_$c"} ] . ' ' . $params-&amp;gt;{"sSortDir_$c"};
        $sql .= ','
    }
    $sql =~ s/,$//;
}

# Limit the output and also allow to paginate or scroll infinitely
$sql .= " LIMIT ? OFFSET ?";
push @values, (($params-&amp;gt;{iDisplayLength} &amp;gt; 0 ? $params-&amp;gt;{iDisplayLength} : 25), ( $params-&amp;gt;{iDisplayStart} // 0));

# Fetch the data from the database
my $data = $db-&amp;gt;selectall_arrayref($sql, { Slice =&amp;gt; [] }, @values);

# Return the JSON object
print $q-&amp;gt;header('application/json');
my $json = encode_json({ aaData =&amp;gt; $data, iTotalRecords =&amp;gt; $count, iTotalDisplayRecords =&amp;gt; $count, sEcho =&amp;gt; int($params-&amp;gt;{sEcho}) });
print $json;
</pre>



<p>An example can be found overhere: <a title="Charon Map" href="http://www.moretrix.com/~insaniac/map/map.pl" target="_blank" rel="noopener">http://www.moretrix.com/~insaniac/map/map.pl</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2013/10/datatables-perl-and-bit-jquery/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Google GeoChart, JSON and Perl</title>
		<link>https://jmorano.moretrix.com/2013/10/google-geochart-json-perl/</link>
					<comments>https://jmorano.moretrix.com/2013/10/google-geochart-json-perl/#comments</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Wed, 09 Oct 2013 09:33:48 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Dev]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[MySQL]]></category>
		<guid isPermaLink="false">http://jmorano.moretrix.com/?p=1006</guid>

					<description><![CDATA[The Google API GeoChart Map (https://developers.google.com/chart/interactive/docs/gallery/geochart) is pretty nice widget to generate nice maps based on certain values.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>The Google API GeoChart Map (<a title="Google GeoChart Map" href="https://developers.google.com/chart/interactive/docs/gallery/geochart" target="_blank" rel="noopener">https://developers.google.com/chart/interactive/docs/gallery/geochart</a>) is pretty nice widget to generate nice maps based on certain values. It has quite a lot of features and it is very easy to use.</p>



<p>Before we look at the Google API for GeoChart, let&#8217;s first set up a script which will get data out of a database and return it in a JSON formatted object.<br />In this example we will use Perl and three Perl modules:</p>



<ul class="wp-block-list"><li>DBI</li><li>JSON</li><li>CGI</li></ul>



<p>When converting database values to a JSON object (or text string), it is very important that all data is properly type-casted.<br />In the following example you will see that we do:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">$_-&amp;gt;[1] = int($_-&amp;gt;[1]) foreach @$data;
</pre>



<p>This snippet will actually make our INTEGER value into a real integer. The DBI module had returned it as a normal string (that&#8217;s just how DBI works).</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#!/usr/bin/perl
use strict; use warnings;
use DBI;
use JSON;
use CGI;

my $q = CGI-&amp;gt;new;
my $db = DBI-&amp;gt;connect("dbi:mysql:host=localhost;db=testdb", 'testuser', 'xxxsecret');

my $sql = "SELECT country_name, count(id) as total from geo_data group by country_name";
my $data = $db-&amp;gt;selectall_arrayref($sql);
$_-&amp;gt;[1] = int($_-&amp;gt;[1]) foreach @$data;
unshift(@$data, ['Country', 'Attacks']);

print $q-&amp;gt;header('application/json');
my $json = encode_json($data);
print $json;
</pre>



<p>The above Perl script will be saved as &#8221;get_countries_data.pl&#8221;.</p>



<p>In the below Javascript example, we will use the Google API for the GeoChart Map and <a title="jQuery" href="http://www.jquery.com/" target="_blank" rel="noopener">jQuery</a> for making the AJAX call to our Perl script. Since the Perl script already provides the data in a JSON format, we do not need to convert or parse it.<br />Furthermore the Javascript code is pretty straightforward and based on the example found at https://developers.google.com/chart/interactive/docs/gallery/geochart, except for the AJAX part.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    google.load('visualization', '1', {packages: ['geochart']});
    google.setOnLoadCallback(drawVisualization);

    function drawVisualization() {
        var options = {
            height: '500',
            width: '1200',
            colorAxis: {minValue: 0,  colors: ['#FFC26B', 
                                               '#FFAF3B', 
                                               '#FF9700', 
                                               '#C1852F', 
                                               '#A86400']},
            datalessRegionColor: '#FAFAFA',
            backgroundColor: '#F4EFE7',
        };
    
        $.ajax({
            type: 'POST',
            url: "get_countries_data.pl",
            dataType: "json",
            async: false,
            success: function(json_data) {
                var data = google.visualization.arrayToDataTable(json_data);
                var chart = new google.visualization.GeoChart(
                                   document.getElementById('visualization') );

                chart.draw(data, options);
            }
        });
    }</pre>



<p>An example of this setup can be found at <a title="Charon Map" href="http://www.moretrix.com/~insaniac/map/map.pl" target="_blank" rel="noopener">http://www.moretrix.com/~insaniac/map/map.pl</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2013/10/google-geochart-json-perl/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Perl/Ajax with JSON</title>
		<link>https://jmorano.moretrix.com/2011/03/perlajax-with-json/</link>
					<comments>https://jmorano.moretrix.com/2011/03/perlajax-with-json/#respond</comments>
		
		<dc:creator><![CDATA[insaniac]]></dc:creator>
		<pubDate>Tue, 29 Mar 2011 14:18:42 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Dev]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<guid isPermaLink="false">http://jmorano.moretrix.com/?p=555</guid>

					<description><![CDATA[I just discovered this very interesting article about Perl, CGI, Template and Ajax using JSON. I&#8217;m going to&#8230;]]></description>
										<content:encoded><![CDATA[<p>I just discovered this very interesting article about Perl, CGI, Template and Ajax using JSON.</p>
<p>I&#8217;m going to use to beef up my image browser which I quickly wrote to simply the contents of directory full with images. (can be found overhere <a href="http://yamamoto.moretrix.com/~insaniac/grtp/">http://yamamoto.moretrix.com/~insaniac/grtp/</a></p>
<p>Here&#8217;s the link to the <a href="http://rohan.almeida.in/archives/get-started-with-jquery-ajax-and-json-in-your-perl-web-applications">article</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2011/03/perlajax-with-json/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Centering a CSS div layer in your browser window</title>
		<link>https://jmorano.moretrix.com/2010/12/centering-a-css-div-layer-in-your-browser-window/</link>
		
		<dc:creator><![CDATA[insaniac]]></dc:creator>
		<pubDate>Wed, 15 Dec 2010 13:50:09 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Dev]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">http://jmorano.moretrix.com/?p=435</guid>

					<description><![CDATA[Some time ago I needed to create a popup window on a web page, and it had be&#8230;]]></description>
										<content:encoded><![CDATA[<p>Some time ago I needed to create a popup window on a web page, and it had be centered in the browser window. &#8220;Couldn&#8217;t be that hard&#8221; was my first thought, although I haven&#8217;t programmed anything in JavasScript for years.</p>
<p>So using CSS and Javascript, this was actually a pretty easy job to do. The only hard thing to do, was making it browser indepedent. But in the end, even this wasn&#8217;t so hard at all since most of these steps have been thoroughly described on the Interweb.<br />
<span id="more-435"></span><br />
What we will need is</p>
<ul>
<li>a CSS file</li>
<li>a JavaScript file</li>
<li>a HTML file</li>
</ul>
<p>The CSS portion is actually very easy:<br />
&#8211; Save this into a file called <em>style.css</em></p>
<pre class="brush:css">
#blanket {
    display: block;
    position:absolute;
    width:100%;
    height: 100%;
    top:0px;
    left:0px;
    z-index: 9998;
    background-color:#111;
    opacity: 0.65;
    filter:alpha(opacity=65);
}
#popUpDiv {
    display: block;
    position:absolute;
    width:450px;
    height:500px;
    z-index: 9999;
    overflow: auto;
    padding-left: 4px;
    padding-right: 4px;
    background-color:#eeeeee;
}
</pre>
<p>As you can see: no rocket science. We create two layers: blanket and popUpDiv. The blanket layer will create a gray transparent layer over the entire page. The popUpDiv layer will create &#8230; well, I think it&#8217;s clear what this layer will do <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The JavaScript portion contains a bit more code. It will contain four functions:</p>
<ul>
<li>toggle(): toggle the visibility of a layer</li>
<li>create_blanket(): calculate the size of the blanket and display</li>
<li>create_popup(): calculate the position of the popup layer and display</li>
<li>popup(): wrapper function which calls toggle(), create_blanket(), create_popup()</li>
</ul>
<p>Let&#8217;s start with the <em>toggle()</em> function, because that&#8217;s the shortest and easiest one.</p>
<pre class="brush:javascript">
function toggle(div_id) {
        var el = document.getElementById(div_id);

        if (el.style.display == 'none') {
                el.style.display = 'block';
        }
        else {
                el.style.display = 'none';
        }
}
</pre>
<p>Again, no rocket science. This procedure has been described and explained a million times on the Interweb, I will not redo it overhere.</p>
<p>Secondly, the <em>create_blanket()</em> function requires a bit more attention, since it&#8217;s more than 4 lines of code. <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br />
In this function, we will try to get the window height. We&#8217;ll do this in two different ways: one for Mozilla based browsers, one for Internet Exploder browsers.</p>
<pre class="brush:javascript">
if (typeof window.innerHeight != 'undefined') {
    height = window.innerHeight;
}
else {
    height = document.documentElement.clientHeight;
}
</pre>
<p>But then again &#8230; we could have just called <code>document.documentElement.clientHeight</code> since this is also supported by Mozilla based browsers.<br />
The variable <em>height</em> will contain the browser height.<br />
But, since we don&#8217;t all have huge screens which eliminates the usage of scrollbars, we will have to check if this <em>height</em> variable is smaller or bigger than the scroll area of the browser. </p>
<pre class="brush:javascript">
if ((height > document.body.parentNode.scrollHeight)
        && (height > document.body.parentNode.clientHeight)) {

        blanket_height = height;
}
else {
        if (document.body.parentNode.clientHeight > document.body.parentNode.scrollHeight) {
                blanket_height = document.body.parentNode.clientHeight;
        }
        else {
                blanket_height = document.body.parentNode.scrollHeight;
        }
}
</pre>
<p>And finally we&#8217;ll create this blanket:</p>
<pre class="brush:javascript">
var blanket = document.getElementById('blanket');
blanket.style.height = blanket_height + 'px';
</pre>
<p>So on with the <em>create_popup()</em> function. This function will first retrieve information about the different dimensions required to calculate the position of the popup. The following information is required:</p>
<ul>
<li>scroll_width: amount of pixels scrolled from left</li>
<li>scroll_height: amount of pixels scrolled from top</li>
<li>client_width: width of the browser (without scrollbars, menubars, padding, &#8230;)</li>
<li>client_height: height of the browser (without scrollbars, menubars, padding, &#8230;)</li>
<li>popup_width: popup width defined in CSS stylesheet file</li>
<li>popup_height: popup height defined in CSS stylesheet file</li>
</ul>
<p>First the scroll width and scroll height:</p>
<pre class="brush:javascript">
if( typeof( window.pageYOffset ) == 'number' ) {
        //Netscape compliant
        scroll_height = window.pageYOffset;
        scroll_width = window.pageXOffset;
} 
else if( document.body
        && ( document.body.scrollLeft || document.body.scrollTop ) ) {
        //DOM compliant
        scroll_height = document.body.scrollTop;
        scroll_width = document.body.scrollLeft;
} 
else if( document.documentElement
        && ( document.documentElement.scrollLeft
            || document.documentElement.scrollTop ) ) {
        //IE6 standards compliant mode
        scroll_height = document.documentElement.scrollTop;
        scroll_width = document.documentElement.scrollLeft;
}
</pre>
<p>Secondly the client height and width:</p>
<pre class="brush:javascript">
var client_height = document.body.parentNode.clientHeight;
var client_width  = document.body.parentNode.clientWidth;
</pre>
<p>And last the popup height and width as stated in the CSS stylesheet file:</p>
<pre class="brush:javascript">
var popup_height = parseInt(window.getComputedStyle(popUpDiv, "").getPropertyValue('height'));
var popup_width  = parseInt(window.getComputedStyle(popUpDiv, "").getPropertyValue('width'));
</pre>
<p>We need to wrap these values from the CSS stylesheet file around the JavaScript function <em>parseInt()</em> since the <em>.getPropertyValue()</em> function will return the values with &#8216;px&#8217; at the end. (e.g.: 400px)</p>
<p>Based on the above information, the position from top and left will be calculated:</p>
<pre class="brush:javascript">
var left    = client_width  / 2 + scroll_width  - (popup_width / 2);
var top     = client_height / 2 + scroll_height - (popup_height / 2);
</pre>
<p>The only thing left to do is, is sending these position values to the browser by simply changing the CSS values for this DIV object:</p>
<pre class="brush:javascript">
popUpDiv.style.left  = left + 'px';
popUpDiv.style.top   = top + 'px';
</pre>
<p>The final function, popup(), will be the wrapper function called from within the HTML code.</p>
<pre class="brush:javascript">
function popup(windowname) {
    create_blanket(windowname);
    create_popup(windowname);
    toggle('blanket');
    toggle(windowname);
}   
</pre>
<p>So now we only need some HTML code to test this!<br />
<a href="http://moretrix.com/~insaniac/popup/">Click here</a> to have a demo page (so where you could do right click + &#8216;View Source&#8217;)</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
