Flutter How to populate data from sqflite to dropdown list - flutter

I have seen the questions in stackoverflow which are quite similar to my question, but those question and answer dint work for me. So here is my question how to populate data from sqflite to dropdown list. Below are the dart files which I have written.Please help me with the question
dbhelper.dart
import 'package:abc/model/manage_categories.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:async';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class DatabaseHelper {
static DatabaseHelper _databaseHelper; // Singleton DatabaseHelper
static Database _database; // Singleton Database
String categoriesTable = 'categories_table';
String colId = 'id';
String colTitle = 'title';
String colDate = 'date';
DatabaseHelper._createInstance(); // Named constructor to create instance of DatabaseHelper
factory DatabaseHelper() {
if (_databaseHelper == null) {
_databaseHelper = DatabaseHelper._createInstance(); // This is executed only once, singleton object
}
return _databaseHelper;
}
Future<Database> get database async {
if (_database == null) {
_database = await initializeDatabase();
}
return _database;
}
Future<Database> initializeDatabase() async {
// Get the directory path for both Android and iOS to categories database.
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'categoriess.db';
// Open/create the database at a given path
var categoriessDatabase = await openDatabase(path, version: 1, onCreate: _createDb);
return categoriessDatabase;
}
void _createDb(Database db, int newVersion) async {
await db.execute('CREATE TABLE $categoriesTable($colId INTEGER PRIMARY KEY AUTOINCREMENT, $colTitle TEXT, '
'$colDate TEXT)');
}
// Fetch Operation: Get all categories objects from database
Future<List<Map<String, dynamic>>> getCategoriesMapList() async {
Database db = await this.database;
// var result = await db.rawQuery('SELECT * FROM $categoriesTable order by $colTitle ASC');
var result = await db.query(categoriesTable, orderBy: '$colTitle ASC');
return result;
}
// Insert Operation: Insert a categories object to database
Future<int> insertCategories(Categories categories) async {
Database db = await this.database;
var result = await db.insert(categoriesTable, categories.toMap());
return result;
}
// Update Operation: Update a categories object and save it to database
Future<int> updateCategories(Categories categories) async {
var db = await this.database;
var result = await db.update(categoriesTable, categories.toMap(), where: '$colId = ?', whereArgs: [categories.id]);
return result;
}
Future<int> updateCategoriesCompleted(Categories categories) async {
var db = await this.database;
var result = await db.update(categoriesTable, categories.toMap(), where: '$colId = ?', whereArgs: [categories.id]);
return result;
}
// Delete Operation: Delete a categories object from database
Future<int> deleteCategories(int id) async {
var db = await this.database;
int result = await db.rawDelete('DELETE FROM $categoriesTable WHERE $colId = $id');
return result;
}
// Get number of categories objects in database
Future<int> getCount() async {
Database db = await this.database;
List<Map<String, dynamic>> x = await db.rawQuery('SELECT COUNT (*) from $categoriesTable');
int result = Sqflite.firstIntValue(x);
return result;
}
// Get the 'Map List' [ List<Map> ] and convert it to 'categories List' [ List<Categories> ]
Future<List<Categories>> getCategoriesList() async {
var categoriesMapList = await getCategoriesMapList(); // Get 'Map List' from database
int count = categoriesMapList.length; // Count the number of map entries in db table
List<Categories> categoriesList = List<Categories>();
// For loop to create a 'categories List' from a 'Map List'
for (int i = 0; i < count; i++) {
categoriesList.add(Categories.fromMapObject(categoriesMapList[i]));
}
return categoriesList;
}
}
Add_store_item.dart
import 'package:flutter/material.dart';
import 'package:abc/database/dbhelper_categories.dart';
import 'package:abc/database/dbhelper_manage_inventory.dart';
import 'package:abc/model/Manageinventory_class.dart';
import 'package:abc/model/manage_categories.dart';
class AddStoreItem extends StatefulWidget {
final Inventory inventory;
AddStoreItem(this.inventory);
#override
State<StatefulWidget> createState() => new AddStoreItemState();
}
class AddStoreItemState extends State<AddStoreItem> {
DatabaseHelper databaseHelper = DatabaseHelper();
List<Categories> categoriesList = <Categories>[];
int count = 0;
DBProvider _db = DBProvider();
TextEditingController _itemController;
TextEditingController _quantityController;
TextEditingController _categoryController;
TextEditingController _unitController;
TextEditingController _locationController;
#override
void initState() {
super.initState();
_loadCategorieslist();
_itemController = new TextEditingController(text: widget.inventory.item);
_quantityController = new TextEditingController(text: widget.inventory.quantity);
_categoryController = new TextEditingController(text: widget.inventory.category);
_unitController = new TextEditingController(text: widget.inventory.unit);
_locationController = new TextEditingController(text: widget.inventory.location);
}
_loadCategorieslist()async{
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add Inventory')
),
body: SingleChildScrollView(
child: Container(
margin: EdgeInsets.all(15.0),
alignment: Alignment.center,
child: Column(
children: <Widget>[
SizedBox(height: 10),
TextField(
controller: _itemController,
decoration: InputDecoration(labelText: 'Item'),
),
SizedBox(height: 10),
TextField(
controller: _quantityController,
decoration: InputDecoration(labelText: 'Quantity'),
),
SizedBox(height: 10),
DropdownButton<String>(
value: categoriesList,
items: categoriesList.map((String){
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}),
isExpanded: true,
onChanged: (value) {
print("value: $value");
},
hint: Text(
"Units",
style: TextStyle(
// color: Colors.black,
),
),
),
DropdownButton<String>(
items: [
DropdownMenuItem<String>(
value: "1",
child: Text(
"First",
),
),
DropdownMenuItem<String>(
value: "2",
child: Text(
"Second",
),
),
],
isExpanded: true,
onChanged: (value) {
print("value: $value");
},
hint: Text(
"Location",
style: TextStyle(
// color: Colors.black,
),
),
),
SizedBox(height: 10),
RaisedButton(
child: (widget.inventory.id != null) ? Text('Update') : Text('Add Inventory'),
onPressed: () {
_addInventory();
},
),
],
),
),
),
);
}
void _addInventory() {
if (widget.inventory.id != null) {
_db
.updateNote(Inventory.withId(
widget.inventory.id,
_itemController.text,
_quantityController.text,
_categoryController.text,
_unitController.text,
_locationController.text,
))
.then((_) => Navigator.pop(context, 'update'));
} else {
_db
.saveNote(Inventory(
_itemController.text,
_quantityController.text,
_categoryController.text,
_unitController.text,
_locationController.text,
))
.then((_) => Navigator.pop(context, 'save'));
}
}
}

