2

I tried to implement something like a multi-select, where the user can either select a value from a data list or can type in a new value. A chosen value should be added to an array if the user presses enter. For detecting changes in the input field I use onChange and a state variable that saves the current value typed in. For detecting the press of enter I use onKeyDown. The problem is that I'm no longer able to type something in the input field, however choosing values from the data list works. I figured out that when I comment out onKeyDown, I can type something in the input field and can also choose from values provided by the data list. However, in this case, adding values to an array on the press of enter doesn't work. I'm fairly new to React, is there something I miss? My current code looks like follows:

const EditableMultiSelect = ({ field, helpers, metadataField, editMode, setEditMode }) => {
    const { t } = useTranslation();

    const [inputValue, setInputValue] = useState('');

    const handleChange = e => {
       
        const itemValue = e.target.value;
        setInputValue(itemValue);


    }

    const handleKeyDown = event => {
        event.preventDefault();

        if (event.keyCode === 13) {
            field.value[field.value.length] = inputValue;
            helpers.setValue(field.value);
            setInputValue("");
        }


    }

    const removeItem = () => {
        console.log('to be implemented');
    }

    return (
        editMode ? (
            <>
                <div
                     onBlur={() => setEditMode(false)}
                     ref={childRef}>
                    <input name="inputValue"
                           value={inputValue}
                           type="text"
                           onKeyDown={e => handleKeyDown(e)}
                           onChange={e => handleChange(e)}
                           placeholder={t('EDITABLE.MULTI.PLACEHOLDER')}
                           list="data-list"
                    />
                    <datalist id="data-list">
                        {metadataField.collection.map((item, key) => (
                            <option key={key}>{t(item.value)}</option>
                        ))}
                    </datalist>
                </div>
                {(field.value instanceof Array && field.value.length !== 0) ? (field.value.map((item, key) => (
                        <span className="ng-multi-value"
                              key={key}>
                        {t(item)}
                            <a onClick={() => removeItem(key)}>
                            <i className="fa fa-times" />
                        </a>
                    </span>
                    ))) : null}
            </>

        ) : (
            <div onClick={() => setEditMode(true)}>
                {(field.value instanceof Array && field.value.length !== 0) ? (
                    <ul>
                        {field.value.map((item, key) => (
                            <li key={key}>
                                <span>{item}</span>
                            </li>
                        ))}
                    </ul>
                ) : (
                    <span className="editable preserve-newlines">
                            {""}
                    </span>
                )}
                <i className="edit fa fa-pencil-square"/>
            </div>
        )
    );
};
1
  • In handling handleKeyDown you're calling event.preventDefault();, which will effectively prevent the keypress from doing anything. Commented Nov 26, 2020 at 8:47

3 Answers 3

6

You're calling event.preventDefault() every time a key is pressed. You should move it inside the if statement:

const handleKeyDown = event => {
  if (event.keyCode === 13) {
    event.preventDefault();
    field.value[field.value.length] = inputValue;
    helpers.setValue(field.value);
    setInputValue("");
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

you can't type anything anymore in the input text because in the handleKeyDown event handler, you're calling event.preventDefault() in the early lines. So i think you just have to move it into the if case:

const handleKeyDown = event => {
  if (event.keyCode === 13) {
    event.preventDefault();

    field.value[field.value.length] = inputValue;
    helpers.setValue(field.value);
    setInputValue("");
  }
}

Comments

-1

Remove e.preventDefault() or put it inside the if statements.
It is the one preventing the input from being editable.

1 Comment

Welcome to SO! Please take a look at the other answers that were given before. Your approach is mentioned there already. In order to keep the site clear and make it easy to find answers, we try to avoid double answers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.