how to link flutter with firebase? - firebase

I am a flutter programmer and I want to learn Firebase and link it to flutter, now I was able to create the following code that allows the user to add the number of units he wants, so that every time he enters the name of the unit and chooses its number, then it sends all the information to Firebase How do I complete this code so that the user can send the information he entered to Firebase?
My code
class _UnitesPageState extends State<UnitesPage> with TickerProviderStateMixin {
var _myWidgets = <Widget>[];
int _index = 0;
final unitesnumber = [
' unite 1 ',' unite 2 ',' unite 3 ',
];
bool autoValidate = true;
GlobalKey<FormBuilderState> _formKey = GlobalKey<FormBuilderState>();
final Map<int, String> namesvalues = Map();
final Map<int, String> unitesvalues = Map();
final List<TextEditingController> _namesControllers = [];
final List<TextEditingController> _unitesControllers = [];
void _add() {
int keyValue = _index;
_myWidgets = List.from(_myWidgets)
..add(Container(
child: Column(
children: <Widget>[
_names(keyValue),
_unites(keyValue),
],
),
));
setState(() => ++_index);
}
#override
Widget build(BuildContext context) {
final bottomNavigationBar = Container(
child: Row(
children: <Widget>[
FlatButton.icon(
label: const Text(' SEND',
)),
onPressed: () async {
setState(() {
autoValidate = !autoValidate;
});
for (var i = 0; i < _myWidgets.length; i++) {
Map<String, dynamic> data = {
"Widgets Number":_myWidgets.length,
"names": _namesControllers[i].text,
"unites":_unitesControllers[i].text,
};
}
}
),
],
),
);
return Scaffold(
// appBar
bottomNavigationBar: bottomNavigationBar,
body:Padding(
child: Form(
autovalidateMode: AutovalidateMode.disabled,
key: _formKey,
child: Stack(
children: <Widget>[
Column(
children: <Widget>[
_buildfaculte(),
Expanded(
child: SizedBox(
child: ListView(
addAutomaticKeepAlives: true,
children: _myWidgets,
),
),
),
],
)
],
),),
),
);
}
Widget _names(int keyValue) {
TextEditingController controller = TextEditingController();
_namesControllers.add(controller);
return FormBuilderTextField(
name: 'names',
controller: controller,
);
}
Widget _unites(int keyValue) {
TextEditingController controller = TextEditingController();
_unitesControllers.add(controller);
return Container(
alignment: Alignment.center,
child: Autocomplete<String>(
optionsBuilder: (TextEditingValue value) {
return unitesnumber.where((suggestion) =>
suggestion.toLowerCase().contains(value.text.toLowerCase()));
},
onSelected: (value) {
setState(() {
_selectedUnites = value;
});
},
),
);
}
}

Related

How can I get specific documents using conditions from flutter real-time database

This is the Realtime Firebase data
In this pic, you can see data and only I want to show available items documents from the database. But it shows all the documents.
I just want to show only available data. If you know how to do it to get once or using stream or any other solution so please help because I was stuck in it for 3 days.
Here is the body of the main page working
class OrderMenu extends StatefulWidget {
const OrderMenu({
Key? key,
required this.dbChild,
}) : super(key: key);
final String dbChild;
#override
_OrderMenuState createState() => _OrderMenuState();
}
class _OrderMenuState extends State<OrderMenu> {
DatabaseReference db = FirebaseDatabase.instance.reference();
User? curUser = FirebaseAuth.instance.currentUser;
int? len;
List<GetData>? data;
Map<String, dynamic>? proceed;
List<GetData>? AvailData;
late List<bool>? avail = List.generate(
len!,
(index) => false,
);
#override
Widget build(BuildContext context) {
return StreamBuilder<List<GetData>>(
stream: DataStreamPublisher(widget.dbChild).getMenuStream(),
builder: (context, snapshot) {
if (snapshot.hasData) {
data = snapshot.data;
len = data!.length;
return SafeArea(
child: SingleChildScrollView(
child: Container(
margin: EdgeInsets.symmetric(vertical: 10.0),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: double.infinity,
child: DataTable2(
showBottomBorder: true,
headingRowHeight: 40,
showCheckboxColumn: true,
sortAscending: true,
columnSpacing: 5,
dataRowHeight: 60,
dividerThickness: 2,
bottomMargin: 20.0,
checkboxHorizontalMargin: 5,
columns: [
DataColumn2(
size: ColumnSize.L,
label: Center(
child: Text(
"Item Name",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
DataColumn2(
size: ColumnSize.S,
label: Center(
child: Text(
"Price",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
DataColumn2(
size: ColumnSize.L,
label: Center(
child: Text(
"Quantity",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
],
rows: List<DataRow>.generate(
data!.length,
(index) => DataRow2(
selected: avail![index],
onSelectChanged: (bool? value) {
setState(() {
avail![index] = value!;
});
},
color: MaterialStateProperty.resolveWith<Color?>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return Theme.of(context)
.colorScheme
.primary
.withOpacity(0.08);
}
return null;
},
),
cells: [
DataCell(
Text(
data![index].Juice_Name,
),
),
DataCell(
Center(
child: Text(
data![index].Price,
),
),
),
DataCell(
IncDecButton(),
),
],
),
),
),
),
],
),
),
),
);
} else if (snapshot.hasError) {
return Center(
child: Text(
'Add Item in Menu.',
style: TextStyle(
fontSize: 18,
),
),
);
}
return Center(
child: const CircularProgressIndicator(),
);
},
);
}
}
**This is stream of GetDataPublisher**
class DataStreamPublisher {
final String dbChild;
DatabaseReference database = FirebaseDatabase.instance.reference();
User? curUser = FirebaseAuth.instance.currentUser;
DataStreamPublisher(this.dbChild);
Stream<List<GetData>> getDataStream() {
final dataStream = database.child(curUser!.uid).child(dbChild).onValue;
final streamToPublish = dataStream.map((event) {
final dataMap = Map<String, dynamic>.from(event.snapshot.value);
final dataList = dataMap.entries.map((e) {
return GetData.fromRTDB(Map<String, dynamic>.from(e.value));
}).toList();
return dataList;
});
return streamToPublish;
}
Stream<List<GetData>> getMenuStream() {
final dataStream = database.child(curUser!.uid).child(dbChild).onValue;
final streamToPublish = dataStream.map((event) {
final dataMap = Map<String, dynamic>.from(event.snapshot.value);
final dataList = dataMap.entries.map((e) {
**if (e.value["Available"] == true) {
print("Here I need a condition to get available data. OR any other possibility");
}**
return GetData.fromRTDB(Map<String, dynamic>.from(e.value));
}).toList();
return dataList;
});
return streamToPublish;
}
}
This is GetData class
class GetData {
String Juice_Name;
String Price;
bool Available;
var key;
GetData({
required this.Juice_Name,
required this.Available,
required this.Price,
required this.key,
});
factory GetData.fromRTDB(Map<String, dynamic> data) {
return GetData(
Juice_Name: data['Juice_Name'] ?? 'Enter Juice Name',
Price: data['Price'] ?? 'Enter Price',
Available: data['Available'] ?? false,
key: data['Key'] ?? 'key',
);
}
}
When you are using the following reference:
final dataStream = database.child(curUser!.uid).child(dbChild)
You will indeed get all the data under the "dbChild" node.
If you only need to get the objects that have the "Available" property set to true, then you should use a Query that look like this:
DatabaseReference db = FirebaseDatabase.instance.reference();
var query = db.child(curUser!.uid).child('Juices').orderByChild("Available").equalTo(true);

Data from database is not fetched/displayed in listview flutter

I have a screen which shows list of customers using listview. Next when I click on a customer I want to show the notes(records) only of that particular customer(customerId) in next screen in listview. This is my code which should work fine but its not displaying anything. I have checked if noteDetails table contains data and it has. Can anyone tell where am I wrong or what code should i add more please.
main.dart
import 'package:flutter/material.dart';
import 'package:vers2cts/screens/user_login.dart';
void main() {
runApp(MyApp());
}
Map<int, Color> color ={50:Color.fromRGBO(170, 0, 95, .1),
100:Color.fromRGBO(170, 0, 95, .2),
200:Color.fromRGBO(170, 0, 95, .3),
300:Color.fromRGBO(170, 0, 95, .4),
400:Color.fromRGBO(170, 0, 95, .5),
500:Color.fromRGBO(170, 0, 95, .6),
600:Color.fromRGBO(170, 0, 95, .7),
700:Color.fromRGBO(170, 0, 95, .8),
800:Color.fromRGBO(170, 0, 95, .9),
900:Color.fromRGBO(170,0,95, 1),};
MaterialColor colorCustom = MaterialColor(0xFF880E4F, color);
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'NoteKeeper',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch:colorCustom,
primaryColor:colorCustom//primarySwatch: Colors.purple
),
home: UserLogin(),
);
}
}
Note_info.dart //This is the file where i want to display the notes of particular customer.
import 'dart:io';
import 'package:customer/models/CustomerNote.dart';
import 'package:customer/models/addCustomer.dart';
import 'package:customer/services/db_service.dart';
import 'package:customer/utils/database_helper.dart';
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'New_Note.dart';
class Note_Info extends StatefulWidget{
final String appBarTitle;
final AddCustomer customer;
Note_Info(this. customer, this.appBarTitle);
#override
State<StatefulWidget> createState() {
return Note_InfoState(this. customer,this.appBarTitle);
}
}
class Note_InfoState extends State<Note_Info> {
DBService dbService = DBService();
List<CustomerNote> noteList;
int count = 0;
static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
CustomerNote note=CustomerNote();
String appBarTitle;
AddCustomer customer;
Note_InfoState(this.customer, this.appBarTitle);
DateTime _date = DateTime.now();
TextEditingController custNameController = TextEditingController();
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
int customerId=customer.custId;
if (noteList == null) {
noteList = List<CustomerNote>();
updateListView();
}
TextStyle titleStyle = Theme.of(context).textTheme.subhead;
var height = MediaQuery.of(context).size.height;
custNameController.text = customer.custName;
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: Icon(
Icons.add,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => NewNote(note)));
},
)
],
),
body: Container(
child: Column(
children: <Widget>[
TextField(controller: custNameController,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center),
Padding(
padding: const EdgeInsets.all(15.0),
child: Row(children: [
ImageProfile(customer.custPhoto),
Padding(
padding: const EdgeInsets.only(left: 30.0),
child: IconButton(
icon: Icon(
Icons.call,
color: Colors.green,
size: 45,
),
onPressed: () {
},
),
),
],),
),
SizedBox(
height: 50,
child: AppBar(
bottom: TabBar(
tabs: [
Tab(
text: "All",
),
Tab(
text: "Pending",
),
Tab(
text: "Cancelled",
),
Tab(
text: "Completed",
),
],
),
),
),
// create widgets for each tab bar here
Expanded(
child: TabBarView(
children: [
// first tab bar view widget
Container(
child: getNoteListView()
),
// second tab bar viiew widget
Container(
),
Container(
child: Center(
child: Text(
'Cancelled',
),
),
),
Container(
child: Center(
child: Text(
'Completed',
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 55.0,
width: 200,
child: RaisedButton(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
color: Theme
.of(context)
.primaryColorDark,
textColor: Colors.white,
child: Text('Save', textScaleFactor: 1.5,),
onPressed: () {
setState(() {
//_reset();
});
},
),
),
),
]
),
)
));
}
Widget ImageProfile(String fileName) {
return Center(
child: CircleAvatar(
radius: 80.0,
backgroundImage: fileName == null
?AssetImage('images/person_icon.jpg')
:FileImage(File(customer.custPhoto))),
);
}
ListView getNoteListView() {
TextStyle titleStyle = Theme.of(context).textTheme.subhead;
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
title: Text(this.noteList[position].note, style: titleStyle,),
trailing: GestureDetector(
child: Icon(Icons.delete, color: Colors.grey,),
onTap: () {
},
),
onTap: () {
},
),
);
},
);
}
void updateListView() {
final Future<Database> dbFuture = DB.init();
dbFuture.then((database) {
int cid=customer.custId;
Future<List<CustomerNote>> noteListFuture = dbService.getCustomerNotes(cid);
noteListFuture.then((noteList) {
setState(() {
this.noteList = noteList;
this.count = noteList.length;
});
});
});
}
}
New_Note.dart //This is where new note is added in database successfully
import 'package:customer/models/CustomerNote.dart';
import 'package:customer/models/addCustomer.dart';
import 'package:customer/screens/Note_info.dart';
import 'package:customer/services/db_service.dart';
import 'package:customer/utils/form_helper.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:smooth_star_rating/smooth_star_rating.dart';
import 'package:intl/intl.dart';
class NewNote extends StatefulWidget{
final CustomerNote note;
NewNote(this. note);
final Function(Color) onChanged;
final double height;
final double width;
NewNote({
Key key,
this.onChanged,
this.height = 25,
this.width = 150,
this.label,
}) : super(key: key);*/
#override
State<StatefulWidget> createState() {
return New_NoteState(this.note);
}
}
class New_NoteState extends State<NewNote> with SingleTickerProviderStateMixin{
New_NoteState(this.note);
CustomerNote note=new CustomerNote();
AddCustomer customer=new AddCustomer();
TextEditingController NoteController=TextEditingController();
TextEditingController custNameController = TextEditingController();
DateTime _reminderDate = DateTime.now();
DBService dbService=new DBService();
SpeedDial _speedDial(){
return SpeedDial(
animatedIcon: AnimatedIcons.add_event,
animatedIconTheme: IconThemeData(size: 24.0),
backgroundColor: Colors.yellow,
curve: Curves.easeInCirc,
children: [
SpeedDialChild(
child: Icon(Icons.location_on,color: Colors.yellow,),
label: 'Add Location',
),
SpeedDialChild(
child: Icon(Icons.keyboard_voice),
//backgroundColor: Colors.yellow,
label: 'Add voice',
//labelBackgroundColor: Colors.yellow
),
SpeedDialChild(
child: Icon(Icons.attachment_outlined,color :Colors.redAccent),
label: 'Add File',
),
SpeedDialChild(
child: Icon(Icons.image,color: Colors.lightBlue,),
label: 'Add Image',
),
],
);
}
//for DropDownMenu
Color value=Colors.red;
final List<Color> colors = [
Colors.red,
Colors.blue,
Colors.green,
Colors.yellow,
Colors.pink,
Colors.purple,
Colors.brown,
];
bool isSwitched = false;
var textValue = 'Switch is OFF';
void toggleSwitch(bool value) {
if(isSwitched == false)
{
setState(() {
isSwitched = true;
this.note.remindOn = _reminderDate.toString();
});
}
else
{
setState(() {
isSwitched = false;
});
}
}
#override
Widget build(BuildContext context) {
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
custNameController.text = customer.custName;
return WillPopScope(
onWillPop: () {
moveToLastScreen();
},
child: Scaffold(
appBar:AppBar(),
body:ListView(
children: <Widget>[
SizedBox(
height: 2.0,
),
TextField(controller: custNameController,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center),
Align(
alignment: Alignment.centerLeft,
child: Text("Add New",textAlign: TextAlign.left,
style: TextStyle(fontSize: 22,fontWeight: FontWeight.bold),),
),
SizedBox(
height: 2.0,
),
Divider(),
SizedBox(
height: 2.0,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: NoteController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: const BorderSide(width: 2.0),)),
keyboardType: TextInputType.multiline,
minLines: 5,
maxLines: 5,
onChanged: (value) {
this.note.note = value;
},
),
),
TableCalendar(
selectedDayPredicate: (day) {
return isSameDay(_reminderDate, day);
},
onDaySelected: (selectedDay, focusedDay) {
setState(() {
_reminderDate = selectedDay;
});
},
focusedDay: DateTime.now(),
firstDay: DateTime.utc(2010, 10, 16),
lastDay: DateTime.utc(2030, 3, 14),),
SizedBox(
height: height*0.03,
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(//mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text("Remind me",style: TextStyle(fontSize: 20),),
Padding(
padding: const EdgeInsets.only(left:80.0),
child: Container(
child: Switch(
onChanged: toggleSwitch,
value: isSwitched,
),
),
],),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(mainAxisAlignment: MainAxisAlignment.start,
children:<Widget>[
Text("Priority",style: TextStyle(fontSize: 20.0),),
Padding(
padding: const EdgeInsets.only(left:20.0),
child: Container(
child: SmoothStarRating(
size: height=50.0,
allowHalfRating: false,
onRated: (value) {
this.note.priority=value;
print("rating value -> $value");
},
),
),
)]),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text("Color",style: TextStyle(fontSize: 20),),
Padding(
padding: const EdgeInsets.only(left:80.0),
child: Container(
child: DropdownButton<Color>(
value: value,
onChanged: (color) {
setState(() => value = color);
},
items: colors.map((e) => DropdownMenuItem(
value: e,
child: Container(
width: 60.0,
color: e,
),
),
)
.toList(),
),
),
),
],),
),
SizedBox(
height: height*0.08,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 55.0,
width: 200,
child: RaisedButton(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
color: Theme.of(context).primaryColorDark,
textColor: Colors.white,
child: Text('Save',textScaleFactor: 1.5,),
onPressed: (){
setState(() {
_save();
});
},
),
),
),
],
),
floatingActionButton:_speedDial(),
));
}
void moveToLastScreen() {
Navigator.pop(context, true);
}
void _save() async {
moveToLastScreen();
note.custId=customer.custId;
note.date = DateFormat.yMMMd().format(DateTime.now());
int result;
if (note.id != null) { // Case 1: Update operation
result = await dbService.updateNote(note);
} else { // Case 2: Insert Operation
result = await dbService.insertNote(note);
}
if (result != 0) { // Success
FormHelper.showAlertDialog(context,'Status', 'Note Saved Successfully');
} else { // Failure
FormHelper.showAlertDialog(context,'Status', 'Problem Saving Note');
}
}
}
db_service.dart
Future<bool> insertCustomer(AddCustomer model) async {
await DB.init();
bool isSaved = false;
if (model != null) {
int inserted = await DB.insert(AddCustomer.table, model);
isSaved = inserted == 1 ? true : false;
}
return isSaved;
}
Future<List<Map<String, dynamic>>> getCustomerMapList() async {
await DB.init();
var result = await DB.query(AddCustomer.table);
return result;
}
Future<List<AddCustomer>> getCustomerList() async {
var CustomerMapList = await getCustomerMapList();
int count = CustomerMapList.length;
List<AddCustomer> customerList = List<AddCustomer>();
for (int i = 0; i < count; i++) {
customerList.add(AddCustomer.fromMap(CustomerMapList[i]));
}
return customerList;
}
Future<int> insertNote(CustomerNote note) async {
await DB.init();
var result = await DB.insert(CustomerNote.table, note);
return result;
}
Future<List<CustomerNote>> getCustomerNotes(int customer) async {
await DB.init();
var res = await DB.rawQuery("noteDetails WHERE custId = '$customer'");
int count = res.length;
List<CustomerNote> notelist = List<CustomerNote>();
for (int i = 0; i < count; i++) {
notelist.add(CustomerNote.fromMap(res[i]));
}
return notelist;
}
database_helper.dart
import 'dart:async';
import 'package:customer/models/model.dart';
import 'package:path/path.dart' as p;
import 'package:sqflite/sqflite.dart';
abstract class DB {
static Database _db;
static int get _version => 1;
static Future<Database> init() async {
if (_db != null) {
return _db;
}
try {
var databasesPath = await getDatabasesPath();
String _path = p.join(databasesPath, 'Customer.db');
_db = await openDatabase(_path, version: _version, onCreate: onCreate);
print('db location:'+_path);
} catch (ex) {
print(ex);
}
}
static void onCreate(Database db, int version) async {
await db.execute(
'CREATE TABLE userDetails (id INTEGER PRIMARY KEY AUTOINCREMENT, '
'firstName STRING, '
'lastName STRING, mobileNum STRING, emailId STRING, address String,'
'userType STRING,password STRING)');
await db.execute(
'CREATE TABLE customerDetails (custId INTEGER PRIMARY KEY AUTOINCREMENT, '
'custName STRING, '
'mobileNum STRING, company STRING, custPhoto STRING, showOnCall bool,'
'remindOn STRING,location STRING)');
await db.execute(
'CREATE TABLE noteDetails (noteId INTEGER PRIMARY KEY AUTOINCREMENT, '
'custId STRING, '
'custName STRING, date STRING, note STRING, remindOn STRING,'
'priority STRING,status STRING,attachment STRING)');
await db.execute(
'CREATE TABLE languagesKnown(custId INTEGER REFERENCES customerDetails(custId),'
' languages STRING,PRIMARY KEY(custId))');
}
static Future<List<Map<String, dynamic>>> query(String table) async =>
_db.query(table);
static Future<int> insert(String table, Model model) async =>
await _db.insert(table, model.toMap());
static Future<int> update(String table, Model model) async => await _db
.update(table, model.toMap(), where: 'id = ?', whereArgs: [model.id]);
static Future<int> delete(String table, Model model) async =>
await _db.delete(table, where: 'id = ?', whereArgs: [model.id]);
static Future<int> deleteCustomer(String table, Model model) async =>
await _db.delete(table, where: 'custId = ?', whereArgs: [model.custId]);
static Future<Batch> batch() async => _db.batch();
static Future<List<Map<String, dynamic>>> rawQuery(String table) async =>
_db.query(table);
}
people_list.dart // This is where list of customers is displayed and by clicking on a listtile i.e customer, Note_info opens
import 'package:customer/models/addCustomer.dart';
import 'package:customer/screens/Note_info.dart';
import 'package:customer/screens/User_Settings.dart';
import 'package:customer/screens/add_person.dart';
import 'package:customer/services/db_service.dart';
import 'package:customer/utils/database_helper.dart';
import 'package:customer/utils/form_helper.dart';
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:sqflite/sqflite.dart';
class People_List extends StatefulWidget{
#override
State<StatefulWidget> createState() {
return People_ListState();
}
}
class People_ListState extends State<People_List> with SingleTickerProviderStateMixin{
DBService dbService = DBService();
List<AddCustomer> customerList;
int count = 0;
static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
var _isSelectedItemIndex;
#override
void initState() {
super.initState();
_searchQuery = new TextEditingController();
}
Widget _buildTitle(BuildContext context) {
var horizontalTitleAlignment =
Platform.isIOS ? CrossAxisAlignment.center : CrossAxisAlignment.start;
return new InkWell(
onTap: () => scaffoldKey.currentState.openDrawer(),
child: new Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: horizontalTitleAlignment,
children: <Widget>[
const Text(''),
],
),
),
);
}
#override
Widget build(BuildContext context) {
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
if (customerList == null) {
customerList = List<AddCustomer>();
updateListView();
}
return Scaffold(
appBar: new AppBar(
),
body:getCustomerListView(),
floatingActionButton: FloatingActionButton(
onPressed: () {
navigateToCustomer(AddCustomer(), 'Add Person');
},
child: const Icon(Icons.add),
),
}
ListView getCustomerListView() {
TextStyle titleStyle = Theme.of(context).textTheme.subhead;
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int position) {
var _imageFile=customerList[position].custPhoto;
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
leading: CircleAvatar(
backgroundImage: _imageFile==null?AssetImage('images/person_icon.jpg')
:FileImage(File(_imageFile.toString()))),
title: Text(this.customerList[position].custName, style: titleStyle,),
trailing: Icon(Icons.keyboard_arrow_right),
onTap: () {
navigateToDetail(this.customerList[position],'Edit ');
},
),
);
},
);
}
void navigateToDetail(AddCustomer customer, String title) async {
bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) {
return Note_Info(customer, title);
}));
if (result == true) {
updateListView();
}
}
void updateListView() {
final Future<Database> dbFuture = DB.init();
dbFuture.then((database) {
Future<List<AddCustomer>> customerListFuture = dbService.getCustomerList();
customerListFuture.then((customerList) {
setState(() {
this.customerList = customerList;
this.count = customerList.length;
});
});
});
}
}
Finally I myself had to solve the problem. The problem was that where I was creating note and saving it in "note" table cust_id was not saved in the table. So I passed CustomerModel object and NoteModel object to New_Note(). Now its working fine
new_note.dart
class NewNote extends StatefulWidget{
final NoteModel note;
final CustomerModel customer;
NewNote(this.customer,this. note);
#override
State<StatefulWidget> createState() {
//return New_NoteState(this.customer);
return New_NoteState(this.customer,this.note);
}
class New_NoteState extends State<NewNote> with SingleTickerProviderStateMixin{
New_NoteState(this.customer,this.note);
NoteModel note=new NoteModel();
CustomerModel customer=new CustomerModel();
}
void _save() async {
note.cust_id=customer.cust_id;
...
}

How can I add 3 widgets in one?

I am trying to show 3 widgets with 3 different on tap functions, but it is not working.
So what I want is the whole widget split in 3 different widgets so I can call widget 1 widget 2 or widget 3. But this is not working and I don't know why exactly.
I have this videos collection where users videos are uploaded with 3 hashtags and what I want is that the user can search for one hashtag no matter which one, but it always shows all 3 hashtags instead of the one which the user searched for. And that is what I mean with 3 different widgets.
Here is my code:
class Openalldocs extends StatefulWidget {
final TextEditingController searchinginput;
static const route = '/openalldocs';
const Openalldocs({Key key, this.searchinginput}) : super(key: key);
#override
_OpenalldocsState createState() => _OpenalldocsState();
}
class _OpenalldocsState extends State<Openalldocs> {
List _allResults = [];
List _resultsList = [];
Future resultsLoaded;
bool nosuerfound = false;
String searchresult;
#override
void initState() {
super.initState();
widget.searchinginput.addListener(_onsearchChanged);
setState(() {
nosuerfound = true;
});
}
#override
void dispose() {
widget.searchinginput.removeListener(_onsearchChanged());
super.dispose();
}
#override
void didChangeDependencies() {
widget.searchinginput.text;
resultsLoaded = getusers();
super.didChangeDependencies();
}
_onsearchChanged() {
setState(() {
nosuerfound = false;
});
searchResults();
}
searchResults() {
var showResults = [];
if (widget.searchinginput.text != "") {
for (var tripsnapshot in _allResults) {
var title = DatbaseService.instance
.videosfromsnapshot(tripsnapshot)
.hashtag1
.toLowerCase();
print(title);
var title2 = DatbaseService.instance
.videosfromsnapshot(tripsnapshot)
.hashtag3
.toLowerCase();
print(title);
var title3 = DatbaseService.instance
.videosfromsnapshot(tripsnapshot)
.hashtag2
.toLowerCase();
print(title);
if (title.contains(widget.searchinginput.text.toLowerCase()) ||
title2.contains(widget.searchinginput.text.toLowerCase()) ||
title3.contains(widget.searchinginput.text.toLowerCase())) {
setState(() {
nosuerfound = true;
});
showResults.add(tripsnapshot);
}
}
} else {
setState(() {
nosuerfound = true;
});
showResults = List.from(_allResults);
}
setState(() {
_resultsList = showResults;
});
}
getusers() async {
var firestore = FirebaseFirestore.instance;
QuerySnapshot qn = await firestore.collection('videos').get();
if (!mounted) return;
setState(() {
_allResults = qn.docs;
});
searchResults();
return "Complete";
}
#override
Widget build(BuildContext context) {
final user = Provider.of<Userforid>(context);
if (nosuerfound == true) {
return ListView.builder(
itemCount: _resultsList.length,
itemBuilder: (BuildContext context, int index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
onTap: () {
},
child: Column(
children: <Widget>[
Column(
children: [
HighlightedMatchesText(
searchString: widget.searchinginput.text,
content: _resultsList[index].data()['hashtag1'],
),
],
),
SizedBox(height: 3),
],
),
),
SizedBox(height: 6),
InkWell(
onTap: () {
},
child: Column(
children: <Widget>[
Column(
children: [
HighlightedMatchesText(
searchString: widget.searchinginput.text,
content: _resultsList[index].data()['hashtag2'],
),
],
),
],
),
),
SizedBox(height: 6),
InkWell(
onTap: () {
},
child: Column(
children: <Widget>[
Column(
children: [
HighlightedMatchesText(
searchString: widget.searchinginput.text,
content: _resultsList[index].data()['hashtag3'],
),
],
),
SizedBox(height: 3),
],
),
),
SizedBox(height: 6),
]);
},
);
} else {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 30, 0, 0),
child: Center(
child: Container(
child: Text(
"No Hashtag found",
style: TextStyle(fontSize: 16),
)),
),
);
}
}
}
Your onTap handlers are empty, so nothing will happen actually when tapping.
To achieve what you are trying to, it is better to instead of creating widgets one by one in the Column children, create a for loop, and make the onTap and everything relative to it.
Here is how to achieve it (I took only a subsection of the code, the Column part):
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// the AMOUNT is how many hashtags you want to show
for (var i = 0; i < AMOUNT; i += 1) ...[
// the SizedBox will only exist between the elements in the list
// as before
if (i != 0) SizedBox(height: 6),
// create a builder to allow declaring a variable
Builder(
builder: (context) {
// declare the hashtag variable
final hashtag = 'hashtag$i';
return InkWell(
onTap: () {
// do something with the hashtag stored in the variable
// this will make it relative to the element in the list
},
child: Column(
children: <Widget>[
// why is there a Column inside another with only one child?
// I would recommend to remove it
Column(
children: [
HighlightedMatchesText(
searchString: widget.searchinginput.text,
// notice how I am using the hashtag variable here
// instead of a constant? ('hashtag1'), by the way
// the for loop will make the hashtag start at 0
// you can change it by increment in the declaration
// `final hashtag = 'hashtag${i+1}'`, if you want
// the existing behavior
content: _resultsList[index].data()[hashtag],
),
],
),
// what is this? if it is to add more space between the items
// in the list, I recommend removing it from here, and add it
// to the first `SizedBox` in the for loop
// in case you do that, the Column that this widget belong
// would also only now contain one widget, so, there is no
// need to have it
SizedBox(height: 3),
],
),
),
},
);
],
],
);
I added a lot of comments, I hope they help you to achieve what you are trying to.

