How to databind nested tables with filters using knockout.js?

Member

by orpha , in category: Javascript , 8 months ago

How to databind nested tables with filters using knockout.js?

Facebook Twitter LinkedIn Telegram Whatsapp

1 answer

by arnoldo.moen , 7 months ago

@orpha 

To data bind nested tables with filters using Knockout.js, you can use the following steps:

  1. Define your main view model that contains an observable array of objects, each representing a row in your main table. Each row object should also contain another observable array of objects, representing the nested rows in the nested table.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function MainViewModel() {
    var self = this;
    
    self.rows = ko.observableArray([
        { 
            name: "Row 1", 
            nestedRows: [{ name: "Nested Row 1" }, { name: "Nested Row 2" }]
        },
        {
            name: "Row 2",
            nestedRows: [{ name: "Nested Row 3" }, { name: "Nested Row 4" }]
        }
    ]);
}


  1. Create your HTML markup for the main table and nested tables using the Knockout.js foreach binding to iterate over the rows and nested rows.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<table>
    <thead>
        <tr>
            <th>Main Table</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: rows">
        <tr>
            <td data-bind="text: name"></td>
        </tr>
        <tr>
            <td>
                <table>
                    <thead>
                        <tr>
                            <th>Nested Table</th>
                        </tr>
                    </thead>
                    <tbody data-bind="foreach: nestedRows">
                        <tr>
                            <td data-bind="text: name"></td>
                        </tr>
                    </tbody>
                </table>
            </td>
        </tr>
    </tbody>
</table>


  1. Add filtering functionality to your view model by adding an observable property for the filter text and a computed property to filter the rows based on the filter text.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function MainViewModel() {
    var self = this;
    
    self.rows = ko.observableArray([
        { 
            name: "Row 1", 
            nestedRows: [{ name: "Nested Row 1" }, { name: "Nested Row 2" }]
        },
        {
            name: "Row 2",
            nestedRows: [{ name: "Nested Row 3" }, { name: "Nested Row 4" }]
        }
    ]);
    
    self.filterText = ko.observable("");
    
    self.filteredRows = ko.computed(function() {
        var filter = self.filterText().toLowerCase();
        return ko.utils.arrayFilter(self.rows(), function(row) {
            return row.name.toLowerCase().indexOf(filter) >= 0 ||
                ko.utils.arrayFirst(row.nestedRows(), function(nestedRow) {
                    return nestedRow.name.toLowerCase().indexOf(filter) >= 0;
                });
        });
    });
}


  1. Update your HTML markup to bind the filter input to the filterText property and use the filteredRows computed property instead of the rows observable array.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<input type="text" data-bind="value: filterText, valueUpdate: 'input'">

<table>
    <thead>
        <tr>
            <th>Main Table</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: filteredRows">
        <tr>
            <td data-bind="text: name"></td>
        </tr>
        <tr>
            <td>
                <table>
                    <thead>
                        <tr>
                            <th>Nested Table</th>
                        </tr>
                    </thead>
                    <tbody data-bind="foreach: nestedRows">
                        <tr>
                            <td data-bind="text: name"></td>
                        </tr>
                    </tbody>
                </table>
            </td>
        </tr>
    </tbody>
</table>


By following these steps, you can databind nested tables with filters using Knockout.js in your web application.

Related Threads:

How to join 3 tables using laravel eloquent?
How to put data into nested array and bind it to html in knockout.js?
How to set selected option in asp.net mvc using knockout.js?
How to select rows from two tables using mysql?
How to query data from many tables using union in mysql?
How to join two tables with a pivot table using laravel?