I have a task to make the following functionality:
The case is I need to be able to add to the table below items from the drop-down menu, so they should be either in drop-down (if tag is not added to the Material model) or in the table (if tag is added). I could easily hard-code it, but it’s also required Add(big blue button) button to add tags and delete button to remove them, which I have no idea how to implement. Tags are stored in another model which has no relation to Material, tags in Material are stored as a string divided by comma. Here’s what I’ve managed to do so far:
Controller:
public function actionView(int $id): string
{
$tagSearchModel = new TagSearch();
$tagDataProvider = $tagSearchModel->search($this->request->queryParams);
$model = $this->findModel($id);
$tagsInModel = explode(', ', $model->tags);
$tag = new Tag();
$allTags = ArrayHelper::map($tag::find()->all(), 'id', 'name');
$unUsedTags = [];
foreach ($allTags as $oneTag) {
if (!in_array($oneTag, $tagsInModel)){
$unUsedTags[] = $oneTag;
}
}
return $this->render('view', [
'model' => $model,
'unUsedTags' => $unUsedTags,
'tagDataProvider' => $tagDataProvider
]);
}
View:
<div class="col-md-6">
<form>
<h3>Теги</h3>
<?php $form = ActiveForm::begin(); ?>
<div class="input-group">
<?= $form->field($model, 'type')->dropDownList(
$unUsedTags,
['prompt' => 'Выберите тип', 'style' => 'width: 270px']
)->label(false) ?>
<?= Html::submitButton('Добавить', ['class' => 'btn btn-primary mb-3',])?>
</div>
<?php ActiveForm::end(); ?>
</form>
</div>
<?= GridView::widget([
'dataProvider' => $tagDataProvider,
'summary' => '',
'tableOptions' => [
'class' => 'table table-responsive',
],
'columns' => [
[
'attribute' => 'name',
'label' => 'Название',
'value' => function (Tag $model) {
return Html::a(
$model->name,
['index', 'search_query' => $model->name],
[
'title' => 'View',
]
);
},
'headerOptions' => ['style' => 'width:90%;'],
'header' => false,
'format' => 'raw',
],
[
'class' => ActionColumn::class,
'template' => '{delete}',
'urlCreator' => function ($action, Tag $model, $key, $index, $column) {
return Url::toRoute([$action, 'id' => $model->id]);
}
],
],
]); ?>
TagSearch model:
class TagSearch extends Tag
{
/**
* {@inheritdoc}
*/
public function rules(): array
{
return [
[['id'], 'integer'],
[['name'], 'safe'],
];
}
/**
* {@inheritdoc}
*/
public function scenarios(): array
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* @param array $params
*
* @return ActiveDataProvider
*/
public function search(array $params): ActiveDataProvider
{
$query = Tag::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
]);
$query->andFilterWhere(['like', 'name', $this->name]);
return $dataProvider;
}
}
