Server-side with columnControl: Active state CSS and button Clear Search not working
Server-side with columnControl: Active state CSS and button Clear Search not working
Hi,
I’m using DataTables with serverSide: true and the columnControl feature.
I am facing two related issues when switching from client-side to server-side processing:
Visual State: I want to apply a specific CSS class (.dtcc-button_active) to the column button when a search is active. It works perfectly in client-side, but in server-side the class is not applied (it seems column().search() returns empty).
Clear Search: The Clear Search button in the dropdown remains disabled even after I apply a filter, so I cannot clear the search.
Here is a version of my configuration ( I don't know how to do it for server-side ) : https://live.datatables.net/zokukoxe/1/
To clarify my setup: I initialize the DataTable after fetching the filter lists via $.when.
Crucially, instead of relying solely on the standard DataTables parameters sent to the server, I inject a custom parameter to send the column configuration (including current filters) to my backend controller.
I suspect this custom data handling is why the standard DataTables API (column().search()) remains empty on the client side, causing the columnControl plugin to lose its active state.
Here is the logic (simplified and generic):
// 1. I load filter options (JSON) from the server first
$.when(
loadFilterData("FilterTypeA"),
loadFilterData("FilterTypeB")
).done(function (dataA, dataB) {
// Process data into {label, value} objects for the searchLists
let optionsA = parseAndMapData(dataA);
let optionsB = parseAndMapData(dataB);
// Global variable to store custom config
let myCustomColumnConfig = [];
// 2. Initialize DataTable
oDataTable = $('#myTable').DataTable({
processing: true,
serverSide: true,
// 3. The Ajax configuration
ajax: {
url: "my_api_endpoint_url",
type: 'POST',
data: {
action: "ListItems",
// THIS IS KEY: I send column configs/filters via this custom param
// instead of relying on standard DT parameters
customParam_ColumnConfig: function () {
return JSON.stringify(myCustomColumnConfig);
},
customParam_GlobalSearch: function () {
return $("#MyGlobalSearchInput").val();
}
},
dataFilter: function (data) {
// Custom response handling
let json = JSON.parse(data);
return JSON.stringify(json.tableData);
}
},
// 4. Column Control Plugin Configuration
columnControl: ['order', 'spacer', ['orderAsc', 'orderDesc', 'orderClear', 'spacer', 'search']],
// 5. Column Definitions
columnDefs: [
{
targets: [1],
name: "COLUMN_A",
// Specific searchList configuration using loaded options
columnControl: ['order', 'spacer', ['orderAsc', 'orderDesc', 'orderClear', 'spacer',
{
extend: 'searchList',
options: optionsA
}
]]
},
{
targets: [2],
name: "COLUMN_B",
columnControl: ['order', 'spacer', ['orderAsc', 'orderDesc', 'orderClear', 'spacer',
{
extend: 'searchList',
options: optionsB
}
]]
},
{
targets: [3],
name: "COLUMN_C"
},
// ... other columns ...
],
initComplete: function () {
// I populate the custom config array here for the server
this.api().columns().every(function () {
var colConfig = this.init();
myCustomColumnConfig.push({
key: colConfig.name,
type: colConfig.data_type
});
});
}
});
});
How can I tell DataTables that a search is active so that the "Clear" button becomes enabled and CSS apply ?
Thanks for your help !
Answers
With this specific setup, since I am bypassing the standard DataTables filtering parameters to use my customParam_ColumnConfig, the columnControl plugin does not detect that a search is active.
Consequently, the button does not get the .dtcc-button_active class automatically. That is why I am trying to manually force this class within the drawCallback by inspecting the server response.
I dont believe there is a server side processing environment that supports the extra ColumnControl parameters in the Datatables JS BIN environment. However you can find base server side processing templates in this technote.
I haven't looked through your code to get a full uunderstanding of what you are doing but it sounds like you are trying to save and restore the ColumnControl state. Have you looked at using
stateSavelike this example?Kevin
Hi Kevin, thank you for the suggestion regarding stateSave.
To clarify, my goal isn't persistence across page reloads, but simply ensuring the UI reflects the "active" state immediately after a server-side draw.
I have made progress and identified the root causes for both the visual state and the disabled button.
I discovered that when using Server-Side Processing with custom parameters, the search value bypasses the standard DataTables API location. Instead, it is nested in settings.oAjaxData at columns[index].columnControl.search.value. Because the standard API sees an empty search, the plugin removes the active CSS class. Solution: I implemented a custom drawCallback to inspect this specific path and force the .dtcc-button_active class. This part now works.
Even though the column is filtered server-side, the "Clear Search" button in the dropdown remains disabled (dtcc-button_disabled).
The Paradox: Inside the same dropdown, the small "X" icon (<span class="dtcc-search-clear">) works perfectly. Clicking it clears the input and reloads the table.
The Root Cause (Missing Link found!): I compared the internal state between Client-side (working) and Server-side (broken) and found that the plugin relies on the searchFixed property using a dtcc key.
Because this object is populated, the "Clear" button is enabled.
Conclusion: In Server-side mode, the plugin fails to write the filter value into aoColumns[index].searchFixed. Since the "Clear" button logic checks this property, it remains disabled.
My Question: Is there a way to force the plugin to populate searchFixed in Server-side mode? Or should I manually inject this object during the drawCallback to "trick" the plugin into enabling the button?
Thanks!
Hi,
It is expected and designed so that ColumnControl will send search information to the server-side using the parameters you highlight. That is documented here, and
searchFixedis not used for server-side processing with ColumnControl.I believe the issue you are seeing is fixed but this commit, which hasn't yet been released. If you could try the nightly build and let me know how you get on with it, that would be useful.
Thanks,
Allan
Hi Allan,
I have tested the nightly build. It fixes the visual active state, but the "Clear Search" button remained disabled in my Server-Side setup.
I used an AI to help me understand the execution flow, and it pointed out that the server-side check was returning too early.
The Cause: In the nightly build, the if ( dt.page.info().serverSide ) { ... return; } block is placed before the logic that updates column.search.fixed. Consequently, in Server-Side mode, the function returns early, and the internal search state is never updated. The "Clear" button sees an empty state and disables itself.
The Fix: Move the Server-Side check block to the very end of the .search() function, just before return searchInput.element();.
Here is the fixed searchText implementation :
I do the same with searchDateTime and searchNumber.
With this change, both the Active State and the Clear Button work perfectly in Server-Side Processing !
Thanks Allan !