Home > OS >  Wordpress Login Form - How to show error message without reload page
Wordpress Login Form - How to show error message without reload page

Time:08-09

I'm building my own custom login page for wordress. The login form seems to work, however I would like to be able to customize the error message more specifically.

When the login credentials are incorrect and you log in, the error message appears only after the page has reloaded. What I would like to do is show the error message without reloading the page.

I searched on stackoverflow and wordpress reference but couldn't find a solution for my case. Anyone have a suggestion on how I might achieve my goal?

Thanks for any replies, I appreciate any help.

Update

Thanks to the users who responded, I really appreciate it. I followed the suggestions that were given in the answers and I believe I have managed to combine something with AJAX Request. The point is that there is something wrong because when I click on login the page is refreshing.

I have been studying all day for this, but my efforts have been in vain. I know it's not much, but I've read some references on wordpress, ajax and js. I searched again on stackoverflow and finally I also found a guide that explains roughly how to create a login with ajax requests on wordpress, it helped.

With the code below I think I can see the message on the same page without the refresh happening. In the chrome inspect I notice the request but the page is still refreshed. I don't understand what I'm doing wrong.

Can anyone clarify this? I leave the updated code below.

My login form template.php file

<?php 

/* Template Name: Custom Login Page */

?>

<?php get_header(); ?>
  
  <div > 
    <form id="wp_login_form" action="" method="post">
      <label>Username / Email</label><br>
      <input type="text" name="user_login"  value=""><br>

      <label>Password</label><br>
      <input type="password" name="user_pass"  value=""><br>

      <label>Remember me</label><br>
      <input type="checkbox" name="rememberme"  value="forever"><br>
      <br><br>
      <input type="submit" id="submitbtn" name="submit"  value="login" >
    </form>
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script>
      jQuery(function(){

        var ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>";

        jQuery("#submitbtn").on("click",function(){
          var formdata = jQuery("#wp_login_form").serialize();
          formdata  = "&action=custom_login&param=login_test"
          jQuery.ajax({
            url: ajaxurl,
            data: formdata,
            type: "POST",
            success: function(response) {
              var data = jQuery.parseJSON(response);
              if (data.status == 1 ) {
                window.location = "<?php echo site_url() ?>";
              } else {
                alert("Invalid username/password");
              }
            }
          });
        });
      });
    </script>
  </div>

<?php get_footer(); ?>

In my functions.php file

/* Ajax Form Login */
add_action("wp_ajax_custom_login", "handle_custom_login"); // wp_ajax_{action_name}
add_action("wp_ajax_nopriv_custom_login", "handle_custom_login");

function handle_custom_login() {
    $param = isset($_REQUEST['param'])?trim($_REQUEST['param']):"";
    if($param=="login_test"){
        $info = array();
        $info['user_login'] = $_POST['user_login'];
        $info['user_password'] = $_POST['user_password'];
        $info['remember'] = true;

        $user_signon = wp_signon($info, false);

        if (is_wp_error($user_signon)) {
            echo json_encode(array("status" => 0));
        } else {
            echo json_encode(array("status" => 1));
        }
    }
    wp_die();
}

add_action("wp_logout", "handle_custom_login_redirection");
function handle_custom_login_redirection(){
    wp_redirect(home_url("/login"));
    exit;
}

CodePudding user response:

What you want isn't achievable using PHP. As quick explanation, PHP is a server side scriptiong language, which means that only the server can execute your code. So whenever you press Login is has to go to the server (doing a request) and then you'll get back the new HTML from your server.

How to do this

Is quite an investment but if you really want to learn or build this you should look into Javascript AJAX requests. In a nutshell, AJAX is how you communicate with your server without any page reload.

Alternative

You could also try to use some plugins that try to do this. I have no experience with them but here's one that claims to do exactly what you want: https://nl.wordpress.org/plugins/login-with-ajax/

If that one doesn't fit your needs, you can at least continue searching using the term AJAX.

I hope this helps :)

TLDR

With PHP, you can't. Use an AJAX WordPress plugin or build a custom solution using Javascript and AJAX.

CodePudding user response:

Introduction

I will briefly describe how HTML forms work, why your page is reloading and how you can communicate with the server without reloading your page, finally, how you can update your page based on this communication.

How HTML forms work

When you create a form tag and a structure into it, with a button of submit type inside of it, specifying an action (or using the default), then, upon clicking on the button mentioned earlier, your form is submitted. On submitting your form, all elements inside the form, having a name attribute (i.e. name="somename") is picked up and a request will be sent to the specified action (defaulting to the same page), where the form data will be represented as key-value pairs, the keys being the names of your form elements and the values being the values of the elements.

Upon form submit, your browser will send a request to the target of the form. The action of the form (if valid) will pick up the request, handle it and respond to your browser.

When the browser receives this response, it will display it as the content of the page. The users experience this behavior as a page reload. You are bothered with this behavior, as you described in your question and you would prefer to have a less obtrusive, smoother behavior. This is possible with AJAX requests.

AJAX

AJAX requests are well-documented, so, if you are unfamiliar with them - which surely is the case -, then I advise to read the content of the link I have given you above and gain some experience with AJAX. If you get stuck with it, let me know your blocker, but, for now, I will assume that the tutorials clarify the matter for you and in a reasonable amount of time you will successfully learn how to tackle them.

You can also communicate with your server (without page reload) with push notifications or websockets, but since this is a request-response use-case, I strongly advise the use of AJAX. Since AJAX stands for Asynchronous Javascript and XML, the asynchronous part suggests that you are calling an asynchronous function that you do not wait for, that is, your request is being sent to the server and there is an event to handle the server response, upon which you can specify function(s) to be executed, known as the callback(s).

If you are going to have an AJAX request, then you do not necessarily need the form and the submit button is definitely not needed, instead, you could use an input type="button" with a click event handler that will pick up the data and send the request.

How to handle server responses

The simplest way to handle the requests is to just take the (HTML) response and refresh your page content for the regions you want to update (without page reload, of course). But this is not necessarily ideal.

If your structure does not change, but your content does, then it makes much more sense to change your server code to just send the content as JSON (Javascript Object Notation) and update only the content of your page. This approach ensures that your server does not have to send very large, superfluous responses to your browser if it's unnecessary. Instead, it just sends the data, reducing the load of your server's networking and, as a result, making your server more scalable. But this means that your browser will have to update the content itself, which is no longer automatic and you need to code the behavior in a client-side language, such as Javascript.

How you should proceed

Since all this is obviously new to you, I advise you to start with the simplest approach, to have some success that will boost your morale, that is, at first stage, send the request as AJAX, the server should only respond with the inner HTML of the body tag, rather than the whole HTML and you could do a

document.body.innerHTML = response;

in your callback.

The reasonable expectation is that your page is not reloaded by the browser, but it is refreshed. If you reach this stage, then you might decide that it is good-enough for you, or you can decide to improve it, change the server-side to respond to the AJAX request with a JSON and implement some client-side functions to handle the request and refresh the content.

I of course advise the latter, but you of course have the liberty of choice here.

Now, let's understand what a request method is.

A GET request is a request defined by a URL (Unified Resource Locator) and the parameters are passed as GET parameters, that is, inside the URL, after the ? mark, like

https://www.yourpage.com?yourparameter=yourvalue&yoursecondparameter=yoursecondvalue

A POST request is a request where POST parameters can also be defined. In PHP you have neat ways to determine the request type, see this excellent page: Detecting request type in PHP (GET, POST, PUT or DELETE)

Now, when you load the page for the first time, a GET request is being send. Once the form is submitted (via AJAX), you need to specify that you are sending a POST request and then the server will know that it will need to send only the data (rather than the HTML) as a response.

  • Related