Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sel value programmability #21

Open
lechuk opened this issue Mar 5, 2020 · 13 comments
Open

Sel value programmability #21

lechuk opened this issue Mar 5, 2020 · 13 comments

Comments

@lechuk
Copy link

lechuk commented Mar 5, 2020

I can't set selected value programmability

@lechuk lechuk changed the title Sel value programability Sel value programmability Mar 5, 2020
@lechuk
Copy link
Author

lechuk commented Mar 5, 2020

Fix like this
`
@OverRide
void initState() {
_updateSelectedIndex();
super.initState();
}

void _updateSelectedIndex() {
if (!_enabled) {
return;
}

if (widget.multipleSelection) {
  selectedItems = List<int>.from(widget.selectedItems ?? []);
} else if (widget.value != null) {
  int i = indexFromValue(widget.value);
  if (i != null && i != -1) {
    selectedItems = [i];
  }
}
if (selectedItems == null) selectedItems = [];

}

@OverRide
void didUpdateWidget(SearchableDropdown oldWidget) {
super.didUpdateWidget(oldWidget);
_updateSelectedIndex();
}
`

@ettiennelr
Copy link

Can this change please be made as it will greatly help with setting initial values.

Currently the initial value set does not work when rebuilding a the widget

@lcuis
Copy link
Collaborator

lcuis commented Mar 14, 2020

Hello @lechuk and @ettiennelr ,

Thanks for your feedback.
I am able to set the initial value as follows in the example app:

...
  String preselectedValue="dolor sit";
...
      "Initial value issue21": SearchableDropdown(
        items: items,
        value: preselectedValue,
        hint: Text('Select One'),
        searchHint: new Text(
          'Select One',
          style: new TextStyle(fontSize: 20),
        ),
        onChanged: (value) {
          setState(() {
            selectedValue = value;
          });
        },
        isExpanded: true,
      ),
...

The result is as expected that the selected value is "dolor sit".

Could it be that you are not using the latest version of the plugin?
Because I seem to recognize an old version of the _updateSelectedIndex() function which doesn't exist anymore.

@ettiennelr
Copy link

Hi @lechuk

Thanks for the quick response and btw i LOVE your work on this widget!!

The problem I am experiencing is that I change value on my SearchableDropdown after it was created the first time due to it being reused in a dependent manner.

What I have noticed is that your logic for value gets done inside initState. So if I try and change it again after the first time to another value the change does not get applied. It then causes index error and value does not display as default before opening drop down again.

Hoped this explains it well?

@ettiennelr
Copy link

ettiennelr commented Mar 14, 2020 via email

@lcuis
Copy link
Collaborator

lcuis commented Mar 14, 2020

Hello @ettiennelr ,

Thanks for your explanations. I think I was able to reproduce your issue within the latest plugin:

...
  String preselectedValue="dolor sit";
