62

I have tried to different ways to clear a form:

<form action="service.php" id="addRunner" name="addRunner" method="post">
First Name: <input type="text" name="txtFirstName" id="txtFirstName" /><br />
Last Name:  <input type="text" name="txtLastName" id="txtLastName" /><br />
Gender: <select id="ddlGender" name="ddlGender"><option value="">--Please Select--</option>
<option value="f">Female</option>
<option value="m">Male</option>
</select><br />
Finish Time:
<input type="text" name="txtMinutes" id="txtMinutes" size="10" maxlength="2">(Minutes)
<input type="text" name="txtSeconds" id="txtSeconds" size="10" maxlength="2">(Seconds)
<br />
<button type="submit" name="btnSave" id="btnSave">Add Runner</button>
<input type="hidden" name="action" value="addRunner" id="action">
</form>

jQuery #1:

function clearInputs(){
$("#txtFirstName").val('');
$("#txtLastName").val('');
$("#ddlGender").val('');
$("#txtMinutes").val('');
$("#txtSeconds").val('');
}

This works perfectly.

jQuery #2:

function clearInputs(data){
$("#addRunner :input").each(function(){
$(this).val('');
});

This clears the form but does not let me submit any more any information to it. I try and click the button again and it does nothing.

Here's the button click handler:

$("#btnSave").click(function(){
    var data = $("#addRunner :input").serializeArray();
    $.post($("#addRunner").attr('action'), data, function(json){
        if (json.status == "fail"){
            alert(json.message);
        }
        if (json.status == "success"){
            alert(json.message);
            clearInputs();
        }
    }, "json");
});

PHP Post code:

<?php
if($_POST){ 
    if ($_POST['action'] == 'addRunner') {
        $fname = htmlspecialchars($_POST['txtFirstName']);
        $lname = htmlspecialchars($_POST['txtLastName']);
        $gender = htmlspecialchars($_POST['ddlGender']);
        $minutes = htmlspecialchars($_POST['txtMinutes']);
        $seconds = htmlspecialchars($_POST['txtSeconds']);
        if(preg_match('/[^\w\s]/i', $fname) || preg_match('/[^\w\s]/i', $lname)) {
            fail('Invalid name provided.');
        }
        if( empty($fname) || empty($lname) ) {
                fail('Please enter a first and last name.');
        }
        if( empty($gender) ) {
            fail('Please select a gender.');
        }
        if( empty($minutes) || empty($seconds) ) {
            fail('Please enter minutes and seconds.');
        }
        $time = $minutes.":".$seconds;

    $query = "INSERT INTO runners SET first_name='$fname', last_name='$lname', gender='$gender', finish_time='$time'";
    $result = db_connection($query);

    if ($result) {
        $msg = "Runner: ".$fname." ".$lname." added successfully" ;
        success($msg);
    } else {
        fail('Insert failed.');
    }
    exit;
}

}

If I use jQuery method #2, I get this error in the console:

Uncaught TypeError: Cannot read property 'status' of null

Why does this happen?

I forgot to include this key information:

function fail ($message){
    die(json_encode(array('status'=>'fail', 'message'=>$message)));
}

function success ($message){
    die(json_encode(array('status'=>'success', 'message'=>$message)));

This sends the message back to the AJAX function in jQuery. It looks like after I submit the form once using method #2 the success/fail messages are blanked out.

djphinesse
  • 969
  • 1
  • 7
  • 13
  • 1
    Some HTML would help, while your PHP is unnecessary in this context. – vzwick Oct 17 '11 at 10:20
  • Show your form's HTML please. – spicavigo Oct 17 '11 at 10:21
  • Also, your code might be vulnerable to [SQL Injection](http://stackoverflow.com/questions/332365/xkcd-sql-injection-please-explain). I better not submit `Robert'; DROP TABLE runners; --` as my first name … – vzwick Oct 17 '11 at 10:21
  • @vzwick Nope that doesn't work, so I guess I am safe :) This takes care of some basic SQL injection: $fname = htmlspecialchars($_POST['txtFirstName']); – djphinesse Oct 17 '11 at 12:54
  • This too: if(preg_match('/[^\w\s]/i', $fname) || preg_match('/[^\w\s]/i', $lname)) { fail('Invalid name provided.'); – djphinesse Oct 17 '11 at 12:56
  • @CharlesBlackwell Whoops, missed that part. Never mind ;) – vzwick Oct 17 '11 at 14:05
  • I figured out what it was! When I cleared the fields using the each() method, it also cleared the hidden field which the php needed to run: if ($_POST['action'] == 'addRunner'). I used the :not() on the selection to stop it from clearing the hidden field. – djphinesse Oct 18 '11 at 03:45

5 Answers5

153

Demo : http://jsfiddle.net/xavi3r/D3prt/

$(':input','#myform')
  .not(':button, :submit, :reset, :hidden')
  .val('')
  .removeAttr('checked')
  .removeAttr('selected');

Original Answer: Resetting a multi-stage form with jQuery


Mike's suggestion (from the comments) to keep checkbox and selects intact!

Warning: If you're creating elements (so they're not in the dom), replace :hidden with [type=hidden] or all fields will be ignored!

$(':input','#myform')
  .removeAttr('checked')
  .removeAttr('selected')
  .not(':button, :submit, :reset, :hidden, :radio, :checkbox')
  .val('');
Community
  • 1
  • 1
Xavier
  • 8,244
  • 18
  • 54
  • 85
  • 20
    I would suggest to remove the "checked" and "selected" attributes right after selecting the input, then filter out :button, :submit, :reset, :hidden, :radio and :checkbox to set the remaining inputs' value to "". Otherwise you will find yourself with checkboxes and radios that don't have any values after the clearing. So it goes like this: $(':input', '#myform') .removeAttr('checked') .removeAttr('selected') .not(':button, :submit, :reset, :hidden, :radio, :checkbox') .val(''); – Michael Ekoka Oct 02 '12 at 15:31
  • 1
    You should in fact use the "reset()" method in native javascript. @see jwaern answer. If you are not good with javascript, you can still $('whatever-the-selector-is').get(0).reset(). Clean, won't remove values from radio button and checkboxes, takes only one line of javascript, probably faster than this solution. – Bene May 22 '15 at 15:16
19

I'd recomment using good old javascript:

document.getElementById("addRunner").reset();
jwaern
  • 643
  • 5
  • 16
  • @James You don't need the `#` for `getElementById()`, it's only used for *selector strings* in things like jQuery's `$(...)` or the native JS equivalent `querySelectorAll(...)`. – MTCoster Jun 08 '16 at 10:38
4

Took some searching and reading to find a method that suited my situation, on form submit, run ajax to a remote php script, on success/failure inform user, on complete clear the form.

I had some default values, all other methods involved .val('') thereby not resetting but clearing the form.

I got this too work by adding a reset button to the form, which had an id of myform:

$("#myform > input[type=reset]").trigger('click');

This for me had the correct outcome on resetting the form, oh and dont forget the

event.preventDefault();

to stop the form submitting in browser, like I did :).

Regards

Jacko

Jacko
  • 72
  • 5
2

You may try

$("#addRunner input").each(function(){ ... });

Inputs are no selectors, so you do not need the : Haven't tested it with your code. Just a fast guess!

Eran
  • 387,369
  • 54
  • 702
  • 768
madc
  • 1,674
  • 2
  • 26
  • 41
0

I figured out what it was! When I cleared the fields using the each() method, it also cleared the hidden field which the php needed to run:

if ($_POST['action'] == 'addRunner') 

I used the :not() on the selection to stop it from clearing the hidden field.

djphinesse
  • 969
  • 1
  • 7
  • 13