0

I am using DataTables to show a list of 'Providers'

I have enabled the column filtering module and it displays 'select' boxes above the columns.

How can I show the table headings as the placeholder on the select?

Here is a screenshot of the current selects: enter image description here

Here is the result I am after

enter image description here

Here is my code

<script>
    $(document).ready(function() {
    $('#Table').DataTable( {
        "pagingType": "full_numbers",
        "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, 100, "All"]],
        "lengthChange": false,
        language: { 
            search: "",
            searchPlaceholder: "Search Providers",
        },
        "ordering": false,
        initComplete: function () {
            this.api().columns().every( function () {
                var column = this;
                var select = $('<select><option value=""></option></select>')
                    .appendTo( $(column.header()).empty() )
                    .on( 'change', function () {
                        var val = $.fn.dataTable.util.escapeRegex(
                            $(this).val()
                        );

                        column
                            .search( val ? '^'+val+'$' : '', true, false )
                            .draw();
                    } );

                column.data().unique().sort().each( function ( d, j ) {
                    select.append( '<option value="'+d+'">'+d+'</option>' )
                } );
            } );
        }
    } );
    $('div.dataTables_filter input').addClass('form-control');
    $('div.dataTables_filter input').placeholder = "Search Providers";
    $( "select" ).addClass( "form-control" );
} );
</script>

<div class="kt-container kt-grid__item kt-grid__item--fluid">
    <div class="row">
        <div class="col-md-12">        
            <div class="kt-portlet">
                <div class="kt-portlet__body">
                    <div class="kt-section">
                        <div class="kt-section__content">
                            <table class="table" id="Table">
                                <thead>
                                    <tr>
                                        <th>Provider</th>
                                        <th>Type</th>
                                        <th>Location</th>
                                        <th>Phone</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    {% for item in records %}
                                        <tr>
                                            <td>{{ item.title }}</td>
                                            <td>{{ item.type }}</td>
                                            <td>
                                                {{ item.city }}
                                            </td>
                                            <td>{{ item.phone }}</td>
                                        </tr>
                                    {% endfor %}
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
Alex Posterns
  • 23
  • 1
  • 8
  • Take a look at [this question](https://stackoverflow.com/questions/5805059/how-do-i-make-a-placeholder-for-a-select-box) - one of the answers there should meet your needs. – andrewJames Mar 12 '20 at 12:57
  • The columns are dynamically generated by DataTables so I can't manually add oen – Alex Posterns Mar 12 '20 at 13:03

1 Answers1

0

This approach uses the following line to get the column header's value:

var colTitle = this.header().innerHTML;

It then places that value into your select control, using the placeholder technique/trick:

var select = $('<select><option value="" disabled selected>' + colTitle + '</option></select>')

So, the relevant segment from your question ends up looking like this:

<script>
    $(document).ready(function() {
    $('#Table').DataTable( {
        "pagingType": "full_numbers",
        "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, 100, "All"]],
        "lengthChange": false,
        language: { 
            search: "",
            searchPlaceholder: "Search Providers",
        },
        "ordering": false,
        initComplete: function () {
            this.api().columns().every( function () {
                var column = this;
                var colTitle = this.header().innerHTML;
                var select = $('<select><option value="" disabled selected>' + colTitle + '</option></select>')
                    .appendTo( $(column.header()).empty() )
                    .on( 'change', function () {
                        var val = $.fn.dataTable.util.escapeRegex(
                            $(this).val()
                        );

                        column
                            .search( val ? '^'+val+'$' : '', true, false )
                            .draw();
                    } );

                column.data().unique().sort().each( function ( d, j ) {
                    select.append( '<option value="'+d+'">'+d+'</option>' )
                } );
            } );
        }
    } );
    $('div.dataTables_filter input').addClass('form-control');
    $('div.dataTables_filter input').placeholder = "Search Providers";
    $( "select" ).addClass( "form-control" );
} );
</script>

The behavior you end up with is: The placeholder text is part of the drop-down, at the top of the list, but greyed out - and it cannot be selected.

Points to note:

1) If you want to see "Provider Name", instead of "Provider" in the first column select control, then change the value in the related table heading:

<th>Provider</th>

2) I don't know how this interacts with the way you need to populate the rest of the values in each drop-down list (mine is a stand-alone test file, not using bootstrap) - so apologies in advance if it does not get you all the way to what you want.

andrewJames
  • 19,570
  • 8
  • 19
  • 51