Flutter pass search data to SearchDelegate

3,545

You can make constructor of DataSearch with parameter q as String and final. Then set this.q to the query you want. And in button, initialize DataSearch with tag of product as parameter to it.

Try this code and tell me if it works.

class DataSearch extends SearchDelegate<Product> {
  final suggestions = new ProductsRepository().fetchAllProducts();
  final lastOnes = ['suggest'];

  final String q;

  DataSearch(this.q) {
       query = this.q;
  }

  @override
  List<Widget> buildActions(BuildContext context) {
    return [
      IconButton(icon: Icon(Icons.clear), onPressed: () {
        query = '';
        showSuggestions(context);
      }),
    ];
  }

  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(
        icon: AnimatedIcon(
          icon: AnimatedIcons.menu_arrow,
          progress: transitionAnimation,
        ),
        onPressed: () {
          close(context, null);
        });
  }

  @override
  Widget buildResults(BuildContext context) {
    final suggestionList = query.isEmpty
        ? []
        : suggestions.where((p) => p.title.contains(query)).toList();
    double _gridSize =
        MediaQuery.of(context).size.height * 0.58; //88% of screen
    double childAspectRatio = MediaQuery.of(context).size.width /
        (MediaQuery.of(context).size.height / 1.0);

    return Column(children: <Widget>[
      new Container(
          height: _gridSize + 100,
          decoration: BoxDecoration(
            color: const Color(0xFFeeeeee),),
          padding: EdgeInsets.only(left: 10, right: 10),
          child: new Column(children: <Widget>[
            new Container(
                margin: EdgeInsets.only(top: 40),
                child: new Column(children: <Widget>[
                  new Container(
                      height: _gridSize - 60,
                      margin: EdgeInsets.only(top: 0),
                      child: new PhysicalModel(
                          color: Colors.transparent,
                          borderRadius: BorderRadius.only(
                              bottomLeft: Radius.circular(_gridSize / 10 - 10),
                              bottomRight:
                              Radius.circular(_gridSize / 10 - 10)),
                          clipBehavior: Clip.antiAlias,
                          child: GridView.builder(
                              itemCount: suggestionList.length,
                              gridDelegate:
                              new SliverGridDelegateWithFixedCrossAxisCount(
                                  crossAxisCount: 2,
                                  childAspectRatio: childAspectRatio),
                              itemBuilder: (BuildContext context, int index) {
                                return new Padding(
                                    padding: EdgeInsets.only(
                                        top: index % 2 == 0 ? 20 : 0,
                                        right: index % 2 == 0 ? 5 : 0,
                                        left: index % 2 == 1 ? 5 : 0,
                                        bottom: index % 2 == 1 ? 20 : 0),
                                    child:
                                    ProductWidget(
                                        product: suggestionList[index]));
                              })

                      )),

                ]))
          ])),
//      new MinimalCart(_gridSize)
    ]);
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    final suggestionList = query.isEmpty
        ? []
        : suggestions.where((p) => p.title.contains(query)).toList();
    return ListView.builder(
      itemBuilder: (context, index) =>
          ListTile(
            leading: Icon(Icons.add),
            onTap: () => showResults(context),
            title: RichText(
                text: TextSpan(
                    text: suggestionList[index].title.substring(
                        0, query.length),
                    style: TextStyle(
                        color: Colors.black, fontWeight: FontWeight.bold),
                    children: [
                      TextSpan(
                          text: suggestionList[index].title.substring(
                              query.length),
                          style: TextStyle(
                              color: Colors.grey))
                    ])),
          ),
      itemCount: suggestionList.length,
    );
  }
}

And your button

child: FlatButton(
     child: Text(widget.product.tags[index]),
     onPressed: () {
            showSearch(
              context: context,
              delegate: DataSearch(widget.product.tags[index]),
         );

       })
Share:
3,545
Wail Hayaly
Author by

Wail Hayaly

Updated on December 13, 2022

