flutter_chips_input icon indicating copy to clipboard operation
flutter_chips_input copied to clipboard

Suggestion create a possibility to add new chips via controller

Open alex89607 opened this issue 5 years ago • 7 comments

Suggestion create a possibility to add new chips via controller(or something like that, by programming way, I meant) because it can be need sometimes for updating widget.

alex89607 avatar Sep 27 '19 12:09 alex89607

This is a great suggestion.

I'll do my best to implement this.

danvick avatar Nov 06 '19 14:11 danvick

@danvick Any work around?

appstute-pratik avatar Feb 27 '20 07:02 appstute-pratik

I was looking for this also. Any idea of when will be implemented?

As workaround i changed the ChipInput class with the addEntryBuilder, and the result its something like this. The text its typed directly in the chip. Needs adjusts, but its just an idea while the package doesn't releases this feature. Hope it helps.

...
typedef EntryBuilder<T> = Widget Function(
    BuildContext context, CustomChipsInputState<T> state);

class ChipsInput<T> extends StatefulWidget {
  ChipsInput({
 ...
    this.addEntryBuilder,
 ...   
  })  : assert(maxChips == null || initialValue.length <= maxChips),
        super(key: key);

 ...  
  final EntryBuilder<T> addEntryBuilder;
 ...  
  @override
  ChipsInputState<T> createState() => ChipsInputState<T>(textOverflow);
}

class ChipsInputState<T> extends State<ChipsInput<T>>
    implements TextInputClient {
 
 ...  
  void addChip(T data) {
    if (widget.enabled) {
      setState(() {
        _chips.add(data);
        _updateTextInputState();
      });
      _initFocusNode();
      widget.onChanged(_chips.toList(growable: false));
    }
  }

 ...  

  @override
  Widget build(BuildContext context) {
    var chipsChildren = _chips
        .map<Widget>((data) => widget.chipBuilder(context, this, data))
        .toList();

    final theme = Theme.of(context);

    chipsChildren.add(
      Container(
        height: 32.0,
        child: Row(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            // Flexible(
            //   flex: 1,
            //   child: Text(
            //     text,
            //     maxLines: 1,
            //     overflow: this.textOverflow,
            //     style: widget.textStyle ??
            //         theme.textTheme.subhead.copyWith(height: 1.5),
            //   ),
            // ),
            Container(child: widget.addEntryBuilder(context, this)),
            Flexible(
              flex: 0,
              child: _TextCaret(
                resumed: _focusNode.hasFocus,
              ),
            ),
          ],
        ),
      ),
    );

 ...  
   
}

And in my page i used the addEntryBuilder like this:

 addEntryBuilder: (context, state) {
                  AppProfile newProfile = AppProfile(state.text, 'email',
                      'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png');

                  if (state.text != null) {
                    return InputChip(
                      key: ObjectKey(newProfile),
                      label: Text(state.text),
                      avatar: CircleAvatar(
                        backgroundImage: NetworkImage(newProfile.imageUrl),
                      ),
                      onPressed: () => state.addChip(newProfile),
                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                    );
                  } else {
                    return Text('');
                  }
                },

JRammos29 avatar Jun 06 '20 03:06 JRammos29

Hi @appstute-pratik, At this point in time, the easiest way to add a chip programmatically is by use of a GlobalKey. Like so:

GlobalKey<ChipsInputState> _chipKey = GlobalKey();
...
ChipsInput(
    key: _chipKey,
    ...
),
_chipKey.currentState.selectSuggestion(chip);
....

danvick avatar Jun 06 '20 20:06 danvick

Sorry for the delay on this guys. Using a ChipsController as I'm planning to will create quite a bit of breaking changes, hence I'm working on this in version 2 of the package which is still in the press.

The reason for the delay is that my schedule is a bit rigid with work stuff (and other opensource projects I'm working on) that I find it hard to react quickly to matters.

Thanks for your understanding, guys.

danvick avatar Jun 06 '20 20:06 danvick

this

Do you have a complete solution for this? I am struggling to implement the same. I need to make http request to database and if data not found then add new.

rayad avatar Jun 07 '20 13:06 rayad

@rayad I created this gist where you can see the code with examples.

I created a flag enabledSuggestions that must be set to false if you don't want to use suggestions.

At the example using object the ideal it's to use a form or a dialog where the user can set the object attributes. The code need some adjusts, but for the purpose of add chips it's working.

You need replace the chip_input.dart with the custom_chip_input.dart (this file use other files from the original flutter_chips_input package if you need to use the suggestions).

JRammos29 avatar Jun 07 '20 14:06 JRammos29