Describe the bug
The AutoComplete component example documented here https://github.com/WordPress/gutenberg/tree/master/packages/components/src/autocomplete
works fine with Gutenberg 3.9.0 but with Gutenberg 4.0.0-rc.1 a javascript errors occurs and no component is displayed.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A simple AutoComplete component has to work fine with Gutenberg 4.0.0-rc.1
Screenshots
Desktop (please complete the following information):
AutoComplete componentDidUpdate() seems to be rewritten and need a record property to pass it to the isCollapsed function of the RichText Component.
In a case where we don't use the AutoComplete component with RichText the property record is undefined and isCollapsed() function causes the error.
Does this ring any bells for you @iseulde?
Looking
Unsure how we can make it work again with a plain contenteditable field without introducing a lot of code. @manooweb How are you using the AutoComplete
component? In combination with RichText
or something else? How are you using it inside a block?
@iseulde no I am inside a plugin sidebar and I just put the code exactly like it is documented in the readme file I linked above.
Screenshot with Gutenberg 3.9.0
Autocomplete component is wrapped in a span tag in our jsx render code of our parent component. This is not a pure function component but a class component with state. I initialize completers inside the constructor and pass this property to Autocomplete with this.completers.
This just the little things that are different with the code example in the documentation.
This is really the component which is inside @wordpress/components and not the other one which is inside the editor package and which is a wrapper.
So, I continue to develop my component with the Autocomplete of Gutenberg 3.9.0 with a simple contentEditable and it works fine. I coded a promise with apiFetch() call to get posts filtered by language to initialize the options of the Autocomplete component.
When I switch to Gutenberg 4.0.0-rc.1, it is broken for the same reason that I opened the issue.
Then, I'm trying to integrate Autocomplete 3.9.0 in our code but now I have a lodash error which seems to be triggered by the "compose" fonction of Autocomplete component
Any kind of help or guidance will be appreciate to continue in the right direction to finish this feature.
Thank you so much
Well, it's ok for me now. I solved my last problem. I just did a mistake with import syntax that I have to change for putting the component outside Gutenberg.
So I integrated directly in our code the Autocomplete component from Gutenberg 3.9.0
The first issue is always there if you want to use the component as it is explained in its documentation.
I'd prefer that the the Autocomplete component stay in Gutenberg to maintain it and continue to work fine with contentEditable as in Gutenberg 3.9.0.
Just updated to 4.1 and it's still occurring.
Thanks @petenelson :-)
I dived deeper in code and understood I have to use RichText component which is using Autocomplete component but I did not find yet how to do it properly.
Hi @iseulde ,
Any chances this component is fixed to the release? Is this been worked on?
Thanks!
Still an issue as of 4.3
I am also seeing this issue in 4.5.1.
Hopefully this is helpful. I really needed an Autocomplete component for the project I am working on right now, so I created a super simple one. https://gist.github.com/thatdevgirl/e20f72d5b985c6eab441bdf491b3edf0
If you add record={{}}
to the Autocomplete component it should work but I am not sure how and when should this record be updated. It receives start
, end
, format
and text
values but I have yet to find how they're managed.
I've managed to figure it out.
Try to import RichText from wp.editor and use it instead of autocomplete.
<RichText
value={this.state.value}
onChange={this.setValue}
autocompleters={completer}
/>
@thatdevgirl Thanks for the snippet. It saves lives. Just one question could we use dynamic ID for autocomplete
uisng withInstanceId
? Something like I have added here.
I definitively doesn't use this component which is too complex for our need.
I inspired myself from another one more simple component : urlInputButton in editor components
https://github.com/WordPress/gutenberg/blob/master/packages/editor/src/components/url-input/index.js
I simplified it and integrated it in our own code to be sure we will be able to maintain it as we want even if it would be preferable to have one in Gutenberg code
https://github.com/polylang/polylang-gutenberg/blob/master/js/sidebar/components/translation-input/index.js
I think I found a way around this. We already know that this _Autocomplete_ component works for the block and user completion, but it's working within the RichText
control, so I simply filtered the autocompleters
to use a custom one instead of the two default ones:
wp.hooks.addFilter(
'editor.Autocomplete.completers',
'jp/addCompleters',
addCompleters,
);
This handles overriding the default autocompleters:
/**
* Add our custom WPCompleters to list of autocompleters (callback)
*
* @param {array} completers existing autocomplete completers
* @param {string} blockName block type the filter is running on
* @return {array} completers just our new companyCompleter if the right block(s)
* @since 1.0.0
*/
const addCompleters = ( completers, blockName ) => {
switch ( blockName ) {
case 'jp/company' :
completers = [ getCompleter( 'jp_company' ) ];
break;
case 'jp/statistic' :
completers = [ getCompleter( 'jp_statistic' ) ];
break;
default:
break;
}
return completers;
};
Here's the helper that returns an instance (object) of autocompleter instructions. This one fetches posts of the post type from a site network via custom REST endpoint:
/**
* Configuration for company <Autocomplete>
*
* @type {WPCompleter}
* @param {string} postType CPT key
* @return {object} Autocomplete completer properites
* @since 1.0.0
*/
const getCompleter = postType => {
return {
name: 'jp/' + postType,
// prefix that triggers this completer
triggerPrefix: '',
// option data
options( search ) {
const args = {
post_type: postType,
};
if ( search ) {
args.search = encodeURIComponent( search );
}
return wp.apiFetch( { path: addQueryArgs( '/jp/v1/network-posts', args ) } );
},
// since we're doing API fetch
isDebounced: true,
// returns option label
getOptionLabel( post ) {
return <span>{ post.post_title } <small>({ sites[ post.BLOG_ID - 1 ].label })</small></span>;
},
// options should be matched by their name
getOptionKeywords: post => [ post.post_title, post.post_content ],
// completions should be removed, but then spawn setPost
getOptionCompletion( post ) {
return {
action: 'replace',
value: setPost( parseInt( post.BLOG_ID ), post.ID, post.post_title ),
};
},
};
};
This example assumes some things that might not work for some situations:
<RichText>
controls in the block(s) being filtered, so that may need to be adjusted if you have multiple text controls and only want the autocomplete in one of them.^ thing 1 explained:
/**
* Set network post ID/title for selected block
*
* @param {integer} blogID network blog ID
* @param {integer} postID company post ID
* @param {string} postTitle company post title
* @since 1.0.0
*/
const setPost = ( blogID, postID, postTitle ) => {
const block = wp.data.select( 'core/block-editor' ).getSelectedBlock();
// block.setAttributes() isn't available here! 馃槷
block.attributes.postBlogID = blogID;
block.attributes.postID = postID;
block.attributes.postTitle = postTitle;
};
@JordanPak I got around the problem like you
I still have a bug, by updating the attribute as you do : block.attributes.postBlogID = blogID;
The block is not refreshed
if I update with setAttributes the block refreshes well but if I have my block several times in an article setAttributes does not update the block being edited but the first one it finds
Can you help me ?
Here is my code
@JordanPak I got around the problem like you
I still have a bug, by updating the attribute as you do : block.attributes.postBlogID = blogID;
The block is not refreshed
if I update with setAttributes the block refreshes well but if I have my block several times in an article setAttributes does not update the block being edited but the first one it findsCan you help me ?
Here is my code
@jfsenechal I am not having an issue where editing one block affects the properties or state of another block, but since I haven't figured out how to use block.setAttributes()
in that setPost() function, the "state" of the block with the autocomplete doesn't fire off consistently :(
Still does not work.
Using example of autocomplete from:
https://developer.wordpress.org/block-editor/components/autocomplete/
throws exception:
TypeError: Cannot read property 'start' of undefined
Unfortunately, this component wasn't really meant to be exported for use in plugins and I highly discourage using this component and see it as experimental. I guess we'll (have to) keep it around in its current form, but at some point I don't expect it to be used by Gutenberg core anymore.
Most helpful comment
Hopefully this is helpful. I really needed an Autocomplete component for the project I am working on right now, so I created a super simple one. https://gist.github.com/thatdevgirl/e20f72d5b985c6eab441bdf491b3edf0