Manually add filter entry

Manually add filter entry

arnorbldarnorbld Posts: 99Questions: 17Answers: 0

Hi guys,

I have a bit of a weird situation. I need to be able to manually set a filter input value in a DataTable list that is loaded via server-side AJAX.

I have tried:

jQuery('#client_id-input').val(clientID);
jQuery('#client_id-input').trigger('keyup');

in various forms. The input does get the value, but it seems that DT ignores it, like the value of the input isn't set or accepted or something. Even if the entry is there and for example I change the sort order triggering a reload, it is still blank in the $_POST coming in to PHP:

        {
            "data": "client_id",
            "name": "client_id",
            "searchable": "true",
            "orderable": "true",
            "search": {
                "value": "",
                "regex": "false"
            }
        }

If I TYPE the filter it works perfectly. Any ideas on how to make this work?

Best regards,

Answers

  • allanallan Posts: 57,300Questions: 1Answers: 9,127 Site admin

    Can you show me your full Javascript for the table and related code?

    Setting a filter for DataTables is typically done with search() or column().search() - which I don't see any reference to in your above code.

    Allan

  • arnorbldarnorbld Posts: 99Questions: 17Answers: 0

    Hi Alan,

    See below. I also have this problem with a dropdown (select/options) I get the data when I change it and DT reloads, but it's not picking up the value from the dropdown.

    contactsTable = jQuery('#contacts-table')
        .DataTable({
            select: multiSelection,
            responsive: true,
            paging: true,
            pageLength: 10,
            "processing": true,
            "serverSide": true,
            "ajax": {
                "url": DataAjaxURL,
                "type": "POST",
                "data": function (d) {
                    return jQuery.extend({}, d, {
                        "clientID"      : clientID,
                        "vendorNumber"  : vendorNum,
                        "forceFilters"  : forceFilter,
                        "forcedColumns" : forcedColumns
                    });
                },
                "error": function (xhr, error, code) {
                    console.log('AJAX error handler');
                    console.log('XHR:');
                    console.log(xhr);
                    console.log('CODE:');
                    console.log(code);
                },
                "dataSrc": function (json) {
                    return json.data;  // MUST return json.data!
                }
    
            },
            aLengthMenu: [
                [10, 25, 50, 100, 200, -1],
                [10, 25, 50, 100, 200, "All"]
            ],
            responsive: true,
                "columnDefs": [ {
                    "targets": -1,
                    "orderable": false,
                    "searchable" : false,
                    "data": null
                } ],
            columns: [
                { "data": "last_name",     "className": "row-last-name",      "name": "last_name",     "orderable": true},
                { "data": "first_name",    "className": "row-first-name",     "name": "first_name",    "orderable": true},
                { "data": "title",         "className": "row-title",          "name": "title",         "orderable": true},
                { "data": "email_address", "className": "row-email",          "name": "email_address", "orderable": true},
                { "data": "contact_type",  "className": "row-type",           "name": "contact_type",  "orderable": true},
                { "data": "mobile_phone",  "className": "row-cell-phone",     "name": "mobile_phone",  "orderable": true},
                { "data": "office_phone",  "className": "row-office-phone",   "name": "office_phone",  "orderable": true},
                { "data": "vendor_number", "className": "row-vendor-number",  "name": "vendor_number", "orderable": true},
                { "data": "vendor_name",   "className": "row-vendor-name",    "name": "vendor_name",   "orderable": true},
                { "data": "client_id",     "className": "row-client-id",      "name": "client_id",     "orderable": true},
                { "data": "actions",       "className": "row-action-column",  "name": "actions",       "orderable": false},
            ],
            initCompleteX: function() {
                console.log('Contacts Table InitComplete.');
    
    
                var api = this.api();
    
                // For each column
                api
                    .columns()
                    .eq(0)
                    .each(function (colIdx) {
                        if(colIdx === 10){
                            return;  // skip the Button Column
                        }
    
                        // Set the header cell to contain the input element
                        var cell = jQuery('.filter-row th').eq(
                            jQuery(api.column(colIdx).header()).index()
                        );
                        var title = jQuery(cell).text();
    
                        jQuery(cell).html('<input type="text" placeholder="' + title + '" />');
    
                        jQuery(
                            'input',
                            jQuery('.filters th').eq(jQuery(api.column(colIdx).header()).index())
                            )
                            .off('keyup change')
                            .on('keyup change', function (e) {
                                e.stopPropagation();
    
                                // Get the search value
                                jQuery(this).attr('title', jQuery(this).val());
                                var regexr = '({search})'; 
    
                                // Search the column for that value
                                api
                                    .column(colIdx)
                                    .search(
                                        this.value != ''
                                            ? regexr.replace('{search}', '(((' + this.value + ')))')
                                            : '',
                                        this.value != '',
                                        this.value == ''
                                    )
                                    .draw();
                            });
                    });
                contactsTable.ajax.reload();
    
            },
            initComplete: function() {
                if (showFilters === true) {
                    this.api()
                        .columns()
                        .every(function () {
                            var that = this;
                            $('input', this.footer()).on('keyup change clear', function () {
                                if (that.search() !== this.value) {
                                    that.search(this.value).draw();
                                    contactsTable.ajax.reload();
                                }
                            });
                        });
                }
            },
    
            "drawCallback": function(settings){
            },
            "rowCallback": function (row, data, index){
            }
    
        });
    

    Best regards,

  • kthorngrenkthorngren Posts: 17,294Questions: 25Answers: 4,109

    Are you saying that this isn't working?

                "data": function (d) {
                    return jQuery.extend({}, d, {
                        "clientID"      : clientID,
                        "vendorNumber"  : vendorNum,
                        "forceFilters"  : forceFilter,
                        "forcedColumns" : forcedColumns
                    });
    

    Since you are using variables you need to make sure they are available in the scope you are accessing them. Are these global variables? Maybe you can get the values directly from inputs like this example.

    Kevin

  • arnorbldarnorbld Posts: 99Questions: 17Answers: 0

    ```Hi Kevin,

    No, that part is working perfectly. Please see below - I don't think I've explained this very well :( Below is a screenshot of the list. It is being loaded into a jQuery DIALOG where users can select contacts for adding to emails.

    One thing to note is that the filter row (and the whole table structure) is created in PHP and passed into the jQuery dialog code via AJAX. The data is then loaded via server-side AJAX.

    See the attached screenshot of the table in question. What I need to do under certain circumstances I need to populate some of the filter entries at the top with values, like in the screenshot, where the Client ID is populated with "A1"

    I created a workaround where I pass that filter value in the clientID property in the code you quoted so I can filter it in the PHP code when the list is first loaded. But if I for example re-sort the list (even if there is just one entry) then the "A1" filter from the INPUT is ignored, like it's not there.

    I also wanted to add a drop down (SELECT/OPTION) on the Type filter, but even if the drop down is selected and I get the Change event and then reload the table the value from the select is ignored.

    What I need to do is be able to prime those filter input fields so the list filters on them when it loads. The user can change the filter, but as it is, as soon as anything happens that causes a reload of the data, the "Client ID" field value does not come back to PHP via the ajax call. There is no problem entering a value and it filters perfectly and works perfectly. It is only in the case where I need to kind of "pre-set" the filter to a certain value that it isn't working.

    This is the input HTML:

    <input id="client_id-input" type="text" placeholder="Client ID">
    

    If I use:

    jQuery('#client_id-input').val(clientID);
    

    to fill that input field, then DataTable is NOT sending that value when reloads the data via AJAX. If I use console.log() to show the clientID when I set the input with it, it holds "A1" and the value does show in the input field. But what I get back in PHP when the list is reloaded (for example by changing the sort order) is:

            {
                "data": "client_id",
                "name": "client_id",
                "searchable": "true",
                "orderable": "true",
                "search": {
                    "value": "",
                    "regex": "false"
                }
            }
    

    The search.value is still blank even with "A1" in the input field.

    Without attempting to pre-set the filters, this works perfectly. I can type in the Client ID filter and it filters 100% correctly. This is only an issue if I use jQuery to manually set the value of the input field and then reload the list - the manually set values are never passed over via the AJAX to PHP.

    Hope this makes sense.

    Best regards,

  • kthorngrenkthorngren Posts: 17,294Questions: 25Answers: 4,109

    Sorry I'm not following your code flow so these answers might not help.

    filter from the INPUT is ignored, like it's not there.

    Instead of using variables use get the input value for the ajax.data option. Like the example I linked.

    It is only in the case where I need to kind of "pre-set" the filter to a certain value that it isn't working.

    Sounds like this is something you are attempting to do before Datatables is initialized, correct?

    to fill that input field, then DataTable is NOT sending that value when reloads the data via AJAX.

    Again I think you need to get the input value instead of using variables.

    Can you post a link to your page or a test case replicating the issues so we can take a look to help debug?
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • arnorbldarnorbld Posts: 99Questions: 17Answers: 0

    Hi Kevin,

    Unfortunately, I can't post a link as this is only on a local development server. But once I can breathe I'll see if I can create an example. I think there is something very simple missing and I'm just not seeing it.

    I probably won't get back to this until later this month - we're going on a trip to Ireland Saturday and we just sold our house so we will be busy moving once we get back! But I will try and cook something up and see if I can duplicate this issue in a simpler setting!

    Best regards,

Sign In or Register to comment.