May 17, 2013

jQuery.post not receiving errors from php script

Preahkumpii’s Question:

I know this has been asked before and I have looked at every post I could find that deals with this. I still cannot get the jQuery.post function to correctly receive the error from a php script. Here are both.

PHP:

<?php 
##CONFIGURATION
# LIST EMAIL ADDRESS
$toemail = "email here";

# SUBJECT (Subscribe/Remove)
$subject = "Someone has contacted International Designs";

# RESULT PAGE
$location = "../thank-you.php";

## FORM VALUES ##
$myname = $_REQUEST['myname'];
$myemail = $_REQUEST['myemail'];
$mymessage = $_REQUEST['mymessage'];

if ( empty($myname) || empty($myemail) || empty($mymessage) ) {

    exit('{"error":"That value was invalid!"}')

} else {

    # SENDER
    $email = $myname . " <" . $myemail . ">";

    # MAIL BODY
    $body .= "Name: " . $myname . " nn";
    $body .= "Email: " . $myemail . " nn";
    $body .= "Message: " . $mymessage . " nn";
    # add more fields here if required

    ## SEND MESSGAE ##

    mail( $toemail, $subject, $body, "From: $email" ) or die ("Mail could not be sent.");

}

?>

JS:

if (verify(myname, myemail, mymessage, human, hash, patt)) {
  $.post(myform.attr('action'), myform.serialize(), function() {
    $('#email-success').fadeIn();
    myform[0].reset();
    setTimeout("$('#email-success').fadeOut();", 5000);
  }, 'json')
  .fail(function() {
    alert('An error has occurred. Please try again later.')
  });
}

I have tried about 5 different methods already, none of which have worked. When I put ‘json’ as the datatype in the .post function the .fail always fires, no matter what’s in the php script. If I leave datatype out, then .fail never fires under any circumstance. I have a feeling the problem is with the php commands and datatype. Any help is appreciated.

Although, yours is a valid JSON data, I always recommend to use json_encode() function to create JSON string.

exit(json_encode(array("error" => "That value was invalid!")));

Another is make sure you send correct headers to ensure the script knows its a json data. So

header('Content-Type: application/json');
exit(json_encode("error" => "That value was invalid!"));
February 27, 2013

jQuery $.post not returning data

Question by Cuonic

I’m using $.post to send a form via ajax to a PHP page, which returns JSON data. Once upon a time, it worked perfectly, and the function(data) executed as normal. Somehow, I’ve broke it, and now it doesn’t even touch the function(data). I’ve tried undoing most of what I’ve done, but I still can’t find the problem.

Here’s the script :

$("#modifyhome").submit(function(event) {
    if($("#modifyhome").valid()) {  
        event.preventDefault();

        var $form = $( this ),
            title = $form.find('input[name="title"]').val(),
            content = $form.find('textarea[name="content"]').val();

        $.post("?action=page-accueil", {"title": title, "content": content},
            function(data) {            
                if(data['error'] == 1)
                {           
                    $().message(data['message']);
                    $("div.jquery-message").effect("shake", {times: 3}, 900);
                }
                else if(data['error'] == 0)
                {           
                    $().message(data['message']);
                    $("div.jquery-message").effect("bounce", {times: 3}, 900);
                }
                else
                {           
                    $().message("Erreur de connexion au serveur : veuillez r&eacute;essayer.");
                    $("div.jquery-message").effect("shake", {times: 3}, 900);
                }
            }, "json"
        );
    }
    else
    {
        $("[id^=qtip-]").effect("pulsate", {times: 3}, 600);
        return false;
    }
});

And here is what the PHP page (?action=page-accueil) returns :

{"error":0,"message":"Page modifi&eacute;e."}

That all checks out as valid JSON, but it’s as if jQuery doesn’t recognize it for some reason. Any help is greatly appreciated 🙂

Answer by Starx

I used to get this problem too, I am exactly not sure of the reason why. But I have a solution that works.

$.post("?action=page-accueil", 
    {"title": title, "content": content},
    function(data) {
        data = eval("("+data+")");
        //.... Then continue it
});

Or, use .parseJSON() function to read the string as JSON, if you dont want to use eval()

$.post("?action=page-accueil", 
    {"title": title, "content": content},
    function(data) {
        data = $.parseJSON(data);
        //.... Then continue it
});
May 4, 2012

jquery POST does not return any result in https

Question by mario

I have a jquery script that just runs fine on http://mysite.com

and looks like this:

Javascript:

$('#form_changePass').live('submit', function() {
    //alert('form_changePass cliked');
    $.POST("_ajaxCall.php", $(this).serialize(),
    function(data){
        var json = eval('('+data+')');
        //alert(data);    
        if(json.message=='alert') {
            $('div.info').hide();
            $('div.alert').show().html(json.string);
        }
        if(json.message=='info') {
            $('div.alert').hide();
            $('div.info').show().html(json.string);
        }
    }
    );
    return false;
})

PHP script:

if ($_POST['formType']=="form_changePass") {
.....
.......
   $arr = array( 'message' => 'info', 'string' => $INFO['updatePass']);
   echo json_encode($arr);
}

Now when I move the domain into https the jquery script is not working anymore. I do not get any return value back. Nothing happens.

I also tried to change the POST to getJSON in the javascript and changed the $_POST to $_GET in the php script but it is still not working.

Anybody a idea?

Answer by Starx

.serialize serializes the form data as a string, so send them using a parameter instead.

$('#form_changePass').on('submit', function() {
    //alert('form_changePass cliked');
    $.POST("_ajaxCall.php", { formData: $(this).serialize() },
    function(data){
        var json = eval('('+data+')');
        //alert(data);    
        if(json.message=='alert') {
            $('div.info').hide();
            $('div.alert').show().html(json.string);
        }
        if(json.message=='info') {
            $('div.alert').hide();
            $('div.info').show().html(json.string);
        }
    }
    );
    return false;
})

And stop using .live() methods, they have been deprecated now. Use .on() methods.

April 17, 2012

jQuery $.post and cakePHP controller giving 400 bad request

Question by Mauritz Swanepoel

I am trying to use $.post() to retrieve a json array from a cakePHP controller. I figured I would not need a view file as I will turn autorender to false and I am expecing a json array. I manage to get a response when I use $.ajax and $.get, but using $.post I get a 400 Bad Request.

My code:

$.post("controller/action",{id: "1"}, function(data) {
      console.log(data);
});

public function action() {
      $this->autoRender = false;
      $array = $_POST;
      header("Content-type: application/json");
      echo json_encode($array);
      exit;
}

Any help or tips on how to possibly do this better? As mentioned $.get, $.ajax does work, but the data callback does not return anything (but firebug shows response array).

Answer by Starx

One error I see is, no indication to expect a json output.

$.post("controller/action",{id: "1"}, function(data) {
      console.log(data);
},"json");
April 14, 2012

Customizing the appearance of a file input in an HTML form

Question by Danny

I’ve been trying to figure out how to customize the appearance of a file input in an HTML form so that the button will match with the rest of the buttons on my site. Looking around here I found a solution that I would expect to work, but it’s having some strange behavior.

I took my file input and set display:none, and created a new text input and button within the form.

            <form method="post" action="../Entry/Create" enctype="multipart/form-data" onsubmit="return aentryValidate()">
                <input type="text" id="EntryTitle" name="EntryTitle" maxlength="50" />
                <div id="invalidTitle" class="invalidData"></div>
                <p id="char-remaining">(50 characters remaining)</p>

                <input type="file" id="ImageFile" name="ImageFile" style="display:none;" />
                <input type="text" id="ImageFileMask" name="ImageFileMask" disabled="true" />
                <button type="button" onclick="HandleFileButtonClick()" id="ImageFileButton" style="margin-left:10px;padding-bottom:0px;height:20px;width:100px;font-size:14px;">browse...</button>
                <div id="invalidImage" class="invalidData"></div>
                <p id="file-desc">(image to represent your entry, jpg, png, or gif)</p>

                <textarea id="EntryDesc" name="EntryDesc"></textarea>
                <div id="invalidDesc" class="invalidData"></div>
                <br />

                <input type="checkbox" id="isPrivate" name="isPrivate" value="true" />
                <input type="hidden" name="isPrivate" value="false" />
                Make my entry private.

                <button id="new-entry-save">save</button>
            </form>

Then my javascript to handle the ImageFileButton button being clicked:

function HandleFileButtonClick() {
    document.getElementById("ImageFile").click();
    document.getElementById("ImageFileMask").value = document.getElementById("ImageFile").value;
}

It appears to work fine. I click the button, the window pops up for me to select a file. When I select a file, it appears in the text box.

The weird behavior comes when I hit the save button on the form. I noticed that it has to be clicked twice to actually submit for some reason now. And, when it submits it is no longer posting the file.

So I made the file input visible again to see what was happening. If I use the ImageFileButton button to select a file, the file shows up in the file input. But when save is clicked, the file input clears and the form doesn’t submit. You then have to click again to submit, and of course now there is no file.

Anybody know what is happening here?

Answer by Starx

No, its not possible. File inputs are generally browser dependant. You might have to use JavaScript replacement or Flash replacement like uploadify.

Article: Input File

Of all form fields, the file upload field is by far the worst when it comes to styling. Explorer Windows offers some (but not many) style possibilities, Mozilla slightly less, and the other browsers none at all. The “Browse” button, especially, is completely inaccessible to CSS manipulation.

March 16, 2012

PHP – Session lost/emptied on form post

Question by Tommy Plummer

So after debugging my session array while logging into my website, I find that when posting a form, all session data is lost. The session data is wiped when the updateDetails and changePassword methods are called. Why is this?

  • session_start() is called before any data processing
  • Upon a POST request, session data is set and unset (but not the entire $_SESSION variable)
  • I use the following code to check for POST requests:

    if($_SERVER[‘REQUEST_METHOD’] == ‘POST’) {
    }

  • It only happens once: Once the session has been lost, the methods can be called without the issue occuring any further (until they lose the session through expiration or closing their browser).

index.php (part)

session_start();

$page = $_GET['p'];
$query = $_GET['q'];
$req = $_GET['req'];

$user = new User();
switch($page) {
    case 'account':

        if($req=="logout") {
            if($user->isLoggedIn())
                $user->logout();

            header("Location: /?p=account");
            exit();

        }
        else if($req=="signup") {
            if($user->isLoggedIn()) {
                header("Location: /?p=account");
                exit();
            }
            else {

                if($_SERVER['REQUEST_METHOD'] == 'POST') {

                    $form_data = array('username' => $_POST['username'],
                        'password' => $_POST['password'],
                        'password_repeat' => $_POST['password_repeat'],
                        'title' => $_POST['title'],
                        'first_name' => $_POST['first_name'],
                        'surname' => $_POST['surname'],
                        'dob_day' => $_POST['dob_day'],
                        'dob_month' => $_POST['dob_month'],
                        'dob_year' => $_POST['dob_year'],
                        'gender' => $_POST['gender'],
                        'email' => strtolower($_POST['email']),
                        'email_repeat' => strtolower($_POST['email_repeat']));

                    if($user->signup($form_data)) {
                        header("Location: /?p=account");
                        exit();
                    }
                }
            }
        }
        else {
            if($user->isLoggedIn()==true) {                 
                if($_SERVER['REQUEST_METHOD'] == 'POST') {

                    if($req=='editdetails') {

                        $form_data = array(
                            'title' => $_POST['title'],
                            'first_name' => $_POST['first_name'],
                            'surname' => $_POST['surname'],
                            'gender' => $_POST['gender'],
                            'phone' => $_POST['phone'],
                            'email' => strtolower($_POST['email']),
                            'password' => $_POST['password']
                            );

                        if($user->updateDetails($form_data)) {
                            header("Location: /?p=account");
                            exit();
                        }
                    }
                    else if($req=='changepassword') {
                        $form_data = array(
                            'old_password' => $_POST['old_password'],
                            'password' => $_POST['password'],
                            'password_repeat' => $_POST['password_repeat'],
                            );

                        if($user->changePassword($form_data)) {
                            header("Location: /?p=account");
                            exit();
                        }
                    }
                }
                $user->retrieveUserDetails();
                $details=$user->getUserDetails();
            }
            else {
                if($req) {
                    header("Location: /?p=account");
                    exit();
                }
                else if($_SERVER['REQUEST_METHOD'] == 'POST') {

                    $form_data = array('username' => $_POST['username'], 'password' => $_POST['password']);

                    if($user->login($form_data)) {
                        $user->retrieveUserDetails();
                        $details=$user->getUserDetails();
                    }
                }

            }
        }
        break;
}

user.php (part)

class User {

private $auth;
private $details;
private $session_alert;

function User() {

    if(isset($_SESSION['alert'])) 
        $this->session_alert = $_SESSION['alert'];

    $this->auth = isset($_SESSION['auth']) ? $_SESSION['auth'] : null;

    if(isset($this->auth)) {
        $database= new Database;
        if($database->checkUserSession($this->auth['user_id'],session_id())) {
            $this->logged_in=true;
        }
        else {
            $this->addSessionAlert('global','Your login session has possibly timed out, you may login again by <a href="/?p=account">clicking here</a>.',true);
            unset($_SESSION['auth']);
        }
    }
}   

function login($data) {
    $return = false;
    $this->form = new Form($data,0);    

    if(!$this->form->getError()) {
        $database= new Database;
        $error_msg = "The username/password entered was invalid. Please check to see if they are correct and try again, or use the relevant links to recover your account.";

        $salt = $database->getSaltByUsername($data['username']);

        if($salt) {
            $hash = $this->hashpwd($data['password'],$salt);

            // Do login
            $this->auth = array();
            $this->auth['user_id'] = $database->checkUserByHash($data['username'],$hash);

            if($this->auth['user_id']) {
                session_regenerate_id();

                if($database->doLogin($this->auth['user_id'],session_id())) {
                    $details=$database->getUserDetailsById($this->auth['user_id']);
                    $this->auth['first_name'] = $details['first_name'];

                    $_SESSION['auth']=$this->auth;

                    $this->logged_in=true;
                    $return = true;
                }
                else
                    $this->form->pushError('Something went wrong, please try again.');
            }
            else
                $this->form->pushError($error_msg);
        }
        else
            $this->form->pushError($error_msg);
    }
    return $return;
}
function logout() {
    $return = false;

    if(isset($this->auth)) {
        $database= new Database;

        if($database->clearUserSession($this->auth['user_id'],session_id())) {
            unset($_SESSION['auth']);
            $this->logged_in=false;
            session_regenerate_id();
            $return = true;
        }
    }

    return $return;
}
function signup($data) {
    $return = false;
    $this->form = new Form($data,1);    

    if(!$this->form->getError()) {
        $database= new Database;

        if($database->checkUserByUsername($data['username']))
            $this->form->pushError("The username entered already exists, please try again.");

        else if($database->checkUserByEmail($data['email']))
            $this->form->pushError("The e-mail address entered is already in use, please try again.");

        else {
            $dbarray = $data;

            unset($dbarray['password'],$dbarray['password_repeat'],$dbarray['dob_month'],$dbarray['dob_day'],$dbarray['dob_year']);

            $dbarray['dob']=date("Y-m-d", mktime(0,0,0,$data['dob_month'], $data['dob_day'], $data['dob_year']));

            $dbarray['salt']=strtoupper(md5(mt_rand()));
            $dbarray['hash'] = $this->hashpwd($data['password'],$dbarray['salt']);

            // Do signup
            $this->auth = array();
            $this->auth['user_id'] = $database->newUser($dbarray);
            if($this->auth['user_id']) { 
                session_regenerate_id();

                if($database->doLogin($this->auth['user_id'],session_id())) {
                    $details=$database->getUserDetailsById($this->auth['user_id']);
                    $this->auth['first_name'] = $details['first_name'];
                    $_SESSION['auth']=$this->auth;

                    $this->logged_in=true;
                }
                $return=true;
            }
            else {
                $this->form->pushError("Something went wrong, please try again.");
            }
        }
    }
    return $return;
}
function updateDetails($data) {
    $return = false;
    $this->form = new Form($data,2);    

    if(!$this->form->getError()) {
        $database= new Database;

        if( $database->checkUserByEmailNotById($data['email'],$this->auth['user_id']) ) {
            $this->form->pushError("The e-mail address entered is already in use, please try again.");
        }

        else {

            $salt = $database->getSaltById($this->auth['user_id']);
            if($salt) {
                $hash = $this->hashpwd($data['password'],$salt);
                if($database->checkUserIdByHash($this->auth['user_id'],$hash)) {
                    $database->updateUserById($this->auth['user_id'],$data);
                    $return = true;

                }
                else 
                    $this->form->pushError("The password entered was incorrect, please try again.");
            }

        }
    }

    return $return;
}

function changePassword($data) {
    $return = false;
    $this->form = new Form($data,3);    

    if(!$this->form->getError()) {
        $database= new Database;

        $salt = $database->getSaltById($this->auth['user_id']);
        if($salt) {

            $hash = $this->hashpwd($data['old_password'],$salt);

            if($database->checkUserIdByHash($this->auth['user_id'],$hash)) {
                $salt=strtoupper(md5(mt_rand()));
                $hash = $this->hashpwd($data['password'],$salt);

                if($database->updateSaltHashById($this->auth['user_id'],$salt,$hash)) $this->addSessionAlert('yourdetails','Your password has been changed successfully.',false);
                $return = true;

            }
            else 
                $this->form->pushError("The old password entered was incorrect, please try again.");
        }
    }

    return $return;
}

function isLoggedIn() {
    return $this->logged_in;
}
function getUserDetails() {
    return $this->details;
}

}

Answer by Starx

Starting a session inside a class’s contructor method, just does not sound nice.

Use session_start(); at the top of the index.php page instead.

February 25, 2012

PHP Update page on POST

Question by Sami Dz Hamida

I have this little problem that when I POST something the page only updates after you refresh the page or change the page.

Example:

Money:
$1,000 -> (echo $money;)

if($_POST['add_money']){
    mysql_query("UPDATE users SET money=money+ '1000' WHERE username = '".$name."'");
    echo "You added $1,000 to your money";
}

“Money” will still say $1,000 unless I change page or refresh.

I’m sure it something so small but I just cant seem to find out how to do it.

Thank you in advanced.

Answer by Starx

Your code should work the way it is. Try this to confirm any errors

if($_POST['add_money']){
    $query = "UPDATE users SET money=money+ '1000' WHERE username = '".$name."'";
    $result = mysql_query($query) or die(mysql_error());
    if($result) {
       echo "You added $1,000 to your money";
    }
}
February 1, 2012

Preserve $_POST variables through different pages like $_SESSION

Question by Starx

Once some data are submitted through POST, is it possible to make them available as $_POST through different pages, same like how $_SESSION allows us to do?

Answer by Starx

Digging up an old question today. But i forgot to post the working solution I dug….

Place this snippet in top of your every page

if(isset($_POST) & count($_POST)) { $_SESSION['post'] = $_POST; }
if(isset($_SESSION['post']) && count($_SESSION['post'])) { $_POST = $_SESSION['post']; }
May 29, 2011

jQuery $.post doesn't pass what button were pressed

Question by Cheburek

Recently I’ve stuck with a problem where $.post does not send information about button which were pressed.
I.e. we have a form with two buttons.

<form method="post"  action="/home/index">

  <input type='hidden' name='data1' value='value1' />

  <button name="button1" type="submit">First</button>
  <button name="button2" type="submit">Second</button>

</form>

$(document).ready(function() {
    $('#formId').submit(function () {
        var f = $(this);
        var action = f.attr("action");
        var serf = f.serialize();
        $.post(action, serf,
        //onreturn
          function (data) {
                //do something here on success
              },
              'json'
          );
        return false;
      });
});

Without ajax form is posted as following if user pressed First button: data1=value1&button1

But when I use $.post posted form does not contain any information about button: data1=value1

jQuery 1.6.1

The behavior depends on that which button were pressed.
Any help or workaround would be appriciate!

Answer by T.J. Crowder

Since you’re stopping the browser’s default behavior, which is what supplies the button value, you’ll have to capture what button was pressed, and add that information to the data you’re posting (your serf data). Probably the most reliable way would be to hook the click event on the buttons as well as the submit event of the form, and route them all to a central function that does the ajax submission with (or without) a button value (without in the case of a form submitted another way, rather than by pressing one of those buttons).

Something along these lines:

$(document).ready(function() {
    function submitTheForm(f, button) {
        var action = f.attr("action");
        var serf = f.serialize();
        if (button && button.name) {
            serf += "&" + encodeURIComponent(button.name);
            if (button.value) {
                serf += "=" + encodeURIComponent(button.value);
            }
        }
        $.post(action, serf,
        //onreturn
          function (data) {
                //do something here on success
          },
          'json'
        );
    }
    $('#formId').submit(function () {
        submitTheForm($(this));
        return false;
    });
    $("#formId :submit").click(function() {
        submitTheForm($(this).closest('form'), this);
        return false;
    });
});

Answer by Starx

I don’t think that is suppose to be happening. But anyways, you could something like this too.

$("#formid").children("input[type="submit"]").click(function() {
    var name = $(this).attr("name");
    post(name);
    return false;
});
function post(buttnname) {
    var action = $("#formid").attr("action");
    var serf = $("#formid").serialize()+"&button="+buttname;
    $.post(action, serf,
    //onreturn
        function (data) {
            //do something here on success
          },
          'json'
        );
}
November 15, 2010

What is wrong with my function? (new to user defined functions)

Question by Mitchell Klein

I am trying to post from a previous page with a form on it, and rather then typing out the code over and over again i tried making a function for it, it didnt work. thanks in advance

function postORempty($field){
isset($_POST[$field]) ? $_POST[$field] : "";
}

$szFname= postORempty('fname');

Answer by Starx

You haven’t returned any value

function postORempty($field){ 
      return isset($_POST[$field]) ? $_POST[$field] : ""; 
}
$szFname= postORempty('fname');
...

Please fill the form - I will response as fast as I can!