This how I managed to populate the list of data from sqflite to drop down
Declared list from sqflite to AddStoreItemState as below
DatabaseHelper databaseHelper = DatabaseHelper();
List<Categories> categoriesList ;
Categories _category;
Now wrap the drop down button as below
Center(
child: DropdownButtonFormField<Categories>(
hint: Text('Categories'),
value: _category,
onChanged: (Categories value){
setState(() {
_category = value;
});
},
items: categoriesList.map((user) => DropdownMenuItem<Categories>(
child: Text(user.cname),
value: user,
)
).toList(),
),
),

In AddStoreItemState change your _loadCategorieslist()async method to:
Future<List<Categories>> _loadCategorieslist() async => databaseHelper.getCategoriesMapList();
And wrap your DropdownButton with a FutureBuilder

This is how I read data from SqfLite to use it in a drop-down or data table, in this case barcode records.
Here is the model, which includes a fromJson() function like below:
class Barcode {
String code;
String itemNo;
Barcode({
this.code,
this.itemNo,
});
Map<String, dynamic> toMap() => {
'code': code,
'itemNo': itemNo,
};
factory Barcode.fromJson(Map<String, dynamic> parsedJson) {
return Barcode(
code: parsedJson['code'],
itemNo: parsedJson['itemNo'],
);
}
}
Here is how I read barcodes (all) from SqfLite:
static Future<List<Barcode>> getAll() async {
final db = await DbUtil.database;
var response = await db.query(tableName);
List<Barcode> list = response.map((c) => Barcode.fromJson(c)).toList();
return list;
}
Here is for reading just one barcode:
static Future<Barcode> get(String barcode) async {
final db = await DbUtil.database;
var response = await db.query(tableName, where: "$pkName = ?", whereArgs: ['$barcode']);
return response.isNotEmpty ? Barcode.fromJson(response.first) : null;
}
Then to call it:
var barcode = await BarcodeDb.get(scanText);
Try this out, it should work for you.

