I searched widely to find a solution for this, and eventually had to realise (as others have before me) that a form will always reset to the values with which it is loaded.
So my solution is to load the form with empty values, and then use pure Javascript to update the values from other hidden inputs. It requires one hidden input, and one line of JS, for each user input. My example below shows the code for just one input. Any further inputs follow the same pattern.
The input (I have omitted the label for clarity):
<li>
<input type="text" name="firstname" id="firstname" value='' tabindex="1" size="45" />
</li>
The hidden input:
<input type = 'hidden' id = 'jfn' name = 'jfn' value = '<?php echo $firstname; ?>' />
The Javascript (in the 'onload' or (if jQuery is available, 'document ready') function)':
document.getElementById('firstname').value = document.getElementById('jfn').value;
When the form is submitted the inputs (in $_POST) are saved to SESSION, whence they can be recalled for as long as the SESSION lasts:
foreach ($_POST as $name=>$value) {
$_SESSION['email'][$name] = $value;
}
and later recovered:
if (!empty($_SESSION['email'])) {
extract ($_SESSION['email']);
}
When/if the form is reloaded, the input values are initially empty. The previously input values are loaded into the hidden inputs. After the page has reloaded those values are transferred to the (visible) inputs. The 'Reset' button will now clear the form.