Making Some Elements Inactive with jQuery BlockUI Plugin + Tweaks

Hello everyone,

When a contact form has been sent, a second form comes up on my website. I am attempting to set it up so that after the e-mail is sent on the first form, the 2nd form will come up while the rest of the page is made inactive by making use of the jQuery BlockUI plugin. The way I’m going to need to do this is to target the entire container div for the blocking of element activity, and I haven’t figured out why I’m not able to see the 2nd form when it is placed outside of the container. The other part of this is tweaking the call to the blockUI() method so that white boxes don’t appear after it executes as well as getting rid of the default “Please Wait…” message and disabling the hourglass/working status that a user’s mouse would show when it is hovering over the blocked content (as if something is loading when nothing else will change on the page). Hopefully someone knows how to tweak this so that I can achieve what I want. I will pop on over to the CSS forum and see if someone can help me figure out how I can see the 2nd form/other content when it is placed outside of the container div.

Screenshot of what it looks like

jQuery:


function showResult(response){
	if (response.indexOf("Submission Successful") != -1){
		$("#confirmform").css("display","block");
		$("#middle").block({css: {backgroundColor: '#E0EBEB'}});
		$("#leftside").block({css: {backgroundColor: '#E0EBEB'}});
		$("#rightside").block({css: {backgroundColor: '#E0EBEB'}});
	} else if (response.indexOf("Invalid E-mail") != -1){
		
	} else if (response.indexOf("Nothing in Box") != -1){
		
	} else {
		//do nothing
	}
}

My website: World Review Group

:wink:

Hi,

