0

I have a view showing some user information displayed using a partial view. I have to include the possibility to update that info with a popup window. I'd also like my popup to use a partial view.

I want to have the user info refreshed if everything went right when saving or I want the popup to display the validation errors if any.

I tried to do so using a telerik window for my popup.

Everything works fine exept when validation errors occur. In that case, instead of remaining as a popup, the edition partial view gets populated in the target div, replacing my user info with my edition view.

How should I work this out?

here is the main view :

@model Models.UserModel

@* Div Containing the user info partial view that needs to be refreshed*@
<div id="UserInfo">
    @{Html.RenderAction("_DisplayUserInfo", new { UserToDisplayId = Model.UserId }); }
</div>

@* link to open the edition popup *@    
<p>
    @Ajax.ActionLink("Edit","_EditUser",new { UserToEditId = Model.UserId}, new AjaxOptions { UpdateTargetId = "EditUser",
                                                                                   InsertionMode = InsertionMode.Replace,
                                                                                   OnSuccess= "openPopup()",
                                                                                   HttpMethod = "GET"}
    )
</p> 

@* Telerik window used as popup to display the edit partial view *@
@{  Html.Telerik().Window()
        .Name("EditWindow")
        .Title("Edit Controller info")
        .Content(@<text>
            @using (Ajax.BeginForm("_EditUser", new AjaxOptions { HttpMethod = "Post"
                                                                          ,UpdateTargetId = "UserInfo"                                                                          
                                                                          ,OnSuccess = "closePopup()"}))
            {                                  
                <div id="EditUser">

                </div>                                              
            }
            </text>)
        .Width(400)
        .Draggable(true)
        .Modal(true)
        .Visible(false)
        .Render();
} 

<script type="text/javascript">

    function openPopup() {        
        $('#EditWindow').data('tWindow').center().open();
    }

    function closePopup() {
        var window = $("#EditWindow").data("tWindow");
        window.close();
    }

</script>

here is the partial view displaying the user info:

@model Models.UserModel

<div>
    <h2>@Html.DisplayFor(model => model.FirstName) @Html.DisplayFor(model => model.LastName) </h2> 
    @Html.DisplayFor(model => model.JobTitle)
    <br />@Html.DisplayFor(model => model.Email)
</div>    

here is the partial view used for Edition:

@model Models.UserModel

<fieldset>
    <legend></legend>

    @Html.HiddenFor(model => model.UserId)

    <div id="1" class="control-group">
        @Html.LabelFor(model => model.Email)
        @Html.EditorFor(model => model.Email)
        @Html.ValidationMessageFor(model => model.Email)
    </div>

    <div id="2" class="control-group">
        @Html.LabelFor(model => model.JobTitle)
        @Html.EditorFor(model => model.JobTitle)
        @Html.ValidationMessageFor(model => model.JobTitle)
    </div>

    <p id="5" class="form-actions">
        <input type="submit" value="Save"  />       
        <input type="button" value="Cancel" onclick="closePopup()" />     
    </p>  

</fieldset>

and here is my controller

public ActionResult _DisplayUserInfo(decimal UserToDisplayId)
{
    // here i build my model 
    //....
    // and send it back to the partial view
    return PartialView(MyUserToDisplay);
}

[HttpGet]
public ActionResult _EditUser(decimal UserToEditId)
{
    // here i build my model 
    //....
    // and send it back to the partial view
    return PartialView(MyUserToEdit);
}

[HttpPost]
public ActionResult _EditUser(UserModel UserToEdit)
{
    if (!ModelState.IsValid)
    {
    //Im guessing this is where I am doing it wrong
        return PartialView(CToEdit);
    }

    //here i save
    //...
    //and redirect
    return RedirectToAction("_DisplayUserInfo", new { UserToDisplayId = CToEdit.UserId });

}
DonQi
  • 409
  • 2
  • 6
  • 10

1 Answers1

0

So! after hours of struggling here is my solution! not sure if it is the right way but it does whay I want!

in the main view, instead of redirecting the ajax form result to the first partial view (the one displaying the user info), I redirect it to the div that contains the popup (I know, that first step was obvious but it took me hours to figure it out...)

so here is the change of the "UpdateTargetId" :

@* Telerik window used as popup to display the edit partial view *@
@{  Html.Telerik().Window()
        .Name("EditWindow")
        .Title("Edit Controller info")
        .Content(@<text>
            @using (Ajax.BeginForm("_EditUser", new AjaxOptions { HttpMethod = "Post"
                                                                          ,UpdateTargetId = "EditUser"                                                                          
                                                                          ,OnSuccess = "closePopup()"}))
            {                                  
                <div id="EditUser">

                </div>                                              
            }
            </text>)
        .Width(400)
        .Draggable(true)
        .Modal(true)
        .Visible(false)
        .Render();
} 

Then I modified the popup partial view to add a hidden input containing whether the modelstate is valid or not :

@Html.Hidden("MytestField",ViewData.ModelState.IsValid)

and finally i modified the ClosePopup() function in order to only close the popup when modelstate is valid and added an ajax request to refresh the UserInfo partial view :

function ManagePopup() {

if ($('MytestField').val() == 'True') {
    var window = $('#EditWindow').data('tWindow');
    window.close();
}

$.ajax({
    type: 'GET',
    url: '/UserController/_DisplayUserInfo',
    data: { UserToDisplayId : '@Model.UserId' },
    cache: false,
    success: function (result) {
        $('#UserInfo').html(result);
    }
});

}

DonQi
  • 409
  • 2
  • 6
  • 10