{"id":12719,"date":"2025-07-11T07:36:58","date_gmt":"2025-07-11T07:36:58","guid":{"rendered":"https:\/\/www.bacancytechnology.com\/qanda\/?p=12719"},"modified":"2025-07-11T07:36:58","modified_gmt":"2025-07-11T07:36:58","slug":"flutter-table-calendar-events-list","status":"publish","type":"post","link":"https:\/\/www.bacancytechnology.com\/qanda\/flutter\/flutter-table-calendar-events-list","title":{"rendered":"Flutter Table Calendar Events List"},"content":{"rendered":"<p><strong>In the documentation, they say that the calendar takes a dynamic list, and a function of type DateTime<\/strong><\/p>\n<p><img decoding=\"async\" class=\"alignright size-full wp-image-12721\" src=\"https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/11071958\/calaender.png\" alt=\"calendar\" width=\"380\" height=\"367\" srcset=\"https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/11071958\/calaender.png 380w, https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/11071958\/calaender-300x290.png 300w\" sizes=\"(max-width: 380px) 100vw, 380px\" \/><\/p>\n<p>Events The complete example is available here. You can supply custom events to TableCalendar widget. To do so, use eventLoader property &#8211; you will be given a DateTime object, to which you need to assign a list of events.<br \/>\neventLoader: (day) { return _getEventsForDay(day); },<\/p>\n<p>Well, I have a list of dates coming from an api, which is the one below<br \/>\n<em>[2021-07-11 00:00:00.000, 2021-07-25 00:00:00.000, 2021-07-26 00:00:00.000, 2021-07-27 00:00:00.000, 2021-09-01 00:00:00.000, 2021-09-01 00:00:00.000, 2021-09-03 00:00:00.000, 2021-09-03 00:00:00.000, 2021-09-22 00:00:00.000, 2021-09-24 00:00:00.000, 2021-10-18 00:00:00.000, 2021-10-21 00:00:00.000]<\/em><\/p>\n<p>This list is in string format, so I converted it like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\">\r\nfinal events = await _jobsServices.getEvents(); final eventsConvert = events .map((date) =&gt; (DateTime.parse(date.dataDoJob))) .toList(); eventsList.assignAll(eventsConvert);\r\n<\/pre>\n<p>The first list is called events, and the list that receives the data that comes from the api, so I converted it to a  date time format, but as you can see in the photo, all calendar days are marked.<\/p>\n<p>On my calendar widget, I put it like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\">\r\nTableCalendar(\r\n              eventLoader: (day) => controller.eventsList, \/\/THIS IS THE EVENTS\r\n              calendarBuilders: const CalendarBuilders(),\r\n              focusedDay: controller.focusedDay.value,\r\n              firstDay: DateTime(2019),\r\n              lastDay: DateTime(2050),\r\n              headerStyle:\r\n                  const HeaderStyle(formatButtonVisible: false), \/\/WEEK VISIBLE\r\n              locale: 'pt_BR',\r\n              daysOfWeekVisible: true,\r\n              calendarFormat: controller.format.value,\r\n              onFormatChanged: (CalendarFormat _format) =>\r\n                  controller.calendarFormat(_format),\r\n              onDaySelected: (DateTime userSelectedDay, DateTime focusedDay) =>\r\n                  controller.selectedDay(userSelectedDay, focusedDay),\r\n              calendarStyle: CalendarStyle(\r\n                  selectedTextStyle: const TextStyle(color: Colors.white),\r\n                  isTodayHighlighted: true,\r\n                  selectedDecoration: BoxDecoration(\r\n                      color: context.buttomThemeClicled,\r\n                      shape: BoxShape.circle)),\r\n              selectedDayPredicate: (DateTime date) {\r\n                return isSameDay(controller.focusedDay.value, date);\r\n              },\r\n            );\r\n<\/pre>\n<h2>Fix Showing Events Dots on Every Date for Table Calendar<\/h2>\n<p>You&#8217;re trying to mark events on a TableCalendar using a list of date strings from an API, but all days in the calendar are showing as having events (see image).<\/p>\n<p>eventLoader: (day) => controller.eventsList, \/\/ controller.eventsList is a List<DateTime><\/p>\n<p>eventLoader expects a function that returns <strong>a list of events only for the specific<\/strong> day passed in, but you&#8217;re returning the <strong>entire list of events every time<\/strong>, regardless of the day.<\/p>\n<h3>Solution:<\/h3>\n<p>You need to convert the list of event DateTimes into a Map<DateTime, List> where each key is a day (normalized to remove the time), and the value is a list of events for that day. Then use that map in eventLoader.<\/p>\n<p><strong>Note:<\/strong> In this example, the API response is mocked as a List<String> for demonstration purposes.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\">\r\nclass _CalendarScreenState extends State<CalendarScreen> {\r\n late final Map<DateTime, List<String>> _eventsMap;\r\n final DateTime _focusedDay = DateTime(2021, 11, 10);\r\n final DateTime _selectedDay = DateTime(2021, 11, 10);\r\n\r\n final List<String> apiDates = [\r\n   '2021-07-11 00:00:00.000',\r\n   '2021-07-25 00:00:00.000',\r\n   '2021-07-26 00:00:00.000',\r\n   '2021-07-27 00:00:00.000',\r\n   '2021-09-01 00:00:00.000',\r\n   '2021-09-01 00:00:00.000',\r\n   '2021-09-03 00:00:00.000',\r\n   '2021-09-03 00:00:00.000',\r\n   '2021-09-22 00:00:00.000',\r\n   '2021-09-24 00:00:00.000',\r\n   '2021-10-18 00:00:00.000',\r\n   '2021-10-21 00:00:00.000',\r\n   '2021-11-10 00:00:00.000',\r\n   '2021-11-15 00:00:00.000',\r\n   '2021-11-15 00:00:00.000',\r\n ];\r\n @override\r\n void initState() {\r\n   super.initState();\r\n   _eventsMap = _convertEvents(apiDates);\r\n }\r\n Map<DateTime, List<String>> _convertEvents(List<String> eventStrings) {\r\n   final map = <DateTime, List<String>>{};\r\n   for (var dateStr in eventStrings) {\r\n     final parsed = DateTime.parse(dateStr);\r\n     final dateOnly = DateTime(parsed.year, parsed.month, parsed.day);\r\n     map.putIfAbsent(dateOnly, () => []).add('Evento');\r\n   }\r\n   return map;\r\n }\r\n @override\r\n Widget build(BuildContext context) {\r\n   return Scaffold(\r\n     appBar: AppBar(title: const Text('Table Calendar Example')),\r\n     body: Padding(\r\n       padding: const EdgeInsets.all(16.0),\r\n       child: TableCalendar(\r\n         locale: 'pt_BR',\r\n         focusedDay: _focusedDay,\r\n         firstDay: DateTime(2019),\r\n         lastDay: DateTime(2050),\r\n         startingDayOfWeek: StartingDayOfWeek.monday,\r\n         calendarFormat: CalendarFormat.month,\r\n         headerStyle: const HeaderStyle(formatButtonVisible: false),\r\n         calendarStyle: const CalendarStyle(\r\n           selectedDecoration: BoxDecoration(\r\n             color: Colors.orange,\r\n             shape: BoxShape.circle,\r\n           ),\r\n           todayDecoration: BoxDecoration(\r\n             color: Colors.blueAccent,\r\n             shape: BoxShape.circle,\r\n           ),\r\n         ),\r\n         selectedDayPredicate: (day) => isSameDay(day, _selectedDay),\r\n         eventLoader: (day) {\r\n           final dateOnly = DateTime(day.year, day.month, day.day);\r\n           return _eventsMap[dateOnly] ?? [];\r\n         },\r\n         onDaySelected: (selectedDay, focusedDay) {\r\n           print('Selected: $selectedDay');\r\n         },\r\n       ),\r\n     ),\r\n   );\r\n }\r\n}\r\n<\/pre>\n<h3>Screenshot:<\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/11072531\/cal-output-473x1024.png\" alt=\"cal-output\" width=\"473\" height=\"1024\" class=\"alignright size-large wp-image-12722\" srcset=\"https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/11072531\/cal-output-473x1024.png 473w, https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/11072531\/cal-output-138x300.png 138w, https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/11072531\/cal-output-768x1664.png 768w, https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/11072531\/cal-output-709x1536.png 709w, https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/11072531\/cal-output.png 945w\" sizes=\"(max-width: 473px) 100vw, 473px\" \/><\/p>\n<div class=\"qanda-read-box\"><div class=\"bg-light read-more-icon\"><img decoding=\"async\" src=\"https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/04\/24061434\/read-txt.png\" alt=\"Also Read\"><p><\/p><h3>Also Read:<\/h3><a href=\"https:\/\/www.bacancytechnology.com\/blog\/flutter-bloc-tutorial\" target=\"_blank\">Flutter BLoC Tutorial<\/a><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>In the documentation, they say that the calendar takes a dynamic list, and a function of type DateTime Events The complete example is available here. You can supply custom events to TableCalendar widget. To do so, use eventLoader property &#8211; you will be given a DateTime object, to which you need to assign a list [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":12720,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[15],"tags":[],"class_list":["post-12719","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-flutter"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts\/12719"}],"collection":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/comments?post=12719"}],"version-history":[{"count":1,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts\/12719\/revisions"}],"predecessor-version":[{"id":12723,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts\/12719\/revisions\/12723"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/media\/12720"}],"wp:attachment":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/media?parent=12719"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/categories?post=12719"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/tags?post=12719"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}