0

I need to get elements from a table that has header for each row. It is something like this:

<table>
    <td>
        <table>
            <tr>
                <th>Name</th>
                <th>Test name</th>
                <th>Percentage</th>
            </tr>
            <tr>....contents(multiple rows of marks for a candidate)........ </tr>
        </table>
    </td>
    <td>
        <table>
            <tr>
                <th>Name</th>
                <th>Test name</th>
                <th>Percentage</th>
            </tr>
            <tr>....contents(multiple rows of marks for a candidate)........ </tr>
        </table>
    </td>
    <td>
        <table>
            <tr>
                <th>Name</th>
                <th>Test name</th>
                <th>Percentage</th>
            </tr>
            <tr>....contents(multiple rows of marks for a candidate)........ </tr>
        </table>
    </td>
</table>

So basically each row of the main table is a table consisting of multiple rows with its own header. I need to get elements of each row table on click on header. I must do this using vanilla Javascript. I should not use any jquery related plugin. That is the requirement. So how can I access each row on clicking the header for that row? At present the className for each row is the same. So when I use getElementsByClassName, I get multiple times of each row. For eg: if there are five rows then I get 5 times of each rows equaling 25 times on each click. If I use setAttribute function then I get the rows only the first time I click the button because I change the className. So how should I go about solving this problem?

getTable.js

th = document.getElementsByTagName('th');


for(let c=0; c < th.length; c++){
    th[c].addEventListener('click',item(c));
}


function item(c){    
    return function(){
        console.log(c);
        sortTable(c);
    }
}

function sortTable(c) {
    let table;
    table = Array.prototype.slice.call(document.getElementsByClassName("the_assessments"));
    for(let j=0; j<table.length; j++) {
        table[j].setAttribute("class","assessment_table");
        console.log(table[j]);
}
10
  • 1
    Please add the code that you've tried so far. Commented May 20, 2019 at 4:38
  • I have added the javascript code. Commented May 20, 2019 at 4:48
  • In the present code I am trying to access the rows. I haven't added the sorting function yet. Commented May 20, 2019 at 4:54
  • 1
    Your html is not valid as it is: tables cannot have table elements as direct children. They need to be placed within a <tr> and a <td>. Commented May 20, 2019 at 4:56
  • And having to do this kind of thing in Vanilla JS sounds to me like: "I have been told to re-invent the wheel" ;-) : Of course, it is possible, but does it make sense? Commented May 20, 2019 at 5:00

2 Answers 2

1

I filled your table structure with a little data to demonstrate how the (ascending) table sorting operation could be done in Vanilla JavaScript:

// get the three sub-tables:
var sortdir=-1,i,
    tbls=document.querySelectorAll('table table');
for (var i=0;i<tbls.length;i++) {
// get all rows from each sub-table and dismiss the first (=header) row:
// ( Array.prototype.slice is used to generate an Array from the collection element)
var rows=Array.prototype.slice.call(tbls[i].querySelectorAll('table tr'),1)
// sort by points in third column:
rows.sort((a,b)=>(a.querySelectorAll('td')[2].textContent
                 -b.querySelectorAll('td')[2].textContent)*sortdir);
// apply the order to the sub-table:
for (var j=0;j<rows.length;j++) tbls[i].appendChild(rows[j]);
}
td, th {vertical-align:top;text-align:left}
<table><tr>
        <td>
           <table>
                <tr>
                    <th>Name</th>
                    <th>Surname</th>
                    <th>Points</th>
                </tr>
                <tr><td>Harry</td><td>Potter</td><td>87</td></tr>
                <tr><td>Hermiony</td><td>Granger</td><td>93</td></tr>
                <tr><td>Ron</td><td>Weasley</td><td>78</td></tr>
                <tr><td>Neville</td><td>Longbottom</td><td>57</td></tr>
            </table>
        </td>
        <td>
            <table>
                <tr>
                    <th>Name</th>
                    <th>Surname</th>
                    <th>Points</th>
                </tr>
                <tr><td>Draco</td><td>Malfoy</td><td>86</td></tr>
                <tr><td>Kevin</td><td>Bletchley</td><td>77</td></tr>
                <tr><td>Pansy</td><td>Parkinson</td><td>82</td></tr>
            </table>
        </td>
        <td>
            <table>
                <tr>
                    <th>Name</th>
                    <th>Surname</th>
                    <th>Points</th>
                </tr>
                <tr><td>Tamsin</td><td>Applebee</td><td>36</td></tr>
                <tr><td>Anthony</td><td>Otterburn</td><td>69</td></tr>
                <tr><td>Diego</td><td>Caplan</td><td>76</td></tr>
            </table>
        </td>
</tr></table>

The three sub-tables containing Hogwart house members are sorted according to their points in column 3.

Please note the fact that appendChild() does not really "add" a DOM element to a table structure but "moves" it instead!

Edit "sorting order":

I added the global variable sortdir to demonstrate how to invert the sorting order. With a negative value the search order is now descending.

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

1 Comment

Thank you. That solved my problem. I wrote a code snippet to sort a basic table in ascending order but I am not able to figure out how to sort the same table in descending order on header click. I will open another question.
0

getElementsByClassName(“something”)[0], this will get only the first collection and not every single element with the class of “something”,

Finally for sorting it, I guess you can use some sorted build in function for it, all you need to do is to use an array or list or... to store the values and after sorting it, replace it with the original.

Sorry for not giving any code, I remember I’ve done it a long time ago and i’m in bed ready to sleep!

Comments

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.