I wanted to post this online because I have been searching for days on this JQuery Remote validation issue. I cannot get it to work. I think my PHP code is correct as I have test the URL with a query in the URL and it returns false and true depending on with the recordset count is one or more
This is my Jquery Validate Code:
// validate form and submit
var $j = jQuery.noConflict();
$j(document).ready(function(){
$j("#myform").validate({
rules: {
ord_ref: {
required: true,
minlength: 12,
remote: "check_ord_ref.php"
},
messages: {
ord_ref: {
remote: "Order Number Does Not Exist"
}
}
}
});
});
This is my PHP code for the remote page "check_ord_ref.php"
$colname_rscheck_ord_ref = "-1";
if (isset($_GET['ord_ref'])) {
$colname_rscheck_ord_ref = (get_magic_quotes_gpc()) ? $_GET['ord_ref'] : addslashes($_GET['ord_ref']);
}
mysql_select_db($database_conn, $conn);
$query_rscheck_ord_ref = sprintf("SELECT ref_ord FROM orders WHERE ref_ord = '%s'", $colname_rscheck_ord_ref);
$rscheck_ord_ref = mysql_query($query_rscheck_ord_ref, $conn) or die(mysql_error());
$row_rscheck_ord_ref = mysql_fetch_assoc($rscheck_ord_ref);
$totalRows_rscheck_ord_ref = mysql_num_rows($rscheck_ord_ref);
if($totalRows_rscheck_ord_ref < 0){
$valid = 'false';
} else {
$valid = 'true';
}
echo $valid;
Please someone can you help solve the puzzle for myself and anyone else having issues
Using JQuery 1.5.2min
Validates OK without remote function
Ok, so I'm no PHP expert, but I do know that jQuery Validate expects the following result from a remote validation method:
The response is evaluated as JSON and must be true for valid elements,
and can be any false, undefined or null for invalid elements
Sending down "true" or "false" (note the quotation marks) is going to result in the value being parsed as the error message instead of being evaluated as a boolean primitive.
Back to the PHP part, I think you should probably use json_encode with a boolean primitive. I'm not quite sure the way to do this in PHP, but I believe it would be something like this:
$colname_rscheck_ord_ref = "-1";
if (isset($_GET['ord_ref'])) {
$colname_rscheck_ord_ref = (get_magic_quotes_gpc()) ? $_GET['ord_ref'] : addslashes($_GET['ord_ref']);
}
mysql_select_db($database_conn, $conn);
$query_rscheck_ord_ref = sprintf("SELECT ref_ord FROM orders WHERE ref_ord = '%s'", $colname_rscheck_ord_ref);
$rscheck_ord_ref = mysql_query($query_rscheck_ord_ref, $conn) or die(mysql_error());
$row_rscheck_ord_ref = mysql_fetch_assoc($rscheck_ord_ref);
$totalRows_rscheck_ord_ref = mysql_num_rows($rscheck_ord_ref);
if($totalRows_rscheck_ord_ref < 0){
$valid = false; // <-- Note the use of a boolean primitive.
} else {
$valid = true;
}
echo json_encode($valid);
This problem seems to be plaguing remote validation scripters and the jQuery documentation on the matter is clearly lacking.
I notice you are using jQuery 1.5.2: from what I understand (and found from experience) you must use the jQuery callback that is sent to the remote script with $_REQUEST with versions after 1.4, AND jQuery is expecting "true" or "false" as a STRING. Here is an example, confirmed working on multiple forms (I'm using jQuery 1.7.1):
if($totalRows_rscheck_ord_ref < 0){
header('Content-type: application/json');
$valid = 'false'; // <---yes, Validate is expecting a string
$result = $_REQUEST['callback'].'('.$check.')';
echo $result;
} else {
header('Content-type: application/json');
$valid = 'true'; // <---yes, Validate is expecting a string
$result = $_REQUEST['callback'].'('.$check.')';
echo $result;
}
I found this answer here (in the answers section), randomly, and have since stopped pulling out my hair. Hope this helps someone.
To add to Andrew Whitaker's response above, I must stress that you are sure that the response is strictly JSON and that there are no other content types being returned. I was having the same issue with my script, and everything appeared to be set properly - including using json_encode(). After some troubleshooting with Firebug's NET tab, I was able to determine that PHP notices were being sent back to the browser converting the data from JSON to text/html. After I turned the errors off, all was well.
//check_validate.php
<?php
// some logic here
echo json_encode(true);
?>
Related
I have a page that makes an Ajax call, which retrieves, JSON encodes and returns data from a database. The page was working, but in the midst of making some changes, it's now failing. (Should note that I'm working with a test site and test database as I make the changes.)
The errorThrown parameter of the error case shows me "SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data."
Here's the function with the Ajax call. (I've enhanced what's in the alerts for debugging purposes. I'll rip that back out once things are working.)
function acceptConfCode(){
var emailAddr = $('#email').val();
var confCode = $('#confcode').val();
var fnargs = "ConfirmCode|'" + emailAddr + "'," + confCode ;
$.ajax({
url: 'retrievedata.php',
type: "POST",
async: true,
data: {"functionname":"confirmcode","arguments":fnargs},
dataType: "JSON",
success: function (obj) {
if (!obj.error) {
$('#logininfo').hide();
$('#emailrow').hide();
$('#coderow').hide();
$('#reviewactions').show();
updateListOfActions(obj);
}
else {
success = false;
alert("The confirmation code you entered didn't match or has expired. Please try again. Type 1");
}
},
error: function(xhr, textStatus, errorThrown) {
success = false;
alert("The confirmation code you entered didn't match or has expired. Please try again. Type 2. textStatus = " + textStatus + "; errorThrown = " + errorThrown);
}
});
};
The retrievedata PHP page is mostly a CASE statement. The relevant case is this (again with added debugging code):
case 'confirmcode':
if ($argcount <2) {
$returnval = 'too few arguments';
}
else {
$returnval = confirmcode($argsarray[0], $argsarray[1]);
echo "Back from confirmcode\r\n";
var_dump($returnval);
}
break;
At the end of the page, it returns $returnval.
The key action is in the confirmcode function, which runs a MySQL SP to confirm that the user has a valid email and code, and then calls another function to retrieve the actual data. Here's confirmcode. As the commented out pieces show, I've checked results along the way and I am getting what I expect and it's getting JSON encoded; I've ran the encoded JSON back through JSON_decode() in testing to confirm it was decodable.
function confirmcode($spname, $params, $errorstring = 'Unable to send requested data') {
$conn = connect2db();
$query = "SELECT ".$spname."(".$params.") as result";
//echo $query."\r\n";
$result = mysqli_query($conn, $query);
$allresult = "unknown";
if (!$result) {
$errmessage = mysqli_error($conn);
$allresult = $errmessage;
$allresult = json_encode($allresult);
//echo $errmessage;
die( print_r( mysql_error(), true));
}
else {
//echo "In else case\r\n";
//retrieve list of action submissions
$resultobj = mysqli_fetch_object($result);
if ($resultobj->result == 1) {
//echo "In success subcase\r\n";
$allresult = getsubmissions($conn);
//echo "After getsubmissions\r\n";
//print_r($allresult);
}
else {
//echo "In failure subcase\r\n";
$result = array('error'=>true);
$allresult = $result;
}
//echo "Before JSON encode\r\n";
$finalresult = json_encode($allresult);
//echo "After JSON encode\r\n";
//echo json_last_error_msg()."\r\n";
//var_dump($finalresult);
$allresult = $finalresult;
return $allresult;
}
}
Finally, here's getsubmissions, again with some debugging code:
function getsubmissions($conn) {
echo "In getsubmissions\r\n";
$query = "CALL GetSubmissions()";
$submissions = mysqli_query($conn, $query);
if (!$submissions) {
echo "In failure case\r\n";
$errmessage = mysqli_error($conn);
$allresult = $errmessage;
$allresult = json_encode($allresult);
echo $errmessage;
die( print_r( mysql_error(), true));
}
else {
echo "In success case\r\n";
$rows = array();
while ($row = mysqli_fetch_assoc($submissions)) {
$rows[] = $row;
}
$allresult = $rows; //json_encode($rows);
}
//print_r( $allresult);
return $allresult;
}
What's really weird is I have another page in the site that retrieves almost exactly the same data through an Ajax call with no problem. The one that works contains a few additional fields, and doesn't contain two date fields that are in this result.
In addition, the live version of the site retrieves exactly the same data as here, except from the live database rather than the test database, and it works. While this version of the code has some additional things in it, the only differences in the relevant portions are the debugging items. (That is, I've made changes, but not in the part I'm showing here.) That leads me to think this may be an issue with the test data rather than with the code, but then why does the other page work in the test site?
UPDATE: To try to see whether this is a data problem, I cut the test data way down so that it's only returning a couple of records. I grabbed the generated JSON and ran it through JSONLint.COM and it says it's valid.
UPDATE 2: With the reduced data set, here's the string that's returned from retrievedata.php to the Ajax call:
[{"ActionSource":"https:\/\/www.voterheads.com\/","ActionSourceName":"Wall-of-us","Title":"Sign up to get notified about local meetings","Description":"Sign up at www.voterheads.com to get notified about local meetings. When we did, using the free option, this is what happened: a page popped up with a list of municipality meetings in the zip code we entered. We clicked on one of the meetings, and presto! -- instant access to the date, time, location, and agenda of the meeting. Pretty awesome.","StartDate":null,"EndDate":null,"UrgencyDesc":"Anytime","UrgencyColor":"#00FF00","UrgOrder":"5","DurationDesc":"Ongoing","DurOrder":"6","CostDesc":"Free","CostOrder":"1","Issues":"Advocacy","Types":"Learn","States":"ALL","iID":"20"},{"ActionSource":"https:\/\/actionnetwork.org\/forms\/ctrl-alt-right-delete-newsletter-2","ActionSourceName":"Ctrl Alt Right Delete","Title":"Sign up to learn what the \"alt-right\" is up to","Description":"Understand how the right operates online. Sign up for a weekly newsletter.","StartDate":null,"EndDate":null,"UrgencyDesc":"Anytime","UrgencyColor":"#00FF00","UrgOrder":"5","DurationDesc":"An hour or less","DurOrder":"2","CostDesc":"Free","CostOrder":"1","Issues":"Advocacy","Types":"Learn","States":"ALL","iID":"25"}]
As noted above, JSONLint.COM says it's valid JSON.
I've found a solution, though I'm just starting to understand why it works. On retrievedata.php, I uncommented:
echo $returnval;
just before the Return statement and it's working again. So I think the issue is that since retrievedata is a page, but not a function, the return statement didn't actually return anything. I needed code to actually return the JSON-encoded string.
I want to validate if username exists in database using jQuery.validate so here's what I have so far:
jQuery:
$("#signupForm").validate({
rules: {
username: {
required: true,
minlength: 3,
remote: "check-username.php"
}
},
messages: {
username:{
remote: "This username is already taken! Try another."
}
}
});
check-username.php:
<?php
require_once "./source/includes/data.php";
header('Content-type: application/json');
$name = mysql_real_escape_string($_POST['username']);
$check_for_username = mysql_query("SELECT username FROM mmh_user_info WHERE username='$name'");
if (mysql_num_rows($check_for_username) > 0) {
$output = true;
} else {
$output = false;
}
echo json_encode($output);
?>
This code always shows an error that the username is taken even if it's not.
I'm using jQuery Mobile 1.9.1
Thanks in advance.
I've managed to get this to work by changing the PHP technique I was using, here's my PHP:
<?php
require_once "./source/includes/data.php";
header('Content-type: application/json');
$request = $_REQUEST['username'];
$query = mysql_query("SELECT * FROM mmh_user_info WHERE username ='$username'");
$result = mysql_num_rows($query);
if ($result == 0){
$valid = 'true';}
else{
$valid = 'false';
}
echo $valid;
?>
Thanks everyone here for your help :)
I have two resources for to look at.
Official example from the validate plugin:
http://jquery.bassistance.de/validate/demo/milk/
jQuery forum solution:
http://forum.jquery.com/topic/jquery-validation-plugin-remote-validation-problem-locks-up
The possible solution is that the response does not need to be json encoded as far as I can tell. Since json needs key value pairs, suppling just the value won't work. So try to just echo it out as 'true' or 'false' strings.
Second, the validate uses GET for the form submission method, not POST.
NOTE: JUST FOUND POSSIBLE SOLUTION QUESTION
jQuery Remote validation
I have successfully implemented the Jquery Validation Plugin http://posabsolute.github.com/jQuery-Validation-Engine/ but i am now trying to get an ajax database email check to work (email exists / email available) and i have written some php script to get this done. Its kinda working but i am getting the most unexpected heretically odd behavior from my IF ELSE statement (seems really crazy to me). observe ### marked comments
PHP code: LOOK AT THE IF ELSE STATEMENT
/* RECEIVE VALUE */
$validateValue = $_REQUEST['fieldValue'];
$validateId = $_REQUEST['fieldId'];
$validateError = "This username is already taken";
$validateSuccess = "This username is available";
/* RETURN VALUE */
$arrayToJs = array();
$arrayToJs[0] = $validateId;
$req = "SELECT Email
FROM business
WHERE Email = '$validateValue'";
$query = mysql_query($req);
while ($row = mysql_fetch_array($query)) {
$results = array($row['Email']);
}
if (in_array($validateValue, $results)) {
$arrayToJs[1] = false;
echo json_encode($arrayToJs); // RETURN ARRAY WITH ERROR ### popup shows "validating, please wait" then "This username is already taken" when email typed is in database - i.e. Working
file_put_contents('output.txt', print_r("1 in array - Email is Taken " . $validateValue, true)); ### this runs!!
}else{
$arrayToJs[1] = true; // RETURN TRUE
echo json_encode($arrayToJs); // RETURN ARRAY WITH success ### popup shows "validating, please wait" when email typed is NOT in the database - i.e. not Working
file_put_contents('output.txt', print_r("2 else - Email is available " . $validateValue, true));
//### THIS RUNS TOO !!!!!!!!!!!!! i.e. echo json_encode($arrayToJs) wont work for both.. If I change (in_array()) to (!in_array()) i get the reverse when email is in database.
//i.e. only the else statements echo json_encode($arrayToJs) runs and the popup msg shows up green "This username is available" crazy right???
//so basically IF ELSE statements run as expected (confirmed by output.txt) but only one echo json_encode($arrayToJs) will work.!!!!
//If i remove the json_encode($arrayToJs) statements and place it once after the IF ELSE statement i get the same problem.
//both $arrayToJs[1] = false; and $arrayToJs[1] = true; can work separately depending on which is first run IF or ELSE but they will not work in the one after another;
}
HERE IS THE REST OF THE CODE-->
1-HTML FORM INPUT CODE:
<tr>
<td> <Label>Business Email</Label>
<br>
<input type="text" name="Email" id="Email" class="validate[required,custom[email],ajax[ajaxUserCallPhp]] text-input">
</td>
</tr>
2-Relevant JQUERY code in jquery.validationEngine.js:
$.ajax({
type: type,
url: url,
cache: false,
dataType: dataType,
data: data,
form: form,
methods: methods,
options: options,
beforeSend: function() {
return options.onBeforeAjaxFormValidation(form, options);
},
error: function(data, transport) {
methods._ajaxError(data, transport);
},
success: function(json) {
if ((dataType == "json") && (json !== true)) {
// getting to this case doesn't necessary means that the form is invalid
// the server may return green or closing prompt actions
// this flag helps figuring it out
var errorInForm=false;
for (var i = 0; i < json.length; i++) {
var value = json[i];
var errorFieldId = value[0];
var errorField = $($("#" + errorFieldId)[0]);
// make sure we found the element
if (errorField.length == 1) {
// promptText or selector
var msg = value[2];
// if the field is valid
if (value[1] == true) {
if (msg == "" || !msg){
// if for some reason, status==true and error="", just close the prompt
methods._closePrompt(errorField);
} else {
// the field is valid, but we are displaying a green prompt
if (options.allrules[msg]) {
var txt = options.allrules[msg].alertTextOk;
if (txt)
msg = txt;
}
if (options.showPrompts) methods._showPrompt(errorField, msg, "pass", false, options, true);
}
} else {
// the field is invalid, show the red error prompt
errorInForm|=true;
if (options.allrules[msg]) {
var txt = options.allrules[msg].alertText;
if (txt)
msg = txt;
}
if(options.showPrompts) methods._showPrompt(errorField, msg, "", false, options, true);
}
}
}
options.onAjaxFormComplete(!errorInForm, form, json, options);
} else
options.onAjaxFormComplete(true, form, json, options);
}
});
3-Relevent code for ajaxUserCallPhp in jquery.validationEngine-en.js:
"ajaxUserCallPhp": {
"url": "validation/php/ajaxValidateFieldUser.php",
// you may want to pass extra data on the ajax call
"extraData": "name=eric",
// if you provide an "alertTextOk", it will show as a green prompt when the field validates
"alertTextOk": "* This username is available",
"alertText": "* This user is already taken",
"alertTextLoad": "*Validating, please wait"
},
Im sure the problem lies with this echo.
echo json_encode($arrayToJs)
Please help i've spent to long on this and its almost working fully.
To clarify - I basically am trying to code it so that if i type an email in the db it shows red "This username is taken" then if i edit the input box to an email not in the database it changes to green "username is available" at the moment only one json_encode will run in any scenario no matter how i change the if else statement –
Thank you very much in advance.
Ok got it finally after a fiddle. I found that json_encode() returns false when any error or warning is posted. using the php error log file in xampp/php/logs/error_logs file i realised that i was getting an error only when the query result was null making $results = null. this caused an output error preventing json_encode() from echoing true, which is why i only got one response.
To fix it i made sure that the $result array was not empty by using the following code after the query to array part.
if(empty($results)){
$results [0]= ("obujasdcb8374db");
}
The whole code is now
$req = "SELECT Email
FROM business
WHERE Email = '$validateValue'";
$query = mysql_query($req);
while ($row = mysql_fetch_array($query)) {
$results[] = $row['Email'];
}
if(empty($results)){
$results [0]= ("obujasdcb8374db");
}
if (in_array($validateValue, $results)) {
$arrayToJs[1] = 0;
echo json_encode($arrayToJs); // RETURN ARRAY WITH ERROR
} else {
$arrayToJs[1] = 1; // RETURN TRUE
echo json_encode($arrayToJs); // RETURN ARRAY WITH success
}
I was able to change ajax url for ajaxusercallphp, ajaxnamecallphp without modifying the languge file... You need to search for this line inside jaquery.validateEngine.js
Find : _ajax:function(field,rules,I,options)
Then scroll down to the ajax request .ie $.ajax
And change url:rule.url to options.ajaxCallPhpUrl
Then all you have to do is include the url as an option like this:
JQuery("#formid").validateEngine('attach', {ajaCallPhpUrl : "yoururl goes here", onValidationComplete:function(form,status){
})
I was able to change ajax url for ajaxusercallphp, ajaxnamecallphp without modifying the languge file... You need to search for this line inside jaquery.validateEngine.js
Find : _ajax:function(field,rules,I,options)
Then scroll down to the ajax request .ie $.ajax
And change url:rule.url to options.ajaxCallPhpUrl
Then all you have to do is include the url as an option like this:
JQuery("#formid").validateEngine('attach', {ajaCallPhpUrl : "yoururl goes here", onValidationComplete:function(form,status){
})
How can I add a check in the PHP for the length of the $username passed. The site is UTF-8 but I believe Javascript is using a different encoding. You can see in the comments where I tried different things in the PHP and they don't work.
What I tried and didn't work:
Changing Ajax (javascript) to pass variables by UTF-8 and not javascript encoding
strlen, mb_strlen in the PHP - both return incorrect values
MORE INFO
My Ajax sends a username to my PHP, which checks the SQL DB and returns available or not. I decided to try and do some extra checking in the PHP before checking the DB (like mb_strlen($username). mb_internal_encoding("UTF-8"); is also set.
I was going to try and send the Ajax request in UTF-8 but didnt see a way to do that.
is UPPER being used correctly in the MySQL? - for UTF-8 stuff?
PHP BELOW ***********
// Only checks for the username being valid or not and returns 'taken' or 'available'
require_once('../defines/mainDefines.php'); // Connection variables
require_once('commonMethods.php');
require_once('sessionInit.php'); // start session, check for HTTP redid to HHHTPs
sleep(2); // Looks cool watching the spinner
$username = $_POST['username'];
//if (mb_strlen($username) < MIN_USERNAME_SIZE) echo 'invalid_too_short';
//if (mb_strlen($username, 'UTF-8') < 10) { echo ('invalid_too_short'); exit; }
//die ('!1!' . $username . '!2!' . mb_strlen($username) . '!3!' . strlen($username) . '!4!');
$dbc = mysqli_connect(DB_HOST, DB_READER, DB_READER_PASSWORD, DB_NAME) or die(DB_CONNECT_ERROR . DB_HOST . '--QueryDB--checkName.php');
$stmt = mysqli_stmt_init($dbc);
$query = "SELECT username FROM pcsuser WHERE UPPER(username) = UPPER(?)";
if (!mysqli_stmt_prepare($stmt, $query)) {
die('SEL:mysqli_prepare failed somehow:' . $query . '--QueryDB--checkName.php');
}
if (!mysqli_stmt_bind_param($stmt, 's', $username)) {
die('mysqli_stmt_bind_param failed somehow --checkName.php');
}
if (!mysqli_stmt_execute($stmt)) {
die('mysqli_stmt_execute failed somehow' . '--checkName.php');
}
mysqli_stmt_store_result($stmt);
$num_rows = mysqli_stmt_num_rows($stmt);
mysqli_stmt_bind_result($stmt, $row);
echo ($num_rows >= 1) ? 'taken' : 'available';
mysqli_stmt_close($stmt);
mysqli_close($dbc);
AJAX CODE BELOW
function CheckUsername(sNameToCheck) {
document.getElementById("field_username").className = "validated";
registerRequest = CreateRequest();
if (registerRequest === null)
alert("Unable to create AJAX request");
else {
var url= "https://www.perrycs.com/php/checkName.php";
var requestData = "username=" + escape(sNameToCheck); // data to send
registerRequest.onreadystatechange = ShowUsernameStatus;
registerRequest.open("POST", url, true);
registerRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
registerRequest.send(requestData);
}
}
function ShowUsernameStatus() {
var img_sad = "graphics/signup/smiley-sad006.gif";
var img_smile = "graphics/signup/smiley-happy088.gif";
var img_checking = "graphics/signup/bluespinner.gif";
if (request.readyState === 4) {
if (request.status === 200) {
var txtUsername = document.getElementById('txt_username');
var fieldUsername = document.getElementById('field_username');
var imgUsername = document.getElementById('img_username');
var error = true;
var response = request.responseText;
switch (response) {
case "available":
txtUsername.innerHTML = "NAME AVAILABLE!";
error = false;
break;
case "taken":
txtUsername.innerHTML = "NAME TAKEN!";
break;
case "invalid_too_short":
txtUsername.innerHTML = "TOO SHORT!";
break;
default:
txtUsername.innerHTML = "AJAX ERROR!";
break;
} // matches switch
if (error) {
imgUsername.src = img_sad;
fieldUsername.className = 'error';
} else {
imgUsername.src = img_smile;
fieldUsername.className = 'validated';
}
} // matches ===200
} // matches ===4
}
TESTING RESULTS
This is what I get back when I DIE in the PHP and echo out as in the following (before and after making the Ajax change below [adding in UTF-8 to the request]...
PHP SNIPPIT
die ('!1!' . $username . '!2!' . mb_strlen($username) . '!3!' . strlen($username) . '!4!');
TEST DATA
Username: David Perry
!1!David Perry!2!11!3!11!4!
Username: ܦ"~÷Û♦
!1!ܦ\"~��%u2666!2!9!3!13!4!
The first one works. The second one should work but it looks like the encoding is weird (understandable).
7 visible characters for the 2nd one. mb_strlen shows 9, strlen shows 13.
After reading Joeri Sebrechts solution and link they gave me I looked up Ajax request parameters and someone had the following...
AJAX SNIPPIT (changed from original code)
registerRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
(I added in the charset=UTF-8 from an example I saw on a article).
UPDATE: Nov 27, 9:11pm EST
Ok, after much reading I believe I am encoding my JS wrong. I was using escape... as follows...
var requestData = "username=" + escape(sNameToCheck);
After looking at this website...
http://www.the-art-of-web.com/javascript/escape/
it helped me understand more of what's going on with each function and how they encode and decode. I should be able to do this...
var requestData = "username=" + encodeURIComponent(sNameToCheck);
in JS and in PHP I should be able to do this...
$username = rawurldecode($_POST['username']);
Doing that still gives me 8 characters for my weird example above instead of 7. It's close, but am I doing something wrong? If I cursor through the text on the screen it's 7 characters. Any ideas to help me understand this better?
FIXED/SOLVED!!!
Ok, thank you for your tips that lead me in the right direction to make this work. My changes were as follows.
In the AJAX -- i used to have escape(sNameToCheck); --
var requestData = "username=" + encodeURIComponent(sNameToCheck);
In the PHP *-- I used to have $username = $_POST['username']; --*
$username = rawurldecode($_POST['username']);
if (get_magic_quotes_gpc()) $username = stripslashes($username);
I really hate magic_quotes... it's caused me about 50+ hours of frustration over form data in total because I forgot about it. As long as it works. I'm happy!
So, now the mb_strlen works and I can easily add this back in...
if (mb_strlen($username) < MIN_USERNAME_SIZE) { echo 'invalid_too_short'; exit; }
Works great!
PHP is a byte processor, it is not charset-aware. That has a number of tricky consequences.
Strlen() returns the length in bytes, not the length in characters. This is because php's "string" type is actually an array of bytes. Utf8 uses more than one byte per character for the 'special characters'. Therefore strlen() will only give you the right answer for a narrow subset of text (= plain english text).
Mb_strlen() treats the string as actual characters, but assumes it's in the encoding specified via mbstring.internal_encoding, because the string itself is just an array of bytes and does not have metadata specifying its character set. If you are working with utf8 data and set internal_encoding to utf8 it will give you the right answer. If your data is not utf8 it will give you the wrong answer.
Mysql will receive a stream of bytes from php, and will parse it based on the database session's character set, which you set via the SET NAMES directive. Everytime you connect to the database you must inform it what encoding your php strings are in.
The browser receives a stream of bytes from php, and will parse it based on the content-type charset http header, which you control via php.ini default_charset. The ajax call will submit in the same encoding as the page it runs from.
Summarized, you can find advice on the following page on how to ensure all your data is treated as utf8. Follow it and your problem should resolve itself.
http://malevolent.com/weblog/archive/2007/03/12/unicode-utf8-php-mysql/
From a quick glance, you can clean this up:
if (request.status == 200) {
if (request.responseText == "available") {
document.getElementById("txt_username").innerHTML = "NAME AVAILABLE!";
document.images['img_username'].src=img_smile;
document.getElementById("continue").disabled = false;
document.getElementById("field_username").className = 'validated';
} else if (request.responseText == "taken") {
document.getElementById("txt_username").innerHTML = "NAME TAKEN!";
document.images['img_username'].src=img_sad;
document.getElementById("field_username").className = 'error';
} else if (request.responseText == "invalid_too_short") {
document.getElementById("txt_username").innerHTML = "TOO SHORT!";
document.images['img_username'].src=img_sad;
document.getElementById("field_username").className = 'error';
} else {
document.getElementById("txt_username").innerHTML = "AJAX ERROR!";
document.images['img_username'].src=img_sad;
document.getElementById("field_username").className = 'error';
}
}
to:
// I prefer triple equals
// Read more at http://javascript.crockford.com/style2.html
if (request.status === 200) {
// use variables!
var txtUsername = document.getElementById('txt_username');
var fieldUsername = document.getElementById('field_username');
var imgUsername = document.getElementById('img_username');
var response = request.responseText;
var error = true;
// you can do a switch statement here too, if you prefer
if (response === "available") {
txtUsername.innerHTML = "NAME AVAILABLE!";
document.getElementById("continue").disabled = false;
error = false;
} else if (response === "taken") {
txtUsername.innerHTML = "NAME TAKEN!";
} else if (response === "invalid_too_short") {
txtUsername.innerHTML = "TOO SHORT!";
} else {
txtUsername.innerHTML = "AJAX ERROR!";
}
// refactor error actions
if (error) {
imgUsername.src = img_sad;
fieldUsername.className = 'error';
} else {
imgUsername.src = img_smile;
fieldUsername.className = 'validated';
}
}
The code below calls a PHP file for a true or false text result using the dojo.xhrGet method. When I load the PHP file by itself (replacing the $variable = $_GET("passedVariable"); with a hard-wired value), it correctly generates a "true" or "false" in my browser window. However, when I run the call in my larger web app, it returns the PHP source code instead of the results of my database query. Using JQuery's .get() method, I receive a XML object.
Here's the Javascript...
dojo.xhrGet({
url: "php/check.php",
handleAs: "text",
content: {guid: featureGuid},
load: function(response){
alert(response);
dojo.style(dojo.byId("photoLink"), "display", "");
}
});
Here's the PHP...
<?php
$guid = $_GET["guid"];
// Connect to Database
$server = "server";
$connectionSettings = array("Database"=>"db", "UID"=>"uid", "PWD"=>"pwd");
$connection = sqlsrv_connect($server, $connectionSettings);
if (!$connection){
die("Failed Connection");
}
// Prepare and Execute query
$sql = "sql";
$results = sqlsrv_query($connection, $sql);
if ($results){
$rows = sqlsrv_has_rows( $results );
if ($rows === true) {
header('Content-Type: text/plain');
echo "true";
}
else {
header('Content-Type: text/plain');
echo "false";
}
}
else{
header('Content-Type: text/plain');
echo "false";
}?>
Anything anybody see wrong with this?
Thanks.
I'd check the requests and responses using Firebug - check that the URLs and headers are the same when you call the URL directly from the browser as opposed to via the XHR.
I am not sure but:
Try making sure that your Main App is executing PHP properly, it seems odd that JavaScript can pull the source code.
Try adding: die() after echo true or echo false which will prevent it from going any further.
The reason I say to check the larger app for PHP execution is because it almost seems like the webserver is rendering the source code as html and not running it through the interpreter.