Frezyx/group_button

Deselect stops working when controller is added

divan opened this issue · 8 comments

divan commented

Hi, thanks for a great plugin.

I use it in a custom FormBuilderField, and needed a way to initialize selected buttons. It wasn't obvious how to set init values, but eventually I made it by adding GroupButtonController. All worked well until I discovered that deselecting buttons stopped working.

If I remove controller, deselecting works again (but no way to set init values).

Any hints on what can be wrong? Is it a bug or I'm doing something wrong? (maybe there is a way to preselect buttons without controller?)

Hi @divan! Cool nickname 😄
It's hard to understand your case from the description. I have not seen such a mistake yet.
I can help you if you provide an example of your code.

From you description I understand that your situation similar to my when I create TalkerScreenFilter in my another package

divan commented

Okay, I started testing example code, and it worked. so I figure out that it was my mistake – I put controller.selectIndex() into the build() method 🤦

While we here, quick question – is there any way to preselect buttons without controller? It would be really handy to use GroupButton from stateless controllers and be able to init with parameter.

So in my code the class looks like this:

 class MyField extends StatelessWidget {
  MyField({Key? key}) : super(key: key);

  final ctrl = GroupButtonController();

  @override
  Widget build(BuildContext context) {
    return FormBuilderField(
        builder: (FormFieldState<dynamic> field) {
          return GroupButton(
            onSelected: (index, isSelected, _) =>
                print('$index button is selected'),
            buttons: ["12:00", "13:00", "14:30", "18:00", "19:00", "21:40"],
            buttonBuilder: null,
            enableDeselect: true,
            controller: ctrl,
          );
        },
    );
  }
}

FormBuilderField is a class from a form builder library, which simplifies form creation a lot. As a part of this simplification it injects initial values into the fields via some obscure magic (InheritedWidget maybe, I don't know). So the initial value is set automagically and accesible via field param of the builder.

Now, the challenge is how to use that field.value to set initial value of GroupButton's selected buttons. That's where I put controller code into the builder and got this weird behaviour.

I probably need to explore more how to properly init fields in this form builder, but I think having something like value or initialValue in GroupButton would simplify this task a lot. Also will remove the need to have a controller.

divan commented

Still puzzled how to init values in this use case..

So my initial code (the one that broken deselect feature) was:

 class MyField extends StatelessWidget {
  MyField({Key? key}) : super(key: key);

  final ctrl = GroupButtonController();
  final items = ["12:00", "13:00", "14:30", "18:00", "19:00", "21:40"];

  @override
  Widget build(BuildContext context) {
    return FormBuilderField(
        builder: (FormFieldState<dynamic> field) {

          if (field.value != null) ctrl.selectIndex(items.indexOf(field.value)); // <-- this breaks deselecting, but otherwise works as intended

          return GroupButton(
            onSelected: (index, isSelected, _) =>
                print('$index button is selected'),
            buttons: items,
            buttonBuilder: null,
            enableDeselect: true,
            controller: ctrl,
          );
        },
    );
  }
}

You can make MyField StatefulWidget
And write this initialization code in initState

if (field.value != null) ctrl.selectIndex(items.indexOf(field.value));

Didn't notice Formbuilder 🤣

You can raise FormBuilder to a higher level

FormBuilder ->
MyField (StatefullWidget) with initState(){ if (field.value != null) ctrl.selectIndex(items.indexOf(field.value)); } ->
GroupButton

divan commented

You can raise FormBuilder to a higher level

Hmm, not sure I got how to do this.

@Frezyx don't want to steal your time here. so the last question – did the GroupButton API has a selectedButtons property before and then was removed? If so, what was the reasoning for the change? Right now it seems like having inititialValue or selectedButtons field would simplify this common task a lot.