icemanbsi / searchable_dropdown

MIT License
107 stars 162 forks source link

Add a way to change the selected item without selecting through the dropdown #85

Closed flikkr closed 4 years ago

flikkr commented 4 years ago

There is no way to set the selected item programmatically.

chaiyifam commented 4 years ago

Okay, i already done this with my code and this work. :)

flikkr commented 4 years ago

Can you elaborate? this is what I am doing in my code and for some reason it does not appear.

class CountryDropdown extends StatefulWidget {
  final Function(Country) onChanged;
  final Country initalValue;

  CountryDropdown({Key key, this.onChanged, this.initalValue})
      : super(key: key);

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

class _CountryDropdownState extends State<CountryDropdown> {
  Country _country;
  String _preselectedValue;

  Map countries = [
    {'name': 'United States', 'alpha2Code': 'US'},
    {'name': 'United Kingdom', 'alpha2Code': 'UK'},
    {'name': 'France', 'alpha2Code': 'FR'},
  ];

  @override
  void initState() {
    _country = widget.initalValue;
    _preselectedValue = _country?.name;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: SearchableDropdown.single(
        hint: Text('Country'),
        isExpanded: true,
        value: _preselectedValue,
        onChanged: (val) {
          if (val == null) return;
          setState(() {
            _country = Country(
              name: val['name'],
              alpha2Code: val['alpha2Code'],
            );
            widget.onChanged(_country);
          });
        },
        items: countries.all
            .map(
              (country) => DropdownMenuItem(
                value: country,
                child: Expanded(
                   child: Text(
                      country['name'],
                      overflow: TextOverflow.visible,
                      style: TextStyle(fontSize: 18.0),
                    ),
                  ),
                ),
              ),
            )
            .toList(),
      ),
    );
  }
}
chaiyifam commented 4 years ago
class CountryDropdown extends StatefulWidget {
  final Function(Country) onChanged;
  final Country initalValue;

  CountryDropdown({Key key, this.onChanged, this.initalValue})
      : super(key: key);

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

class _CountryDropdownState extends State<CountryDropdown> {
  Country _country;
  String _preselectedValue;

  Map countries = [
    {'name': 'United States', 'alpha2Code': 'US'},
    {'name': 'United Kingdom', 'alpha2Code': 'UK'},
    {'name': 'France', 'alpha2Code': 'FR'},
  ];

  @override
  void initState() {
    _country = widget.initalValue;
    _preselectedValue = _country?.name; //index of ?, the code cannot execute this properly, dont initial in here because cant get a item data from u dropdownitem.
    super.initState();
  }

@override
  Widget build(BuildContext context) {
    return Container(
      child: SearchableDropdown.single(
        hint: Text('Country'),
        isExpanded: true,
        value: _preselectedValue,
        onChanged: (val) { //because here, the code just appear when u change the value in the dropdown value.
          if (val == null) return;
          setState(() {
            _country = Country(
              name: val['name'],
              alpha2Code: val['alpha2Code'],
            );
            widget.onChanged(_country);
          });
        },
        items: countries.all
            .map(
              (country) => DropdownMenuItem(
                value: country,
                child: Expanded(
                   child: Text(
                      country['name'],
                      overflow: TextOverflow.visible,
                      style: TextStyle(fontSize: 18.0),
                    ),
                  ),
                ),
              ),
            )
            .toList(),
      ),
    );
chaiyifam commented 4 years ago

idonnu, u mean abaout change item without selectitem is like mine, or select the first value. my case, get data id customer from other screen. lololo

flikkr commented 4 years ago

I mean set the value of the dropdown with a specific value when I create it, like it shows in you GIF. For example, in this code the dropdown is showing the hint but not the value defined in the variable preselectedValue.

import 'package:flutter/material.dart';
import 'package:searchable_dropdown/searchable_dropdown.dart';

class DemoPage extends StatefulWidget {
  @override
  _DemoPageState createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  String preselectedValue = "dolor sit";

  List<DropdownMenuItem<dynamic>> items = List.generate(
    10,
    (index) => DropdownMenuItem(
      value: 'Item no. $index',
      child: Text('Item no. $index'),
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: SearchableDropdown.single(
        hint: "Select one",
        searchHint: "Select one",
        isExpanded: true,
        value: preselectedValue,
        items: items,
        onChanged: (value) {
          setState(() {
            preselectedValue = value;
          });
        },
      ),
    );
  }
}

The dropdown in this screenshot should show "dolor sit" but it only shows the hint. Screenshot_20200717_171456

chaiyifam commented 4 years ago
import 'package:flutter/material.dart';
import 'package:searchable_dropdown/searchable_dropdown.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: DemoPage(),
    );
  }
}

class DemoPage extends StatefulWidget {
  @override
  _DemoPageState createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  String preselectedValue = "dolor sit";

  List<String> items = [
    "dolor sit",
    "sit",
    "dolor",
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: SearchableDropdown.single(
        isExpanded: true,
        value: preselectedValue,
        items: items
            .map(
              (e) => DropdownMenuItem(
                child: Text(e),
                value: e,
              ),
            )
            .toList(),
        onChanged: (value) {
          setState(() {
            preselectedValue = value;
          });
        },
      ),
    );
  }
}

i fix the code for show the dolor sit, make sure the item is on the value dropitem...

Screenshot_1595003004

flikkr commented 4 years ago

Wow amazing, I managed to fix it thanks to you! I didn't know that the initial value had to be the same as the dropdown item value. Thanks!