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

Is it possible to get the value of the typed search string ? #122

Open
kfchengkf opened this issue Mar 22, 2021 · 7 comments
Open

Is it possible to get the value of the typed search string ? #122

kfchengkf opened this issue Mar 22, 2021 · 7 comments

Comments

@kfchengkf
Copy link

Hi,

I would like to know it it is possible to check if the current typed string matches anything.
If no, then I would enable a button which can get the current typed search string,
(so that I can further process it, e.g. create a new item based on the typed search string).

Thanks.

@lcuis
Copy link
Collaborator

lcuis commented Mar 22, 2021

Hello @kfchengkf ,

You can use searchFn argument.
Here is an example with search_choices plugin but it should work the same with searchable_dropdown plugin:

SearchChoices.multiple(
        items: items,
        selectedItems: selectedItemsMultiCustomDisplayDialog,
        onChanged: (value) {
          setState(() {
            selectedItemsMultiCustomDisplayDialog = value;
          });
        },
        searchFn: (String keyword, items) {
          print("Typed keyword: $keyword");
          List<int> ret = [];
          if (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++;
              });
            });
          }
          if (keyword.isEmpty) {
            ret = Iterable<int>.generate(items.length).toList();
          }
          return (ret);
        },
        isExpanded: true,
      )

@kfchengkf
Copy link
Author

Hi locus,
Is it possible to customize either the done button or the close button to reference the typed search string, as mentioned previously, such that if the search string doesn't match, the button would be enabled and, when clicked, open a new widget with the search string in one field, and the user able to enter values for other fields ?

@lcuis
Copy link
Collaborator

lcuis commented Mar 22, 2021

The UI must propose to the user the addition of an object to the list in case the keyword doesn’t match?

@kfchengkf
Copy link
Author

No. Only the field to be search should be added. The search field is the name of the object. If it doesn't exist, I can call the "Close" button that popup another screen with the name field preset. Other fields can then be edited on this screen too.
I wonder if a "global" variable is needed to save the typed string in the searchFn, and then checked in the "Close" button function.

@lcuis
Copy link
Collaborator

lcuis commented Mar 23, 2021

Hi @kfchengkf ,

I believe that the following code does what you are asking for. If not, I apologize for my misunderstanding.

search_choices-add_missing_keyword

  List<DropdownMenuItem> editableItems = [];
  final _formAddMissingKey = GlobalKey<FormState>();
  final _fieldAddMissingKey = GlobalKey<FormFieldState>();
  String inputString = "";
  List<int> selectedItemsMultiAddMissingDialog = [];
  List<DropdownMenuItem> editableItems = [];
  bool multiAddMissingDialogPropose=false;
  String multiAddMissingDialogProposeKeyword="";

...
  addItemDialogWithProposal(String proposal) async {
    return await showDialog(
      context: MyApp.navKey.currentState?.overlay?.context ?? context,
      builder: (BuildContext alertContext) {
        return (AlertDialog(
          title: Text("Add an item"),
          content: Form(
            key: _formAddMissingKey,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                TextFormField(
                  key: _fieldAddMissingKey,
                  validator: (value) {
                    return ((value?.length ?? 0) < 6
                        ? "must be at least 6 characters long"
                        : null);
                  },
                  initialValue: proposal,
                  onChanged: (value) {
                    inputString = value;
                  },
                  onSaved: (value){
                    inputString = value!;
                  },
                  autofocus: true,
                ),
                TextButton(
                  onPressed: () {
                    if (_formAddMissingKey.currentState?.validate() ?? false) {
                      _fieldAddMissingKey.currentState?.save();
                      setState(() {
                        editableItems.add(DropdownMenuItem(
                          child: Text(inputString),
                          value: inputString,
                        ));
                      });
                      Navigator.pop(alertContext, inputString);
                    }
                  },
                  child: Text("Ok"),
                ),
                TextButton(
                  onPressed: () {
                    Navigator.pop(alertContext, null);
                  },
                  child: Text("Cancel"),
                ),
              ],
            ),
          ),
        ));
      },
    );
  }
...
SearchChoices.multiple(
        items: editableItems,
        selectedItems: selectedItemsMultiAddMissingDialog,
        onChanged: (value) {
          setState(() {
            selectedItemsMultiAddMissingDialog = value;
          });
        },
        searchFn: (String keyword, items) {
          List<int> ret = [];
          if (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++;
              });
            });
          }
          if (keyword.isEmpty) {
            ret = Iterable<int>.generate(items.length).toList();
          }
          multiAddMissingDialogPropose=ret.length==0;
          multiAddMissingDialogProposeKeyword=keyword;
          return (ret);
        },
        isExpanded: true,
        disabledHint: (Function updateParent) {
          return (TextButton(
            onPressed: () {
              addItemDialogWithProposal("").then((value) async {
                if (value != null) {
                  selectedItemsMultiAddMissingDialog = [0];
                  updateParent(selectedItemsMultiAddMissingDialog);
                }
              });
            },
            child: Text("No choice, click to add one"),
          ));
        },
        closeButton: (List<int> values, BuildContext closeContext,
            Function updateParent) {
          return (editableItems.length >= 100||!multiAddMissingDialogPropose
              ? SizedBox.shrink()
              : TextButton(
            onPressed: () {
              addItemDialogWithProposal(multiAddMissingDialogProposeKeyword).then((value) async {
                if (value != null) {
                  int itemIndex = editableItems
                      .indexWhere((element) => element.value == value);
                  if (itemIndex != -1) {
                    selectedItemsMultiAddMissingDialog.add(itemIndex);
                    Navigator.pop(
                        MyApp.navKey.currentState?.overlay?.context ??
                            context);
                    updateParent(selectedItemsMultiAddMissingDialog);
                  }
                }
              });
            },
            child: Text("Add and select item"),
          ));
        },
      );
...

Note that I didn't try this with plugin searchable_dropdown but with search_choices. Maybe this works with both?

@kfchengkf
Copy link
Author

Hi Icuis,
Yes, exactly.
Thanks

@lcuis
Copy link
Collaborator

lcuis commented Mar 23, 2021

You’re welcome @kfchengkf !

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

2 participants