-1

I am not quite getting how to do AJAX or rather use jQuery in case of a partial view . Here is the issue I am facing :

In my view MyAction.cshtml which receives a collection of StudentViewModel objects :

@model IEnumerable<MvcApplication4.ViewModels.StudentViewModel>  
@{
    ViewBag.Title = "MyAction";
    Layout = "~/Views/Shared/_myTemplateLayoutPage.cshtml";
}

<script type="text/javascript" src="/scripts/jquery-1.3.2.js"></script>
<script type="text/javascript">
    $('.editDetails').click(function () {
        alert('Edit Clicked');
    });
</script>

<div id="content">
    <div id="mainpage">

    <h2>Registration Details</h2>
        <ul>
        @foreach(var item in Model) 
        {
            <li>
                @Ajax.ActionLink(item.UserName, 
                "GetUserDetails",
                new { id = item.Student.StudentId },
                    new AjaxOptions
                    {
                        UpdateTargetId = "StudentDetails", 
                        InsertionMode = InsertionMode.Replace,
                        HttpMethod = "GET" @*HTTP method *@
                    }
                )
            </li>
        }
        </ul>
        <div id ="StudentDetails"></div>
    </div>
    <div id="sidebar">
    </div>
    <div id="sidebarbottom"></div>
</div>

I have certain username hyperlinks which are essentially ajax action links . When clicked GetUserDetails controller action method gets fired that returns the specfic partial view containing the StudentViewModel object details.

    [HttpGet]
    public PartialViewResult GetUserDetails(int? id)
    {
        StudentContext context = new StudentContext();

        var result = context.Students.Where(s => s.StudentId == id)
            .Include(s => s.Department)
            .Select(s => new StudentViewModel
                {
                    Student = s,
                    UserName = s.UserName,
                    DepartmentName = s.Department.DepartmentName
                }).First();

        return PartialView("_StudentDetails",result);

    }

The partial view _StudentDetails looks like :

@model MvcApplication4.ViewModels.StudentViewModel

<h2>Student Details</h2>
<table border="1">
    <tr>
        <th>
            Name
        </th>
        <th>
            User Name
        </th>
        <th>
            Department
        </th>
        <th colspan="2">
            Actions
        </th>
    </tr>
    <tr>
        <td>
            @Html.DisplayFor(x => x.StudentFullName)
        </td>
        <td>
            @Html.DisplayFor(x => x.UserName)
        </td>
        <td>
            @Html.DisplayFor( x => x.DepartmentName)
        </td>
        <td>
            <input type="submit" class="editDetails" value="Edit Details" name="Command" />
        </td>
        <td>
            <input type="submit" class="addDetails" value="Add Details" name="Command" />
        </td>
    </tr>
</table>

Those get rendered exactly the way they are expected to. The partial View gets rendered in the StudentDetails div id.

enter image description here

Now when I click the edit button the alert does not get fired .

    <script type="text/javascript" src="/scripts/jquery-1.3.2.js"></script>
    <script type="text/javascript">
    $('.editDetails').click(function () {
        alert('Edit Clicked');
    });
</script>

What am I missing ?

References in the _myTemplateLayoutPage.cshtml have been taken care of.

enter image description here

Google chrome shows following errors in the console log.

enter image description here

And the bundle config looks like :

       public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js"));

        bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                    "~/Scripts/jquery-ui-{version}.js"));

        bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.unobtrusive*",
                    "~/Scripts/jquery.validate*"));

        // Use the development version of Modernizr to develop with and learn from. Then, when you're
        // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
        bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                    "~/Scripts/modernizr-*"));

        bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));

        bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
                    "~/Content/themes/base/jquery.ui.core.css",
                    "~/Content/themes/base/jquery.ui.resizable.css",
                    "~/Content/themes/base/jquery.ui.selectable.css",
                    "~/Content/themes/base/jquery.ui.accordion.css",
                    "~/Content/themes/base/jquery.ui.autocomplete.css",
                    "~/Content/themes/base/jquery.ui.button.css",
                    "~/Content/themes/base/jquery.ui.dialog.css",
                    "~/Content/themes/base/jquery.ui.slider.css",
                    "~/Content/themes/base/jquery.ui.tabs.css",
                    "~/Content/themes/base/jquery.ui.datepicker.css",
                    "~/Content/themes/base/jquery.ui.progressbar.css",
                    "~/Content/themes/base/jquery.ui.theme.css"));
    }
StrugglingCoder
  • 4,231
  • 11
  • 55
  • 90
  • 1
    Add your BundleConfig.cs to your question. – JB06 Feb 29 '16 at 19:58
  • Also, why are you referencing jQuery so many times? – JB06 Feb 29 '16 at 19:59
  • Unrelated to the errors shown, but definitely related to the problem at hand, is that you're trying to bind a click event to elements that don't exist yet. Take a look here: http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – David Feb 29 '16 at 20:00
  • No luck as of yet :( Please look at the BundleConfig.cs also. – StrugglingCoder Feb 29 '16 at 20:06
  • Remove any references you have to jQuery that aren't the bundles and try again. You're using two different versions right now – JB06 Feb 29 '16 at 20:11
  • From where have I to remove ? From the layout itself ? i.e. ? – StrugglingCoder Feb 29 '16 at 20:14
  • Leave the Scripts.Render tags there and remove any other references to any script you already load in the bundles. Also, I don't see a bundles/bootstrap bundle in your class, so that will cause an error, unless you load it somewhere else. – JB06 Feb 29 '16 at 20:31
  • Can you confirm when you click on "zack dyas" partial view is getting rendered? If that's the case then you shouldn't be getting all the errors in the Chrome as I believe AJAX call will only work if your script path is correct. Also please help me understand the actual problem. Is that the hyperlinks of Partial views not working or your AJAX call is not working? – ndd Feb 29 '16 at 20:36
  • @ndd Yes when I click on the hyperlink "zack dyas" , the partial view that contains the Student Details get rendered. And that's why I can click on the Edit Details and Add Details buttons as they are on the partial view itself. But when I click the buttons the alert is not coming . – StrugglingCoder Feb 29 '16 at 20:42

4 Answers4

2

You are dynamically generating the Edit buttons in the view (i.e. they are added after the page it first loaded You need to use event delegation to handle dynamically added elements. Change the script to

$('#StudentDetails').on('click', '.editDetails', function () {
    alert('Edit Clicked');
});

in this case the element with id="StudentDetails" is the closest ancestor that exists in the DOM when the page is first rendered.

1

Make sure jquery is loadedproperly. you can use cdn something like this.

    <script src="//code.jquery.com/jquery-2.2.1.js"></script>

Because the partial view is dynamically loaded you have to use $(document).on function. Also I would put that everything inside document.ready()...

    $(function() {
      $(document).on("click", ".editDetails", function () {
        alert('Edit Clicked');
     });
    });
Kalyan
  • 175
  • 1
  • 12
0

If you're going put the <script> elements in yourself, you can't just throw a ~ character in there - you need to resolve it to a real URL when the page is rendered.

<script src='@Url.Content("~/Scripts/jquery-1.9.1.js")' type='text/javascript'></script>

Of course, if you do this, you're cheating yourself out of all the awesomeness that is bundling.

Dave
  • 4,330
  • 3
  • 21
  • 30
  • Yet there is no alert till now. :( Any thing that needs to be done more ? – StrugglingCoder Feb 29 '16 at 20:12
  • Your alert was the "404." If you remove the bundles for now and use direct ` – Dave Feb 29 '16 at 20:15
  • I am not getting the alert . – StrugglingCoder Feb 29 '16 at 20:16
  • You're jumping way too far ahead in your troubleshooting. First you verify the files are loading. Then you worry about getting your own scripts to execute. – Dave Feb 29 '16 at 20:20
0

Please replace your your AJAX Actionlink's AJAXOptions with the below one. Please note OnComplete = "RegisterClickHanders"

<li>
    @Ajax.ActionLink(item.UserName,
    "GetUserDetails",
    new { id = item.Student.StudentId },
        new AjaxOptions
        {
            UpdateTargetId = "StudentDetails",
            InsertionMode = InsertionMode.Replace,
            HttpMethod = "GET" @*HTTP method *@,
            OnComplete = "RegisterClickHanders"
        }
    )
</li>

And in your main page add this function.

<script>
    function RegisterClickHanders() {
        $('.editDetails').click(function () {
            alert('Edit Clicked');
        });
    }
</script>
ndd
  • 2,829
  • 2
  • 22
  • 37
  • Not working . I added the section in my view file MyAction.cshtml where the partial view got rendered. – StrugglingCoder Feb 29 '16 at 20:19
  • @StrugglingCoder so based on your previous comment I am sure that your bundle paths are correct. The reason your click handlers are not working is that you are registering them before those HTML elements are rendered (they will be rendered dynamically on click of Student name) and that's why you need to subscribe for `OnComplete` event. Please try updated code and let me know if you are still facing problems. – ndd Feb 29 '16 at 20:57
  • Ok so both the code blocks would be there in the main view only ? – StrugglingCoder Feb 29 '16 at 21:04
  • Yes both will go in the main view. – ndd Feb 29 '16 at 21:04
  • Alert is working . But even when I put the section well on top of the ajax action links definition the alert works fine. Just curious "Is not the code gets executed top-to-bottom" approach ? Then how does it work ? – StrugglingCoder Feb 29 '16 at 21:07
  • 1
    You are right code gets executed from top to bottom but in your case since all the `.editDetails` links are not there `$('.editDetails').` will not do nothing. Those links are rendered when you click on the Student name. At this point your DOM is changed and now you need to subscribe for click events of `.editDetails`. To test what I am explaining put a break point in Chrome Developers tool on the line `$('.editDetails')` and check inside console the length of it. [Example](http://postimg.org/image/b60mrie67/3010bb44/) – ndd Feb 29 '16 at 21:15