Vue FilterBuilder - Integrate with a DevExtreme UI Component

The FilterBuilder's fields array should contain data fields from a UI component's data source. For example, the following code passes the List's Name and Price fields to the FilterBuilder:

jQuery
JavaScript
const products = [{
    ID: 1,
    Name: "HD Video Player",
    Price: 330,
    Category: "Video Players"
}, {
    ID: 2,
    Name: "SuperPlasma 50",
    Price: 2400,
    Category: "Televisions"
}, 
// ...
];
const fields = [{
    dataField: "ID",
    dataType: "number"
}, {
    dataField: "Name"
}, {
    dataField: "Price",
    dataType: "number",
    format: "currency"
}];

$(function () {
    $("#list").dxList({
        dataSource: products, 
        itemTemplate: function (data) {
            return $("<div>").text(data.Category ": " data.Name);
        }
    });
    $("#filterBuilder").dxFilterBuilder({
        fields: fields
    });
});
Angular
HTML
TypeScript
<dx-filter-builder>
    <dxi-field
        dataField="ID"
        dataType="number">
    </dxi-field>
    <dxi-field dataField="Name"></dxi-field>
    <dxi-field
        dataField="Price"
        dataType="number"
        format="currency">
    </dxi-field>
</dx-filter-builder>
<dx-list 
    [dataSource]="products">
    <div *dxTemplate="let item of 'item'">
        <div>{{item.Category}}: {{item.Name}}</div>
    </div>
</dx-list>
import { DxListModule, DxFilterBuilderModule } from "devextreme-angular";
// ...
export class AppComponent {
    products = [{
        ID: 1,
        Name: "HD Video Player",
        Price: 330,
        Category: "Video Players"
    }, {
        ID: 2,
        Name: "SuperPlasma 50",
        Price: 2400,
        Category: "Televisions"
    }, 
    // ...
    ];
}
@NgModule({
    imports: [
        // ...
        DxListModule,
        DxFilterBuilderModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxFilterBuilder>
        <DxField
            data-field="ID"
            data-type="number"
        />
        <DxField data-field="Name" />
        <DxField
            data-field="Price"
            data-type="number"
            format="currency"
        />
    </DxFilterBuilder>
    <DxList :data-source="products">
        <template #item="{ data }">
            <div>{{ data.Category }}: {{ data.Name }}</div>
        </template>
    </DxList>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxFilterBuilder, { DxField } from 'devextreme-vue/filter-builder';
import DxList from 'devextreme-vue/list';

export default {
    components: {
        DxFilterBuilder,
        DxField,
        DxList
    },
    data() {
        return {
            products: [{
                ID: 1,
                Name: "HD Video Player",
                Price: 330,
                Category: "Video Players"
            }, {
                ID: 2,
                Name: "SuperPlasma 50",
                Price: 2400,
                Category: "Televisions"
            }, 
            // ...
            ]
        };
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import FilterBuilder, { Field } from 'devextreme-react/filter-builder';
import List from 'devextreme-react/list';

const products = [{
    ID: 1,
    Name: "HD Video Player",
    Price: 330,
    Category: "Video Players"
}, {
    ID: 2,
    Name: "SuperPlasma 50",
    Price: 2400,
    Category: "Televisions"
}, 
// ...
];

const ListItem = (data) => {
    return (
        <div>{ data.Category }: { data.Name }</div>
    );
}

export default function App() {
    return (
        <React.Fragment>
            <FilterBuilder>
                <Field
                    dataField="ID"
                    dataType="number"
                />
                <Field dataField="Name" />
                <Field
                    dataField="Price"
                    dataType="number"
                    format="currency"
                />
            </FilterBuilder>
            <List
                dataSource={products}
                itemRender={ListItem}
            />
        </React.Fragment>
    );
}

To filter data, update the data source's filter according to the built filter expression. The following code does this on a button click:

jQuery
JavaScript
$(function () {
    // ...
    $("#button").dxButton({
        text: "Apply Filter",
        onClick: function () {
            const filterExpr = $("#filterBuilder").dxFilterBuilder("instance").getFilterExpression();
            const listDataSource = $("#list").dxList("instance").getDataSource();
            listDataSource.filter(filterExpr);
            listDataSource.load();
        },
    });
});
Angular
TypeScript
HTML
import { 
    DxListModule, 
    DxFilterBuilderModule, 
    DxButtonModule,
    DxListComponent, 
    DxFilterBuilderComponent 
} from "devextreme-angular";
// ...
export class AppComponent {
    @ViewChild(DxListComponent, { static: false }) list: DxListComponent;
    @ViewChild(DxFilterBuilderComponent, { static: false }) filterBuilder: DxFilterBuilderComponent;
    // Prior to Angular 8
    // @ViewChild(DxListComponent) list: DxListComponent;
    // @ViewChild(DxFilterBuilderComponent) filterBuilder: DxFilterBuilderComponent;
    // ...
    applyFilter() {
        const listDataSource = this.list.getDataSource();
        listDataSource.filter(this.filterBuilder.getFilterExpression());
        listDataSource.load();
    }
}
@NgModule({
    imports: [
        // ...
        DxButtonModule,
        DxListModule,
        DxFilterBuilderModule
    ],
    // ...
})
<!-- ... -->
<dx-button 
    text="Apply Filter"
    (onClick)="applyFilter()">
</dx-button>
Vue
App.vue
<template>
    <DxFilterBuilder :ref="filterBuilderRefKey">
        <!-- ... -->
    </DxFilterBuilder>
    <DxList :ref="listRefKey" ... >
        <!-- ... -->
    </DxList>
    <DxButton 
        text="Apply Filter"
        @click="applyFilter"
    />
</template>

<script>
// ...
import DxButton from 'devextreme-vue/button';

const filterBuilderRefKey = "my-filter-builder";
const listRefKey = "my-list";

export default {
    components: {
        // ...
        DxButton
    },
    data() {
        return {
            // ...
            filterBuilderRefKey,
            listRefKey
        };
    },
    method: {
        applyFilter() {
            const listDataSource = this.list.getDataSource();
            listDataSource.filter(this.filterBuilder.getFilterExpression());
            listDataSource.load();
        }
    },
    computed: {
        filterBuilder: function() {
            return this.$refs[filterBuilderRefKey].instance;
        },
        list: function() {
            return this.$refs[listRefKey].instance;
        }
    }
}
</script>
React
App.js
import React, { useRef } from 'react';
// ...
import Button 'devextreme-react/button';

export default function App() {
    const filterBuilder = useRef(null);
    const list = useRef(null);

    const applyFilter = () => {
        const listDataSource = list.getDataSource();
        listDataSource.filter(filterBuilder.getFilterExpression());
        listDataSource.load();
    };

    return (
        <React.Fragment>
            <FilterBuilder ref={filterBuilder}>
                {/* ... */}
            </FilterBuilder>
            <List ref={list}>
                {/* ... */}
            </List>
            <Button 
                text="Apply Filter"
                onClick={applyFilter}
            />
        </React.Fragment>
    );
}

Filter Builder with Data Grid Demo Filter Builder with List Demo

See Also