8

Context
Let`s say i have:
In layout Site.Master:

<div class="leftColumn">
    <asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
<div class="rightColumn">
    <% Html.RenderPartial("_Login"); %>
    <asp:ContentPlaceHolder ID="SideContent" runat="server" />
</div>

Login partialView looks like:

<form action="/myApp/Account/Login" method="post">
    <input name="name" />Name<br />
    <input name="password" type="password" />Password<br />
    <button>Login</button>
</form>

Is it possible to update only login widget form, not the entire content page?

Arnis Lapsa
  • 45,880
  • 29
  • 115
  • 195

5 Answers5

15

If you are referring to a http post, only a post initiated (it can also be initiated by javascript) by a submit button from within the form will be posted to the server.

If your forms are nested then this won't work. The outer form will always post to the server.

In the sample HTML below, clicking on the submit button on the first form will not send the values from the second form to the server. Likewise, clicking the second submit button won't post the values from the first form.

<html>
...
  <body> 
    <div>

      <form action="/Login/Login" method="post">
        <input type="text" name="username" value="" />
        <input type="text" name="passowrd" value="" />
        <input type="submit" name="login" value="Login" />
      </form>


      <form action="/Login/AdminLogin" method="post">
        <input type="text" name="username" value="" />
        <input type="text" name="passowrd" value="" />
        <input type="submit" name="login" value="Login Admin" />
      </form>
    </div>
</body>
</html>

If you only wish to update/change one of the form section, then no this can not be done without using javascript and performing a javascript post(aka Ajax).

Chuck Conway
  • 16,287
  • 11
  • 58
  • 101
  • 1
    Yay... Despite that question surely was unclear, this is exactly what i wanted to hear: "If you only wish to update/change one of the form section, then no this can not be done without using". So far it seems, that there aren`t a clean way to implement so called widgets in asp.net mvc. :/ – Arnis Lapsa May 05 '09 at 07:58
  • This isn't a limitation of MVC - you are asking to update part of the page only so you have to do something client side (e.g. AJAX/JS) as ALL HTML forms by their definition will change page when submitted. – Matt Mitchell May 22 '09 at 04:30
  • Question just hit 'popular' badge mark. Amazingly to see how much I've learned. Such a stupid question. :D – Arnis Lapsa Mar 13 '10 at 13:27
1

If you have two simple forms, you can use this aproach:

You create two different partial views.

@model CustomerInfoModel
@using (Ajax.BeginForm("CustomerInfo", "Customer", new AjaxOptions { HttpMethod = "Post", OnBegin = "InfoLoading", OnComplete = "InfoCompleted" }, new { id = "info", @class = "form-horizontal" }))
    {
    <input type="text" class="form-control" name="Name" id="Name" value="@Model.Name" />
    <input type="email" class="form-control" name="Email" id="Email"  value="@Model.Email" />
    <button type="submit" id="save-info" class="btn-medium red">Save</button>
    }

and

@model CustomerPasswordChangeModel
@using (Ajax.BeginForm("CustomerPasswordChange", "Customer", new AjaxOptions { HttpMethod = "Post", OnBegin = "InfoLoading", OnComplete = "InfoCompleted" }, new { id = "change", @class = "form-horizontal" }))
{
<input type="password" class="form-control" name="OldPassword" id="OldPassword"  value="" />
<input type="password" class="form-control" name="NewPassword" id="NewPassword"  value="" />
<button type="submit" id="save-change" class="btn-medium red" autocomplete="off">Save</button>
}

In your parent view,

@Html.Partial("CustomerInfo", Model.CustomerInfo)

and

@Html.Partial("CustomerPasswordChange", Model.CustomerPasswordChange)

In Controller:

    [HttpPost]
    public ActionResult CustomerInfo([Bind(Include = "Name,Email")] CustomerInfoModel model)
    {
        if (ModelState.IsValid)
            return new Json(new { success=true, message="Updated.", errors=null);

// do you logic

        return new Json(new { success=false, message="", errors=getHtmlContent(ModelState.Values.SelectMany(v => v.Errors).ToList(), "ModelError"));
    }

    [HttpPost]
    public ActionResult CustomerPasswordChange([Bind(Include = "OldPassword,NewPassword")] CustomerPasswordChangeModel model)
    {
        if (ModelState.IsValid)
            return new Json(new { success=true, message="Updated.", errors=null);

// do you logic

        return new Json(new { success=false, message="", errors=getHtmlContent(ModelState.Values.SelectMany(v => v.Errors).ToList(), "ModelError"));
    }

This will do what you want to do.

Note: getHtmlContent method is just generating an error message to be displayed on page. Nothing so special. I may share it if required.

hakan
  • 3,284
  • 2
  • 19
  • 25
1

If you build a controller method that accepts a FormCollection and your view has two forms defined, the formcollection returned will either be populated with values from form A or form B. You can inspect the formCollection and branch your logic based on the value therein. If you want the be very explicit you could have the same hidden variable occur in both forms with a value that would help your make your choice.

That's one approach. there are a few ways to deal with this I'm sure.

MarkDav.is
  • 640
  • 1
  • 8
  • 16
0
if(pass != true) 
{ 
 ViewData["Message'] = "Hey your login failed!"; Return View("Login") 
}

On ViewPage

<form action="/tralala/Account/Login" method="post"> 
  <input name="name" />Name<br /> 
  <input name="password" type="password" />Password<br /> 

  <button>Login</button> 
 <div style="color: red"><%=ViewData["Message"] %><div> 
</form>
gideon
  • 19,329
  • 11
  • 72
  • 113
Skiltz
  • 544
  • 1
  • 6
  • 18
  • 1
    You missed the point. Question was - how to update 1 form only, if that is possible, not how to use ViewData dictionary. – Arnis Lapsa May 05 '09 at 00:45
  • Sorry dude, I keep reading your question and I don't understand what you are asking. – Skiltz May 05 '09 at 00:54
  • 1
    I`m just asking, if page with 2
    elements can update only 1 of them at the time, not touching the other one.
    – Arnis Lapsa May 05 '09 at 01:01
0

Your question is not very clear.

But as far as I could understand, the answer is most likely yes. You can update anything you want depending on the user input.

Çağdaş Tekin
  • 16,592
  • 4
  • 49
  • 58
  • I also don't understand what you are asking... can you please edit your question to give some more context. Your first 'form' is badly formed and doesn't have any input elements... What is it for? I thought that the modelviewstate only updates the fields that it tried to bind...? Is that a login widget or a login page? Or are you having issues with the Validation Messages and validation highlighting? I had to create some custom HTMLHelper extensions to handle multiple forms but I really don't know if they apply here because I can't understand what your problem is... some more info would help. – Charlino May 05 '09 at 01:28
  • I'm really sorry. English is not my native too. I'll try to edit question. – Arnis Lapsa May 05 '09 at 06:49