You may have already experienced this, and I know that I experienced it before, but I experienced it again and forgot about it, and so I figure it would be a good time to blog about it.  (When I blog, I remember things better).  If you happen to use the using syntax with Html.BeginForm as in the following partial view (or view as well):

<% Html.BeginForm(“JQueryCustomIndex”, “RenderingActions”); %>
 <%= ViewData[“CustomMessage”] %>
  
 <div>
  Name: <%= Html.TextBox(“CustomName”)%>
 </div>
 <div>
  Value: <%= Html.TextBox(“CustomValue”)%>
 </div>
 
 <input type=”submit” value=”save” />
<% Html.EndForm(); %>

If you use JQuery to refresh this partial view’s UI entirely, you may experience an issue with the form rendering.  In my example, I use Html.Action to inject this partialview into another form, then use JQuery to update this form’s content.  In the master view (the one that injects the partial view into it), I use JQuery to refresh it; you have to put the JavaScript in the main view, because the refreshed partial view does not run its JavaScript.  If you want more details on that, please leave me a comment or tweet me at @brianmains, and I’ll blog about it.

I use this to update the partial view.  A wrapper DIV is used (JQueryCustomParent) to minimize the scope in which I find the partial view’s form, and when the submit button is clicked, and async post is made to the server.  It works great.

function attachToForm() {
 $(“#JQueryCustomParent”).find(“input[type=’submit’]”).live(‘click’, function(e) {
  e.preventDefault();
  e.stopPropagation();

  var form = $(“#JQueryCustomParent”).find(“form:first”);
  $.post(form.attr(“action”), form.serialize(), function(data) {
   $(“#JQueryCustomParent > div:first”).replaceWith($(“<div/>”).html(data));
   attachToForm();
  });
 });
}

$(document).ready(function() {
 attachToForm();
});

It works great, except for one thing: (using Html.BeginForm()) expires too soon; the form is disposed and the ending </form> tag is rendered at a bad place in the markup, which means either none or a part of the form actually posts back.  Switching to:

<% Html.BeginForm(..); %>

<% Html.EndForm(); %>

Remedies this.