Comments

  • Wail Hayaly
    Wail Hayaly over 1 year

    I created products with tags, so when the user press on a tag button it will open the SearchDelegate and search for that tag,

    so how can I pass the tag name to the Search Delegate query?

    my code:

    class DataSearch extends SearchDelegate<Product> {
      final suggestions = new ProductsRepository().fetchAllProducts();
      final lastOnes = ['suggest'];
    
      @override
      List<Widget> buildActions(BuildContext context) {
        return [
          IconButton(icon: Icon(Icons.clear), onPressed: () {
            query = '';
            showSuggestions(context);
          }),
        ];
      }
    
      @override
      Widget buildLeading(BuildContext context) {
        return IconButton(
            icon: AnimatedIcon(
              icon: AnimatedIcons.menu_arrow,
              progress: transitionAnimation,
            ),
            onPressed: () {
              close(context, null);
            });
      }
    
      @override
      Widget buildResults(BuildContext context) {
        final suggestionList = query.isEmpty
            ? []
            : suggestions.where((p) => p.title.contains(query)).toList();
        double _gridSize =
            MediaQuery.of(context).size.height * 0.58; //88% of screen
        double childAspectRatio = MediaQuery.of(context).size.width /
            (MediaQuery.of(context).size.height / 1.0);
    
        return Column(children: <Widget>[
          new Container(
              height: _gridSize + 100,
              decoration: BoxDecoration(
                color: const Color(0xFFeeeeee),),
              padding: EdgeInsets.only(left: 10, right: 10),
              child: new Column(children: <Widget>[
                new Container(
                    margin: EdgeInsets.only(top: 40),
                    child: new Column(children: <Widget>[
                      new Container(
                          height: _gridSize - 60,
                          margin: EdgeInsets.only(top: 0),
                          child: new PhysicalModel(
                              color: Colors.transparent,
                              borderRadius: BorderRadius.only(
                                  bottomLeft: Radius.circular(_gridSize / 10 - 10),
                                  bottomRight:
                                  Radius.circular(_gridSize / 10 - 10)),
                              clipBehavior: Clip.antiAlias,
                              child: GridView.builder(
                                  itemCount: suggestionList.length,
                                  gridDelegate:
                                  new SliverGridDelegateWithFixedCrossAxisCount(
                                      crossAxisCount: 2,
                                      childAspectRatio: childAspectRatio),
                                  itemBuilder: (BuildContext context, int index) {
                                    return new Padding(
                                        padding: EdgeInsets.only(
                                            top: index % 2 == 0 ? 20 : 0,
                                            right: index % 2 == 0 ? 5 : 0,
                                            left: index % 2 == 1 ? 5 : 0,
                                            bottom: index % 2 == 1 ? 20 : 0),
                                        child:
                                        ProductWidget(
                                            product: suggestionList[index]));
                                  })
    
                          )),
    
                    ]))
              ])),
    //      new MinimalCart(_gridSize)
        ]);
      }
    
      @override
      Widget buildSuggestions(BuildContext context) {
        final suggestionList = query.isEmpty
            ? []
            : suggestions.where((p) => p.title.contains(query)).toList();
        return ListView.builder(
          itemBuilder: (context, index) =>
              ListTile(
                leading: Icon(Icons.add),
                onTap: () => showResults(context),
                title: RichText(
                    text: TextSpan(
                        text: suggestionList[index].title.substring(
                            0, query.length),
                        style: TextStyle(
                            color: Colors.black, fontWeight: FontWeight.bold),
                        children: [
                          TextSpan(
                              text: suggestionList[index].title.substring(
                                  query.length),
                              style: TextStyle(
                                  color: Colors.grey))
                        ])),
              ),
          itemCount: suggestionList.length,
        );
      }
    }
    

    My tag button:

     child: FlatButton(
         child: Text(widget.product.tags[index]),
         onPressed: () {
                showSearch(
                  context: context,
                  delegate: DataSearch(),
             );
    
           })
    

    I tried to pass query variable but it didn't work because query is inside the Widgets, is there another way to do it?

  • Llama
    Llama over 3 years
    idk why I couldnt figure this out, thanks a bunch @Shady Boshra. This worked for me