首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AJAX链Select2

AJAX链Select2
EN

Stack Overflow用户
提问于 2020-12-20 00:23:47
回答 1查看 307关注 0票数 0

我想实现两件事:

  1. 允许可搜索和可过滤的选择选项。

  1. 自动选择值-如果给定的选项仅为1

下面的代码实现了我的第一点,但我不确定在当前的实现情况下,如何实现我的第二点。选择一个值将被添加到args中,因此在打开select2时,它使用更新的args查询数据库,并返回筛选的选项,用于特定的select2。工作版本如下所示:

代码语言:javascript
复制
jQuery( 'document' ).ready( function( $ ) {
            
    let select2s = [];
    let args = {};
    
    
    /**
     * Clear select2 values
     */
    function clear_select2s( except_name ) {
        
        except_name = ( 'undefined' !== typeof except_name ) ? except_name : '';
        
        select2s.forEach( function( $select2, key ) {
            if( $select2.attr( 'name' ) == except_name ) { return; }
            $select2.val( '' );
        } );
        
    }
    
    
    /**
     * Initialize select2s
     */
    $( '#s2Container .select2' ).each( function() {
        
        let name = $( this ).attr( 'name' );
        let placeholder = $( this ).attr( 'placeholder' );
        let $select2 = $( this ).select2( {
            allowClear: true,
            placeholder: placeholder,
            ajax: {
                type: 'post',
                url: test.ajaxurl,
                dataType: 'json',
                data: function( params ) {
                    return {
                        action: 'select2_filtering',
                        return: name,
                        args: Object.assign( args, {
                            'search': params.term
                        } ),
                    };
                },
                processResults: function( response ) {
                    return {results: response.data.options};
                },
            },
        } );
        
        /* Push select into Array */
        select2s.push( $select2 );
    } );
    
    
    /**
     * Remove selected value from arguments
     */
    $( '#s2Container .select2' ).on( 'select2:unselecting', function() {
        
        let name = $( this ).attr( 'name' );
        args[ name ] = '';
        
        clear_select2s();
        
    } );
    
    /**
     * Add selected value to arguments
     */
    $( '#s2Container .select2' ).on( 'select2:select', function() {
        
        let name = $( this ).attr( 'name' );
        let value = $( this ).val();
        
        Object.assign( args, {[name]:value} );
        
        clear_select2s( name );
        
    } );
    
} );

HTML

代码语言:javascript
复制
<div id="s2Container">
    <select class="select2" name="product_id" placeholder="Select Product"></select>
    <select class="select2" name="category_id" placeholder="Select Category"></select>
    <select class="select2" name="brand_id" placeholder="Select Brand"></select>
</div>

上面的代码通过ajax过滤选择选项,非常好。问题是,我的返回只返回当前select2的选项。

如果我返回所有选项的数据,那么我的理解是我需要完全重建每个select2。然后破坏和重建select2,就失去了ajax功能。在processResults内部这样做似乎是有缺陷的,我不确定是否有更好的方法去做。

如果我将其分解为两个ajax调用,一个用于select2选项的初始负载,另一个用于处理on( 'select2:select' ),那么我最终得到的ajax调用比我需要的要多,并且我的select2:select ajax将被初始的select2实例ajax覆盖。

基于彼此的动态填充多个select2选项的最佳方法是什么?如果返回的选项计数仅为1,我将如何设置选定的值?

EN

回答 1

Stack Overflow用户

发布于 2020-12-20 16:36:19

Select2使关闭活动选项变得非常困难。我必须确保select2是.empty(),然后我必须销毁实例,用相同的设置重新创建整个事件。是一种痛苦。最后,我决定简单地不使用select2 ajax填充程序更容易,并在初始化后填充它们。我想出的是:

代码语言:javascript
复制
jQuery( 'document' ).ready( function( $ ) {
            
    let args = {};
    
    
    /**
     * Update all select2s with fresh options
     */
    function update_select2s() {
        
        $.ajax( {
            type: 'post',
            url: test.ajaxurl,
            dataType: 'json',
            data: {
                action: 'product_filtering',
                args: args,
            },
            success: function( response ) {
                
                let options = response.data.results;
                
                for( const [ key, values ] of Object.entries( options ) ) {
                    
                    if( ! $( '#s2Container select[name="' + key + '"]' ).length ) {
                        continue;
                    }
                    
                    let $select2    = $( '#s2Container select[name="' + key + '"]' );
                    let selected    = $select2.val();
                    let name        = $select2.attr( 'name' );
                    let placeholder = $select2.attr( 'placeholder' );
                    
                    /**
                     * If we have a select2, empty and destroy it.
                     * This will allow us to reinitialize the select2 with fresh options.
                     * Select2 instance is not yet initialized on first run.
                     */
                    if( $select2.data( 'select2' ) ) {
                        $select2.empty().select2( 'destroy' );
                    }
                    
                    $select2.select2( {
                        allowClear: true,
                        placeholder: placeholder,
                        data: values,
                    } );
                    
                    /**
                     * If there is only one option, select 2 automatically.
                     */
                    if( values.length > 1 ) {
                        $select2.val( '' ).trigger( 'change.select2' );
                    }
                    
                }
                
            }
        } );
        
    }
    
    /* Populate Select2 options */
    update_select2s();
    
    
    $( '#s2Container .select2' ).on( 'select2:unselect', function() {

        let name = $( this ).attr( 'name' );
        delete args[ name ];
        
        update_select2s();
        
    } );
    
    
    $( '#s2Container .select2' ).on( 'select2:select', function() {
        
        let name = $( this ).attr( 'name' );
        let value = $( this ).val();
        
        /**
         * If a named arg already exists, this means the user wants change
         * We need to clear our args and give our select2s fresh data.
         */
        if( args.hasOwnProperty( name ) && args[name].length ) {
            args = {[name]:value};
        } else {
            Object.assign( args, {[name]:value} );
        }
        
        update_select2s();
        
    } );
    
} );

使用此更新,我也不会返回特定select2的数据,而是返回所有select2s的数据。返回按选定名称键键的数据:

代码语言:javascript
复制
{
    product_id: [ {id: 1, text: 'foo'}, {id: 1,text: 'foo'} ],
    category_id: [ {id: 1,text: 'xyz'}, {id: 1,text: '123'} ],
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65375809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档