skip to Main Content

I have a for that I am using .trim() on the values during my onChange event to remove the leading and trailing whitespace. As of right now, it is not allowing me to add a space between words until I type the first character of the next word. So if you were to type "next word" you will get "nextword" until you arrow back and add the space between the "next" and "word". Is there I was to use trim, but allow me to type out the name normally? Delay the trailing trim long enough to type the next character? Maybe run .trim() at the time of validation?

Here is how I am currently handling it:

    const [values, setValues] = React.useState({} as any);
    const [errors, setErrors] = React.useState({} as any);

// Handle Input Change
    const handleInputChange = e => {
        const { name, value } = e.target;
        setValues({
            ...values,
            // [name]: value
            [name]: ( typeof value === 'string' ? (value).trim() : value ) 
        });
        if (validateOnChange)
          { validate({ [name]: value }); }
    };

// Validate Form
    const validate = (fieldValues = values) => {
      const temp = { ...errors };
      if ('name' in fieldValues) { 
          if (!fieldValues.name) {
              temp.name = 'Department Name is required.';  }
          else {temp.name = ''; }
      }
      if ('description' in fieldValues) {
        if (!fieldValues.description) {
            temp.description = 'Description is required..';  }
        else {temp.description = ''; }
      }
      setErrors({
          ...temp
      });
      if (fieldValues === values)
          { return Object.values(temp).every(x => x === ''); }
    };

// Edit Record
    async function editRecord(values: any) {
      await axios.put(`${ltUpdateUrl + (values.id)}`, values)
      .then(res => console.log( res.data))
      .catch(error => {console.log( 'the error has occured: ' + error); });
      refreshTable();
    }

// Submit Record
    const handleSubmit = e => {
        e.preventDefault();
        if (validate()){
          editRecord(values);
          closeModal();
        }
    };

I liked handling it as the values we were set, because I did not have to repeat code. If I have to handle it during each part of the validation, I can, but throughout this app there would be a lot of repeated code. Or really, if I could handle it at the time of submit might work fine as well.

3

Answers


  1. I think you can avoid calling trim() if the last character of value = " ":

    const handleInputChange = e => {
      const { name, value } = e.target;
      setValues({
        ...values,
        [name]: ( typeof value === 'string' && value[value.length - 1] !== " " ? (value).trim() : value ) 
      });
    
      if (validateOnChange)
      { validate({ [name]: value }); }
    };
    

    You could also add a timeout that waits to trim for a certain amount of time, but that is not good practice.

    Login or Signup to reply.
  2. if it is about delaying trim maybe using setTimeout would be better

    inputTimeouts[name] = setTimeout(() => {
            setValues({
                ...values,
                [name]: value.trim()
            });
            
            if (validateOnChange) {
                validate({ [name]: value });
            }
        }, 500)
    

    or using lodash debounce like that

    import _ from 'lodash';
    const debouncedHandleInputChange = _.debounce((name, value) => {
      setValues({
        ...values,
        [name]: typeof value === 'string' ? value.trim() : value,
      });
      if (validateOnChange) {
        validate({ [name]: value });
      }
    }, 500);
    
    Login or Signup to reply.
  3. I like your idea of running trim() when you validate, or possibly even later, like when the user presses a submit button or the <input> loses focus, something like that.

    However, you could consider using a debounce() function on your handleInputChange, and running trim() in there.

    const handleInputChange = (e) => { ... }
    
    const debouncedOnChange = debounce(handleInputChange, 500);
    
    return <input onChange={debouncedOnChange} />
    

    (source)

    Personally, I think I’d keep the formatting closer to where you’re processing the data rather than inputting it, but a debounce is a reasonable consideration regardless.

    Here are Lodash resources in case you want to use theirs or use their code as a starting point:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search