Ricardo
Ricardo

Reputation: 169

MVC - Opening PartialView in a jquery dialog

I have a problem that's been driving me crazy for days. So I have an html table with items in it. The point is basically to click a button and open a jquery dialog with a message, asking me if I want to delete the selected item. Now the delete part can come next cause as it is I can't even display the dialog with the confirmation message. What I do is click one of the delete icons on my table to delete an item of my choosing, but as the partialview with the dialog finishes loading, jquery throws an undefined function error. The following pattern has already been implemented on another similar funcionality (table with clickable icon, shows dialog) but I can't find out whats wrong here.

Here's the code of the table in the "main" view.

<table width="100%" cellspacing="0" border="0" align="center" cellpadding="3"  
 style='table-layout: fixed'>
    <tr class="tr-header">
        <th width="20px">
            &nbsp;
        </th>
        <th width="200px">
            File Name
        </th>
        <th width="120px">
            Type
        </th>
        <th width="130px">
            Date
        </th>
        <th width="480px">
            Comments
        </th>
    </tr>
    @foreach (var item in Model.Uploads)
    {
        <tr>
        <td align="center">
            @using (Ajax.BeginForm("DeleteUpload", "Candidate", 
                                   new { id = item.UploadID }, 
                                   new AjaxOptions { UpdateTargetId = 
                                                    "DeleteUploadForm", 
                                                     HttpMethod = "Get" }))
            {
                @*<a href='@Url.Action("DeleteUpload", new { id = item.UploadID })'>
                <img src="@Url.Content("~/icons/delete.png")" alt="Click to delete upload" border="0" /></a>*@
                <input type="image" name="DeleteUpload" id="DeleteUpload" src="@Url.Icon("delete.png")"/>
            }
            </td>
            <td align="center">
                @(item.FileName);
            </td>
            <td align="center" nowrap="nowrap">
                 @item.UploadType
            </td>
            <td align="center" nowrap="nowrap">
                 @item.UploadDate
            </td>
            <td align="justify" style="overflow:auto">
                        @Html.Raw(Html.Encode(item.Comments).Replace("\n", "<br />"))
                    </td>
                </tr>
            }
        </table>

<div id="DeleteUploadForm">
</div>

As you notice in the first column I have two ways of calling the controller commented, the one with the input image doesn't do a submit when I click it and the anchor link can call the controller and the partialview where I have the dialog, but jQuery library "crashes" when its all done.

This is the controller.

public ActionResult DeleteUpload(int id)
{
    Upload UploadToDelete = CandidateProxy.GetUploadByID(this.CurrentUser.DbInfo, id);

    return PartialView(UploadToDelete);
 }

Nothing too spectacular there. Then it calls the following partial view.

@model Project.Entities.Uploads

<script src="@Url.Script("jquery.validate.min.js")" type="text/javascript"></script>           
<script src="@Url.Script("jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Script("jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="@Url.Script("ui/jquery.ui.core.js")" type="text/javascript"></script>
<script src="@Url.Script("ui/jquery.ui.widget.js")" type="text/javascript"></script>

<script src="@Url.Script("ui/jquery-ui-1.8.23.custom.js")" type="text/javascript"></script>
<script src="@Url.Script("ui/jquery.ui.mouse.js")" type="text/javascript"></script>
<script src="@Url.Script("ui/jquery.ui.button.js")" type="text/javascript"></script>
<script src="@Url.Script("ui/jquery.ui.draggable.js")" type="text/javascript"></script>
<script src="@Url.Script("ui/jquery.ui.position.js")" type="text/javascript"></script>
<script src="@Url.Script("ui/jquery.ui.resizable.js")" type="text/javascript"></script>
<script src="@Url.Script("ui/jquery.ui.dialog.js")" type="text/javascript"></script>
<script src="@Url.Script("ui/jquery.effects.core.js")" type="text/javascript"></script>
<script src="@Url.Script("dialog/DeleteUploadDialog.js")" type="text/javascript"></script>

<div="DeleteUploadDialog">
@using (Html.BeginForm("DeleteUpload", "Home", FormMethod.Post))
{
    <fieldset>
    <div>
    <br />
    Do you want to delete the following file? @Model.UploadName
    </div>
    <input type="submit" name="submit" value="Delete" class="toolbar-button" />
    <input type="button" name="submit" value="Cancel" class="toolbar-button" />
    </fieldset>
}

</div>

This is the partialview that holds the design for my dialog. It will eventually send to the Controller a request to delete an upload which is easy cause I'm more familiar with server-side coding but this whole front-end thing is very new to me. Finally here's the DeleteUploadDialog.js file where I have written the dialog's properties.

$(function () {
    $("#DeleteUploadDialog").dialog({
        autoOpen: true,
        modal: true,
        width: 950,
        height: 350,
        close: function (event, ui) {
            $("#DeleteUploadDialog").remove();
        }
    });
});

So that's my code. Anything else you'd like to know about it let me know. Thanks in advance!

Upvotes: 0

Views: 2342

Answers (3)

free4ride
free4ride

Reputation: 1643

I think that what you are trying to do here is an overhead. You are opening a dialog and removing it on close.. Wouldn't be simpler to do sth like this:

 $(buttonDelete).click(function () {
        var confirmDelete = confirm("Are you sure you want to delete this item?");
        if (confirmDelete === true) {
           $.ajax({
                url: '/Home/DeleteAttachment',
                dataType: "json",
                type: "POST",
                data: { "id": id },
                success: function () {
                    $(rowToDelete).remove();
                }
            });
        }
    });

and

     [HttpPost]
    public JsonResult DeleteAttachment(int id)
    {
        DeleteAttachment(id);
        return Json("ok");
    }

if you really want to return partial you can do sth like this:

$(buttonDelete).click(function () {
        var confirmDelete = confirm("Are you sure you want to delete this item?");
        if (confirmDelete === true) {
           $.ajax({
                url: '/Home/DeleteAttachment',
                dataType: "html",
                type: "POST",
                data: { "id": id },
                success: function (response) {
                    $(divId).replace(response);
                }
            });
        }
    });

and

    [HttpPost]
    public PartialViewResult DeleteAttachment(int id)
    {
        Upload UploadToDelete = CandidateProxy.GetUploadByID(this.CurrentUser.DbInfo, id);
        return PartialView(UploadToDelete);
    }

Upvotes: 1

Vipul
Vipul

Reputation: 1583

Making a server round trip just for confirmation is not a good idea. you can take confirmation on client side using below custom confirmation dialog. This will not block your script execution also.

I have created custom confirmation box, you may try this:

function ConfirmationBox(pTitle, pText, pButtonType, pParam, pCallBack, pCancelCallback) {
    if (pButtonType == null) pButtonType = "okcancel";

    $('<div></div>').appendTo('body').html(pText)
    .dialog({
        resizable: false,
        modal: true,
        title: pTitle,
        buttons: GetButtons(pButtonType),
        autoOpen: true,
        width: 'auto'
        , Close: function (event, ui) {
            $(this).remove();
        }
    });

    $("input[type=submit], input[type=button]").button();
    $("#confirmDialog button").button();
    return this;
    function GetButtons(pButtonType) {
        var cBtn;
        switch (pButtonType) {
            case "yesno":
                cBtn = {
                    "Yes": function () {
                        if (pCallBack && pCallBack.length > 0) {
                            window[pCallBack](pParam);
                        }
                        $(this).dialog("close");
                        return true;
                    },
                    "No": function () {
                        if (pCancelCallback && pCancelCallback.length > 0) {
                            window[pCancelCallback](pParam);
                        }
                        $(this).dialog("close");
                        return false;
                    }
                }
                break;
            case "okcancel":
                cBtn = {
                    "Ok": function () {
                        if (pCallBack && pCallBack.length > 0) {
                            window[pCallBack](pParam);
                            $(this).dialog("close");
                        }
                        return true;
                    },
                    Cancel: function () {
                        if (pCancelCallback && pCancelCallback.length > 0) {
                            window[pCancelCallback](pParam);
                            $(this).dialog("close");
                        }
                        return false;
                    }
                }
                break;
        }
        return cBtn;
    }
}

Parameter details:

pTitle: Title of your dialog

pText: Text of dialog

pButtonType: Here we have 2 option yesno | okcancel

pParam: parameter to callback function

pCallBack: Success callback (function to call on "Yes" click)

pCancelCallback: Cancel callback (function to call on "No" click )

Upvotes: 1

MVCKarl
MVCKarl

Reputation: 1295

Shouldn't it be

autoOpen: false

instead of

autoOpen: true

Then in your click event something like

$("#DeleteUpload").click(function()
{
    $("#DeleteUploadDialog").dialog("open");
});

Upvotes: 0

Related Questions