Showing posts with label AJAX. Show all posts
Showing posts with label AJAX. Show all posts

Monday, October 6, 2014

Bootstrap Loading-State Button on AJAX call

The sample code on http://www.tutorialrepublic.com/codelab.php?topic=bootstrap&file=stateful-button shows how to change the state of a button from its normal state to a loading state.

I thought I'd use the use on the code on my previous post to have a button that makes an AJAX request, change the content to 'loading data...' and revert back to its content after the AJAX response.

To see if I can get the effect I've set a five second delay on the backend PHP. If my approach is correct, I should be seeing 'Loading data...during the delay'. The PHP code on the backend is listed below:
    <?php
$time =  array("hr1"=>"1:00", "hr2"=>"2:00", "hr3"=>"3:00", "hr4"=>"4:00", "hr5"=>"5:00", "hr6"=>"6:00", "hr7"=>"7:00", "hr8"=>"8:00", "hr9"=>"9:00", "hr10"=>"10:00", "hr11"=>"11:00", "hr12"=>"12:00", "hr13"=>"13:00", "hr14"=>"14:00", "hr15"=>"15:00", "hr16"=>"16:00", "hr17"=>"17:00", "hr18"=>"18:00", "hr19"=>"19:00", "hr20"=>"20:00", "hr21"=>"21:00", "hr22"=>"22:00", "hr23"=>"23:00", "hr24"=>"00:00");

$action = '';
if(isset($_GET['action'])) $action = $_GET['action'];
$return = array();
switch ($action){
 case "init":
  $length = count($time);
  $return = array("return_param" => $length);
  break;
 case "get-time":
  $return = array("return_param" => ($time));
  break;
 default:
  $return = array("return_param" => "Error");
}
sleep(5);
echo json_encode($return);
?>

On my first attempt, I did not exactly get the effect I wanted. The 'Loading data' on the button reverted back to its initial content before the content was displayed. I realized then that it was the asynchronous part of the AJAX that continued with the execution of the script while it was making a request.

Using anonymous function approach, I was able to sync the change of the button contents during and after AJAX has completed the request and loaded the response.

The button to make the AJAX request has an id of 'loadhrs' and data-loading-text of 'Loading data...'

The adjustments in the code consists of a bind of the button id '#loadhrs' to the click event. The method queue() allows the button to display the loading text while AJAX is pulling the request. To sync with AJAX, I used anonymous function which accepts the button as an object passed as parameter.
The rest of the code is left unchanged.

To test, the html page with the code is loaded.. The button in its initial state displays 'Load Hours'

When the button is clicked, the initial text is replaced with the loading text. The button is likewise in its deactivated state.

After AJAX has pulled the response and displayed the contents, the button is back to its initial state.

