JQuery selectors – selecting elements by a partial id

Recently a coworker had a grid like the one below in an ASP.Net page. He wanted me too see if there was any way to make the javascript the manages the checkboxes easier to maintain.

CheckboxGrid +

The checkboxes on the left check or uncheck the day check boxes for the corresponding row. When the checkbox next to Barney Rubble is checked the grid looks like this:

CheckboxGridDays

The SO button checks all signoff checkboxes in the grid and when it is clicked the grid looks like this:

CheckboxGridDaysSO

The original programmer had a load of javascript to select the day checkboxes for the row, and to select all of the signoff checkboxes he did a post back to do the work on the server.

Right away I knew this would be easy to do with JQuery. The only problem that I had was how to get just the day checkboxes or just the signoff checkboxes. Luckily, all of the day checkbox Ids had the word “Day” in them and the signoff checkboxes had the words “IsSignedOff” in their Ids.

Here is how I check all of the day checkboxes in the row that the select all checkbox resides in:

The function call from the select all checkbox’s onclick event:

 

<input id="ctl00_ContentPlaceHolder1_grdTest_ctl03_SelectAll" type="checkbox" onclick="javascript:onSelectAll(this);" name="ctl00$ContentPlaceHolder1$grdTest$ctl03$SelectAll" />

I pass “this”, which is the checkbox, to the function. Now for the function that does the work:

function

onSelectAll(checkbox) {

 

var cb = $("#" + checkbox.id);

 

var td = cb.parent("td");

 

var tr = td.parent("tr");

tr.children().children(

"input:checkbox[id*=Day]").attr('checked', cb.attr('checked'));

}

Let’s break the function down. It has to get checkboxes with html like this:

<td style="border-color: Black; border-style: Solid;">

<input id="ctl00_ContentPlaceHolder1_grdTest_ctl03_Day1" type="checkbox" name="ctl00$ContentPlaceHolder1$grdTest$ctl03$Day1" />

</td>

The actual select all checkbox is passed as an argument. I then get the JQuery handle to that checkbox by using a JQuery id selector built using the actual id of the checkbox passed in.

Next I get the TD that contains the select all checkbox using the JQuery parent function on the checkbox. Then I get the TD’s parent row using the JQuery parent function on the TD.

Now that I have the rows I can get all of the checkboxes that are descendent children of that row, but I only want the checkboxes that contain the string “Day” in their ids. Remember, that last checkbox in the row has “IsSignedOff” in it’s id and the first one in the row is the select all checkbox.

Using a css selector of input:checkbox[id*=Day] says give me the input controls that are of type checkbox that have an id that contains the string “Day”. The *= is the JQuery operator for contains.

So this function gets me all of the day checkboxes and sets their checked attribute to the checked attribute of the select all checkbox that initiates the function call.

The last piece is to get the is signed off checkboxes in all rows, one per row. This is really easy. The button html looks like this:

<input type=”button” onclick="javascript:checkSignOffs();" value=”Sign Off” />

The function is this:

function

checkSignOffs() {

$("#grdTest input:checkbox[id*=IsSignedOff]").attr('checked', true);

}

It has to get checkboxes with html like this:

 

<input id="ctl00_ContentPlaceHolder1_grdTest_ctl03_IsSignedOff" type="checkbox" name="ctl00$ContentPlaceHolder1$grdTest$ctl03$IsSignedOff" />

The selector says for a table with an id of “grdTest”, get me the input controls of type checkbox that have an id that contains the string “IsSignedOff”. When JQuery gets the set of checkboxes, set the checked attribute of each one to checked.

Not  bad for a few lines of code. Now maintenance will be much easy. We ripped out alot of javascript, removed a post back and best of all, I now have JQuery in another application.

If anyone has a cleaner, more concise way of doing this please leave a comment. I know I can get the table row in the first set of code easier, I just need to figure it out. I will post an update when I do. I was in a hurry to share this :0)

6 Comments

  • This post is really an angel for me.. It solved my great problem

  • This reads like a really long-winded description of the "contains" operator. Regarding the onclick attributes, convention dictates those should never be mixed in with markup when using jQuery;

  • @Rick - I solved a problem that a coworker had without making him redo his page. I don't see how this is long winded, I gave a good example of the problem and the solution.

    Please share with the community how you would have done it.

    Thanks for commenting.

  • You really ROCK!!!... saved my day ;)

  • // no change here except for avoiding the onclick attribute
    $('input[value=SO]').bind('onclick', function() {
    $("#grdTest input:checkbox[id*=IsSignedOff]").attr('checked', true);
    });

    // this one is a little different * completely untested but you get the idea
    $('input[value*=SelectAll]').bind('onclick', function() {
    var $this = $(this);
    var checked = $this.attr(checked);
    $this.parents('tr:first').find(input[id*=Day]).attr('checked', checked );
    });

  • Very useful JQuery tip for manipulating .net generated element ID's !

Comments have been disabled for this content.