Index column with deferred rendering

Index column with deferred rendering

TablefakTablefak Posts: 35Questions: 8Answers: 0
edited January 6 in Free community support

Hi there. I tried using the code from this example to implement an index column. However, it seems that it doesn't work for tables with deferred rendering.

First of all, neither search, nor order events are fired when I switch the page in my table. But even if I listen to the page.dt event, the nodes don't seem to be available yet by the time my listener is invoked. My table displays 10 rows per page, and when I switch to page 2, only 10 nodes are available (checked inside my listener function), page 3 – 20, page 4 – 30, and so on. That is, only the nodes for the previously visited pages are available. If I switch to the previous pages, the index column will be drawn correctly. And if I add a small delay (100ms in my case), it also helps.

Answers

  • colincolin Posts: 15,236Questions: 1Answers: 2,598

    The events are being triggered as expected in this example.

    The nodes wouldn't be available if deferRender is enabled. This is the optimisation for that option to speed up the table loading. By the time the event draw is triggered, the nodes would be fully formed (see the example above),

    Could you look at that, please, and see if it helps. If it's still not working for you, please can you update my example, or link to your page, so that we can see the problem.

    Colin

  • TablefakTablefak Posts: 35Questions: 8Answers: 0

    Thank you for your answer. I added the code needed to display the index column to your code (see here). However, there's a bug. Try switching pages in this order: 1 -> 6 -> 5. You should see that the numbering is wrong (page 6 has indexes 11-17, page 5 has indexes 11-20).

  • TablefakTablefak Posts: 35Questions: 8Answers: 0
    edited January 6

    Please note that I have also tried to define my index column like so:

    {
        orderable: false,
        searchable: false,
        data: null,
        title: "#",
        render: (data: any, type: any, row: any, meta) => {
            return meta.row + 1
        }
    }
    

    It works well most of the time, but sometimes the numbering gets screwed up too. It happens after some sorting/redrawing and I can't reliably reproduce it.

  • allanallan Posts: 62,990Questions: 1Answers: 10,367 Site admin

    Hi,

    What do you want to happen when the table is ordered or sorted? Should display gaps in the index, or is a number assigned to a row, always what it will display?

    Allan

  • TablefakTablefak Posts: 35Questions: 8Answers: 0
    edited January 6

    The content of the index column should be static, in some sense. That is, regardless of the ordering or sorting, the very first row on the very first page should always have number 1, and the number is incremented for each next row. Therefore, there should never be any gaps, and the number of the next row should always be +1 from the previous one.

  • kthorngrenkthorngren Posts: 21,082Questions: 26Answers: 4,908

    Instead of using column().nodes() use cell().data() as shown in the first example you linked to. Like this:
    https://live.datatables.net/ruhuguwu/273/edit

    Kevin

  • kthorngrenkthorngren Posts: 21,082Questions: 26Answers: 4,908

    If you don't want the indexes to change after sorting or searching then move the code to initComplete, for example:
    https://live.datatables.net/wibayuzi/1/edit

    Kevin

  • TablefakTablefak Posts: 35Questions: 8Answers: 0

    @kthorngren, the former of your two examples seems to do what I want. However, typescript complains:

  • TablefakTablefak Posts: 35Questions: 8Answers: 0

    Even if I suppress the warnings, the code doesn't seem to work.
    I'm using datatables.net@1.13.8.

  • TablefakTablefak Posts: 35Questions: 8Answers: 0
    edited January 8

    I found another solution on the internet, and it seems to work so far:

        dtApi.on('draw', function() {
            const pageInfo = dtApi.page.info()
            dtApi
                .column(1, { page: 'current' })
                .nodes()
                .each( function (cell, i) {
                    cell.innerHTML = pageInfo.start + i + 1
            })
        })
    

    Do you think this is a reliable solution?

    Also, if you could help me out solving the issue above, I'd appreciate. I couldn't figure out myself what's wrong. The version I'm using is the same as in the example you linked (1.13.8). I also tried disabling all my datatables plugins. Even if I suppress the typescript errors, the code doesn't seem to work (the content of the cells appears as [Object object]).

  • colincolin Posts: 15,236Questions: 1Answers: 2,598

    Editing the HTML is directly means that DataTables wouldn't be aware of the change, but that's fine if you don't want that column to be searchable or orderable, which you don't, so yep, a good way to go for you.

    I'll let Allan reply to the TS issue, that's his territory! :)

    Colin

  • TablefakTablefak Posts: 35Questions: 8Answers: 0

    @colin, thank you!

  • allanallan Posts: 62,990Questions: 1Answers: 10,367 Site admin

    The TS error is an error in the DT TypeScript files - sorry. Do 0 as any for the moment. I know it's a bit crap:

    but it will at least get you going until I get the release with the fix out (it has been fixed).

    Out of interest, what the is VSC extension you are using to show the parameter names for functions - that's cool. I've not seen that before.

    Can you update Kevin's example to show the issue you are having with [object Object] so I can take a look into it please?

    Allan

  • TablefakTablefak Posts: 35Questions: 8Answers: 0
    edited January 8

    what the is VSC extension you are using to show the parameter names for functions

    This is not VSC but WebStorm. It does this out of the box.

  • TablefakTablefak Posts: 35Questions: 8Answers: 0
    edited January 8

    I'm still seeing [object Object]. To reproduce this you simply need to specify data: null for the index column (see here). Surprisingly, though, if I change null to some real property name from my datasource, it still won't work as expected – it will just display the data from that property.

    More details
    If I log this.data() right after changing the data, it shows the whole row's data instead of the cell's data (which is unexpected, I guess).

  • kthorngrenkthorngren Posts: 21,082Questions: 26Answers: 4,908
    edited January 8

    I think you need to add columns.defaultContent with an empty string to that column.. Otherwise the data: null will try to display the full row of data thus the [object Object]. This is from the columns.data docs:

    null
    Description:
    Use the original data source for the row rather than plucking data directly from it. This action has effects on two other initialisation options:

    Kevin

  • TablefakTablefak Posts: 35Questions: 8Answers: 0

    Now the index column just displays whatever I put in the defaultContent. And this.data() still shows the data of the whole row (I check it after doing this.data(i++)).

  • kthorngrenkthorngren Posts: 21,082Questions: 26Answers: 4,908

    Do you still have the TS2554 error you noted above?

    Can you provide a test case showing the issue?

    I'm not familiar with TypeScript either so if its TS related then Allan will need to help.

    Kevin

  • allanallan Posts: 62,990Questions: 1Answers: 10,367 Site admin

    If you are using data: null you don't want to then use cell().data() to write to that cell. Assuming DataTables even copes with that (I've never tried it), it would delete the rest of the data from the row, since as Kevin points out null means the whole data object is the data for that cell.

    If the issue is that you want to write the index to a data point on the object, a data point which doesn't exist, just make one up: https://live.datatables.net/wibayuzi/2/edit . Set a default content value so DataTables doesn't complain about it initially.

    The other option, since you just want an index based on the row's position in the array, is to add it as a property before DataTables uses the data for the display. If you are Ajax loading the data like in the example, then use ajax.dataSrc to manipulate the data: https://live.datatables.net/roxoyipa/1/edit .

    Allan

  • kthorngrenkthorngren Posts: 21,082Questions: 26Answers: 4,908

    it would delete the rest of the data from the row

    That's a neat feature I never considered ;-)

    Kevin

Sign In or Register to comment.