简体   繁体   English

如何仅禁用带有复选框的输入字段?

[英]How to disable only a input field with checkbox?

I would like to disable the "Date of Completion" field with the checkbox.我想用复选框禁用“完成日期”字段。

The problem is that I created these fields dynamically, so when I try to disable only the field relating to it, it disables all other "Date of Completion" fields I would like to disable only the previous field and not all others.问题是我动态创建了这些字段,因此当我尝试仅禁用与其相关的字段时,它会禁用所有其他“完成日期”字段我只想禁用前一个字段而不是所有其他字段。

Image图片

    const [checked, setChecked] = useState(false)    
    const [inputList, setInputList] = useState([
        { 
            startDate: "Start Date",            
            completionDate: "Completion Date:",
            inline: true 
        }
    ])
    const handleInputChange = (e, index, val) => {
        const { name, value } = e.target
        setChecked(e.target.checked)    
    
        const list = [...inputList]
    
        list[index][name] = val !== undefined ? val : value 
        setInputList(list)
    }
    const handleRemoveClick = (index) => {
        const list = [...inputList]
        list.splice(index, 1)
        setInputList(list)
    }
    const handleAddClick = () => {
        setInputList([
            ...inputList,
            { 
                startDate: "Start Date",            
                completionDate: "Completion Date:",
                inline: true 
            }
        ])
    }
    let embed = {
        embed: {
            fields: inputList
        }
    }    
    //Form
    {inputList.map((x, i) => {                
        return (
            <>           
                <FormControl>
                    <Box>
                        <FormLabel htmlFor='startDate'>Start Date:</FormLabel>                      
                        <Input 
                            name="startDate"
                            onChange={(e) => handleInputChange(e, i)}              
                            type='text' 
                            placeholder='Start Date' 
                        />                                                
                    </Box>
                    <Box>
                        <FormLabel htmlFor='completionDate'>Completion Date:</FormLabel>                        
                        <Input 
                            name="completionDate"
                            isDisabled={checked ? true : false}
                            onChange={(e) => handleInputChange(e, i)} 
                            type='text' 
                            placeholder='Completion Date' 
                        />                                                
                    </Box>                
                    <Box pt={{ base: '0', md: '2.7rem'}}>                       
                        <Checkbox  
                            type="checkbox" 
                            name="inline" 
                            checked={x.inline}                                     
                            onChange={(e) => handleInputChange(e, i, e.target.checked)}
                            colorScheme='purple'>
                                <label>Studying</label>
                        </Checkbox>  
                    </Box>                                 
                </FormControl>           
                {inputList.length - 1 === i && (
                    <Button onClick={handleAddClick}> + New Section </Button> 
                    )}
                {inputList.length !== 1 && (
                    <Button  onClick={() => handleRemoveClick(i)}>- Remove Section</Button> 
                )}                      
              
            </>
        )
    })} 

You should add checked to inputList object.您应该将checked添加到inputList对象。

const [inputList, setInputList] = useState([
    {
        startDate: "Start Date",
        completionDate: "Completion Date:",
        inline: true,
        checked: false
    }
])
const handleInputChange = (e, index, val) => {
    const { name, value } = e.target

    let newList = inputList
    newList[index]['checked'] = e.target.checked
    setInputList(newList)

    const list = [...inputList]

    list[index][name] = val !== undefined ? val : value
    setInputList(list)
}
const handleRemoveClick = (index) => {
    const list = [...inputList]
    list.splice(index, 1)
    setInputList(list)
}
const handleAddClick = () => {
    setInputList([
        ...inputList,
        {
            startDate: "Start Date",
            completionDate: "Completion Date:",
            inline: true,
            checked: false
        }
    ])
}
let embed = {
    embed: {
        fields: inputList
    }
}
//Form
{
    inputList.map((x, i) => {
        return (
            <>
                <FormControl>
                    <Box>
                        <FormLabel htmlFor='startDate'>Start Date:</FormLabel>
                        <Input
                            name="startDate"
                            onChange={(e) => handleInputChange(e, i)}
                            type='text'
                            placeholder='Start Date'
                        />
                    </Box>
                    <Box>
                        <FormLabel htmlFor='completionDate'>Completion Date:</FormLabel>
                        <Input
                            name="completionDate"
                            isDisabled={x.checked}
                            onChange={(e) => handleInputChange(e, i)}
                            type='text'
                            placeholder='Completion Date'
                        />
                    </Box>
                    <Box pt={{ base: '0', md: '2.7rem' }}>
                        <Checkbox
                            type="checkbox"
                            name="inline"
                            checked={x.inline}
                            onChange={(e) => handleInputChange(e, i, e.target.checked)}
                            colorScheme='purple'>
                            <label>Studying</label>
                        </Checkbox>
                    </Box>
                </FormControl>
                {inputList.length - 1 === i && (
                    <Button onClick={handleAddClick}> + New Section </Button>
                )}
                {inputList.length !== 1 && (
                    <Button onClick={() => handleRemoveClick(i)}>- Remove Section</Button>
                )}

            </>
        )
    })
} 

