Native Select

General

You need to use a fetchCallback property to format the data of the API callback, which will match the data structure of the component.


Show Code
import React from "react";
import NativeSelect from 'funda-ui/NativeSelect';
import axios from 'axios';
 
class DataService {
    
    // `getList()` must be a Promise Object
    async getList(searchStr = '', limit = 0, otherParam = '') {
 
        console.log('searchStr: ', searchStr);
        console.log("limit: ", limit);
        console.log("otherParam: ", otherParam);
 
        return {
            code: 0,
            message: 'OK',
            data: [
                {item_name: 'foo', item_code: 'bar'},
                {item_name: 'foo2', item_code: 'bar2'},
                {item_name: 'foo3', item_code: 'bar3'}
            ]
        };
    }
 
 
    async getListUseAxios(searchStr = '', limit = 0) {
        let _data = null;
        const res = await axios.get(`https://api`, {
            params: {
                s: searchStr,
                limit: limit
            },
            headers: {
                'Authorization': 'Bearer xxxx-xxxxxxxx-xxxxxxxx'
                'Content-Type': 'application/json'
            }
        }).catch(function (error) {
            console.log(error);
        });
 
        if (res && res.status == 200) _data = res.data;
 
 
        // result
        if (_data === null) {
            return {
                code: 0,
                message: 'OK',
                data: []
            };
        } else {
            return {
                code: 0,
                message: 'OK',
                data: _data
            };
        }
 
    }
    	
}
 
 
export default () => {
 
 
    function handleChange(e: any, val: string, currentData: any, currentIndex: number) {
        console.log(e.target, val, currentData, currentIndex);
        /*
        <select ...>...</select>,
        'value-1',
        {label: 'Option 1', listItemLabel: 'Option 1 (No: 001)', value: 'value-1'},
        0
        */
    }
 
    return (
        <>
            <NativeSelect
                value="value-2"
                name="name"
                label="String"
                options={[
                    {"label": "Option 1","value": "value-1"},
                    {"label": "Option 2","value": "value-2"},
                    {"label": "Option 3","value": "value-3","customAttr1": "attr1","customAttr2": "attr2"},
                    {"label": "Option 4","value": "value-4","disabled":true}
                ]}
                onChange={handleChange}
            />
 
            <NativeSelect
                value="value-2"
                name="name"
                label="String"
                options={[
                    { "label": "Option 1", "listItemLabel": "Option 1 (No: 001)", "value": "value-1" },
                    { "label": "Option 2", "listItemLabel": "Option 2 (No: 002)", "value": "value-2" },
                    { "label": "Option 3", "listItemLabel": "Option 3 (No: 003)", "value": "value-3" },
                    { "label": "Option 4", "listItemLabel": "Option 4 (No: 004)", "value": "value-4", "disabled": true, "customAttr1": "attr1","customAttr2": "attr2" }
                ]}
                onChange={handleChange}
            />
 
 
 
 
            <NativeSelect
                value="bar2"
                name="name"
                label="String"
                fetchFuncAsync={new DataService}
                fetchFuncMethod="getList"
                fetchFuncMethodParams={['',0]}
                fetchCallback={(res) => {
 
                    const formattedData = res.map((item, index) => {
                        return {
                            label: item.item_name,
                            value: item.item_code,
                            disabled: index === res.length - 1 ? true : false
                        }
                    }); 
 
                    console.log(formattedData);
                    /*
                    [
                        {"label": "foo","value": "bar","disabled": false},
                        {"label": "foo2","value": "bar2","disabled": false},
                        {"label": "foo3","value": "bar3","disabled": true}
                    ]  
                    */
 
                    return formattedData;
                }}
                onFetch={(res) => {
                    console.log('onFetch: ', res);
 
                }}
            />
 
 
 
        </>
    );
}

No spacing


Show Code
import React from "react";
import NativeSelect from 'funda-ui/NativeSelect';
 
export default () => {
 
 
    return (
        <>
 
            <NativeSelect
                ...
                wrapperClassName="position-relative"
                ...
            />
 
             <NativeSelect
                ...
                wrapperClassName=""
                ...
            />
 
        </>
    );
}

Use the object as the default

You can specify an object as the default, and if the default value is not in the list of options, it will be displayed by default.


Show Code
import React from "react";
import NativeSelect from 'funda-ui/NativeSelect';
 
export default () => {
 
    return (
        <>         
           
            <NativeSelect
                value={{ "label": "Option 2", "value": "value-2" }}
                name="name"
                label="String"
                options={[
                    { "label": "Option 1", "value": "value-1" },
                    { "label": "Option 2", "value": "value-2" },
                    { "label": "Option 3", "value": "value-3", "customAttr1": "attr1", "customAttr2": "attr2" },
                    { "label": "Option 4", "value": "value-4", "disabled": true }
                ]}
            />
 
 
 
            <NativeSelect
                value={{ "label": "Option New", "value": "value-new", "queryString": "" }}
                name="name"
                label="String"
                options={[
                    { "label": "Option 1", "value": "value-1" },
                    { "label": "Option 2", "value": "value-2" },
                    { "label": "Option 3", "value": "value-3", "customAttr1": "attr1", "customAttr2": "attr2" },
                    { "label": "Option 4", "value": "value-4", "disabled": true }
                ]}
            />
 
 
        </>
    );
}

Click on the callback via option

Use the callback attribute of the option.


Show Code
import React from "react";
import NativeSelect from 'funda-ui/NativeSelect';
 
export default () => {
 
    return (
        <>         
           
 
            <NativeSelect
                name="name"
                label="String"
                options={[
                    { "label": "Option 1", "value": "value-1" },
                    { "label": "Option 2", "value": "value-2" },
                    {
                        "label": "Option 3 (click on the callback)", "value": "value-3", "callback": () => {
                            alert('Option 3');
                        }
                    }
                ]}
            />
 
 
        </>
    );
}

Asynchronous requests are not executed by default

Set property firstRequestAutoExec to false. The first asynchronous request is not executed (saving bandwidth and improving performance). Trigger the first asynchronous request when the options area is expanded.

Valid when the series attribute fetchXXXX is exist


Show Code
import React from "react";
import NativeSelect from 'funda-ui/NativeSelect';
 
 
class DataService {
    
    // `getList()` must be a Promise Object
    async getList(searchStr = '', limit = 0, otherParam = '') {
 
        console.log('searchStr: ', searchStr);
        console.log("limit: ", limit);
        console.log("otherParam: ", otherParam);
 
        return {
            code: 0,
            message: 'OK',
            data: [
                {item_name: 'foo', item_code: 'bar', kb_code: 'fb,foobar'},
                {item_name: 'foo2', item_code: 'bar2', kb_code: 'fb2,foobar2'},
                {item_name: 'foo3', item_code: 'bar3', kb_code: 'fb3,foobar3'}
            ]
        };
    }
	
}
 
export default () => {
 
    return (
        <>        
        
            <NativeSelect
                name="name"
                firstRequestAutoExec={false}
                fetchFuncAsync={new DataService}
                fetchFuncMethod="getList"
                fetchFuncMethodParams={['',0]}
                fetchCallback={(res) => {
 
                    const formattedData = res.map((item, index) => {
                        return {
                            label: item.item_name,
                            value: item.item_code,
                            disabled: index === res.length - 1 ? true : false
                        }
                    }); 
                    return formattedData;
                }}
            />
 
            
        </>
    );
}

The Option Group element

Specify the content in the optgroup attribute of options.


Show Code
import React from "react";
import NativeSelect from 'funda-ui/NativeSelect';
 
export default () => {
 
    function handleChange(e: any, val: string, currentData: any, currentIndex: number) {
        console.log(e.target, val, currentData, currentIndex);
    }
 
    return (
        <>         
 
            <NativeSelect
                value="value-2"
                name="name"
                label="String"
                options={[
                    { "label": "Option 0", "value": "value-0" },
                    {
                        "label": "Group 1", "value": "", "optgroup": [
                            { "label": "Option 1", "value": "value-1" },
                            { "label": "Option 2", "value": "value-2" }
                        ]
                    },
                    {
                        "label": "Group 2", "value": "", "optgroup": [
                            { "label": "Option 3", "value": "value-3" },
                            { "label": "Option 4", "value": "value-4" },
                            { "label": "Option 5", "value": "value-5" }
                        ]
                    }
 
                ]}
                onChange={handleChange}
            />
 
 
        </>
    );
}

Convert raw data into a tree structure

Set hierarchical categories ( with sub-categories ) to attribute options.


Show Code
import React from "react";
import NativeSelect from 'funda-ui/NativeSelect';
 
class HierarchicalDataService {
    
    async getList(searchStr = '', limit = 0, otherParam = '') {
 
        console.log('searchStr: ', searchStr);
        console.log("limit: ", limit);
        console.log("otherParam: ", otherParam);
 
        let demoData: any = [
            {
                "parent_id": 0,
                "id": 1,
                "item_name": "Title 1",
                "item_code": 'title-1'
            },
            {
                "parent_id": 0,
                "id": 2,
                "item_name": "Title 2",
                "item_code": 'title-2'
            },
            {
                "parent_id": 2,
                "id": 3,
                "item_name": "Title 3",
                "item_code": 'title-3'
            },
            {
                "parent_id": 3,
                "id": 4,
                "item_name": "Title 4",
                "item_code": 'title-4'
            },
            {
                "parent_id": 2,
                "id": 5,
                "item_name": "Title 5",
                "item_code": 'title-5'
            } 
        ];   
 
 
        return {
            code: 0,
            message: 'OK',
            data: demoData
        };
    }
 
 
}
 
 
 
export default () => {
 
    /**
     * Convert Tree
     * @param {Array} arr                    - Input array to convert
     * @param  {?String | ?Number} parentId  - Parent id
     * @param  {?String} keyId               - Key value of id.
     * @param  {?String} keyParentId         - Key value of parent id.
     * @returns Array
     */
    function convertTree(arr, parentId = '', keyId = 'id', keyParentId = 'parent_id') {
        
        if( !parentId ) {
            
            // If there is no parent id (when recursing for the first time), all parents will be queried
            return arr.filter(item => !item[keyParentId]).map(item => {
                // Query all child nodes by parent node ID
                item.children = convertTree(arr, item[keyId], keyId, keyParentId);
                return item;
            })
        } else {
            return arr.filter(item => item[keyParentId] === parentId).map(item => {
                // Query all child nodes by parent node ID
                item.children = convertTree(arr, item[keyId], keyId, keyParentId);
                return item;
            })
        }
    }
    
 
 
    return (
        <>
            
            <NativeSelect
                value=""
                name="name"
                label="String"
                hierarchical={true}
                indentation="—"
                fetchFuncAsync={new HierarchicalDataService}
                fetchFuncMethod="getList"
                fetchFuncMethodParams={['',0]}
                fetchCallback={(res) => {
 
                    const formattedData = res.map((item: any) => {
                        return {
                            id: item.id,
                            parent_id: item.parent_id,
                            label: item.item_name,
                            value: item.item_code
                        }
                    });
 
                    const treeData = convertTree(formattedData);
 
                    treeData.unshift({
                        id: 0,
                        parent_id: 0,
                        label: 'Root Label',
                        value: '0'
                    });
                    
                    return treeData;
                }}
                onFetch={(res) => {
                    console.log('onFetch: ', res);
 
                }}
            />
 
 
 
 
        </>
    );
}

Using Vanilla JavaScript to assignment

Modify options or value with Vanilla JavaScript, which is generally used for dynamic forms with cascading relationships.


Assign1 ("bar2" will be selected)
Assign2 ("bar2" will be selected)
Show Code
import React from "react";
import NativeSelect from 'funda-ui/NativeSelect';
 
export default () => {
 
    function addOptions(data: any[], defaultValue: string = '', node: HTMLElement) {
        if ( !Array.isArray(data) ) return;
    
        node.innerHTML = '';
        for(let i = 0; i < data.length; i++) {
            const opt = document.createElement("option");
            opt.textContent = data[i].label;
            opt.value = data[i].value;
    
            //
            if ( 
                (typeof node.dataset.value !== 'undefined' && node.dataset.value == data[i].value) ||
                (defaultValue !== '' && data[i].value == defaultValue)
            ) {
                opt.selected = true;
            }
    
            node.appendChild(opt);
        }
    }
    
    
 
    function handleAssign1(e: any) {
        e.preventDefault();
 
        const optionsData = [
            {"label": "foo","value": "bar"},
            {"label": "foo2","value": "bar2"},
            {"label": "foo3","value": "bar3"}
        ];
        
        optionsData.unshift({"label": "NativeSelect","value": ""});
 
        const el = document.querySelector('#my-select') as HTMLElement;
        addOptions(optionsData, 'bar2', el);
 
    }
 
    function handleAssign2(e) {
        e.preventDefault();
 
 
        // If the `data-value` attribute exists
        const optionsData = [
            {"label": "foo","value": "bar"},
            {"label": "foo2","value": "bar2"}
        ];
        
        optionsData.unshift({"label": "NativeSelect","value": ""});
 
        const el = document.querySelector('#my-select2') as HTMLElement;
        addOptions(optionsData, '', el);
 
    }
 
    return (
        <>
            <a href="#" onClick={handleAssign1}>Assign1 ("bar2" will be selected)</a>
            <NativeSelect
                value=""
                id="my-select"
                name="name1"
                options={``}
            />
 
 
            <a href="#" onClick={handleAssign2}>Assign2 ("bar2" will be selected)</a>
            <NativeSelect
                data-value="bar2"
                value=""
                id="my-select2"
                name="name2"
                options={``}
            />
 
        </>
    );
}

API

Native Select

import NativeSelect from 'funda-ui/NativeSelect';
PropertyTypeDefaultDescriptionRequired
refReact.ForwardedRef-It is the return element of this component.-
wrapperClassNamestringmb-3 position-relativeThe class name of the control wrapper.-
optionsJSON Object Literals | JSON Object-Set the default value using JSON string format for menu of options, like this: [{"label": "Option 1","value": "value-1"},{"label": "Option 2","value": "value-2"},{"label": "Option 3","value": "value-3","customAttr1": "attr1","customAttr2": "attr2"},{"label": "Option 4","value": "value-4","disabled":true}]
Note: Use API data if database query exists. That is, the attribute fetchXXXX
-
hierarchicalbooleanfalseSet hierarchical categories ( with sub-categories ) to attribute options.-
indentationstring-Set hierarchical indentation placeholders, valid when the hierarchical is true.-
doubleIndentbooleanfalseSet double indent effect, valid when the hierarchical is true.-
defaultValuestring | JSON Object-Specifies the default value. Use when the component is not controlled. It does not re-render the component because the incoming value changes.
If you use objects, you can default to values that do not exist in the option list. such as {"label":"Option 0","value":"value-0","queryString":""} (Single selection only!!!)
-
valuestring | JSON Object-Set a default value for this control.
If you use objects, you can default to values that do not exist in the option list. such as {"label":"Option 0","value":"value-0","queryString":""} (Single selection only!!!)
-
labelstring | ReactNode-It is used to specify a label for an element of a form.
Support html tags
-
namestring-Name is not deprecated when used with form fields.-
disabledbooleanfalseWhether it is disabled-
requiredbooleanfalseWhen present, it specifies that a field must be filled out before submitting the form.-
firstRequestAutoExecbooleantrueThe first asynchronous request is automatically executed. If false, trigger the first asynchronous request when the options area is expanded.
Valid when the series attribute fetchXXXX is exist
-
fetchFuncAsyncConstructor-A method as a string from the constructor.-
fetchFuncMethodstring-When the property is true, every time the select changes, a data request will be triggered.
The methord must be a Promise Object.
-
fetchFuncMethodParamsarray-The parameter passed by the method, it is an array.
Note: the first element is a query string, the second element is the number of queried data (usually a number), and then you can increase the third, or fourth, and more parameters.
Such as ['',0], ['',99,'string 1','string 2']
There should be at least one parameter which is the query string.
-
fetchCallbackfunction-Return value from fetchCallback property to format the data of the API callback, which will match the data structure of the component.
At the same time it returns the original data, you will use this function and use the return keyword to return a new value.
-
onFetchfunction-Call a function when data is successfully fetched. It returns one callback value which is the fetched data (Array)-
onChangefunction-Call a function when the value of an HTML element is changed. It returns four callback values.
  1. The first is the Control Event (Event)
  2. The second is the current value (String)
  3. The third is the data (Exposes the JSON format data) about the option. (JSON Object)
  4. The last is the current index number (Number)
-
onBlurfunction-Call a function when a user leaves an form field. It returns only one callback value which is the Control Event (Event)-
onFocusfunction-Call a function when an form field gets focus. It returns only one callback value which is the Control Event (Event)-

It accepts all props which this control support. Such as style, data-*, tabIndex, id, and so on.


JSON Object Literals configuration properties of the options and callback from fetchCallback:

PropertyTypeDefaultDescriptionRequired
labelstring-Specify the label text for each option.
listItemLabelstring-Specify the label text for pop-up list items.
Support html tags
-
valuestring-Specify the value for each option
optgrouparray-Creates a grouping of options. It will be displayed using the value of label. such as [{"label":"Option 0","value":"value-0"},{"label":"Group 1","value":"","optgroup":[{"label":"Option 1","value":"value-1"},{"label":"Option 2","value":"value-2"}]}]-
disabledboolean-When present, it specifies that an option should be disabled.-
callbackfunction-Click on the callback function for this option.-

Create Callback via fetchCallback

A successful response returns the details of the callback such as Sample Request Body:

Among them, label, listItemLabel, value, optgroup, disabled and callback are attributes used by the system, and other attributes can be added freely

[
    {
        "label": "banana",
        "listItemLabel": "banana (No. 0)",
        "value": "b",
        "disabled": false
    },
    {
        "label": "apple",
        "listItemLabel": "apple (No. 1)",
        "value": "a",
        "disabled": false
    },
    ...
]