Save multiple selections from a listbox - Yii2 - yii2

I have made a Listbox depend on a dropDownList, when selecting an option from the dropDownList brings me a list of data that is added to the Listbox, it works to save a single option but the problem occurs when trying to save multiple selections, I cannot save more than 1 option, I have tried to add a foreach in my controller but it throws an error.
DropDownList
<?php echo $form->field($model, 'group_id')->widget(Select2::classname(), [
'data' => $seccion->lgrupo, //I get the group list
'size' => Select2::MEDIUM,
'theme' => Select2::THEME_BOOTSTRAP,
'options' => [
'placeholder' => '-- '.Yii::t('backend', 'Select').' --',
'onchange'=>'
$.post( "lists?id="+$(this).val(), function( data ) {//I get the list of people registered in the group and send it to the listbox
$( "select#assignment-user_id" ).html( data );
});',
],
'pluginOptions' => [
'allowClear' => true,
],
'addon' => [
'prepend' => [
'content' => Html::icon('building')
],
]
]); ?>
ListBox
<?php echo $form->field($model2, 'users_id')->listBox([] ,['multiple'=>true,'size'=>17]
); ?>
Groups Controller
public function actionCreate()
{
$model = new Groups();
$model2 = new Assignment();
$seccion = new Group();
if ($model->load(Yii::$app->request->post()) && $model2->load(Yii::$app->request->post())) {
if ($model->save(false)) {
foreach ($model2->users_id as $i => $as) {
$as->assign_group_id = $model->id_group_list;
if ($model2->save()) {
} else {
// error in saving model
}
}
return $this->redirect(['view', 'id' => $model->id_group]);
}
}
return $this->render('create', [
'model' => $model,
'model2' => $model2,
'seccion' => $seccion,
]);
}
Tables
I hope your can tell me what I'm doing wrong.

public function actionCreate()
{
$model = new Groups();
$model2 = new Assignment();
$seccion = new Group();
if ($model->load(Yii::$app->request->post()) && $model2->load(Yii::$app->request->post())) {
if ($model->save(false)) {
foreach ($model2->users_id as $user_id) {
$assignmentModel = new Assignment();
$assignmentModel->user_id= $user_id;
$assignmentModel->assign_group_id = $model->id_group_list;
//$assignmentModel->area= ''; //if you want to set some value to these fields
//$assignmentModel->assignment= '';
if ($assignmentModel->save()) {
} else {
// error in saving model
}
}
return $this->redirect(['view', 'id' => $model->id_group]);
}
}
return $this->render('create', [
'model' => $model,
'model2' => $model2,
'seccion' => $seccion,
]);
}

Related

How to add new values to multiple Select2 from Kartik instead of replace old ones?

I use Select2 widget in multiply mode in YII2 framework. "kartik-v/yii2-widget-select2": "#dev" - this one I have downloaded via composer.
kartik-v/yii2-widget-select2 dev-master dd09e46
I added initial values with ajax on widget init ('initSelection'). And added another ajax method to suggest new values on user's typing. When user select one from list, it replaced initial values what were added on init. New values replace initial values, but don't another new.
I want new values to add to initial instead of replace it.
<?= $form->field($model, 'security[]')->widget(Select2::class, [
'attribute' => 'security',
'hideSearch' => true,
'data'=>$security_data,
'options' => [
'placeholder' => 'Security',
'multiple' => true,
],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 1,
'ajax' => [
'url' => Url::toRoute([ '/admin/security/select-items' ]),
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }'),
'results' => new JsExpression('function(data,page) { return {results:data.results}; }'),
],
'initSelection' => new JsExpression('function(element, callback) { var id = '.Yii::$app->request->getQueryParams()['id'].';if(id !== "") {$.ajax("' . \yii\helpers\Url::toRoute([ '/admin/security/init-items' ]) . '", {data: {id: id},dataType: "json"}).done(function(data) {callback(data.results);});}}'),
],
]); ?>
And here is my api methods:
public function actionSelectItems($q = null){
Yii::$app->response->format = Response::FORMAT_JSON;
$out = ['results' => []];
if(!empty($q)){
$items = Security::find()->where(['like', 'title', $q])->all();
foreach ($items as $item){
$out['results'][] = ['id'=>$item->id, 'text'=>$item->title];
}
}
return $out;
}
public function actionInitItems($id = null){
Yii::$app->response->format = Response::FORMAT_JSON;
$adv = Adv::findOne($id);
$security = #json_decode($adv->security, true);
$out = ['results' => []];
foreach ($security as $item){
$text = Security::findOne($item)->title;
$out['results'][] = ['id'=>$item, 'text'=>$text];
}
return $out;
}
Is there some sort of settings or I missed something when handle http result?

how insert Initial value in yii2 ckeditor

<?=
$form->field($model, 'template')->widget(CKEditor::className(), [
'options' => ['rows' => 100],
'preset' => 'full',
'value'=>'<p>Incercam sa editam</p>',
])->label(true)
?>
This is my code
I need to set initial value in editor
You should assign a value in your field template eg in you controller/create
public function actionCreate()
{
$model = new YourModel();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
$model->template ="your initila value ....... text "
return $this->render('#common/views/antigone-contribuente/create', [
'model' => $model,
]);
}
}
once you have assigne to youe $model->template the value you need yuo should see this in your editor in view

Yii2 Dynamic form update fail on kartik-Select2

I am using wbraganca dynamic form widget. It works fine for the Create action.
Let me thanks for those guys making great tutorial video on youtube!!!
I am working on the Update action now. I work it on a purchase order function.
the controller of update action :
public function actionUpdate($id)
{
$model = $this->findModel($id);
$modelsItem = $model->purchaseitems;
if ($model->load(Yii::$app->request->post()) ) {
$oldIDs = ArrayHelper::map($modelsItem, 'purchaseitem_id', 'purchaseitem_id');
$modelsItem = Model::createMultiple(Purchaseitem::classname(), $modelsItem);
Model::loadMultiple($modelsItem, Yii::$app->request->post());
$deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsItem, 'purchaseitem_id', 'purchaseitem_id')));
$valid = $model->validate();
$valid = Model::validateMultiple($modelsItem) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
if (! empty($deletedIDs)) {
Purchaseitem::deleteAll(['purchaseitem_id' => $deletedIDs]);
}
foreach ($modelsItem as $modelItem) {
$modelItem->purchaseitem_purchaseorder_id = $model->purchaseorder_id;
$modelItem->purchaseitem_description = Inventory::findOne($modelItem->purchaseitem_inventory_id)->inventory_partno;
if (! ($flag = $modelItem->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->purchaseorder_id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
//return $this->redirect(['view', 'id' => $model->purchaseorder_id]);
} else {
return $this->render('update', [
'model' => $model,
'modelsItem' => (empty($modelsItem)) ? [new Purchaseitem] : $modelsItem
]);
}
}
But I think the problem may happen on the view file, as the Select2 field can show the value, which is the 'id' of the product rather than the product code.
view:
<div class="panel panel-default">
<div class="panel-body">
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper',
'widgetBody' => '.container-items',
'widgetItem' => '.item',
'limit' => 50,
'min' => 1,
'insertButton' => '.add-item',
'deleteButton' => '.remove-item',
'model' => $modelsItem[0],
'formId' => 'dynamic-form',
'formFields' => [
'purchaseitem_inventory_id',
'purchaseitem_qty',
'purchaseitem_cost_usd',
'purchaseitem_deliverydate',
],
]); ?>
<?php foreach ($modelsItem as $i => $modelItem): ?>
<div class="item">
<?php
// necessary for update action.
if (! $modelItem->isNewRecord) {
echo Html::activeHiddenInput($modelItem, "[{$i}]purchaseitem_id");
}
?>
<div class="row">
<?= $form->field($modelItem, "[{$i}]purchaseitem_inventory_id")->widget(
Select2::classname(), [
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 2,
'language' => [
'errorLoading' => new JsExpression("function () { return 'Error on finding results...'; }"),
],
'ajax' => [
'url' => Url::toRoute('inventory/inventorylist'),
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),
'templateSelection' => new JsExpression('function (purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),
],
])->label(false) ?>
<?= $form->field($modelItem, "[{$i}]purchaseitem_qty")->textInput(['maxlength' => true])->label(false) ?>
<?= $form->field($modelItem, "[{$i}]purchaseitem_cost_usd")->textInput(['maxlength' => true])->label(false) ?>
<?= $form->field($modelItem, "[{$i}]purchaseitem_deliverydate")->widget(
DatePicker::className(), [
'options' => [
['placeholder' => 'Please enter delivery date'],
],
'removeButton' => false,
'pluginOptions' => [
'autoclose'=>true,
'format' => 'yyyy-mm-dd',
'todayHighlight' => true,
]
]
)->label(false) ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
I have a thought that the problem maybe related to that few lines of JsExpression function.
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),
'templateSelection' => new JsExpression('function (purchaseitem_inventory_id) { return purchaseitem_inventory_id.text; }'),
For the Select2 query URL method is here:
public function actionInventorylist($q = null, $id = null) {
Yii::$app->response->format = yii\web\Response::FORMAT_JSON;
$out = ['results' => ['id' => '', 'text' => '']];
if (!is_null($q)) {
$query = new Query;
$query->select('inventory_id AS id, inventory_partno AS text')
->from('inventory')
->where(['like', 'inventory_partno', $q])
->limit(10);
$command = $query->createCommand();
$data = $command->queryAll();
$out['results'] = array_values($data);
}
elseif ($id > 0) {
$out['results'] = ['id' => $id, 'text' => Inventory::find($id)->inventory_partno];
}
return $out;
}
I can load the record, when I click in the update view. Most of the data are feed in right place of the form, except the 'partno' field. I use Select2 to let user select partno by text and store the 'id' in table. It works on the Create view.
but in the update view, it only show the 'id' instead of the 'partno'.
if I make input to the field, I can select 'other' partno only, let me explain here:
if there are 2 code, "ABC" with 'id' is 1, "XYZ" with 'id' 2.
the record original is "ABC", the field show "1".
If I input "XYZ", it will show "XYZ" as normal effect of widget. But, if I change back to "ABC", it will show "1" instead of "ABC".
And the form also cannot submit for update. the button click with no effect.
I am new to Yii2 framework, and quite stuck on this issue, does anyone knows how can I solve this?
THANKS!!!!
I just solve the problem, a few issue happened actually.
To solve the Select2 widget cannot display the partno instead of the ID, I find the partno by the ID and feed it with initValueText in Select2. For my case:
$partno = empty($modelItem->purchaseitem_inventory_id) ? '':Inventory::findOne($modelItem->purchaseitem_inventory_id)->inventory_partno;
$form->field($modelItem, "[{$i}]purchaseitem_inventory_id")->widget(Select2::classname(), ['initValueText' => $partno, ...
About the update POST fail issue, I got error of Getting unknown property: backend\models\Purchaseitem::id, and I found it happened on the Dynamic-form widgets Model.php line 25. That lines is $keys = array_keys(ArrayHelper::map($multipleModels, 'id', 'id'));
If I change the 'id' to my ID field name, i.e 'purchaseitem_id', it will work, but this model will only work for this Id field name afterward. So I get the model's primaryKey and make it work for my other model.
add this line $primaryKey = $model->tableSchema->primaryKey; and modify above line $keys = array_keys(ArrayHelper::map($multipleModels, $primaryKey, $primaryKey));

Yii2 renderPartial clientSide validation doesn't work

renderPartial clientSide validation doesn't work. I want to render part of form with ajax. Ex.:
_form.php
$form = ActiveForm::begin([
'options' => [
'enableAjaxValidation' => true,
]
]);
$form->field($model, 'category_id')->dropDownList($category, [
'onchange'=>'
$.get( "'.Url::toRoute('/controller/params').'", { id: $(this).val() } )
.done(function( data ) {
$( "#offers-param-content" ).html( data );
}
);'
]);
Controller.php
public function actionParams($id)
{
$model = new Param();
$params = EavAttribute::find()->where(['category_id'=>$id])->all();
$this->renderPartial('_params', ['model' => $model, 'params' => $params];
}
_params.php
foreach($params as $item){
echo Html::activeTextInput('text', $model, $item->name);
}
If you want to enable client validation, then set this property to true.
$form = ActiveForm::begin([
'options' => [
'enableAjaxValidation' => true,
'enableClientValidation'=>true
]
]);
And use renderAjax() function in place of renderPartial() it will inject into the rendering result with JS/CSS scripts and files which are registered with the view
In your Controller.php you need to set layout to false and die the execution
public function actionParams($id)
{
$this->layout = false;
$model = new Param();
$params = EavAttribute::find()->where(['category_id'=>$id])->all();
$this->renderPartial('_params', ['model' => $model, 'params' => $params];
die;
}
Your not returning any validation errors from your controller to your view.
To archive that use
yii\widgets\ActiveForm::validate($yourModel);
If your not using activeform you can return errors by
$model->getErrors();//will return errors from $model->validate()
From your excerpt try this
public function actionParams($id) {
$model = new Param();
if ($model->load(Yii::$app->request->post())) {
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return ActiveForm::validate($model); /* Validation error messages are returned by this static function */
}
$params = EavAttribute::find()->where(['category_id' => $id])->all();
$this->renderPartial('_params', ['model' => $model, 'params' => $params]);
}
}

Selected Value is not showing in Kartik Select2 multiple select

This is my view file:
<?php
$data = array();
echo '<label class="control-label">Attribute Group Name</label>';
echo Select2::widget([
'name' => 'attribute_grp_name',
'data' => $attribute_group_name, // initial value
'options' => ['placeholder' => 'Please Enter Attribute Group Name', 'multiple' => true],
'pluginOptions' => [
'attribute_grp_name' => true,
'maximumInputLength' => 100,
],
]);
?>
In my view here selected data is not showing.
This is my controller for create and update function:
public function actionCreate()
{
$model = new AttributeSet();
$attribute_group = AttributeGroupLang::find()->select('*')->all();
$attribute_group_name = ArrayHelper::map($attribute_group, 'id_attribute_group', 'name');
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$post_array = Yii::$app->request->post();
foreach ($post_array['attribute_grp_name'] as $key => $value) {
$attribute_set_group_combination = new AttributeSetGroupCombination();
$attribute_set_group_combination->id_attribute_set = $model->id_attribute_set;
$attribute_set_group_combination->id_attribute_group = $value;
$attribute_set_group_combination->save(false);
}
return $this->redirect(['view', 'id' => $model->id_attribute_set]);
} else {
return $this->render('create', [
'model' => $model,
'attribute_group_name' => $attribute_group_name,
]);
}
}
This is update function:
public function actionUpdate($id)
{
$model = $this->findModel($id);
$attribute_set_group_combination = AttributeSetGroupCombination::find()->where(['id_attribute_set' => $id])->all();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$post_array = Yii::$app->request->post();
if(!empty($post_array['attribute_grp_name'])){
AttributeSetGroupCombination::deleteAll('id_attribute_set = '.$id);
foreach ($post_array['attribute_grp_name'] as $key => $value) {
$attribute_set_group_combination = new AttributeSetGroupCombination();
$attribute_set_group_combination->id_attribute_set = $model->id_attribute_set;
$attribute_set_group_combination->id_attribute_group = $value;
$attribute_set_group_combination->save(false);
}
}
return $this->redirect(['view', 'id' => $model->id_attribute_set]);
} else {
return $this->render('update', [
'model' => $model,
'attribute_set_group_combination' => $attribute_set_group_combination,
'attribute_group_name' => $this->getExistAttrSet($id),
]);
}
}
public function getExistAttrSet($id){
$query = new Query;
$query->select(['attribute_group_lang.name AS attribute_group_name','attribute_group_lang.id_attribute_group'])
->from('attribute_set_group_combination')
->join('LEFT OUTER JOIN', 'attribute_set', 'attribute_set.id_attribute_set =attribute_set_group_combination.id_attribute_set')
->join('LEFT OUTER JOIN', 'attribute_group_lang', 'attribute_group_lang.id_attribute_group =attribute_set_group_combination.id_attribute_group')
->where('attribute_set.id_attribute_set='.$id)
->all();
$command = $query->createCommand();
$model = $command->queryAll();
$data = array();
foreach ($model as $attrsetlist[]) {
$data = ArrayHelper::map($attrsetlist, 'id_attribute_group', 'attribute_group_name');
}
return $data;
}
Can anyone help me that how can i show the selected value in the multiple select field.
You just need to pass in model value:
<?php
echo kartik\select2\Select2::widget([
'name' => 'some_field_name',
// ----------------------
'value' => 'a',
//'value' => ['a', 'b'],
//'value' => $model->some_value,
// ----------------------
'data' => ['a'=>'a', 'b'=>'b', 'c'=>'c'],
'options' => ['placeholder' => 'Select menu items ...', ],
]);
?>