How to write a remote data MultiSelect by using a pagination API?

Hi every one,

I am write a remote data multi-select with the infinite scrolling feature.

This component can read data from API, but it can not read this data from a pagination API.

How can i write a remote data multi-select by using a pagination API?

Thank you


This is my code for reading data from API (without pagination):

<template>
    <div>
        <div class="control-section multiselect-databinding">
            <div id='remote' style="margin: 0px auto; width:64%; padding-top: 20px;">
                <h4>Remote Data</h4>
                <ejs-multiselect
                    id="remoteData"
                    ref="multiselect"
                    :dataSource="data"
                    :open="onOpen.bind()"
                    :fields="remoteFields"
                    :query="query"
                    :placeholder="remoteWaterMark"
                    popupHeight="200px">
                </ejs-multiselect>
            </div>
        </div>
    </div>
</template>

<style scoped>
</style>

<script>
import Vue from "vue";
import { MultiSelectPlugin } from "@syncfusion/ej2-vue-dropdowns";
import { CheckBoxPlugin } from "@syncfusion/ej2-vue-buttons";
import { Query, DataManager, ODataV4Adaptor } from '@syncfusion/ej2-data';

Vue.use(MultiSelectPlugin);
Vue.use(CheckBoxPlugin);

let remoteData = new DataManager({
    url: 'http://localhost.test/api/datasource',
    adaptor: new ODataV4Adaptor,
    crossDomain: true
});

export default Vue.extend ({
    data: function() {
        return {
            data: remoteData,
            remoteFields: { text: 'description', value: 'id' },
            query: new Query().select(['description', 'id']).take(10).requiresCount(),
            remoteWaterMark: 'Select names',
        };
    },
    methods: {
        onOpen: function (e) {
            let listObj = this.$refs.multiselect.ej2Instances
            let operator = new Query()
            let start = 7
            let end = 12
            let listElement = listObj.list
            listElement.addEventListener("scroll", () => {
                if (listElement.scrollTop + listElement.offsetHeight >= listElement.scrollHeight) {
                    let filterQuery = operator.clone()
                    this.data
                        .executeQuery(filterQuery.range(start, end))
                        .then((event) => {
                            start = end
                            end += 5
                            listObj.addItem(event.result)
                        })
                        .catch((e) => {})
                }
            })
        },
    },
});
</script>


This is a page of pagination API: http://localhost.test/api/datasource?page=

{
    "current_page": 1,
    "data": [
        {
            "id": 1,
            "description": "...",
        },
        {
            "id": 2,
            "description": "...",
        },
        {
            "id": 3,
            "description": "...",
        },
        {
            "id": 4,
            "description": "...",
        },
        {
            "id": 5,
            "description": "...",
        }
    ],
    "first_page_url": "http://localhost.test/api/datasource?page=1",
    "from": 1,
    "last_page": 20,
    "last_page_url": "http://localhost.test/api/datasource?page=20",
    "links": [
        { "url": null, "label": "« Previous", "active": false },
        { "url": "http://localhost.test/api/datasource?page=1", "label": "1", "active": true },
        { "url": "http://localhost.test/api/datasource?page=2", "label": "2", "active": false },
        { "url": "http://localhost.test/api/datasource?page=3", "label": "3", "active": false },
        { "url": "http://localhost.test/api/datasource?page=4", "label": "4", "active": false },
        { "url": "http://localhost.test/api/datasource?page=5", "label": "5", "active": false },
        { "url": "http://localhost.test/api/datasource?page=6", "label": "6", "active": false },
        { "url": "http://localhost.test/api/datasource?page=7", "label": "7", "active": false },
        { "url": "http://localhost.test/api/datasource?page=8", "label": "8", "active": false },
        { "url": "http://localhost.test/api/datasource?page=9", "label": "9", "active": false },
        { "url": "http://localhost.test/api/datasource?page=10", "label": "10", "active": false },
        { "url": null, "label": "...", "active": false },
        { "url": "http://localhost.test/api/datasource?page=19", "label": "19", "active": false },
        { "url": "http://localhost.test/api/datasource?page=20", "label": "20", "active": false },
        { "url": "http://localhost.test/api/datasource?page=2", "label": "Next »", "active": false }
    ],
    "next_page_url": "http://localhost.test/api/datasource?page=2",
    "path": "http://localhost.test/api/datasource",
    "per_page": 5,
    "prev_page_url": null,
    "to": 5,
    "total": 100
}



3 Replies

BC Berly Christopher Syncfusion Team November 1, 2021 12:40 PM UTC

Hi HoSa, 
  
 
Greetings from Syncfusion support. 
  
 
We have already considered “Virtual scrolling with pagination support in Multiselect component” as feature and added to our feature request list. It will be implemented in any of any upcoming releases.  
  
 
At the planning stage for every release cycle, we review all open features and identify features for implementation based on specific parameters including product vision, technological feasibility, and customer interest. We will let you know when this feature is implemented.   
  
  
Feedback Linkhttps://www.syncfusion.com/feedback/9773/       
  
For using huge amount of data, we suggest you use Virtual Scrolling technique which loads items on demand. We can achieve this by loading items manually on scrolling. Here we have initially loaded some items using take property in query. And when you scroll the popup dynamically, we have updated the list items by demand. We can use the open event in the multiselect control and bind the scroll event for the popup list event.  
  
  
Regards, 
Berly B.C 



HO HoSa replied to Berly Christopher November 5, 2021 06:34 PM UTC

thank you for your answer

we have two problems:

1- we write code about drop-down component. in spite, the virtual scroll only works properly. but when we combine with filtering function. the output results in virtual scroll is incorrect.

2- when we search word/words with filtering function, the output results is correct. but when we click on the page, we again open drop-down. the output search results change and the wrong outputs is shown.

<template>
    <div>
        <ejs-combobox
            :dataSource="dataSource"
            :fields="fields"
            :placeholder="placeholder"
            :sortOrder="sortOrder"
            :autofill="autofill"
            :popupHeight="height"
            :query="query"
            :open="onOpen"
            ref="comboboxObj"
            :allowFiltering="true"
            :filtering="onFiltering"
        ></ejs-combobox>
    </div>
</template>

<script>
import { ComboBoxPlugin } from "@syncfusion/ej2-vue-dropdowns";
import { Query, DataManager, UrlAdaptor } from '@syncfusion/ej2-data';

Vue.use(ComboBoxPlugin);

export default Vue.extend({
    props: {
        url: {
            type: String,
            default: null,
        },
    },
    data () {
        return {
            dataSource : new DataManager ({
                url: this.url,
                adaptor: new UrlAdaptor,
                crossDomain: true,
            }),
            fields: {
                value: "id",
                text: "combobox_text",
            },
            placeholder: "Select a item",
            sortOrder: "Ascending",
            autofill: false,
            height: "200px",
            query : new Query().select(['id', 'combobox_text']).take(10),
        }
    },
    methods: {
        onOpen (e) {
                var start = 7;
                var end = 12;
                var listElement = this.$refs.comboboxObj.ej2Instances.popupObj.element.firstChild;
                listElement.addEventListener('scroll', () => {
                    if ((listElement.scrollTop + listElement.offsetHeight >= listElement.scrollHeight)) {
                        var filterQuery = this.query.clone();
                        this.dataSource.executeQuery(filterQuery.range(start, end)).then((e) => {
                            start = end;
                            end += 5;
                            this.$refs.comboboxObj.ej2Instances.addItem(e.result);
                        })
                        .catch((e) => {});
                    }
                })
        },
        onFiltering (e) {
            var query = new Query().select(['id', 'combobox_text']).take(10);
            query = (e.text !== '') ? query.where('combobox_text', 'contains', e.text, true) : query;
            e.updateData(this.dataSource, query);
        },
    },
});
</script>

<style scoped>
</style>



BC Berly Christopher Syncfusion Team November 8, 2021 11:44 AM UTC

Hi HoSa, 
  
Query 1: 
  
we write code about drop-down component. in spite, the virtual scroll only works properly. but when we combine with filtering function. the output results in virtual scroll is incorrect. 
  
Response: 
  
We have checked the shared code example. We would like to inform you that, by default combobox will be filter the data based on the “text” (“combobox_text”) field mapped in the component. You have re-write the filtering action by filter the data based on the “combobox_text” field again in the filtering event. So, there is no necessary to add this custom filtering functionality in the filtering event itself. If you want to filter the data based on the different field, then you can write the custom filtering functionality as mentioned in the below documentation. 
  
  
Query 2: 
  
when we search word/words with filtering function, the output results is correct. but when we click on the page, we again open drop-down. the output search results change and the wrong outputs is shown. 
  
Response: 
  
We would like to inform you that, while filter the data by entering the text in the combobox input, then the matched result will be displayed in the popup. If you are clicking the document and re-open the popup then original data of the component will be displayed in the popup. This is the intended behavior of the component. 
  
Regards, 
Berly B.C 


Loader.
Up arrow icon