skip to Main Content

On my site, I’d like to implement a filter that allows users to filter an event based on their range. For example: there are many videos in the database (short videos or short films or feature films). I would like that the user in the field could type, for example, in the "from" field – the number 60, and in the "to" field – the number 120, and he was given films lasting from 60 to 120 minutes.

I already have certain developments. I implemented the input field using TextField. I also made restrictions on the number of characters entered (the number entered cannot be more than seven characters).

But I have a problem that by default in these fields is zero (and also zero appears after the user deletes the previously entered value). Please tell me how can I make the field empty by default.

    const MAX_DURATION = 9999999

export default function Duration() {
  const { filters, setFilters } = useContext(PageContext);
  const [minDuration, setMinDuration] = useState(filters.durationRange.start);
  const [maxDuration, setMaxDuration] = useState(filters.durationRange.end);

  useEffect(() => {
    setMinDuration(filters.durationRange.start);
    setMaxDuration(filters.durationRange.end);
  },
    [filters.durationRange.start, filters.durationRange.end]);

  useEffect(() => {
    var updatedFilters = { ...filters }
    updatedFilters.durationRange = { start: minDuration, end: maxDuration }
    setFilters(updatedFilters)
  }, [minDuration, maxDuration]);


  return (
      <div>
        <div>
          <TextField
            label="From"
            value={minDuration}
            onInput={(e) => {
              e.target.value = Math.max(e.target.value).toString().slice(0, 7)
              const newValue = Number(e.target.value)
              if (newValue) {
                setMinDuration(newValue)
              } else if (newValue == 0) {
                setMinDuration(0)
              }
            }}
          />
        </div>

        <div>
          <TextField
            label="To"
            value={maxDuration}
            onInput={(e) => {
              e.target.value = Math.max(e.target.value).toString().slice(0, 7)
              const newValue = Number(e.target.value)
              if (newValue) {
                setMaxDuration(newValue)
              } else if (newValue === 0) {
                setMaxDuration(0)
              }
              else setMaxDuration(MAX_DURATION)
            }}
          />
        </div>

      </div>
  );
}

2

Answers


  1. I have a problem that by default in these fields is zero (and also
    zero appears after the user deletes the previously entered value).
    Please tell me how can I make the field empty by default.

    The returned value from Number('') is 0

    In your onInput handler you have:

    } else if ( newValue === 0 ) {
        setMaxDuration( 0 );
    }
    

    The problem is that you’re setting the input’s value back to 0. This is the same for the other input too.

    Listening for the input event might not be what you want, perhaps consider listening for the change event

    Login or Signup to reply.
  2. It happens because any time you delete the text from the input, the empty string is going to be type coerced to the value 0.

    To solve this, you could create a function that returns the empty string if the value is equal to ''.

    function getInputValue(value) {
      if (value === '') { // make sure it is ===, not ==
        return '';
      } else {
        return value;
      }
    }
    

    Just call the function on the textfield:

    <TextField label="From" value={getInputValue(minDuration)} ... />
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search