Input text box underneath each column for Searching | Clicking on text input cell orders table?

Input text box underneath each column for Searching | Clicking on text input cell orders table?

castillocalebcastillocaleb Posts: 4Questions: 1Answers: 0

Hello, I am creating a datatable that has a search text input underneath each column. However, when I click on the cell that has contains the cell, it also performs an order by. How do I stop it from ordering the table?

I've looked at this article and read all the comments but I can't seem to get the order by to STOP working when clicking the text input cells.

I have attached an image of when I click on the text input, it does an order by.

URL: https://datatables.net/examples/api/multi_filter.html

HTML Below

<head>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/2.1.8/css/dataTables.dataTables.css">
    <script src="https://code.jquery.com/jquery-3.7.1.js"></script>
    <script src="https://cdn.datatables.net/2.1.8/js/dataTables.js"></script>
</head>

<table id="example" class="display" style="width:100%">
    <thead>
        <tr>
            <th>Name</th>
            <th>Position</th>
            <th>Office</th>
            <th>Age</th>
            <th>Start date</th>
            <th>Salary</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Tiger Nixon</td>
            <td>System Architect</td>
            <td>Edinburgh</td>
            <td>61</td>
            <td>2011-04-25</td>
            <td>$320,800</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <th>Name</th>
            <th>Position</th>
            <th>Office</th>
            <th>Age</th>
            <th>Start date</th>
            <th>Salary</th>
        </tr>
    </tfoot>
</table>

JavaScript Here

<script>
    new DataTable('#example', {
        initComplete: function () {
            this.api()
                .columns()
                .every(function () {
                    let column = this;
                    let title = column.footer().textContent;

                    // Create input element
                    let input = document.createElement('input');
                    input.placeholder = title;
                    column.footer().replaceChildren(input);

                    var r = $('#example tfoot tr');
                    r.find('th').each(function () {
                        $(this).css('padding', 8);
                    });
                    $('#example thead').append(r);
                    $('#search_0').css('text-align', 'center');

                    // Event listener for user input
                    input.addEventListener('keyup', () => {
                        if (column.search() !== this.value) {
                            column.search(input.value).draw();
                        }
                    });
                });
        }
    });
</script>

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,602Questions: 1Answers: 10,486 Site admin

    Put the input elements into a second row in the table header and use orderCellsTop to tell DataTables to apply ordering to the top cells only.

    The other option is to add e.stopPropagation() in your event handler to stop the event bubbling up (add e to the event handler function's parameters).

    Allan

  • castillocalebcastillocaleb Posts: 4Questions: 1Answers: 0

    Hi allan, I was able to stop the order by using e.stopPropagation()

    But I am curious how to implement your first option. Put the input Tag element into the second row in the table header? How does that looks like? Something like this?

    Then use the orderCellsTop to use the first tr's from the thead?

    <table id="example" class="display" style="width:100%">
        <thead>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
            <tr>
                <input type="text" name="Name">
                <input type="text" name="Position">
                <input type="text" name="Office">
                <input type="text" name="Age">
                <input type="text" name="Start">
                <input type="text" name="Salary">
            </tr>
        </thead>
    

    JavaScript that worked with e.stopPropagation() here

    <script>
        new DataTable('#example', {
            initComplete: function () {
                this.api()
                    .columns()
                    .every(function () {
                        let column = this;
                        let title = column.footer().textContent;
    
                        // Create input element
                        let input = document.createElement('input');
                        input.placeholder = title;
                        column.footer().replaceChildren(input);
    
                        var r = $('#example tfoot tr');
                        r.find('th').each(function () {
                           this.addEventListener('click', (e) => {
                                e.stopPropagation();
                           });
    
                           $(this).css('padding', 8);
                        });
    
                        $('#example thead').append(r);
                        $('#search_0').css('text-align', 'center');
    
                        // Event listener for user input
                        input.addEventListener('click', (e) => {
                            e.stopPropagation();
                        });
    
                        // Event listener for user input
                        input.addEventListener('keyup', (e) => {
                            e.stopPropagation();
                            if (column.search() !== this.value) {
                                column.search(input.value).draw();
                            }
                        });
                    });
            }
        });
    
  • kthorngrenkthorngren Posts: 21,391Questions: 26Answers: 4,961
    Answer ✓

    Here is an example of search inputs in the second header row:
    https://live.datatables.net/giharaka/1/edit

    Kevin

  • castillocalebcastillocaleb Posts: 4Questions: 1Answers: 0
    edited November 5

    Hi kthorngren, This does not work with serverside processing.

    Also, I noticed when I hit enter on the input text it will sort on the column. How do I stop it from sort when pressing the enter key on the input text?

    I already have a stopPropagation like so.

                input.addEventListener('click', (ev) => {
                    ev.stopPropagation();
                });
    
                input.addEventListener('keyup', function (ev) {
                    ev.stopPropagation();
                });
    
                input.addEventListener('keydown', function (ev) {
                    ev.stopPropagation();
                    if (ev.keyCode == 13) {
                        if (iteratedColumn.search() !== this.value) {
                            ..table searching here
                        }
                    }
                });
    
  • kthorngrenkthorngren Posts: 21,391Questions: 26Answers: 4,961
    edited November 5

    The example I provided does work with server side processing. If the table is being sorted then that suggests you aren't using the orderCellsTop that Allan mentioned is needed for the two header solution. You shouldn't need the stopPropagation calls with this solution.

    Kevin

  • castillocalebcastillocaleb Posts: 4Questions: 1Answers: 0

    I got it to work by using the following:

                input.addEventListener('click', (ev) => {
                    ev.preventDefault();
                    ev.stopPropagation();
                });
    
                input.addEventListener('input', (ev) => {
                    ev.preventDefault();
                    ev.stopPropagation();
                });
    
                input.addEventListener('keydown', function (ev) {
                    if (ev.keyCode == 13) {
                        ev.preventDefault();
    
  • kthorngrenkthorngren Posts: 21,391Questions: 26Answers: 4,961

    Sorry I must not be clear on what solution were are asking about. Here is the server side processing example of two header row with orderCellsTop:
    https://live.datatables.net/giharaka/1845/edit

    It doesn't need any of those event listeners to stopPropagation.

    Kevin

Sign In or Register to comment.