Search code examples
javascriptjqueryasp.net-mvcdatatable

How to search dynamic columns in Datatable in asp.net core?


Following the example, on https://www.datatables.net/release-datatables/examples/api/regex.html I want to filer the table by columns, The global search us working fine but search the columns is showing an error that.

Uncaught TypeError: $(...).DataTable(...).column(...).search(...).draw is not a function
    at filterColumn (Index:667)
    at HTMLInputElement.<anonymous> (Index:637)
    at HTMLInputElement.dispatch (jquery.min.js:2)
    at HTMLInputElement.v.handle (jquery.min.js:2)

This is my code


@section Styles {
    <!-- DataTables -->
    <link rel="stylesheet" href="~/libs/datatables/css/dataTables.bootstrap.min.css">
    <link href="~/css/listedviews.css" rel="stylesheet" />

}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"
        integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
        crossorigin="anonymous"></script>

@section Scripts {
    <!-- DataTables -->
    <script src="~/libs/datatables/js/jquery.dataTables.min.js"></script>
    <script src="~/libs/datatables/js/dataTable110.21.js"></script>

}
<script>
    $(document).ready(function () {
        $('#dailyload').DataTable({
            pageLength: 10,
            ajax: {
                url: '/MonthlyInterest/MonthlyDetails',
                dataSrc: ''
            },
            columns: [
                {title: 'Account No', data: 'loanAccountNo'},
                {title: 'Amount Written off',data: 'amountWrittenOff'}
            ]
        });

        $('input.global_filter').on('keyup click', function () {
            filterGlobal();
        });

        $('input.column_filter').on('keyup click', function () {
            filterColumn($(this).parents('tr').attr('data-column'));
        });
    });

    function filterGlobal() {
        $('#dailyload').DataTable().search(
            $('#global_filter').val(),
        ).draw();
    }

    function filterColumn(i) {
        $('#dailyload').DataTable().column(i).search(
            $('#col' + i + '_filter').val()
        ).draw();
    }
</script>

<div class="container">
    <div class="row">
        <div class="box">
            <div class="box-header">
            </div>

            <div class="box-body" style="padding-right: 80px">
                <div style="background-color:#f5f5f5; padding:20px">
                    <h2>Search Panel</h2>
                    <table>
                        <tbody>
                            <tr>
                                <td>Employee Name</td>
                                <td align="center"><input type="text" class="global_filter" id="global_filter"></td>
                                <td align="center"><input type="text" class="column_filter" id="col0_filter"></td>
                            </tr>
                        </tbody>
                    </table>
                </div>
                <table id="dailyload" class="table table-striped">
                </table>
            </div>
        </div>
    </div>
</div>

Solution

  • Actually you were pretty close.

    You forgot to include your second filter on its own row and include the data-column attribute on its tr tag. This is your original code:

    <tr>
        <td>Employee Name</td>
        <td align="center"><input type="text" class="global_filter" id="global_filter"></td>
        <td align="center"><input type="text" class="column_filter" id="col0_filter"></td>
    </tr>
    

    And this is how you should do it:

    <tr>
        <td>Employee Name</td>
        <td align="center"><input type="text" class="global_filter" id="global_filter"></td>
    </tr>
    <tr data-column="0">
        <td>Another Filter</td>
        <td align="center"><input type="text" class="column_filter" id="col0_filter"></td>
    </tr>
    

    Look at my example:

    var jsonData = [
      { 
         "loanAccountNo": "500507082020",
         "amountWrittenOff": "$320,800"
      },
      { 
         "loanAccountNo": "308205105020",
         "amountWrittenOff": "$170,750"
      },
      { 
         "loanAccountNo": "120205205070",
         "amountWrittenOff": "$186,800"
      }
    ];
    
    $(document).ready(function () {
      $('#dailyload').DataTable({
        pageLength: 10,
        /*ajax: {
          url: '/MonthlyInterest/MonthlyDetails',
          dataSrc: ''
        },*/
        data: jsonData,
        columns: [
          {title: 'Account No', data: 'loanAccountNo'},
          {title: 'Amount Written off',data: 'amountWrittenOff'}
        ]
      });
    
      $('input.global_filter').on('keyup click', function () {
        filterGlobal();
      });
    
      $('input.column_filter').on('keyup click', function () {
        filterColumn($(this).parents('tr').attr('data-column'));
      });
    });
    
    function filterGlobal() {
      $('#dailyload').DataTable().search(
        $('#global_filter').val(),
      ).draw();
    }
    
    function filterColumn(i) {
      $('#dailyload').DataTable().column(i).search(
        $('#col' + i + '_filter').val()
      ).draw();
    }
    
    /*function filterColumn2(i) {
      $('#dailyload').DataTable().columns(i).search(
        $('#col' + i + '_filter').val()
      ).draw();
    }*/
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
    <link href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css" rel="stylesheet"/>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
    
    <div class="container">
      <div class="row">
        <div class="box">
          <div class="box-header">
          </div>
    
          <div class="box-body" style="padding-right: 80px">
            <div style="background-color:#f5f5f5; padding:20px">
              <h2>Search Panel</h2>
              <table>
              <tbody>
                <tr>
                  <td>Employee Name</td>
                  <td align="center"><input type="text" class="global_filter" id="global_filter"></td>
                </tr>
                <tr data-column="0">
                  <td>Another Filter</td>
                  <td align="center"><input type="text" class="column_filter" id="col0_filter"></td>
                </tr>
              </tbody>
              </table>
            </div>
            <br>
            <table id="dailyload" class="table table-striped">
            </table>
          </div>
        </div>
      </div>
    </div>

    By the way, in my first attempt I was having the same issue (same error message), and I changed this line:

     $('#dailyload').DataTable().column(i).search(
    

    For this:

     $('#dailyload').DataTable().columns(i).search(
    

    And finally it was working as expected. Notice the extra s in columns.

    But then I tried again removing the s (with column), and suddenly, to my surprise, it was working. Strange glitch, maybe?