Home > database >  Flutter - How to perform multi select in the same list of objects but with a different question?
Flutter - How to perform multi select in the same list of objects but with a different question?

Time:09-03

I have a list of objects called options

List<Map<String, dynamic>> options = [
{"name": "usually", "value": 100, "id": 1},
{"name": "sometimes", "value": 70, "id": 2},
{"name": "rarely", "value": 40, "id": 3},
{"name": "never", "value": 0, "id": 4},

];

also, I have another list called questions

  late List<Map<String, dynamic>> questions = [
{"id": 1, "name": "Q1", "options": options},
{"id": 2, "name": "Q2", "options": options},
{"id": 3, "name": "Q3", "options": options},
{"id": 4, "name": "Q4", "options": options},
{"id": 5, "name": "Q5", "options": options},
{"id": 6, "name": "Q6", "options": options},
{"id": 7, "name": "Q7", "options": options},
{"id": 8, "name": "Q8", "options": options},
{"id": 9, "name": "Q9", "options": options},
{"id": 10, "name": "Q10", "options": options},
{"id": 11, "name": "Q11", "options": options},
{"id": 12, "name": "Q12", "options": options},
{"id": 13, "name": "Q13", "options": options},
{"id": 14, "name": "Q14", "options": options},

];

How can I perform multi select for each question which allow the user select one option per one question ?

Code for the UI

return Scaffold(
  body: Column(
    children: [
      Expanded(
        child: ListView.separated(
          itemCount: questions.length,
          separatorBuilder: (context, index) {
            return Divider();
          },
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(questions[index]['name']),
              subtitle: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.min,
                children: List.generate(
                    questions[index]['options'].length,
                    (lowerIndex) => Padding(
                        padding: const EdgeInsets.all(5.0),
                        child: InkWell(
                            onTap: () =>
                                ChoicesHelper.addValueToSelectedValuesList(
                                    questions[index]['options'][lowerIndex]
                                        ['value'],
                                    questions[index]['id'],
                                    questions[index]['options'][lowerIndex]
                                        ['id']),
                            child: Row(
                                crossAxisAlignment:
                                    CrossAxisAlignment.center,
                                mainAxisAlignment: MainAxisAlignment.center,
                                mainAxisSize: MainAxisSize.min,
                                children: [
                                  Container(
                                      width: 20,
                                      height: 20,
                                      color:  Colors.grey  ),
                                  SizedBox(width: 1),
                                  Text(questions[index]['options']
                                      [lowerIndex]['name'])
                                ])))),
              ),
            );
          },
        ),
      ),
      ElevatedButton(
          onPressed: () {
            ChoicesHelper.calculateResults();
          },
          child: Text('Calculate')),
    ],
  ),
);

Code for the methods in another class

  static List<int> selectedValues = [];
  static List<Map<String, dynamic>> answeredQuestionsIds = [];

  static void addValueToSelectedValuesList(int value, int questionID, optionID) {

    selectedValues.add(value);
    answeredQuestionsIds.add({"questionID": questionID,"optionID": optionID});

  }

enter image description here

As you can see, I just need to select one box for each question and turn it's color to red, but the problem is that all the row for single question is selected and all the boxes turns into red.

How can I select only one option for one question ?

CodePudding user response:

try this:

class ListWidget extends StatefulWidget {
  const ListWidget({Key? key}) : super(key: key);

  @override
  State<ListWidget> createState() => _ListWidgetState();
}

class _ListWidgetState extends State<ListWidget> {
  late List<Map<String, dynamic>> questions = [
    {"id": 1, "name": "Q1", "options": options},
    {"id": 2, "name": "Q2", "options": options},
    {"id": 3, "name": "Q3", "options": options},
    {"id": 4, "name": "Q4", "options": options},
    {"id": 5, "name": "Q5", "options": options},
    {"id": 6, "name": "Q6", "options": options},
    {"id": 7, "name": "Q7", "options": options},
    {"id": 8, "name": "Q8", "options": options},
    {"id": 9, "name": "Q9", "options": options},
    {"id": 10, "name": "Q10", "options": options},
    {"id": 11, "name": "Q11", "options": options},
    {"id": 12, "name": "Q12", "options": options},
    {"id": 13, "name": "Q13", "options": options},
    {"id": 14, "name": "Q14", "options": options},
  ];
  List<Map<String, dynamic>> options = [
    {"name": "usually", "value": 100, "id": 1},
    {"name": "sometimes", "value": 70, "id": 2},
    {"name": "rarely", "value": 40, "id": 3},
    {"name": "never", "value": 0, "id": 4},
  ];

  List<Question> _questions = [];

  @override
  void initState() {
    super.initState();
    _questions = questions.map((e) => Question.fromJson(e)).toList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
          itemCount: _questions.length,
          itemBuilder: (context, index) {
            return _buildQuestion(
              _questions[index],
              (int? value) {
                print("cvalue = ${value}");
                var q = Question(
                    name: _questions[index].name,
                    id: _questions[index].id,
                    options: _questions[index].options,
                    groupValue: value!);
                setState(() {
                  _questions[index] = q;
                });
              },
            );
          }),
    );
  }

  _buildQuestion(Question question, Function(int?)? onChanged) {
    return Row(
      children: [
        Expanded(
          child: RadioListTile<int?>(
              contentPadding: EdgeInsets.zero,
              dense: true,
              visualDensity: VisualDensity(horizontal: -4),
              title: Text(question.options[0].name),
              value: question.options[0].value,
              groupValue: question.groupValue,
              onChanged: onChanged),
        ),
        Expanded(
          child: RadioListTile<int?>(
              contentPadding: EdgeInsets.zero,
              dense: true,
              visualDensity: VisualDensity(horizontal: -4),
              title: Text(question.options[1].name),
              value: question.options[1].value,
              groupValue: question.groupValue,
              onChanged: onChanged),
        ),
        Expanded(
          child: RadioListTile<int?>(
              contentPadding: EdgeInsets.zero,
              dense: true,
              visualDensity: VisualDensity(horizontal: -4),
              title: Text(question.options[2].name),
              value: question.options[2].value,
              groupValue: question.groupValue,
              onChanged: onChanged),
        ),
        Expanded(
          child: RadioListTile<int?>(
              contentPadding: EdgeInsets.zero,
              dense: true,
              visualDensity: VisualDensity(horizontal: -4),
              title: Text(question.options[3].name),
              value: question.options[3].value,
              groupValue: question.groupValue,
              onChanged: onChanged),
        ),
      ],
    );
  }
}

class Question {
  final String name;
  final int id;
  final List<OptionModel> options;
  final int groupValue;
  Question(
      {required this.name,
      required this.id,
      required this.options,
      required this.groupValue});

  static Question fromJson(Map<String, dynamic> json) {
    return Question(
        name: json['name'],
        id: json['id'],
        groupValue: -1,
        options: (json['options'] as List)
            .map((e) => OptionModel.fromJson(e))
            .toList());
  }
}

class OptionModel {
  final String name;
  final int value;
  final int id;

  OptionModel({required this.name, required this.id, required this.value});

  static OptionModel fromJson(Map<String, dynamic> json) {
    return OptionModel(
        name: json['name'], id: json['id'], value: json['value']);
  }
}

enter image description here

  • Related