Search code examples
javascriptphpformspostdata-entry

PHP programmatically navigate to new form using post


I'm fairly new to PHP. I have a form that a user is filling in with various details (start date, end date, etc), called purchaseLicence.php. When it is submitted, the form action reloads itself to use PHP to validate the data.

If validation is passed, I want it to navigate to purchaseLicence2.php using the post method, as though the form had originally posted directly to purchaseLicence2.php.

I don't mind involving Javascript to do this, and I'm guess that it would need to be involved as it will end up looking at a different form to the one it would otherwise expect to be on.

This is my current purchaseLicence.php, the problem I get is that both purchaseLicence2.php and purchaseLicence.php are rendered after the form has been posted, and the browser is still pointing to purchaseLicence.php, rather that purchaseLicence2.php.

    <?php
        include_once('php/strings.php');
        include_once('php/sprocs.php');
        include_once('php/dates.php');

        $encounteredValidationError = false;
        $navigateAway=false ;

        if (isset($_POST['process']))
        {
            if ($_POST['process'] == 1)
            {
                // if here, form has been posted
                $ProductCode = $_POST['ProductCode'];
                $StartDate = $_POST['StartDate'];
                $EndDate = $_POST['EndDateHidden'];

                // standardise the date formats to ISO8601
                $StartDate = date("Y-m-d", strtotime($StartDate));
                $EndDate = date("Y-m-d", strtotime($EndDate));

                echo "<descriptive>" . PHP_EOL;
                echo "ProductCode:" . $ProductCode . "<br/>" . PHP_EOL;
                echo "StartDate:" . $StartDate . "<br/>" . PHP_EOL;
                echo "EndDate:" . $EndDate . "<br/>" . PHP_EOL;
                echo "</descriptive>" . PHP_EOL;


                // validation to happen here

                if (!$encounteredValidationError) 
                {
                    // so we're happy with the values. The form has just reloaded, so we need to put these back from $_POST into the input fields, so
                    // that we can call NavigateToPurchaseLicence2(), which will get them out of the input fields and post them to purchaseLicence2.php
                    // What a faff!

                    $data = array('ProductCode'=>$ProductCode, 'StartDate'=>$StartDate, 'EndDate'=>$EndDate);
                    $options = array(
                                    'http'=>array(
                                                    'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
                                                    'method'  => 'POST',
                                                    'content' => http_build_query($data)
                                                )
                                    );

                    $context  = stream_context_create($options);
                    $result = file_get_contents('purchaseLicence2.php', false, $context);
                    if ($result === FALSE) { /* Handle error */ }

                    var_dump($result);
                }
                else
                {
                    // hilite errors in the form here, how? form is not yet loaded
                }
            }
        }
    ?>

</head>
<body>
    <form method="post" action="purchaseLicence.php" id="form1">
        <input type="hidden" name="process" value="1">
        <table border=0 width=800px align=left style="margin: 0px auto;">

            <tr> <!-- Product > -->
                <td style="vertical-align:top" width="500px" bgcolor="lightgray"><descriptive>Product</descriptive></td>
                <td width="500px" bgcolor="lightgray">
                    <?php
                        // creates a dropdown of products
                        OutputSelectFromSQL("SELECT * FROM Product ORDER BY Description", "ProductCode", "ProductCode", "Description", "");
                    ?>
                </td>
            </tr>

            <tr> <!-- Licence Period -->
                <td style="vertical-align:top" width="500px" bgcolor="lightgray"><descriptive>Licence Period</descriptive></td>
                <td width="500px" bgcolor="lightgray"><descriptive>1 year</descriptive></td>
            </tr>

            <tr> <!-- Start Date -->
                <td style="vertical-align:top" width="500px" bgcolor="lightgray"><descriptive>Start/End Dates</descriptive></td>
                <td width="500px" bgcolor="lightgray">
                    <input type="date" style="font-family:verdana;font-size:12px;" name="StartDate" id="StartDate" onchange="updateEndDate(this.value);"></input>
                    <descriptive> to <a id="EndDate"></a></descriptive>
                    <input type="hidden" name="EndDateHidden" id="EndDateHidden"></input> <!-- this is used so we can post the end date to $_POST -->
                </td>
            </tr>

            <tr> <!-- Next > -->
                <td style="vertical-align:top" width="500px" bgcolor="lightgray"><descriptive></descriptive></td>
                <td width="500px" bgcolor="lightgray" align="right"><input type="submit" value="Next"></input></td>
            </tr>

        </table>
    </form>
</body>

A simple example for a standard pattern to follow would be really useful.


Solution

  • I suggest you use $_SESSION to hold state between your forms, below is a very crude example, with 1 field on the first form which if good (numeric) , the entire form state is set into the session, then redirects to the second form to fill out additional fields. Very simple but you get the idea.

    dataentry1.php

    <?php 
    session_start();
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    
        // define form state
        $form = [
            'value' => $_POST,
            'error' => []
        ];
    
        // validate a_field
        if (empty($form['value']['a_field'])) {
            $form['error']['a_field'] = 'a_field is a required field!';
        } elseif (!is_numeric($form['value']['a_field'])) {
            $form['error']['a_field'] = 'a_field should be a number!';
        }
    
        // all good
        if (empty($form['error'])) {
            $_SESSION['form'] = $form;
            exit(header('Location: dataentry2.php'));
        }
    }
    ?>
    
    <?= (!empty($form['error']['global']) ? $form['error']['global'] : null) ?>
    
    <form action="/dataentry1.php" method="post">
      <lable>a_field:</lable>
      <input type="text" name="a_field" value="<?= (isset($form['value']['a_field']) ? htmlentities($form['value']['a_field']) : null) ?>">
      <?= (!empty($form['error']['a_field']) ? '<br>'.$form['error']['a_field'] : null) ?>
      <br>
      <input type="submit" value="Submit">
    </form> 
    

    dataentry2.php - requires the previous form to be filled out.

    <?php 
    session_start();
    
    // set form into scope from session
    if (!empty($_SESSION['form'])) {
        $form = $_SESSION['form'];
    } else {
        $_SESSION['form']['error']['global'] = 'You must fill out dataentry1 form first';
        exit(header('Location: dataentry1.php'));
    }
    
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    
        // define form state
        $form = [
            'value' => array_merge($form['value'], $_POST),
            'error' => []
        ];
    
        // validate a_field
        if (empty($form['value']['b_field'])) {
            $form['error']['b_field'] = 'b_field is a required field!';
        } elseif (!is_numeric($form['value']['b_field'])) {
            $form['error']['b_field'] = 'b_field should be a number!';
        }
    
        // all good
        if (empty($form['error'])) {
            exit('Do something cool!');
        }
    }
    ?>
    
    <form action="/dataentry2.php" method="post">
      <lable>a_field:</lable>
      <input type="text" name="a_field" value="<?= (isset($form['value']['a_field']) ? htmlentities($form['value']['a_field']) : null) ?>" readonly="readonly">
      <?= (!empty($form['error']['a_field']) ? '<br>'.$form['error']['a_field'] : null) ?>
    
      <lable>b_field:</lable>
      <input type="text" name="b_field" value="<?= (isset($form['value']['b_field']) ? htmlentities($form['value']['b_field']) : null) ?>">
      <?= (!empty($form['error']['b_field']) ? '<br>'.$form['error']['b_field'] : null) ?>
      <br>
      <input type="submit" value="Submit">
    </form>