A little bit of a jQuery / Ajax problem

Thank You Jim, I gave you karma for this one.

First thanks for showing me how to better stylize the form in css, I should have thought about top-down after all it’s Cascading Style Sheets ;D

I have a couple of questions if you don’t mind (They’re probably stupid ones)?

The errors in php that are thrown are they some kind of uniform standard error code(s) (I don’t if I’m wording that correctly), by that I mean is there some kind of governing body that determines them (I’m assuming there is)? An if so where could I find out the more info on the different error codes is so?

Secondly, how would this affect my php code that deals with graceful degradation (JavaScript Disabled)?

Thanks Once Again,
John

There is no such thing as stupid questions :slight_smile:

See this code above:
[php] function error($message, $code = 500) {
/* Set response code so javascript understands this is not a 200 OK

try to run the above, there is no real validation logic added, but it should be pretty easy to iron it out. of course you will not get live field validation on the client side without javascript. but posting the form should work and you can do validation then :slight_smile:

One thing to note is that I try to avoid fetching fields directly from the DOM, like this:
[php]var $username = $(’#username’).val();[/php]

I’ve always liked it better to use the form submit handler where you get the actual form object, and work with that. That way if you change the form content you don’t have to change it all over the client side.

And these http status codes is nothing more than what you see on a daily basis. 404 not found, 500 internal server error, etc. And if you open the console in the browser you’ll see that most requests return 200 OK :slight_smile:

Well actually I should had written it this way

[php]var $username = $(’#username’);[/php]

That way I wouldn’t be changing it all over the client side, all I would have to do is go up the var section at the top and change that if I needed to. I also get a little sloppy with my code when I trying to debug and I get tired. :slight_smile:

Jim, I have a quirky error (I believe it’s in jQuery)

First my php file ajax.php :

[php]<?php
header(‘Content-type: application/json’);
require_once ‘lib/includes/utilities.inc.php’;
/* set content type so javascript understands this should be parsed as json

  • and not html, this gives us automatic translation into arrays/object on
  • the client side */

/* get ajax action */
$action = isset($_GET[‘action’]) ? $_GET[‘action’] : NULL;

/* validate ajax action /
switch ($action) {
case ‘save’:
save($pdo);
break;
case ‘validateUnique’:
/
valid ajax action, run it! /
$action();
break;
default:
/
invalid ajax action, show error! */
error(‘Invalid action’, 400);
break;
}

function save($pdo) {
if (empty($_POST[‘username’]) || empty($_POST[‘password’]) ) {
error(‘Missing param(s)’, 400);
}
else
{
/* Hash the Password with password_hash (PHP 5.5 or greater) /
/
PHP 5.3, 5.4 - https://github.com/ircmaxell/password_compat/blob/master/lib/password.php */
$password_hash = password_hash($_POST[‘password’], PASSWORD_BCRYPT, array(“cost” => 15));

  try {
    /* Set the query with the user's profile using prepared statements */
    $query = 'INSERT INTO users ( username, password ) VALUES ( :username, :password )';
    /* Prepare the statement using PDO prepare method */
    $stmt = $pdo->prepare($query);
    /* Execute statement along with the prepared values */
    $result = $stmt->execute(array(':username' => $_POST['username'], ':password' => $password_hash));
    /* If a result is return back then return "success" back */
    if ($result) {
      output('Saved ' . $_POST['username'] . ' / ' . $_POST['password'] );
    } else {
      error('Not Saved!');
    }
  } catch (PDOException $e) { // Report the Error!	
    echo "DataBase Error: The user could not be added.<br>" . $e->getMessage();
  } catch (Exception $e) {
    echo "General Error: The user could not be added.<br>" . $e->getMessage();
  }  
}

}

/* Displays error message /
function error($message, $code = 500) {
/
Set response code so javascript understands this is not a 200 OK
see: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes */
//http_response_code($code);

output($message, [], ‘error’);
}

/* Output data in correct format */
function output($message = ‘’, $data = [], $status = ‘success’) {
echo json_encode([
‘status’ => $status,
‘data’ => $data,
‘message’ => $message
]);
}[/php]

the strange things is when I comment out the http_response_code($code) it works and when I don’t i get url 400 Bad Request in the JavaScript console.

Here’s the js file:
[php]$(function() {
$("#register").submit(function(event) {
event.preventDefault(); // Prevent submit button from firing:
console.log($(this).serialize());
$.post(“ajax.php?action=save”, $(this).serialize())
.done(function() {
$("#register input[type=‘text’], #register input[type=‘password’]").each(function() {
$(this).val(’’);
});
}).always(function(response) {
console.log(response);
$(".result").text(response.message).html();
});

});

}); // END OF DOCUMENT READY FUNCTION:
[/php]

I’ve done google searches, but to no avail.

Open up the developer console / inspector in your browser, fire off a request (should show up in the console or network tab depending on which browser it is), then highlight it and see if the request data (params), and the response look alright. You should get the error message from the server side in the response so should be possible to figure out where it goes wrong there.

Btw. in your php file you currently echo out two error messages, it’s better to use the error function that outputs json data so JS understands it :slight_smile:

OK, I turn the echo into error functions and this is what I get in the console window in Chrome:

POST http://localhost/registration_demo/ajax.php?action=save 400 (Bad Request) when I don’t comment this

[php]/* Displays error message /
function error($message, $code = 500) {
/
Set response code so javascript understands this is not a 200 OK
see: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes */

http_response_code($code); // Not Commented out:

output($message, [], ‘Error’);
}[/php]

It’s looks like JavaScript is freaking out when username and/or password isn’t set, for it works when I go save it. An it spits out the error message when I comment //http_response_code($code); out. Very Strange.

BTW - Thanks for helping me.

it recognizes it, for when I do a console.log(response); in js, I see this in the console window:

responseText: “{“status”:“Error”,“data”:[],“message”:“Missing param(s)”}”

You don’t need to console.log it, just look at what you get as a response to the request.

[hr]

This is the only code you have throwing that error:

[php] function save() [
if (!isset($_POST[‘username’]) || !isset($_POST[‘password’])) {
error(‘Missing param(s)’, 400);
}
…[/php]

So you probably aren’t sending the form fields properly.

[hr]

If you have the complete code (github?) I can try it and see what’s wrong

Unfortunately I don’t have it on Github, for some strange reason I can never figure out github. I must be too old for this…joking. :slight_smile: it is show up in the Network as 400 Bad Request but in Red…Hmmm. My form looks OK? As a matter of fact I did it the way you said to. Hmmm…I’ll take a break for awhile, maybe a lightbulb will click on.

I got it to work. Well I got kind of of a work around for it, but I’m sure I can optimize it some more.

[php]$(function() {
$("#register").submit(function(event) {
event.preventDefault(); // Prevent submit button from firing:
console.log($(this).serialize());
$.post(“ajax.php?action=save”, $(this).serialize())
.done(function() {
$("#register input[type=‘text’], #register input[type=‘password’]").each(function() {
$(this).val(’’);
});
}).fail(function(xhr, textStatus, errorThrown){
console.log(xhr.status, textStatus, errorThrown);
var myResponse = JSON.parse(xhr.responseText);
console.log(‘myResponse.message’, myResponse.message);

    console.log("xhr.responseText",xhr.responseText, 'textStatus', textStatus, 'errorThrown', errorThrown);
    $(".result").text(errorThrown + " Message " + myResponse.message);
  }).always(function(response) {
    console.log("response", response);
    if (response.status === 'Success') {
      $(".result").text("Status " + response.status + ' Message ' + response.message);
    }
  });

});

}); // END OF DOCUMENT READY FUNCTION:
[/php]

Yeah. The reason we set the content type was so JS would parse it automatically. If you want to then zip up the files (with a db dump) and I can try to have a look :slight_smile:

Thanks for the offer to help, but I believe I got it to work (the code isn’t shown here) correctly and it works pretty darn good. I will be posting it once I get polished and I agree getting the JS to parse is a life saver…well at least a tad bit easier than doing it the other way around. A lot less confusing. I aslo took out the error codes all together and just used the validation if it was good or not. Made it a lot easier. success - passes validation / error - fails validation.

Example of what I’m talking about:

[php] /* Call the function that checks to see if username is unique */
$result = checkForDupicates($pdo, $data[‘username’]);

/* If result is true, then spit out error stating username is unavailable */
if ($result) {
return json_encode([‘type’ => ‘error’, ‘text’ => ‘Username is unavailable, please try again!’]);
}[/php]

Then in my jQuery:
[php] /* Load json data from server and output appropiate message */
if(response.type === ‘error’) {
$password.val(’’);
$verify.val(’’);
$status.css({
‘background-color’ : ‘red’
});
output = response.text; // Display the error message:
$status.animate({width: ‘toggle’}, 350); // Slide the error/success container div down:
displayTimer(12);
} else { // Display to screen if it is successful:
$status.css({
‘background-color’ : ‘green’
});
$(’#register input[type=“text”], #register input[type=“password”]’).each(function() {
$(this).val(’’); // Clear input fields:
});
$username.focus(); // Set Focus on first input tag:
output = response.text; // Grab the success message from php:
$status.slideDown(500);
displayTimer(6); // Call Timer and only display it for so many seconds:
}
$message.text(output); // Set the text in the p tag with the result class:

  [/php]

A good step in the right direction then (y)

I would still recommend you iron out the status code stuff, atm you seem to return a “200 OK” and instead rely on a returned param (type) to check if the request was successful or not. If you get status codes working (as in my example) you return 200 OK only if the request was ok, and something else if not. Jquery understands these codes and executes the correct callback, making the code a bit more structured and better to read.

[php]$.post( “ajax.php?action=validateUnique”, $(this).serialize() )
.done(function() {
/* Do this if we get a 200 OK response /
field.removeClass(‘invalid’);
field.addClass(‘valid’);
})
.fail(function() {
/
Do this if we get any error */
field.removeClass(‘valid’);
field.addClass(‘invalid’);
})
.always(function(response) {
$( “#result” ).text("Performed unique check: " + response.message).html();
});[/php]

I got the status code to work, what drives me crazy is jQuery spitting an error code highlighted in red. Maybe I’m being nit picky about it.

Where? Into the page? If it’s the request in the console then it’s supposed to be red if it failed, it’s easy to pick up on (y). If it shows like it was successful its kinda counter intuitive.

I’m still getting a response back no matter what, I think if I ever redo my trivia game I would use error codes. However for just simple validation this will work:

An I know where the response is going to in JQuery:
[php] var myData = {
‘action’ : ‘save’,
‘username’ : $username.val(),
‘password’ : $password.val(),
‘verify’ : $verify.val(),
‘firstName’ : $firstName.val(),
‘lastName’ : $lastName.val(),
‘emailAddress’ : $emailAddress.val()
};

$.post('ajax.02.php', myData, function(response) {
   
  /* Load json data from server and output appropiate message */
  if(response.type === 'error') {
    $password.val('');
    $verify.val('');
    $status.css({
      'background-color' : 'red'
    });
    output = response.text; // Display the error message:
    $status.animate({width: 'toggle'}, 350); // Slide the error/success container div down:
    displayTimer(12);
  } else { // Display to screen if successful:
    $status.css({
      'background-color' : 'green'
    });
    $('#register input[type="text"], #register input[type="password"]').each(function() {
      $(this).val(''); // Clear input fields:
    });        
    $username.focus(); // Set Focus on first input tag:        
    output = response.text; // Grab the success message from php:
    $status.slideDown(500);
    displayTimer(6); // Call Timer and only display it for so many seconds:
  }
  $message.text(output); // Set the text in the p tag with the result class:
  
  
}); // End of Post Data to Server Function:[/php]

The red bothers me for the simple fact that if there is something wrong elsewhere in the javascript (JQuery) the first thing I do is look at the console and go “Oh know an error just halted my script”. Like I said I’m being nit picky. To me it should have been may a yellow or dark yellowish or maybe a different color meaning “Yeah, it’s an error but a control error”. Though I might use error codes with checking single inputting of input tags…hmmmm :-\ Me Dr. Jekyll and Mr. Hyde. :smiley:

The more I look at the code the more I think it would be easy just to throw the errors codes in…OK I’m going crazy. :-\

Sponsor our Newsletter | Privacy Policy | Terms of Service