Comments (5)
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.
@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:
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]
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.
@panuavakul Any ideas?
from material_tag_editor.
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.
@panuavakul Thank you for your help.
from material_tag_editor.
Related Issues (19)
- How to change the color of the chips? HOT 1
- how to integrate the tag_editor like drop down? HOT 2
- The pub version requires Widget type Chip HOT 1
- Allow more control over the text box HOT 2
- Allow us to set submit to complete the tag instead of dismissing the keyboard HOT 4
- Expose on TextField valueChanged and onSubmitted HOT 3
- Expose focusNode HOT 1
- Add Github Action for CD
- Figure out a way to remove tag with the backspace keyboard key HOT 3
- Please add controller parameter HOT 2
- Suggestion new features - Min/Max characters of tags HOT 4
- Suggestion new features - Not null tags HOT 1
- inputformatters usage HOT 2
- Why use CustomMultiChildLayout HOT 2
- Textfield chips does not support multilines. HOT 2
- chips displayed below input field. HOT 1
- How to prevent adding empty row at the end? HOT 9
- the value list cant disposed
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from material_tag_editor.