emirşah erden
emirşah erden

Reputation: 53

not pulling data in search button

I want to search from the search button, but it doesn't work. I'm missing a small place, but I couldn't find it.

my code dataTable

import 'package:data_table_2/data_table_2.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:novadan_admin/global/models/endpoint/responsedata/nv_search_products_response_data.dart';
import 'package:novadan_admin/global/utilities/consts_design.dart';
import 'package:novadan_admin/global/widgets/datatable/global_paginated_datatable.dart';
import 'package:novadan_admin/global/widgets/loading_indicator.dart';
import 'package:novadan_admin/modules/products/products_main/controllers/products_main_controller.dart';
import 'package:novadan_admin/modules/products/products_main/widgets/datatable/datasource.dart';
import 'package:novadan_admin/modules/products/products_main/widgets/datatable/widgets/head/head.dart';
import 'package:novadan_admin/modules/products/products_main/widgets/datatable/widgets/header/actions.dart';

class ProductsMainDataTable extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        padding: EdgeInsets.all(defaultPadding),
        decoration: BoxDecoration(
          color: secondaryColor,
          borderRadius: defaultRadius,
        ),
        child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
          ProductsMainDataTableHead(),
          SizedBox(
            height: 30,
          ),
          GetBuilder<ProductsMainController>(
              id: "datatable",
              builder: (controller) {

            return FutureBuilder(
                future: controller.mainFuture.value,
                builder: (context, snapshot) {
                  switch (snapshot.connectionState) {
                    case ConnectionState.active:
                    case ConnectionState.waiting:
                      return SizedBox(height: 600, child: LoadingIndicator());
                    case ConnectionState.done:
                      if (snapshot.hasError) {
                        return SizedBox(
                            width: double.infinity,
                            height: 600,
                            child: Center(
                                child: SelectableText(snapshot.error.toString(), style: Theme.of(context).textTheme.caption)));
                      }

                      controller.productsData.value = (snapshot.data! as List)[0];
                      final DataTableSource _data = ProductsMainSource(controller.productsData.value.searchProductsData!);

                      return SizedBox(
                          width: double.infinity,
                          height: (controller.productsData.value.searchProductsData!.length * 120) + 200,
                          child: GlobalPaginatedDataTable(
                            source: _data,
                            minWidth: 600,
                            emptyText: "productsmainnotfound",
                            rowsPerPage: controller.productsData.value.searchProductsData!.length == 0
                                ? 1
                                : controller.productsData.value.searchProductsData!.length,
                            dataRowHeight: 120,
                            showCheckboxColumn: true,
                            headerAction: ProductsMainDataTableHeaderActions(),
                            statusMessage: controller.statusMessage.value,
                            hintText: "",
                            /*    "${controller.page.value}-${(controller.productsData.value.total!  controller.productsData.value.perPage!).toStringAsFixed(0)}",
                             pageLength: (controller.productsData.value.total! /
                                    controller.productsData.value.perPage!)
                                .round(),
                            onFirst: () => controller.getFirstPage(),
                            onLast: () => controller.getLastPage(),
                            onPrevious: () => controller.getPreviousPage(),
                            onNext: () => controller.getNextPage(),
                            onPage: (value) => controller.getPage(value!), */
                            columns: [
                              DataColumn2(
                                size: ColumnSize.S,
                                label: Text(
                                  "productsmainpicture".tr,
                                  style: Theme.of(context).textTheme.subtitle1,
                                ),
                              ),
                              DataColumn2(
                                size: ColumnSize.L,
                                label: Text(
                                  "productsmaintitletext".tr,
                                  style: Theme.of(context).textTheme.subtitle1,
                                ),
                              ),
                              DataColumn2(
                                size: ColumnSize.S,
                                label: Text("productsmainprice".tr, style: Theme.of(context).textTheme.subtitle1),
                              ),
                              DataColumn2(
                                  size: ColumnSize.S,
                                  label: Text("productsmainaction".tr, style: Theme.of(context).textTheme.subtitle1))
                            ],
                          ));
                    default:
                      return SizedBox(height: 600, child: LoadingIndicator());
                  }
                });
          }),
        ]));
  }
}

My code ProductsMainController

    import 'dart:async';
import 'package:get/get.dart';
import 'package:novadan_admin/global/models/endpoint/responsedata/nv_search_products_response_data.dart';
import '../services/products_main_service.dart';

class ProductsMainController extends GetxController {
  final productsData = NvSearchProductsResponseData().obs;
  final mainFuture = Future.wait([]).obs;
  final productsFuture = Future.value(NvSearchProductsResponseData()).obs;
  var perPage = "50".obs;
  var page = 1.obs;
  var statusMessage = "".obs;

  @override
  void onInit() {
    super.onInit();
    getProducts();
    mainFuture.value = Future.wait([productsFuture.value]);
  }

  getProducts() {
    productsFuture.value = searchProducts("");
   
  }

  getSearchedProducts(String searchText) {
    productsFuture.value = searchProducts(searchText);
    update(["datatable"]);
  }

  selectRow(bool selected, index) {
    productsData.value.searchProductsData![index].selected = selected;
    update();
  }

  void getFirstPage() {
    if (page.value != 1) {
      page.value = 1;
      getProducts();
      update();
    }
  }

  void getLastPage() {
    getProducts();
    update();
  }

  void getPreviousPage() {
    if (page.value != 1) {
      page.value -= 1;
      getProducts();
      update();
    }
  }

  void getNextPage() {
    getProducts();
    update();
  }

  void getPage(int newPage) {
    page.value = newPage;
    getProducts();
    update();
  }
}

data is not coming

enter image description here

Upvotes: 0

Views: 113

Answers (1)

willypede
willypede

Reputation: 199

I have made my custom Search Widget to do filtering. Check out these codes.

Main Page:

import 'package:flutter/material.dart';
import "package:inventory_control_flutter/models/stock.dart";
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:inventory_control_flutter/templates/stock_card.dart';
import 'package:inventory_control_flutter/widgets/search_widget.dart';

class StockList extends StatefulWidget {
  const StockList({Key? key}) : super(key: key);

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

class _StockListState extends State<StockList> {
  String query = '';
  List<Stock> arrStock = [];
  List<Stock> arrFilteredStock = [];
  bool isFiltered = false;

  Future<List<Stock>> _fetchData() async {
    if(!isFiltered){
      final response = await http
          .get(Uri.parse('http://tos.petra.ac.id/~c14170010/api/getAllItem.php'));
      if (response.statusCode == 200) {
        var jsonData = json.decode(response.body);
        List<Stock> arr = [];
        for (var data in jsonData) {
          Stock stock = Stock(data["item_id"], data["code"], data["comname"],
              data["unit"], data["quantity"]);
          arr.add(stock);
        }
        arrStock = arr;
        arrFilteredStock = arrStock;
      } else {
        throw Exception('Failed to load stock');
      }
    }
    return arrFilteredStock;
  }

  @override
  Widget build(BuildContext context) {

    return GestureDetector(
      onTap: (){
        FocusManager.instance.primaryFocus?.unfocus();
      },
      child: SafeArea(child:
      Scaffold(
          body: Column(children: <Widget>[
            Container(
              width: double.infinity,
              margin: EdgeInsets.all(16),
              child: const Text("Inventory",
                  textAlign: TextAlign.center,
                  style: TextStyle(
                      fontFamily: "Quicksand",
                      fontSize: 20,
                      fontWeight: FontWeight.w700)),
            ),
            Container(
              child:_buildSearch(),
            ),
            Flexible(
              child:
              FutureBuilder(
                  future: _fetchData(),
                  builder: (context, AsyncSnapshot snapshot) {
                    if(isFiltered){
                      isFiltered = false;
                      return ListView.builder(
                        // itemCount: snapshot.data.length,
                        itemCount: arrFilteredStock.length,
                        itemBuilder: (context, index) {
                          var id = arrFilteredStock[index].id;
                          var code = arrFilteredStock[index].itemCode;
                          var comname = arrFilteredStock[index].itemComname;
                          var unit = arrFilteredStock[index].itemUnit;
                          var qty = arrFilteredStock[index].itemStockBalanceQty;
                          return StockCard(
                              stock: Stock(id, code, comname, unit, qty));
                        },
                      );
                    }else{
                      if (snapshot.data == null) {
                        return Container(
                            child: const Center(
                              child: Text("Loading..."),
                            ));
                      } else {
                        return ListView.builder(
                          itemCount: snapshot.data.length,
                          itemBuilder: (context, index) {
                            var id = snapshot.data[index].id;
                            var code = snapshot.data[index].itemCode;
                            var comname = snapshot.data[index].itemComname;
                            var unit = snapshot.data[index].itemUnit;
                            var qty = snapshot.data[index].itemStockBalanceQty;
                            return StockCard(
                                stock: Stock(id, code, comname, unit, qty));
                          },
                        );
                      }
                    }
                  }),
            )
          ]))
      ),
    );
  }
  void searchItem(String query){
    final items = arrStock.where((item){
      final nameLower = item.itemComname.toLowerCase();
      final codeLower = item.itemCode.toLowerCase();
      final searchLower = query.toLowerCase();

      return nameLower.contains(searchLower) || codeLower.contains(searchLower);
    }).toList();
    isFiltered = true;
    if(query.isEmpty){
      isFiltered = false;
    }
    setState(() {
      this.query = query;
      this.arrFilteredStock = items;
    });
  }
  Widget _buildSearch() => SearchWidget(
    text: query,
    hintText: "Item Code or Item Name",
    onChanged: searchItem,
  );
}

Custom Search Widget:

import 'package:flutter/material.dart';

class SearchWidget extends StatefulWidget {
  final String text;
  final ValueChanged<String> onChanged;
  final String hintText;

  const SearchWidget({
    Key? key,
    required this.text,
    required this.onChanged,
    required this.hintText,
  }) : super(key: key);

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

class _SearchWidgetState extends State<SearchWidget> {
  final controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    final styleActive = TextStyle(color: Colors.black);
    final styleHint = TextStyle(color: Colors.black54);
    final style = widget.text.isEmpty ? styleHint : styleActive;

    return Container(
      height: 42,
      margin: const EdgeInsets.fromLTRB(16, 16, 16, 16),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(12),
        color: Colors.white,
        border: Border.all(color: Colors.black26),
      ),
      padding: const EdgeInsets.symmetric(horizontal: 8),
      child: TextField(
        controller: controller,
        decoration: InputDecoration(
          icon: Icon(Icons.search, color: style.color),
          suffixIcon: widget.text.isNotEmpty
              ? GestureDetector(
            child: Icon(Icons.close, color: style.color),
            onTap: () {
              controller.clear();
              widget.onChanged('');
              FocusScope.of(context).requestFocus(FocusNode());
            },
          )
              : null,
          hintText: widget.hintText,
          hintStyle: style,
          border: InputBorder.none,
        ),
        style: style,
        onChanged: widget.onChanged,
      ),
    );
  }
}

Upvotes: 1

Related Questions