0

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:

OnLoad

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

AfterRefresh

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?

Analytic Lunatic
  • 3,853
  • 22
  • 78
  • 120
  • If you are getting 404 error, check you URL. Instead of this: var url = '~/VerifyAssets/NewCutoffDateInterval'... Try this: var url = '@Url.Action("NewCutoffDateInterval", "VerifyAssets")'; – Dawood Awan Mar 02 '15 at 15:45
  • ^ or `'@Url.Content("~/VerifyAssets/NewCutoffDateInterval")'` – Inspector Squirrel Mar 02 '15 at 15:46
  • 1
    Also try using `@Html.Partial()` instead of `@Html.RenderPartial()` – Inspector Squirrel Mar 02 '15 at 15:47
  • @DawoodAwan, Thanks! `@Url.Action` is successfully calling my `NewCutoffDateIntervall()` action. Do you have thoughts on how to modified my view to properly render the `partial` and use the return from my action to refresh it? – Analytic Lunatic Mar 02 '15 at 15:48
  • See my above comment, as for your success function: `$('.assetList').html(resp);` – Inspector Squirrel Mar 02 '15 at 15:49
  • 1
    Your controller seems to be correct, you are returning the Partial View as HTML, which will render the Partial View with the Model at the server. So you should have HTML on this line in response. **.html(response);** As mentioned by Sippy you have to use **$('.assetList').html(response);** Instead of **$("#assetList").html(response);** – Dawood Awan Mar 02 '15 at 15:51
  • Thank you both! Most of it is now working, though there is a minor issue with modifying the div contents. Please see my EDIT above. – Analytic Lunatic Mar 02 '15 at 16:14
  • 1
    **
    ** Move this to you Main View. And just put the HTML you are reloading in the partial View (In your case the Table/Grid)
    – Dawood Awan Mar 02 '15 at 16:21
  • Thanks! Everything seems to be going well now :) I was getting so frustrated trying to figure this out. – Analytic Lunatic Mar 02 '15 at 16:25
  • @DawoodAwan, You helped me out greatly with this, I was wondering if you would mind taking a crack at another question I opened awhile back? https://stackoverflow.com/questions/28747690/mvc-export-contents-of-a-grid-on-my-view-to-excel-file – Analytic Lunatic Mar 02 '15 at 21:24

1 Answers1

2

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.

Jason Evans
  • 28,906
  • 14
  • 90
  • 154
  • This is something I was attempting to earlier, and while I understand the `return PartialView` and the javascript refresh code, I can't get the `Html. RenderPartial` to work since I'm not understanding how to define the `model` parameter? – Analytic Lunatic Mar 02 '15 at 15:50
  • 1
    [`RenderPartial` doesn't work the way you think it does](http://stackoverflow.com/questions/5248183/html-partial-vs-html-renderpartial-html-action-vs-html-renderaction). Use `Partial`. – Inspector Squirrel Mar 02 '15 at 15:51