reactjs 如何自定义物料界面芯片组件可编辑和复制粘贴内容(逗号分隔)

e37o9pze  于 2023-02-12  发布在  React
关注(0)|答案(2)|浏览(84)

我需要创建一个输入字段,该字段采用数字数组(逗号“,”分隔),如[123,34,23,13]。
我希望当用户将此123,34,23,13复制到输入字段时,它应该基于逗号以下面的格式更改。

有办法做到这一点吗。
稍后,我想显示红旗也为不正确的数字(这将是验证提交的价值)。

xcitsw88

xcitsw881#

这个jsFiddle demo符合您的要求吗?(单击"运行"开始演示。)如果不符合,请告诉我缺少什么。

注解

1.这个演示只接受逗号分隔的整数(或单个整数)作为输入。不允许空格。
1.重复值用红色芯片显示,并且不包括在结果集中。到目前为止,重复值是导致值失败的唯一验证标准,失败通过红色芯片显示给用户。
1.非数字输入失败,但没有提示。

索引. html

<!DOCTYPE html>
<html>

    <head>
        <title>Material-UI Chip Input Field Test</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>

    <body>
        <div id="testContainer" class="testContainer"></div>
        <script src="./index.js"></script>
        <noscript> Please enable javascript to view the site </noscript>
    </body>

</html>

索引. jsx

import * as React from 'react';
import { createRoot } from 'react-dom/client';
const container = document.getElementById( 'testContainer' );
const root = createRoot( container );

import Chip from '@mui/material/Chip';
import Autocomplete from '@mui/material/Autocomplete';
import TextField from '@mui/material/TextField';
import Stack from '@mui/material/Stack';

import { v4 as uuidv4 } from 'uuid';

let collator = new Intl.Collator( 'en', { numeric: true, sensitivity: 'base' } );

const getSortedListAsArray = ( list ) => {
    let sortedList = list.sort( ( a, b ) => {
        return collator.compare( a.value, b.value );
    } );
    return sortedList;
}

export default function Tags() {
    const [ list, setList ] = React.useState( [] );
    const selectedItems = list.filter( ( item ) => item.isValid );
    const selectedLengthIndex = selectedItems.length - 1;

    let listById = {};
    for ( let item of list ) {
        listById[ item.id ] = item;
    }

    function updateList( items ) {
        let newList = [].concat( list, items );
        newList = getSortedListAsArray( newList );
        setList( newList );
    }

    function validateValue( value, validatedItems ) {
        let isValid = false;
        const valueInt = parseInt( value );
        const selectedValues = list.map( ( item ) => item.value );
        const validatedValues = validatedItems.map( ( item ) => item.value );
        if ( selectedValues.indexOf( valueInt ) === -1 &&
            validatedValues.indexOf( valueInt ) === -1
        ) {
            isValid = true;
        }
        return isValid;
    }
    
    function validateInput( event, inputs, reason ) {
        if ( 'createOption' == reason ) {
            let validatedItems = [];
    
            let values = inputs[ inputs.length - 1 ].split( ',' );
            for ( let value of values ) {

                // Test for positive integers. Fail silently.
                if ( /[^0-9]+/.test( value ) || value.length == 0 ) {
                    continue;
                } else {
                    let isValid = validateValue( value, validatedItems );
                    validatedItems.push( {
                        id: uuidv4(),
                        value: parseInt( value ),
                        isValid
                    } );
                }
            }
    
            updateList( validatedItems );
        } else if ( 'removeOption' == reason ) {
            let newList = inputs.map( ( id ) => listById[ id ] );
            setList( newList );
        } else if ( 'clear' == reason ) {
            setList( [] );
        }
    }

    /**
     * Return call adapted from Material-UI 'Multiple values' Autocomplete demo.
     * @see https://mui.com/material-ui/react-table/#sorting-amp-selecting
     * Code: @see https://github.com/mui/material-ui/blob/v5.9.2/docs/data/material/components/autocomplete/Tags.tsx
     *
     */
    return (
        <Stack spacing={ 3 } sx={ { width: 500 } }>
            <Autocomplete
                multiple
                id='tags-filled'
                filterSelectedOptions={ true }
                options={ [] }
                value={ list.map( ( item ) => item.id ) }
                freeSolo
                renderTags={ ( listIds, getTagProps ) =>
                    listIds.map( ( id, index ) => (
                        <Chip
                            key={ index }
                            variant='outlined'
                            label={ listById[ id ].value }
                            sx={ {
                                color: ( theme ) => {
                                    let chipColor = '#fff';
                                    if ( typeof( listById[ id ] ) == 'object' ) {
                                        chipColor = listById[ id ].isValid
                                            ? theme.palette.common.white 
                                            : theme.palette.common.white
                                    }
                                    return chipColor;
                                },

                                backgroundColor: ( theme ) => {
                                    let chipColor = '#fff';
                                    if ( typeof( listById[ id ] ) == 'object' ) {
                                        chipColor = listById[ id ].isValid
                                            ? theme.palette.primary.main 
                                            : theme.palette.error.main
                                    }
                                    return chipColor;
                                },
                            
                                [`& .MuiSvgIcon-root.MuiSvgIcon-fontSizeMedium.MuiChip-deleteIcon.MuiChip-deleteIconMedium.MuiChip-deleteIconColorDefault.MuiChip-deleteIconOutlinedColorDefault`]: {
                                    fill: ( theme ) => theme.palette.grey[200]                
                                }
                            } }
                            { ...getTagProps( { index } ) }
                        />
                    ) )
                }
                renderInput={ ( params ) => (
                    <TextField
                        { ...params }
                        variant='filled'
                        label='Material-UI Chip Input Test'
                        placeholder='e.g. 12,73,902,23,41'
                        helperText='Enter comma separated integers (no spaces)'
                    />
                ) }
                onChange={ validateInput }
            />

            { /* Display list of unique integers. */ }
            <div>
                { selectedItems.map( ( item, index ) => {
                    let comma = null;
                    if ( selectedLengthIndex != index ) {
                        comma = ( <span key={ 'idx' + index }>, </span> );
                    }

                    return (
                        item.isValid
                            ? <span key={ index }>{ item.value }{ comma }</span>
                            : null
                    );
                } ) }
            </div>
        </Stack>
    );
}

/**
 * Inject component into DOM
 */
root.render(
    <Tags />
);
wpx232ag

wpx232ag2#

这是我到现在才发现的:https://codesandbox.io/s/quirky-waterfall-5ebi3y?file=/src/Chips.jsx
当API返回错误/无效的输入数组时,缺少部分,则应转换为红色标记

相关问题