Reri
Reri

Reputation: 25

Passing ListView.builder index data to a text widget

So what I'm trying to achieve is, with the use of ListView.builder, when a user taps on a specific ListTile item, it will open an AlertDialog form where at the top of that form, I want to display a Text widget which will show the specific index (In this case, the String eventName inside the eventList list) of ListView.builder.

The problem is, I have no idea how to call that index to a text widget outside of ListView.builder. Is what I'm trying to achieve possible or is there another way to do this? Also if it helps, I'm getting an error "Undefined name 'index'" when I try to pass the index inside the text widget.

More info on what I'm trying to achieve (excuse my handwriting): The AlertDialog Form

Here is my code:

import 'package:flutter/material.dart';
import 'package:smc_app/Models/events.dart';

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

  @override
  _EventsConfirmationState createState() => _EventsConfirmationState();
}
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
 List<EventList> schoolEvents = [
   EventList(eventName: 'SMC General Assembly', location: 'College Gym', time: '9AM-11AM',),
   EventList(eventName: 'College Finals Week', location: 'SMC', time: 'ALL DAY',),
   EventList(eventName: 'College Baccalaureate and Graduation Day', location: 'TBA', time: 'TBA',),
   EventList(eventName: 'Semester Break', location: 'N/A', time: 'N/A',),
];

    class _EventsConfirmationState extends State<EventsConfirmation> {
    
    
      Future<void> showInformationDialog(BuildContext context) async {
        return await showDialog(context: context,
            builder: (context){
          return AlertDialog(
            content: Form(
              child: Column(
                children: [
                  Text(schoolEvents[index].eventName), //HERE IS WHERE I'M HAVING PROBLEMS 
                  TextFormField(
                    validator: (val) => val!.isEmpty ? 'This field is required' : null,
                    decoration: InputDecoration(hintText: "Name/Student ID"),
                  ),
                ],
              ),
            ),
          );
          });
      }
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Upcoming Events, Confirm Your Attendance.'),
          ),
          body: ListView.builder(
              itemCount: schoolEvents.length,
              itemBuilder: (context, index) {
                return Padding(
                  padding: const EdgeInsets.symmetric(vertical: 1.0, horizontal: 4.0),
                  child: Card(
                    child: InkWell(
                      child: ListTile(
                        onTap: () async {
                          await showInformationDialog(context);
                        },
                        title: Text(schoolEvents[index].eventName),
                        subtitle: Text(schoolEvents[index].location),
                      ),
                    ),
                  ),
                );
              }
          ),
        );
      }
    }

The class for EventList:

class EventList {

String eventName;
String location;
String time;

EventList({required this.eventName, required this.location, required this.time});
}

Hope someone helps me on this thank you.

Upvotes: 0

Views: 1357

Answers (1)

Daniel Silva
Daniel Silva

Reputation: 980

We have some options to fix your issue:

  1. Like @Uni commented you can pass the index as a parameter on your showInformationDialog:

Future showInformationDialog(BuildContext context, int index) async

  1. What I would do, to avoid accessing the list, is pass the schoolEvent as a paramenter instead, this way if something happens to the list after you load the screen it wouldn't affect your function, I would also remove async and await, they are not necessary in this case.
Future<void> showInformationDialog(BuildContext context, EventList event) {
    return showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          content: Form(
            child: Column(
              children: [
                Text(event.eventName),
                TextFormField(
                  validator: (val) => val!.isEmpty ? 'This field is required' : null,
                  decoration: InputDecoration(hintText: "Name/Student ID"),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

And on the list tile:

ListTile(
  onTap: () async {
    await showInformationDialog(context, schoolEvents[index]);
  },
  title: Text(schoolEvents[index].eventName),
  subtitle: Text(schoolEvents[index].location),
);

Upvotes: 1

Related Questions