0
votes

In a partial view, when an html element clicked I'm calling jquery .click() events but those are not firing. But when I place same code in the main View those are working. Please assist me

following are the events.

$('.page-change').click(function (e) {
            alert("Hello page");
        });

        $('.toggle-sort').click(function (e) {
            alert("Hello");
        });

Please click on this link which will show output with highlighted areas for on click event which should get called

Below are the steps I have done:

Called partial view from regular view page. When I click on Header EmployeeName should fire related .click() event which is not working.

If I place partial view's code in index.cshtml then .click() events are working.

Controller: HomeController which passed view model data to index cshtml

      public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        public IActionResult Index()
        {
            var res = new List<EmployeeViewModel>() { 
                new EmployeeViewModel() { EmployeeDepartment = "Development", EmployeeName = "Sarath" },
            new EmployeeViewModel (){ EmployeeDepartment="Sales",EmployeeName="Stephen"},
            new EmployeeViewModel (){ EmployeeDepartment="Human Resource",EmployeeName="Krishna"},
            new EmployeeViewModel (){ EmployeeDepartment="Development",EmployeeName="Naresh"}};
            return View(res);
        }
}

View: Index.cshtml

@model IEnumerable<EmployeeViewModel>

@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Employees Data</h1>

    <div class="row">
        <div class="col my-3">
            <partial name="_EmployeesDataPartial" model="Model" />
        </div>
    </div>

</div>

Partial View _EmployeesDataPartial.cshtml

    @model IEnumerable<RandDpartialView.Models.EmployeeViewModel>


<table class="table">
    <thead>
        <tr>
            <th class="th--sortable toggle-sort" style="cursor:pointer">
                @Html.DisplayNameFor(model => model.EmployeeName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.EmployeeDepartment)
            </th>            
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.EmployeeName)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.EmployeeDepartment)
                </td>               
            </tr>
        }
    </tbody>
</table>
<div>
    <ul class="pagination" style="cursor:pointer">
        <li class="pagination-item">
            <a class="pagination-link page-change" data-page="1">
                <span class="icon fa fa-fw fas fa-angle-double-left"></span><span class="text">&nbsp;First</span>
            </a>
        </li>
    </ul>
</div>

@section Scripts{
    <script type="text/javascript">

        $(function () {

            $('.page-change').click(function (e) {
                alert("Hello page");
            });

            $('.toggle-sort').click(function (e) {
                alert("Hello");
            });
        });
    </script>
}
1

1 Answers

0
votes

@section does not work in partials. There's an article on it here:

https://www.adamrussell.com/asp-net-core-section-scripts-in-a-partial-view/

The author imitates the behavior using an HtmlHelper class:

using System;
using System.Linq;
using System.Text.Encodings.Web;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Rendering;
public static class HtmlHelperExtensions
{
    private const string _partialViewScriptItemPrefix = "scripts_";
    public static IHtmlContent PartialSectionScripts(this IHtmlHelper htmlHelper, Func<object, HelperResult> template)
    {
        htmlHelper.ViewContext.HttpContext.Items[_partialViewScriptItemPrefix + Guid.NewGuid()] = template;
        return new HtmlContentBuilder();
    }
    public static IHtmlContent RenderPartialSectionScripts(this IHtmlHelper htmlHelper)
    {
        var partialSectionScripts = htmlHelper.ViewContext.HttpContext.Items.Keys
            .Where(k => Regex.IsMatch(
                k.ToString(),
                "^" + _partialViewScriptItemPrefix + "([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$"));
        var contentBuilder = new HtmlContentBuilder();
        foreach (var key in partialSectionScripts)
        {
            var template = htmlHelper.ViewContext.HttpContext.Items[key] as Func<object, HelperResult>;
            if (template != null)
            {
                var writer = new System.IO.StringWriter();
                template(null).WriteTo(writer, HtmlEncoder.Default);
                contentBuilder.AppendHtml(writer.ToString());
            }
        }
        return contentBuilder;
    }
}

Replace the @section:

@Html.PartialSectionScripts(
    @<script>
        alert('Hello from the partial view!');
    </script>
)

And add the call to render the scripts:

    @*...*@
    @RenderSection("Scripts", required: false)
    @Html.RenderPartialSectionScripts()
</body>
</html>