-1

I have a complicated registration form intended for WordPress genealogical websites. This form has several generational fieldsets that are displayed based on a radio select field. IF the fieldset is displayed, all fields are required. If any of the fields are empty on submit, I want the fieldset to be displayed with error messages. The relevant fieldsets are hidden or displayed using javascript.

The select field looks like this:

<fieldset>
        <div style="color:red;font-weight:bold;"><?php echo $error_message2; echo $relationError; ?></div>
        <legend>How are you related to this person?</legend>
    <table><tr><td>
        <span style="display: inline-block;"><?php echo $read.$readonly; ?></span>
        &nbsp;
        <span style="display: inline-block;">
        <label style="display: inline-block;" for="whom">is</label>
        <input id="whom" type ="radio" name="whom" class="required" value="My" onclick="document.getElementById ('spouse').style.display = 'none';" <?php if (isset($_POST['whom']) && $_POST['whom'] == 'My') echo 'checked="checked"'; ?>/>My &nbsp;
        <input id="whom" type ="radio" class="required" name="whom" onclick="document.getElementById ('spouse').style.display = 'block';" value="Spouse" <?php if (isset($_POST['whom']) && $_POST['whom'] == 'Spouse') echo 'checked="checked"'; ?>/>My Spouse's
        </span>
        &nbsp;
        <span style="display: inline-block;">
        <?php $relation = $_POST["relation"]; ?>
        <select id="relation" name="relation" onchange="processAncestor();" class="required">
            <option value="Self" <?php if (isset ($relation) && $relation == "Self") echo 'selected = "selected"';?>>Self</option>
            <option value="Spouse" <?php if (isset($relation) && $relation == "Spouse") echo 'selected = "selected"';?>>Spouse</option>
            <option value="Father" <?php if (isset($relation) && $relation == "Father") echo 'selected = "selected"';?>>Father</option>
            <option value="Mother" <?php if (isset($relation) && $relation == "Mother") echo 'selected = "selected"';?>>Mother</option>
            <option value="FatherSister" <?php if (isset($relation) && $relation == "FatherSister") echo 'selected = "selected"';?>>Sister of Father</option>
            <option value="MotherSister" <?php if (isset($relation) && $relation == "MotherSister") echo 'selected = "selected"';?>>Sister of Mother</option>
            <option value="FatherBrother" <?php if (isset($relation) && $relation == "FatherBrother") echo 'selected = "selected"';?>>Brother of Father</option>
            <option value="MotherBrother" <?php if (isset($relation) && $relation == "MotherBrother") echo 'selected = "selected"';?>>Brother of Mother</option>
            <option value="Brother" <?php if (isset($relation) && $relation == "Brother") echo 'selected = "selected"';?>>Brother</option>
            <option value="Sister" <?php if (isset($relation) && $relation == "Sister") echo 'selected = "selected"';?>>Sister</option>
            <option value="Grandfather" <?php if (isset($relation) && $relation == "Grandfather") echo 'selected = "selected"';?>>Grandfather</option>
            <option value="Grandmother" <?php if (isset($relation) && $relation == "Grandmother") echo 'selected = "selected"';?>>Grandmother</option>
            <option value="GrGrandfather" <?php if (isset($relation) && $relation == "GrGrandfather") echo 'selected = "selected"';?>>Great Grandfather</option>
            <option value="GrGrandmother" <?php if (isset($relation) && $relation == "GrGrandmother") echo 'selected = "selected"';?>>Great Grandmother</option>
            <option value="2ndGrGrandfather" <?php if (isset($relation) && $relation == "2ndGrGrandfather") echo 'selected = "selected"';?>>2nd Great Grandfather</option>
            <option value="2ndGrGrandmother" <?php if (isset($relation) && $relation == "2ndGrGrandmother") echo 'selected = "selected"';?>>2nd Great Grandmother</option>
            <option value="NULL" <?php if (!isset($_POST["relation"])) echo 'selected = "selected"';?>>Select a Relationship</option>
        </select>
        </span>
    </td></tr></table>
</fieldset>

