5

I am currently learning C# Blazor framework and I am faced with question, how to get HTML element I clicked on?

I need it to get it's position in DOM and in parent HTML element.

For example, classic way with JQuery:

$('selector').click(function (event) {
    alert($(this).index());
});

http://jsfiddle.net/bCTAh/

I know, that there is @onclick attribute in Blazor, for example:

<tr @onclick="OnYes">...</tr>

@functions {
    ElementReference inputTypeFileElement;

    public async Task MainTableOnClick(MouseEventArgs e)
    {
        Console.WriteLine("clicked!");
    }
}

How can I get index of TR HTML element that was clicked on?

My task is convert Windows Form app to Web-version. The old Windows Form has DataGridView, each row of that has onClick event and Tag Object too. When some of row of the DataGridView clicked, onClick get's Tag Object of the row and used it to fill data to another DataGridView's on the form. So, I need to know, what row clicked to get data from some object (it can be DataTable, or, to be more simply, Array). Based on index of row and index in Array, I need to get data for filling another tables on Web Page.

So, first table is Clients (name, surname, etc...).

When some of row with Client has been clicked, I need to get row (Client) index in the table. By that index I'll get data from Array of Clients. By found Client object I plan to fill another tables on the page dynamically.

Arthur
  • 3,253
  • 7
  • 43
  • 75
  • 3
    XY problem? Can you explain why you need the html element in the first place? – Postlagerkarte Nov 20 '19 at 16:59
  • Not XY problem, I need to find position of the first element within the set of matched elements in relation to its siblings - https://api.jquery.com/index/ – Arthur Nov 21 '19 at 07:25

2 Answers2

12

In this case, you can use JSInterop

Or

<tr @onclick="() => TrClickedAtIndex(0)">...</tr>

@code {
    ElementReference inputTypeFileElement;

    public void TrClickedAtIndex(int index)
    {
        Console.WriteLine($"tr clicked at index {index}!");
    }
}

agua from mars
  • 16,428
  • 4
  • 61
  • 70
  • Ie, it's not possible to get index in Jquery-like style, from DOM, without passing element index (int) in method parameters? – Arthur Nov 21 '19 at 07:22
  • I wonder why you need to have the index actualy, maybe there's some other way to implement the behavior you need without to access the index. – agua from mars Nov 21 '19 at 07:27
  • My task is convert Windows Form app to Web-version. The old Windows Form has DataGridView, each row of that has onClick event and Tag Object too. When some of row of the DataGridView clicked, onClick get's Tag Object of the row and used it to fill data to another DataGridView's on the form. So, I need to know, what row clicked to get data from some object (it can be DataTable, or, to be more simply, Array). Based on index of row and index in Array, I need to get data for filling another tables on Web Page. – Arthur Nov 21 '19 at 08:35
  • OK, I'll do it now. – Arthur Nov 21 '19 at 08:37
  • Basically, I think you can pass the reference of your object instead of using index. Because you're going to construct your table using foreach loop on your arrays, right ? – agua from mars Nov 21 '19 at 08:39
  • Question updated. How can I pass reference to object in Blazor? ) Yep, my code is ` @foreach (var line in dataGridView1) { @foreach (var col in line.cols) { @col } } ` – Arthur Nov 21 '19 at 08:42
  • 1
    using @, for exemple: `@foreach (var line in dataGridView1) { OnYes(line)> @foreach (var col in line.cols) { ColLineClicked(col, line)" > @col ...` – agua from mars Nov 21 '19 at 08:46
  • Interesting, very interesting. It works now: ` @foreach (var line in dataGridView1) { MainTableOnClick(line)"> @foreach (var col in line.cols) { @col } } ` ... `public async Task MainTableOnClick(TableRow tr) { Console.WriteLine("!!! "+tr.Tag); }` But if I am looking in Developer tools of Chrome - Network - there is no requests on clicks! – Arthur Nov 21 '19 at 08:54
  • But Windows Console prints data! How it passed data between Google Chrome and my app, if it didn't make any requests between browser and my app (server)? – Arthur Nov 21 '19 at 08:55
  • Oh, I see, it uses WebSocket to communicate. Cool! Thank you again! – Arthur Nov 21 '19 at 08:59
8

If you want to get the element you can use a @ref to return an element, but generally in Blazor you're not interest in the elements (as you might in JQuery) but what they relate to.

I created this simple BlazorFiddle that lists three strings in a table. It's similar to the other answer but it demonstrates a little wrinkle - when passing a value from a loop or enumeration you need to assign it.

https://blazorfiddle.com/s/br8lwsl2

This shows a table for three strings. When you click a row, it passes the data item from the clicked row - not just an index.

    int index = i;
    <tr @onclick="()=> ClickedRow(list[index])" ><td>

Hope this helps

Quango
  • 12,338
  • 6
  • 48
  • 83
  • 1
    Quite useful hint to use a quick assignment in such case, useful fiddle! – Giancarlo Sierra Apr 10 '20 at 18:52
  • 1
    I find this solution much better than using JSInterop for everything. The entire point of Blazor is not having to resort to JS for these kinds of simple issues. This should be the accepted answer – Christoph B Nov 18 '20 at 07:53