Skip to content

Instantly share code, notes, and snippets.

@wmucheru
Last active May 9, 2019 12:36
Show Gist options
  • Save wmucheru/8ca61a8378dfcd2449f58ffb8d228e52 to your computer and use it in GitHub Desktop.
Save wmucheru/8ca61a8378dfcd2449f58ffb8d228e52 to your computer and use it in GitHub Desktop.
React Tags Input component. Used in multiple emails/tags entry
import React, { Component } from 'react';
export default class TagsInput extends Component{
constructor(props){
super(props);
this.state = {
tags: []
};
}
handleKeyDown = (e) => {
const { keyCode, target } = e;
const { tags } = this.state;
const { name, onTagsUpdate } = this.props;
let newTag = target.value;
if(keyCode === 13){
if(newTag !== '' /* && isEmailAddress(newTag) */){
tags.push(newTag);
target.value = '';
this.setState({ tags }, ()=>{ onTagsUpdate(name, tags) });
}
else{
alert('Enter a valid email address');
}
e.preventDefault();
return false;
}
if(keyCode === 8 && newTag === '' && tags.length > 0){
let removed = tags.pop();
this.setState({ tags }, ()=>{ onTagsUpdate(name, tags) });
}
}
removeTag = (e) => {
e.preventDefault();
const { tags } = this.state;
tags.pop();
this.setState({ tags });
}
render(){
const { tags } = this.state;
const { placeholder } = this.props;
return(
<div className="tag-input" onClick={ ()=>{ this.refs.tagInput.focus() } }>
{ tags.length > 0 ?
tags.map((tag, index) => {
return(
<span className="pill" key={ index }>
<span className="tag">{ tag }</span>
<a className="remove" onClick={ this.removeTag }>×</a>
</span>
)
})
:
null
}
<input
ref="tagInput"
placeholder={ placeholder }
type="text"
onKeyDown={ this.handleKeyDown }
className="new-tag" />
</div>
);
}
}
/* Style */
.tag-input {
border:solid 1px #ccc;
color:#555;
margin-bottom: 0.8em;
padding:5px 4px 0;
position:relative;
}
.tag-input .pill {
background:#eee;
border:1px solid#bbb;
border-radius:2px;
color:#444;
display:inline-block;
margin:0 5px 5px 0;
padding:0 4px 0 8px;
transition:all .5s ease;
}
.tag-input .pill .remove {
cursor:pointer;
margin-left:4px;
padding:2px;
text-decoration:none;
}
.tag-input .new-tag {
border:none;
padding:3px 2px 5px;
outline:none;
width:auto;
}
/* USAGE */
import React, { Components } from 'react';
import TagsInput from './TagsInput';
class Test extends Component{
constructor(props){
super(props);
this.state = {
myTags: []
};
}
handleTagsUpdate = (name, tags) => {
this.setState({ [name]: tags });
}
render(){
return(
<div>
<TagsInput
name="myTags"
placeholder="Enter email and press ENTER..."
onTagsUpdate={ this.handleTagsUpdate } />
</div>
);
}
}
@wmucheru
Copy link
Author

Dead simple component to help you with multiple email/tag entry, see screenshot below:

screen shot 2017-12-29 at 13 34 31

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment