Skip to content

Commit

Permalink
feature: Added month and day view
Browse files Browse the repository at this point in the history
- Added month view
- Added day view
- Added example to demonstrate month view and day view.
  • Loading branch information
PRBaraiya authored and ParthBaraiya committed Jun 23, 2021
1 parent 1408efb commit e8b78b0
Show file tree
Hide file tree
Showing 32 changed files with 3,080 additions and 101 deletions.
1 change: 1 addition & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ app.*.map.json
/android/app/release

pubspec.lock
.vscode/
8 changes: 8 additions & 0 deletions example/lib/constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import 'dart:ui';

class AppConstants {
AppConstants._();

static const Color black = Color(0xff444444);
static const Color white = Color(0xffefefef);
}
209 changes: 209 additions & 0 deletions example/lib/create_event_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import 'package:example/constants.dart';
import 'package:example/date_time_selector.dart';
import 'package:example/event.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_calendar_page/flutter_calendar_page.dart';

import 'extension.dart';

class CreateEventPage extends StatefulWidget {
final bool withDuration;

const CreateEventPage({Key? key, this.withDuration = false})
: super(key: key);

@override
_CreateEventPageState createState() => _CreateEventPageState();
}

class _CreateEventPageState extends State<CreateEventPage> {
GlobalKey<FormState> _formKey = GlobalKey();

late DateTime _date;
DateTime? _startTime;
DateTime? _endTime;
String _title = "";
String _description = "";

late FocusNode _titleNode;
late FocusNode _descriptionNode;
late FocusNode _dateNode;

@override
void initState() {
super.initState();

_titleNode = FocusNode();
_descriptionNode = FocusNode();
_dateNode = FocusNode();
}

@override
void dispose() {
_titleNode.dispose();
_descriptionNode.dispose();
_dateNode.dispose();

super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
centerTitle: false,
leading: IconButton(
onPressed: context.popRoute,
icon: Icon(
Icons.arrow_back,
color: AppConstants.black,
),
),
title: Text(
"Create New Event",
style: TextStyle(
color: AppConstants.black,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
body: Form(
key: _formKey,
child: ListView(
padding: const EdgeInsets.symmetric(vertical: 30.0, horizontal: 10.0),
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: [
TextFormField(
focusNode: _titleNode,
style: TextStyle(
color: AppConstants.black,
fontSize: 17.0,
),
decoration: InputDecoration(
labelText: "Title",
),
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.trim() == "") return "Invalid Title";
return null;
},
onSaved: (value) => _title = value ?? "",
),
SizedBox(
height: 15.0,
),
DateTimeSelectorFormField(
decoration: InputDecoration(
labelText: "Select Date",
),
onSave: (date) => _date = date,
textStyle: TextStyle(
color: AppConstants.black,
fontSize: 17.0,
),
type: DateTimeSelectionType.date,
),
SizedBox(
height: 15.0,
),
if (widget.withDuration) ...[
Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: DateTimeSelectorFormField(
decoration: InputDecoration(
labelText: "Start Time",
),
textStyle: TextStyle(
color: AppConstants.black,
fontSize: 17.0,
),
onSave: (date) => _startTime = date,
type: DateTimeSelectionType.time,
),
),
SizedBox(width: 20.0),
Expanded(
child: DateTimeSelectorFormField(
decoration: InputDecoration(
labelText: "End Time",
),
textStyle: TextStyle(
color: AppConstants.black,
fontSize: 17.0,
),
onSave: (date) => _endTime = date,
type: DateTimeSelectionType.time,
),
),
],
),
SizedBox(
height: 15.0,
),
],
TextFormField(
focusNode: _descriptionNode,
style: TextStyle(
color: AppConstants.black,
fontSize: 17.0,
),
keyboardType: TextInputType.multiline,
textInputAction: TextInputAction.newline,
selectionControls: MaterialTextSelectionControls(),
minLines: 1,
maxLines: 10,
maxLength: 1000,
validator: (value) {
if (value == null || value.trim() == "")
return "Invalid Description";
return null;
},
decoration: InputDecoration(
labelText: "Description",
),
onSaved: (value) => _description = value ?? "",
),
SizedBox(
height: 50.0,
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState?.save();
CalendarEventData<Event> event = CalendarEventData<Event>(
date: _date,
event: Event(title: _title),
title: _title,
description: _description,
startTime: _startTime,
endTime: _endTime,
);
context.popRoute(event);
}
},
child: Text(
"Create",
style: Theme.of(context)
.textTheme
.subtitle1!
.copyWith(color: AppConstants.white),
),
style: ButtonStyle(
elevation: MaterialStateProperty.all<double>(8),
padding: MaterialStateProperty.all<EdgeInsets>(
EdgeInsets.symmetric(vertical: 10.0)),
),
),
],
),
),
);
}
}
147 changes: 147 additions & 0 deletions example/lib/date_time_selector.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import 'package:flutter/material.dart';
import 'package:flutter_calendar_page/flutter_calendar_page.dart';

import 'extension.dart';

typedef Validator = String? Function(String? value);

enum DateTimeSelectionType { date, time }

class DateTimeSelectorFormField extends StatefulWidget {
final Function(DateTime?)? onSelect;
final DateTimeSelectionType? type;
final FocusNode? focusNode;
final DateTime? minimumDateTime;
final Validator? validator;
final bool displayDefault;
final TextStyle? textStyle;
final void Function(DateTime date)? onSave;
final InputDecoration? decoration;

const DateTimeSelectorFormField({
this.onSelect,
this.type,
this.onSave,
this.decoration,
this.focusNode,
this.minimumDateTime,
this.validator,
this.displayDefault = false,
this.textStyle,
});

@override
_DateTimeSelectorFormFieldState createState() =>
_DateTimeSelectorFormFieldState();
}

class _DateTimeSelectorFormFieldState extends State<DateTimeSelectorFormField> {
late TextEditingController _textEditingController;
late FocusNode _focusNode;

late DateTime _selectedDate;

@override
void initState() {
super.initState();

_textEditingController = TextEditingController();
_focusNode = FocusNode();

_selectedDate = widget.minimumDateTime ?? DateTime.now();

if (widget.displayDefault && widget.minimumDateTime != null) {
if (widget.type == DateTimeSelectionType.date) {
_textEditingController.text = widget.minimumDateTime
?.dateToStringWithFormat(format: "dd/MM/yyyy") ??
"";
} else {
_textEditingController.text =
widget.minimumDateTime?.getTimeInFormat(TimeStampFormat.parse_12) ??
"";
}
}
}

@override
void dispose() {
_focusNode.dispose();
_textEditingController.dispose();
super.dispose();
}

Future<void> _showSelector() async {
DateTime? date;

if (widget.type == DateTimeSelectionType.date) {
date = await _showDateSelector();
_textEditingController.text =
(date ?? _selectedDate).dateToStringWithFormat(format: "dd/MM/yyyy");
} else {
date = await _showTimeSelector();
_textEditingController.text =
(date ?? _selectedDate).getTimeInFormat(TimeStampFormat.parse_12);
}

_selectedDate = date ?? DateTime.now();

if (mounted) {
setState(() {});
}

widget.onSelect?.call(date);
}

Future<DateTime?> _showDateSelector() async {
DateTime now = widget.minimumDateTime ?? DateTime.now();

DateTime? date = await showDatePicker(
context: context,
initialDate: now,
firstDate: widget.minimumDateTime ?? now,
lastDate: Constants.maxDate,
);

if (date == null) return null;

return date;
}

Future<DateTime?> _showTimeSelector() async {
DateTime now = widget.minimumDateTime ?? DateTime.now();
TimeOfDay? time = await showTimePicker(
context: context,
builder: (context, widget) {
return widget ?? Container();
},
initialTime: TimeOfDay(hour: now.hour, minute: now.minute),
);

if (time == null) return null;

DateTime? date = now.copyWith(
hour: time.hour,
minute: time.minute,
);

if (widget.minimumDateTime == null) return date;

return date;
}

@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _showSelector,
child: TextFormField(
style: widget.textStyle,
controller: _textEditingController,
validator: widget.validator,
minLines: 1,
onSaved: (value) => widget.onSave?.call(_selectedDate),
enabled: false,
decoration: widget.decoration,
),
);
}
}
Loading

0 comments on commit e8b78b0

Please sign in to comment.