0

I am trying to search my sqlite database, right now it returns all the members, even when text is input to the text form. I have a ListView builder in the memberList constructor that creates cards for each member. What I want it to do is display just the cards that match the users input.

i.e. if a user inputs J it would show only the members that either have first or last name with the letters J.

I can see the query is working properly as I have it printing the count in the dbHelper class and it updates each time I make a change to the textform's text. What I need it to do is essentially refresh the body of the Scaffold onChange of the textform's text, which is not working.

Any suggestions on how I can do this?

I prefer to have the textform in the appbar if at all possible. Below is my code:


import 'package:flutter/material.dart';
import 'package:troop_mobile_app/MemberFiles/Member.dart';
import 'package:troop_mobile_app/MemberFiles/MemberList.dart';
import 'package:troop_mobile_app/DatabaseFiles/DBHelper.dart';

Future<List<Member>> search(String search) async {
  var dbHelper = DBHelper();
  Future<List<Member>> members = dbHelper.searchScouts(search);
  return members;
}

class SearchFunction extends StatefulWidget {
  @override
  _SearchFunctionState createState() => _SearchFunctionState();
}

class _SearchFunctionState extends State<SearchFunction> {

  TextEditingController controller = TextEditingController();

  String searchText = "";

  _searchResults(String text) {
    return new FutureBuilder<List<Member>>(
        future: search(text),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return MemberList(snapshot.data);
          }
          return Container(
              alignment: AlignmentDirectional.center,
              child: new CircularProgressIndicator(
                strokeWidth: 7,
              ));
        });
  }

  Widget build(BuildContext context) {

    //Page Creation returning the UI Home Page Display
    return Scaffold(
        //Top 'Menu Bar' (AppBar) Creation
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.arrow_back),
            onPressed: () {
              Navigator.pop(context);
            },
            padding: EdgeInsets.fromLTRB(
                20 /*left*/, 0 /*top*/, 20 /*right*/, 0 /*bottom*/),
          ),
          title: TextField(
            //initialValue: 'Search...',
            style: TextStyle(color: Colors.black),
            decoration: InputDecoration(
              //fillColor: Colors.white,
              //filled: true,
              //border:
              //OutlineInputBorder(borderRadius: BorderRadius.circular(12.0)),
              labelText: 'Search...',
              contentPadding: EdgeInsets.fromLTRB(10, 6, 0, 6),
              prefixIcon: Icon(Icons.search),
            ),
            onChanged: (text) async {
              _searchResults(text);
              searchText = text;
            },
            controller: controller,
          ),
        ),
        //End Top 'Menu Bar' Creation

        //Main Body Creation
        body: Container(
                  child: new FutureBuilder<List<Member>> (
                      future: search(searchText),
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          return MemberList(snapshot.data);
                        }
                        return Container(
                            alignment: AlignmentDirectional.center,
                            child: new CircularProgressIndicator(
                              strokeWidth: 7,
                            ));
                      }),

        )
        //End Main Body Creation


        );
  }
}

MemberList:

import 'package:flutter/material.dart';
import 'MemberCards.dart';
import 'package:troop_mobile_app/MemberFiles/Member.dart';

class MemberList extends StatelessWidget {
  final List<Member> members;
  MemberList(this.members);

  @override
  Widget build(BuildContext context) {
    return _buildList(context);
  }

  ListView _buildList(context) {
    return ListView.builder(
      itemCount: members.length,
      itemBuilder: (context, int) {
        return MemberCards(members[int], );
      },
    );
  }
}

DBHelper:

  Future<List<Map<String, dynamic>>> searchScoutsMap(String search) async {
    Database db = await this.database;
    print("This works? $db");
    var result = await db.rawQuery("SELECT * FROM $memberTable  WHERE adult = 'N' AND ($colFirstName Like '%$search%' OR $colLastName Like '%$search%') ORDER BY $colFirstName ASC, $colLastName ASC");
    print("result is working? $result");
    print(result.length);
    return result;
  }

  Future<List<Member>> searchScouts(String search) async {

    var searchResults = await searchScoutsMap(search); // Get 'Map List' from database
    print(searchResults.length);
    print(searchResults.toString());
    int count = searchResults.length;         // Count the number of map entries in db table

    List<Member> memberList = List<Member>();
    // For loop to create a 'Member List' from a 'Map List'
    for (int i = 0; i < count; i++) {
      print("for loop working: ${i+1}");
      memberList.add(Member.fromMapObject(searchResults[i]));
    }

    print("completed for loop");
    return memberList;

  }

1 Answer 1

1

I was able to solve my mistake after hours of frustrating work...

Here is was my fix:

In the first code snippet I was missing the setState()

I had to wrap the return new FutureBuilder... with setState()

_searchResults(String text) {
    return new FutureBuilder<List<Member>>(
        future: search(text),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return MemberList(snapshot.data);
          }
          return Container(
              alignment: AlignmentDirectional.center,
              child: new CircularProgressIndicator(
                strokeWidth: 7,
              ));
        });
  }

New code snippet shown below:

I hope this helps anyone else out there that runs into a similar issue.

  _searchResults(String text) {
    setState(() {
      return new FutureBuilder<List<Member>>(
          future: search(text),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return MemberList(snapshot.data);
            }
            return Container(
                alignment: AlignmentDirectional.center,
                child: new CircularProgressIndicator(
                  strokeWidth: 7,
                ));
          });
    });
  }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.