Jared Jared - 1 month ago 11
C# Question

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.

Answer

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