The full code is listed below:
<!DOCTYPE html>
<html lang="en">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Bootstrap Pagination</title>
 
 <link href="css/bootstrap.min.css" rel="stylesheet">

    <!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
    <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
    <script src="js/ie-emulation-modes-warning.js"></script>

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
 <!--nivo stylesheets-->
 <link rel="stylesheet" href="css/nivo-slider.css" type="text/css" />
 <link rel="stylesheet" href="css/default.css" type="text/css" />
 <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/docs.min.js"></script>
 <script>
  
  $(document).ready(function (){
   var itemsperpage = 5;
   function bindli(itemsperpage, jlength, pages){
    $("ul.pagination li a").bind("click",function(){
      var showPage = this.id;
      if(showPage == 'first') showPage = 1;
      if(showPage == 'last') showPage = pages;
      showli(parseInt(showPage), itemsperpage, jlength)
    });
   }
   function showli(page, itemsperpage, jlength){
    $('ul.pagination li').removeClass('active');
    var offset = page +1;
    var activePage = 'ul.pagination li:nth-child('+offset+')';
    $(activePage).addClass('active');
    $( "div#hours ul li" ).hide();
    var upto = parseInt(page * itemsperpage);
    var start = (upto + 1) - itemsperpage;
    if(upto > jlength) upto = jlength;
    
    for(i = start; i <= upto; i++){
     showitem = 'div#hours li:nth-child('+i+')';
     $(showitem).show();
    }
   }
   function populateli(json, itemsperpage, jlength, pages){
    html = '<ul class="list-group">';
    $.each(json, function (key, data) {
     $.each(data, function (index, data2) {
      html += '<li class="list-group-item">'+data2+'</li>';
     })
    })
    html += '</ul>';
    $('div#hours').html(html);
    showli(1, itemsperpage, jlength);
    bindli(itemsperpage, jlength, pages);
   }
   function displayli(json, itemsperpage){
    var jlength = Object.keys(json.return_param).length;    
    var pages = parseInt(jlength/itemsperpage);
    var remainder = parseInt(jlength % itemsperpage);
    if(remainder > 0) pages++;
    var html = '<li><a href="#" id="first">&laquo;</a></li>';
    for(i = 1; i <= pages; i++) html += '<li><a href="#" id="'+i+'" title="'+i+'">'+i+'</a></li>';
    html += '<li><a href="#" id="last">&raquo;</a></li>';
    $('ul.pagination').html(html);
    populateli(json, itemsperpage, jlength, pages);
   }
   function init(sychit){
    $.ajax({    
     url: 'gethours.php?action=get-time',  
     dataType: 'json',       
     success: function(json) {
      var objButton = $("#loadhrs");
      sychit(objButton);
      displayli(json, itemsperpage);
     },  
     error: function(xhr, ajaxOptions, thrownError) { 
      alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText + "\r\n" + "Err-01");  
     }  
    });    
   }
   $("#loadhrs").bind("click",function(){
    $(this).button('loading').delay(1000).queue(function() {
     init(function(objButton){
      //this just forces a synch to reset/dequeue the button object
      objButton.button('reset');
      objButton.dequeue();
     });
    });
   });
  })
 </script>
</head>
<body>
 <div class="container">
  <div class="row">
   <div class="col-xs-12">
    <ul class="pagination">     
    </ul>
   </div>
  </div>
  <div class="row">
   <div class="col-xs-12">
    <div id="hours">
    hours
    </div>
   </div>
  </div>
   <button id='loadhrs' type="button" class="btn btn-primary" data-loading-text="Loading data...">Load Hours</button>
 </div>
</body>
</html>

Need help on some web coding task? Let me know about it. Email me at jun.dolor@gmail.com and I'll be more than happy to blog about it with my thoughts.

Hosting of the sample pages were provided for by the following:

Saturday, October 4, 2014

Showing progress on Bootstrap loader during JQuery AJAX download

Taking advantage of XMLHttpRequest2's support for "listening" to progress events, the code from my last post can further be improved by letting the progress bar loader slide up during the progression of its AJAX JSON download response.

The link http://www.dave-bond.com/blog/2010/01/JQuery-ajax-progress-HMTL5/ provided the progress event listener integrated to the code of my previous post.

The first adjustment to the code is to give an ID to the div holding the class .progress-bar and set the CSS style width to 10%. The CSS width will show the status of the progress. When the AJAX has completed the JSON response download, the width should be set to 100%

On the AJAX call, we add the XHR callback for the XMLHttpRequest2 object code from the link above.

Since we are concerned with the progress of the AJAX download, we tweak the corresponding event listener. The idea is to let the AJAX call "listen" how much progress is made on the download and update the progress  bar width.

On success of AJAX download, I've commented out the hiding of the progress bar. On the test run, I would want to retain the bar.

And speaking of test run, I now execute the code. Initially, the progress bar is set to 10%


When AJAX starts to download the JSON response, the progress bar slides up until it hits 100%.

The full code is listed below:
<!DOCTYPE html>
<html lang="en">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Loader</title>
 
 <link href="css/bootstrap.min.css" rel="stylesheet">

    <!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
    <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
    <script src="js/ie-emulation-modes-warning.js"></script>

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
 <!--nivo stylesheets-->
 <link rel="stylesheet" href="css/nivo-slider.css" type="text/css" />
 <link rel="stylesheet" href="css/default.css" type="text/css" />
 <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/docs.min.js"></script>
 <script>
  $(document).ready(function (){
   function updateprogress(){
   }
   function init(){
    $.ajax({    
     xhr: function(){
      var xhr = new window.XMLHttpRequest();
      //Upload progress
      xhr.upload.addEventListener("progress", function(evt){
       if (evt.lengthComputable) {
        var percentComplete = evt.loaded / evt.total;
        //Do something with upload progress
        console.log(percentComplete);
       }
      }, false);
      //Download progress
      xhr.addEventListener("progress", function(evt){
       if (evt.lengthComputable) {
        var percentComplete = evt.loaded / evt.total;
        //Do something with download progress
        var value = percentComplete * 100;
        value = value+"%";
        $('#loadingbar').width(value)
        console.log(percentComplete);
       }
      }, false);
      return xhr;
     },
     url: 'gethours.php?action=get-time',  
     dataType: 'json',  
     
     success: function(json) {
      //var jlength = Object.keys(json.return_param).length;
      //alert('parameter1 = '+jlength); 
      //$("#loading").hide();
      
     },  
     error: function(xhr, ajaxOptions, thrownError) { 
      $("#loading").hide();
      alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText + "\r\n" + "Err-01");  
     }  
    });    
   }
   
   init();
  })
 </script>
</head>
<body>
 <div class="container">
  <div class="row">
   <div class="col-xs-12">
    <div id="loading">
    
    <div class="progress progress-striped active">
     <div id="loadingbar" class="progress-bar" style="width:10%;">
      <span class="sr-only">60% Complete</span>
     </div>
    </div>
    
    </div>
   </div>
  </div>
 </div>
</body>
</html>

Need help on some web coding task? Let me know about it. Email me at jun.dolor@gmail.com and I'll be more than happy to blog about it with my thoughts.

Hosting of the sample pages were provided for by the following:

Thursday, October 2, 2014

Bootstrap loader on Jquery AJAX

Bootstrap progress bars can be set up as a loader when AJAX is busy fetching data from a backend source. The code snippet below has a div element with ID "loading" displaying an animated stripped bar.
<div class="container">
  <div class="row">
   <div class="col-xs-12">
    <div id="loading">
    
    <div class="progress progress-striped active">
     <div class="progress-bar" style="width: 100%;">
      <span class="sr-only">60% Complete</span>
     </div>
    </div>
    
    </div>
   </div>
  </div>
 </div>

The snippet below makes a JQuery AJAX call. In the event of either success or error, the div with ID "loading" is hidden.
<script>
  $(document).ready(function (){
   function init(){
    $.ajax({    
     url: 'gethours.php?action=get-time',  
     dataType: 'json',  
     success: function(json) {  
      $("#loading").hide();
      var jlength = Object.keys(json.return_param).length;
      alert('parameter1 = '+jlength); 
      
     },  
     error: function(xhr, ajaxOptions, thrownError) { 
      $("#loading").hide();
      alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText + "\r\n" + "Err-01");  
     }  
    });    
   }
   
   init();
  })
 </script>

The screen shot below shows the animated stripped bar while AJAX is making the calling. For purposes of this post, I've placed a 5 second delay on the back end.

Need help on some web coding task? Let me know about it. Email me at jrwxpun.dolor@gmqoapmssail.co57agsblm and I'll be more than happy to blog about it with my thoughts.

Hosting of the sample pages were provided for by the following:

Saturday, September 6, 2014

IP Switching with AJAX-JSON using Recursion

In the last post, I showed an IP switching technique using AJAX-JSON. This checks on the first IP, and if determined not to be live, uses the second IP. This approach works fine if we're sure that at least one of the two IP addresses will always be live.

But what if there's a possibility that both IP addresses will be down? Or what if there's more than two IP addresses to test?

That would put a need for the testing of IP address to be repeated until we get a live IP or run out of IP address to test. The code for testing will be adjusted to apply recursion.

The adjusted code:
<!doctype html>
<html>
  <head>
    <title>IP Switch with JSON</title>
 <script src="jquery-1.11.1.min.js"></script>
 <script>
 
 $(document).ready(function (){
  function test_ip(Ip_arr, ctr, finalUrl){
   if(ctr < Ip_arr.length){
    var param = 'json_test.php?action=test&jsonp=?';
    var test_url = Ip_arr[ctr];
    $.ajax({
     url: test_url + param,
     dataType: 'json',
     timeout: 1000,
     success: function(jdata){
      var offset = ctr +1;
      finalUrl('IP' + offset, Ip_arr[ctr]);      
     },
     error: function(xhr, ajaxOptions, thrownError) {
      ctr += 1;
      test_ip(Ip_arr, ctr, finalUrl);
     }
    });
   }
   else{
    alert("No IP is available");
   }
  }
   
  function start_app(){
   var Ip_arr = ['http://aaa.aa.aa.10/', 'http://zzz.zz.zz.15/'];
   var ctr = 0;
   test_ip(Ip_arr, ctr, function(Ip_mode, ip){
    alert('IP mode= '+Ip_mode+ '/ IP: '+ip);
    //continue with code
   });
  }
  
  start_app();
 })
 
 </script>
  </head>
  <body>
  </body>
</html>

The start_app() function defines a variable ctr. This is the IP array element counter and keeps track of the current element. The initial value is zero, being the first array element in JavaScript. The element counter is passed as a parameter to test_ip() function.



When test_ip() function is called. A check is made if the element counter variable ctr has not yet reached the total array length.This means that there is an IP address to test and the code proceeds with the $.ajax call. Otherwise, the counter has reached the array length and there is no more IP address to test. An alert handles this situation.























If the check determines an IP address to test, a variable test_url is defined and takes the current element of the IP array. The variable is used on the url setting of the $.ajax call.






The error handler of the $.ajax call is triggered when the AJAX call to the url fails to return the JSON response. The variable ctr is incremented by one- this moves to the next element of the IP array. The call to test_ip() function is repeated.
Add caption


















The test_ip() function is repeatedly called until a live IP is found or the testing runs out of IP addresses to test.

Need help on some web coding task? Let me know about it. Email me at jrwxpun.dolor@gmqoapmssail.co57agsblm and I'll be more than happy to blog about it with my thoughts.

IP Switching with AJAX-JSON

A web service may be published on more than one IP. In the diagram below a client can access a web service using hypothetical IP addresses on URL addresses:
  • http://aaa.aa.aa.10/web_service
  • http://zzz.zz.zz.15/web_service

This set up is typical for web services handling large volume request bandwidth. If one IP gets overloaded and becomes temporarily unavailable, a switch to the second IP is made.

A client may connect to the web service using an available IP. A routine PING check is made to see if the IP is live. When the IP becomes unavailable, adjustments are made to the web application to connect on the second IP.

This becomes a tedious approach since the check is made manually. The set of codes in this post presents one way to automate IP switching.

A test page on the web service will return a simple JSON response. The idea is for the client  to request the test page using IP#1. If after a defined period and no response was made, IP#1 is assumed to be down and switch to IP#2 is made.

For the test page, json_test.php, a simple JSON is returned as a response:
<?php
//json_test.php
//
header('Content-type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *'); 
$function_name = '';
$source = '';
if (isset($_GET['jsonp'])){
 $function_name = $_GET['jsonp'];
}
$arr['id'] = 'test';
$arr['desc'] = 'ok to proceed';

$json = json_encode($arr);
echo "$function_name (\n";
echo $json;
echo ");\n";
?>


The web client making the JSON IP test is as follows
<!doctype html>
<html>
  <head>
    <title>IP Switch with JSON</title>
 <script src="jquery-1.11.1.min.js"></script>
 <script>
 
 $(document).ready(function (){
  function test_ip(Ip_arr, finalUrl){
   var param = 'json_test.php?action=test&jsonp=?';
   $.ajax({
    url: Ip_arr[0] + param,
    dataType: 'json',
    timeout: 1000,
    success: function(jdata){
     finalUrl('IP1', Ip_arr[0]);
    },
    error: function(xhr, ajaxOptions, thrownError) {
     finalUrl('IP2', Ip_arr[1]);
    }
   });
  }
   
  function start_app(){
   var Ip_arr = ['http://aaa.aa.aa.10/', 'http://zzz.zz.zz.15/'];
   test_ip(Ip_arr, function(Ip_mode, ip){
    alert('IP mode= '+Ip_mode+ '/ IP: '+ip);
    //continue with code
   });
  }
  
  start_app();
 })
 
 </script>
  </head>
  <body>
  </body>