The fieldset for spouse, for the purpose of this question, is as follows:

    <div style="color:red;font-weight:bold;"> <?php $Svalid="false"; echo $error_message2; echo $spouse_firstnameError; echo $spouse_lastnameError; echo $spouse_birthdateError; echo $spouse_birthplaceError; echo $spouse_mar_dateError; ?></div>
    <div id="spouse">
    <fieldset>
        <legend>Spouse's Information</legend>
    <p><strong>Please complete the following information about your spouse:</strong></p>
    <table>
        <tr>
            <td>
                <label class="required" for "spouse_firstname">Spouse Name</label>
                <input type="text" id="spouse_firstname" class="required" name="spouse_firstname" <?php if (!empty($_POST['spouse_firstname'])) {echo "value=\"" . htmlspecialchars($_POST["spouse_firstname"]) . "\"";} ?> />
            </td>
            <td>
                <label class="required" for "spouse_lastname">Spouse Surname/Maiden Name</label>
                <input type="text" id="spouse_lastname" class="required" name="spouse_lastname" <?php if (!empty($_POST['spouse_lastname'])) {echo "value=\"" . htmlspecialchars($_POST["spouse_lastname"]) . "\"";} ?> />
            </td>
            <td>
                <label class="required" for "spouse_birthdate">Spouse Date of Birth</label>
                <input type="text" id="spouse_birthdate" class="required date" name="spouse_birthdate" <?php if (!empty($_POST['spouse_birthdate'])) {echo "value=\"" . htmlspecialchars($_POST["spouse_birthdate"]) . "\"";} ?> />
            </td>
        </tr>
        <tr>
            <td>
                <label class="required" for "spouse_birthplace">Spouse Location Of Birth</label>
                <input type="text" id="spouse_birthplace" class="required" name="spouse_birthplace" <?php if (!empty($_POST['spouse_birthdate'])) {echo "value=\"" . htmlspecialchars($_POST["spouse_birthdate"]) . "\"";} ?> />
            </td>
            <td>
                <label class="required" for "md">Your Marriage Date</label>
                <input type="text" id="spouse_mar_date" class="required date" name="spouse_mar_date" <?php if (!empty($_POST['spouse_birthdate'])) {echo "value=\"" . htmlspecialchars($_POST["spouse_birthdate"]) . "\"";} ?> />
            </td>
        </tr>
    </table>
    </fieldset>
    </div>

Using "Self" and "Spouse" as examples, the relevant javascript code that hides/displays the appropriate fieldsets looks like this:

    if (document.getElementById("relation").selectedIndex == 0) {//self
        document.getElementById('parents').style.display = 'none';
        document.getElementById('grandparents').style.display = 'none';
        document.getElementById('gr_grandparents').style.display = 'none';
    }
    if (document.getElementById("relation").selectedIndex == 1) {//spouse
        document.getElementById('parents').style.display = 'none';
        document.getElementById('grandparents').style.display = 'none';
        document.getElementById('gr_grandparents').style.display = 'none';
        document.getElementById('spouse').style.display = 'block';
    }

// If error, show fieldset with error message
function showOnSubmit() {
    if (document.getElementById("relation").selectedIndex == 1) {//spouse
        var valid = <?php echo $Svalid; ?>;
        spouse = document.getElementById('spouse').value;
        if (valid = 'false') {
            document.getElementById('spouse').style.display = 'block';
        }
        return false;
    }
}

The server side PHP code to check for errors on submitting the form:

<?php
if((isset($_POST['submit']))){
    $valid = true;
    if(empty($_POST['spouse_firstname'])){
        $valid=false;
        $spouse_firstnameError = "Your spouse's first name is missing.".PHP_EOL;
        $spouse_firstnameError = nl2br($spouse_firstnameError);
    }
    if(empty($_POST['spouse_lastname'])){
        $valid=false;
        $spouse_lastnameError = "Your spouse's last name is missing.".PHP_EOL;
        $spouse_lastnameError = nl2br($spouse_lastnameError);
    }
    if(empty($_POST['spouse_birthdate'])){
        $valid=false;
        $spouse_birthdateError = "Your spouse's birthdate is missing.".PHP_EOL;
        $spouse_birthdateError = nl2br($spouse_birthdateError);
    }
    if(empty($_POST['spouse_birthplace'])){
        $valid=false;
        $spouse_birthplaceError = "Your spouse's birthplace is missing.".PHP_EOL;
        $spouse_birthplaceError = nl2br($spouse_birthplaceError);
    }
    if(empty($_POST['spouse_mar_date'])){
        $valid=false;
        $spouse_mar_dateError = "Your spouse's marriage date is missing.".PHP_EOL;
        $spouse_mar_dateError = nl2br($spouse_mar_dateError);
    }
}