It sounds to me that you are after some kind of Lightbox effect.
As I remember, fancyBox does forms quite nicely (or [URL=“http://fancyapps.com/fancybox/”]fancybox2 if the site is non-commercial or you are willing to pay for a licence).
In both versions there are options to remove the close button, but you would probably have to hack the plugin, so that it doesn’t shut when you click on the overlay: http://stackoverflow.com/questions/1363806/jquery-fancybox-prevent-close-on-click-outside-of-fancybox

Alternatively, you could just build this functionality yourself.
Here’s a demo.

Thanks, Pullo. This seems to be more along the lines of what I have been looking for; however, I will have to customize the effects so that it does what I need it to do. Apparently, the default behavior is that it puts the overlay and it shows a small box on top of the overlay after you activate its trigger (in my case, the trigger is the submit button on the first form, which has an i.d. of #submit).

As I mentioned before, the goal I have is to display the second form inside of a div with an i.d. of #submissionform on top of the gray overlay after the user has successfully submitted the e-mail address on the first form.

I haven’t found any real tutorials on how to really customize the source code or the CSS in order to achieve this. It seems as though the most popular use of these jQuery plugins is for image galleries. I saw that there are other “more customizable” alternatives to LightBox (like ColorBox), but I still see no tutorials that help me with my specific needs.

Here is my current jQuery:


jQuery(document).ready(function(){
	jQuery("#emailbox").submit(function(event){
		event.preventDefault();
		var ea = $("#go").val();
		
		$.ajax({
    		url: $(this).attr('action'),
			type: $(this).attr('method'),
			data: $(this).serialize(),
			success: function(response){
				$('#status').append(response);
				showResult(response);
			}
			});
	});
});

function showResult(response){
	if (response.indexOf("Submission Successful") != -1){
		$("#submissionform").css("display","block");
		$("#submit").lightBox({});
	} else if (response.indexOf("Invalid E-mail") != -1){
		//display error
	} else if (response.indexOf("Nothing in Box") != -1){
		//do nothing
	} else {
		//do nothing
	}
}

If I make the call for the LightBox right after the document.ready function, it will display the lightbox right after I click the submit button - without displaying the second form. If I make the LightBox call after the result from my PHP script is tested and returns “Submission Successful”, the second form is shown (in its rightful time to be shown), but there is no overlay effect and LightBox does nothing. :confused:

Edit: I downloaded the LightBox version 0.5

Hi there,

Are you talking about the demo I made or one of the plugins I recommended?

I’m talking about the Lightbox plugin, but on another read of your previous post, I see that you recommended FancyBox - which is especially good for forms.

Let me give that a try and see what I come up with.

Hmm… Well, also, your demo does not use a plugin. Neat! :slight_smile: I bet I can learn more with this one you wrote up and just tweak it a bit.

Yeah, with the demo we’re in full control of the code (i.e. no plugin needed), so if I was you, I’d go with that.
All of the JS is in the source code, so have a look at that (if you haven’t already), then let me know if you need a hand making it to do anything that it already doesn’t.

Well, I already see one thing that I need to figure out.

This script is not set up to test the results of the input. Mine tests the input in PHP and I have set up the other jQuery to receive those results as you’ll see in the code of my previous post. Do I migrate that .ajax() call into this new script, or how can I receive those results and show this next step with the black overlay accordingly? It seems I’d need to keep the .ajax() call in the current file as adding it to this new overlay script would make everything too complex. If that’s the case, I have no clue how I’d transfer that data over to the new script (Maybe the creation of an object or class or something? Not sure if jQuery is considered object-oriented programming and if you can make classes or anything.) I saved that new script in the same folder under file name ‘formoverlay.js’ and the code I posted earlier is in a file named ‘emailbox.js’.

I guess you’ve disappeared, Pullo, or have I not given you appropriate time to answer? Is the answer obvious?

I’m sorry, I had the audacity to sleep last night (I am in a different timezone).
I’ll get back to you soon :slight_smile:

Oh… yeah, you’re in Germany (sorry).

You were very responsive and then dropped off. I was just wondering.

It’s time for me to hit the hay as it’s 3AM here.

Do what’s convenient for you. I’ll be here trying to figure this out.

Hi there,

So, the first thing is that this example is really bare-bones.
It consists of one form, which upon submission displays a second form (to which it passes the value of its input) in a lighbox.
The lightbox can only be dispelled by reloading the page or by submitting the second form.
This is hopefully the UI blocking effect that you were after.

Apart from that my demo is devoid of all functionality.

This is what I would do.
I would attach an on submit event listener to the first form.
On submit, it fires off an AJAX request to a PHP script which can then validate the user’s input.
If the input validates, you can then display form two in the lightbox.

I would have all of this code together in one file (or also at the bottom of your page if you so wish).

jQuery is nothing more than a JavaScript library.
JavaScript is not a full-blown OOP language, rather an object-based language.
You can read more here: http://stackoverflow.com/questions/6954293/difference-between-object-oriented-and-object-based-language

Classes in JavaScript are a tricky subject.
You can kind of have them, as in you can approximate class-like functionality, but really and truly there is no such thing as classes in JS.
You can read more here: http://stackoverflow.com/questions/387707/whats-the-best-way-to-define-a-class-in-javascript

I hope that helps.

I will only be around on an irregular basis over the w/e, but I’m subscribed to this thread, so I’ll see you’ve answered.

Well, I’m certainly learning a lot, but at the moment, it’s a bit much (my head hurts). :injured:

Here’s my current code for this, and I’ll explain what the current behavior/outcome is below.

emailbox.js


//removes "your e-mail" default value in input selection when user activates input field
function input_focus(obj){
	if ( obj.value == obj.defaultValue ){
		obj.value = ""
	}
}

//resets default value in input field if it is left empty
function input_reset(obj){
	if (!obj || obj.length === 0)
		obj.value = obj.defaultValue;
}

//this is the function called from the onsubmit attribute of the first form
function firstSubmitProcessor(event){
		event.preventDefault();
		
		$.ajax({
    		url: $(this).attr('action'),
			type: $(this).attr('method'),
			data: $(this).serialize(),
			success: function(response){
				testFirstResults(response);
			}
			});
}

function testFirstResults(response){
	if (response.indexOf("Submission Successful") != -1){
		displayFormContent();
	} else if (response.indexOf("Invalid E-mail") != -1){
		//display error
	} else if (response.indexOf("Nothing in Box") != -1){
		//do nothing
	} else {
		//do nothing
	}
}

// Overlay Effect Script for E-mail Submission Form
function displayFormContent(){
	 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;
		  }
		
		  $('<div>',{ id : 'blackoverlay' }).insertBefore('#submissionform');
			
		  $("#submissionform").css("display", "block");
		  $("#submissionform").center();
						
		  return false;
}

first form markup:


 <form id="emailbox" name="form1" method="get" action="Scripts/emailtester.php" onsubmit="firstSubmitProcessor(this)">
        <div>
          <input type="text" name="email" id="go" value="your e-mail" onclick="input_focus(this)" onblur="input_reset(this)" maxlength="60"/>
          <input type="submit" id="submit" value="Join" />
        </div>
      </form>

styles of #blackoverlay and the #submissionform div (second form):


#submissionform{
	background:url("emailsubmission.gif") no-repeat scroll 50% 0 transparent;
	width:360px;
	height:280px;
	position:absolute;
	display:none;
	top:500px;
	right:460px;
	z-index:9;
	padding:60px 10px 0 45px;
	text-align:left;
}

#blackoverlay{
    display:block;
    position:absolute;
    top:0%;
    left:0%;
    width:100%;
    height:100%;
    background-color:black;
    z-index:8;
    -moz-opacity: 0.8;
    opacity:.80;
	filter:alpha(opacity=80);
}

