Solved

jQuery form validation before ajax submit

Posted on 2012-04-07
10
2,026 Views
Last Modified: 2012-04-12
I am trying to add a simple form valadation to my jquery mobile webapp using the jQuery Validation Plugin.

The problem I have is the ajax runs straight away and doesnt wait for the validation.

I have included the html and js script below.

Could someone give me some pointers.

Thanks

Steve


<!DOCTYPE html> 
<html> 
<head>
    <?php require_once 'includes/config.php'; ?>
    <?php require_once 'includes/header.php'; ?>
    <title><?php echo "Type - " . $pageTitle; ?></title>
    
</head>

<body>

<div data-role="page" data-theme="engagea" id="words" class='words'>
	<div data-role="header" data-theme="engagea">
        <a href="#" data-icon="home" data-role="button" data-transition="reverse slide" data-theme="engagea" style="font-size:18px" id="quitWords">Home</a>
        <h1>Words</h1>
	</div>
	<!-- /header -->
  
    <div data-role="content">
        <!-- Words JS --> 
        <script src="words/wordsjs.js"></script>
        <script type="text/javascript" src="http://jzaefferer.github.com/jquery-validation/jquery.validate.js"></script>

<style type="text/css">
* { font-family: Verdana; font-size: 96%; }
label { width: 10em; float: left; }
label.error { float: none; color: red; padding-left: .5em; vertical-align: top; }
p { clear: both; }
.submit { margin-left: 12em; }
em { font-weight: bold; padding-right: 1em; vertical-align: top; }
</style>

        <form action="" id="form" name="form" method="post">
            
            <div data-role="fieldcontain">    
                <label for="nname" style="font-size:16pt;padding:9px;"><strong>Enter Name:</strong> </label>
                <input id="nname" name="name" type="text"  value="" maxlength="32" style="background-color:White;font-size:16pt;"/>
                
                <label for="ssubject" style="font-size:16pt;padding:9px;"><strong>Subject:</strong> </label>
                <input id="ssubject" name="subject" type="text" value="" maxlength="32" style="background-color:White;font-size:16pt;"/>
                
                <input type="hidden" name="messageType" id="text" value="" />
            </div>
    
            <label for="mmessage" style="font-size:16pt;"><strong>Text Entry:</strong></label>
            <textarea id="mmessage" name="message"  style="background-color:White;height:350px;font-size:16pt;" class="required"></textarea> 
         
            <font size="+2"><button id="button" onclick="return submitWords(this.form);" data-theme="e" data-icon="check">Save</button></font>
        </form>
    </div>
    <!-- /content -->

	<?php require_once 'includes/footer.php'; ?>
  
</div>
<!-- /page -->

</body>
</html>

Open in new window





function submitWords(frm) {
	$("#form").validate();
	submitWords1(frm);
}


function submitWords1(frm) {

    $.blockUI({ message: '<h1><img src="images/busy.gif" /><br>Submitting...<br>Please Wait...</h1>' }); 
	//setTimeout($.unblockUI, 5000); 	
	var name = encodeURIComponent(frm.name.value)
	var subject = encodeURIComponent(frm.subject.value)
	var message = encodeURIComponent(frm.message.value)

    $.ajax({
      	type: 'POST',
      	url: 'words/submitwords.php',
	  	dataType : 'json',
	  	data: "name="+name+"&subject="+subject+"&message="+message,
		cache: false,
		async: true,
		
	success: function(data) {
						
			if (data.status == "success") {
				
				//alert("SUCCESS. " + data.id);

				$.blockUI({ message: '<h1><img src="images/big-tick.jpg" width="160" height="140" /><br><font color="#009900">Success!</font><br>Words submitted.</h1><br>' }); 
				
				setTimeout(function(){$.unblockUI;
				window.location.href = "index.php";
				}, 4000);
				//alert("Image Save Successful!");
				
			} else {
				setTimeout($.unblockUI,1000); 
				alert("Oops. " + data.message);
			}
		},
		
		error: function(jqXHR, exception) {
            if (jqXHR.status === 0) {
                alert('Not connect.\n Verify Network.');
            } else if (jqXHR.status == 404) {
                alert('Requested page not found. [404]');
            } else if (jqXHR.status == 500) {
                alert('Internal Server Error [500].');
            } else if (exception === 'parsererror') {
                alert('Requested JSON parse failed.');
            } else if (exception === 'timeout') {
                alert('Time out error.');
            } else if (exception === 'abort') {
                alert('Ajax request aborted.');
            } else {
                alert('Uncaught Error.\n' + jqXHR.responseText);
            }
        }
	});
	    return false;
};

