Display a modal popup div from controller

若如初见. 提交于 2019-12-12 09:46:49

问题


Can please someone help me here?! Thank you!

I have a view that displays a list of products along with an "Add Product" button for each. I am calling the CreateNewProduct method for each "Add Product" click to find the status of the product. Depending on the status, either I need to stay on the same view or I need to call a modal popup. I am able to do this by creating a modal popup in a different view. But I want to call the modal popup div (also pass the modal) from the same view where it displays a list of products. Is this possible?

public ActionResult CreateNewProduct(int productId)
{
    var sharedProduct = _productTemplateService.GetSharedProducts(productId);
    var _finalSharedProducts = (sharedProduct.Any(t => t.productId != productId));

    if (_finalSharedProducts)
    {
        var sharedProdctTemplate = _productTemplateService.GetSharedProduct(productId);
        return View("ModalView", new SharedModel
        {
            SharedProduct = sharedProdctTemplate
        });
    }
    else
    {
        _productTemplateService.CreateNewProduct(productId);
        return RedirectToAction("Details", "ProductTemplate");
    }
}

Model View Code

<div class="modal fade" id="myModal" role="dialog">
    <div class="modal-dialog">

        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Shared Product</h4>
            </div>
            <div class="modal-body">
                <div class="flex-row">
                    <div class="col-6">
                        <div class="d-flex flex-row">
                            <div class="p-2">Product ID</div>
                            <div class="p-2">Product Types</div>
                            <div class="p-2">Status</div>
                        </div>
                        @foreach (var productTemplate in Model.SharedProduct )
                        {
                            <div class="d-flex flex-row">
                                <div class="p-2">@productTemplate.ProductId</div>
                                <div class="p-2">@productTemplate.ProductType</div>
                                <div class="p-2">@productTemplate.StatusCode</div>
                            </div>
                        }
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>

    </div>
</div>

<p>
    @Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ }) |
    @Html.ActionLink("Back to List", "Index")
</p>
<script type="text/javascript">
    $(document).ready(function () {
        $('#myModal').modal('show');
    });
</script>

UPDATE: I made it working. This is what I did. At the end, I have mentioned issues I am facing.

Link, modal and script in my main view - Detail View (called from ProductTemplate Controller)

<td><a href="#" class="btn btn-sm btn-primary" onclick="loadModal('@productTemplate.productId,'@productTemplate.customerId')">Add New Product</a></td>


<div class="modal fade" id="mymodel" role="dialog" tabindex="-1">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Shared Products</h4>
                <button type="button" class="close" data-dismiss="modal">&times;</button>

            </div>
            <div class="modal-body" id="mymodelbody">

            </div>
        </div>
    </div>

<script>

        var loadModal = function (productId, customerId) {
            $.ajax({
                type: 'GET',
                url: '/NewProductTemplate/CreateNewProduct',
                cache: false,
                data: {
                    productId: productId,
                    customerId: customerId
                },
                dataType: 'html',
                success: function (data) {;
                    $("#mymodelbody").html(data);
                    $("#mymodel").modal("show");
                }
            });
        }
    </script>

NewProductTemplateController Code

public ActionResult CreateNewProduct(Guid productId, Guid customerId)
    {
        var sharedProduct = _productTemplateService.GetSharedProducts(productId);
        var _finalSharedProducts = (sharedProduct.Any(t => t.productId != productId));

        if (_finalSharedProducts)
        {
            var sharedProdctTemplate = _productTemplateService.GetSharedProduct(productId);
            return PartialView("_shared", new SharedModel
            {
                SharedProduct = sharedProdctTemplate
            });
        }
        else
        {
            _productTemplateService.CreateNewProduct(productId);
            return RedirectToAction("Details", "ProductTemplate");
        }
    }

Partial view _shared.view code

@model SharedModel
@using (Html.BeginForm("ShareProduct", "NewProductTemplate", FormMethod.Post))
{
    @Html.AntiForgeryToken()
   <div class="flex-row">
    <div class="col-6">
        <div class="d-flex flex-row">
            <div class="p-2">Product ID</div>
            <div class="p-2">Product Types</div>
            <div class="p-2">Status</div>
        </div>

        @for (var i = 0; i < Model.SharedProducts.Count(); i++)
        {
            @Html.HiddenFor(model => model.SharedProducts.ElementAt(i).ProductId)
            @Html.HiddenFor(model => model.SharedProducts.ElementAt(i).CustomerId)
            @Html.HiddenFor(model => model.SharedProducts.ElementAt(i).ProductType)
            @Html.HiddenFor(model => model.SharedProducts.ElementAt(i).StatusCode)
            @Html.HiddenFor(model => model.SharedProducts.ElementAt(i).IsShared)
            <div class="d-flex flex-row">
                <div class="p-2">@Html.DisplayFor(model => model.SharedProducts.ElementAt(i).ProductId)</div>
                <div class="p-2">@Html.DisplayFor(model => model.SharedProducts.ElementAt(i).ProductType)</div>
                <div class="p-2">@Html.DisplayFor(model => model.SharedProducts.ElementAt(i).StatusCode)</div>
                @if (Model.SharedProducts.ElementAt(i).StatusCode == VersionStatus.PUBLISHED)
                {
                    <div class="p-2">@Html.EditorFor(m => m.SharedProducts.ElementAt(i).IsShared)</div>
                }
            </div>
        }
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Save" class="btn btn-sm btn-primary" />
            <button type="button" class="btn btn-sm btn-primary" data-dismiss="modal">Close</button>
        </div>
    </div>
</div>

PROBLEM: 1) When I save submit button in modal pop-up (partial view), it calls ShareProduct method from NewProductTemplate controller. For some reason, model SharedModel's SharedProducts property is null when it gets to controller code. Can you please help me here why it gets null?

public ActionResult ShareProduct (SharedModel shareModel)
        {
           //Access ShareProducts from shareModel 
            return RedirectToAction("Details", "ProductTemplate");
        }

PROBLEM: 2) I want to load popup only if the product is shared, otherwise I just want to redirect to Detail view as mentioned in NewProductTemplate controller's CreateNewProduct method. Problem is that it loads Detail view also in popup if product is not shared since that's what my script is doing. Is there any way that I can check data in Success function before showing modal popup? If data/html contains Shared text, I would like to load the normal Detail view. I am just assuming. I tried to do so but with no success.

Detail method in ProductTemplate Controller

public ActionResult Details()
        {
            var productTemplate = _productTemplateService.GetAllProducts(User);
            return View(new DetailsModel
            {
                ProductTemplate = productTemplate,
             });
        }

回答1:


(This is for Bootstrap 3.3.7 Hopefully it's relevant for the version you're on) I handle this by popping open the modal on the client side from my main view. The link that pops the modal contains the URL to the controller method that will render the actual contents (list of products, in your case). This controller method should return a partial view.

Modal in my main view:

<div class="modal fade name-of-my-modal" tabindex="-1" role="dialog">
    <div class="modal-dialog modal-lg">
        <div class="modal-content"></div>
    </div>
</div>

Link in my main view:

<a class="btn btn-default btn-xs" data-toggle="modal" data-target=".name-of-my-modal" role="button" href="/SomeController/SomeMethodThatReturnsPartialView/234">Show Modal</a>

My controller method for the partial view:

public ActionResult SomeMethodThatReturnsPartialView(int id)
{
    var model = GetProducts();
    return PartialView("_IndexPartial", model);
}

My partial view that will populate the actual modal contents:

<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>

    <h4 class="modal-title">Title goes here</h4>
</div>

<form class="form-horizontal" id="SomeId" name="SomeName" role="form">
    <div class="modal-body">
        <div>Product 1</div>
        <div>Product 2</div>
        <div>Product 3</div>
        <div>Product 4</div>
    </div>
</form>

Also, if the contents of the modal change frequently, or are variable based upon the ID you pass to the partial controller method, then you'll want to clear the modal contents when closing it. From your main view:

$(document).on('hidden.bs.modal', '.modal', function (e) {
    // Handles the event thrown when a modal is hidden
    $(this).removeData('bs.modal');
    $(this).find(".modal-content").empty();
});

Let me know if this helps, and whether anything needs to be clarified.




回答2:


Problem 2 you could return a JSON result and put the HTML in a string as shown here:

https://www.codemag.com/article/1312081/Rendering-ASP.NET-MVC-Razor-Views-to-String

you could also set a boolean on the returned JSON for whether to redirect.

If it is a redirect do that in Javascript on the success using

window.location


来源:https://stackoverflow.com/questions/55923022/display-a-modal-popup-div-from-controller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!