简体   繁体   中英

Why does this jQuery reset method not work correctly?

I have a modal form that is loaded on click using jQuery. There is a reset button in the form that works like this:

$('input#reset').click(function() {
        $(':input', '#contactForm')
            .not(':submit, :reset, :hidden, :button')
            .val('')
            .removeAttr('checked')
            .removeAttr('selected');

        return false;
    });

This works fine. However I decided that I wanted the form to clear whenever the link is clicked. I copied the code over to my other click function and now it doesn't reset the form:

$('a.modal').click(function(){  
                    ...
        //show the contact form
        $('.success, .error, .success_header, .error_header').hide();
        $('form#contactForm,#contact_subhead').show();

        // Reset all the default values in the form fields

        $(':input', '#contactForm')
            .not(':submit, :reset, :hidden, :button')
            .val('')
            .removeAttr('checked')
            .removeAttr('selected');
             //this doesn't work

        //show the mask and contact divs
        $('#mask').show().fadeTo('', 0.7);
        $('div#contact').fadeIn();

    // stop the modal link from doing its default action
        return false;
    });

I've played around with the order show form->clear it, clear form->show it. But for some reason, even though I see it call the code using Firebug, it doesn't clear the form. I can put some stuff in the dialog, close it, click on the link to display the form again and see the old data.

Why isn't this working like I think it should? It is the same code isn't it?

EDIT: Providing more information

My dialog is css based so it isn't actually a jQuery dialog. Here is the relevant piece:

#contact {
background-color:#fff;
display:none;
left:50%;
margin-left:-300px;
position:absolute;
top:20px;
width:643px;
z-index:9999;
border-radius:2px;
-moz-border-radius:2px;
-webkit-border-radius:2px;
padding:3px;
}


#contactForm {
width: 350px;
margin-left: 20px;
position: relative;
top: -50px; 
float: left;
}

Here is the relevant HTML of the page.

<div id="contact">
<html:form action="/contactUs" styleId="contactForm">   
    <br /><html:text property="emailAddress" maxlength="30" style="width=30"/>
    <br /><html:errors property="emailAddress"/></p>        
    <div class="button_container">
        <p><input type="image" src="images/reset_btn.png" id="reset" name="reset" alt="Reset" onclick="ntptEventTag('ev=link&linkname=' + escape('contact form: Reset'));" />
        <html:image src="images/submit_btn.png" styleId="submit" onclick="ntptEventTag('ev=link&linkname=' + escape('contact form: Submit'));"></html:image></p>
    </div>

   </html:form>
</div>

EDIT

I included a jsfiddle to simulate the problem. See that clicking the link shows the input but doesn't clear it. It only clears it after the input is visible.

I assume the "..." in your code is where you omitted the dialog loading code. I think what's happening is that your clearing code is running at the wrong time. If you're using the jQueryUI modal utilize its 'open' event:

$('a.modal').click(function(){
  $('#yourmodal').dialog({
    open: function(event, ui) {
      $(this).find(':input', '#contactForm')
          .not(':submit, :reset, :hidden, :button')
          .val('')
          .removeAttr('checked')
          .removeAttr('selected');
    }
  });
  return false;
});

The code would be a little different if you're attaching the dialog at a different place but that's the general idea.

EDIT - So the trick here isn't actually the 'open' event but rather using the $.find() method. From what I can tell jQuery caches the DOM structure and when you invoke a dialog those DOM elements are copied, deleted, and moved elsewhere in the DOM tree. Since jQuery doesn't have those moved DOM elements in its cache you must use a method that forces a live search through the DOM (which is what find() is doing).

I solved the problem. It seems silly now when I look back on it. The .not(':hidden') was the issue. I was of the opinion that

$(':input')
.not(':submit, :reset, :hidden, :button')

would not match a text input that was set to display:none but apparently it does. Test this for yourself here : http://jsfiddle.net/rawsmell/pDe43/2/ , remove the :hidden and it works as expected.

<div id="contact">
    <input type="text" value="Test" />
   Other text 
</div>

CSS

#contact {
background-color:#fff;
display:none;
}

Onclick

 $(':input')
        .not(':submit, :reset, :button')
        .val('')
        .removeAttr('checked')
        .removeAttr('selected');
         //this DOES work

    $('div#contact').fadeIn();
    return false;

To sum up, the problem with the script is that an text input which is set to display:none can be selected using :hidden .

I suggest using the reset button for this.

<button type="reset">Reset</button>

And, you can trigger it manually on the form if you wish.

$("#contactForm")[0].reset();

Here's a fiddle: http://jsfiddle.net/Tentonaxe/cCg7t/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM