多个 select 产品使用 select2 作为 wordpress 插件选项页面

Multiple select product using select2 for wordpress plugin option page

我正在尝试使用 select2 实现多个 select 产品。该列表使用 getproductsearch 这个 ajax 我之前执行的操作但 我未能保存它 。我之前为 post-metaproduct-category 做过这个功能,但没有为插件 option page 做过。我不确定我做错了什么。

请帮忙。

 class FeatureSale {
    private $feature_sale_options;

    public function __construct() {
        add_action( 'admin_menu', array( $this, 'feature_sale_add_plugin_page' ) );
        add_action( 'admin_init', array( $this, 'feature_sale_page_init' ) );
    }

    public function feature_sale_add_plugin_page() {
        add_submenu_page(
        'exclutips-settings',
            'Feature & Sale', // page_title
            'Feature & Sale', // menu_title
            'manage_options', // capability
            'feature-sale', // menu_slug
            array( $this, 'feature_sale_create_admin_page' ) // function
        );
    }

    public function feature_sale_create_admin_page() {
        $this->feature_sale_options = get_option( 'feature_sale_option_name' ); ?>

        <div class="wrap">
        <div class="catbox-area-admin" style="width: 500px;background: #fff;padding: 27px 50px;">
            <h2>Feature & Sale</h2>
            <p></p>
            <?php settings_errors(); ?>

            <form method="post" action="options.php">
                <?php
                    settings_fields( 'feature_sale_option_group' );
                    do_settings_sections( 'feature-sale-admin' );
                    submit_button();
                ?>
            </form>
        </div>
        </div>
    <?php }

    public function feature_sale_page_init() {
        register_setting(
            'feature_sale_option_group', // option_group
            'feature_sale_option_name', // option_name
            array( $this, 'feature_sale_sanitize' ) // sanitize_callback
        );

        add_settings_section(
            'feature_sale_setting_section', // id
            '', // title
            array( $this, 'feature_sale_section_info' ), // callback
            'feature-sale-admin' // page
        );

        add_settings_field(
            'vpm_sale_product', // id
            'VPM Sale Product', // title
            array( $this, 'vpm_sale_product_callback' ), // callback
            'feature-sale-admin', // page
            'feature_sale_setting_section' // section
        );

        add_settings_field(
            'vpm_featured_product', // id
            'VPM Featured Product', // title
            array( $this, 'vpm_featured_product_callback' ), // callback
            'feature-sale-admin', // page
            'feature_sale_setting_section' // section
        );
    }

    public function feature_sale_sanitize($input) {
        $sanitary_values = array();
        if ( isset( $input['vpm_sale_product'] ) ) {
            $sanitary_values['vpm_sale_product'] = $input['vpm_sale_product'];
        }

        if ( isset( $input['vpm_featured_product'] ) ) {
            $sanitary_values['vpm_featured_product'] = $input['vpm_featured_product'];
        }

        return $sanitary_values;
    }

    public function feature_sale_section_info() {

    }

    //Output the HTML for the metabox.

    public function vpm_sale_product_callback() {
        global $post;
        // Nonce field to validate form request came from current site
        wp_nonce_field( basename( __FILE__ ), 'vpm_sale_product_nonce' );

        $html = '';

        // always array because we have added [] to our <select> name attribute
        $feature_sale_options = get_option( 'feature_sale_option_name' ); // Array of All Options
        $vpm_sale_product = $feature_sale_options['vpm_sale_product'];

        $html .= '<p><select id="vpm_sale_product" name="vpm_sale_product[]" multiple="multiple" style="width:99%;max-width:25em;">';

        if( $vpm_sale_product ) {
            foreach( $vpm_sale_product as $post_id ) {
                $title = get_the_title( $post_id );
                // if the post title is too long, truncate it and add "..." at the end
                $title = ( mb_strlen( $title ) > 50 ) ? mb_substr( $title, 0, 49 ) . '...' : $title;
                $html .=  '<option value="' . $post_id . '" selected="selected">' . $title . '</option>';
            }
        }
        $html .= '</select></p>';

        echo $html;
        //==========================================
    }


     //* Output the HTML for the metabox.

    public function vpm_featured_product_callback() {
        global $post;
        // Nonce field to validate form request came from current site
        wp_nonce_field( basename( __FILE__ ), 'vpm_featured_product_nonce' );

        $html = '';

        // always array because we have added [] to our <select> name attribute
        $feature_sale_options = get_option( 'feature_sale_option_name' ); // Array of All Options
        $vpm_featured_product = $feature_sale_options['vpm_featured_product'];

        $html .= '<p><select id="vpm_featured_product" name="vpm_featured_product[]" multiple="multiple" style="width:99%;max-width:25em;">';

        if( $vpm_featured_product ) {
            foreach( $vpm_featured_product as $post_id ) {
                $title = get_the_title( $post_id );
                // if the post title is too long, truncate it and add "..." at the end
                $title = ( mb_strlen( $title ) > 50 ) ? mb_substr( $title, 0, 49 ) . '...' : $title;
                $html .=  '<option value="' . $post_id . '" selected="selected">' . $title . '</option>';
            }
        }
        $html .= '</select></p>';

        echo $html;
        echo $vpm_featured_product;
        //==========================================
        ?>
        <script>
        (function ($) {
            'use strict';
        $(function () {
            //--------------------------------------------------------------------------
            // multiple select with AJAX search
            $('#vpm_featured_product,#vpm_sale_product').select2({
                ajax: {
                        url: ajaxurl, // AJAX URL is predefined in WordPress admin
                        dataType: 'json',
                        delay: 250, // delay in ms while typing when to perform a AJAX search
                        data: function (params) {
                            return {
                                q: params.term, // search query
                                action: 'getproductsearch' // AJAX action for admin-ajax.php
                            };
                        },
                        processResults: function( data ) {
                        var options = [];
                        if ( data ) {

                            // data is the array of arrays, and each of them contains ID and the Label of the option
                            $.each( data, function( index, text ) { // do not forget that "index" is just auto incremented value
                                options.push( { id: text[0], text: text[1]  } );
                            });

                        }
                        return {
                            results: options
                        };
                    },
                    cache: true
                },
                minimumInputLength: 3 // the minimum of symbols to input before perform a search
            });

            //----------------------------------------------------------------------------------------
        });
    })(jQuery);
    </script>   
        <?php 
    }

}
if ( is_admin() )
    $feature_sale = new FeatureSale();

问题是这些 select 标签没有使用正确的 name 值:

<select id="vpm_sale_product" name="vpm_sale_product[]"...>
<select id="vpm_featured_product" name="vpm_featured_product[]"...>

正确的 name 值是:(基于您的 register_setting() 调用)

<select id="vpm_sale_product" name="feature_sale_option_name[vpm_sale_product][]"...>
<select id="vpm_featured_product" name="feature_sale_option_name[vpm_featured_product][]"...>

虽然在纠正上述问题后,表单数据将被正确保存,传递给 add_submenu_page() 的第五个参数(即 menu/page slug)应该与传递给 [=] 的第四个参数匹配17=] 和 add_settings_field(),以及传递给 do_settings_sections() 的那个。在您的 add_submenu_page() 调用中,menu/page slug 是 feature-sale,但是对于其他三个函数,您将其设置为 feature-sale-admin.

建议使用 wp_nonce_field(),但在您的情况下,没有必要,因为您要提交给 wp-admin/options.php。当然,除非您想在 WordPress 保存选项之前进行检查。但即便如此,我相信一个 nonce 字段还是不错的。 :)