...
  @override
  Widget build(BuildContext context) {
    Map<String, Widget> widgets;
    widgets = {
...
      "Update value from elsewhere issue21": Column(
        children: [
          SearchableDropdown(
            items: items,
            value: selectedValue,
            hint: Text('Select One'),
            searchHint: new Text(
              'Select One',
              style: new TextStyle(fontSize: 20),
            ),
            onChanged: (value) {
              setState(() {
                selectedValue = value;
              });
            },
            isExpanded: true,
          ),
          FlatButton(
            child: Text("Select $preselectedValue"),
            onPressed: () {
              setState(() {
                selectedValue = preselectedValue;
              });
            },
          ),
        ],
      ),
...

Indeed, pressing the new button doesn't set the value at least on the screen.
I will check your example and whether there is a solution.

@ettiennelr
Copy link

ettiennelr commented Mar 14, 2020 via email

@lcuis
Copy link
Collaborator

lcuis commented Mar 15, 2020

Thank you very much @ettiennelr and @lechuk !

Indeed, calling a restored _updateSelectedIndex() function from the didUpdateWidget function allows update of the selected value from outside the widget.
So, I just applied the solution provided by @lechuk .
The only issues were regressions with the "select all" and "select none" examples which are corrected by using the selectedItems instead of the selectedItemsClose.
Automated tests pass.
I created PR #26 for the correction and asked @icemanbsi for review before he may publish to pub.dev .
My version of the plugin was also affected. I applied the same correction and published to pub.dev through CD.

I hope this solves your issues!

Thanks again!

@ettiennelr
Copy link

ettiennelr commented Mar 15, 2020 via email

@lcuis
Copy link
Collaborator

lcuis commented Mar 15, 2020

My pleasure @ettiennelr .
For the release, this is already published for search_choices and for searchable_dropdown, this depends on @icemanbsi as I cannot publish for him.

@ettiennelr
Copy link

ettiennelr commented Mar 15, 2020 via email

@lcuis
Copy link
Collaborator

lcuis commented Mar 15, 2020

Hello @ettiennelr ,

I believe that with the newer example, the onPressed functions should use selectedItems instead of selectedItemsClosed and selectedItems should be initialized as [].
Though, even with those corrections, indeed, I'm not sure why your example doesn't display the selectedItems as expected.
I'm investigating.

Thanks for reporting this!

lcuis added a commit to lcuis/search_choices that referenced this issue Mar 15, 2020
@lcuis
Copy link
Collaborator

lcuis commented Mar 15, 2020

Hi @ettiennelr ,

Thanks again for raising this concern!

Here is a working example based on yours when using the latest version of search_choices:

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

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}


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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  List<int> selectedItems = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SingleChildScrollView(
        scrollDirection: Axis.vertical,
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new SearchChoices.multiple(
                selectedItems: selectedItems,
                closeButton: (selectedItemsClose, closeContext, Function updateParent) {
                  return Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      RaisedButton(
                          onPressed: () {
                            setState(() {
                              selectedItemsClose.clear();
                              selectedItemsClose.addAll(Iterable<int>.generate(3).toList());
                            });
                            updateParent(selectedItemsClose);
                          },
                          child: Text("Select all")),
                      RaisedButton(
                          onPressed: () {
                            setState(() {
                              selectedItemsClose.clear();
                            });
                            updateParent(selectedItemsClose);
                          },
                          child: Text("Select none")),
                    ],
                  );
                },
                searchFn: (String keyword, items) {
                  List<int> ret = List<int>();
                  if (keyword == null || keyword.isEmpty) {
                    ret = Iterable<int>.generate(items.length).toList();
                  }

                  if (keyword != null && items != null && keyword.isNotEmpty) {
                    keyword.split(" ").forEach((k) {
                      int i = 0;
                      items.forEach((item) {
                        if (k.isNotEmpty &&
                            (item.value.toString().toLowerCase().contains(k.toLowerCase()))) {
                          ret.add(i);
                        }
                        i++;
                      });
                    });
                  }

                  return (ret);
                },
                items: ["ONE", "TWO",
                  "THREE"].map<DropdownMenuItem<String>>((String value) {
                  return DropdownMenuItem<String>(
                    value: value,
                    child: Container(
                      alignment: AlignmentDirectional.centerEnd,
                      child: Text(value.trim(), overflow:
                      TextOverflow.ellipsis, textAlign: TextAlign.right),
                    ),
                  );
                }).toList(),
                onChanged: (value) {
                  setState(() {
                    selectedItems = value;
                  });
                },
                isExpanded: true,
              ),
            ],
          ),
        ),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

I am not certain why the update was not happening in your case. Maybe because it is not in tabs.
Anyway, I added a setState call in the updateParent call to make sure the dialog gets refreshed.

It would be interesting to test with searchable_dropdown which doesn't have the updateParent method.

Anyway, sorry for the inconvenience @ettiennelr and I hope this solves your issue.

icemanbsi added a commit that referenced this issue Mar 31, 2020
Corrected issue #21 to allow selection update from outside the plugin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants