Search code examples
javascriptc#jquerymodel-view-controllerwebgrid

javascript click event working only for first element in WebGrid MVC


I have a webgrid that gets populated on page load. In this grid I have an element that has a javascript event handled when it is clicked. Here I simply intend to sent the user to an external site. I also have this tied to a controller. Both are working for the first element. However, when it comes to anything after the first element in the list the javascript does not get called.

WebGrid:

@grid.GetHtml(tableStyle: "table table-striped table-bordered",
            headerStyle: "thead-default",
            columns: grid.Columns(
                grid.Column("post_tran_a", Model.year_a, canSort: false, format: (item) =>
                    new HtmlString(Html.CheckBox("post_tran_a", (bool)item.post_tran_a.is_reviewed, new { disabled = "disabled" })
                    + " " +
                    Html.ActionLink((string)item.post_tran_a.month, "PostTransmission", Model.controller, new { report_id = item.post_tran_a.report_id, link = item.post_tran_a.link }, new { @id = "external-link", data_url=Url.Action() })
                    ))))

Javascript:

$("#external-link").click(function () {
    var url = $("#external-link").attr("data-url");
    alert(url);
});

If this approach won't work I'm open to alternative solutions.


Solution

  • Simplest way in your particular case might work like

    $("table a").click(function () {    
        // you need here 'this' it is available by default
       // and it points to the object on which click is called
        var url = $(this).attr("data-url");
        alert(url);
    });
    

    But above is too general. It will fail if you have tables having other links a where you do not want to fire the even so better approach is following

    Id only works for one element. For a set of elements (e.g. multiple links). You need to use the class and access them by class as well.

    I replaced your id with class and accessed it with that name as well.

    grid.GetHtml(tableStyle: "table table-striped table-bordered",
                headerStyle: "thead-default",
                columns: grid.Columns(
    grid.Column("post_tran_a", Model.year_a, canSort: false, format: (item) =>
        new HtmlString(Html.CheckBox("post_tran_a", 
    (bool)item.post_tran_a.is_reviewed, new { disabled = "disabled" })
                        + " " +
    Html.ActionLink((string)item.post_tran_a.month, "PostTransmission",
    Model.controller, new { report_id = item.post_tran_a.report_id, link = item.post_tran_a.link },
    
    // See following carefully
    new { @class="someuniquecalssname" data_url=Url.Action() })))))
    

    Now the javascript will work fine

    $(".someuniquecalssname").click(function () {
        var url = $(this).attr("data-url");
        alert(url);
    });
    

    If you are not willing to add class attribute then, Creating Unique Ids like ex-link1, ex-link2 could be possible in many cases. But they are useless for an event like above