views:

106

answers:

2

I am using jQuery1.4.2, ASP.NET MVC 2 and jQuery.UI-1.8.

I am creating a data input dialog which works OK when all the data is valid, but I want to validate the input data on the server and return an error to the dialog describing the error and I am not quite sure how to do that and keep the dialog open. The dialog is opened when a link is clicked. The solution may be to try to bypass more of the MVC framework's default binding that handles the submit button clicks and creates the expected ProfilePermission object and calls the Controller's AddPermission POST Action method, but I was hoping there may be an easier way without having to write more jquery/javascript code to handle the button clicks and pass the data to/from the server.

My script code looks like

$("#dialog").dialog({ modal: true,
    position: ['center', 180],
    width: 500,
    height: 130,
    autoOpen: false
});

$(".addPermissionDialog").click(function (event) {
    event.preventDefault();
    $("#dialog").dialog('open');
    return false;
});

My View

<div id="dialog" title="Add Permission">
<%: Html.ValidationSummary("") %>
<% using (Html.BeginForm("AddPermission", "Profile"))
{ %>
    <%: Html.Hidden("PersonId") %>
    <%: Html.Hidden("ProfileId") %>
    <div class="editor-label">
        <label for="PersonName">User Name:</label>
        <%: Html.TextBox("PersonName")%>
        <label for="PermissionType">Permission:</label>
        <select name="PermissionTypeId" id="PermissionTypeId" >
            <option value="2">Edit</option>
            <option value="3">View</option>
        </select>
    </div>
    <br />
    <p>
    <input type="submit" name="saveButton" value="Add Permission" />
    <input type="submit" id="cancelButton" name="cancelButton" value="Cancel" />
    <script type="text/javascript">
        document.getElementById("cancelButton").disableValidation = true;
    </script>
    </p>
<% } %>
</div>
<br />
<p>
    <%: Html.ActionLink("Add Permission", "AddPermission", new { profileId = Model.First().ProfileId }, new { @class = "addPermissionDialog" })%>
</p>

My Controller action

    [AcceptVerbs("Post")]
    [HandleError]
    public ActionResult AddPermission(string cancelButton, ProfilePermission profilePermission)
    {
        ViewData["Controller"] = controllerName;
        ViewData["CurrentCategory"] = "AddPermission";
        ViewData["ProfileId"] = profilePermission.ProfileId;

        PermissionTypes permission = repository.GetAccessRights(profilePermission.ProfileId);
        if (permission == PermissionTypes.View || permission == PermissionTypes.None)
        {
            ViewData["Message"] = "You do not have access rights (Edit or Owner permissions) to this profile";
            return View("Error");
        }

        // If cancel return to previous page
        if (cancelButton != null)
        {
            return RedirectToAction("ManagePermissions", new { profileId = profilePermission.ProfileId });
        }

        if (ModelState.IsValid)
        {
            repository.SavePermission(profilePermission);

            return RedirectToAction("ManagePermissions", new { profileId = profilePermission.ProfileId });
        }

        // IF YOU GET HERE THERE WAS AN ERROR
        return PartialView(profilePermission); // The desire is to redisplay the dialog with error message
    }

LATER EDIT I was hoping for a mechanism to return an error to the dialog using MVC's plumbing, I eventually broke down and added a save button via the jquery.ui.dialog API and handled the issue that way. I removed the buttons from the .aspx page. I returned return new EmptyResult(); from the controller's actions if everything worked OK and if there was an error Response.StatusCode = (int)HttpStatusCode.BadRequest; return Content(errorMessage, MediaTypeNames.Text.Plain);

    // To add a button and bypass more of MVC plumbing
    buttons: {
        "Save": function () {
            var dlg = $(this);
            $.ajax({
                url: "/Profile/AddPermission",
                type: 'POST',
                data: {
                    PersonId: $("#PersonId").val(),
                    ProfileId: $("#ProfileId").val(),
                    PermissionTypeId: $("#PermissionTypeId").val(),
                    PersonName: $("#PersonName").val()
                },
                success: function (data) {
                    dlg.dialog('close');
                },
                error: function (data) {
                    alert(data.responseText);
                }
            });
        }
    }
A: 

I would suggest changing the input type submit to a normal button and making an Ajax call on click of the button, to ensure that the dialog is not closed. Send data to the server using JsonValueProviderFactory from the MVC2 futures library based on Phils post. If the validation fails trap the error in the ajax error: option. If data is valid close the dialog from the Ajax complete: option. Hope this helps.

Nikhil
Thanks for the suggestion! I was just hoping there was a mechanism that allowed me to use a little bit more of the exising MVC plumbing...I wasn't aware of the JsonValueProvider factory. That looks very interesting. I'll give it a try...Thanks again.
Rick
+1  A: 

I was doing this kind of stuff using jquery.form and jquery dialog; in the post action if everything is good you return Content("OK") if not you return the PartialView() (that contains the modelstate errors) after in the function that handles the successful post response you check if it is "OK" close the dialog if not you set the $("#yourDialogDiv").html(responseHtmlThatYouGotFromTheServer)

Omu
Thanks, your solution will make life a lot easier......I appreciate the help!
Rick