Skip to content
Advertisement

Increment and decrement counter according to select or unselect tag

I am working with the next js to handle a question form, I have multiple questions that have multiple answers, and the user may select one or multiple tags for a question. if a user selects one or more tag to answer a question it must increment the counter just one time, If a user unselect a tag it must not decrement until unselect the last tag of the related question.

1 – When the user selects a tag of a question at first increment the counter, but it must not increment when I select the second tag in the same question.

2 – When the user unselects tags of question it must not decrement if any one of them is selected it must not decrement until the last one is unselected.

Now when selecting the first tag it increments the counter but after that, if I select or unselect, it does not decrement or increment.

Please help me to handle this.

enter image description here

My code:

<TageQuestion
     key={item.attributes.Number}
     id={item.attributes.Number}
     data={item}
     name={`${item.attributes.Number}`}
     errors={errors}
     touched={touched}
     handleSelectOption={handleSelectOption}
/>

The component:

<div className="mt-3">
     {Object.keys(attributes.options).map(item => (
       <div className="inline" key={item}>
         <input
           {...feild}
           {...props}
           className="hidden"
           id={item}
           value={item}
           type="checkbox"
           name={`${name}[answer]`}
         />
         <label
           htmlFor={item}
           id={item + "lable"}
           onClick={e => {
             selectTage(e.target);
             handleSelectOption(`question${id}`, item);
           }}
           className="inline-flex items-center px-3 py-0.5 rounded-full text-sm font-medium bg-gray-100 text-gray-800 mr-3 mb-2 cursor-pointer"
         >
           {item}
         </label>
       </div>
     ))}
   </div>

The function:

function handleSelectOption(title, item) {
     setCompareTagTitle(title);

     if (title !== compareTagTitle) {
       setTagItem([...tagItem, item]);
       setCounter(++counter);
     } else if (title === compareTagTitle) {
       setCounter(counter);
     } else {
       setCounter(--counter);
     }
}

Data that come from the backend: t,

Advertisement

Answer

we should consider 2 steps first in child component TagQuestions then in parent component [type].js

step1:

//TagQuestions.js
const [intialRender, setIntialRender] = useState(true);
// if component render for first time
const selectTag = (e) => {
// we should change intialRender to false to say that user select somthing
....
   if (tage.length > 0) {
  const isExit = tage.filter((item) => item.name === el.innerHTML);
  if (isExit.length === 0) {
    setTage([...tage, { name: el.innerHTML }]);
    if (intialRender) {
      setIntialRender(false);
    }
  }
} else {
  setTage([...tage, { name: el.innerHTML }]);
  if (intialRender) {
    setIntialRender(false);
  }
}
....
}
//use effect function to if user unselect all tags after selctions
useEffect(() => {
if (tage.length === 0 && !intialRender) {
   //call parent function and set empty param to true.
   handleSelectOption(`question${id}`, "", true);
 }
}, [tage]);

step2(parent component):

const [compareTagTitle, setCompareTagTitle] = useState([]);
 function handleSelectOption(title, item, empty = false) {
if (empty) {
      const filter = compareTagTitle.filter(
    (value) => value.toString() !== title.toString()
  )
  setCompareTagTitle(filter);
  setCounter(--counter);
} else {
  if (!compareTagTitle.includes(title)) {
    setCompareTagTitle([...compareTagTitle, title]);
    setCounter(++counter);
  }
  }
}
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement