4

I have a table that is created in ASP.NET C# code behind. The table has several levels of groupings, and when I create the rows for the outer most grouping, I add an custom attribute as follows:

foreach (Table2Row row in Table2Data)
{
    // skipping a bunch of irrelevent stuff
    ...
    tr_group.Attributes.Add("RowsToToggle", String.Format(".InnerRowGroupId_{0}", row.GroupHeaderId));
    ...
}

The attribute is the CSS class name of the inner level rows that I would like to toggle. When the user clicks on the outer level row, I would like to call JQuery Toggle function for all inner level rows that match the custom attribute.

To achieve that effect, I have attached an onclick event to the header rows with the following script in the aspx file:

var tableId = '<%= Table2MainTable.ClientID %>';
$(document).ready(function () {
    var table = document.getElementById(tableId);
    var groupRows = table.getElementsByClassName("Table2GroupHeaderRow");
    for (i = 0; i < groupRows.length; i++) {
        table.groupRows[i].onclick = function () { ToggleOnRowClick(table.rows[i]); }
    }
});

function ToggleOnRowClick(row) {
    var r = $('#' + row.id);
    var innerRows = r.attr('RowsToToggle');
    $(innerRows ).toggle();
}

So, clicking anywhere on the header row should call the function ToggleOnRowClick, which should then toggle the set of rows below it via the custom attribute RowsToToggle.

When I set a (FireBug) break point in the ToggleOnRow function, the variable r appears to be pointing to the correct object. However, innerRows is not getting set but instead remains null. So am I setting the custom attribute incorrectly in ASP.NET or reading in incorrectly in JQuery?

5
  • 2
    What does the rendered table look like? That's where you'll find your answer. Commented Sep 17, 2013 at 13:27
  • what does variable cssClass contain when debugging ? Commented Sep 17, 2013 at 13:28
  • Are you sure you don't want to be using the class functions and not the attribute functions? (api.jquery.com/category/manipulation/class-attribute) Commented Sep 17, 2013 at 13:31
  • cssClass contains the Class name that was assigned to all of the rows that I'd like to toggle. The row being clicked on is the outer grouping. It contains an inner table. Its the rows of the inner table that I'm trying to toggle. Commented Sep 17, 2013 at 13:54
  • Do you actually see the RowsToToggle attribute in the html of the rendered page? Commented Sep 19, 2013 at 17:05

4 Answers 4

2
+50

You did not post the code to generate inner level rows, I am assuming you sat proper classes to them.

There are few issues with the jquery you posted. This line wouldn't work:

   table.groupRows[i].onclick = function () { ToggleOnRowClick(table.rows[i]); }
  1. You don't have any groupRows property defined for table object.
  2. We don't care about table row anymore, we care about groupRows[i] and want to pass it to ToggleOnRowClick function.
  3. This line in next function is also wrong:var r = $('#' + row.id);

Solution: Change your script to this:

var tableId = '<%= Table2MainTable.ClientID %>';
$(document).ready(function () {
    var table = document.getElementById(tableId);
    var groupRows = table.getElementsByClassName("Table2GroupHeaderRow");
    for (i = 0; i < groupRows.length; i++) {
        groupRows[i].onclick = function () { ToggleOnRowClick(this); }
    }
});

function ToggleOnRowClick(row) {
    //var r = $('#' + row.id);
    var innerRows = $(row).attr('RowsToToggle');
    $("." + innerRows).toggle();
}

I have tested the code with dummy data. So if you have any issue, PM me.

Sign up to request clarification or add additional context in comments.

4 Comments

Why have jquery and yet continue to use getElementsByXXX. Could this also be improved by using JQuery on?
@Zholen - good catch! I agree, and I would do it to suggest a new solution. Here I am only fixing OP's code, keeping working portion of his code.
I agree this is mostly likely the solution. Google "Javascript hoisting" if it's not clear why.
This is nothing to do with hoisting... It's a classic event handler in a loop with a closure problem.
1

This line is your culprit:

table.groupRows[i].onclick = function () { ToggleOnRowClick(table.rows[i])

By the time the event handler runs, table.rows might still exist, but i will be set to groupRows.length+1, which is out of bounds for the array. The handler will get called with an argument of undefined.

Remember, Javascript is an interpreted language! The expression "table.rows[i]" will get interpeted when the handler runs. It will use the last value of i (which will still be set to the value that caused your for loop to end, groupRows.length+1).

Just use

    table.groupRows[i].onclick = function () { ToggleOnRowClick(this) }

Comments

0

So, First you shouldn't use custom attributes... they are a sin!

Please use data attributes instead, so that is what I'm going to use in the code, should be an easy fix regardless.

If this doesn't work then I'd be very very interested in seeing a dumbed down HTML snippet of the actual output.

$(document).ready(function () {

    $('#MYTABLE').on('click', '.Table2GroupHeader', function() {
      var attr_if_you_insist_on_sinning = $(this).attr("RowsToToggle");
      var data_if_you_like_not_sinning = $(this).data("RowsToToggle");
      //if the row is like <tr data-RowsToToggle=".BLAH" or th etc

      //asumming you set the attribute to .BLAH then:
      var rows_to_toggle = $(data_if_you_like_not_sinning);
      rows_to_toggle.toggle();

      //assuming you set it to BLAH then:
      var rows_to_toggle = $("."+ data_if_you_like_not_sinning);
      rows_to_toggle.toggle();
    });

});

Comments

-1
$(document).ready(function () {

    $('#<%= Table2MainTable.ClientID %> .Table2GroupHeader').each(function(){
        $(this).click(function(){
            $(this).toggle();
        });

    });

});

4 Comments

see my comment above. I'm not trying to Toggle (this). I'm trying to toggle $('.SomeOtherRows'). The custom attribute has the value of '.SomeOtherRows'. For example, on Row 155, it would have the value of '.Table2DataGroup_155' as assigned in the C# code at the top.
@SteveWash Why vote down. Just change your code where want to do something different.
The question is all about the custom attribute. That's where I need the help. You answer doesn't help me in any significant way. Its a little more concise but doesn't address the problem.
$(this).toggle(); So change this thing to -> $(this).attr('customAttr','yourvalue');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.