Bipin Karkee
Bipin Karkee

Reputation: 43

jquery tablesorter not working on a dyanamically created table

My table sorter doesnt work. It says cannot read property of rows undefined. But I am not sure why its saying that. Using jquery.min.js and jquery.tablesorter.js. I have a table named tickettable. I set the class="tablesorter". I suspect its because the way i made the table. Documentation says it needs a tbody and thead. But I think I dont have a tbody and I am not sure how to append data to tbody. I get the data from the session and append it on the table.

<table id="tickettable" class="tablesorter">
                            <thead>             
                            <th style="width: 300px;">TicketID</th>
                            <th style="width: 300px;">CUID</th>
                            <th style="width: 600px;">Detail</th>
                            <th style="width: 300px;">Severity</th>
                            <th style="width: 300px;">Status</th>
                        </thead>
                    <tbody>

                    </tbody>

                </table>


<script>
    function makeTicketTable() {
        var ticketBody = document.getElementById("tickettable");
        console.log("Ticket body was made.");

        <c:forEach items="${ticketArray}" var="ticket">
        console.log("Array process.");
        var tr = document.createElement('TR');
        var rowNum = document.getElementById("tickettable").rows.length;
        tr.id = "r" + (rowNum - 1);
        tr.className = "ModalD";
        tr.title = "Click to edit: " + "${ticket.ticketid}";
        ticketBody.appendChild(tr);

        console.log("Click function made.");
        var td = document.createElement('TD');
        td.appendChild(document.createTextNode("${ticket.ticketid}"));
        console.log("${ticket.ticketid}");
        tr.appendChild(td);

        var td1 = document.createElement('TD');
        td1.appendChild(document.createTextNode("${ticket.CUID}"));
        tr.appendChild(td1);

        var td2 = document.createElement('TD');
        var details = "${ticket.detail}";
        details = details.substring(0, 50) + "...";
        td2.appendChild(document.createTextNode(details));
        tr.appendChild(td2);

        var td3 = document.createElement('TD');
        td3.appendChild(document.createTextNode("${ticket.severity}"));
        tr.appendChild(td3);

        var td4 = document.createElement('TD');
        td4.appendChild(document.createTextNode("${ticket.status}"));
        tr.appendChild(td4);

        //used for details section
        var hidIn = document.createElement('INPUT');
        hidIn.id = "${ticket.ticketid}";
        hidIn.type = 'hidden';
        hidIn.value = "${ticket.detail}";
        tr.appendChild(hidIn);

        if ("${ticket.status}" == "Unassigned") {
            tr.style.backgroundColor = "#ff4444";
            tr.style.color = "#000000";
        } else if ("${ticket.status}" == "Ongoing") {
            tr.style.backgroundColor = "#ffbb33";
            tr.style.color = "#000000";
        } else if ("${ticket.status}" == "Completed") {
            tr.style.backgroundColor = "#00C851";
            tr.style.color = "#000000";
        }

        </c:forEach>

Upvotes: 1

Views: 1089

Answers (2)

Bipin Karkee
Bipin Karkee

Reputation: 43

Thanks everyone. I fixed my problem. I edited my JavaScript code. I appended my data to tbody. I used the table sorter by kyyogenix. It did not sort before because my data were being appended to the footer.

function makeTicketTable() {
        var ticketBody = document.getElementById("tickettable");
        var tableRef = ticketBody.getElementsByTagName('tbody')[0];
        console.log("Ticket body was made.");

        <c:forEach items="${ticketArray}" var="ticket">

        console.log("Array process.");
        var tr = document.createElement('TR');
        var rowNum = document.getElementById("tickettable").rows.length;
        tr.id = "r" + (rowNum - 1);
        tr.className = "ModalD";
        tr.title = "Click to edit: " + "${ticket.ticketid}";
        tableRef.appendChild(tr);

HTML code.

<table id="tickettable" class="sortable">
                            <thead>             
                            <th style="width: 300px;">TicketID</th>
                            <th style="width: 300px;">CUID</th>
                            <th style="width: 600px;">Detail</th>
                            <th style="width: 300px;">Severity</th>
                            <th style="width: 300px;">Status</th>
                        </thead>
                    <tbody>

                    </tbody>

                </table>

Upvotes: 0

dtalley2000
dtalley2000

Reputation: 19

I have been struggling with maybe the same problem, also with a dynamically generated table. The table has hidden columns. I have 'fixed' the problem by adding some console.log statements and finding where the tablesorter.js code didn't like my table. I hated doing that but it worked... for me.

In my table I have hidden columns. So I have 11 columns, and only 8 are visible in my test. The hidden three are the first and last columns and one in the middle.

I saw that buildParserCache and buildCache were using cells.length to determine the number of columns -- 11 in this case. The buildHeaders correctly found the 8 visible columns (don't ask me how.. I didn't investigate) but buildCache and buildParserCache looped on 11 columns... so they died trying to loop on the visible data.

For my 'fix' I just added a little code to buildCache and buildParsercache to quit processing when the bad data is reached.

In buildCache, at the top of the j-loop I added this (I'm showing the j-loop line here):

for (var j = 0; j < totalCells-1; ++j) {
if (typeof(JSON.stringify(parsers[j], null, 4)) == "undefined"){
break;
}

In buildParserCache at the top of the i-loop I added this (again I'm showing the top of the i loop):

for (var i = 0; i < l; i++) {
if (typeof $headers[i] === "undefined") {
return list;
}

Upvotes: 0

Related Questions