首页 文章

Wordpress Gutenberg自动完成 - 保存属性

提问于
浏览
1

我想开发一个自定义块,让用户从自动完成中选择一些信息 . 我设法在编辑功能上创建自动完成组件 .

用户可以选择项目,但我不知道如何处理属性保存 .

我正在尝试将所选项目保存为属性package_name . 我在Autocomplete组件上创建了onChange函数,但是event.target.value是未定义的 .

这是我在block.js中的代码

const { __ } = wp.i18n; // Import __() from wp.i18n
const {  AlignmentToolbar,
        BlockControls,
        registerBlockType } = wp.blocks; 
const { RichText } = wp.editor;
const { Autocomplete, } =wp.components;


const MyAutocomplete = () => {
    const autocompleters = [
        {
            name: 'fruit',   
            triggerPrefix: '@',   
            options: [
                {  name: 'Apple', id: 1 },
                {  name: 'Orange', id: 2 },
                {  name: 'Grapes', id: 3 },
                {  name: 'test', id: 4 },
            ],

            getOptionLabel: option => (
                <span>
                  { option.name }
                </span>
            ),

            getOptionKeywords: option => [ option.name ],

            isOptionDisabled: option => option.name === 'Grapes',

            getOptionCompletion: option => (
                <abbr title={ option.name }>{ option.name }</abbr>
            ),
        }
    ];

    function onChangeAuto(newContent){
        console.log('autocompletexx '+newContent);
    }

    function onSelectAuto(event){
        console.log(event.target);
           console.log( event.target.value);
    }

    return (
        <div>
            <Autocomplete completers={ autocompleters }>
                { ( { isExpanded, listBoxId, activeId } ) => (
                    <div
                        contentEditable
                        suppressContentEditableWarning
                        aria-autocomplete="list"
                        aria-expanded={ isExpanded }
                        aria-owns={ listBoxId }
                        aria-activedescendant={ activeId }
                        onChange={onChangeAuto }
                        onSelect={onSelectAuto}

                    >
                    </div>
                ) }
            </Autocomplete>
            <p class="autocomplete_p">Type @ for triggering the autocomplete.</p>
        </div>
    );
};




registerBlockType( 'residence-gutenberg-block/membership-package-settings', {
    title: __( 'Residence - Membership Package Settings' ), // Block title.
    icon: 'shield', 
    category: 'common', 
    keywords: [
        __( 'membership-package-settings' ),
    ],
        attributes:{
            package_id:{
                type:'string',
                select:'p'
            },
            package_name:{
                type:'string',
            },
        },


    edit: function( props ) {

                const { attributes: {package_name}, className,setAttributes,isSelected } = props;               
        return (
            <div className={ props.className }>
                            <form>
                                <label className="wpresidence_editor_label">Current Package: {package_name}</label>
                                <MyAutocomplete></MyAutocomplete>
                             </form>

            </div>

        );
    },

    save: function( props ) {
              // Rendering in PHP
                return null;

    },
} );

1 回答

  • 1

    onChangeonSelect 传递给 div 元素将不起作用,因为这些属性仅适用于表单字段元素(如 input, select 等) .

    我检查了文档和源代码,但没有找到处理案例的任何细节或官方方法 .

    但是,我看到了两种可能的方法来获取所选值:

    1.使用自动填充onReplace prop

    查看Autocomplete's source code,我注意到 onSelect 回调调用 onReplace prop,并将所选选项作为数组 . 它可能不适合所有情况,但你可以尝试一下!对你的情况来说可能已经足够了!您可以尝试将处理程序添加到 onReplace ,如下所示:

    <Autocomplete
      onReplace={ option => { console.log(option) } }
      completers={ autocompleters }>
      { ( { isExpanded, listBoxId, activeId } ) => (
        <div
          contentEditable
          suppressContentEditableWarning
          aria-autocomplete="list"
          aria-expanded={ isExpanded }
          aria-owns={ listBoxId }
          aria-activedescendant={ activeId }
        />
      ) }
    </Autocomplete>
    

    2.手动监听<div />更改

    您可以将 onInputonBlur 侦听器添加到 <div /> ,具有不受控制的react div组件以及div 's value is changed then we can keep the changed value in your parent component' s状态 .

    这是一个很好的讨论,它描述了这些技术:React.js: onChange event for contentEditable

    好的想法是,已经有一个插件(基于此讨论)可以为您做到:react-contenteditable .

    首先,您必须将 <MyAutocomplete /> 组件转换为statefull(不起作用),然后:

    import ContentEditable from 'react-contenteditable'
    
    // Boilerplate ...
    
    <Autocomplete completers={ autocompleters }>
      { ( { isExpanded, listBoxId, activeId } ) => (
        <ContentEditable
          html={this.state.html}
          onChange={this.handleChange}
          contentEditable
          suppressContentEditableWarning
          aria-autocomplete="list"
          aria-expanded={ isExpanded }
          aria-owns={ listBoxId }
          aria-activedescendant={ activeId }
        />
      ) }
    </Autocomplete>
    

    结论

    我很惊讶Autocomplete's documentation因为以下声明(27.08.2018)而没有't any details for this case. I guess it':

    Gutenberg正在GitHub上开发,你可以从插件库中尝试今天的早期测试版 . 尽管如此,请记住它不是功能齐全,功能齐全或 生产环境 就绪 .

    但是,上述两种方法之一都会对您提供帮助,直到它们提供完整的API来处理其组件 .

    我建议你继续使用自己的组件包装Wordpress的 <Autocomplete /> ,以便稍后在发布完整的API时轻松重构代码 .

    如果您有任何疑问,请随时在下面发表评论 .

相关问题