簡體   English   中英

Material UI Autocomplete-Popper 不會停留在渲染它的組件上

[英]Material UI Autocomplete- Popper not STUCk to the component which rendered it

我的自動完成功能的當前 Output 位於隨附的視頻鏈接中,當 window 滾動時,Atocomplete 建議在頁面上跳動: Z5E056C500A1C4B6A7110B50D807BADEcastbTZd://www.screen.

我正在嘗試將自動完成建議修復到自動完成控件,並且以某種方式自動建議下拉菜單堅持自動完成但自動完成中的滾動體驗並不那么流暢

使用的解決方案如下:

使用自動完成屬性PopperComponent ={PopperMy}

const PopperMy = function (props) {
  return <Popper {...props} placement="bottom-start" disablePortal={true} />;
};

或者這個popperVariant:

<Popper
      {...props}
      disablePortal={true}
      placement="bottom-start"
      popperOptions={{ positionFixed: true }}
    />

任何建議和固定表示贊賞。 謝謝 !

在此處添加文件內容以供參考:

import React, { useState, useEffect } from "react";
import {
  TextInputField,
  InputLabelField,
  BoxField,
  CustomWhiteTooltip,
} from "../../atoms";
import Autocomplete, {
  createFilterOptions,
} from "@material-ui/lab/Autocomplete";
import {
  IsArrayNotEmpty,
  IsNotEmpty,
  IsString,
  IsObject,
  IsFunction,
  ThrowException,
  IsObjectNotEmpty,
  ObjectHasKey,
  IsNotUndefined,
} from "../../../utility";
import UserMessages from "../../../constants/UserMessages";
import TextField from "@material-ui/core/TextField";
import { InfoIcon } from "../../../resources/ThemeIcons";
import { Popper } from "@material-ui/core";


