GithubHelp home page GithubHelp logo

Comments (5)

panuavakul avatar panuavakul commented on August 22, 2024

Hey @PashaTurok , it is certainly very possible. The TagEditor does expose a tagBuilder that you can use to build your own Tag. Please check out the final section in the Readme for information on building your own tag.

from material_tag_editor.

PavelTurk avatar PavelTurk commented on August 22, 2024

@panuavakul Thank you for your answer. I am trying to implement solution and I almost did it. The only problem is that it always deletes the last tag, but not the one which I choose.

This is the complete code:


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

import 'package:material_tag_editor/tag_editor.dart';

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<String> _values = [];
  final FocusNode _focusNode = FocusNode();
  final TextEditingController _textEditingController = TextEditingController();

  _onDelete(index) {
    setState(() {
      print(this._values);
      print("deleting:" + index.toString());
      _values.removeAt(index);
      print(this._values);
    });
  }

  /// This is just an example for using `TextEditingController` to manipulate
  /// the the `TextField` just like a normal `TextField`.
  _onPressedModifyTextField() {
    final text = 'Test';
    _textEditingController.text = text;
    _textEditingController.value = _textEditingController.value.copyWith(
      text: text,
      selection: TextSelection(
        baseOffset: text.length,
        extentOffset: text.length,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title ?? ''),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: ListView(
            children: <Widget>[
              TagEditor(
                length: _values.length,
                controller: _textEditingController,
                focusNode: _focusNode,
                delimiters: [',', ' '],
                hasAddButton: true,
                resetTextOnSubmitted: true,
                // This is set to grey just to illustrate the `textStyle` prop
                textStyle: const TextStyle(color: Colors.grey),
                onSubmitted: (outstandingValue) {
                  setState(() {
                    _values.add(outstandingValue);
                  });
                },
                inputDecoration: const InputDecoration(
                  border: InputBorder.none,
                  hintText: 'Hint Text...',
                ),
                onTagChanged: (newValue) {
                  setState(() {
                    _values.add(newValue);
                  });
                },
                tagBuilder: (context, index) => _Chip(
                  index: index,
                  label: _values[index],
                  onDeleted: _onDelete,
                ),
                // InputFormatters example, this disallow \ and /
                inputFormatters: [
                  FilteringTextInputFormatter.deny(RegExp(r'[/\\]'))
                ],
              ),
              const Divider(),
              // This is just a button to illustrate how to use
              // TextEditingController to set the value
              // or do whatever you want with it
              ElevatedButton(
                onPressed: _onPressedModifyTextField,
                child: const Text('Use Controlelr to Set Value'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _Chip extends StatefulWidget {
  const _Chip({
    required this.label,
    required this.onDeleted,
    required this.index,
    Key? key,
  }): super(key: key);

  final String label;
  final ValueChanged<int> onDeleted;
  final int index;

  @override
  _ChipState createState() => _ChipState(label:this.label, onDeleted: this.onDeleted, index: this.index);
}

class _ChipState extends State<_Chip> {
  _ChipState({
    required this.label,
    required this.onDeleted,
    required this.index,
  });

  final String label;
  final ValueChanged<int> onDeleted;
  final int index;
  bool _deleteState = false;

  @override
  Widget build(BuildContext context) {
    return  Wrap(
      children: <Widget>[
        Container(
          padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
          decoration: BoxDecoration(
            color: Color(0xffDBDBDB),
            shape: BoxShape.rectangle,
            borderRadius: BorderRadius.circular(20.0),
          ),
          child: Wrap(
            alignment: WrapAlignment.center,
            crossAxisAlignment: WrapCrossAlignment.center,
            runSpacing: 10,
            children: <Widget>[
              if (!this._deleteState)
                CircleAvatar(
                  radius: 18,
                  backgroundImage: NetworkImage("https://i.pravatar.cc/150?img=3"),
                  backgroundColor: Colors.white,
                )
              else
                Padding(
                  padding: const EdgeInsets.all(9.0),
                  child: InkWell(
                    onTap: () {
                      this.onDeleted(this.index);
                    },
                    child: Icon(
                      Icons.close, size: 18,
                    ),
                  ),
                ),
              //Padding(padding: const EdgeInsets.all(5.0)),
              InkWell(
                  onTap: () {
                    this.setState(() {
                      this._deleteState = !this._deleteState;
                    });
                  },
                  child: Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 10),
                    child: Text(this.label, style: TextStyle(fontSize: 16),),
                  )
              ),
            ],
          ),
        )
      ],
    );
  }
}

And this is example. I have entered 4 tags and want the delete the second one ("bbb"), so I tap on the tag title:
Screenshot from 2022-12-09 12-13-06

Now I tap on close button. This is log (from : _onDelete method)

I/flutter ( 6223): [aaa, bbb, ccc, ddd]
I/flutter ( 6223): deleting:1
I/flutter ( 6223): [aaa, ccc, ddd]

And this is the result:
Screenshot from 2022-12-09 12-13-36

As we see from the log _values are correct - "bbb" was deleted. But on the screen we see a different picture.

Could anyone say how to solve this problem?

from material_tag_editor.

PavelTurk avatar PavelTurk commented on August 22, 2024

@panuavakul Any ideas?

from material_tag_editor.

panuavakul avatar panuavakul commented on August 22, 2024

Hey @PashaTurok , can you try adding an unique ObjectKey to your _Clip?
Maybe something like this?

tagBuilder: (context, index) => _Chip(
  key: ObjectKey('${_values[index]}-$index')
  index: index,
  label: _values[index],
  onDeleted: _onDelete,
),

from material_tag_editor.

PavelTurk avatar PavelTurk commented on August 22, 2024

@panuavakul Thank you for your help.

from material_tag_editor.

Related Issues (19)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.