Add subtitle in kartik Select2 yii2

125 views Asked by At

I have a db table with fields like this

posts table

'id'
'group_id'
'name'

I display this table as a list in kartik Select2 widget

$form->field($model, 'post')
    ->widget(
        \kartik\select2\Select2::className(),
        [
            'data' => ArrayHelper::map(Post::find()->all(), 'id', 'name'),
            'options' => [
                'placeholder' => \Yii::t('modules', 'Choose post'),
                'multiple' => true
            ],
            'pluginOptions' => [
                'allowClear' => true,
            ],
        ]
    )->label('');

Now I have in the list all posts in a row from the table are displayed

But I have a group_id field in this table, and the corresponding groups table

'id'
'name'

How can I make it so that the name field from the groups table is displayed as a subtitle in the select and all records are respectively divided into groups depending on the group_id with the corresponding subtitle?

I try something like this but end up with the same group name and the same post name multiple times in the list

$result = [];

$posts = ArrayHelper::map(Post::find()->all(), 'id', 'name');
$groups = Group::find()->all();

foreach ($posts as $post) {
    $groups = $groups[$post->group_id] ?? null;
    if (is_null($groups)) {
        $result[$post->id] = $post->name;
    } else {
        $line = [];
        foreach ($groups as $group) {
            $line[$post->group_id . '-' . $group->id] = $group->name;
        }
        $result[$post->name] = $line;
    }
}
2

There are 2 answers

0
VIPLIKE On BEST ANSWER
$result = [];
$posts = Post::find()->with('group')->all();
foreach($posts as $post){
  $group = $post->group;
  $key = $group->id . '-' . $group->name;
  $result[$key][$post->id] = $post->id . '-' . $post->name;
}

$form = ActiveForm::begin();
echo $form->field($model, 'post')->widget(\kartik\select2\Select2::class, [
  'data'          => $result,
  'options'       => [
    'placeholder' => \Yii::t('modules', 'Choose post'),
    'multiple'    => true,
  ],
  'pluginOptions' => [
    'allowClear' => true,
  ],
]);
ActiveForm::end();

Post model should have Group foreign key relation

0
zivkovicf On

According to documentation https://demos.krajee.com/widget-details/select2#settings solution that will suit your needs would be nested array where key would be group name and items would be posts.

With that structure you will get same output result as in examples with countries and time zones.

Considering your items have following values:

id, name, group_id:
item_id_1, item_name_1, group_id_1, 
item_id_2, item_name_2, group_id_1,
item_id_xy, item_name_xy, group_id_2

you can map your items with ArrayHelper::map() function:

ArrayHelper::map(Post::find()->all(), 'id', 'name', 'group_id')

resulting array would have following structure

[
   'group_id_1' => [
      'item_id_1' => 'item_name_1',
      'item_id_2' => 'item_name_2,
   ],
   'group_id_2' => [
      'item_id_xy' => 'item_name_xy'
   ]
]

then you can iterate that array and fetch group names from database and put as key instead of groupId to display group name, and append to item names if you need more detail group names

$formattedData = [];
foreach ($data as $groupId => $items) {
    $group = Group::findOne($groupId);
    foreach ($items as $item) {
        $formattedData[$group->name][] = [$item['id'] => $item['name'] . ' ' . $group->name];
    }
}