Related

How to retrieve particular data from id on flutter

How to retrieve particular data from id on flutter and want to show data inside list view. I have created view, insert, delete and update operations.i used sqflite
my code is below.
main.dart file
class _SqliteAppState extends State<SqliteApp> {
int? selectedId;
final textController = TextEditingController();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: TextField(
controller: textController,
),
),
body: Center(
child: FutureBuilder<List<Grocery>>(
future: DatabaseHelper.instance.getGroceries(),
builder: (BuildContext context,
AsyncSnapshot<List<Grocery>> snapshot) {
if (!snapshot.hasData) {
return Center(child: Text('Loading...'));
}
return snapshot.data!.isEmpty
? Center(child: Text('No Groceries in List.'))
: ListView(
children: snapshot.data!.map((grocery) {
return Center(
child: Card(
color: selectedId == grocery.id
? Colors.white70
: Colors.white,
child: ListTile(
title: Text(grocery.name),
onTap: () {
setState(() {
if (selectedId == null) {
textController.text = grocery.name;
selectedId = grocery.id;
} else {
textController.text = '';
selectedId = null;
}
});
},
onLongPress: () {
setState(() {
DatabaseHelper.instance.remove(grocery.id!);
});
},
),
),
);
}).toList(),
);
}),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.save),
onPressed: () async {
selectedId != null
? await DatabaseHelper.instance.update(
Grocery(id: selectedId, name: textController.text),
)
: await DatabaseHelper.instance.add(
Grocery(name: textController.text),
);
setState(() {
textController.clear();
selectedId = null;
});
},
),
),
);
}
The model class code is below
Grocery({this.id, required this.name});
factory Grocery.fromMap(Map<String, dynamic> json) => new Grocery(
id: json['id'],
name: json['name'],
);
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
}; } }
This is my db_helper class code. I have created view, insert, delete and update operations.
class DatabaseHelper {
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database? _database;
Future<Database> get database async => _database ??= await _initDatabase();
Future<Database> _initDatabase() async {
Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, 'groceries.db');
return await openDatabase(
path,
version: 1,
onCreate: _onCreate,
);
}
Future _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE groceries(
id INTEGER PRIMARY KEY,
name TEXT
)
''');
}
Future<List<Grocery>> getGroceries() async {
Database db = await instance.database;
var groceries = await db.query('groceries', orderBy: 'name');
List<Grocery> groceryList = groceries.isNotEmpty
? groceries.map((c) => Grocery.fromMap(c)).toList()
: [];
return groceryList;
}
Future<int> add(Grocery grocery) async {
Database db = await instance.database;
return await db.insert('groceries', grocery.toMap());
}
Future<int> remove(int id) async {
Database db = await instance.database;
return await db.delete('groceries', where: 'id = ?', whereArgs: [id]);
}
Future<int> update(Grocery grocery) async {
Database db = await instance.database;
return await db.update('groceries', grocery.toMap(),
where: "id = ?", whereArgs: [grocery.id]);
}
}
You can use this function to get the data by id:
Future<List<Grocery>> getGrocerieById(int id) async {
Database db = await instance.database;
var groceries =
await db.query('groceries', where: 'id = ?', whereArgs: [id]);
List<Grocery> groceryList = groceries.isNotEmpty
? groceries.map((c) => Grocery.fromMap(c)).toList()
: [];
return groceryList;
}

How to make DropdownButtonFormField data from sqflite?

class SQLHelper
Future<List<Map<String, dynamic>>> selectAllServer() async {
final db = await init();
return db.query('server', orderBy: "ip");
}
class ModalDialog
List<Map<String, dynamic>> _server = [];
void getDataDB() async {
final data = await db.selectAllServer();
setState(() {
_server = data;
});
}
DropdownButtonFormField(
onChanged: (val) {},
items: _server.map((ip) {
return DropdownMenuItem(
value: ip['ip'],
child: Text(ip['ket']),
);
}).toList(),
)
Why Value and Child DropdownMenuItem now show?
I want to make Dropdown, value and title get from sqflite.

How to get data from model class with using SQFlite in Flutter?

Here I use SqFlite functionality with model class for data store. But problem is that, when I click on button, addData method was called null.
This is my model class.
import 'dart:convert';
DatabaseModel fromJson({String str}) {
final jsonData = json.decode(str);
return DatabaseModel.fromMap(jsonData);
}
String toJson(DatabaseModel databaseModel) {
final dyn = databaseModel.toMap();
return json.encode(dyn);
}
class DatabaseModel {
String id;
String imageUrl;
String title;
String description;
String newsLink;
String createDate;
String category;
String footerTitle;
DatabaseModel(
{this.id,
this.imageUrl,
this.title,
this.description,
this.newsLink,
this.createDate,
this.category,
this.footerTitle});
factory DatabaseModel.fromMap(Map<String, dynamic> json) => DatabaseModel(
id: json['id'],
imageUrl: json['imageUrl'],
title: json['title'],
description: json['description'],
newsLink: json['newsLink'],
createDate: json['createDate'],
category: json['category'],
footerTitle: json['footerTitle']);
Map<String, dynamic> toMap() => {
'id': id,
'imageUrl': imageUrl,
'title': title,
'description': description,
'newsLink': newsLink,
'createDate': createDate,
'category': category,
'footerTitle': footerTitle
};
}
Now, I display my database class which I use for Add, Delete, and Get data. In this class I use Model class because I want to display my data in Bookmark class.
import 'dart:io';
import 'package:news_app/src/model/bookmark_db_provider.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseProvider {
// DatabaseProvider._();
// static final DatabaseProvider db = DatabaseProvider._();
Database _database;
Future<Database> get database async {
if (_database != null) return _database;
_database = await getDatabaseInstance();
return _database;
}
Future<Database> getDatabaseInstance() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, 'bookmark.db');
return await openDatabase(path, version: 1,
onCreate: (Database db, int version) async {
await db.execute('create table Bookmark ('
'id integer primary key autoincrement,'
'imageUrl text,'
'title text,'
'description text,'
'newsLink text,'
'createDate text,'
'category text,'
'footerTitle text'
')');
});
}
addToDatabase(DatabaseModel databaseModel) async {
final db = await database;
var raw = await db.insert('Bookmark', databaseModel.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace);
return raw;
}
updateDatabase(DatabaseModel databaseModel) async {
final db = await database;
var response = await db.update('Bookmark', databaseModel.toMap(),
where: 'id = ?', whereArgs: [databaseModel.id]);
return response;
}
Future<DatabaseModel> getDatabaseModelWithId(int id) async {
final db = await database;
var response = await db.query('Bookmark', where: 'id = ?', whereArgs: [id]);
return response.isNotEmpty ? DatabaseModel.fromMap(response.first) : null;
}
Future<List<DatabaseModel>> getAllData() async {
final db = await database;
var response = await db.query('Bookmark');
List<DatabaseModel> list =
response.map((c) => DatabaseModel.fromMap(c)).toList();
return list;
}
deleteDatabase(int id) async {
final db = await database;
return db.delete('Bookmark', where: 'id = ?', whereArgs: [id]);
}
deleteAllDatabase() async {
final db = await database;
db.delete('Bookmark');
}
}
Here I display my BookMark class. This class I use for display data for user.
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:news_app/src/model/bookmark_db_provider.dart';
import 'package:news_app/src/screens/home.dart';
import 'package:news_app/src/utils/database.dart';
class BookMark extends StatefulWidget {
#override
_BookMarkState createState() => _BookMarkState();
}
class _BookMarkState extends State<BookMark> {
DatabaseProvider databaseProvider;
#override
void initState() {
super.initState();
databaseProvider = DatabaseProvider();
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => Navigator.push(
context, MaterialPageRoute(builder: (context) => HomePage())),
child: Scaffold(
backgroundColor: Theme.of(context).primaryColor,
appBar: AppBar(
backgroundColor: Theme.of(context).appBarTheme.color,
elevation: 0,
centerTitle: true,
title: Text(
'BookMark News',
style: TextStyle(fontSize: 23, fontWeight: FontWeight.bold),
),
),
body: Container(
padding: EdgeInsets.all(8.0),
child: FutureBuilder<List<DatabaseModel>>(
future: databaseProvider.getAllData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
var common = snapshot.data[index];
return Card(
elevation: 5.0,
child: ListTile(
leading: SizedBox(
height: 85,
width: 79,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
image: DecorationImage(
image:
NetworkImage(common['imageUrl']),
fit: BoxFit.cover)),
),
),
title: Text(common['title']),
isThreeLine: true,
subtitle: Text(common['footerTitle']),
trailing: Column(
children: <Widget>[
Text(common['createDate']),
Text(common['category'])
],
),
),
);
});
} else {}
return Center(
child: CircularProgressIndicator(),
);
},
)
)),
);
}
}
I all of data in Home Page and in this Page when I pressed on button it display Method was called null. This type I handle onclick.
onPressed: () async {
print('added data');
dbHelper.addToDatabase(DatabaseModel(
imageUrl: allNewsDetail[index]['image_url'],
category: allNewsDetail[index]['category'],
footerTitle: allNewsDetail[index]['footer_title'],
createDate: allNewsDetail[index]['created_date'],
newsLink: allNewsDetail[index]['news_link'],
description: allNewsDetail[index]['description'],
title: allNewsDetail[index]['title']));
Navigator.push(context,MaterialPageRoute(builder: (context) =>BookMark()));
}
When click on button it displays this error.
The method 'getAllData' was called on null.
Receiver: null
Tried calling: getAllData()
Please check This code I give me solution for it.
You are not passing in the databaseProvider into this class and that is why you are getting null!

Getter method returning null value

I have developed a login page using local db in flutter SQL. I want to display the username in SQL database after the table is created but the getter method is returning null.
I am displaying the username like this in class home
body: Center(
child: user != null ? Text("Saved \n \n Username: '${user.username}' ")
: Text("Not saved"),
),
Here is login page code
BuildContext _ctx;
bool _isLoading = false;
final _formKey = new GlobalKey<FormState>();
final scaffoldKey = new GlobalKey<ScaffoldState>();
String _username,_password;
LoginPagePresenter _presenter;
#override
void initState(){
_presenter = new LoginPagePresenter(this);
}
void _submit(){
final form = _formKey.currentState;
if(form.validate()){
_isLoading = true;
form.save();
_presenter.doLogin(_username, _password);
}
}
void _showsnackbar(String text){
scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text(text),
));
}
#override
Widget build(BuildContext context) {
return _isLoading ? Loading() :Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: Text('Login Page',textAlign: TextAlign.center,),
),
body: Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 50.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(height: 20.0),
TextFormField(
decoration: InputDecoration(labelText:'Username' ),
validator: (val) => val.isEmpty ? 'Enter Username' : null,
onChanged: (val) {
setState(() => _username = val);
},
),
SizedBox(height: 20.0),
TextFormField(
obscureText: true,
decoration: InputDecoration(labelText:'Password' ),
validator: (val) => val.length < 6 ? 'Enter a password 6+ chars long' : null,
onChanged: (val) {
setState(() => _password = val);
},
),
SizedBox(height: 20.0),
RaisedButton(
color: Colors.pink[400],
child: Text(
'Sign In',
style: TextStyle(color: Colors.white),
),
onPressed: () async {
_submit();
}
),
],
),
),
),
);
}
#override
void onLoginError(String error) {
_showsnackbar(error);
setState(() {
_isLoading = false;
});
}
#override
void onLoginSuccess(User user) async {
_showsnackbar(user.toString());
setState(() {
_isLoading = false;
});
var db = new DatabaseHelper();
await db.saveUser(user);
Navigator.of(_ctx).push(MaterialPageRoute<Null>(
builder: (BuildContext context){
return new Home(
user:user,
);
}
));
}
Here is user class
class User{
String _username;
String _password;
User(this._username,this._password);
User.map(dynamic obj){
this._username = obj['username'];
this._password = obj['password'];
}
String get username => _username;
String get password => _password;
Map<String,dynamic> toMap(){
var map = new Map<String,dynamic>();
map["username"] = _username;
map["password"] = _password;
return map;
}
}
And this is database helper class
class DatabaseHelper{
static final DatabaseHelper _instance = new DatabaseHelper.internal();
DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
static Database _db;
Future<Database> get db async{
if(_db!= null)
{
return _db;
}
_db = await initdb();
return _db;
}
initdb() async{
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path,"main.db");
var ourDb = await openDatabase(path,version:1,onCreate:_onCreate);
return ourDb;
}
void _onCreate(Database db,int version)async {
await db.execute("CREATE TABLE User(id INTEGER PRIMARY KEY,username TEXT,password TEXT)");
print("Table created");
}
//insertion of data
Future<int> saveUser(User user)async {
var dbClient = await db;
int res = await dbClient.insert("User", user.toMap());
return res;
}
// deleting data
Future<int> deleteUser(User user)async {
var dbClient = await db;
int res = await dbClient.delete("User");
return res;
}
}
this is login presenter
abstract class LoginPageContract{
void onLoginSuccess(User user);
void onLoginError(String error);
}
class LoginPagePresenter{
LoginPageContract _view;
RestData api = new RestData();
LoginPagePresenter(this._view);
doLogin(String username,String password){
api
.login(username, password)
.then((user)=> _view.onLoginSuccess(user))
.catchError((onError)=>_view.onLoginError(onError()));
}
}
This is github link to the code for reference: https://github.com/meadows12/sql
Please help !!
All you have to do is to access the user obejct as "widget.user" instead of "user". So, the following would do the trick :
body: Center(
child: widget.user != null ? Text("Saved \n \n Username: '${widget.user.username}' ")
: Text("Not saved"),
)
There's one more problem in the code. You are not assigning the buildcontext to variable _ctx. So, the screen change didn't happen on your code on the github. I added one line in login.dart as below to make it work :
Widget build(BuildContext context) {
_ctx = context;
return _isLoading ? Loading() :Scaffold(______________
Result :

How to implement search delegate with sqflite flutter

I have created an app that stores some notes in sqlite database. I did all CRUD operations and it's working well, but when I'm trying to make search operation inside my database with SearchDelegate, I got some problem. I'll show you my code before I make search with SearchDelegate
databaseHelper:
import 'dart:async';
import 'package:plants/model/plant.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DatabaseHelper {
static final DatabaseHelper _instance = new DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
final String tableNote = 'noteTable';
final String columnId = 'id';
final String columnLocation = 'location';
final String columnTitle = 'title';
final String columnDescription = 'description';
static Database _db;
DatabaseHelper.internal();
Future<Database> get db async {
if (_db != null) {
return _db;
}
_db = await initDb();
return _db;
}
initDb() async {
String databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'notes.db');
// await deleteDatabase(path); // just for testing
var db = await openDatabase(path, version: 1, onCreate: _onCreate);
return db;
}
void _onCreate(Database db, int newVersion) async {
await db.execute(
'CREATE TABLE $tableNote($columnId INTEGER PRIMARY KEY,$columnLocation TEXT, $columnTitle TEXT, $columnDescription TEXT)');
}
Future<int> saveNote(Note note) async {
var dbClient = await db;
var result = await dbClient.insert(tableNote, note.toMap());
// var result = await dbClient.rawInsert(
// 'INSERT INTO $tableNote ($columnTitle, $columnDescription) VALUES (\'${note.title}\', \'${note.description}\')');
return result;
}
Future<List> getAllNotes() async {
var dbClient = await db;
var result = await dbClient.query(tableNote, columns: [columnId, columnLocation , columnTitle, columnDescription]);
// var result = await dbClient.rawQuery('SELECT * FROM $tableNote');
return result.toList();
}
Future<int> getCount() async {
var dbClient = await db;
return Sqflite.firstIntValue(await dbClient.rawQuery('SELECT COUNT(*) FROM $tableNote'));
}
Future<Note> getNote(int id) async {
var dbClient = await db;
List<Map> result = await dbClient.query(tableNote,
columns: [columnId, columnLocation , columnTitle, columnDescription],
where: '$columnId = ?',
whereArgs: [id]);
// var result = await dbClient.rawQuery('SELECT * FROM $tableNote WHERE $columnId = $id');
if (result.length > 0) {
return new Note.fromMap(result.first);
}
return null;
}
Future<int> deleteNote(int id) async {
var dbClient = await db;
return await dbClient.delete(tableNote, where: '$columnId = ?', whereArgs: [id]);
// return await dbClient.rawDelete('DELETE FROM $tableNote WHERE $columnId = $id');
}
Future<int> updateNote(Note note) async {
var dbClient = await db;
return await dbClient.update(tableNote, note.toMap(), where: "$columnId = ?", whereArgs: [note.id]);
// return await dbClient.rawUpdate(
// 'UPDATE $tableNote SET $columnTitle = \'${note.title}\', $columnDescription = \'${note.description}\' WHERE $columnId = ${note.id}');
}
Future close() async {
var dbClient = await db;
return dbClient.close();
}
}
Class Notes
class Note {
int _id;
String _location;
String _title;
String _description;
Note(this._location,this._title, this._description);
Note.map(dynamic obj) {
this._id = obj['id'];
this._location = obj['location'];
this._title = obj['title'];
this._description = obj['description'];
}
int get id => _id;
String get location => _location;
String get title => _title;
String get description => _description;
Map<String, dynamic> toMap() {
var map = new Map<String, dynamic>();
if (_id != null) {
map['id'] = _id;
}
map['location'] = _location;
map['title'] = _title;
map['description'] = _description;
return map;
}
Note.fromMap(Map<String, dynamic> map) {
this._id = map['id'];
this._location = map ['location'];
this._title = map['title'];
this._description = map['description'];
}
}
List.dart
import 'package:flutter/material.dart';
import 'package:plants/AddPlant.dart';
import 'package:plants/model/plant.dart';
import 'database/dbhelper.dart';
class ListViewNote extends StatefulWidget {
#override
State<StatefulWidget> createState() => new ListViewNoteState();
}
class ListViewNoteState extends State<ListViewNote> {
List<Note> items = new List();
DatabaseHelper db = new DatabaseHelper();
#override
void initState() {
super.initState();
db.getAllNotes().then((notes) {
setState(() {
notes.forEach((note) {
items.add(Note.fromMap(note));
});
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Plant List',
),
centerTitle: true,
actions: <Widget>[
IconButton(icon: Icon(Icons.search,
color: Colors.white,), onPressed: (){
showSearch(context: context,
delegate: DataSearch(this.items));
})
],
),
body: Center(
child: ListView.builder(
itemCount: items.length,
padding: const EdgeInsets.all(15.0),
itemBuilder: (context, position) {
return Dismissible(
background: stackBehindDismiss(),
key: ObjectKey(items[position]),
child: Card(
elevation: 2.0,
margin: new EdgeInsets.symmetric(horizontal: 0.0,vertical: 2.0),
child: Column(
children: <Widget>[
ListTile(
title: Text(
'${items[position].title}',
style: TextStyle(
fontSize: 22.0,
color: Colors.deepOrangeAccent,
),
),
subtitle: Text(
'${items[position].description}' + '' + '${items[position].location}',
style: new TextStyle(
fontSize: 18.0,
fontStyle: FontStyle.italic,
),
),
onTap: () => _navigateToNote(context, items[position]),
),
],
),
),
onDismissed: (dirction){
var item = items.elementAt(position);
_deleteNote(context, items[position], position);
Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Item deleted"),
));
},
);
}
),
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.green[700],
child: Icon(Icons.add),
onPressed: () => _createNewNote(context),
),
);
}
void _deleteNote(BuildContext context, Note note, int position) async {
db.deleteNote(note.id).then((notes) {
setState(() {
items.removeAt(position);
});
});
}
void _navigateToNote(BuildContext context, Note note) async {
String result = await Navigator.push(
context,MaterialPageRoute(builder: (context) => NoteScreen(note)),
);
if (result == 'update') {
db.getAllNotes().then((notes) {
setState(() {
items.clear();
notes.forEach((note) {
items.add(Note.fromMap(note));
});
});
});
}
}
void _createNewNote(BuildContext context) async {
String result = await Navigator.push(
context,MaterialPageRoute(builder: (context) => NoteScreen(Note('', '', ''))),
);
if (result == 'save') {
db.getAllNotes().then((notes) {
setState(() {
items.clear();
notes.forEach((note) {
items.add(Note.fromMap(note));
});
});
});
}
}
stackBehindDismiss() {
return Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20.0),
color: Colors.green[700],
child: Icon(
Icons.delete,
color: Colors.white,
),
);
}
}
class DataSearch extends SearchDelegate<Note> {
DatabaseHelper db = new DatabaseHelper();
final List<Note> items = new List();
List<Note> suggestion = new List();
// ListViewNoteState i = ListViewNoteState();
DataSearch(this.suggestion);
#override
ThemeData appBarTheme(BuildContext context) {
assert(context != null);
final ThemeData theme = Theme.of(context);
assert(theme != null);
return theme;
}
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(icon: Icon(Icons.clear), onPressed: () {
query = '';
} )
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: (){
close(context, null);
},
);
}
#override
Widget buildResults(BuildContext context) {
}
#override
Widget buildSuggestions(BuildContext context) {
final suggestion = query.isEmpty
? items
: items.where((target) => target.title.startsWith(query)).toList();
if(items.isEmpty)
{
print("Null");
}
return ListView.builder(
itemBuilder: (context, position)=>
ListTile(
title: Text(items[position].title),
),
itemCount: suggestion.length,
);
}
}
On CRUD, everything is working well and I'm adding 3 records but when I'm using SearchDelegate to implement search, I not getting any result.
The thing I need is to searchlist from database using searchbar
Try this:
return ListView.builder(
itemBuilder: (context, index)=>
ListTile(
title: Text(suggestion[index].title),
),
It should work and display the right results, at least mine is working this way, but I think you'll have to point to items list when you build your results or when you tap to open it or something like that.