B_CooperA Posted April 3, 2014 Share Posted April 3, 2014 I've made a form with CodeIgniter to retrieve users password and send it to the given email address. However, if I'm trying to send the request with Ajax, it doesn't work. It is working without the Ajax part. Form: <form action="<?=base_url()?>users/forgot_pass" method="post" id="forget_pass_form"> <div class="form_header"> <h1>Unohditko salasanasi?</h1> </div> <p>Tilaa uusi salasana syöttämällä sähköpostiosoitteesi</p> <div class="front_success" style="display:none" id="forgot-pass-success"> <p>Salasana on lähetetty antamaasi sähköpostiosoitteeseen.</p> </div> <div class="login_error" style="display:none" id="forgot-pass-error"> <p>Sähköpostiosoitetta ei löytynyt järjestelmästämme.</p> </div> <div id="loading_spinner"></div> <p><input type="text" name="to_email" placeholder="Sähköpostiosoite" class="user" style="background-postion: -200px; margin-top: 20px;" /> <input type="submit" name="to_submit" value="Lähetä salasana" class="login_submit" id="forget-pass" /></p> </form> Here's the controller to handle the form: <?php class Users extends CI_Controller { public function forgot_pass() { if($_POST['to_submit']) { $this->load->model('user'); $email = $_POST['to_email']; $email_addr = $this->user->get_email_address($email); if(!empty($email_addr)) { foreach($email_addr as $row) { $this->load->library('email'); $this->email->from('[email protected]', 'Your Name'); $this->email->to($email); $this->email->subject('Password'); $this->email->message($row['password']); if($this->email->send()) { echo "1"; } else { echo "0"; } } } } } } ?> And here's the JS file: $(document).ready(function() { $("form#forget_pass_form").on('submit', function(){ var from = $(this); $.ajax({ url: from.attr('action'), type: from.attr('method'), data:$(from).serialize(), beforeSend: function(){ $("#loading_spinner").show(); }, success: function (data) { if(data == '1'){ //if the email is send then it return 1 so that you show success msg $(".front_success").show(); } else { //if the email is not send then it return 0 so that you show error msg $("#forgot-pass-error").show(); } $("#loading_spinner").hide();// hide when ajax complete } }); return false; }); }); Each and everytime it will show that "login_error" div even though I have typed my email address correctly. Any help would be appreciated Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/ Share on other sites More sharing options...
Psycho Posted April 3, 2014 Share Posted April 3, 2014 (edited) I've made a form with CodeIgniter to retrieve users password and send it to the given email address. Forget your AJAX problem. You first need to resolve the issue that you are apparently storing an unhashed value for the user's password. No one, not even you, should have access to the user's password. You should store a hash of the user's password which is a sort of one-way encryption. If done correctly, it would be impossible to ever revert the hashed value back to the original value provided by the user. And, you're sending this through email no less! Edited April 3, 2014 by Psycho Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1474831 Share on other sites More sharing options...
B_CooperA Posted April 3, 2014 Author Share Posted April 3, 2014 I already know this. I'm just making some simple tests and of course the final product will be nothing like this. I'd be more than happy if anyone is able to help me. Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1474835 Share on other sites More sharing options...
Psycho Posted April 3, 2014 Share Posted April 3, 2014 I already know this. I'm just making some simple tests and of course the final product will be nothing like this. I'd be more than happy if anyone is able to help me. If you know that then why are you not implementing a password reset process instead of going to the trouble of retrieving their current password to send to them? If you truly intend to do it correctly, then why are you wasting time writing code to do something the wrong way? It would make more sense if you were just building this to send a mock email with the intent of updating it to send a new temp password rather than writing code to retrieve the password. As to your problem, what debugging have you done so far and what did you find? We can't solve your problem since we don't know what the results are. So, pick one place of possible failure and verify what is or is not happening. Here is the break-down as I see it should go: 1. The JavaScript makes a call to a PHP page passing the email value 2. The PHP page takes the email value, performs operations and returns a 1 or 0 3. The JavaScript page takes the return value to determine what to show/hide All you know is that in step 3 you are always getting the error condition, I would start by testing the PHP page by directly submitting the form instead of calling it via AJAX. If that works then adding some debugging to the PHP page to verify the data it is receiving from the AJAX call the ultimate output. However, since this is being called via AJAX you need a way to output that info. You could either have the page write debugging info to a flat file that you inspect or you could output the debugging info back to the AJAX return function and output it to the page. Edit: After reading the PHP file, all it contains is a class. Is that the file that is called from the AJAX request? If so, the class is never instantiated or called. So, that page would simply return nothing. Also, that function has almost zero error handling. Plus, the logic in it isn't making sense to me. For example, why is there a foreach() loop on something that should only include a single record? Anyway, you just need to follow some simple debugging processes. Take one point in the process and add some debugging code to verify the data coming in and the data going out. - If the data coming in is not right, then you know that the problem exists somewhere earlier in the process - If the data coming in is correct, but incorrect going out - then you've found at least one problem and can address it - If the data coming in and going out is correct, then you know the problem exists somewhere later in the process. Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1474839 Share on other sites More sharing options...
B_CooperA Posted April 3, 2014 Author Share Posted April 3, 2014 As to your problem, what debugging have you done so far and what did you find? We can't solve your problem since we don't know what the results are. So, pick one place of possible failure and verify what is or is not happening. Here is the break-down as I see it should go: 1. The JavaScript makes a call to a PHP page passing the email value 2. The PHP page takes the email value, performs operations and returns a 1 or 0 3. The JavaScript page takes the return value to determine what to show/hide Well, the script works perfectly without the ajax. So the PHP file itself is working properly. Edit: After reading the PHP file, all it contains is a class. Is that the file that is called from the AJAX request? If so, the class is never instantiated or called. So, that page would simply return nothing. The method forgot_pass() is called from the AJAX request.. And since I'm using CodeIgniter (MVC pattern), why should I instantiate the class? For example, why is there a foreach() loop on something that should only include a single record? Yeah I know foreach() loop isn't the most fanciest way to loop if there are only record one. I could of use while() loop instead Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1474841 Share on other sites More sharing options...
Psycho Posted April 3, 2014 Share Posted April 3, 2014 Well, the script works perfectly without the ajax. So the PHP file itself is working properly. OK, good. That's the type of information that would be helpful to know up front. The method forgot_pass() is called from the AJAX request.. And since I'm using CodeIgniter (MVC pattern), why should I instantiate the class? Well, I don't see how that class gets called from the AJAX request. It may not be getting used at all for all I know. You could do a couple of quick tests to see what is happening. Change the success condition in the AJAX call to alert() the returned value. Then you can verify what, if anything, is being returned. If you do get a 0 response then change the PHP method to return the $_POST['to_email'] value (with the alert still in place) so you can verify the AJAX is passing the value correctly. If you aren't getting anything inthe alert() then that method is not getting called. Yeah I know foreach() loop isn't the most fanciest way to loop if there are only record one. I could of use while() loop instead What I meant was why do you have a loop at all? IF there will only be one record just reference that record directly if(!empty($email_addr)) { $this->load->library('email'); $this->email->from('[email protected]', 'Your Name'); $this->email->to($email); $this->email->subject('Password'); $this->email->message($email_addr[0]['password']); // <<== Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1474842 Share on other sites More sharing options...
B_CooperA Posted April 3, 2014 Author Share Posted April 3, 2014 Well, I don't see how that class gets called from the AJAX request. It may not be getting used at all for all I know. You could do a couple of quick tests to see what is happening. Change the success condition in the AJAX call to alert() the returned value. Then you can verify what, if anything, is being returned. If you do get a 0 response then change the PHP method to return the $_POST['to_email'] value (with the alert still in place) so you can verify the AJAX is passing the value correctly. If you aren't getting anything inthe alert() then that method is not getting called. Well, yeah, I got an empty alert(). I thought ajax would grab the method in here: url: from.attr('action') So the question is how do I call that method so that ajax can get the value from that forgot_pass() method? Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1474846 Share on other sites More sharing options...
Psycho Posted April 3, 2014 Share Posted April 3, 2014 You stated that the page works when you do not implement the AJAX call and just let the form post to the PHP page identified in the action parameter, correct? That doesn't make sense since it would just load the page with the class definition, but not actually use the class. If you are not getting a response from the AJAX call, the first order of business is to verify that it is even calling the page correctly. You are setting the URL for the AJAX call using this url: from.attr('action'), You should validate that it is the value you think it is. Try adding a line right after you define from var from = $(this); alert(from.attr('action')); If that isn't alerting the value you expect then that's the source of your problem. If it is the value you expect, then go to the next logical step in the process and verify the data. Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1474851 Share on other sites More sharing options...
B_CooperA Posted April 3, 2014 Author Share Posted April 3, 2014 You should validate that it is the value you think it is. Try adding a line right after you define from var from = $(this); alert(from.attr('action')); If that isn't alerting the value you expect then that's the source of your problem. If it is the value you expect, then go to the next logical step in the process and verify the data. I alerted the form action, and yes it was directing into that forgot_pass method.. Could it be that the error is caused by that login method? Every time I submit the button and take a look at developer tools tab, the referer line is always indicating to that login method? Am I loading the views wrong? Here's my whole controller: <?php class Users extends CI_Controller { public function login() { $data['error'] = 0; if(isset($_POST['submit'])) { $this->load->model('user'); $email = $_POST['email']; $password = $_POST['password']; $user = $this->user->login($email, $password); if(!$user) { $data['error'] = 1; } else { echo "Kirjautuminen onnistui"; } } $this->load->view('header'); $this->load->view('index', $data); $this->load->view('footer'); } public function forgot_pass() { if(isset($_POST['to_submit'])) { $this->load->model('user'); $email = $_POST['to_email']; $email_addr = $this->user->get_email_address($email); if($email_addr) { $this->load->library('email'); $this->email->from('[email protected]', 'Your Name'); $this->email->to($email); $this->email->subject('Test'); $this->email->message($email_addr[0]['password']); if($this->email->send()) { echo "1"; } else { echo "0"; } } } $this->view->load('header'); $this->view->load('index'); $this->view->load('footer'); } } ?> Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1474854 Share on other sites More sharing options...
B_CooperA Posted April 4, 2014 Author Share Posted April 4, 2014 Anyone?! Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1474924 Share on other sites More sharing options...
Psycho Posted April 4, 2014 Share Posted April 4, 2014 I alerted the form action, and yes it was directing into that forgot_pass method.. Could it be that the error is caused by that login method? Every time I submit the button and take a look at developer tools tab, the referer line is always indicating to that login method? Am I loading the views wrong? What you are stating makes no sense. You can't have the AJAX call a method. An AJAX call has to be to a PHP page that will be processed just as if the user typed the URL into their browser. The AJAX call doesn't automatically initiate/run a method on the page called. So, either you are doing something completely wrong or you are using the wrong terminology which is making it difficult to help you. You stated previously that the functionality worked when you let the form post normally (w/o the AJAX). If your form action is pointing to the file where the Users class is defined, then I call BS. Just loading that script would do nothing. All it does is define the class - it never calls the class to actually do anything. Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1474949 Share on other sites More sharing options...
B_CooperA Posted April 4, 2014 Author Share Posted April 4, 2014 So the only option is to put that method in separate file? Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1474994 Share on other sites More sharing options...
Psycho Posted April 5, 2014 Share Posted April 5, 2014 So the only option is to put that method in separate file? That's not what I was saying at all. You are making this difficult to try and help you because there is some miscommunication here which I believe is due to the misuse of the wrong terminology. Also, I explained the process to try and debug the problem yourself, but I've not seen that you actually attempted that process in any meaningful way. I still haven't seen a single piece of code that ever instantiates the Users class or calls the forgot_pass() method. The fact that your alert was empty shows that the method is never getting called OR it is going into one of the conditions that has no output - because the method is poorly written. You could at least change your method so it would always have an output. class Users extends CI_Controller { public function forgot_pass() { if(!$_POST['to_submit']) { exit("No post value"); } $this->load->model('user'); $email = $_POST['to_email']; $email_addr = $this->user->get_email_address($email); if(empty($email_addr)) { exit("Email address not found"); } $password = $email_addr[0]['password']; $this->load->library('email'); $this->email->from('[email protected]', 'Your Name'); $this->email->to($email); $this->email->subject('Password'); $this->email->message($password); echo ($this->email->send()) ? 1 : 0; } } If you still do not see anything int he alert then you know the method is not being called - which is what I believe is happening. Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1475020 Share on other sites More sharing options...
B_CooperA Posted April 7, 2014 Author Share Posted April 7, 2014 Okay, I did what you posted above, copied your version of the method. And now I'm getting "No post value" as output and a notice of undefined index of "to_submit". So it doesn't recognize the form is being submitted. So how should I pull this off? Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1475255 Share on other sites More sharing options...
Psycho Posted April 7, 2014 Share Posted April 7, 2014 OK, so what IS in the POST data? I'm doing my best to help you, but I feel I have to spoon feed you everything. I am not very strong in AJAX, plus these types of problems can be difficult to debug since the data is crossing multiple technologies. I provided guidance above on how you should approach debugging an issue, but it seems as soon as you find a problem you throw up your hands in despair. So, let's take inventory of where we are at. You can now confirm that the PHP method is being executed. But, it is not receiving the data that it expects. So, the logical question (at least to me) is what data IS being sent? YOU can answer that by adding some more debugging code to that method. Change exit("No post value"); To $msg = "No post value<br>"; $msg .= "POST: <pre>" . print_r($_POST, 1) . "</pre>"; exit($msg); Now you will know what is being sent with the AJAX request. I think the problem is in how you are sending the form data data:$(from).serialize(), But, as I said, AJAX is not my strong suite. Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1475268 Share on other sites More sharing options...
Solution Psycho Posted April 7, 2014 Solution Share Posted April 7, 2014 (edited) OK, I'm pretty sure I found the issue. I had to construct some working pages using the code you provided above, and the problem is actually pretty simple. You are submitting the page via AJAX! In other words, the user is NOT clicking the submit button. You made the submit button an input field. Input buttons are only passed if they are clicked! I was able to verify this by just doing the simple debugging I proposed above. The return value that was alerted in the java script showed that the to_email was included in the POST data, but that was it. So, this line in the method is always returning false: if($_POST['to_submit']) { That's a poor implementation. I see it a lot, but checking to see if a submit button was clicked is not the best way to check if a form is posted. For a form with multiple input fields you can check the $_SERVER super global for the request method. But, in this case, the user in only submitting one field. So, you should just check that. This should resolve your problem class Users extends CI_Controller { public function forgot_pass() { if(!$_POST['to_email']) { //No email post value return 0; } $this->load->model('user'); $email = $_POST['to_email']; $email_addr = $this->user->get_email_address($email); if(empty($email_addr)) { //Email address not found return 0; } $password = $email_addr[0]['password']; $this->load->library('email'); $this->email->from('[email protected]', 'Your Name'); $this->email->to($email); $this->email->subject('Password'); $this->email->message($password); //Return true false based upon result of send() response echo ($this->email->send()) ? 1 : 0; } } Edited April 7, 2014 by Psycho Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1475270 Share on other sites More sharing options...
B_CooperA Posted April 7, 2014 Author Share Posted April 7, 2014 Thank you so much! God how stupid I am, so simple mistake yet so crucial. Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1475311 Share on other sites More sharing options...
Psycho Posted April 7, 2014 Share Posted April 7, 2014 Thank you so much! God how stupid I am, so simple mistake yet so crucial. You're welcome. But, the whole point of this exercise (for me) was for you to learn some simple debugging techniques. It's not hard, it just takes a little thought and a little bit of work. First understand the process. Then identify a certain point in the process that may not be working correctly. Add some debugging code to verify what the input data and the output data is from that process. From that you can determine if the problem is before or after that point. Then just move your debugging efforts forward/backward from that point and try again. Quote Link to comment https://forums.phpfreaks.com/topic/287494-forget-password-form-not-working-with-ajax/#findComment-1475333 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.