0

I am trying to get an input field to appear when the user selects 'other' from the drop down menu. It was only appearing when I first got on the add recipes page, but I changes a few lines and then it stopped appearing all together. I am using FLask for the backend and it is pulling the cuisines from a database.

import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';

function AddRecipe() {
  const navigate = useNavigate();
  const [formData, setFormData] = useState({
    name: '',
    description: '',
    ingredients: '',
    directions: '',
    prep_time: '',
    total_servings: '',
    image: '',
    cuisine_id: '',
    user_id: '', 
  });

  const [cuisines, setCuisines] = useState([]);
  const [otherCuisineName, setOtherCuisineName] = useState('');
  const [selectedCuisine, setSelectedCuisine] = useState('');
  const [successMessage, setSuccessMessage] = useState('');

  useEffect(() => {
    fetchCuisines();
  }, []);

  const fetchCuisines = async () => {
    try {
      const response = await fetch('/api/cuisines');
      const data = await response.json();
      setCuisines(data);
    } catch (error) {
      console.error('Error fetching cuisines:', error);
    }
  };

  const handleInputChange = (e) => {
    const { name, value } = e.target;
    setFormData({ ...formData, [name]: value });
  };

  const handleCuisineChange = (e) => {
    const value = e.target.value;
    console.log("Selected cuisine:", value);
    setSelectedCuisine(value);
    if (value === 'Other') {
      setOtherCuisineName('');
      document.getElementById('other-cuisine-input').style.display = 'block';
    } else {
      document.getElementById('other-cuisine-input').style.display = 'none';
    }
  };

  const handleOtherCuisineNameChange = (e) => {
    setOtherCuisineName(e.target.value);
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    let cuisineId;
    if (selectedCuisine === 'Other') {
      try {
        const response = await fetch('/api/cuisines', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ name: otherCuisineName }),
        });
        const data = await response.json();
        cuisineId = data.id;
      } catch (error) {
        console.error('Error creating new cuisine:', error);
      }
    } else {
      cuisineId = selectedCuisine;
    }
    // Retrieves cuisine id
    formData.cuisine_id = cuisineId;
    try {
      const response = await fetch('/api/recipes', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(formData),
      });
      const data = await response.json();
      console.log('Recipe created:', data);
      setSuccessMessage(`${formData.name} added!`);
      setFormData({
        name: '',
        description: '',
        ingredients: '',
        directions: '',
        prep_time: '',
        total_servings: '',
        image: '',
        cuisine_id: '',
        user_id: '', 
      });
      navigate('/recipes')
    } catch (error) {
      console.error('Error creating recipe:', error);
    }
  };

  return (
    <div className="addrecipe">
      <h2>Add Recipe</h2>
      <form onSubmit={handleSubmit}>
        <div className="addrecipe-card">
          {successMessage && <p>{successMessage}</p>}
          <label>Name:</label>
          <input
            type="text"
            name="name"
            placeholder="recipe name"
            value={formData.name}
            onChange={handleInputChange}
            required
          />
          <div>
            <label>Description:</label>
            <textarea
              name="description"
              placeholder="brief recipe description"
              value={formData.description}
              onChange={handleInputChange}
              required
            />
          </div>
          <div>
            <label>Ingredients:</label>
            <textarea
              name="ingredients"
              placeholder="recipe ingredients separated by commas"
              value={formData.ingredients}
              onChange={handleInputChange}
              required
            />
            <label>Directions:</label>
            <textarea
              name="directions"
              placeholder="recipe directions separated by periods."
              value={formData.directions}
              onChange={handleInputChange}
              required
            />
          </div>
          <div>
            <label>Prep Time (minutes):</label>
            <input
              type="number"
              name="prep_time"
              placeholder="approximate prep time"
              value={formData.prep_time}
              onChange={handleInputChange}
              required
            />
          </div>
          <div>
            <label>Total Servings:</label>
            <input
              type="number"
              name="total_servings"
              placeholder="total servings"
              value={formData.total_servings}
              onChange={handleInputChange}
              required
            />
          </div>
          <div>
            <label>Image Link:</label>
            <input
              type="text"
              name="image"
              value={formData.image}
              onChange={handleInputChange}
            />
          </div>
          <div>
            <label>Cuisine:</label>
            <select
              name="cuisine_id"
              value={selectedCuisine}
              onChange={handleCuisineChange}
              required
            >
              <option value="">Select cuisine...</option>
              {cuisines.map(cuisine => (
                <option key={cuisine.id} value={cuisine.id}>{cuisine.name}</option>
              ))}
              {/* Prevents duplicating of cuisines */}
              {!cuisines.some(cuisine => cuisine.name === 'Other') && (
                <option value="Other">Other</option>
              )}
            </select>

            <input
              id="other-cuisine-input"
              type="text"
              placeholder="Enter custom cuisine name"
              value={otherCuisineName}
              onChange={handleOtherCuisineNameChange}
              style={{ display: selectedCuisine === 'Other' ? 'block' : 'none' }}
            />
          </div>
          <button className="button" type="submit">Add Recipe</button>
        </div>
      </form>
    </div>
  );
}

export default AddRecipe;

2 Answers 2

0

You are using display: none to show and hide your html and this is not a correact approach in React. The correct approach is using condional rendering - see: https://react.dev/learn/conditional-rendering

So in you case you should remove direct HTML manipulation from

const handleCuisineChange = (e) => {
    const value = e.target.value;
    console.log("Selected cuisine:", value);
    setSelectedCuisine(value);
  };

Then in your JSX

              {selectedCuisine === 'Other' && (
                  <input
                    id="other-cuisine-input"
                    type="text"
                    placeholder="Enter custom cuisine name"
                    value={otherCuisineName}
                    onChange={handleOtherCuisineNameChange}
                    style={{ display: selectedCuisine === 'Other' ? 'block' : 'none' }}
                  />
                )}

The snippet above uses logical AND operator. More on this approach here: https://react.dev/learn/conditional-rendering#logical-and-operator-

Sign up to request clarification or add additional context in comments.

Comments

-1

You should use npm dropdown library: Library Get data in a list and then just pass it to dropdown

Comments

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.