vondip
vondip

Reputation: 14029

jquery - get elements in a specified columns of an html table

Using jquery, I'd like to get all elements in a specified columns of an html table. Please note that it can be more than one column

For example, if I have the following html table:

<table>
   <tr> 
    <td>
      a
    </td>
    <td>
      b
    </td>
    <td>
      c
    </td>
   </tr>
   <tr> 
    <td>
      1
    </td>
    <td>
      2
    </td>
    <td>
      3
    </td>
   </tr>
</table>

which looks as following:

1     2      3
a     b      c

I would like to get 1, 3, a , c

How should I do it? What would be the most efficient way to do so? (I am traversing a huge table generated by some reporting utility)

Upvotes: 7

Views: 25006

Answers (6)

Javascipt alternative. Two functions that can be used independently

  • First, The function that return the column by given the index column
  • Second, the function that will use the function before, but you will pass the number of column that you want to return (using varargs)

const table = document.querySelector("table");
// geting the first and third column
let elementsFromColumn = getAllElementsOfMultiplesColumn(table, 0,2);

//Just to print the values
let elementsFromColumnToString = elementsFromColumn.join();
console.log("Get first and third column elemets:",elementsFromColumnToString); // a,1,c,3

// geting the third and second column
elementsFromColumn = getAllElementsOfMultiplesColumn(table, 2,1);
elementsFromColumnToString = elementsFromColumn.join();
console.log("Get third and second column elements:",elementsFromColumnToString);

// geting just the first column
elementsFromColumn = getAllElementsOfMultiplesColumn(table, 0);
elementsFromColumnToString = elementsFromColumn.join();
console.log("Get just first column elements:",elementsFromColumnToString);

// geting all column
elementsFromColumn = getAllElementsOfMultiplesColumn(table, 0, 1, 2);
elementsFromColumnToString = elementsFromColumn.join();
console.log("Get first, second and third column elements:",elementsFromColumnToString);

/**
 * 
 * @param {Object} table The tableDOM element
 * @param {Number} columnIndex The column index
 * @returns Array containes the elments of a column chosen by columnIndex
 */
function getColumnElementsByColumnIndex(table, columnIndex) {
    const tableRows = table.querySelectorAll("tr");
    let columnElements = [];

    for (let row of tableRows) {
        let rowElements = row.querySelectorAll("td");
        columnElements.push(rowElements[columnIndex].innerText);
    }

    return columnElements;
}

/**
 * 
 * @param {Object} table: The Table DOM element 
 * @param  {...number} indexesColumn: the indexes of the column 
 * @returns Array[][] represent the columns chosen by indexes
 */
function getAllElementsOfMultiplesColumn(table, ...indexesColumn) {
    let elementsSelectedByColumn = [];
    const numberOfColumn = table.querySelectorAll("tr").length;

    indexesColumn.forEach((indexColumn)=>{
        if(indexColumn > numberOfColumn) throw Error(`the column indexe: ${indexColumn} is out of bound`);
        if(typeof indexColumn !== "number") throw Error("The indexeColumns must be a number type");
    });

    for (let indexeColumn of indexesColumn) {
        elementsSelectedByColumn.push(getColumnElementsByColumnIndex(table, indexeColumn));
    }

    return elementsSelectedByColumn;
}
<table>
    <tr>
        <td>
            a
        </td>
        <td>
            b
        </td>
        <td>
            c
        </td>
    </tr>
    <tr>
        <td>
            1
        </td>
        <td>
            2
        </td>
        <td>
            3
        </td>
    </tr>
</table>

<script src="./findElementInColumn.js"></script>

If you want that the function return the DOM element instead of the innerText, just remove the innerText from the first function, like so:

columnElements.push(rowElements[columnIndex]);

Upvotes: 0

sergio
sergio

Reputation: 1

you can do like this

var retorno=[];
linha=$("td:nth-child(1), td:nth-child(3)").clone().each(function(){retorno.push($(this).text())});

$.each(retorno,function(index, item) {$('#Console').append(item+', ');});

1-use clone to not modify table, if you remove table modify after this line. 2-put elements into retorno array 3-use each for print inside element Console

you can make too like this. with one line:

$("td:nth-child(1), td:nth-child(3)").clone().map(function(){ return $(this).text()}).get().join(',');

map - create array with return columns get - get the array join - chang array in line separete with comma and show

1,3,a,c

it's the best i can do.

Upvotes: 0

Arun
Arun

Reputation: 3077

You can do it with a selector using nth-child. The following is another way.

$("TABLE").find("tr").each(function(){
    var tr = this;
    $([0,2]).each(function(){
        alert($(tr[this]).html());
    });
});

For 1st and 3rd you'll have to specify 0, 2

Upvotes: 1

Shadow Wizard
Shadow Wizard

Reputation: 66389

Here is more or less generic example letting you define the desired indices as array:

var cellIndexMapping = { 0: true, 2: true };
var data = [];

$("#MyTable tr").each(function(rowIndex) {
    $(this).find("td").each(function(cellIndex) {
        if (cellIndexMapping[cellIndex])
            data.push($(this).text());
    });
});

$("#Console").html(data.join("<br />"));

Test case: http://jsfiddle.net/yahavbr/FuDh2/

Using associative array to have faster performance, as far as I know search for specific item in such array should be optimized already.

Note that in JS first index is always 0, so 1st and 3rd cells means indices 0 and 2.

Upvotes: 10

Kaivosukeltaja
Kaivosukeltaja

Reputation: 15735

You can use the :nth-child() selector.

$("tr td:nth-child(1), tr td:nth-child(3)").css('color', 'red');

Upvotes: 12

John Fisher
John Fisher

Reputation: 22719

var table = $("table"); // Make this more accurate if there are multiple tables on the page
var rows = table.find("tr");  // Will find too much if there are <tr> tags nested in each other

for (var i=0; i=rows.length; ++i) {
  var cells = rows.eq(i).find("td");
  var values = [cells.eq(0).text(), cells.eq(2).text()];
}

Upvotes: 2

Related Questions