簡體   English   中英

以編程方式在 material-ui 自動完成文本字段中設置值

[英]Programmatically set value in material-ui Autocomplete TextField

在我的 React 應用程序中,我有一個可以從下拉列表中獲取值的輸入。 對於這個假設,我使用 material-ui 自動完成和 TextField 組件。

問題:如何在不從下拉列表中選擇的情況下通過單擊按鈕以編程方式設置輸入值? 例如,我想從示例中設置“教父”,這個值應該在輸入中直觀地看到。

此處的代碼沙盒示例

import React from "react";
import Autocomplete from "@material-ui/lab/Autocomplete";
import { TextField, Button } from "@material-ui/core";

export default function ComboBox() {
  const handleClick = () => {
    // set value in TextField from dropdown list
  };

  return (
    <React.Fragment>
      <Autocomplete
        options={top100Films}
        getOptionLabel={option => option.title}
        style={{ width: 300 }}
        renderInput={params => (
          <TextField
            {...params}
            label="Combo box"
            variant="outlined"
            fullWidth
          />
        )}
      />
      <Button onClick={handleClick}>Set value</Button>
    </React.Fragment>
  );
}

// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
const top100Films = [
  { title: "The Shawshank Redemption", year: 1994 },
  { title: "The Godfather", year: 1972 },
  { title: "The Godfather: Part II", year: 1974 },
  { title: "The Dark Knight", year: 2008 }
];

您可以在狀態中存儲所需的值並將其傳遞給自動完成組件。

導入useState

   import React, { useState } from 'react';

使用useState

   const [val,setVal]=useState({})

單擊按鈕更改值

  const handleClick = () => {
    setVal(top100Films[0]);//you pass any value from the array of top100Films
   // set value in TextField from dropdown list
 };

並將這個值傳遞給渲染中的組件

 <Autocomplete
   value={val}
    options={top100Films}
    getOptionLabel={option => option.title}
    style={{ width: 300 }}
    renderInput={params => (
      <TextField
        {...params}
        label="Combo box"
        variant="outlined"
        fullWidth

      />
    )}
  />

如果您在這里嘗試測試從 MUI 的Autocomplete組件調用的更改處理程序:

在您的 setupTests.js 文件中

import '@testing-library/jest-dom/extend-expect'

document.createRange = () => ({
  setStart: () => {},
  setEnd: () => {},
  commonAncestorContainer: {
    nodeName: 'BODY',
    ownerDocument: document
  }
})

在您的測試文件中:

import { render, fireEvent } from '@testing-library/react'

...

const { getByRole } = render(<MyComponentWithAutocomplete />)

const autocomplete = getByRole('textbox')

// click into the component
autocomplete.focus()

// type "a"
fireEvent.change(document.activeElement, { target: { value: 'a' } })

// arrow down to first option
fireEvent.keyDown(document.activeElement, { key: 'ArrowDown' })

// select element
fireEvent.keyDown(document.activeElement, { key: 'Enter' })

expect(autocomplete.value).toEqual('Arkansas')
expect(someChangeHandler).toHaveBeenCalledTimes(1)

有關更多示例,請查看庫中測試

如果要在輸入中顯示默認選定值,還必須設置 Autocomplete 組件的 inputValue 屬性和 onInputChange 事件

狀態變化:

const [value, setValue] = useState("");
const [inputValue, setInputValue] = useState("");

手柄點擊的變化

const handleClick = () => {
   setValue(top100Films[0]);
   setInputValue(top100Films[0]);
};

自動完成的變化

 <Autocomplete
    {...custom}
    value={value}
    inputValue={inputValue}
    onChange={(event, newValue) => {
      setValue(newValue);
    }}
    onInputChange={(event, newInputValue) => {
      setInputValue(newInputValue);
    }}

    options={top100Films}
    getOptionLabel={option => option.title}
    renderInput={(params) => (
      <TextField
        {...input}
        {...params}
        variant="outlined"
      />
    )}
  />

沒有人給出正確答案...

const options = [
  { label: "A", value: 1 },
  { label: "B", value: 2 },
  { label: "A", value: 3 },
];

function MyInput() {
  const [value, setValue] = useState(options[0].value);

  return (
    <Autocomplete
      value={options.find((option) => option.value === value)}
      onChange={(_, v) => setValue(v?.value)}
      options={options}
      getOptionLabel={(option) => option.label}
      renderInput={(params) => (
        <TextField {...params}/>
      )}
    />
  )
}

當下拉列表中不存在該選項時,它將添加一個新選項

import * as React from 'react';
import TextField from '@mui/material/TextField';
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';

const filter = createFilterOptions();

export default function FreeSoloCreateOption() {
  const [value, setValue] = React.useState(null);

  return (
    <Autocomplete
      value={value}
      onChange={(event, newValue) => {
        if (typeof newValue === 'string') {
          
          setValue({
            title: newValue,
          });
        } else if (newValue && newValue.inputValue) {
          // Create a new value from the user input
          top100Films.push({title: newValue.inputValue})
          setValue({
            title: newValue.inputValue,
          });
        } else {
          setValue(newValue);
        
        }
       
        
      
      }}
      filterOptions={(options, params) => {
        const filtered = filter(options, params);

        const { inputValue } = params;
        // Suggest the creation of a new value
        const isExisting = options.some((option) => inputValue === option.title);
        if (inputValue !== '' && !isExisting) {
          filtered.push({
            inputValue,
            title: `Add "${inputValue}"`,
          });
        }

        return filtered;
      }}
      selectOnFocus
      clearOnBlur
      handleHomeEndKeys
      id="free-solo-with-text-demo"
      options={top100Films}
      getOptionLabel={(option) => {
        // Value selected with enter, right from the input
        if (typeof option === 'string') {
          return option;
        }
        // Add "xxx" option created dynamically
        if (option.inputValue) {
          return option.inputValue;
        }
        // Regular option
        return option.title;
      }}
      renderOption={(props, option) => <li {...props}>{option.title}</li>}
      sx={{ width: 300 }}
      freeSolo
      renderInput={(params) => (
        <TextField {...params} label="Free solo with text demo" />
      )}
    />
  );
}

// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
const top100Films = [
  { title: 'The Shawshank Redemption', year: 1994 },
  { title: 'The Godfather', year: 1972 },
  { title: 'The Godfather: Part II', year: 1974 }
 
];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM