如何在第一次单击日期文本字段时生成我的日期选择器 UI?

Posted

技术标签:

【中文标题】如何在第一次单击日期文本字段时生成我的日期选择器 UI?【英文标题】:How do I spawn my date picker UI upon first clicking on the date text field? 【发布时间】:2020-07-28 23:19:11 【问题描述】:

我正在使用 React 16.13.0 和材料的 KeyboardDatePicker 组件 -- https://material-ui-pickers.dev/api/KeyboardDatePicker 。我已经这样设置了...

import 
  KeyboardDatePicker,
  KeyboardTimePicker,
  MuiPickersUtilsProvider,
 from "@material-ui/pickers";
...

          <KeyboardDatePicker
            margin="normal"
            id="date-pickUp"
            label="Select Date"
            format="MM/dd/yyyy"
            value=pickUpDateLabel
            onChange=(date) => handleDate(date, "pickUp")
            KeyboardButtonProps=
              "aria-label": "change date",
            
          />

我想调整的是,当我单击可以输入日期的文本字段或单击图标图形以调出日期选择器时,我希望日期选择器 UI 自动出现.我不知道如何配置,只要我点击文本字段,日期选择器的 UI 就会弹出。

编辑:我无法使用代码启动一个正常工作的应用程序,但这是默认呈现的文本字段的屏幕截图,右侧的图标...

现在您必须单击该图标才能显示日期选择器,但我希望能够单击文本字段并立即显示日期选择器。

编辑 2: 响应给定答案的屏幕截图 ...

【问题讨论】:

你能创建一个最小的例子并在这里给出链接吗? 不知道为什么这些问题被否决了。是的,一个可行的例子会很好,并且肯定会帮助加快解决方案,但我真的认为它不值得投反对票。这是一个有趣的问题,我投了赞成票。 您好 rzwnahmd 和 @Dekel,在启动一个正常工作的应用程序时遇到了一些麻烦,但我在我的问题中包含了一个屏幕截图,以说明功能应该出现的内容和位置。 【参考方案1】:

对于使用更新的 material-ui 库 (v5) 的任何人,您可以使用 open=bool 属性来使用何时打开 DatePicker。

           const [dateOpen,setDateOpen] = useState(false);
           const [dueDate,setDueDate] = useState(new Date());
                <DatePicker
                  clearable=true
                  open=dateOpen
                  onClose=() => setDateOpen(false)
                  label="Due Date"
                  value=dueDate
                  minDate=new Date()
                  onChange=(newValue) => 
                    setDueDate(newValue);
                  
                  renderInput=(params) => (
                    <TextField
                      ...params
                      onClick=() => setDateOpen(true)
                    />
                  )
                />

【讨论】:

【参考方案2】:

对于其他感兴趣的人,我想出了以下解决方案:

    您将KeyboardDatePicker 更改为DatePicker 您利用InputProps 并添加日历图标
    InputProps=
        endAdornment: (
            <InputAdornment>
                <Event />
            </InputAdornment>
        )
     

工作沙盒: https://codesandbox.io/s/customicon-forked-zitm9?file=/src/DatePicker.js

【讨论】:

【参考方案3】:

解决此问题时要处理的多个问题:

    由于您想将焦点放在Input 上来控制 DatePicker 弹出框的打开 - 必须是一个受控组件(您可以使用状态来控制它的打开。 这个状态其实就是KeyboardDatePickeropen prop 下一个问题是,一旦关闭 Popover - 焦点将回到 Input,一旦我们获得焦点,Popover 就会打开(不好)。我们可以使用 Popover 的 disableRestoreFocus 属性来解决这个问题。 我们需要使用InputonFocus 来打开Popover,但要真正关闭Popover 的onClose(因为我们控制了Popover 的打开状态)。 最后 - 图标不再控制弹出框的打开。我们需要这样做,使用KeyboardButtonPropsonFocus

这是完整的代码:

const KeyDatePickerContainer = () => 
  const [selectedDate, handleDateChange] = useState(null);
  const [isOpen, setIsOpen] = useState(false);

  return (
    <KeyboardDatePicker
      variant="inline"
      value=selectedDate
      inputVariant="outlined"
      label="With keyboard"
      format="MM/dd/yyyy"
      onChange=newDate => 
        handleDateChange(newDate);
      
      KeyboardButtonProps=
        onFocus: e => 
          setIsOpen(true);
        
      
      PopoverProps=
        disableRestoreFocus: true,
        onClose: () => 
          setIsOpen(false);
        
      
      InputProps=
        onFocus: () => 
          setIsOpen(true);
        
      
      open=isOpen
    />
  );
;

这是一个工作示例的链接:https://codesandbox.io/s/material-pickers-open-modal-click-on-text-kjgjk

更新:如果您还想在选择日期后关闭 DatePicker,您可以使用 onChange 函数不仅可以设置新日期,还可以关闭 Popover:

onChange=newDate => 
    handleDateChange(newDate);
    setIsOpen(false); // Add this

【讨论】:

非常感谢。不过有一件事 - 在您的演示中以及当我将其集成到我的应用程序中时,选择日期选择器 UI 出现的日期并不会关闭 UI 日期选择器并填充底层文本控件(我包含了一个屏幕截图作为对我的问题进行第二次编辑)。如果这太难了,以前有“确定”和“取消”按钮,但现在不会出现。 效果很好!明天会回来接受,因为 SO 让我在奖励赏金前等待一天。 选择在选择日期后单击确定后,它将我返回到当天的日期并且没有关闭选择器。 span>

以上是关于如何在第一次单击日期文本字段时生成我的日期选择器 UI?的主要内容,如果未能解决你的问题,请参考以下文章

如何将颤动的日期选择器值添加到文本字段?

如何在文本字段单击时弹出 datePicker 并在编辑完成后消失

jquery 日历/日期选择器

如果在第二次单击时未选择日期并出现日期验证问题,则日期选择器会从日期选择器文本框中清除所选值

日期选择器在文本字段 iOS 8 上崩溃

按 esc 后无法打开日期选择器