</html>

The start_app() function fires up the web application. This creates an array of IP addresses to  test. This is followed by a call to test_ip() function with the array anonymous function as parameters.












The test_ip() function parameters takes the array of IP addresses to test and a reference to the anonymous function, finalUrl. The function starts with initializing a variable param to pass parameters on the URL. Take not of the jsonp parameter since the web client may make a cross domain call. This is followed by JQuery $.ajax() call.
















The URL setting has the first IP in array and the variable param values, The timeout is set to 1 second- if after this period. If after this period, a JSON response was successful, the first IP is assumed to be live and passes this to the finalUrl anonymous function reference.

Otherwise, there was no JSON response on the timeout. The error handler calls the finalUrl anonymous function reference with the second IP.

The anonymous function is the heart of the web client application. The live IP is now used as needed:























Need help on some web coding task? Let me know about it. Email me at jrwxpun.dolor@gmqoapmssail.co57agsblm and I'll be more than happy to blog about it with my thoughts.

Tuesday, September 2, 2014

Keeping AJAX in sync

The front end of a web app needs to pick up data from a back end and do complex processing on it. An attempt would be to write AJAX on the front and process the returned data after the AJAX call. .

The JQuery code snippet below is triggered after an element with ID 'process' is clicked. An AJAX call sends a request variable, name of a city to a back end, which returns its population and stores to a variable. The variable is then alerted after the AJAX call.















The approach would seem perfect, except that the asynchronous part of AJAX lets the code continue the processing. While AJAX is still waiting for the response value, the application will continue to the next part of the code. The alert will show a null or undefined value.

So there is now a need to keep the execution of AJAX in sync with the remainder of the code. This can be achieved by using anonymous functions as parameter as shown below:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery-AJAX-JSON</title>
<style>
div#result{
 color:blue;
 width:
}
</style>
<script src="jquery-1.11.1.min.js"></script>
<script>


$(document).ready(function (){
 function get_population(show_population){
  var city = 'Manila';
  var city_population = '';
  //execute ajax to pass requestvalues and get response output
  $.ajax({  
   url: 'get_population.php',
   type: 'post',
   data: { City: city},
   dataType: 'json',
   success: function(json) {
    city_population = json.population;
    show_population(city, city_population);
   },
   error: function(xhr, ajaxOptions, thrownError) {
    alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText + "\r\n" + "Err-01");
   }
   
  });
 } 
 
 function init_get_population(){  
  get_population(function(city, population){
   alert('Population of ' + city + ': ' + population);
   //continue processing the returned value
  });
 }

 $("#process").click(function(){
  init_get_population();  
 });
});

</script>
</head>

<body>

<form action="#" method="post">
<input id='process' type="button" name='submit' value='process' />
</form>
</body>

</html>

The anonymous function approach is similar to the click event handler. As soon as the element with ID 'process' is clicked, the function init_get_population() is called.













The init_get_population() will in turn call function get_population() but notice that the parameter being passed. Instead of typical value, an unnamed function is passed. This unnamed function is the anonymous function to keep our AJAX code is sync.







The anonymous function will in turn take in parameters of its own, variables city and population.

The function get_population() has the parameter- show_population,to "connect" to the anonymous function.


The function get_population initializes two variables, city and city_population. City will contain the value to be passed as request parameter to the AJAX call. City_population will contain the returned value.

The AJAX call will start with the settings show below. The back end URL called handles a Post HTTP request and return JSON formatted data.

The success setting below shows how the AJAX call will be in sync with the anonymous function. 

The variable city_population takes the returned population from the JSON response. The parameter show_population connects to the anonymous function will pass the city and an city_population values as parameters.
The call to the anonymous function lets us process the returned value as how we need it. Taking this approach, we are able to synchronize AJAX call with our code.

Got a question or have any web coding you'd like me to help you out? I'd be more than happy to assist you and blog about it!

Just drop me an email at jrundolor@gmamail.com and tell me more about it!