javascript 将可单击对象放入Select2列表

mgdq6dx1  于 2023-01-11  发布在  Java
关注(0)|答案(1)|浏览(270)

bounty已结束。回答此问题可获得+50声望奖励。奖励宽限期将在2小时后结束。Tanoro希望引起更多人关注此问题。

我将Select2与kartik-v/yii2-widget-select2小部件一起使用,以生成可搜索的选择菜单。
我需要在每个Select2选项的开头添加一个星星图标(使用Font awesome),这样做的目的是让用户能够“喜爱”某些选项,并将它们推到列表的顶部。

为了实现这一点,我使用了select2:selecting事件,在该事件中,我附加了一个函数,当单击星星时执行该函数,并阻止Select2使用其默认行为(选择选项并关闭选择列表)。

$('#shelf_id').on("select2:selecting", function (e) {
    if(typeof e.params.args !== 'undefined') {
        if (
            e.params.args.originalEvent.target.className === 'far fa-light fa-star fav_btn'
            || e.params.args.originalEvent.target.className === 'fas fa-light fa-star fav_btn'
        ) {
            e.preventDefault();
            e.stopPropagation();
            
            // The star was clicked
            console.log('Star was clicked');
        }
    }
});

这对于没有被选中的选项很有效。但是,Select2在点击一个已经被选中的选项时不会触发selecting事件。如果用户选择了一个选项,然后重新打开列表并打算点击星星,列表会再次关闭,并且对星号的点击不会被注册。
Select2是否提供了解决方案?是否有更好的方法将可单击元素放置在列表选项中?或者是否有方法让选择事件在所有选择上触发,而不仅仅是选择中的“更改”?
编辑以添加初始化下拉列表的代码。此代码从PHP调用。

<?php

$resultsJs = <<< JS
function (data, params) {
    params.page = params.page || 1;
    var more = (params.page * 10) < data.total_count;
    return {
        results: data.items,
        pagination : {
          more: more
        }   
    };
}
JS;

echo Select2::widget([
    'model' => $searchModel,
    'attribute' => 'shelf_name',
    'options' => [
        'prompt' => 'Select Shelf',
        'title' => 'Select Shelf',
        'id' => 'shelf_id',
        'nolabel' => true,
        'class' => 'form-control'
    ],
    'pluginOptions' => [
        'allowClear' => true,
        'ajax' => [
            'url' => Url::to(['mybook/shelf-listfav']),
            'dataType' => 'json',
            'data' => new JsExpression(
                'function(params){return {q:params.term,page:params.page || 1,module_name:"My Books",dropdown_name:"Select Shelf"};}'
            ),
            'delay' => 250,
            'processResults' => new JsExpression($resultsJs) 
        ],
        'templateSelection' => new JsExpression('format'),
        'templateResult' => new JsExpression('format'),
        'escapeMarkup' => $escape,
    ],
    'pluginEvents' => [
        'select2:select' => 'function(e){selectBooks()}',
        'select2:unselect' => 'function(){unselectBooks()}',
    ],
]);
lsmd5eda

lsmd5eda1#

根据select2's docs,还有select2:unselecting事件,类似于您已经使用的select2:selecting
select2:unselecting:在删除选择之前触发。此事件可以防止。
因此,您可以将同一个事件处理程序绑定到这两个事件,例如:

$('#shelf_id').on("select2:selecting select2:unselecting", function (e) {

    // with e.type you can know which event is triggered
    var isSelecting = e.type === 'select2:selecting';

    if(typeof e.params.args !== 'undefined') {
        if (
            e.params.args.originalEvent.target.className === 'far fa-light fa-star fav_btn'
            || e.params.args.originalEvent.target.className === 'fas fa-light fa-star fav_btn'
        ) {
            e.preventDefault();
            e.stopPropagation();
            
            // The star was clicked
            console.log('Star was clicked');
        }
    }
});

注意,e.type保存了触发处理程序的事件名,如果需要的话,这对于区分功能非常有用。

相关问题