At the moment, inline validation works. If any form fields are empty or invalid, on submit the form reloads with the appropriate error messages except that (using spouse as shown here as an example), if there are error messages for that fieldset, the messages appear, but the fieldset is hidden again unless the user once again selects the relationship. I want the fieldset(s) with errors to automatically redisplay when the form reloads. How can I make that happen?

  • So if I'm understanding correctly, the user chooses to show a fieldset for example via Javascript, but submits an overall invalid form, and when PHP returns its errors on a fresh page, you want the Javascript choices the user made before to automatically reappear? – symlink Jun 03 '23 at 14:16
  • "large parts of both files are cut due to length" this is still way too much: you are welcome to post a giant wall-o-code but very few people (especially the people you would *want* an answer from) will bother to read it. Please strip this down to a [minimal reproduction case](https://stackoverflow.com/help/minimal-reproducible-example). – Jared Smith Jun 03 '23 at 14:20
  • @symlink, yes, you understand correctly. Please see the reworded question. If a fieldset is displayed based on the relationship selected and that fieldset returns errors on submit, I want the fieldset to be redisplayed automatically with the error messages. – HeatherFeuer Jun 03 '23 at 18:04

2 Answers2

0

First: you should reconsider using table for layout

Second: you should reconsider using inline CSS everywhere

Third: your server side php code already know which part is invalid, it can also show that part, like this:

function showInfoDiv(id) {
  document.querySelectorAll('.info:not(.has-error)').forEach((div) => {
    div.classList.add('hidden');
  })
  document.getElementById(id).classList.remove('hidden');
}
.hidden {
  display: none;
}

.error-message {
  color: red;
}

.has-error fieldset {
  border-color: red;
  /*orther style for invalid fieldset*/
}
<?php 
  $valid_spouse = false; 
  /*you server side validation logic here*/
 ?>
<form>
  <div class="error-message">
    <?php /*echo "your error messages here";*/ ?>
  </div>
  <div id="spouse" class="info <?php echo ($valid_spouse?'hidden':'has-error');?>">
    <fieldset>
      <legend>Spouse's Information</legend>
    </fieldset>

  </div>

  Examples:
  <div class="error-message">
    Error message
  </div>
  <div id="parents" class="info has-error">
    <fieldset>
      <legend>Parents' Information</legend>
      This div has error and will be showed
    </fieldset>
  </div>
  <div class="error-message"></div>
  <div id="grandprents" class="info hidden">
    <fieldset>
      <legend>Grandparents' Information</legend>
      This div won't be showed (it will be after clicking that button)
    </fieldset>
  </div>
  <div class="error-message"></div>
  <div id="sisters" class="info hidden">
    <fieldset>
      <legend>Sisters' Information</legend>
      This div won't be showed (it will be after clicking that other button)
    </fieldset>
  </div>
</form>
<button onclick="showInfoDiv('grandprents')">Show Grandparents div </button>
<button onclick="showInfoDiv('sisters')">Show Sisters div </button>
haolt
  • 353
  • 1
  • 9
0

Way I would do it is set a session var on the server if the fieldset has errors (meaning it was selected), then use a ternary in the HMTL to add a "prevSelected" class so you can show the fieldset via CSS:

PHP

if(//fieldset_a_errors)
{
  $_SESSION["fieldset_a_errors"] = true;
}

HTML

<fieldset name="a" class="<?php $_SESSION['fieldset_a_errors'] ? 'prevSelected':''; ?>" >
//form fields
</fieldset>
symlink
  • 11,984
  • 7
  • 29
  • 50