-
-
Save thatdevgirl/e20f72d5b985c6eab441bdf491b3edf0 to your computer and use it in GitHub Desktop.
/** | |
* A very simple autocomplete component | |
* | |
* This is to replace the OOTB Gutenberg Autocomplete component because it is | |
* currently broken as of v4.5.1. | |
* | |
* See Github issue: https://github.com/WordPress/gutenberg/issues/10542 | |
* | |
* Note: The options array should be an array of objects containing labels and values; i.e.: | |
* [ | |
* { value: 'first', label: 'First' }, | |
* { value: 'second', label: 'Second' } | |
* ] | |
*/ | |
// Load external dependency. | |
import { isEmpty } from 'lodash'; | |
function MyAutocomplete( { | |
label, | |
id, | |
value, | |
onChange, | |
options = [], | |
} ) { | |
// Construct a unique ID for this block. | |
const blockId = `my-autocomplete-${ id }`; | |
// Function to handle the onChange event. | |
const onChangeValue = ( event ) => { | |
onChange( event.target.value ); | |
}; | |
// Return the block, but only if options were passed in. | |
return ! isEmpty( options ) && ( | |
<div> | |
{ /* Label for the block. */ } | |
<label for={ blockId }> | |
{ label } | |
</label> | |
{ /* Input field. */ } | |
<input | |
list={ blockId } | |
value={ value } | |
onChange={ onChangeValue } | |
/> | |
{ /* List of all of the autocomplete options. */ } | |
<datalist id={ blockId }> | |
{ options.map( ( option, index ) => | |
<option value={ option.value } label={ option.label } /> | |
) } | |
</datalist> | |
</div> | |
); | |
}; | |
export default MyAutocomplete; |
Hi @simonhammes,
Yes I did, Please find the PHP code below.
/**
* Prefix_Core_Mag_Stories class
*
* This is used to define Mag Stories.
*
* @link https://abc.com
* @since 1.0.0
* @package Prefix_Core
* @subpackage Prefix_Core/includes/blocks
* @author ABC <[email protected]>
*/
class Prefix_Core_Mag_Stories {
/**
* Initialize the class and set its properties.
*
* @since 1.0.0
*/
public function __construct() {
// Register Block - Mag Stories.
add_action( 'init', array ( $this, 'prefix_block_mag_stories' ) );
}
public function prefix_block_mag_stories() {
// Skip block registration if Gutenberg is not enabled/merged.
if ( !function_exists('register_block_type') ) {
return;
}
$dir = dirname(__FILE__);
$index_js = 'mag-stories.js';
wp_register_script(
'prefix-mag-stories-js',
plugins_url( $index_js, __FILE__ ),
array(
'wp-blocks',
'wp-element',
'wp-i18n'
),
filemtime( "$dir/$index_js" ),
true
);
// Collect Post Tags Data
$tags[] = array(
'label' => esc_html__( 'All Tags', 'prefix-core' ),
'value' => '',
);
$jumbo_stories_tags = get_tags();
foreach ( $jumbo_stories_tags as $jumbo_stories_tag ) {
$tags[] = array(
'label' => $jumbo_stories_tag->name,
'value' => $jumbo_stories_tag->term_id,
);
}
wp_localize_script(
'prefix-mag-stories-js',
'mag_stories',
array(
'tags' => $tags,
)
);
register_block_type( 'mydomain-blocks/mag-stories', array(
'editor_script' => 'prefix-mag-stories-js',
'render_callback' => [ $this, 'prefix_block_mag_stories_handler' ],
'attributes' => apply_filters(
'jumbo_stories_attributes', [
'className' => array( 'type' => 'string', 'default' => null ),
'tag' => array( 'type' => 'string', 'default' => '' )
]
)
));
}
/**
* Handler for Mag Stories block
*
* @access public
* @param array $atts - [$tag] attributes.
*
* @return string
*/
public function prefix_block_mag_stories_handler( $atts = [] ) {
// normalize attribute keys, lowercase.
$atts = array_change_key_case( (array)$atts, CASE_LOWER );
return $this->prefix_mag_stories( $atts );
}
/**
* Output the Mag Stories 1
*
*
* @return string
*/
public function prefix_mag_stories( $atts ) {
$args = array(
'post_type' => 'post',
'posts_per_page' => 6
);
if ( ! empty( $atts['tag'] ) ) {
$args['tag__in'] = $atts['tag'];
}
$mag_story_posts = new WP_Query( $args );
// Start output.
ob_start();
if ( $mag_story_posts ->have_posts() ) :
return $mag_story_posts;
endif;
$html = ob_get_clean();
// Return output.
return $html;
}
}
new Prefix_Core_Mag_Stories();
Hi @mohsinrafiq -
The example I gave is in ES6. For ES5, you actually need to use the node require()
function; import
is an ES6 feature.
var MyAutocomplete = require( './MyAutocomplete' );
How to create an autocomplete for all the text blocks. Say, I want to add emoji picker for text components.
@techjewel The AutoComplete is a component that you can use more than once, just like any other component. So, expanding on my previous comment at https://gist.github.com/thatdevgirl/e20f72d5b985c6eab441bdf491b3edf0#gistcomment-2982019, you can do something like this:
import MyAutocomplete from 'simple-autocomplete.js'; // adjust if you saved this file somewhere else.
( function() {
const emojis = [
{ 'value': 1, 'label': 'First option' }
{ 'value': 2, 'label': 'Second option' }
];
registerBlockType( 'my/custom_block', {
title: 'My custom block',
// Other block registration code goes here.
edit: ( props ) {
const { isSelected } = props;
const { attribute1, attribute2 } = props.attributes;
return (
{ isSelected && (
<InspectorControls>
<PanelBody title='Things'>
<MyAutocomplete
label='Attribute 1'
value={ attribute1 }
onChange={ onChangeAttribute1 }
options={ emojis }
/>
<MyAutocomplete
label='Attribute 2'
value={ attribute2 }
onChange={ onChangeAttribute2 }
options={ emojis }
/>
</PanelBody>
</InspectorControls>
) }
);
}
}
} )();
This helped a lot. Thanks!
I get this error in the browser console every time an item is selected.
Uncaught TypeError: Cannot read properties of undefined (reading 'toLowerCase')
at HTMLDocument.eval (eval at <anonymous> (eval at ExRmtSvrCd (eval at <anonymous> (wit.js:206))), <anonymous>:1:29484)
By the way, is it possible to search posts by typing a partial post title?
@mipon I just tried and I am not seeing that error. (Testing on Chrome latest.) I am also curious about the error talking about toLowerCase
(which is not used by this component). I wonder if it is conflicting with something else in your code. Would you be comfortable sharing the code that is using the autocomplete component?
Just a quick comment: Did you register the block in PHP? It would be helpful if you would post your PHP code too.