searchable_dropdown icon indicating copy to clipboard operation
searchable_dropdown copied to clipboard

Hello Search option not working

Open atta1234 opened this issue 4 years ago • 21 comments

Hello sir i have used your provided solution and the search still not working

import 'package:flutter/material.dart';
// import 'package:foodfromforeign1/models/country.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:searchable_dropdown/searchable_dropdown.dart';

void main() => runApp( MyApp());

class Country{
  String name;
  int id;
  Country(this.name,this.id);
  toString(){
    return(name);
  }
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return  MaterialApp(
      title: 'Flutter Demo',
      theme:  ThemeData(
        primarySwatch: Colors.red,
      ),
      home:  MyHomePage(title: 'Users'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {

static final String countriesJson = '[{"id":0,"name":"Afghanistan"},{"id":1,"name":"Albania"},{"id":2,"name":"Algeria"},{"id":3,"name":"Angola"}]';
List<Country> countries;
List<DropdownMenuItem<Country>> countriesDropdownItems;
Country selectedCountry;


    @override
  void initState() {
    super.initState();
   countries=(jsonDecode(countriesJson) as List<dynamic>).map<Country>((e) => Country(e['name'],e['id'])).toList();
    countriesDropdownItems = countries.map<DropdownMenuItem<Country>>((e) => DropdownMenuItem(child:Text(e.name),value:e,)).toList();
    super.initState();
  }

@override
  Widget build(BuildContext context) {
    return  Scaffold(
      appBar:  AppBar(
        title:  Text(widget.title),
      ),
      body:Container(
          padding: EdgeInsets.symmetric(horizontal: 20, vertical: 30),
        child:Column(
         children: <Widget>[
            SearchableDropdown.single(
        items: countriesDropdownItems,
        value: selectedCountry,
        hint: "Select one country",
        searchHint: "Select one country",
        onChanged: (value) {
          setState(() {
            selectedCountry = value;
          });
        },
        isExpanded: true,
      )
         ],

        ),  
      


        
      ),
    );
  
  }
}


atta1234 avatar Apr 20 '20 14:04 atta1234

Hi @atta1234 ,

I copy pasted this example in my main.dart file in the example/lib folder of the searchable_dropdown plugin. I removed the first super.initState();.

I ran on an Android device. I clicked on the widget area. I typed in the search field "gh". Only the "Afghanistan" country appeared.

Do you have something else?

lcuis avatar Apr 20 '20 15:04 lcuis

sir when i print setState(() { print(value); selectedCountry = value; }); value it still print the country name i was expecting id of the country,,

atta1234 avatar Apr 21 '20 06:04 atta1234

Hi @atta1234 ,

As long as you can access the selectedCountry object, you can access the selectedCountry id:

print("selected country id: ${selectedCountry.id}");

In order to avoid getting a null exception when no country is selected, you could do it this way:

print("selected country id: ${selectedCountry?.id??'none selected'}");

lcuis avatar Apr 21 '20 09:04 lcuis

i want to include this all thing in function but then it's not working

List<Country> countries;
List<DropdownMenuItem<Country>> countriesDropdownItems;
Country selectedCountry;

final String url = "http://10.0.2.2/fff/api/allcountries/";
getSWData() async {
   var res = await http .get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
   var resBody = json.decode(res.body);
   setState(() {
    final String countriesJson = resBody as List;
countries=(jsonDecode(countriesJson) as List<dynamic>).map<Country>((e) => Country(e['name'],e['id'])).toList();
   countriesDropdownItems = countries.map<DropdownMenuItem<Country>>((e) => DropdownMenuItem(child:Text(e.name),value:e,)).toList();
   });

}

   @override
 void initState() {
   this.getSWData();
 
   super.initState();
 }

atta1234 avatar Apr 21 '20 09:04 atta1234

Hi @atta1234 ,

Can you tell me what are the symptoms that show that this is not working?

I cannot replicate on my side because I don't have access to this API server.

lcuis avatar Apr 21 '20 10:04 lcuis

Hello sir so finally i manage things with help of your code and got a workable country state city dropdown list, i will post my final code so that can save your time for future users, my last issue when i select country or city i m getting this warning in debug console .
W/IInputConnectionWrapper(25093): getSelectedText on inactive InputConnection W/IInputConnectionWrapper(25093): getTextAfterCursor on inactive InputConnection W/IInputConnectionWrapper(25093): beginBatchEdit on inactive InputConnection W/IInputConnectionWrapper(25093): endBatchEdit on inactive InputConnection

atta1234 avatar Apr 21 '20 14:04 atta1234

Hi @atta1234 ,

Great if it works for you! Thanks for the information.

I'm not familiar with the warnings you shared. Sorry. I hope it will not be an issue for you.

lcuis avatar Apr 21 '20 15:04 lcuis

Hello sir how to implement validation on it, if country is not selected so i want to show the message under that on button press,, and thire is another error appear at sometime error: RangeError (index): Invalid value: Not in range 0..1, inclusive: 2

atta1234 avatar Apr 21 '20 18:04 atta1234

Hi @atta1234 ,

I thought that the answers to two of your last questions (hide clear button and validation) were answered in the readme. Please let me know if this is not the case, not clear enough or if it wasn't your question.

I'm sorry, I think that you will have to solve this RangeError with for example the help of a debugger. I believe in you. I'm sure you can do it.

lcuis avatar Apr 21 '20 19:04 lcuis

i don't see validation part in read me guide,,and RangeError (index): Invalid value: Not in range 0..1, inclusive: 2 appear sometime so i m not sure what's the case ,i think this is the last help and i m done with flutter

atta1234 avatar Apr 21 '20 19:04 atta1234

this is the complete error Exception caught by widgets library ═══════════════════════════════════ The following RangeError was thrown building SearchableDropdown<City>(dirty, dependencies: [_LocalizationsScope-[GlobalKey#c42ed], Directionality, _InheritedTheme], state: _SearchableDropdownState<City>#4c267): RangeError (index): Invalid value: Not in range 0..2, inclusive: 3

The relevant error-causing widget was SearchableDropdown<City> lib\api\country_api.dart:128 When the exception was thrown, this was the stack #0 List.[] (dart:core-patch/growable_array.dart:149:60) #1 _SearchableDropdownState.build. package:searchable_dropdown/searchable_dropdown.dart:520 #2 List.forEach (dart:core-patch/growable_array.dart:285:8) #3 _SearchableDropdownState.build package:searchable_dropdown/searchable_dropdown.dart:517 #4 StatefulElement.build package:flutter/…/widgets/framework.dart:4334 ...

atta1234 avatar Apr 21 '20 20:04 atta1234

Here is the demo sir please have a look ,,the issue appear when i select province but hardly appear and i can't recognize the issue i made a video so you can see it please: https://drive.google.com/file/d/1swNSSCfpD142b0fih5s-OZTb90NoxBgX/view

atta1234 avatar Apr 21 '20 22:04 atta1234

Thanks for sharing the error details and the video @atta1234 . Unfortunately, I can not solve such error remotely even with a video. It could be due to a Future value that is not available at the moment it is supposed to be used. It could be due to a selected value that is not reinitialized at the right moment. It could be something completely different. I could go on with speculations that would probably mainly waste your time and mine.

One thing, though, you may want to try this with the latest version of the plugin which is not yet published to the pub.dev site. To make use of the latest merged version, you can use the following in your pubspec.yaml file:

  searchable_dropdown:
    git:
      url: https://github.com/icemanbsi/searchable_dropdown.git

Last thing, if updating a country updates the list of states, and the list of states is updated from a server (the list of states is a Future). This means that you must handle the situation when the list of states didn't reach you app yet. For example through a progress wheel or through a text saying something like loading.... Ideally, there should be a timeout on this and also a handling of the errors. Even better, if there is an error or a timeout, there should be a solution for the user to retry for example through a button. Does this make sense? If you wanted to simulate a longer duration to retrieve the data from the server to see how you app reacts in more normal or extreme situations, you could add an artificial delay before the http call in your update functions.

I wish you luck with that.

lcuis avatar Apr 22 '20 03:04 lcuis

Hello sir thanks you were right ,future was not reaching some time i solved it with this line of code if(res.statusCode==200){ var resBody = (res.body); setState(() { final String cetiesJson = resBody; ceties=(jsonDecode(cetiesJson) as List).map<City>((d) => City(d['name'],d['id'])).toList(); cetiesDropdownItems = ceties.map<DropdownMenuItem<City>>((d) => DropdownMenuItem(child:Text(d.name),value:d,)).toList(); }); }else{ City selectedCity; } but you did not tell me validation part where is the mention in documentaion

atta1234 avatar Apr 22 '20 08:04 atta1234

i have place the package like this searchable_dropdown: git: url: https://github.com/icemanbsi/searchable_dropdown.git and installation show error

atta1234 avatar Apr 22 '20 08:04 atta1234

Hi @atta1234 ,

Great if it works.

You should be able to find the validation part in the readme file by looking for "validator".

For the installation error, I should mention that you need to mind the indentation and you need to run the command flutter packages upgrade .

lcuis avatar Apr 22 '20 08:04 lcuis

new package casing build fail Launching lib\main.dart on sdk gphone x86 in debug mode... e: C:\src\flutter.pub-cache\git\searchable_dropdown-799d871b6f82b121957ae63106156f556a7830f4\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (12, 14): Redeclaration: SearchableDropdownPlugin e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.3\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (12, 14): Redeclaration: SearchableDropdownPlugin

FAILURE: Build failed with an exception.

  • What went wrong: Execution failed for task ':searchable_dropdown:compileDebugKotlin'.

Compilation error. See log for more details

  • Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

atta1234 avatar Apr 22 '20 09:04 atta1234

Hello sit that issue still exist, RangeError (index): Invalid value: Not in range 0..1, inclusive: 2 The relevant error-causing widget was SearchableDropdown<City> only happens with this city dropdown not for province or country ,, i m worrying why that happen only for city dropdown ,,

atta1234 avatar Apr 23 '20 09:04 atta1234

i have also did this items: cetiesDropdownItems??[], but still same issue occur sometime

atta1234 avatar Apr 23 '20 09:04 atta1234

sir waiting fro you to sovle my issue please here is my full code tried everything even future builder clear list etc,

`import 'package:flutter/material.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:foodfromforeign1/models/Country.dart';
import 'package:searchable_dropdown/searchable_dropdown.dart';


class Province{
  String name;
  int id;
  Province(this.name,this.id);
  toString(){
    return(name);
  }
}





class City{
  String name;
  int id;
  City(this.name,this.id);
  toString(){
    return(name);
  }
}


class CountryApi extends StatefulWidget {
  CountryApi({Key key}) : super(key: key);
  @override
  _CountryApiState createState() => _CountryApiState();
}

class _CountryApiState extends State<CountryApi> {
  //get countries
  final String url = "http://10.0.2.2/fff/api/allcountries/";
 List<Country> countries;
List<DropdownMenuItem<Country>> countriesDropdownItems=[];
Country selectedCountry;
  Future<String> getSWData() async {
    var res = await http .get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
    var resBody = (res.body);
    setState(() {
     final String countriesJson = resBody;
 countries=(jsonDecode(countriesJson) as List<dynamic>).map<Country>((e) => Country(e['name'],e['id'])).toList();
    countriesDropdownItems = countries.map<DropdownMenuItem<Country>>((e) => DropdownMenuItem(child:Text(e.name),value:e,)).toList();
    });
    return 'sucess';
  }

//get province
final String urlstates = "http://10.0.2.2/fff/api/state/";
 List<Province> provinces=[];
List<DropdownMenuItem<Province>> provincesDropdownItems=[];
Province selectedProvince;
  Future<String> getprovincesData(id) async {
    var res = await http .get(Uri.encodeFull(urlstates+id.toString()), headers: {"Accept": "application/json"});
    var resBody = (res.body);
    setState(() {
     final String provincessJson = resBody;
 provinces=(jsonDecode(provincessJson) as List<dynamic>).map<Province>((f) => Province(f['name'],f['id'])).toList();
    provincesDropdownItems = provinces.map<DropdownMenuItem<Province>>((f) => DropdownMenuItem(child:Text(f.name),value:f,)).toList();
    });
    return 'sucess';
 }
 

//get city
Future _city;
final String urlcity = "http://10.0.2.2/fff/api/city/";
 List<City> ceties=[];
List<DropdownMenuItem<City>> cetiesDropdownItems=[];
City selectedCity;
  Future<String> getcitydata(id) async {
    var res = await http .get(Uri.encodeFull(urlcity+id.toString()), headers: {"Accept": "application/json"});
    var resBody = (res.body);
   if(res.statusCode==200){ 
    setState(() {  
     final String cityJson = resBody;
 ceties=(jsonDecode(cityJson) as List<dynamic>).map<City>((f) => City(f['name'],f['id'])).toList();
   // cetiesDropdownItems = ceties.map<DropdownMenuItem<City>>((f) => DropdownMenuItem(child:Text(f.name),value:f,)).toList();
    });
   }
   else{
    return 'internet is not working';
   }
    return 'sucess';
 }
 

 




 @override
     void initState() {
    this.getSWData();
    super.initState();
  }
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(10),
      child:Column(
      children: <Widget>[
           //Text('SEND DEAL TO YOUR FRIEND AND FAMILY RIGHT NOW',style: TextStyle(fontSize:20,fontWeight: FontWeight.bold,color:Colors.redAccent),),

         SearchableDropdown.single(
        items: countriesDropdownItems,
        value: selectedCountry,
        hint: "Select one country",
        searchHint: "Select one country",
        onChanged: (value) {
          setState(() {
            selectedCountry = value;
             provinces=null;
            selectedProvince =null;
               ceties=null;
            selectedCity =null;
            this.getprovincesData(value.id);
          });
        },
        isExpanded: true,
      ),
         

        SearchableDropdown.single(
        items: provincesDropdownItems,
        value: selectedProvince,
        hint: "Select one State",
        searchHint: "Select one State",
        onChanged: (value) {
          setState(() {
            selectedProvince = value;
            ceties=null;
            selectedCity =null;
           _city=getcitydata(value.id);
          });
        },
        isExpanded: true,
      ),





FutureBuilder(
    future:_city,
    builder: (context, projectSnap) {
      if (projectSnap.connectionState == ConnectionState.none &&
          projectSnap.hasData == null) {
        return Text('Loading');
      }else{
      return(
       SearchableDropdown.single(
       items: ceties?.map((data) => DropdownMenuItem<City>(
                child: Text(data.name),
                value: data,
              ))?.toList()??[],
        hint: "Select one City",
        searchHint: "Select one City",
        onChanged: (value) {
          setState(() {
            selectedCity =value;
            print(selectedCity.id);
          });
        },
        isExpanded: true,
      )
      );
    }
    }
  )

      //  FutureBuilder(
      //  future:getcitydata(1), 
      // SearchableDropdown.single(
      //   items: cetiesDropdownItems,
      //   value: selectedCity,
      //   hint: "Select one City",
      //   searchHint: "Select one City",
      //   onChanged: (value) {
      //     setState(() {
      //       selectedCity = value;
      //     });
      //   },
      //   isExpanded: true,
      // ),)
      
//    InkWell(
//   onTap: () {
   
//   },
//   child:  Container(
//     //width: 100.0,
//     height: 50.0,
//     decoration:  BoxDecoration(
//       color: Colors.redAccent,
//       border:  Border.all(color: Colors.white, width: 2.0),
//       borderRadius:  BorderRadius.circular(10.0),
//     ),
//     child:  Center(child:  Text('Search  DEAL', style:  TextStyle(fontSize: 18.0, color: Colors.white),),),
//   ),
// ),


         ],

        )
        );
    
    
 


      
  }
}

`

atta1234 avatar Apr 23 '20 21:04 atta1234

u have replace the flutter normal dropdown list ,with last city dropdown, and that error gone return( Expanded( child:DropdownButton( items: ceties?.map((data) => DropdownMenuItem<City>( child: Text(data.name), value: data, ))?.toList()??[], hint: Text(selectedCity.toString() ?? 'Please choose a location'),

    onChanged: (value) {
      setState(() {
        selectedCity =value;
        print(selectedCity.id);
      });
    },
    isExpanded: true,
  )
  )
  );

so the hack is in the plugin i think

atta1234 avatar Apr 23 '20 22:04 atta1234