Search code examples
javascriptwordpressjsxwordpress-gutenberg

call DateTimePicker in wordpress Gutenberg block


This should be relatively easy I imagine, however I cannot figure it out.

I am creating a custom Gutenberg block in JSX with React components which has an attribute I call datetime. Using the block you can choose a date and time that will be saved to the database and rendered on the front-end.

Using the documentation I import all dependencies and created a const like this:

const MyDateTimePicker = withState( {
    date: new Date(),
} )( ( { date, setState } ) => {
    const settings = __experimentalGetSettings();

    // To know if the current timezone is a 12 hour time with look for an "a" in the time format.
    // We also make sure this a is not escaped by a "/".
    const is12HourTime = /a(?!\\)/i.test(
        settings.formats.time
            .toLowerCase() // Test only the lower case a
            .replace( /\\\\/g, '' ) // Replace "//" with empty strings
            .split( '' ).reverse().join( '' ) // Reverse the string and test for "a" not followed by a slash
    );

    return (
        <DateTimePicker
            currentDate={ date }
            onChange={ ( date ) => setState( { date } ) }
            is12Hour={ is12HourTime }
        />
    );
} );

My question is: how do I call this?

I tried { MyDateTimePicker }, { MyDateTimePicker() } and <button onClick={ MyDateTimePicker }>test</button>. None of this seems to work.


Solution

  • You need to read about Edit and Save functions

    On edit you'd use it somehow like this assuming you already defined the attribute datetime as needed:

    const { Fragment, createElement } = window.wp.element;
    const { InspectorControls } = window.wp.editor;
    const { Panel, PanelBody, PanelRow, DateTimePicker } = window.wp.components;
    
    export default function edit( { attributes, setAttributes } ) {
    
      const { datetime } = attributes;
    
      const onUpdateDate = ( dateTime ) => {
        var newDateTime = moment(dateTime).format( 'YYYY-MM-DD HH:mm' );
        setAttributes( { datetime: newDateTime } );
      };
    
      return (
        <Fragment>
          <InspectorControls>
            <PanelBody
                title="Some title for the date-tile panel"
                icon=""
                initialOpen={ false }
            >
              <PanelRow>
                <DateTimePicker
                    currentDate={ datetime }
                    onChange={ ( val ) => onUpdateDate( val ) }
                    is12Hour={ true }
                />
              </PanelRow>
            </PanelBody>
          </InspectorControls>
        </Fragment>
      );
    }
    

    On the save function, you could display the output easily like this:

    const { createElement, Fragment } = window.wp.element;
    export default function save( { attributes } ) {
    
        const { datetime } = attributes;
    
        return (
            <Fragment>
            { datetime ?
          <div>
            <p>The Date-Time: <span>{datetime}</span></p>
          </div> :
            <p>No date defined</p>
            </Fragment>
        );
    }
    

    Note: the example above will display the date-time picker in the block editor right panel on its own panel row, if you want it displayed differently or as a part of some action you'd need to get a little creative and create you own React components.