Your completion date input isDisabled property depends on one checked state which is shared with all completion date input.您的完成日期输入isDisabled属性取决于一个checked状态,该状态与所有完成日期输入共享。

<Input 
    name="completionDate"
    isDisabled={checked ? true : false}       //  <--- checked shared state
    ...
/> 

So, when you click any checkbox, the checked state will be updated by handleInputChange and all completion date input will be in disabled/enabled mode, depending on the latest clicked checkbox checked value.因此,当您单击任何复选框时,已选中状态将由handleInputChange更新,并且所有完成日期输入将处于禁用/启用模式,具体取决于最近单击的复选框选中值。

As said by @hossein , you need to add checked property.正如@hossein 所说,您需要添加checked的属性。 So, let's do it.所以,让我们去做吧。

First, update your inputList initialization:首先,更新您的inputList初始化:

  const [inputList, setInputList] = useState([
    {
      startDate: undefined,           // to hold startDate value
      completionDate: undefined,      // to hold completionDate value
      disabled: false,                // to hold completionDate disabled state
      checked: false,                 // to hold inline checked state
    },
  ]);

Next, update your handleInputChange method:接下来,更新您的handleInputChange方法:

  const handleInputChange = (e, i) => {
    const { checked, name, value } = e.target;
    setInputList((prevState) => {
      if (name === "inline") {
        prevState[i].checked = checked;
        prevState[i].disabled = checked;  // disabled value follows checked value
      } else {
        prevState[i][name] = value;
      }
      return [...prevState];
    });
  };

Next, update your handleAddClick method:接下来,更新您的 handleAddClick 方法:

  const handleAddClick = () => {
    setInputList((prevState) => {
      const newInputs = {
        startDate: undefined,
        completionDate: undefined,
        disabled: false,
        checked: false,
      };
      return [...prevState, newInputs];
    });
  };

And finally, update your onChange at Checkbox component:最后,在 Checkbox 组件中更新您的onChange

// from
onChange={(e) => handleInputChange(e, i, e.target.checked)}
// into
onChange={(e) => handleInputChange(e, i)}

Your code should work after you made those updates.进行这些更新后,您的代码应该可以工作。

Here is the minimal example that works:这是有效的最小示例:

 const { useState } = React; function App() { const [inputList, setInputList] = useState([ { startDate: undefined, completionDate: undefined, disabled: false, checked: false, }, ]); const handleInputChange = (e, i) => { const { checked, name, value } = e.target; setInputList((prevState) => { if (name === "inline") { prevState[i].checked = checked; prevState[i].disabled = checked; } else { prevState[i][name] = value; } return [...prevState]; }); }; const handleAddClick = () => { setInputList((prevState) => { const newInputs = { startDate: undefined, completionDate: undefined, disabled: false, checked: false, }; return [...prevState, newInputs]; }); }; const handleRemoveClick = (index) => { const list = [...inputList]; list.splice(index, 1); setInputList(list); }; return ( <div> <div>App</div> {inputList.map((input, i) => { return ( <div key={i}> <br /> <div> <label> Start Date: <input name="startDate" type="text" onChange={(e) => handleInputChange(e, i)} placeholder="Start Date" /> </label> </div> <div> <label> Completion Date: <input name="completionDate" type="text" disabled={input.disabled} onChange={(e) => handleInputChange(e, i)} placeholder="Completion Date" /> </label> </div> <div> <label htmlFor={`checkbox-${i}`} style={{ cursor: "pointer" }}> <input id={`checkbox-${i}`} name="inline" type="checkbox" checked={input.checked} onChange={(e) => handleInputChange(e, i)} /> {`Checkbox-${i}`} </label> </div> <br /> {inputList.length - 1 === i && ( <button onClick={() => handleAddClick()}>+ New Section</button> )} {inputList.length !== 1 && ( <button onClick={() => handleRemoveClick(i)}> - Remove Section </button> )} </div> ); })} </div> ); } ReactDOM.render(<App />, document.querySelector('.react'));
 <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div class='react'></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM