Last active
February 16, 2022 09:58
-
-
Save igorbenic/1df80a183b99e0d434cdfd80b8ee589f to your computer and use it in GitHub Desktop.
Gutenberg Components: Form Token Field (Tags Field) | https://www.ibenic.com/gutenberg-components-form-token-field
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import MyFormTokenField from './components/FormTokenField'; | |
class App extends Component { | |
render() { | |
return ( | |
<div className="App"> | |
<header className="App-header"> | |
<img src={logo} className="App-logo" alt="logo" /> | |
<p> | |
Edit <code>src/App.js</code> and save to reload. | |
</p> | |
<MyFormTokenField /> | |
</header> | |
</div> | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fetchTerms( params = {} ) { | |
const { taxonomy } = this.props; | |
const query = { ...DEFAULT_QUERY, ...params }; | |
const request = apiFetch( { | |
path: addQueryArgs( `/wp/v2/${ taxonomy.rest_base }`, query ), | |
} ); | |
request.then( unescapeTerms ).then( ( terms ) => { | |
this.setState( ( state ) => ( { | |
availableTerms: state.availableTerms.concat( | |
terms.filter( ( term ) => ! find( state.availableTerms, ( availableTerm ) => availableTerm.id === term.id ) ) | |
), | |
} ) ); | |
this.updateSelectedTerms( this.props.terms ); | |
} ); | |
return request; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ... other code | |
class SearchPosts extends React.Component { | |
constructor( props ) { | |
super( props ); | |
this.state = { tokens: [], availablePosts: [] } | |
} | |
render(){ | |
return 'Nothing yet'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ... other code | |
class SearchPosts extends React.Component { | |
constructor( props ) { | |
super( props ); | |
this.searchPosts = this.searchPosts.bind(this); | |
this.state = { tokens: [], availablePosts: [] } | |
} | |
searchPosts( value ) { | |
apiFetch( { path: 'https://www.ibenic.com/wp-json/wp/v2/posts?search=' + value } ).then( posts => { | |
this.setState( ( state ) => ( { | |
availablePosts: state.availablePosts.concat( | |
posts.filter( ( post ) => ! find( state.availablePosts, ( availablePost ) => availablePost.id === post.id ) ) | |
), | |
} ) ); | |
} ); | |
} | |
// ..other code | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ... other code | |
class SearchPosts extends React.Component { | |
constructor( props ) { | |
super( props ); | |
this.savePosts = this.savePosts.bind(this); | |
this.state = { tokens: [], availablePosts: [] } | |
} | |
savePosts( posts ) { | |
if ( typeof( Storage ) !== "undefined" ) { | |
sessionStorage.posts = posts; | |
} | |
this.setState( { tokens: posts } ); | |
} | |
// ..other code | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ... other code | |
class SearchPosts extends React.Component { | |
constructor( props ) { | |
super( props ); | |
this.savePosts = this.savePosts.bind(this); | |
this.state = { tokens: [], availablePosts: [] } | |
} | |
// Retrieving the saved posts titles. | |
componentDidMount() { | |
if ( typeof( Storage ) !== "undefined" ) { | |
if ( sessionStorage.posts ) { | |
let tokens = sessionStorage.posts.split(','); | |
this.setState( { tokens } ); | |
} | |
} | |
} | |
// Saving the post in the local session | |
savePosts( posts ) { | |
if ( typeof( Storage ) !== "undefined" ) { | |
sessionStorage.posts = posts; | |
} | |
this.setState( { tokens: posts } ); | |
} | |
// ..other code | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ... other code | |
class SearchPosts extends React.Component { | |
// .. other code | |
render() { | |
const { tokens, availablePosts } = this.state; | |
let suggestions = []; | |
if ( availablePosts.length ) { | |
suggestions = availablePosts.map( (post) => post.title.rendered ); | |
} | |
return <FormTokenField | |
value={ tokens } | |
suggestions={ suggestions } | |
onChange={ tokens => this.savePosts( tokens ) } | |
onInputChange={ (value) => this.searchPosts( value ) } | |
placeholder="Type a post title" | |
/>; | |
} | |
} | |
export default SearchPosts; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { FormTokenField } from '@wordpress/components'; | |
import apiFetch from '@wordpress/api-fetch'; | |
import { find } from 'lodash'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// function passed to onChange property | |
onChange( termNames ) { | |
const uniqueTerms = uniqBy( termNames, ( term ) => term.toLowerCase() ); | |
this.setState( { selectedTerms: uniqueTerms } ); | |
const newTermNames = uniqueTerms.filter( ( termName ) => | |
! find( this.state.availableTerms, ( term ) => isSameTermName( term.name, termName ) ) | |
); | |
const termNamesToIds = ( names, availableTerms ) => { | |
return names | |
.map( ( termName ) => | |
find( availableTerms, ( term ) => isSameTermName( term.name, termName ) ).id | |
); | |
}; | |
// Updating the terms with term IDs if there are no new ones. | |
if ( newTermNames.length === 0 ) { | |
return this.props.onUpdateTerms( | |
termNamesToIds( uniqueTerms, this.state.availableTerms ), | |
this.props.taxonomy.rest_base | |
); | |
} | |
// Adding new term names (IDs). | |
Promise | |
.all( newTermNames.map( this.findOrCreateTerm ) ) | |
.then( ( newTerms ) => { | |
const newAvailableTerms = this.state.availableTerms.concat( newTerms ); | |
this.setState( { availableTerms: newAvailableTerms } ); | |
return this.props.onUpdateTerms( | |
termNamesToIds( uniqueTerms, newAvailableTerms ), | |
this.props.taxonomy.rest_base | |
); | |
} ); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "gutenberg-components-series", | |
"version": "0.1.0", | |
"private": true, | |
"dependencies": { | |
"@wordpress/api-fetch": "^3.1.0", | |
"@wordpress/components": "^7.0.6", | |
"lodash": "^4.17.11", | |
"node-sass": "^4.11.0", | |
"react": "^16.7.0", | |
"react-dom": "^16.7.0", | |
"react-scripts": "2.1.3" | |
}, | |
"scripts": { | |
"start": "react-scripts start", | |
"build": "react-scripts build", | |
"test": "react-scripts test", | |
"eject": "react-scripts eject" | |
}, | |
"eslintConfig": { | |
"extends": "react-app" | |
}, | |
"browserslist": [ | |
">0.2%", | |
"not dead", | |
"not ie <= 11", | |
"not op_mini all" | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// return of the render() method in FlatTermSelector | |
return ( | |
<FormTokenField | |
value={ selectedTerms } | |
suggestions={ termNames } | |
onChange={ this.onChange } | |
onInputChange={ this.searchTerms } | |
maxSuggestions={ MAX_TERMS_SUGGESTIONS } | |
disabled={ loading } | |
label={ newTermLabel } | |
messages={ { | |
added: termAddedLabel, | |
removed: termRemovedLabel, | |
remove: removeTermLabel, | |
} } | |
/> | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// passed to onInputChange | |
searchTerms( search = '' ) { | |
invoke( this.searchRequest, [ 'abort' ] ); | |
this.searchRequest = this.fetchTerms( { search } ); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
render() { | |
// ... code | |
const { loading, availableTerms, selectedTerms } = this.state; | |
const termNames = availableTerms.map( ( term ) => term.name ); | |
// ... other code | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment