gator
gator

Reputation: 3523

Execute PHP code on button press without navigating away from page

I have a page finduser.php which is accessed by clicking a button on another page user.php. user.php is a simple form that takes a couple of parameters from an end user, submits to finduser.php which appends that user to a list.

user.php

<form action="finduser.php" method="post">
    <input type="text" name="username" required="required"/>
    <input type="submit" value="Find User"/>
</form>

finduser.php

<?php
    //session start is on another page included on every page
    $theUser = $_POST["username"];
    if (!isset($_SESSION["users"])) {
        $_SESSION["users"] = array();
    } else {
        $_SESSION["users"][] .= $theUser;
    }
?>

The way the UX handles is that you begin on user.php, submit form and are navigated to finduser.php, but if you want to keep searching for users, you need to press back and resubmit the form. I'd like a way to not redirect on form submit, but still execute the code on finduser.php.

I notice some sites use a similar concept for adding items to a cart. Some sites redirect you to the cart on adding something, but some stay on the same page without disrupting UX. A little box might appear "x has been added to cart", which lets you add multiple things from the same page to cart but without seeing the cart between.

How can I accomplish this? To reiterate what I'm trying to do:

I could do something like the below:

user.php

<?php
    //session start is on another page included on every page
    if ((sizeof($_POST) == 1) && isset($_POST["username"])) {
        $theUser = $_POST["username"];
        if (!isset($_SESSION["users"])) {
            $_SESSION["users"] = array();
        } else {
            $_SESSION["users"][] .= $theUser;
        }
    }
    <form action="user.php" method="post">
        <input type="text" name="username" required="required"/>
        <input type="submit" value="Find User"/>
    </form>
?>

This way only one page is needed, but it still needs to redirect (to itself), and is prone to disruption when someone refreshes the page for example.

Upvotes: 1

Views: 2320

Answers (1)

scrowler
scrowler

Reputation: 24406

You need to use AJAX to process your PHP code and return the result. Here's an option using jQuery's AJAX handler:

# File: yourform.html
<form action="finduser.php" id="findUserForm" method="post">
    <input type="text" name="username" required="required"/>
    <input type="submit" value="Find User"/>
    <div class="messages"></div>
</form>

<script type="text/javascript">
$(document).ready(function() {
    $('#findUserForm').submit(function(e) {
        // Stop the regular post action
        e.preventDefault();
        var $form = $(this);

        // Define the request that should happen instead
        $.ajax({
            url: $form.attr('action'),
            method: $form.attr('method'),
            dataType: 'json',
            data: {
                username: $('input[name="username"]').val()
            }
        }).done(function(result) {
            // Append the results to the messages div
            $('.messages').append('<p>' + result.message + '</p>');
        });
    });
});
</script>

Then your backend script to process the username:

# File: finduser.php
<?php

session_start();

if (isset($_POST['username'])) {
    // do your processing...
    if (empty($_SESSION['users'])) {
        $_SESSION['users'] = [];
    }
    // Add it to the array
    $_SESSION['users'][] = trim($_POST['username']);
    // do more processing?
    // Return a result
    echo json_encode(
        'success' => true,
        'message' => $_POST['username'] . ' was successfully added!'
    );
    exit;
}

// Handle errors!
echo json_encode(
    'success' => false,
    'message' => 'No username was posted.'
);

I haven't tested this, but the idea is that you tell jQuery to override the default way it handles that form being submitted, and instead it should send the username via AJAX to finduser.php. That script will do things that you tell it to, add the user to the session array, then output a JSON result message. jQuery's .done() event then processes that result message and adds the message to the .messages div.

You can use the success => bool option to control how the messages might display, for example:

.done(function(result) {
    var $elem = $('<p></p>');
    // Add a CSS class for display
    if (result.success) {
        $elem.addClass('success');
    } else {
        $elem.addClass('error');
    }
    // Append the results to the messages div
    $elem
        .html(result.message)
        .appendTo($('.messages'));
});

Then add some CSS like so:

.success {
    color: green;
}

.error {
    color: red;
}

In theory, your result messages should then be colour coded.

Upvotes: 2

Related Questions