What is occurring right now is when I submit the form the page is redirected to a blank page that merely displays the response obtained from the PHP code (for example, if you entered a valid e-mail in the first form, you would see a blank page that says “Submission Successful” come up).

As I figured, I would not correctly modify the example script from your hibbard.eu site on my first attempt. I don’t know that I’ve done what I need to do with the on submit event listener. I saw how there is an .addEventListener() JS function that I dabbled around with- maybe I need to get that in there as the HTML onsubmit attribute may not be accomplishing that.

You’re probably able to point out some other shortcomings, however. I’m sure that the event listener is not the only issue with my code. :teach:

Well, I tried that .addEventListener() in the JS file, but I’m still seeing that behavior.

Here’s what I added & modified:


document.ready(function(event){
	event.preventDefault();
	var form1 = document.form1;
	form1.addEventListener("submit", firstSubmitProcessor(), false);
});

//and the modified firstSubmitProcessor that's called from the HTML
function firstSubmitProcessor(){
		$.ajax({
    		url: $(this).attr('action'),
			type: $(this).attr('method'),
			data: $(this).serialize(),
			success: function(response){
				testFirstResults(response);
			}
			});
}

That’s where I am stuck at so far.

Hi there,

So, let’s break this down into smaller pieces:

The first thing to do, is to ensure that when the user clicks submit, the form fires off an AJAX request to a PHP script.
The PHP script should then validate the input it is passed and only show the second form (in the lightbox) if the server gives the all clear.

I have amended my example to reflect this:

If you leave the name field blank and click submit, the server will send back an error message and the program will display an alert box asking the visitor to ammend their input.
If you enter anything into the box, the server will give the all clear, return an appropriate response and the script proceeds as before.

Have a look at what I have done and see if you can use it to bring your script forward.

<!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>
    <!--http://www.sitepoint.com/forums/showthread.php?980303-Disabling-Making-Elements-Inactive-When-a-Form-is-Shown-->
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Display a form in a lightbox</title>
    <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
    <style>
      #black_overlay{
        display: block;
        position: absolute;
        top: 0%;
        left: 0%;
        width: 100%;
        height: 100%;
        background-color: black;
        z-index:1001;
        -moz-opacity: 0.8;
        opacity:.80;
        filter: alpha(opacity=80);
      }
      
      #image {
        position:relative;;
        border: 16px solid white;
        z-index:1002;
      }
      
      #hiddenContent{ 
        display: none;
        position: absolute;
        top: 25%;
        width: 350px;
        height: 200px;
        padding: 16px;
        border: 16px solid orange;
        background-color: white;
        z-index:1002;
        overflow: auto;
      }
    </style>
  </head>
  
  <body>
    <form id="myForm">
      <label for="name">Please enter your name:</label>
      <input id="name" type="text" />
      <input id="submit" type="submit" />
    </form>
  
    <div id="hiddenContent">
      <p id="userName"></p>
      <form id="myForm2">
        <label for="name">Please enter your age:</label>
        <input id="age" type="text" />
        <p><input id="submit" type="submit" /></p>
      </form>
    </div>

    <script>
      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 () {
        $("#myForm").submit(function(e) {
          name = $("#name").val();

          $.ajax({
            type : "POST",
            dataType:'json',
            cache : false,
            url : "myScript.php",
            data  : 'name=' + name,
            success : function(data) {
              if (data['validation'] == "fail"){
                alert("The server says: " + data['message']);
              } else {
                $('<div>',{
                  id : 'black_overlay',
                }).insertBefore('#myForm');
                
                $("#hiddenContent").css("display", "block");
                $("#hiddenContent").center();
                $("#userName").text(data['message']);
              }
            }
          });
          e.preventDefault();
        });
        
        $('body').on('submit','#myForm2',function(){
          age = ($(this).find($("#age")).val() == '')? "nothing" : $(this).find($("#age")).val();
          alert("You entered " + age);
        });
      });
    </script>
  </body>
</html>

myScript.php

<?php 
  $name = $_POST['name'];
  if ($name == ''){
    $response = array("validation" => "fail", "message" => "Please enter a name");
  } else {
    $response = array("validation" => "pass", "message" => "Hello $name,");
  }
  echo json_encode($response)
?>

Also, here’s a demo to see it in action.

Hi Dave, and thanks for your reply. Great post.

I’m still not doing it right!!! :nono: :headbang:

I’m not using an array to pass data back and forth, my form method is set to “get”, I’m not working on processing the second form (yet), among some other little nuances that differentiate my script from yours, but something is incorrect with what I tried.

Currently, when I submit the form, the page does nothing (no page refresh, no redirection, nothing). It does not matter if it is a valid submission or not.

Maybe someone knows what I have done incorrectly.

The JS file:


//this function is called by the AJAX method to handle the PHP script results
function testFirstResults(response){
	if (response.indexOf("Submission Successful") != -1){
		$('<div>',{ id : 'blackoverlay' }).insertBefore('#submissionform');
        $("#submissionform").css("display", "block");
        $("#submissionform").center();
	} else if (response.indexOf("Invalid E-mail") != -1){
		//display error
	} else if (response.indexOf("Nothing in Box") != -1){
		//do nothing
	} else {
		//do nothing
	}
}

// Overlay Effect Script for E-mail Submission Form
 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(){
        $("#emailbox").submit(function(e){

          $.ajax({
            type: $(this).attr('method'),
            dataType: 'json',
            cache: false,
            url: "emailtester.php",
            data: $(this).serialize(),
            success: function(data){
			  testFirstResults(data);
            }
          });
          e.preventDefault();
        });
 });

HTML Code:


<form id="emailbox" name="form1" method="get" action="Scripts/emailtester.php">
        <div>
          <input type="text" name="email" id="go" value="your e-mail" onclick="input_focus(this)" onblur="input_reset(this)" maxlength="60"/>
          <input type="submit" id="submit" value="Join" />
        </div>
 </form>

CSS styles:


#submissionform{
	background:url("emailsubmission.gif") no-repeat scroll 50% 0 transparent;
	width:360px;
	height:280px;
	position:absolute;
	display:none;
	top:500px;
	right:460px;
	z-index:9;
	padding:60px 10px 0 45px;
	text-align:left;
}

#blackoverlay{
    display:block;
    position:absolute;
    top:0%;
    left:0%;
    width:100%;
    height:100%;
    background-color:black;
    z-index:8;
    -moz-opacity: 0.8;
    opacity:.80;
	filter:alpha(opacity=80);
}

The PHP scripts:


/* emailtester.php */
<?php
		require_once('checkfirstsub.php');
		$email = $_GET['email'];
		if (!isset($email) || $email == "your e-mail")
			echo '<p>Submission Failure - Nothing in Box:  ' . $email . '</p>';
		else {
			$email = htmlentities($email);
			$obj_PE = new ProcessEmail();
			$messages = $obj_PE -> processor($email);
			echo json_encode($messages);	
		}
?>

/* checkfirstsub.php */
<?php
    class ProcessEmail
    {	
        public function processor($email)
        {
			if (!empty($email)){
				if ($email != "your e-mail"){
						if ($this -> isItAValidEmail($email))
						{
							return '<p>Submission Successful</p>';
						} else {
							return '<p>Submission Failure- Invalid E-mail</p>';
						}
				} else {
					return '<p>Submission Failure- Default Value in Box</p>';
				}
			} else {
				return '<p>Submission Failure- Nothing in Box</p>';
			}
        }

        public function isItAValidEmail($email)
        {
            if (filter_var($email, FILTER_VALIDATE_EMAIL))
                return true;
            else
                return false;
        }
    }
?>

Weird. It says Jennifer replied, but I see nothing here.

Jenifer was probably a spam bot who got zapped :slight_smile:
I’ll check out what you posted and get back to you later.

Hi again,

So, the problem seems to be occurring in your PHP script which must echo back the result of its validation, not just return it.
You also cannot wrap everything in a class without somehow initializing an object of that class.
Also, $email is undefined.

I’ve altered your PHP a little bit:

<?php 
$email = $_GET['email'];

if (!empty($email)){ 
  if ($email != "your e-mail"){ 
    if (isItAValidEmail($email)){ 
      echo '<p>Submission Successful</p>'; 
    } else { 
      echo '<p>Submission Failure- Invalid E-mail</p>'; 
    } 
  } else { 
    echo '<p>Submission Failure- Default Value in Box</p>'; 
  } 
} else { 
  echo '<p>Submission Failure- Nothing in Box</p>'; 
} 

function isItAValidEmail($email){ 
  if (filter_var($email, FILTER_VALIDATE_EMAIL)){ 
    return true; 
  } else {
    return false; 
  } 
} 
?>

There are, as they say, one hundred ways to skin a cat.
This is just one of them, but at least now the PHP script will return something reasonable as a response to the AJAX request.

Back in your JavaScript, you still had the dataType set to json.
It should be HTML:

$(document).ready(function(){
  $("#emailbox").submit(function(e){
    $.ajax({
      type: $(this).attr('method'),
      dataType: 'html',
      cache: false,
      url: "emailtester.php",
      data: $(this).serialize(),
      success: function(data){
        testFirstResults(data);
      }
    });
    e.preventDefault();
  });
});

After that, you can use console.log(response); in your testFirstResults function and work out what to dofrom there.

The rest is hopefully plain sailing.

I hope this helps.

Hello again, Dave, unfortunately this hasn’t gotten me over the hump. The page still sits blankly after submission. :shifty:

I had previously accomplished a full AJAX loop with the PHP I already had, but this time I am trying to accomplish that same loop while adding in the JS plugin that inserts the black overlay div that makes the other page elements inactive while the submission form is being interacted with (or until the user presses cancel on the 2nd form). Those are two files I posted the code for, which the .ajax() call from the JS first initializes the emailtester.php file, and the emailtester.php instantiates the checkfirstsub.php file as you’ll see if you look again. The emailtester.php does echo a variable $messages at the end of that file, after it runs the contents of the other file and returns the results to the first file. However, I did plug in your altered PHP, but I still see no changes.

As far as the JS changes/additions, I did change the dataType to ‘html’, and I also added in the console.log(response); into the testFirstResults() method (how do I view the console to see what has happened?).

I remember what solved my loop problem the first time (before I started tackling this black overlay functionality) was removing the onblur DOM event from the HTML form. The problem there was that the JS function being called from the onblur attribute would reset the submission value to “your e-mail” every time. I tried to fix that to only replace the value if the input field was empty, but I couldn’t figure that out yet; so, I removed the onblur once again, but it had no effect on what we are debugging right now.

Sigh, if programming was easy, then everyone would do it, and it would drive down the wages of the profession. This is hard and frustrating! :confused: -> :headbang:

Hi there,

Sorry to hear that this didn’t work. I appreciate how frustrating this can be …
Nonetheless, we have all of the pieces we need, it’s just a matter of fitting them together the right way.

So, sorry about my PHP comments. I somehow missed the top part of the PHP you posted previously.
I replaced my PHP script with what you posted in post 16 and it worked out of the box.

So, the next thing to do is to see what the AJAX call is returning.

If you alter your jQuery to this:

$(document).ready(function(){
  $("#emailbox").submit(function(e){
    $.ajax({
      type: $(this).attr('method'),
      dataType: 'json',
      cache: false,
      url: "emailtester.php",
      data: $(this).serialize(),
      success: function(data){
        //testFirstResults(data);
        console.log(data);
      }
    });
    e.preventDefault();
  });
});

Then post back with the results.

I wrote a short blog post about how to debug JS using the console.
You can find it here: Simple JavaScript debugging with Chrome’s console

If you read this, it explains how to see the output of the console.log() function.