removing previous value and adding new in firestore list flutter

Here in firestore I want to update list with new values entered by the user and to remove all previous values. Suppose user add 2 new values [American English, French]. What I want is to remove all the values in the list and update the list with these values. I have used set and update method and it is just adding new values in newer index but not removing previous.
here is my code.
addCategoriesAndSkillsInDB({List categories, List skills}) async {
print('$skills');
categories == null
? _firestore
.collection('users')
.doc(getCurrentUser().uid)
.set({'skills': skills})
: _firestore
.collection('users')
.doc(getCurrentUser().uid)
.update({'categories': FieldValue.arrayUnion(categories)});
}
and that is how I am retaining new values in the list
import 'file:///E:/flutterProject/filmmaker/lib/auth_screens/signUp_screens/worker/signUp_screen5.dart';
import 'package:filmmaker/auth_screens/signUp_screens/worker/signUp_screen14.dart';
import 'package:filmmaker/logic/bloc/fields/fields_bloc.dart';
import 'package:filmmaker/resources/repo/firebase_repo.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class SignUpScreen4 extends StatefulWidget {
bool edit = false;
SignUpScreen4([this.edit]);
#override
_SignUpScreen4State createState() => _SignUpScreen4State();
}
class _SignUpScreen4State extends State<SignUpScreen4> {
List<String> _dynamicChips = [];
String _value;
final key = GlobalKey<FormState>();
final controller = TextEditingController();
#override
void dispose() {
// TODO: implement dispose
super.dispose();
controller.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Sign Up Screen 4'),
Form(
key: key,
child: TextFormField(
controller: controller,
validator: (value) =>
value.trim().isEmpty || value == null ? 'Empty Text' : null,
autofocus: true,
autocorrect: true,
enableSuggestions: true,
decoration: InputDecoration(
hintText:
'Type things like: Final Cut Pro, or Documentary making',
hintStyle: TextStyle(fontStyle: FontStyle.italic),
labelText: 'Tell us about some of your skills',
),
),
),
MaterialButton(
onPressed: () {
if (key.currentState.validate()) {
if (!_dynamicChips.contains(controller?.text)) {
setState(() {
_value = controller?.text;
});
_dynamicChips.add(_value);
controller.text = '';
}
}
},
child: Text("Add"),
),
dynamicChips(),
BlocConsumer<FieldsBloc, FieldsState>(builder: (context, state) {
if (state is FieldsInitial) {
return Container();
} else if (state is FieldSuccessfulState) {
return Container();
} else if (state is FieldUnsuccessfulState) {
return Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.error,
color: Colors.red,
),
SizedBox(
width: 5.0,
),
Text(
state.message,
style: TextStyle(color: Colors.red),
),
],
));
}
return Container();
}, listener: (context, state) {
if (state is FieldSuccessfulState)
widget.edit
? Navigator.of(context).push(
MaterialPageRoute(builder: (_) => SignUpScreen14()))
: Navigator.of(context).push(
MaterialPageRoute(builder: (_) => SignUpScreen5()));
}),
ElevatedButton(
onPressed: () {
BlocProvider.of<FieldsBloc>(context)
.add(NextButtonEventScreen4(_dynamicChips));
},
child: Text('Next'))
],
),
),
);
}
dynamicChips() {
return Wrap(
spacing: 6.0,
runSpacing: 6.0,
children: List<Widget>.generate(
_dynamicChips?.length,
(int index) => Chip(
label: Text(_dynamicChips[index]),
onDeleted: () {
setState(() {
_dynamicChips.removeAt(index);
});
},
)),
);
}
}
You need to pass List instead of String. For example
List<String> languages = ['English', 'Nepali', 'hindi'];
and then,
_firestore
.collection('users')
.doc(getCurrentUser().uid)
.update({'other languages': languages});

How to show Current Date Time when the button clicked in SQLlite Flutter?

This is My App
I want to add a new column contain the current date when add new name, this is my code any help?
this class to add the name
class Employee {
int id;
String name;
Employee(this.id, this.name);
Map<String, dynamic> toMap() {
var map = <String, dynamic>{
'id': id,
'name': name,
};
return map;
}
Employee.fromMap(Map<String, dynamic> map) {
id = map['id'];
name = map['name'];
}
}
and here is the database i use to store the name and show the delete button how can i add a new column here contain the current date time when adding new name?
strong text
Future<List<Employee>> employees;
TextEditingController controller = TextEditingController();
String name;
int curUserId;
final formKey = new GlobalKey<FormState>();
var dbHelper;
bool isUpdating;
#override
void initState() {
super.initState();
dbHelper = DBHelper();
isUpdating = false;
refreshList();
}
refreshList() {
setState(() {
employees = dbHelper.getEmployees();
});
}
clearName() {
controller.text = '';
}
validate() {
if (formKey.currentState.validate()) {
formKey.currentState.save();
if (isUpdating) {
Employee e = Employee(curUserId, name);
dbHelper.update(e);
setState(() {
isUpdating = false;
});
} else {
Employee e = Employee(null, name);
dbHelper.save(e);
}
clearName();
refreshList();
}
}
form() {
return Form(
key: formKey,
child: Padding(
padding: EdgeInsets.all(15.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
verticalDirection: VerticalDirection.down,
children: <Widget>[
TextFormField(
controller: controller,
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: 'Name'),
validator: (val) => val.length == 0 ? 'Enter Name' : null,
onSaved: (val) => name = val,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FlatButton(
onPressed: validate,
child: Text(isUpdating ? 'UPDATE' : 'ADD'),
),
FlatButton(
onPressed: () {
setState(() {
isUpdating = false;
});
clearName();
},
child: Text('CANCEL'),
)
],
),
],
),
),
);
}
SingleChildScrollView dataTable(List<Employee> employees) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: DataTable(
columns: [
DataColumn(
label: Text('NAME'),
),
DataColumn(
label: Text('DELETE'),
),
// DataColumn(label: Text("")'null')
],
rows: employees
.map(
(employee) => DataRow(cells: [
DataCell(
Text(employee.name),
onTap: () {
setState(() {
isUpdating = true;
curUserId = employee.id;
});
controller.text = employee.name;
},
),
DataCell(IconButton(
icon: Icon(Icons.delete),
onPressed: () {
dbHelper.delete(employee.id);
refreshList();
},
)),
]),
)
.toList(),
),
);
}
list() {
return Expanded(
child: FutureBuilder(
future: employees,
builder: (context, snapshot) {
if (snapshot.hasData) {
return dataTable(snapshot.data);
}
if (null == snapshot.data || snapshot.data.length == 0) {
return Text("No Data Found");
}
return CircularProgressIndicator();
},
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Stay_Safe'),
centerTitle: true
),
body: new Container(
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
verticalDirection: VerticalDirection.down,
children: <Widget>[
form(),
list(),
],
),
),
);
}
}
Add DateTime to Employee model:
class Employee {
int id;
String name;
DateTime dateTime;
Employee(this.id, this.name, this.dateTime);
Map<String, dynamic> toMap() {
final Map<String, dynamic> map = new Map<String, dynamic>();
map['id'] = this.id;
map['name'] = this.name;
map['dateTime'] = dateTime != null ? this.dateTime.toIso8601String() : '';
return map;
}
Employee.fromMap(Map<String, dynamic> map) {
id = map['id'];
name = map['name'];
dateTime = map['dateTime'] != null? DateTime.parse(map['dateTime']): null;
}
}
DateTime.now() returns current DateTime of user.We will pass this whenever user is updating or adding new data.We will create another data column and cell for showing time.The datetime needs to be converted to presentable string so we will use our custom function getFormattedDate and lastly show it in Text widget.
Future<List<Employee>> employees;
TextEditingController controller = TextEditingController();
String name;
int curUserId;
final formKey = new GlobalKey<FormState>();
var dbHelper;
bool isUpdating;
#override
void initState() {
super.initState();
dbHelper = DBHelper();
isUpdating = false;
refreshList();
}
refreshList() {
setState(() {
employees = dbHelper.getEmployees();
});
}
clearName() {
controller.text = '';
}
validate() {
if (formKey.currentState.validate()) {
formKey.currentState.save();
if (isUpdating) {
Employee e = Employee(curUserId, name,DateTime.now());
dbHelper.update(e);
setState(() {
isUpdating = false;
});
} else {
Employee e = Employee(null, name,DateTime.now());
dbHelper.save(e);
}
clearName();
refreshList();
}
}
form() {
return Form(
key: formKey,
child: Padding(
padding: EdgeInsets.all(15.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
verticalDirection: VerticalDirection.down,
children: <Widget>[
TextFormField(
controller: controller,
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: 'Name'),
validator: (val) => val.length == 0 ? 'Enter Name' : null,
onSaved: (val) => name = val,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FlatButton(
onPressed: validate,
child: Text(isUpdating ? 'UPDATE' : 'ADD'),
),
FlatButton(
onPressed: () {
setState(() {
isUpdating = false;
});
clearName();
},
child: Text('CANCEL'),
)
],
),
],
),
),
);
}
SingleChildScrollView dataTable(List<Employee> employees) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: DataTable(
columns: [
DataColumn(
label: Text('NAME'),
),
DataColumn(
label: Text('DELETE'),
),
DataColumn(
label: Text('DATE'),
),
// DataColumn(label: Text("")'null')
],
rows: employees
.map(
(employee) => DataRow(cells: [
DataCell(
Text(employee.name),
onTap: () {
setState(() {
isUpdating = true;
curUserId = employee.id;
});
controller.text = employee.name;
},
),
DataCell(IconButton(
icon: Icon(Icons.delete),
onPressed: () {
dbHelper.delete(employee.id);
refreshList();
},
)),
DataCell(
Text(((DateTime date) =>
"${date.hour % 12}:${date.minute} ${date.hour > 12
? 'PM'
: 'AM'}")(
employee.dateTime) + ' ${getFormattedDate(employee.dateTime.toIso8601String())}'),
onTap: () {
//Any action
},
),
]),
)
.toList(),
),
);
}
list() {
return Expanded(
child: FutureBuilder(
future: employees,
builder: (context, snapshot) {
if (snapshot.hasData) {
return dataTable(snapshot.data);
}
if (null == snapshot.data || snapshot.data.length == 0) {
return Text("No Data Found");
}
return CircularProgressIndicator();
},
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Stay_Safe'),
centerTitle: true
),
body: new Container(
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
verticalDirection: VerticalDirection.down,
children: <Widget>[
form(),
list(),
],
),
),
);
}
String getFormattedDate(String date) {
var d = DateTime.parse(date);
return [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
][d.month - 1] +
" " + d.day.toString() +
"," +
d.year.toString();
}

Resources