samedi 5 mars 2022

Toggle a button selection on same and others in React (Javascript)?

I have a form with a question and 3 answers. Only one answer can be selected so I need to toggle each answer individually AND toggle between the 3.

I put an incoming array of objects into state on component load and iterate over that data. I add in a selected key to each object of the array with boolean which will be deleted before form submit.

Right now the behavior is that I'm able to toggle the same button but clicking another does change the previous selected but have to click again to select the new current. Obviously one crucial set is missing but not sure if I should set up a new state or if it can be done with the current config. Basically, the buttons should behave like checkboxes.

The code:

const answers = ['Frequency', 'Some Times', 'Hardly Ever'] // predefined 

const ChecklistModal = ({ setShowModal, checklist }: any) => {

  const [updatedList, setUpdatedList] = useState(
    checklist.list.map((c) => ({
      ...c,
      selected: !!c.answer, // added key with truthy value based on already chosen from 
                            // backend or selected in form (frontend) 
    })),
  ) 
  
// where the magic happens 
  const handleAnswer = (
    answer: string,
    questionId: number,
    listIdx: number,
  ) => {
    const listCopy = [...updatedList]
    const list = listCopy[listIdx]
    list.question = questionId
    list.answer = answer
    list.selected = !list.selected
    listCopy[listIdx] = list
    setUpdatedList(listCopy)
  }

  return (
    <Modal>

      <View style={[styles.container, containerByDevice]}>

       // relevant code 

        {checklist.list.map((li, index) => (
          <View key={li.question.id}>
            <Text style={styles.questionText}>{li.question.title}</Text>
            <View style={styles.answerRow}>
              {answers.map((answer) => (
                <View
                  key={answer}
                  style={
                    updatedList[index].selected &&
                    updatedList[index].answer === answer
                      ? styles.selectedAnswerButton
                      : styles.answerButton
                  }
                >
                  <TouchableOpacity
                    onPress={() => {
                      handleAnswer(answer, li.question.id, index)
                    }}
                  >
                    <Text>{answer}</Text>
                  </TouchableOpacity>
                </View>
              ))}
            </View>
          </View>
        ))}
      </View>
    </Modal>
  )
}

export default ChecklistModal

The initial checklist data looks like this:

   checklist {
        concern {
          title
        }
        list {
          question {
            id
            title
          }
          answer
        }
      }
    }
  }
`



Aucun commentaire:

Enregistrer un commentaire