How To

Configure the Cascading MultiSelect

The cascading MultiSelect is a series of MultiSelect, where the value of one MultiSelect depends upon another’s value. This can be configured by using the change event of the parent MultiSelect. Within that change event handler, data has to be loaded to the child MultiSelect based on the selected value of the parent MultiSelect.

The following example, shows the cascade behavior of country, state, and city MultiSelect. Here, the dataBind method is used to reflect the property changes immediately to the MultiSelect.

Source
Preview
index.tsx
index.html
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { MultiSelectComponent,  MultiSelect } from '@syncfusion/ej2-react-dropdowns';
import { Query, DataManager, Predicate } from '@syncfusion/ej2-data';

export default class App extends React.Component<{}, {}> {
    constructor(){
        super();
        this.onCountryChange=this.onCountryChange.bind(this);
        this.onStateChange=this.onStateChange.bind(this);
    }
    // country  MultiSelect instance
    private countryObj: MultiSelect;

    // state  MultiSelect instance
    private stateObj: MultiSelect;

    // city  MultiSelect instance
    private cityObj: MultiSelect;

    //define the country  MultiSelect data
    private countryData: { [key: string]: Object }[] = [
        { countryName: 'Australia', countryId: '2' },
        { countryName: 'United States', countryId: '1' }
    ];

    //define the state  MultiSelect data
    private stateData: { [key: string]: Object }[] = [
        { stateName: 'New York', countryId: '1', stateId: '101' },
        { stateName: 'Virginia ', countryId: '1', stateId: '102' },
        { stateName: 'Tasmania ', countryId: '2', stateId: '105' }
    ];

    //define the city  MultiSelect data
    private cityData: { [key: string]: Object }[] = [
        { cityName: 'Albany', stateId: '101', cityId: 201 },
        { cityName: 'Beacon ', stateId: '101', cityId: 202 },
        { cityName: 'Emporia', stateId: '102', cityId: 206 },
        { cityName: 'Hampton ', stateId: '102', cityId: 205 },
        { cityName: 'Hobart', stateId: '105', cityId: 213 },
        { cityName: 'Launceston ', stateId: '105', cityId: 214 }
    ];

    // maps the country column to fields property
    private countryField: object = { value: 'countryId', text: 'countryName' };

    // maps the state column to fields property
    private stateField: object = { value: 'stateId', text: 'stateName' };

    // maps the city column to fields property
    private cityField: object = { text: 'cityName', value: 'cityId' };

    onCountryChange() {
   //Query the data source based on country MultiSelect selected value
        let pred:Predicate;
        if(this.countryObj.value)
            for(var d=0;d<this.countryObj.value.length;d++){
                if(pred)
                    pred.or("countryId",'equal',this.countryObj.value[d]);
                else{
                    pred=new Predicate("countryId",'equal',this.countryObj.value[d]);
                }
        }
        else{
            this.stateObj.setProperties({enabled:false,values:[]});
            this.cityObj.setProperties({enabled:false,values:[]});
            return;
        }
        // enable the state MultiSelect
        this.stateObj.setProperties({query:new Query().where(pred),enabled:true,values:[]});
        //clear the existing selection in city MultiSelect
        this.cityObj.setProperties({enabled:false,values:[]});
    }
    onStateChange() {
 //Query the data source based on country MultiSelect selected value
        let pred:Predicate,temp:any;
        if(this.stateObj.value)
            for(var d=0;d<this.stateObj.value.length;d++){
                if(pred)
                    pred.or("stateId",'equal',this.stateObj.value[d]);
                else{
                    pred=new Predicate("stateId",'equal',this.stateObj.value[d]);
                }
        }
        else{
            this.cityObj.setProperties({enabled:false,values:[]});
            return;
        }
        this.cityObj.setProperties({query:new Query().where(pred),enabled:true,values:[]});
    }

    render() {
        return (
            <div>
                {/* specifies the tag for render the country MultiSelect component */}
                <MultiSelectComponent id="country-ms" ref={(scope) => { this.countryObj = scope; }} fields={this.countryField} dataSource={this.countryData} placeholder='Select a country' change={this.onCountryChange} />
                <br />

                 {/* specifies the tag for render the state MultiSelect component */}
                 <MultiSelectComponent id="state-ms" ref={(scope) => { this.stateObj = scope; }} enabled={false} fields={this.stateField} dataSource={this.stateData} placeholder='Select a state' change={this.onStateChange} />
                <br />

                 {/* specifies the tag for render the city MultiSelect component */}
                <MultiSelectComponent id="city-ms" ref={(scope) => { this.cityObj = scope; }} enabled={false} fields={this.cityField} dataSource={this.cityData} placeholder='Select a city' />
            </div>
        );
    }
}
ReactDOM.render(<App />, document.getElementById('sample'));
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React MultiSelect</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
</head>

<body>
    <div id='sample' style="margin: 20px auto 0; width:250px;">
        <div id='loader'>Loading....</div>
    </div>
</body>

</html>

Show the list items with icons

You can render icons to the list items by mapping the iconCss  field. This iconCss field create a span in the list item with mapped class name to allow styling as per your need.

In the following sample, icon classes are mapped with iconCss field.

Source
Preview
index.tsx
index.html
styles.css
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { MultiSelectComponent } from '@syncfusion/ej2-react-dropdowns';

export default class App extends React.Component<{}, {}> {
    // define the array of data
    private sortFormatData: { [key: string]: Object }[] = [
        { class: 'asc-sort', type: 'Sort A to Z', id: '1' },
        { class: 'dsc-sort', type: 'Sort Z to A ', id: '2' },
        { class: 'filter', type: 'Filter', id: '3' },
        { class: 'clear', type: 'Clear', id: '4' }
    ];

    // map the icon column to iconCSS field.
    private fields: object = { text: 'type', iconCss: 'class', value: 'id' };

    render() {
        return (
             // specifies the tag for render the MultiSelect component
            <MultiSelectComponent id="mtselement" dataSource={this.sortFormatData} fields={this.fields} placeholder="Select a format" />
        );
    }
}
ReactDOM.render(<App />, document.getElementById('sample'));
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React MultiSelect</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="styles.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
</head>

<body>
    <div id='sample' style="margin: 20px auto 0; width:250px;">
        <div id='loader'>Loading....</div>
    </div>
</body>

</html>
.e-list-icon {
    line-height: 1.3;
    padding-right: 10px;
    text-indent: 5px;
}

.asc-sort:before {
    content: '\e73f';
    font-family: 'e-icons';
    font-size: 20px;
}

.dsc-sort:before {
    content: '\e721';
    font-family: 'e-icons';
    font-size: 20px;
}

.filter:before {
    content: '\e818';
    font-family: 'e-icons';
    font-size: 20px;
    opacity: 0.78;
}

.clear:before {
    content: '\e7db';
    font-family: 'e-icons';
    font-size: 20px;
}

Custom value selection

The MultiSelect allows user to add a new non-present option to the component value when allowCustomValue is enabled. while selecting the new custom value customValueSelection event will be triggered.

The following sample demonstrates configuration of custom value support with the MultiSelect component.

Source
Preview
index.tsx
index.html
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { MultiSelectComponent, CustomValueEventArgs } from '@syncfusion/ej2-react-dropdowns';

export default class App extends React.Component<{}, {}> {

    // define the JSON of data
    private sportsData: { [key: string]: Object }[] = [
        { id: 'game1', sports: 'Badminton' },
        { id: 'game2', sports: 'Football' },
        { id: 'game3', sports: 'Tennis' }
    ];

    // maps the appropriate column to fields property
    private fields: object = { text: 'sports', value: 'id' };

    private onCustomValueSelection = (e: CustomValueEventArgs) => {
    // Gets the newly added data.
        console.log(e.newData);
    }

    render() {
        return (
             // specifies the tag for render the MultiSelect component
            <MultiSelectComponent id="mtselement" dataSource={this.sportsData} fields={this.fields} placeholder="Select a game"  allowCustomValue={true} customValueSelection={this.onCustomValueSelection.bind(this)}/>
        );
    }
}
ReactDOM.render(<App />, document.getElementById('sample'));
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React MultiSelect</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-react-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-react-buttons/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
</head>

<body>
    <div id='sample' style="margin: 20px auto 0; width:250px;">
        <div id='loader'>Loading....</div>
    </div>
</body>

</html>