├── README.md
├── examples
└── my-custom-tag-manager.jsx
├── tag-manager.css
└── tag-manager.jsx
/README.md:
--------------------------------------------------------------------------------
1 | # React Tag Manager
2 | React Tag Manager is a React plugin for implementing tagging system easily with React.
3 |
4 | # Features
5 | * Autocomplete
6 | * Dynamic creating/deleting
7 |
8 | # Demo
9 | http://howtomakeaturn.github.io/react-tag-manager/
10 |
11 | # Getting Started
12 | To use the tag manager plugin, include the react library, the JSX transformer, and the react-tag-manager library inside the tag of your HTML document:
13 |
14 | ```html
15 |
16 |
17 |
18 |
19 |
20 |
21 | ```
22 |
23 | Tell tag manager what's the initial tags and options for autocomplete:
24 | ```jsx
25 |
44 | ```
45 | We done! The live demo is here: [Basic example](http://howtomakeaturn.github.io/react-tag-manager/)
46 |
47 | # Advanced
48 |
49 | Usually you need to send an ajax or do some other things after user creating/deleting tags. Tag manager support this with callback functions in composition components.
50 |
51 | Simply create your own component with callback functions for creating/deleting, and then render TagManager with [JSX spread attributes](http://facebook.github.io/react/docs/jsx-spread.html).
52 |
53 | ```jsx
54 | /** @jsx React.DOM */
55 |
56 | var MyCustomTagManager = React.createClass({
57 |
58 | addTagCallback: function(tagName, setStateCallback){
59 | alert('Add a tag! Maybe you should send an ajax!');
60 | setStateCallback({id: 99, name: tagName});
61 | },
62 |
63 | removeTagCallback: function(tag){
64 | alert('Remove a tag! Maybe you should send an ajax!');
65 | },
66 |
67 | render: function(){
68 | return(
69 |
70 | )
71 | }
72 |
73 | });
74 |
75 | ```
76 | To render the customized tag manager, it's the same as the original one:
77 | ```jsx
78 | /** @jsx React.DOM */
79 |
80 | var tags = [
81 | { name: 'Jack', id: 1},
82 | { name: 'Betty', id: 2},
83 | { name: 'Kelly', id: 3},
84 | ];
85 |
86 | var tagOptions = [
87 | 'apple',
88 | 'banana',
89 | 'cat'
90 | ];
91 |
92 | React.renderComponent(
93 | ,
94 | document.getElementById('advanced-tag-manager')
95 | );
96 | ```
97 |
98 |
99 | The live demo is here: [Custom tag manager example](http://howtomakeaturn.github.io/react-tag-manager/)
100 |
--------------------------------------------------------------------------------
/examples/my-custom-tag-manager.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx React.DOM */
2 |
3 | var MyCustomTagManager = React.createClass({
4 |
5 | addTagCallback: function(tagName, setStateCallback){
6 | alert('Add a tag! Maybe you should send an ajax!');
7 | setStateCallback({id: 99, name: tagName});
8 | /*
9 | $.ajax({
10 | url: "/tag/add",
11 | method: 'post',
12 | data: { name: tagName },
13 | success: function(res){
14 | setStateCallback(res.tag);
15 | }
16 | });
17 | */
18 | },
19 |
20 | removeTagCallback: function(tag){
21 | alert('Remove a tag! Maybe you should send an ajax!');
22 | /*
23 | $.ajax({
24 | url: "/tag/remove",
25 | method: 'delete',
26 | data: { id: tag.id },
27 | });
28 | */
29 | },
30 |
31 | render: function(){
32 | return(
33 |
34 | )
35 | }
36 |
37 | });
38 |
--------------------------------------------------------------------------------
/tag-manager.css:
--------------------------------------------------------------------------------
1 | .react-tag-add-component{
2 | display: inline-block;
3 | }
4 | .react-tag-add-input{
5 | width: 210px;
6 | }
7 | .react-tag-option{
8 | background-color: white;
9 | padding: 5px;
10 | margin: 0;
11 | width: 200px;
12 | cursor: pointer;
13 | }
14 | .react-tag-option:hover{
15 | background-color: lightgrey;
16 | }
17 | .react-tag-option-container{
18 | position: absolute;
19 | border: 1px solid grey;
20 | }
21 | .react-tag{
22 | border-radius: 5px;
23 | padding: 5px;
24 | margin: 5px;
25 | background-color: #2EB8E6;
26 | color: white;
27 | cursor: pointer;
28 | }
29 |
--------------------------------------------------------------------------------
/tag-manager.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx React.DOM */
2 |
3 | var TagOption = React.createClass({
4 |
5 | onClick: function(){
6 | this.props.addTag(this.props.value);
7 | this.props.closeInput();
8 | },
9 |
10 | render: function(){
11 | return (
12 |
13 | {this.props.value}
14 |
15 | );
16 | }
17 | });
18 |
19 | var AddTagComponent = React.createClass({
20 |
21 | componentDidMount: function(){
22 | document.addEventListener("keydown", function (e) {
23 | if ( (this.props.showInput) && (e.keyCode === 27) ){
24 | this.props.closeInput();
25 | }
26 | }.bind(this));
27 |
28 | document.addEventListener("click", function (e) {
29 | if( this.props.showInput && (e.target !== this.refs.input.getDOMNode()) ){
30 | this.props.closeInput();
31 | }
32 | }.bind(this));
33 |
34 | },
35 |
36 | componentDidUpdate: function(){
37 | if (this.props.showInput){
38 | this.refs.input.getDOMNode().focus();
39 | }
40 | },
41 |
42 | onKeyDown: function(e){
43 | if (e.keyCode === 13){
44 | if (this.refs.input.getDOMNode().value === ''){
45 |
46 | } else {
47 | this.props.addTag(this.refs.input.getDOMNode().value);
48 | this.refs.input.getDOMNode().value = '';
49 | this.props.closeInput();
50 | }
51 | }
52 | },
53 |
54 | onClickButton: function(e){
55 | // Using stopImmediatePropagation rather than stopPropagation is kind of ugly.
56 | // But since the current button is disappearing at the same time, it's not easy
57 | // to figure out which element is the parent element.
58 |
59 | e.nativeEvent.stopImmediatePropagation();
60 | this.props.openInput();
61 | },
62 |
63 | render: function(){
64 |
65 | if (this.props.showInput){
66 | var tagOptions = [];
67 | for(var i in this.props.tagOptions){
68 | tagOptions.push();
69 | }
70 |
71 | return (
72 |