I have the following calendar and code. How can I have the month be only 3 letters eg Nov 2021 instead of November 2021.
Container(
height: MediaQuery.of(context).size.height*0.3,
// width: MediaQuery.of(context).size.width*0.3,
color: Colors.white,
child: TableCalendar(
headerStyle: HeaderStyle(
titleTextStyle: TextStyle(fontSize: 12)
),
shouldFillViewport: true,
rowHeight:MediaQuery.of(context).size.height*0.02,
firstDay: DateTime.utc(2010, 10, 16),
lastDay: DateTime.utc(2030, 3, 14),
focusedDay: DateTime.now(),
onDaySelected: (selectedDay, focusedDay) {
if (!isSameDay(_selectedDay, selectedDay)) {
// Call `setState()` when updating the selected day
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
}
}
),
),
I achieved a responsive table with the customisation I wanted using this code:
Container(
height: MediaQuery.of(context).size.height*0.3,
color: Colors.white,
child: TableCalendar(
calendarStyle: CalendarStyle(
todayTextStyle: TextStyle(fontSize: MediaQuery.of(context).size.width*0.008,color: Colors.white),
weekendTextStyle: TextStyle(fontSize: MediaQuery.of(context).size.width*0.008),
outsideTextStyle: TextStyle(fontSize: MediaQuery.of(context).size.width*0.008),
defaultTextStyle: TextStyle(
fontSize: MediaQuery.of(context).size.width*0.008
)
) ,
headerStyle: HeaderStyle(
titleCentered: true,
titleTextFormatter: (date, locale) => DateFormat.yMMM(locale).format(date),
formatButtonVisible: false,
titleTextStyle: TextStyle(fontSize: MediaQuery.of(context).size.width*0.007)
),
shouldFillViewport: true,
rowHeight:MediaQuery.of(context).size.height*0.02,
firstDay: DateTime.utc(2010, 10, 16),
lastDay: DateTime.utc(2030, 3, 14),
focusedDay: DateTime.now(),
onDaySelected: (selectedDay, focusedDay) {
if (!isSameDay(_selectedDay, selectedDay)) {
// Call `setState()` when updating the selected day
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
}
}
),
),
as new table_calender 3.0.8 to disable two weeks/format button you can set
availableCalendarFormats: const {
CalendarFormat.month : 'Month'
}
and to center the title you also need to set up
headerStyle: HeaderStyle(
titleCentered: true
)
To remove 2 weeks use different calendarFormat
To change Header titile use titleTextFormatter
And finally play with PositionedOffset to control positions.
** Everything that is possible to change is documented here: https://pub.dev/documentation/table_calendar/latest/table_calendar/table_calendar-library.html
Related
What I want to do is listening to a stream which contains Lists of Events for each day of month.
I need this for my TableCalendar Widget
I want to count each Event of each list of the stream and display it in the calendar.
For this I wrote this function:
countEvents(DateTime datetime) {
eventBloc.getEventsOfDay(datetime).listen((event) {
counter = event.length;
});
}
This is where I execute the function (in markerBuilder):
StreamBuilder<List<Event>>(
stream: selectedEvents,
builder: (context, snapshot) {
if (snapshot.hasData) {
final events = snapshot.data;
groupEvents(allEventsList);
return Column(children: [
Card(
clipBehavior: Clip.antiAlias,
margin: const EdgeInsets.all(10),
elevation: 5,
child: TableCalendar(
firstDay: DateTime.utc(1970, 01, 01),
lastDay: DateTime.utc(2999, 12, 31),
focusedDay: _selectedDay,
locale: 'en_US',
onPageChanged: (focusedDay) {
_focusedDay = focusedDay;
},
selectedDayPredicate: (day) {
return isSameDay(_selectedDay, day);
},
headerStyle: HeaderStyle(
decoration: BoxDecoration(
color: AppColors.red,
),
headerMargin: const EdgeInsets.only(bottom: 10),
),
calendarStyle: CalendarStyle(),
calendarBuilders: CalendarBuilders(
markerBuilder: ((context, day, events) {
countEvents(day);
return Container(
width: 20,
height: 15,
decoration: BoxDecoration(
color: AppColors.red,
borderRadius: BorderRadius.circular(4.0)),
child: Text(counter.toString()),
);
})),
//Day Changed
onDaySelected: (DateTime selectDay, DateTime focusDay) {
setState(() {
_selectedDay = selectDay;
_focusedDay = focusDay;
selectedEvents =
eventBloc.getEventsOfDay(_selectedDay);
});
//print(_focusedDay);
},
startingDayOfWeek: StartingDayOfWeek.monday,
eventLoader: getEventsForDay,
),
counter is a global variable for the class
I used the debugger and it seems like the listen function is skipped all the time..
Thank you for your help!
I have a List of DatesAppointmentTotals object.
List<DatesAppointmentTotals> daTotals = [
DatesAppointmentTotals(appointmentDate: '2022/08/08', appointmentTotals: 25),
DatesAppointmentTotals(appointmentDate: '2022/08/09', appointmentTotals: 5),
DatesAppointmentTotals(appointmentDate: '2022/08/10', appointmentTotals: 12),
];
I want to show the appointmentTotals in the table calendar based on the appointmentDate, does anyone have an idea how to do this? Maybe I can add it on the markerbuilder...
body: TableCalendar(
calendarBuilders: CalendarBuilders(
markerBuilder: (context, datetime, events) {
return Container(
width: 48,
height: 15,
decoration: BoxDecoration(color: Colors.blue.shade600),
child: Text(
'24',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 10,
),
),
);
},
),
focusedDay: DateTime.now(),
firstDay: DateTime.now().subtract(Duration(days: 30)),
lastDay: DateTime.now().add(Duration(days: 90)),
calendarFormat: format,
onFormatChanged: (CalendarFormat _format) {
setState(
() {
format = _format;
},
);
},
onDaySelected: (DateTime selectDay, DateTime focusDay) {
setState(() {
selectedDay = selectDay;
focusedDay = focusDay;
showAppointments();
});
},
selectedDayPredicate: (DateTime date) {
return isSameDay(selectedDay, date);
},
isTodayHighlighted: true,
),
I want to print the events from an event list that I'm getting from API. In this code, the events attribute of the Calendar widget is hardcoded. what should I do?
events Map(It's the Map of events that is getting passed on to the events attribute of calender, instead of this i want to pass my own list of events which im getting from API)
final Map<DateTime, List<CleanCalendarEvent>> events = {
DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day): [
CleanCalendarEvent('Event A',
startTime: DateTime(DateTime.now().year, DateTime.now().month,
DateTime.now().day + 1, 10, 0),
endTime: DateTime(DateTime.now().year, DateTime.now().month,
DateTime.now().day + 1, 12, 0),
description: 'A special event',
color: Colors.orangeAccent),
],
};
void _handleData(date) {
setState(() {
selectedDay = date;
selectedEvent = events[selectedDay] ?? [];
});
}
Calendar widget inside the body of Scaffold
Calendar(
startOnMonday: false,
selectedColor: Colors.blue,
todayColor: Colors.red,
eventColor: Colors.green,
eventDoneColor: Colors.amber,
bottomBarColor: Colors.deepOrange,
onRangeSelected: (range) {
print('selected Day ${range.from},${range.to}');
},
onDateSelected: (date) {
return _handleData(date);
},
events: events,
isExpanded: true,
dayOfWeekStyle: const TextStyle(
fontSize: 12,
color: Colors.blueGrey,
fontWeight: FontWeight.bold,
),
bottomBarTextStyle: const TextStyle(
color: Colors.white,
),
hideBottomBar: false,
hideArrows: false,
weekDays: const [
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun'
],
),
I want to get only selected date from tablecalender, but it gives me this output
2021-08-18 12:00:00.000Z
here is tablecalender code
final dateFormat = DateFormat('yyyy-MMMM-dd');
DateTime _chosenDate = DateTime.now();
child: TableCalendar(
calendarController: _controller,
initialSelectedDay: _chosenDate,
initialCalendarFormat: CalendarFormat.month,
calendarStyle: CalendarStyle(
canEventMarkersOverflow: true,
markersColor: Colors.white,
weekdayStyle: TextStyle(color: Colors.blue[900]),
todayColor: Colors.white54,
todayStyle: TextStyle(color: Colors.blue[900], fontSize: 15, fontWeight: FontWeight.bold),
selectedColor: Colors.blue[900],
outsideWeekendStyle: TextStyle(color: Colors.blue[900]),
outsideStyle: TextStyle(color: Colors.blue[900]),
weekendStyle: TextStyle(color: Colors.blue[900]),
renderDaysOfWeek: false,),
onCalendarCreated: (date,event,_){
},
onDaySelected: (date, event,_) {
setState(() {
_chosenDate = date;
print("_chosenDate");
print(_chosenDate);
});
},
));
}
i tried to use split method, but it is not accessible
please help how to get only date (2021-08-18) using tablecalender
in print replace _chosenDate with "${_chosenDate.toString().split(" ").first}"
I'm using table_calendar package to display a calendar on a page.
I want the user to be able to chose a date from the calendar, but when tapping on a date, the focusedDay won't change, so it always stays on the default focusedDay.
I tried to search the docs, and I can't figure out what is wrong, from the docs it seems like it should work fine.
This is what I have for the CalendarWidget:
TableCalendar(
focusedDay: _focusedDay,
firstDay: DateTime.now(),
lastDay: DateTime.utc(2030, 1, 1),
calendarFormat: CalendarFormat.month,
headerStyle: HeaderStyle(
formatButtonVisible: false,
titleCentered: true,
rightChevronIcon: Icon(
Icons.chevron_right,
size: 16,
color: Colors.grey,
),
leftChevronIcon: Icon(
Icons.chevron_left,
size: 16,
color: Colors.grey,
),
),
onDaySelected: (selectedDay, focusedDay) {
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
},
),
This is inside a stateful widget, and I have _focusdDay as a variable in that class, which I update.
The TableCalendar is of course inside the build function of that class.
Don't forget to define the selectedDayPredicate in your TableCalendar:
TableCalendar(
...
selectedDayPredicate: (day) =>isSameDay(day, selectedDay),
...
)
The widget will use this to find out which day is the selected day
Instead of Using this , You can Use DatePicker and Redesign it by Yourself
here is the Example :
onTap: () async {
DateTime newSelectedDate =
await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime.now(),
lastDate: DateTime(2100),
builder: (BuildContext context,
Widget child) {
return Theme(
data: ThemeData.dark().copyWith(
colorScheme: ColorScheme.dark(
primary: Colors.pink,
onPrimary: Colors.white,
surface: Colors.white,
onSurface: Colors.black,
),
dialogBackgroundColor:
Colors.grey[200],
),
child: child,
);
});
if (newSelectedDate != null) {
setState(() {
_selectedDate = newSelectedDate;
final DateFormat formatter =
DateFormat('yyyy-MM-dd');
formattedSelectedDate =
formatter.format(_selectedDate);
});
}
},