0

Nothing has quite fit my needs here, Im sure this is easy compared to most things but I really have no knowledge or understanding of jQuery, so I am kind of flailing here.

I have a password change form (That currently works as far as changing the password goes) but what it doesnt do is show that anything has happened. So right now when I fill the passwords out, hit submit, the form is submitted to the changePassword.php script, and handled properly, but I get no visible indication of this.

I would like the password forms to clear, and a div underneath the button to populate with one of my $response messages.

main.php

<div id="s-window">
   <form id="changepassword" action="changePassword.php" method="POST">
    <input type="password" name="currentPassword" placeholder="Current Password"/>
    <input type="password" name="newPassword" placeholder="New Password"/>
    <input type="password" name="confirmPassword" placeholder="Confirm Password"/>
    <input class="button" type="submit" value="Change Password" />
   </form>
<div id="response"></div>

jQuery in main.php:

$(document).ready(function(){
    $("#changepassword").submit(function(e) {
        e.preventDefault(); // stop normal form submission
        $.ajax({
            url: "changePassword.php",
            type: "POST",
            data: $(this).serialize(), // you also need to send the form data
            dataType: "html",
            success: function(data){ // this happens after we get results
                $("#results").show();
                $("#results").append(data);
            }
        });
    });
});

And finally, the script changePassword.php

$currentPassword = ($_POST['currentPassword']); 
$password = ($_POST['newPassword']);
$password2 = ($_POST['confirmPassword']);
$username = ($_SESSION['username']);
$response = '';

if($password === '' || $password === FALSE){
  $response = "Your password cannot be blank!";
} else {
  if(strlen($password)<7){
    $response = "Your password is too short!";
  } else {
    if ($password <> $password2) { 
      $response = "Your passwords do not match.";
    }
    else if ($password === $password2){

    $hashed_password = password_hash($password, PASSWORD_DEFAULT);


    $sql = "UPDATE Staff SET password='$hashed_password' WHERE username='$username'";

    mysql_query($sql) or die( mysql_error() );
    echo $response;
    }
    else { mysqli_error($con); }
  };
};
  • Try moving `echo $response;` outside the closing `}` ? – Maximus2012 Apr 17 '15 at 18:24
  • Additionally, try using `==` in place of `===` and see if that helps as well. – Maximus2012 Apr 17 '15 at 18:25
  • 4
    Presumably you want to fill this div `
    ` but your selector `$("#results")` targets the id of "results" instead of "response"
    – Grax32 Apr 17 '15 at 18:25
  • 1
    [You need to prevent SQL Injection!](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) Please, [stop using `mysql_*` functions](http://stackoverflow.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php). They are no longer maintained and are [officially deprecated](https://wiki.php.net/rfc/mysql_deprecation). Learn about [prepared statements](http://en.wikipedia.org/wiki/Prepared_statement) instead, and use [PDO](http://jayblanchard.net/demystifying_php_pdo.html). – Jay Blanchard Apr 17 '15 at 18:26
  • To clear the password fields in the form use `$('input[type="password"]').val('');` inside success function. – Mahendran Sakkarai Apr 17 '15 at 19:49
  • I know this may seem small in the grand scheme of things but the `dataType` property in `$.ajax` is _"The type of data that you're expecting back from the server. "_ according to the [docs](http://api.jquery.com/jquery.ajax/). This should theoretically be accurate with regards to what you're returning (i.e. if you're not returning `html` it shouldn't be `html`). – War10ck Apr 17 '15 at 21:05

2 Answers2

1

Your $response variable is only being returned inside the nested else statements. Move return $response to the outside of the if \ else statement as you want a response regardless of what happens in these blocks.

Also your div that is populating the results has an id of response but you are trying to append it to a div with an id of results.

Change

$("#results").show();
$("#results").append(data);

To

$("#response").show();
$("#response").append(data);

If that doesn't do the trick, try and console.log(data) to make sure you are actually getting a response from the server. Use your browsers developer tools to view the log.

Hope this helps!

Justin Ober
  • 839
  • 6
  • 14
1

I'm updated you coding. From the suggestion of @jay-blanchard I updated the changePassword.php code with PDO.

And also implemented validation rule and store them in a array. In your previous code you used if else if. So, If a password has 3 error's means it wont show at one time. You need to press submit button 3 times to get those errors one by one. Now I updated those with storing those errors to array and in the final stage I encode them as json. Check the below code. If you found any issue means please reply me. Because, I haven't tested the code. Hope it will execute successfully.

changePassword.php

<?php

// Database configuration
define('DB_HOST', 'localhost');
define('DB_USER', 'username');
define('DB_PASS', 'password');
define('DB_NAME', 'database');

// Initializing error array
$response['error'] = array();

try {
    $db = new PDO('mysql:host=' . DB_HOST .';dbname=' . DB_NAME . ';charset=utf8mb4', DB_USER, DB_PASS);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch (Exception $e) {
    $response['error'][] = "Error in DB Connection";
}

// Store post and session values to variable.
$currentPassword = $_POST['currentPassword']; 
$password = $_POST['newPassword'];
$password2 = $_POST['confirmPassword'];
$username = $_SESSION['username'];

// Validating Password
if($password === '' || $password === FALSE ){
    $response['error'][] = "Your Password cannot be blank";
}
if(strlen($password)<7){
    $response['error'][] = "Your Password is too short!";
}
if($password <> $password2){
    $response['error'][] = "Your Passwords do not match";
}

// If validation password update the password for the user.
if(empty($response['error'])){
    $stmt = $db->prepare('UPDATE Staff SET password=? WHERE username=?'); // Prepare the query
    $stmt->execute(array(password_hash($password, PASSWORD_DEFAULT), $username)); // Bind the parameters to the query
    $affectedRows = $stmt->rowCount(); // Getting affected rows count
    if($affectedRows != 1){
        $response['error'][] = "No User is related to the Username";
    }
}

// printing response.
if(!empty($response['error'])){
    echo json_encode($response);
}else{
    echo json_encode(array("success"=>true));
}

I formatted the response as json. So I'm updating the ajax function dataType to json. Check the below code.

main.php

<div id="s-window">
    <form id="changepassword" action="changePassword.php" method="POST">
        <input type="password" name="currentPassword" placeholder="Current Password"/>
        <input type="password" name="newPassword" placeholder="New Password"/>
        <input type="password" name="confirmPassword" placeholder="Confirm Password"/>
        <input class="button" type="submit" value="Change Password" />
    </form>
<div id="response" style="display:none"></div>

<script>
$(document).ready(function(){
    $("#changepassword").submit(function(e) {
        e.preventDefault(); // stop normal form submission
        $.ajax({
            url: "changePassword.php",
            type: "POST",
            data: $(this).serialize(), // you also need to send the form data
            dataType: "json",
            success: function(data){ // this happens after we get results
                $("#response").show();
                $("#response").html("");
                // If there is no error the response will be {"success":true}
                // If there is any error means the response will be {"error":["1":"error",..]}
                if(data.success){
                    $("#response").html("Successfully Updated the Password");
                }else{
                    $.each(data.error, function(index, val){
                        $("#response").append(val+"<br/>");
                    });
                }
            }
        });
    });
});
</script>

Hope it will helps you. Enjoy.

Mahendran Sakkarai
  • 8,381
  • 6
  • 44
  • 66
  • I do not know enough about Mysqli and PDO to use this response. I understand it is the better way of doing things. But would you be willing to just help me fix it the way it is instead? It is currently not working and I dont know enough to properly debug it. – Frank Edgar May 01 '15 at 19:50
  • EDIT: It is working now. Thank you. If you could recommend a good clear tutorial for PDO and Mysqli, that would be great. There is copious information about MySQL function, but decidedly less about MySqli (probably a function of it being more recent). I have yet to bridge that gap. – Frank Edgar May 01 '15 at 19:57
  • best to read about mysqli is its [official documentation](http://php.net/manual/en/book.mysqli.php) – Mahendran Sakkarai May 04 '15 at 06:35