Search code examples
javascripthtmlreactjsbuttondisable

How to disable a button in React.js until one or several form field value changes?


I have a form within a react component:

import React, { useState, useRef, useEffect } from 'react';
import { useAuth } from './AuthContext';

export default function EditProfile() {
   //refs for form fields
   const nameRef = useRef();
   const hometownRef = useRef();
         .
         .
         .
   //refs for other fields in the form

   //state variable to store data fetched from database
   const [currentUserData, setCurrentUserData] = useState({});

   //context that has current user data
   const { currentUser } = useAuth();

  //useEffect to fetch data from database when component first mounts
    useEffect(() => {
          ... code that fetches user data ...
          setCurrentUserData(doc.data());
   
  }, []);

  
  function handleSubmitEditProfile(e) {
    e.preventDefault();

    var docRef = db.collection('users').doc(currentUser.uid);

    var updateDocuments = docRef
      .update({
        name: nameRef.current.value,
        school: schoolRef.current.value,
        currentCity: currentCityRef.current.value,
        hometown: hometownRef.current.value,
        hobbies: hobbiesRef.current.value,
      })
      .then(() => {
        console.log('Document successfully updated');
      });
  }

   return(
       <form onSubmit={handleSubmitEditProfile}>
                <div className='row'>
                  <div className='label'>
                    <label for='name'>Name</label>
                  </div>
                  <input
                    type='text'
                    name='name'
                    ref={nameRef}
                    defaultValue={currentUserData.displayName && currentUserData.displayName}
                  />
                </div>
                        .
                        .
                        .

                 <div className='row'>
                  <div className='label'>
                    <label for='hometown'>Hometown</label>
                  </div>
                  <input
                    type='text'
                    name='hometown'
                    ref={hometownRef}
                    defaultValue={
                      currentUserData.hometown && currentUserData.hometown
                    }
                  />
                </div>
                <button className='submit-btn' type='submit'>
                  Submit
                </button>
              </form>
   )
}

I have populated the fields in the form from the data fetched from database. The user might not have values for these fields in the database and could be entering data for the first time to be submitted to database.

I want the submit button disabled in the case where the form fields are empty and enable the button when user enters data in the form fields. I also want to make the button disabled if the form fields are populated with data from database but none of them have been edited by the user. There could be a state variable that can be set to true if there are empty fields and that disables the button but how can I set it up to also work with the later case mentioned above?


Solution

  • Using a state variable to store true/false values for disabled attribute in the button worked for both of the scenarios. I made changes by having state variables to store the field values.

    const [name, setName] = useState('');
    const [hometown, setHometown] = useState('');
    
    //state to control the disabled attribute in the button
    const [disabled, setDisabled] = useState(true);
    

    and changed the input JSX to:

                      <input
                        type='text'
                        name='name'
                        defaultValue={currentUser.displayName}
                        ref={nameRef}
                        onChange={(e) => {
                          setName(e.target.value);
                          setDisabled(false);
                        }}
                      />
    

    which would toggle the disabled state variable to true when the user enters some info in the fields(did the same for every input fields in the JSX).

    And after the database is updated in the handleSubmitEditProfile() function, I added the line

    setDisabled(true);
    

    to toggle it back so that the button is disabled after submitting the form.