0

I'm very new to ASP.Net and am trying to figure out partial views. I'm trying to get some very simple data to load in a partial view and am just not having any luck. I've got the following, and everything in it works except the load button:

Index.cshtml

@model IEnumerable<MMC_ASP.Models.MMCProjectViewModel>

@{
    ViewBag.Title = "MMCView";
}

<h2>Active Projects</h2>

<div class="project-list">
    @foreach (var item in Model)
    {
        <div class="mig-project @item.ColorClass">
            <div>
                <div class="client-name">@item.Client</div>
                <div class="source-target">@item.SourceTarget</div>
                <div class="server-name">@item.ServerName</div>
                <div class="error-count">@item.ErrorCount</div>
            </div>
        </div>
    }
</div>

<div id="partial"></div>

<input type="button" id="btn" value="Click for Data" />

<script type="text/javascript">
    $(document).ready(function () {
        $('#btn').click(function () {
            $('#partial').load('/MMC/LoadPartialView');
        });
    });
</script>

MMCController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MMC_ASP.Controllers
{
    public class MMCController : Controller
    {

        public ActionResult Index()
        {
            Models.MMCProjectViewModel Project1 = new Models.MMCProjectViewModel() { Client = "Test Client1", SourceTarget = "Source to Target", ServerName = "Server1", ErrorCount = 3, ColorClass = "yellow" };
            Models.MMCProjectViewModel Project2 = new Models.MMCProjectViewModel() { Client = "Test Client2", SourceTarget = "Source to Target", ServerName = "Server2", ErrorCount = 1, ColorClass = "red" };
            Models.MMCProjectViewModel Project3 = new Models.MMCProjectViewModel() { Client = "Test Client3", SourceTarget = "Source to Target", ServerName = "Server3", ErrorCount = 0, ColorClass = "green" };
            Models.MMCProjectViewModel Project4 = new Models.MMCProjectViewModel() { Client = "Test Client4", SourceTarget = "Source to Target", ServerName = "Server4", ErrorCount = 2, ColorClass = "green" };
            Models.MMCProjectViewModel Project5 = new Models.MMCProjectViewModel() { Client = "Test Client5", SourceTarget = "Source to Target", ServerName = "Server5", ErrorCount = 1, ColorClass = "red" };

            List<Models.MMCProjectViewModel> ProjectList = new List<Models.MMCProjectViewModel>();
            ProjectList.Add(Project1);
            ProjectList.Add(Project2);
            ProjectList.Add(Project3);
            ProjectList.Add(Project4);
            ProjectList.Add(Project5);

            return View(ProjectList.OrderBy(o => o.Client).ToList());
        }

        public ActionResult LoadPartialView()
        {
            return PartialView();
        }
    }
}

LoadPartialView.cshtml

<div>TEST DATA HERE</div>

Nothing happens when I click the "Click for Data" button. What am I missing? And for the record, I do realize I should be breaking the script into a separate file, and that the work on the Index action will be done differently. This is a proof of concept for me to make sure I understand all the pieces, and I believe this is the last one to make this work.

TheDoc
  • 688
  • 2
  • 14
  • 33
  • I think this would be a good time to look in to `Ajax.BeginForm()`. This will simplify your code a bit by leveraging Razor syntax to achieve the same effect. A [previous question](http://stackoverflow.com/questions/5410055/using-ajax-beginform-with-asp-net-mvc-3-razor) has some examples. – maccettura Mar 14 '17 at 16:59
  • 1
    If you breakpoint the LoadPartialView method, does it actually get in there when you click the button? – sleeyuen Mar 14 '17 at 17:08
  • @sleeyuen I just checked and no, it does not enter the LoadPartialView ActionResult. – TheDoc Mar 14 '17 at 17:16
  • OK, one step back - using Chrome/IE Dev Tools, does it show that a request is being sent to /MMC/LoadPartialView ? – sleeyuen Mar 14 '17 at 17:17
  • @maccettura I'll look into that. I know about the helpers (Html and Ajax), I just haven't quite gotten there yet. :) Thanks for the advice. By the way, where do you see the opportunity for them in the existing code? – TheDoc Mar 14 '17 at 17:18
  • 1
    Basically just wrap your button in an `Ajax.BeginForm`, the parameters of that function is where you would pass the endpoint ("/MMC/LoadPartialView") and the `UpdateTargetId ` of the element you want to replace ("partial"). You wouldn't need the jquery you posted any longer with this. – maccettura Mar 14 '17 at 17:20
  • @sleeyuen I'm not familiar with Chrome Dev Tools, and I can't seem to find a simple way to find out what a button is doing...do you know of any good walkthroughs on how to set that up? – TheDoc Mar 14 '17 at 19:12
  • @maccettura I tried that with this: `@using (Ajax.BeginForm("LoadPartialView", "MMC", new AjaxOptions { UpdateTargetId = "partial" })) { }` but still get no results when pressing the button. – TheDoc Mar 14 '17 at 19:13
  • 1
    Does your project have the `jquery.unobtrusive-ajax.js`? Its part of the default MVC project and required for Ajax.BeginForm – maccettura Mar 14 '17 at 19:26
  • 1
    If you're testing this page in Chrome or IE, hit the F12 key and then go to the Network tab. Once there, click your button and see if an entry is generated in the Network tab to show where the request is being sent. – sleeyuen Mar 14 '17 at 19:32
  • @maccettura Ah, yeah, there is no `jquery-unobtrusive-ajax.js` in the project. Got `jquery.validate.unobtrusive.js` and unobtrusive.min.js, but no ajax. That might be the answer. Curious that you say it's included, but I just made this project a few days ago in Visual Studio 2015. – TheDoc Mar 14 '17 at 19:45

2 Answers2

1

Your code looks fine. I have a very strong feeling that your code is failing to update the partial view because you are getting a 404 Not Found error when trying to make an ajax call.

It is a good practice to take advantage of the HTML helper methods like Url.Action to generate the correct url to an action method. You can execute the Url.Action method in the razor view and keep the output of that(the url) in html 5 data attributes on the button.

<input type="button" id="btn" data-url="@Url.Action("LoadPartialView","MMC")"
                                                                 value="Click for Data" />

Now when click event happens, read the data attribute value and use that to make the ajax call.

$(function () {

    $('#btn').click(function (e) {
        e.preventDefault();
        $('#partial').load($(this).data("url"));
    });

});
Shyju
  • 214,206
  • 104
  • 411
  • 497
  • I tried this: ` ` but am getting no results when pressing the button. No error, no result of any kind that I can see. – TheDoc Mar 14 '17 at 19:14
  • 1
    check your browser console and see whether you have any script errors. When you click the button , is it making a net work call (check network tab) – Shyju Mar 14 '17 at 19:26
  • I see this in the Console: `Uncaught ReferenceError: $ is not defined` and it references line 96, which is in the script. Could that be the issue? – TheDoc Mar 14 '17 at 19:32
  • 1
    Absolutely - looks like jQuery isn't properly referenced on your page. – sleeyuen Mar 14 '17 at 19:33
  • @sleeyuen Seems reasonable...any help on how to do that? – TheDoc Mar 14 '17 at 19:34
  • 1
    Yea. that means jQuery is not available(not loaded) before this script was called ? Are you loading jQuery library ? If yes you need to make sure you are loading your page level script inside `@section Scripts` block to ensure that your code is executed after jQuery is loaded – Shyju Mar 14 '17 at 19:34
  • 1
    Take a look at [where should i place the js script files in a mvc application so jquery works well?](http://stackoverflow.com/questions/34147155/where-should-i-place-the-js-script-files-in-a-mvc-application-so-jquery-works-we/34147263#34147263) – Shyju Mar 14 '17 at 19:35
  • Add this tag to your page and see if it works properly: `` – sleeyuen Mar 14 '17 at 19:37
  • I added `@section scripts { }` to the Index.cshtml page under the ViewBag section and it worked! Thanks for your help, guys. I'm still curious why the Ajax.BeginForm method wouldn't work, though... – TheDoc Mar 14 '17 at 19:40
0

Thanks to the great help from @sleeyuen, @Shyju, and @maccettura I got it working. I needed to add this to my view below the @{ViewBag.Title...} area:

@section scripts {
    <script type="text/javascript">
        $(document).ready(function () {
            $('#btn').click(function (e) {
                $('#partial').load($(this).data("url"));
            });
        });
    </script>
    }

And the Ajax.BeginForm method wouldn't work because my project doesn't include jquery.unobtrusive-ajax.js. Hope this helps someone else down the line.

TheDoc
  • 688
  • 2
  • 14
  • 33