react-bootstrap-table | header column alignment fix

I am working with react-bootstrap-table. Its a great module with few teething problem. for example whenever I have a lots of columns (in the table) my header column is misaligned with the columns in the dataarea.

example: (before the fix)


after applying the fix ( note that now you have a scroll bar too)


Reason for the problem:
In react-bootstrap-table "header" is a table and the data is another table. Since they are 2 different tables sometimes the header column width gets misaligned from the column of data table.

Fix-Logic applied:
The idea is simple,

  1. First I allow the table to be rendered as it is 
  2. Then first adjust the width of the data table columns using the width of the respective header column width. But remember only for the columns whose width is lesser than the header respective column width. 
  3. Now get the width of all data-columns and set the same to the width of the respective header columns.
and tadaaaa the table in perfect alignment now.

Steps to do:
  • Know that his only works for STRIPED data table (ie the rows with alternate colors)
  • copy the following CSS to your CSS file. If you dont have one create one and add it to your html page. ( its easy like you add any other css file)
/*-----------------------------
** Reactjs
**-----------------------------------*/
div.react-bs-table-container{
    overflow: auto;
}

.table>thead>tr>th {
    background-color: #616161;
    color: white;
}
.table-hover>tbody>tr:hover{
    background-color:#E3EEF5;
}
.table{
   margin-bottom:0px;
}
.table-striped{
   width: auto;
}
.h1class{
    text-align:center
}

td, th {
    padding: 0;
    white-space: nowrap;
}
  • Copy the below function into some .js file and call this after you reder your
  • function myReactBootstrapTable_adj(){
    
        //---fix the data table based on the header if the header size is greater than the column width(datatable)
        var tables = document.getElementsByClassName("table");
        console.log( "total no of tables", tables.length )
        console.log( tables )
    
        var l_header_table = null;
        var l_row_table = null;
        var l_wd = null;
        for ( var i = 0; i < tables.length; i++){
            console.log( "---total no of tables", tables.length )
            console.log( "tables ----------------------------------", i)
            if (i%2 == 0){ //header
                console.log("header", i)
                l_header_table = tables[i]
            }else{ // row table
                console.log("row", i)
                l_row_table = tables[i]
                var first_row = l_row_table.getElementsByTagName("TR")[0];
                var tds = first_row.getElementsByTagName('TD');
                var larr_col_size = []
                for ( var j = 0; j < tds.length; j++){ // width of each cell
                    console.log( tds[j].innerText, tds[j].style.width, tds[j].style.offsetWidth, tds[j].getBoundingClientRect().width)
                    larr_col_size.push(tds[j].getBoundingClientRect().width)
                }
    
                console.log(l_row_table )
                console.log(larr_col_size)
                console.log(l_header_table)
    
                var first_row = l_header_table.getElementsByTagName("TR")[0];
                var h_tds = first_row.getElementsByTagName('TH');
                for ( var k = 0; k < h_tds.length; k++){ // each cell
                    console.log( h_tds[k].innerText, larr_col_size[k])
                    l_wd = h_tds[k].getBoundingClientRect().width
                    console.log( l_wd, ' ...>... ', larr_col_size[k] )
                    if (  l_wd > larr_col_size[k]){// if header width is greater than row width then apply that to row
                        tds[k].style.width = l_wd+'px'
                        tds[k].style.minWidth  = l_wd+'px'
                    }else{
                        tds[k].style.width = larr_col_size[k]+'px'
                        tds[k].style.minWidth  = larr_col_size[k]+'px'
                    }
    
                }
    
            }
        }
    
        //---fix the header table based on column width in the data table
        var tables = document.getElementsByClassName("table");
        console.log( tables )
    
        l_header_table = null;
        for ( var i = 0; i < tables.length; i++){
            console.log( "tables *******************************************-", i)
            if (i%2 == 0){ //header
                console.log("header", i)
                l_header_table = tables[i]
            }else{ // row table
                console.log("row", i)
                l_row_table = tables[i]
                var first_row = l_row_table.getElementsByTagName("TR")[0];
                var tds = first_row.getElementsByTagName('TD');
                var larr_col_size = []
                for ( var j = 0; j < tds.length; j++){ // width of each cell
                    console.log( tds[j].innerText, tds[j].style.width, tds[j].style.offsetWidth, tds[j].getBoundingClientRect().width)
                    larr_col_size.push(tds[j].getBoundingClientRect().width)
                }
                console.log(l_row_table )
                console.log(larr_col_size)
                console.log(l_header_table)
                var first_row = l_header_table.getElementsByTagName("TR")[0];
                var h_tds = first_row.getElementsByTagName('TH');
    
                for ( var k = 0; k < h_tds.length; k++){
                    console.log( h_tds[k].innerText, larr_col_size[k])
                    l_wd = h_tds[k].getBoundingClientRect().width
                    console.log( l_wd, ' __>__ ', larr_col_size[k] )
    
                    h_tds[k].style.width = larr_col_size[k]+'px'
                    h_tds[k].style.minWidth  = larr_col_size[k]+'px'
                }
    
            }
        }
    }
    
    exports.myReactBootstrapTable_adj = myReactBootstrapTable_adj; //public function
    
    

    Comments

    Unknown said…
    Where do i call the function from ?
    After my render(){...} ,
    or before my render(){...} ???
    Unknown said…
    this is my decision of this problem (css not needs):

    myReactBootstrapTable_adj() {

    //---fix the data table based on the header if the header size is greater than the column width(datatable)
    var tables = document.getElementsByClassName("table");

    if(tables.length == 2){
    let firstTableCol = tables[0].querySelectorAll('colgroup col');
    let secondTableCol = tables[1].querySelectorAll('colgroup col');
    if(firstTableCol.length == secondTableCol.length){
    for(let index = 0; index < firstTableCol.length; index++){
    firstTableCol[index].style.width = secondTableCol[index].style.width;
    }
    }else
    console.log('cols count mismatch');
    }else
    console.log('count of tables are bigger than 2');
    }

    Popular posts from this blog

    Tableau - Accessing Tableau's DB

    Django 1.8 | email as username