Open in new window

0
Comment
Question by:sjtinsley83
  • 5
  • 4
10 Comments
 
LVL 3

Expert Comment

by:fjocke
ID: 37820222
By default AJAX is asynchronous so your script will not wait for your
AJAX response before it continues. Setting 'async' to false will have
the script wait.

You can check how the change the ajax async here: http://api.jquery.com/jQuery.ajax/
0
 
LVL 6

Expert Comment

by:jjperezaguinaga
ID: 37821301
Greetings sjtinsley83,

The easiest way to do this is to wrap your ajax call in functions. For instance:

$(document).ready(function() {

      function validation()
     {
              // your validation code ...
              // return 1 if validation succedded
      }

      function ajaxCall() 
      {
             $.ajax({ ... }) // your  ajax code
      }

      function load() 
      {
            //Validation will be executed as a result, so the ajaxCall will be used only if validation passed.
            if (validation()) ajaxCall();
      }

      load(); // we call the load function

});

Open in new window


Please, by no means use async to false. Remember what AJAX stands for, async to false WAITS until the server responds, which may BLOCK your website. If you develop a plugin, or code that uses this feature and by some reason it fails, you may hang the client forever.

There are multiple design patterns that can be used to handle AJAX requests without blocking the server. Feel free to investigate more; there are plenty of documentation related on why async to false is a really bad idea.

Hope it helps!
-JJ
0
 

Author Comment

by:sjtinsley83
ID: 37821693
Hi JJ,

GOSH... I'm learning by the second which is great.. I'm still a little confused with how I will call the validation then the ajax submit functions.

Currently I have a button <button id="button" onclick="return submitWords(this.form);" data-theme="e" data-icon="check">Save</button> which calls the corrent function with the correct variables.

If I change it to the above function layout, will the button have a onclick for load(this.form)?

