On select of a checkbox a loading screen covers the site until the selction is loaded

I am building a page up using some javascript where basically on select of a checkbox the page automatically refreshes and eventually the page will load the results, not quite there on that bit yet.

But what I want to see happening if its possible is that on click of the checkbox to stop them quickly selecting another checkbox before that one has loaded it would be good to have a faded out screen appear to cover the site until the site has loaded.

here is my full code:



<?
session_start();
error_reporting(E_ALL);
ini_set('display_errors','On');
include("config.php");
?>
<?
$url = $_SERVER['REQUEST_URI'];
print "<pre>";

print $url;

$url_parsed = parse_url($url);
//print_r($url_parsed);

parse_str($url_parsed['query'], $url_parts);
print_r($url_parts);

print "</pre>";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script language="JavaScript">
function checkRefresh(value)
{

	document.form1.submit();
	
}
</script>

<title></title>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link href="css/style.css" rel="stylesheet" type= "text/css" />

<meta name="keywords" content=""/>

<meta name="description" content=""/>

<meta name="robots" content="all" />
</head>

<body>
<div id="wrapper">
<?
if (is_array($_GET['regions'])) {
     foreach($_GET['regions'] as $regions) {
       //echo $regions;
     }
}
?>
<form name="form1">
<?php
$r=mysql_query("select Id_Rsrt, Nom_Rsrt, IdCntry_Rsrt, Id_show from tbl_resorts where (IdCntry_Rsrt='7') and (Id_show='1') order by Nom_Rsrt ASC");
while($q=mysql_fetch_assoc($r)){ ?>
<input type="checkbox" name="regions[]" value="<?=$q['Id_Rsrt']?>" onClick="javascript:checkRefresh()" <?=((in_array($q['Id_Rsrt'], $_REQUEST['regions'])) ? "checked=\\"checked\\"" : "")?> class="inline" /><?=$q['Nom_Rsrt']?><br/>
<? } ?>
</form>

<div id='result_table'></div>

</div>
</body>
</html>

I htink I understand that that process does its magic inside this function:


function checkRefresh(value)
{

	document.form1.submit();
	
}

But looking for some tips of what to do.

Cheers

Hi there,

Does it have to be an overlay?
A simpler solution might be to just temporarily disable the checkboxes.

Hi Pullo,

Umm no its not necessary but I know the people I work for given the option would like to see somehting visually appealing like that happening, as it looks clever too, than the other way, which in honesty sounds good too.

If for instance the buttons checkboxes stopped working and also faded out whilst it loaded, now again that will go down better.

Thanks for the reply though

Hi again,

Ok, lets go with that then.
I presume your form is using (going to use) AJAX to fetch the results from the server.
If that is the case, you will want to attach an event handler to your checkboxes, that fires the request and blocks the UI every time one of them is selected.
Then, when the AJAX request returns, you will want to unblock the UI and update your content.

I made you a simple demo that does that.

My script fires a request to sleep.php, which, as the name suggests, sleeps for three seconds, then returns the value of whichever option you selected.

Here’s the code:

index.html

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Block UI with jQuery</title>
    <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
    <style>
      #myForm div{margin-bottom:5px;}
      #result{
        border:solid 1px green; 
        background: #6F9; 
        margin-top:15px; 
        padding:7px; 
        display:none;
      }
      #black_overlay{
        display: block;
        position: fixed;
        top: 0%;
        left: 0%;
        width: 100%;
        height: 100%;
        background-color: black;
        z-index:1001;
        -moz-opacity: 0.8;
        opacity:.80;
        filter: alpha(opacity=80);
      }
      #loading{
        padding: 10px;
        border: 5px solid orange;
        background-color: white;
        z-index:1002;
        overflow: auto;
      }
    </style>
  </head>
  
  <body>
    <h1>My wonderful form</h1>   
    <form action="convert.php" method="post" id="myForm">
      <p>Please select an option:</p>
      <div>
        <input type="radio" name="option" value="1" id="option1">
        <label for="option1">Option 1</label>
      </div> 
      <div>
        <input type="radio" name="option" value="2" id="option2">
        <label for="option2">Option 2</label>
      </div> 
      <div>
        <input type="radio" name="option" value="3" id="option3">
        <label for="option3">Option 3</label>
      </div>   
    </form>
    
    <p id="result"></p>
    
    <script type="text/javascript">
      jQuery.fn.center = function () {
        this.css("position","absolute");
        this.css("top", ( $(window).height() - this.height() ) / 2+$(window).scrollTop() + "px");
        this.css("left", ( $(window).width() - this.width() ) / 2+$(window).scrollLeft() + "px");
        return this;
      }  

      $(document).ready(function() {
        $("input:radio").on("change", function(e) {
          $("#result").hide();
          var v = ($(this).val());
          
          $('<div id="black_overlay"></div>').appendTo('body');
          $('<div id="loading">Loading Content</div>').appendTo('body').center();
          
          $.ajax({
            type : "POST",
            url : "sleep.php",
            data  : 'v=' + v,
            success : function(res) {
              $("#loading").remove();
              $('#black_overlay').fadeOut('slow', function() {
                $('#black_overlay').remove();
                $("#result").text("You chose option " + res).css("display", "inline-block");
              });              
            }
          });
        });
      });
    </script>
  </body>
</html>

sleep.php

<?php 
  sleep(2);
  echo $_POST['v'];
?>

I hope that helps you.
If you have any questions, let me know.

Hi Pullo,

Good to speak to you again.

I added all the above to my development page and I needed to make a small change as im using checkboxes rather than radio’s so changed this bit:


$("input:checkbox").on("change", function(e) {

I think also with the way this page works, the three second wait is being cancelled out and the blackout for some reason as there is another script thats being called on elect of the checkbox to refresh the page.

Here is the link to the dev area:

http://devchecksafetyfirst.csf.dcmanaged.com/

And here is the full code for that page as it stands:


<?
session_start();
error_reporting(E_ALL);
ini_set('display_errors','On');
include("config.php");
?>
<?
$url = $_SERVER['REQUEST_URI'];
print "<pre>";

print $url;

$url_parsed = parse_url($url);
//print_r($url_parsed);

parse_str($url_parsed['query'], $url_parts);
print_r($url_parts);

print "</pre>";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script language="JavaScript">
function checkRefresh(value)
{
	document.form1.submit();	
}
</script>

<title></title>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<style>
      #myForm div{margin-bottom:5px;}
      #result{
        border:solid 1px green;
        background: #6F9;
        margin-top:15px;
        padding:7px;
        display:none;
      }
      #black_overlay{
        display: block;
        position: fixed;
        top: 0%;
        left: 0%;
        width: 100%;
        height: 100%;
        background-color: black;
        z-index:1001;
        -moz-opacity: 0.8;
        opacity:.80;
        filter: alpha(opacity=80);
      }
      #loading{
        padding: 10px;
        border: 5px solid orange;
        background-color: white;
        z-index:1002;
        overflow: auto;
      }
</style>
</head>
<body>

<?
if (is_array($_GET['regions'])) {
     foreach($_GET['regions'] as $regions) {
       //echo $regions;
     }
}
?>
<form name="form1" id="myForm">
<?php
$r=mysql_query("select Id_Rsrt, Nom_Rsrt, IdCntry_Rsrt, Id_show from tbl_resorts where (IdCntry_Rsrt='7') and (Id_show='1') order by Nom_Rsrt ASC");
while($q=mysql_fetch_assoc($r)){ ?>
<input type="checkbox" name="regions[]" value="<?=$q['Id_Rsrt']?>" onClick="javascript:checkRefresh()" <?=((in_array($q['Id_Rsrt'], $_REQUEST['regions'])) ? "checked=\\"checked\\"" : "")?> class="inline" /><?=$q['Nom_Rsrt']?><br/>
<? } ?>
</form>

<p id="result"></p>


<script type="text/javascript">
      jQuery.fn.center = function () {
        this.css("position","absolute");
        this.css("top", ( $(window).height() - this.height() ) / 2+$(window).scrollTop() + "px");
        this.css("left", ( $(window).width() - this.width() ) / 2+$(window).scrollLeft() + "px");
        return this;
      }

      $(document).ready(function() {
        $("input:checkbox").on("change", function(e) {
          $("#result").hide();
          var v = ($(this).val());

          $('<div id="black_overlay"></div>').appendTo('body');
          $('<div id="loading">Loading Content</div>').appendTo('body').center();

          $.ajax({
            type : "POST",
            url : "sleep.php",
            data  : 'v=' + v,
            success : function(res) {
              $("#loading").remove();
              $('#black_overlay').fadeOut('slow', function() {
                $('#black_overlay').remove();
                $("#result").text("You chose option " + res).css("display", "inline-block");
              });
            }
          });
        });
      });
</script>
</body>
</html>

Hi there,

The problem is the checkRefresh() function, which submits the form and cancels out the overlay.
Do you need to submit the form every time a checkbox is checked?
I had assumed you were doing something with AJAX.

The idea is that yes the page refreshes every time a checkbox is selected and the results then change.

I’m building this up at the moment, as I havent used AJAX before so at this stage its using the checkRefresh() function.

Its building an array up at the moment, eventually that array will control what gets displayed, but I’m not quite there yet.

There no way around it is there with my checkRefresh() function.

I know you will probably laugh, but i took the refresh bit out of the other function and placed it at the end of your one:


type : "POST",
 url : "sleep.php",
