≡

ColumnControl: search input value restored from stateSave is not sent with the first server-side req

ColumnControl: search input value restored from stateSave is not sent with the first server-side req

Elizabeth M SmithElizabeth M Smith Posts: 6Questions: 1Answers: 0

Versions: DataTables 3.1.2, ColumnControl 2.1.2 (also 3.0.4 / 2.0.2). No jQuery.

Description

With serverSide: true and stateSave: true, a ColumnControl search input restored from saved state shows its value in the header, but the first Ajax request doesn't include it. columns[i].columnControl is missing from that request, so the table loads unfiltered while the header shows a filter. Nothing redraws afterwards, so the table stays unfiltered until the user edits a search.

searchList is not affected: its restored selection is in the first request.

Reproduction (an ajax function stands in for the server; it logs what each request carries):

const blank = { search: '', smart: true, regex: false, caseInsensitive: true };

new DataTable('#example', {
    serverSide: true,
    stateSave: true,
    stateLoadCallback: () => ({
        time: Date.now(), start: 0, length: 10, order: [], search: blank,
        columns: [{ visible: true, search: blank }],
        columnControl: { name: { searchInput: { logic: 'contains', type: 'text', value: 'abc' } } },
    }),
    stateSaveCallback: () => {},
    columns: [{ name: 'name', data: 'name' }],
    columnControl: [
        { target: 0, content: ['order'] },
        { target: 1, content: ['search'] },
    ],
    ajax: (data, callback) => {
        console.log('columnControl sent:', JSON.stringify(data.columns[0].columnControl));
        callback({ draw: data.draw, recordsTotal: 0, recordsFiltered: 0, data: [] });
    },
});

Expected: the first request has columns[0].columnControl.search = { value: 'abc', logic: 'contains', type: 'text' }.

Actual: the first request has no columnControl for the column (undefined), and the header input shows abc. Typing in the input afterwards sends columnControl.search as expected.

What I think is happening

The search content's constructor registers its preXhr listener (e.page.info().serverSide && e.on('preXhr.DT', …)), and it also calls _stateLoad(state.loaded()) to restore the input. In my testing these contents are built after initComplete, which is after the first request has gone out. The restore happens with _loadingState set, so no draw follows either. The value is therefore restored into the UI, but it never reaches a request until the user changes it.

A plain api.draw() inside initComplete doesn't help: at that point the listener isn't registered yet, so the redraw is unfiltered too. Deferring the redraw by a tick works.

Workaround we're using

initComplete(settings) {
    const api = new DataTable.Api(settings);
    const restored = Object.values(api.state.loaded()?.columnControl ?? {})
        .some((c) => c?.searchInput && (c.searchInput.value !== ''
            || c.searchInput.logic === 'empty' || c.searchInput.logic === 'notEmpty'));

    if (restored) {
        setTimeout(() => api.draw(false));
    }
}

It works, but it costs a second request on load. It would be better if the first request carried the restored search. Either way, I'd expect a restored search to trigger a draw once the contents are ready.

Answers

  • allanallan Posts: 66,049Questions: 1Answers: 10,997 Site admin

    Thank you for the detailed bug report! I'll look into it in detail tomorrow and get back to you then.

    Allan

  • coreyg142coreyg142 Posts: 25Questions: 2Answers: 0

    This sounds like a similar issue to one I reported here

  • allanallan Posts: 66,049Questions: 1Answers: 10,997 Site admin

    Hi,

    It looks me a little while to realise what the trigger for this was, as I couldn't replicate it locally initially. The issue is in the -content search type when column.name is specified. If -content searchText were used, it would work, as would -content search without column.name!

    The combination of the two results in the error you are seeing - apologies for the bug.

    Your test case (very neat - nice one!) shows it working with the nightly build now in this little example.

    Thank you for the detailed bug report.

    Allan

Sign In or Register to comment.