rilwis/meta-box

View on GitHub
inc/fields/autocomplete.php

Summary

Maintainability
B
4 hrs
Test Coverage
<?php
defined( 'ABSPATH' ) || die;

/**
 * The autocomplete field.
 */
class RWMB_Autocomplete_Field extends RWMB_Multiple_Values_Field {
    public static function admin_enqueue_scripts() {
        wp_enqueue_style( 'rwmb-autocomplete', RWMB_CSS_URL . 'autocomplete.css', [], RWMB_VER );
        wp_style_add_data( 'rwmb-autocomplete', 'path', RWMB_CSS_DIR . 'autocomplete.css' );
        wp_enqueue_script( 'rwmb-autocomplete', RWMB_JS_URL . 'autocomplete.js', [ 'jquery-ui-autocomplete' ], RWMB_VER, true );

        RWMB_Helpers_Field::localize_script_once( 'rwmb-autocomplete', 'RWMB_Autocomplete', [
            'delete' => __( 'Delete', 'meta-box' ),
        ] );
    }

    /**
     * Get field HTML.
     *
     * @param mixed $meta  Meta value.
     * @param array $field Field parameters.
     * @return string
     */
    public static function html( $meta, $field ) {
        if ( ! is_array( $meta ) ) {
            $meta = [ $meta ];
        }

        // Filter out empty values in case the array started with empty or 0 values
        $meta = array_filter( $meta, function ( $index ) use ( $meta ) {
            return $meta[ $index ] !== '';
        }, ARRAY_FILTER_USE_KEY );

        $field   = apply_filters( 'rwmb_autocomplete_field', $field, $meta );
        $options = $field['options'];

        if ( is_array( $field['options'] ) ) {
            $options = [];
            foreach ( $field['options'] as $value => $label ) {
                $options[] = [
                    'value' => (string) $value,
                    'label' => $label,
                ];
            }
            $options = wp_json_encode( $options );
        }

        // Input field that triggers autocomplete.
        // This field doesn't store field values, so it doesn't have "name" attribute.
        // The value(s) of the field is store in hidden input(s). See below.
        $html = sprintf(
            '<input type="text" class="rwmb-autocomplete-search">
            <input type="hidden" name="%s" class="rwmb-autocomplete" data-options="%s" disabled>',
            esc_attr( $field['field_name'] ),
            esc_attr( $options )
        );

        $html .= '<div class="rwmb-autocomplete-results">';

        // Each value is displayed with label and 'Delete' option.
        // The hidden input has to have ".rwmb-*" class to make clone work.
        $tpl = '
            <div class="rwmb-autocomplete-result">
                <div class="label">%s</div>
                <div class="actions">%s</div>
                <input type="hidden" class="rwmb-autocomplete-value" name="%s" value="%s">
            </div>
        ';

        if ( is_array( $field['options'] ) ) {
            foreach ( $field['options'] as $value => $label ) {
                if ( ! in_array( $value, $meta ) ) {
                    continue;
                }
                $html .= sprintf(
                    $tpl,
                    esc_html( $label ),
                    esc_html__( 'Delete', 'meta-box' ),
                    esc_attr( $field['field_name'] ),
                    esc_attr( $value )
                );
            }
        } else {
            $meta = array_filter( $meta );
            foreach ( $meta as $value ) {
                $label = apply_filters( 'rwmb_autocomplete_result_label', $value, $field );
                $html .= sprintf(
                    $tpl,
                    esc_html( $label ),
                    esc_html__( 'Delete', 'meta-box' ),
                    esc_attr( $field['field_name'] ),
                    esc_attr( $value )
                );
            }
        }

        $html .= '</div>'; // .rwmb-autocomplete-results.

        return $html;
    }
}