data  : 'v=' + v,
success : function(res) {
$("#loading").remove();
$('#black_overlay').fadeOut('slow', function() {
$('#black_overlay').remove();
$("#result").text("You chose option " + res).css("display", "inline-block");
document.form1.submit();

And by the seems it allows yours and what I got at the moment to work together.

Nah, man!
Everyone has to learn somewhere.
Let’s step through this bit by bit:

If I understand you correctly, you are currently submitting your form every time a user checks a checkbox.
The script you are submitting the form to is returning some kind of array based on what has been selected and you are using this array to add more content to your page.

This is a perfect case for AJAX.
Currently, every time you submit the form, you are causing the page to reload.
On a small test site (probably hosted locally), this is ok and you don’t notice much of a performance hit, but when your site grows and you have everything on a remote server, all of these reloads will slow your page down and could make it feel sluggish.

What I was proposing is that you use JavaScript (and the jQuery library) to monitor when a user checks or unchecks a checkbox.
You do that, like this:

$("input:checkbox").on("change", function(e) {
...
}

Then, you should fire off an AJAX request to the script you were otherwise submitting your form to (sleep.php was just an example).

$("input:checkbox").on("change", function(e) {
  $.ajax({
    type : "POST",
    url : URL HERE,
    data : DATA HERE
  });
}

This will post the data you specify to the script you specify.

You can then use a success callback to update the page with whatever the PHP script returns.

$("input:checkbox").on("change", function(e) {
  $.ajax({
    type : "POST",
    url : URL HERE,
    data : DATA HERE,
    success : function(res) {
      UPDATE STUFF HERE        
    }
  });
}

Now, we come to the starting point of your question.
While the AJAX is off doing its thing, how can we block the UI and ensure that the user doesn’t select a different checkbox.

In psuedo code you would do that, like this:

$("input:checkbox").on("change", function(e) {
  BLOCK UI HERE
  $.ajax({
    type : "POST",
    url : URL HERE,
    data : DATA HERE,
    success : function(res) {
      UPDATE STUFF HERE   
      UNBLOCK UI HERE     
    }
  });
}

And that was what my code was doing.

However, you shouldn’t use both scripts together, rather you should integrate mine into yours.

Does that make sense?

Off Topic:

@Pullo; Dave, you really must put all the demos you create onto a snippets page on your blog! They are excellent as a learning tool and for reference/examples!

Nope, it is more appreciated by all of us when folk have a go at something and at least try and solve the problem before coming back to ask for help. Far too many people just expect a solution to be handed to them on a plate. Laugh? no, Applaud and help -yes.

[/FONT][/COLOR]

Off Topic:

Sure! I can do this in a spare moment and I’ll link to the new page in my signature. Watch this space …

Yes I think I can see what you where getting at, and will go through it now and take a look.

And yes your right, basically what happens is the user for example clicks a country before heading to the page im developing, then all the hotels are displayed.

Then through a set of dynamically generated checkboxes in relation to the country, the user refines their search by using the checkboxes, and each time they check it, it refreshes and the results change, thats why I wanted to stop them clicking one straight after the other, as there a possibilty they wont get the search they thought they asked for.

Ive just managed to get the data out of the array in preparation to start using it to draw out the hotels from the database using the code below:


if (is_array($_GET['regions'])) {
	 $regionsArray = array();
     foreach($_GET['regions'] as $regions) {
		 $regionsArray[] = '\\''.$regions.'\\'';
	 	 $ids = implode(',', $regionsArray);
$sql = mysql_query("SELECT * FROM table WHERE id IN ($regionData)");
     }
	 echo $ids;
}

I wont to add a little bit to the off topic stuff to above, and say that in the course of 8-9 months this forum has pushed my skill level up massively, and I try not to come on here asking for the full answer, as I know its not the best way to learn, but everyone on here is awsome.

Ye I think I get it properly now, I get the sleep.php bit, so that basically will allow the script I just posted above to work to put the array into the select from the database instruction.

Then on success of that the (success : function(res) {) deals with it and then the blackout screen goes away.

Awsome ye, I like that, just getting it all tied up now to see if I can get it working.

I will have a go and come back if needed, thanks Dave.

Lee

This is the bit you want to be doing with AJAX.
You can define (for example) a <div> element with an id of “results” and dynamically load the results of your AJAX call into there.

Kind of. The sleep was just there, so that you could see the overlay blocking the UI.

Also kind of. You do have to remove the overlay (it doesn’t just happen automatically), but all of that will happen within the success callback.

I wrote a short blog post on AJAX and jQuery. Maybe it’ll help you.

Good luck! You sould have all the pieces you need now. It’s just a matter of putting them together.

Just thinking out loud here:

Can I add a php variable onto your code below, so it looks liek this.

var v = ($(this).val());

var v = (<?php $regionData?>);

Or am I barking up the wrong tree, as rather than just sending up one value such as the value of the checkbox I need to build the query up.

Hi,

Sorry for the short reply, but I am now away from the PC.

Anyway, it is certainly possible to write the value of a JS variable using PHP.
Just make sure it is the correct type (i.e. what your script is expecting) and all will be good.