Also... why do I need $(document).ready(function() { in the javascript file? Can the functions not just sit there untill they are called? Im sure there is a good reason for this...

Many Thanks

Steve
0
 
LVL 6

Expert Comment

by:jjperezaguinaga
ID: 37822043
Oh, the document ready is just an enhancement to make sure all your DOM was loaded before any operation can be performed :) it's just a technique I recommend but of course the functions can be just there.

When you put return in a onclick button what happens is that that default behavior relies on the result of the called function. Buttons don't have a default reaction, but for instance, if you would had that in a <input type="submit"> what would happen is that the form wouldn't be submitted if the validation failed.

In this case, you can just simply do this:

<!-- HTML -->
<button id="button" onclick="load(submitWords(this.form));" data-theme="e" data-icon="check">Save</button>

//Javascript

function load(validation)
{
 if(validation) ajaxCall();
}

Open in new window


Does that make sense? I'm trying to make sure you change the less code possible while trying to understand the control flow; you could ready it like this:

* The validation is triggered when the button is pressed. A HTML object <form> is sent to the validation function.
* The validation function returns true or false depending if the <form> object and its content passed the validation.
* The returned value then is passed to other function, this one called load.
* Load receives an argument and checks if it's true or false. If true -which means the validation passed- then performs the ajax call.

Now, remember buttons don't have a default behavior in HTML. If you want to add functionality to a button, you do it through Javascript (which is fine), but you have to make sure the user receives feedback about what's going on when he clicks a button, since the browser won't do anything. I think you understand AJAX enough since you are using a correct aproach, but I just wanted to point that out.

Cheers!
-JJ
0
 

Author Comment

by:sjtinsley83
ID: 37824064
Hi JJ,
Thanks so much for the help!
I think im getting there with this but still haven't got it working correctly.
Ive taken what you had said and played around with it for a bit. I have the validation working but it wont submit the ajax request...

I know its my knowledge of javascript but im learning!

Ive just signed up for a jsfiddle account and posted a simplified version of what I want to do: http://jsfiddle.net/stinsley/q2h6Z/2/

Can you offer any more advise?

Ive added 2 buttons but only the first does something...
<button id="button" onclick="return submitWords(this.form);" data-theme="e" data-icon="check">Save A</button>

<button id="button" onclick="load(submitWords(this.form));" data-theme="e" data-icon="check">SaveB</button>

Also if i add $(document).ready(function() { nothing works...

Thanks

Steve
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 6

Accepted Solution

by:
jjperezaguinaga earned 500 total points
ID: 37824412
Ah no problem my friend, we are all here to learn!

You were ALMOST there! You just forgot to add "return true" in the validation() function!

Jsfiddle allows you to use the DOMReady function (which is pretty much the reason why the .ready does not work); I usually use "onDomReady" instead of "no wrap (head)" so I don't have to use the ready function.

Oh, you can even test ajax posts in jsfiddle! Read the docs and it will be easy enough to actually simulate your whole script instead of with just functions!

Btw, here's the code with the return true in case you got lost ;) http://jsfiddle.net/q2h6Z/7/

Code strong!
-JJ
0
 

Author Closing Comment

by:sjtinsley83
ID: 37834159
Thanks so much for the help!

I wondered if I could ask you another question.....
I have only started looking into this but it could be complex...

I want to be able to display a WAITING screen on a php page whilst the value of ready in a mysql database is 0. When I update the mysql READY field to 1 the waiting screen goes.

The goal eventually will be:
User click to voting.php
User sees waiting box
When I want the user to start voting the first question shows.
User can then complete all questions to the end.

Do you have any thought on this??

I thought perhaps have an ajax call every second until ready =1...

Any other ideas.

Thanks

Steve
0
 
LVL 6

Expert Comment

by:jjperezaguinaga
ID: 37834809
Hey! Thanks for the points!

Sure, there are multiple ways to do this! The easiest one is to just ajax your voting page and handle ONE ajax request with the .complete() method of the ajax object (you can read about it here! http://api.jquery.com/jQuery.ajax/); so you know when you request is complete and then perform and action.

For instance, if you request and you get 0, you can trigger an ajax request again until you get 1. How many times you can do this? As many times as you want, use a function within your success callback function:

...
success: function(data) { if(!data) ajax_load_again() }
....

Open in new window


There is other technique, which I think it's the best if you have no idea when the value will turn to 1. It's called long polling, and pretty much what you do is set timeouts for your ajax calls and request them every X seconds (you have to decide how many seconds is good, 1 second will hit your server... well, once every second, while 10 seconds may be too much).

It's easy to set a long polling request! Just read about setTimeout() in javascript or just put the code within a loop with a delay()

while(!updatable_value)
{
   updatable_vale = ajax_load();
   delay(5000);
}

Open in new window


Cheers!
0
 

Author Comment

by:sjtinsley83
ID: 37839771
Long polling looks like the job!

When you say put the code within a loop with a delay() do you mean in the php script?
Would that mean the ajax call would be fairly similar?
0
 

Author Comment

by:sjtinsley83
ID: 37839995
Ive opened another post and just posted an idea of the code.
http://www.experts-exchange.com/Programming/Languages/Scripting/AJAX/Q_27671581.html

Would you mind having a look?
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Introduction A frequently asked question goes something like this:  "I am running a long process in the background and I want to alert my client when the process finishes.  How can I send a message to the browser?"  Unfortunately, the short answer …
There are a couple ways to attach a JavaScript function to dynamically created elements. You can make a new script for each element as it’s created or you can use delegation. Delegation allows a single script that is added at page creation to mat…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now