views:

935

answers:

2

I have a View for creating a new account in my aopplication. This view starts with Html.BeginForm() and hits the right controller (Create) no problems.

I decided to add an Ajax.BeginForm() so that I could make sure an account with the same name doesn't already exist in my application.

When I click the submit using either button it goes to the same controller (Create). To try and differentiate which submit button was clicked, I put in a check to see if the request is Ajax then try to run a different code path. But Request.IsAjaxRequest() doesn't fire. What is my best bet to implement this funtionality in an existing form with MS Ajax?

<% using (Html.BeginForm()) {%>
           ..............
  <% using(Ajax.BeginForm("Echo", 
     new AjaxOptions() { UpdateTargetId = "EchoTarget" })) 
  { %>    
     Echo the following text: 
  <%=Html.TextBox("echo", null, new { size = 40 })%>
  <input type="submit" value="Echo" />
  <% } %>   
  <div id="EchoTarget">

controller code:

[AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(User newUser)
    {
        if (Request.IsAjaxRequest())
        {
            return Content("*you hit the ajax button");
        }
        else
        { //regular create code here.....
        }
  </div>
+2  A: 

You cannot nest forms, ever, in any HTML page, no matter how you generate the form. It isn't valid HTML, and browsers may not handle it properly. You must make the forms siblings rather than children.

Craig Stuntz
Yes, that fixes it. Thanks for the clarification!Now, my original problem remains, how do I put a button inside that first form that can run off and execute a controller without a postback?
Mouffette
You can do it with JavaScript. (I.e., a button with an onclick handler.) Or you can put the forms next to each other instead of one inside the other.
Craig Stuntz
Or some absolute positioning voodoo to drop form b inside form a.
Wyatt Barnett
+2  A: 

If you insist on multiple form usage..use Javascript in a some function like this

<SCRIPT>
  function InnerFormSubmitter(dataForm, actionForm) {
  actionForm.innerHTML = dataForm.innerHTML;
  actionForm.submit();      
 }
</SCRIPT>

<form name="yourButton" action="ValidateSomething" method="post"></form>

<form name="mainForm" action="SavedData" method="post">
<input type="textbox" name="text1">
<input type="textbox" name="text2">
<button name="validateUserButton" id="FormButton" onChange=
"InnerFormSubmitter  (this.form, document.getElementById('yourButton'))">

</button>
  </form>

Hope this helps!

Addendum on jQuery usage for your scenario:

Since you wanted a link:

<a href="javascript:isValidUser(<%=Model.USerId%>);">Check Availability</a>


function isValidUser(userId) { 
var url = "<CONTROLLER>/<ACTION>/" + userId; 
$.post(url, function(data) { 
    if (data) { 
        // callback to show valid user 
    } else { 
        // callback to show error/permission 
    } 
}); 
}

And you controller should have:

[AcceptVerbs("POST")] 
public bool IsValidUser(int id) { 
 // check availability 
 bool allow = CheckUser(); 

 // if allow then insert 
 if (allow) { 
    //insert user

    return true; 
 } else { 
    return false; 
 } 
}

Further Update on jQuery:

Instead of

document.getElementById('UserIdent').value

you can use

$('#UserIdent').val();

Update on JSON usage

The JsonResult class should be used in the Controller and $.getJson function in the View.

$(function() {
    $('#yourLinkOrButton').click(function() {
        $.getJSON("<CONTROLLER>/GetUserAvailability/", null, function(data) {
            $("#yourDivorLablel").<yourFunctionToUpdateDiv>(data);
        });
     });

  public JsonResult GetUserAvailability()
    {
        //do all validation and retrieval
  //return JsonResult type

    }
Shankar Ramachandran
You could also explore the possibility of using Iframes. http://ajaxpatterns.org/IFrame_Call
Shankar Ramachandran
Multiple forms are really not a problem. It's only nesting them that's an issue, and that's essentially never necessary. If you're going to resort to JS, you may as well just concoct a POST directly instead of using an HTML form, though.
Craig Stuntz
The consummate elegant solution is to use JSON request mechanism after hooking jQuerypowerhorse to the MVC cart!
Shankar Ramachandran