【问题标题】:Yii2: How to use option groups with AJAX-based Kartik's Select2Yii2:如何在基于 AJAX 的 Kartik 的 Select2 中使用选项组
【发布时间】:2017-07-08 22:31:09
【问题描述】:

目前,我有一个表单字段来呈现带有基于 Kartik 的 Select2 的选项组的静态下拉列表。使用以下内容填充数据:

public function getBibliographyList()
{ 
    return ArrayHelper::map($this->find()->select(['id','title','author'])
              ->orderBy('author','title')->all(), 'id', 'title', 'author');
}

因此标题显示在其各自的作者选项组下。

现在我想修改表单以利用 AJAX,所以我以 Krajee Demo Site for Select2 的示例进行了修改,如下所示:

------查看 ----------

<?= $form->field($model, 'orig_id')->widget(Select2::classname(), [
        'options' => ['placeholder' => Yii::t('app', 'Select a title...)],
        'pluginOptions' => [
            'allowClear'         => true,
            'minimumInputLength' => 3,
            'language'           => Yii::$app->language,
            'theme'              => 'krajee',
            'ajax' => [
                'url'      => \yii\helpers\Url::to(['search-doc']),
                'dataType' => 'json',
                'data'     => new JsExpression('function (params) { return {q:params.term}; }'),
            ],
            'errorLoading'      => new JsExpression("function () { return '".Yii::t('app', 'Waiting for data...')."'; }"),
            'escapeMarkup'      => new JsExpression("function (markup) { return markup; }"),
            'templateResult'    => new JsExpression("function (bibliography) { return bibliography.title; }"),
            'templateSelection' => new JsExpression("function (bibliography) { return bibliography.title; }"),
        ],
]) ?>

-------- 控制器 -------------

public function actionSearchDoc($q = null)
{
    Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    $out = ['id' => '', 'title' => '', 'author' => ''];
    if ($q) {
        $query = new yii\db\Query;
        $query->select('id, title, author')
              ->from('bibliography')
              ->where(['like', 'title', $q])
              ->orWhere(['like', 'author', $q])
              ->limit(50);
        $command = $query->createCommand();
        $data    = $command->queryAll();
        $out = array_values($data);
    }
    return \yii\helpers\ArrayHelper::map($out, 'id', 'title', 'author');
}

根据 Kartik 的 Select2 docs,当 optgroups 出现时,ArrayHelper::map 是要走的路,但我无法弄清楚这一点,因为结果下拉列表总是空的。这是来自 ArrayHelper::map 的示例 JSON 字符串:

{"results":{"Author1":{"4":"DocumentFoo1","121":"DocumentFoo2","219":"DocumentFoo3","197":"DocumentFoo4","198":"DocumentFoo5","2":"DocumentFoo6","273":"DocumentFoo7"},"Author2":{"68":"DocumentThee1"}}}

有什么想法吗?

【问题讨论】:

  • 能否请您添加错误信息?
  • mmmm,我错过了 ArrayHelper 行开头的反斜杠,因此出现此错误。无论如何,映射 optgroups 的问题仍然存在。我会继续尝试,直到我能发布一个合适的解决方案。

标签: jquery ajax yii2 select2 kartik-v


【解决方案1】:

这是我自己想出来的。首先,我们必须关心提供基于 AJAX 的 Select2 所需的 JSON 字符串,它必须像这样):

Array
(
[results] => Array
    (
        [0] => Array
            (
                [text] => "author1"
                [children] => Array
                    (
                        [0] => Array
                            (
                                [id] => "id1"
                                [text] => "title1"
                            )
                        [1] => Array
                            (
                                [id] => "id2"
                                [text] => "title2"  
                            )                           
                    )
            )
        [1] => Array
            (
                [text] => "author2"
                [children] => Array
                    (
                        [0] => Array
                            (
                                [id] => "id3"
                                [text] => "title3"
                            )
                    )
            )
    )
)

但是,四参数ArrayHelper::map输出如下:

Array
(
    [author1] => Array
        (
            [id1] => "title1"
            [id2] => "title2"
        )

    [author2] => Array
        (
            [id3] => "title3"
        )
)

因此,我们必须重新排列内容并合并这些特殊关键字。因此,正确的控制器动作应该是这样的:

public function actionSearchDoc($q = null)
{
    // JSON format result.
    Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    $out['results'] = '';
    if ($q) {
        $query = Bibliography::find()->select(['id', 'title', 'author'])
                                     ->where(['like', 'title', $q])
                                     ->orWhere(['like', 'author', $q])
                                     ->all();
        // Group titles by author.
        $authorArray = ArrayHelper::map($query, 'id', 'title', 'author');
        // Previous array lacks keywords needed to use optgroups
        // in AJAX-based Select2: 'results', 'id', 'text', 'children'.
        // Let's insert them.
        $results = []; 
        foreach ($authorArray as $author => $docArray) {
            $docs  = [];
            foreach ($docArray as $id => $title) {
                $docs[] = ['id' => $id, 'text' => $title];
            }
            $results[] = ['text' => $author, 'children' => $docs];
        }
        $out['results'] = $results;
    }
    return $out;
}

所以,就是这样。希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    相关资源
    最近更新 更多