const TypeaheadField = ({
  id = "",
  renderInputId = "",
  listOptions,
  mainListOptionsKey = IsString(mainListOptionsKey)
    ? mainListOptionsKey
    : "title",
  getPropertyFromSingleObject = IsString(getPropertyFromSingleObject)
    ? getPropertyFromSingleObject
    : false,
  //defaultSelected='',
  isCreatable = false,
  onChange,
  addNewLabel = "Add",
  disableClearable = false,
  className = "",
  textFieldClassName = "",
  isSelectMultiple = false,
  limitTags = -1,
  filterSelectedOptions = true,
  openOnFocus = true,
  blurOnSelect = false,
  labelAtTop = false,
  labelClassName = "",
  popupIcon,
  size = "small",
  disabled = false,
  variant = "standard",
  label = "",
  required = false,
  placeholder = "",
  fullWidth = true,
  value = "",
  ChipProps = {},
  inputLabelProps = {},
  helperText = "",
  error = false,
  onBlur = "",
  name = "",
  tooltipMessage = "",
  tooltipIcon = "",
  ...rest
}) => {
  /* Required props:  listOptions, onChange */
  const isListOptionsProvided = IsArrayNotEmpty(listOptions);
  const isOnChangeProvided = IsFunction(onChange);
  if (!isListOptionsProvided || !isOnChangeProvided) {
    //ThrowException(UserMessages.warnings.missingRequiredProps);
  }

  const [autovalue, setValue] = React.useState(value);

  useEffect(() => {
    const IsMultipleSelectAllowed = isSelectMultiple === true;
    if (IsMultipleSelectAllowed) {
      setValue(autovalue && IsArrayNotEmpty(autovalue) ? autovalue : []);
    } else if (!IsMultipleSelectAllowed) {
      setValue(autovalue && IsNotEmpty(autovalue) ? autovalue : null);
    }
  }, []);

  const handleOnChange = (event, newValue) => {
    let selectedValue = newValue;

    if (newValue && IsObject(newValue)) {
      if (newValue[mainListOptionsKey]) {
        // Create a new value from the user input
        if (newValue.type === "new") {
          if (IsString(listOptions[0])) {
            selectedValue = newValue.value;
            listOptions.push(newValue.value);
          } else {
            selectedValue = newValue.value;
            listOptions.push({
              [mainListOptionsKey]: newValue.value,
            });
          }
        }
      } else {
        const LastObject = IsArrayNotEmpty(newValue)
          ? newValue[newValue.length - 1]
          : null;
        const IsNewValueAdded =
          LastObject && LastObject.type === "new" && LastObject.value;
        if (IsNewValueAdded) {
          // Create a new value from the user input
          const CurrentValues =
            autovalue && IsArrayNotEmpty(autovalue) ? [...autovalue] : [];
          if (IsString(listOptions[0])) {
            selectedValue = [...CurrentValues, LastObject.value];
            listOptions.push(LastObject.value);
          } else {
            selectedValue = [
              ...CurrentValues,
              { [mainListOptionsKey]: LastObject.value },
            ];
            listOptions.push({ [mainListOptionsKey]: LastObject.value });
          }
        }
      }
    }

    setValue(selectedValue);
    if (
      getPropertyFromSingleObject !== false &&
      isSelectMultiple === false &&
      IsObjectNotEmpty(selectedValue) &&
      ObjectHasKey(selectedValue, getPropertyFromSingleObject)
    ) {
      onChange(selectedValue[getPropertyFromSingleObject]);
      return;
    }
    onChange(selectedValue);
  };

  const handleFilterOptions = (options, params) => {
    const filter = createFilterOptions();
    const filtered = filter(options, params);

    // Suggest the creation of a new value
    const IsSuggestNewValue = params.inputValue !== "" && isCreatable === true;
    if (IsSuggestNewValue) {
      filtered.push({
        value: params.inputValue,
        type: "new",
        [mainListOptionsKey]: `${addNewLabel} "${params.inputValue}"`,
      });
    }
    return filtered;
  };

  const handleGetOptionLabel = (option) => {
    if (typeof option === "string") {
      return option;
    }
    return option ? option[mainListOptionsKey] : null;
  };

  const handleGetOptionSelected = (option, value) => {
    if (value && IsObject(value) && IsObjectNotEmpty(value)) {
      return option[mainListOptionsKey] === value[mainListOptionsKey];
    } else if (
      option &&
      IsObject(option) &&
      IsObjectNotEmpty(option) &&
      value &&
      IsString(value) &&
      IsNotEmpty(value)
    ) {
      return option[mainListOptionsKey] === value;
    } else {
      return option === value;
    }
  };

  const handleEmptyValue = (valueParam) => {
    /**
     * TODO:: Add these in utility folder.
     */
    if (isSelectMultiple) {
      return value && IsArrayNotEmpty(value)
        ? value
        : valueParam && IsArrayNotEmpty(valueParam)
        ? valueParam
        : [];
    } else {
      if (IsObject(valueParam) || IsObject(value)) {
        return IsNotUndefined(value) &&
          value !== null &&
          IsObjectNotEmpty(value)
          ? value
          : IsNotUndefined(valueParam) &&
            valueParam !== null &&
            IsObjectNotEmpty(valueParam)
          ? valueParam
          : null;
      } else if (IsString(valueParam) || IsString(value)) {
        return IsNotEmpty(value)
          ? value
          : IsNotEmpty(valueParam)
          ? valueParam
          : null;
      }
    }
  };

  const handleOnBlur = () => {
    if (IsFunction(onBlur)) {
      onBlur();
    }
  };

  const autocompleteValue = handleEmptyValue(autovalue);

  const inputRequired =
    required === true &&
    (isSelectMultiple
      ? !IsArrayNotEmpty(autocompleteValue)
      : !IsNotEmpty(autocompleteValue));

  return (
    <Autocomplete
      className={className}
      multiple={isSelectMultiple}
      value={autocompleteValue}
      filterSelectedOptions={filterSelectedOptions}
      id={id}
      size={size}
      ChipProps={ChipProps}
      disableClearable={disableClearable}
      popupIcon={popupIcon}
      openOnFocus={openOnFocus}
      blurOnSelect={blurOnSelect}
      options={listOptions}
      limitTags={limitTags}
      onChange={handleOnChange}
      disabled={disabled}
      filterOptions={handleFilterOptions}
      getOptionLabel={handleGetOptionLabel}
      getOptionSelected={handleGetOptionSelected}
      
      name={name}
      onBlur={handleOnBlur}
      renderInput={(params) => (
        <div>
       <TextField
            {...params}
            id={renderInputId ? renderInputId : label}
            variant={variant}
            label={!labelAtTop && label}
            className={textFieldClassName}
            required={inputRequired}
            //onChange={()=>{}}
            placeholder={placeholder}
            fullWidth={fullWidth}
            InputLabelProps={inputLabelProps}
            helperText={helperText}
            error={error}           
          /> 
        </div>
      )}
    />
  );
};

export default TypeaheadField;

我想更多地了解您的代碼以獲得更好的上下文。 第一個建議是使用道具 anchorEl 並引用您的 Textfield。 您可以在此處的文檔中找到有關它的更多信息和示例:

https://material-ui.com/es/components/popper/

而且我不知道您是否直接使用自動完成組件,所以如果您是,請告訴我。

暫無
暫無

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

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