简体   繁体   中英

MVC5: Refresh partial view on button click?

My VerifyAsset/Index view is currently defined as so:

@using GridMvc.Html
@using System.Collections.Generic
@model List<InventoryTracker.Models.INV_Assets>

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h3>Verify Assets</h3>

<div class="mainAssetBtns">
    @Html.DropDownList("NumberValueSelection", Enumerable.Range(1, 31).Select(x => new SelectListItem { Text = x.ToString(), Value = x.ToString() }))
    @Html.DropDownList("intervalList")
    <a href="#" class="btn btn-info btn-sm noDecoration" onclick="newCutoffDate()"><span class="glyphicon glyphicon-refresh"> REFRESH</span></a>
    @*<a href="/INV_Assets/Create" class="btn btn-success btn-sm noDecoration"><span class="glyphicon glyphicon-plus"></span> Create Asset</a>
    <a href="/Home/Index" class="btn btn-info btm-sm noDecoration"><span class="glyphicon glyphicon-filter"></span> Clear All Filters</a>*@
</div>

@* prism - admin/usermanagement/index - mvcgrid example *@
<div class="assetList">

    @*Images in Columns: https://gridmvc.codeplex.com/discussions/440977*@
    @try
    {
        @Html.Grid(Model).Columns(columns =>
        {
            columns.Add().Encoded(false).Sanitized(false).SetWidth(30).RenderValueAs(o => @Html.CheckBox("checked", false));
            columns.Add().Encoded(false).Sanitized(false).RenderValueAs(o => @<a href="#" class="btn btn-default btn-sm noDecoration verifyBtn" onclick="verifyAsset(@o.Id)"><span class="glyphicon glyphicon-ok"></span> @*View*@</a>).SetWidth(15);
            @*columns.Add().Encoded(false).Sanitized(false).RenderValueAs(o => @<a href="/INV_Assets/Details/@o.Id" class="btn btn-default btn-sm noDecoration"><span class="glyphicon glyphicon-eye-open"></span> @*View*</a>).SetWidth(15);*@
            columns.Add(o => o.Status.status_description).Titled("Status").RenderValueAs(o => o.Status.status_description).Sanitized(false).Encoded(false).Sortable(true).Filterable(true).SetWidth(20);
            columns.Add(o => o.Location.location_dept).Titled("Dept").RenderValueAs(o => o.Location.location_dept).SetWidth(20);
            columns.Add(o => o.Location.location_room).Titled("Room").RenderValueAs(o => o.Location.location_room).SetWidth(20);
            columns.Add(o => o.owner).Titled("Owner").RenderValueAs(o => o.owner).SetWidth(20);
            columns.Add(o => o.Type.type_description).Titled("Type").RenderValueAs(o => o.Type.type_description).SetWidth(20);
            columns.Add(o => o.Manufacturer.manufacturer_description).Titled("Manufacturer").RenderValueAs(o => o.Manufacturer.manufacturer_description).SetWidth(20);
            columns.Add(o => o.Model.model_description).Titled("Model").RenderValueAs(o => o.Model.model_description).SetWidth(20);
            columns.Add(o => o.Vendor.vendor_name).Titled("Vendor").RenderValueAs(o => o.Vendor.vendor_name).SetWidth(20);
            columns.Add(o => o.description).Titled("Desc").RenderValueAs(o => o.description).SetWidth(20);
            columns.Add(o => o.asset_tag_number).Titled("Asset Tag #").RenderValueAs(o => o.asset_tag_number).SetWidth(20);
            columns.Add(o => o.serial_number).Titled("Serial #").RenderValueAs(o => o.serial_number).SetWidth(20);
            columns.Add(o => o.ip_address).Titled("IP Addr").RenderValueAs(o => o.ip_address).SetWidth(20);
            columns.Add(o => o.mac_address).Titled("Mac Addr").RenderValueAs(o => o.mac_address).SetWidth(20);
            columns.Add(o => o.po_number).Titled("PO #").RenderValueAs(o => o.po_number).SetWidth(20);
            columns.Add(o => o.invoice_number).Titled("Inv. #").RenderValueAs(o => Convert.ToString(o.invoice_number)).SetWidth(20);
            columns.Add(o => o.cost).Titled("Cost").RenderValueAs(o => "$" + Convert.ToString(o.cost)).SetWidth(20);
            columns.Add(o => o.note).Titled("Note").RenderValueAs(o => o.note).SetWidth(20);
            columns.Add(o => o.acquired_date).Titled("Acq. Date").RenderValueAs(o => Convert.ToString(o.acquired_date)).SetWidth(20);
            columns.Add(o => o.disposed_date).Titled("Disp. Date").RenderValueAs(o => Convert.ToString(o.disposed_date)).SetWidth(20);
            columns.Add(o => o.verified_date).Titled("Ver. Date").RenderValueAs(o => Convert.ToString(o.verified_date)).SetWidth(20);
            columns.Add(o => o.created_date).Titled("Crtd. Date").RenderValueAs(o => Convert.ToString(o.created_date)).SetWidth(20);
            columns.Add(o => o.created_by).Titled("By").RenderValueAs(o => o.created_by).SetWidth(20);
            columns.Add(o => o.modified_date).Titled("Mod. Date").RenderValueAs(o => Convert.ToString(o.modified_date)).SetWidth(20);
            columns.Add(o => o.modified_by).Titled("By").RenderValueAs(o => o.modified_by).SetWidth(20);
        }).WithPaging(100).Sortable().Filterable().WithMultipleFilters();
    }
    catch (NullReferenceException ex)
    {
        return;
    }
</div>

I am trying to set up my <div class="assetList"> as a partial view which users can refresh based on there dropdown selections and clicking the [REFRESH] button.

I've created a partial view called _VerificationPartial :

@using GridMvc.Html
@using System.Collections.Generic
@model List<InventoryTracker.Models.INV_Assets>

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h3>Verify Assets</h3>

<div class="mainAssetBtns">
    @Html.DropDownList("NumberValueSelection", Enumerable.Range(1, 31).Select(x => new SelectListItem { Text = x.ToString(), Value = x.ToString() }))
    @Html.DropDownList("intervalList")
    <a href="#" class="btn btn-info btn-sm noDecoration" onclick="newCutoffDate()"><span class="glyphicon glyphicon-refresh"> REFRESH</span></a>
    @*<a href="/INV_Assets/Create" class="btn btn-success btn-sm noDecoration"><span class="glyphicon glyphicon-plus"></span> Create Asset</a>
    <a href="/Home/Index" class="btn btn-info btm-sm noDecoration"><span class="glyphicon glyphicon-filter"></span> Clear All Filters</a>*@
</div>

@* prism - admin/usermanagement/index - mvcgrid example *@
<div class="assetList">

    @*Images in Columns: https://gridmvc.codeplex.com/discussions/440977*@
    @try
    {
        @Html.Grid(Model).Columns(columns =>
        {
            columns.Add().Encoded(false).Sanitized(false).SetWidth(30).RenderValueAs(o => @Html.CheckBox("checked", false));
            columns.Add().Encoded(false).Sanitized(false).RenderValueAs(o => @<a href="#" class="btn btn-default btn-sm noDecoration verifyBtn" onclick="verifyAsset(@o.Id)"><span class="glyphicon glyphicon-ok"></span> @*View*@</a>).SetWidth(15);
            @*columns.Add().Encoded(false).Sanitized(false).RenderValueAs(o => @<a href="/INV_Assets/Details/@o.Id" class="btn btn-default btn-sm noDecoration"><span class="glyphicon glyphicon-eye-open"></span> @*View*</a>).SetWidth(15);*@
            columns.Add(o => o.Status.status_description).Titled("Status").RenderValueAs(o => o.Status.status_description).Sanitized(false).Encoded(false).Sortable(true).Filterable(true).SetWidth(20);
            columns.Add(o => o.Location.location_dept).Titled("Dept").RenderValueAs(o => o.Location.location_dept).SetWidth(20);
            columns.Add(o => o.Location.location_room).Titled("Room").RenderValueAs(o => o.Location.location_room).SetWidth(20);
            columns.Add(o => o.owner).Titled("Owner").RenderValueAs(o => o.owner).SetWidth(20);
            columns.Add(o => o.Type.type_description).Titled("Type").RenderValueAs(o => o.Type.type_description).SetWidth(20);
            columns.Add(o => o.Manufacturer.manufacturer_description).Titled("Manufacturer").RenderValueAs(o => o.Manufacturer.manufacturer_description).SetWidth(20);
            columns.Add(o => o.Model.model_description).Titled("Model").RenderValueAs(o => o.Model.model_description).SetWidth(20);
            columns.Add(o => o.Vendor.vendor_name).Titled("Vendor").RenderValueAs(o => o.Vendor.vendor_name).SetWidth(20);
            columns.Add(o => o.description).Titled("Desc").RenderValueAs(o => o.description).SetWidth(20);
            columns.Add(o => o.asset_tag_number).Titled("Asset Tag #").RenderValueAs(o => o.asset_tag_number).SetWidth(20);
            columns.Add(o => o.serial_number).Titled("Serial #").RenderValueAs(o => o.serial_number).SetWidth(20);
            columns.Add(o => o.ip_address).Titled("IP Addr").RenderValueAs(o => o.ip_address).SetWidth(20);
            columns.Add(o => o.mac_address).Titled("Mac Addr").RenderValueAs(o => o.mac_address).SetWidth(20);
            columns.Add(o => o.po_number).Titled("PO #").RenderValueAs(o => o.po_number).SetWidth(20);
            columns.Add(o => o.invoice_number).Titled("Inv. #").RenderValueAs(o => Convert.ToString(o.invoice_number)).SetWidth(20);
            columns.Add(o => o.cost).Titled("Cost").RenderValueAs(o => "$" + Convert.ToString(o.cost)).SetWidth(20);
            columns.Add(o => o.note).Titled("Note").RenderValueAs(o => o.note).SetWidth(20);
            columns.Add(o => o.acquired_date).Titled("Acq. Date").RenderValueAs(o => Convert.ToString(o.acquired_date)).SetWidth(20);
            columns.Add(o => o.disposed_date).Titled("Disp. Date").RenderValueAs(o => Convert.ToString(o.disposed_date)).SetWidth(20);
            columns.Add(o => o.verified_date).Titled("Ver. Date").RenderValueAs(o => Convert.ToString(o.verified_date)).SetWidth(20);
            columns.Add(o => o.created_date).Titled("Crtd. Date").RenderValueAs(o => Convert.ToString(o.created_date)).SetWidth(20);
            columns.Add(o => o.created_by).Titled("By").RenderValueAs(o => o.created_by).SetWidth(20);
            columns.Add(o => o.modified_date).Titled("Mod. Date").RenderValueAs(o => Convert.ToString(o.modified_date)).SetWidth(20);
            columns.Add(o => o.modified_by).Titled("By").RenderValueAs(o => o.modified_by).SetWidth(20);
        }).WithPaging(100).Sortable().Filterable().WithMultipleFilters();
    }
    catch (NullReferenceException ex)
    {
        return;
    }
</div>

What I can't seem to figure out is how to use @Html.RenderPartial to render my view, as I'm not clear on how to provide the Model parameter?

@Html.RenderPartial("~/Views/Shared/_VerificationPartial.cshtml") currently yields "cannot implicitly convert type 'void' to 'object' .

My VerifyAsset/Index controller action is defined like so:

    public async Task<ActionResult> Index()
    {
        List<SelectListItem> intervalList = new List<SelectListItem>();
        intervalList.Add(new SelectListItem { Text = "Month", Value = "Month" });
        intervalList.Add(new SelectListItem { Text = "Day", Value = "Day" });
        intervalList.Add(new SelectListItem { Text = "Year", Value = "Year" });
        var cutoffDate = DateTime.Now.AddMonths(-3);
        var iNV_Assets = db.INV_Assets.Where(i => i.verified_date < cutoffDate).Include(i => i.Location).Include(i => i.Manufacturer).Include(i => i.Model).Include(i => i.Status).Include(i => i.Type).Include(i => i.Vendor);
        ViewBag.intervalList = intervalList;
        return View(await iNV_Assets.ToListAsync());
        //return PartialView("~/Views/Shared/_VerificationPartial.cshtml", await iNV_Assets.ToListAsync());
    }

and this is the script I use on my view where I'm attempting to call my controller action to refresh the partial view -- note: my parameter values are correctly filled in, but I get a 404 error when it trying to find the Action on the controller?:

    function newCutoffDate() {
        var _value = document.getElementById("NumberValueSelection").value;
        var _interval = document.getElementById("intervalList").value;
        var data = { value: _value, interval: _interval };
        var url = '~/VerifyAssets/NewCutoffDateInterval'
        $.get(url, { value: _value, interval: _interval })
        .done(function (response) {
            $("#assetList").html(response);
        });
        //window.location.href = url;
        @*$.ajax({
            type: "POST",
            dataType: "JSON",
            url: '@Url.Action("NewCutoffDateInterval", "VerifyAssets")',
            data: data,
            success: function (resp) {
                alert("Sucess! Value: " + resp.value + " | Interval: " + resp.interval);
            },
            error: function (resp) {
                alert("Error! Value: " + resp.value + " | Interval: " + resp.interval);
            }
        })*@
    }

VerifyAssets/NewCutoffDateInterval :

    [HttpGet]
    public async Task<ActionResult> NewCutoffDateInterval(int value, string interval)
    {
        var cutoffDate = DateTime.Now.AddMonths(-3);
        if (interval == "Month")
        {
            cutoffDate = DateTime.Now.AddMonths(-value);
        }
        else
        {
            if (interval == "Day")
            {
                cutoffDate = DateTime.Now.AddDays(-value);
            }
            else
            {
                if (interval == "Year")
                {
                    cutoffDate = DateTime.Now.AddYears(-value);
                }
            }
        }

        var iNV_Assets = db.INV_Assets.Where(i => i.verified_date < cutoffDate).Include(i => i.Location).Include(i => i.Manufacturer).Include(i => i.Model).Include(i => i.Status).Include(i => i.Type).Include(i => i.Vendor);

        if (Request.IsAjaxRequest())
        {
            return PartialView("~/Views/Shared/_VerificationPartial.cshtml", await iNV_Assets.ToListAsync());
        }
        else
        {
            return PartialView("~/Views/Shared/_VerificationPartial.cshtml", await iNV_Assets.ToListAsync());
        }

    }

Can anyone with more experience help with this?


EDIT :

Thank you all for the suggestions! My partial view is now rendering on the View and the script is now successfully calling my action method.

There does however seem to be a minor issue when my partial view is refreshed.

My VerifyAssets/Index view is now:

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h3>Verify Assets</h3>

<div class="mainAssetBtns">
    @Html.DropDownList("NumberValueSelection", Enumerable.Range(1, 31).Select(x => new SelectListItem { Text = x.ToString(), Value = x.ToString() }))
    @Html.DropDownList("intervalList")
    <a href="#" class="btn btn-info btn-sm noDecoration" onclick="newCutoffDate()"><span class="glyphicon glyphicon-refresh"> REFRESH</span></a>
    @*<a href="/INV_Assets/Create" class="btn btn-success btn-sm noDecoration"><span class="glyphicon glyphicon-plus"></span> Create Asset</a>
    <a href="/Home/Index" class="btn btn-info btm-sm noDecoration"><span class="glyphicon glyphicon-filter"></span> Clear All Filters</a>*@
</div>

@Html.Partial("~/Views/Shared/_VerificationPartial.cshtml")

@section Scripts {
        function newCutoffDate() {
            var _value = document.getElementById("NumberValueSelection").value;
            var _interval = document.getElementById("intervalList").value;
            var data = { value: _value, interval: _interval };
            //var url = '~/VerifyAssets/NewCutoffDateInterval'
            var url = '@Url.Action("NewCutoffDateInterval", "VerifyAssets")';
            $.get(url, { value: _value, interval: _interval })
            .done(function (response) {
                alert("Made it here!");
                $(".assetList").html(response);
            });
            //window.location.href = url;
            @*$.ajax({
                type: "POST",
                dataType: "JSON",
                url: '@Url.Action("NewCutoffDateInterval", "VerifyAssets")',
                data: data,
                success: function (resp) {
                    alert("Sucess! Value: " + resp.value + " | Interval: " + resp.interval);
                },
                error: function (resp) {
                    alert("Error! Value: " + resp.value + " | Interval: " + resp.interval);
                }
            })*@
        }
    </script>
}

This is my the contents of my partial view on load:

负载

And this is the content if I change the interval to be 5 - Days :

刷新后

It seems my <div class="assetList"> on refresh adds another <div class="assetList"> within the first one. How would I simply replace the first instead of inserting a child div?

To make it easier, why not try returning the partial view as text to the page via an AJAX call when you want to refresh it?

For example in the controller you can have an action method that would return the partial view:

public async Task<ActionResult> GetFoo()
{
    return PartialView("~/Views/Shared/_VerificationPartial.cshtml", await iNV_Assets.ToListAsync());
}

Then you would have JavaScript make a $.get() call to refresh the part of the view where the partial would be located:

$.get("/Home/GetFoo")
.then(function (response) {
    // response will be the HTML of the partial view.
    // e.g. $("#partialviewhost).html(response);
});

So it's pretty much what you have already done, but in way that the partial view HTML can be generated for a refresh.

I hope I've understood your problem correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM