Fandango68
Fandango68

Reputation: 4868

How to refer to Parent Gridview from Checkbox in jQuery

This function works. It's a quick way of selecting all the checkboxes in a GridView from the checked status of the header checkbox, and for only a specific column.

//jQuery to select all checkboxes on the last column (4th column) of gvStudents
function SelectAllCheckboxesCol(chk) 
{
    //var gV = chk.parent;
    var wsList = "#<%=gvStudents.ClientID %> >tbody >tr >td:nth-child(4) > input:checkbox";
    var cBox = $(wsList);
    cBox.attr('checked', chk.checked);  //check all the checkboxes
}

I don't like hard-coding in the gvStudents nor the column number 4.

How can I re-write this to be more dynamic - ie: to bring in the Gridview and n-th column number?

Here was my attempt but I get literal and no object reference errors.

//jQuery to select all checkboxes on the last column (4th column) of gvStudents
function SelectAllCheckboxesCol(chk) 
{
    var gV = chk.parent; // assume this brings in the Gridview?
    var wsList = "#<%=" + gV.CliendID + " %> >tbody >tr >td:nth-child(4) > input:checkbox";
    var cBox = $(wsList);
    cBox.attr('checked', chk.checked);  //check all the checkboxes
}

Thanks

Upvotes: 0

Views: 1146

Answers (2)

Fandango68
Fandango68

Reputation: 4868

[SOLVED] I solved this by doing more research and finding the power of CSS for myself. I have no idea why I didn't consider CSS in the first place.

I created the following CSS to handle gridview formatting.

<style type="text/css">
    .arial { font-family: Arial; font-size: small; }
    .table { font-family: Arial; font-size: small; background-color: #eeeeee; margin-right: 10px; display: inline; vertical-align: top; }
    .header { text-align: center; background-color: #5D7B9D; color: White; font-weight: bold; font-size: medium; }

    table.gvCSS {
      margin-top: 50px;
      font: 12px Verdana;
    }

    table.gvCSS > tbody > tr {
      background-color: white;
    }

    table.gvCSS > tbody > tr:nth-of-type(odd) {
      background-color: #EEE;
    }

    table.gvCSS > tbody > tr:first-of-type {
      background-color: #5D7B9D;
      color: white;
    }

    table.gvCSS > tbody > tr.selected-row {
      background-color: yellow;
    }

    table.gvCSSsub > tbody > tr.selected-row {
      background-color: lightgreen;
    }

    table.gvCSS tr td {
      padding: 4px 15px;
    }

    /* ******** */

    #gvCSS > tbody > tr > td:nth-of-type(1) {
      width: 100px;
    }

    #gvCSS > tbody > tr > td:nth-of-type(2) {
      width: 70px;
    }

    #gvCSS table > tbody > tr > td:nth-of-type(1) {
      width: 120px;
    }

    #gvCSS table > tbody > tr > td:nth-of-type(2) {
      width: 100px;
    }

    #gvCSS table > tbody > tr > td:nth-of-type(3) {
      width: 100px;
    }
</style>

I then implemented the following JavaScript to check all checkboxes along the same column (hence avoiding a global find and set situation, which is the common response), and able to highlight rows within a nested gridview separately from the checkboxes and rows on the parent GridView.

    //################################################################################################################
    //The code below came from a question into StackExch and a response from user @Buzinas.
    //URL - http://stackoverflow.com/questions/32773892/how-to-pass-gridview-ids-and-other-controls-into-jquery-functions
    function gridViewCheckAll(chk) {
      var cell = chk.parentNode;
      var row = cell.parentNode;
      var tbody = row.parentNode;
      var rows = tbody.children;

      var index = [].indexOf.call(row.children, cell);

      for (var i = 1; i < rows.length; i++) {
        var checkBoxes = rows[i].children[index].querySelectorAll('input[type=checkbox]');

        for (var j = 0; j < checkBoxes.length; j++) {
            checkBoxes[j].checked = chk.checked;
            highlightRow(checkBoxes[j]);
        }
      }
    }

    function highlightRow(chk) {
      var row = chk.parentNode.parentNode;  //go to the <td> of the checkbox and then again to the <tr> of the <td>, which is the row
      if (chk.checked)
        addClass(row, 'selected-row');
      else
        removeClass(row, 'selected-row');
    }
    //################################################################################################################

As an added bonus I found the following shims, which allow the above JavaScript to work across all browsers from IE7 onwards.

// Add ECMA262-5 method binding if not supported natively
//
if (!('bind' in Function.prototype)) {
    Function.prototype.bind= function(owner) {
        var that= this;
        if (arguments.length<=1) {
            return function() {
                return that.apply(owner, arguments);
            };
        } else {
            var args= Array.prototype.slice.call(arguments, 1);
            return function() {
                return that.apply(owner, arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments)));
            };
        }
    };
}

// Add ECMA262-5 string trim if not supported natively
//
if (!('trim' in String.prototype)) {
    String.prototype.trim= function() {
        return this.replace(/^\s+/, '').replace(/\s+$/, '');
    };
}

// Add ECMA262-5 Array methods if not supported natively
//
if (!('indexOf' in Array.prototype)) {
    Array.prototype.indexOf= function(find, i /*opt*/) {
        if (i===undefined) i= 0;
        if (i<0) i+= this.length;
        if (i<0) i= 0;
        for (var n= this.length; i<n; i++)
            if (i in this && this[i]===find)
                return i;
        return -1;
    };
}
if (!('lastIndexOf' in Array.prototype)) {
    Array.prototype.lastIndexOf= function(find, i /*opt*/) {
        if (i===undefined) i= this.length-1;
        if (i<0) i+= this.length;
        if (i>this.length-1) i= this.length-1;
        for (i++; i-->0;) /* i++ because from-argument is sadly inclusive */
            if (i in this && this[i]===find)
                return i;
        return -1;
    };
}
if (!('forEach' in Array.prototype)) {
    Array.prototype.forEach= function(action, that /*opt*/) {
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this)
                action.call(that, this[i], i, this);
    };
}
if (!('map' in Array.prototype)) {
    Array.prototype.map= function(mapper, that /*opt*/) {
        var other= new Array(this.length);
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this)
                other[i]= mapper.call(that, this[i], i, this);
        return other;
    };
}
if (!('filter' in Array.prototype)) {
    Array.prototype.filter= function(filter, that /*opt*/) {
        var other= [], v;
        for (var i=0, n= this.length; i<n; i++)
            if (i in this && filter.call(that, v= this[i], i, this))
                other.push(v);
        return other;
    };
}
if (!('every' in Array.prototype)) {
    Array.prototype.every= function(tester, that /*opt*/) {
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this && !tester.call(that, this[i], i, this))
                return false;
        return true;
    };
}
if (!('some' in Array.prototype)) {
    Array.prototype.some= function(tester, that /*opt*/) {
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this && tester.call(that, this[i], i, this))
                return true;
        return false;
    };
}

function hasClass(ele,cls) {
  return !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}

function addClass(ele,cls) {
  if (!hasClass(ele,cls)) ele.className += " "+cls;
}

function removeClass(ele,cls) {
  if (hasClass(ele,cls)) {
    var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
    ele.className=ele.className.replace(reg,' ');
  }
}

Upvotes: 0

Muhammed Shevil KP
Muhammed Shevil KP

Reputation: 1396

Why can't you add a jquery change event handler to your Select All checkbox? give a proper id to that checkbox, then handle it say id as chkSelectAll

$("#chkSelectAll").change(function(e){
      var check = $(this).is(':checked');
      $(this).parents('gvDiv').find('input:checkbox').prop('checked', check);
)};

where gvDiv is the parent div which holds the gridview

so try this way

function SelectAllCheckboxesCol(chk, celpos) {
    var gV = chk.parents('table'); // assume this brings in the Gridview?
    var wsList = $(gV).find("tbody >tr >td:eq(" + celpos + ") > input:checkbox";
    var cBox = $(wsList);
    cBox.attr('checked', chk.checked); //check all the checkboxes
}

pass checkbox column position also

Please check the Fiddle

Upvotes: 1

Related Questions