How to organize multiselect dropdownlist using kartik-select2 extension - php

I need to organize multiselect dropdownlist. I tried like this:
<?= $form->field($model, 'receiver_id')->widget(Select2::classname(),
[ 'data' => ArrayHelper::map(User::find()->all(),'id','username'),
'options' =>
['placeholder' => 'Select receivers...', 'multiple' => true],
'pluginOptions' =>
[ 'tags' => true,
'maximumInputLength' => 10
],
]);
?>
In the view it seems correctly, in the textfield receivers appear one by one, but when I press "Send" button it says that Receiver ID must be an integer. How can I solve this issue? I need to duplicate one db record for different receivers which I select using select2 dropdown list. For example, I choose in dropdownlist user1 and user2, "Send" action should work twice accordingly. In the db table named as 'letter' should be two same records with different id and receiver_id.
My actionCreate function in the Controller class:
public function actionCreate()
{
$model = new Letter();
if ($model->load(Yii::$app->request->post())) {
foreach($model->receiver_id as $r_id){
$save = new Letter();
$save->type_id = $model->type_id;
$save->subject = $model->subject;
$save->body = $model->body;
$save->sender_id = $model->sender_id;
$save->start_date = $model->start_date;
$save->end_date = $model->end_date;
$save->receiver_id = $r_id;
$save->save();
}
$model->attachment = UploadedFile::getInstance($model, 'attachment');
$filename = pathinfo($model->attachment , PATHINFO_FILENAME);
$ext = pathinfo($model->attachment , PATHINFO_EXTENSION);
$newFname = $filename.'.'.$ext;
$path=Yii::getAlias('#webroot').'/uploads/';
if(!empty($newFname)){
$model->attachment->saveAs($path.$newFname);
$model->attachment = $newFname;
if($model->save()){
return $this->redirect(['view', 'id' => $model->id]);
}
}
}
return $this->render('create', [
'model' => $model,
]);
}
My IDE says on "$model->receiver_id" that "Expected types array or object, Actual: int"
Thanks in advance.

do receiver_id as array on your model; and
foreach($model->receiver_id as $r_id){
$save = new YourModel();
$save->yourProperty = $model->yourProperty;
....
$save->receiver_id = $r_id;
$save->save();
}

Related

Yii2 controller not saving all data

I am working on yii2. I have a form in which there are 3 dropdowns.
use kartik\select2\Select2;
<div class="allow-area-form">
<?php $form = ActiveForm::begin(); ?>
<?=
$form->field($model, 'city_name')
->widget(Select2::className(),[
'data' => \common\models\AllowArea::toCityArrayList(),
'options' => ['placeholder'=>'Select Area'],
'pluginOptions' => [
'allowClear' => true,
'multiple' => true
],
]);
?>
<?=
$form->field($model, 'user_id')
->widget(Select2::className(),[
'data' => \app\models\User::toArrayList(),
'options' => ['placeholder'=>'Select a User'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?=
$form->field($model, 'salesman_code')
->widget(Select2::className(),[
'data' => \common\models\AllowArea::toArrayList(),
'options' => ['placeholder'=>'Select A Booker'],
'pluginOptions' => [
'allowClear' => true,
],
]);
?>
<div class="form-group">
<?= Html::submitButton(Yii::t('app', 'Save'), ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
Interface
In, the above the areas can be selected multiple. Users can only be one and a booker is also one. A single area have multiple sub-areas. So when the main area is selected all of its sub-areas are allotted to a user. So for example, if I select 3 Main-Areas and each of them has 10 sub-areas, a single user is allowed 30 sub-areas. For this purpose, I have implemented the following in my controller
public function actionCreate()
{
$model = new AllowArea();
if (isset($_REQUEST['AllowArea'])) {
try {
$m = new AllowArea();
foreach ($_REQUEST['AllowArea']['city_name'] as $a=>$b)
{
$sql = "select AreaCode from area where CityNameFull = '$b'";
$res = Yii::$app->sds->createCommand($sql)->queryAll();
foreach ($res as $r)
{
$m->load(Yii::$app->request->post());
$areacode = $r['AreaCode'];
$query = "select AreaNameFull from area where AreaCode = '$areacode'";
$rst = Yii::$app->sds->createCommand($query)->queryOne();
$areaname = $rst['AreaNameFull'];
$m->area_code = $areacode;
$m->area_name = $areaname;
$m->user_id = $m['user_id'];
$m->user_name = AllowArea::idTouser($m['user_id']);
$m->salesman_code = $m['salesman_code'];
$m->salesman_name = AllowArea::idTousersalesman($m['salesman_code']);
$m->city_name =$b;
$m->created_by = Yii::$app->user->id;
$m->created_at = date('Y-m-d H:i:s');
$m->save();
}
}
}catch (Exception $e) {
return $this->redirect(['index']);
}
return $this->redirect(['index']);
}
return $this->render('create', [
'model' => $model
]);
}
Data
Below is the database table result of a single selected main area.
So if I select ALLAMA IQBAL TOWN-01(ALL-BLOCK) in the main area, all of the 20 sub-areas should be saved. But my controller only saves the last ZEENAT BLOCK AIT sub-area and leaves the rest of the remaining.
I have also checked the data inside the 3rd foreach loop, it does get the first item but saves the last one so it means that all of the 20 sub-areas are inside the loop.
There must be some mistake that my code is not saving the data and I am stuck in it.
How to save all the data?
Any help would be highly appreciated.
You are reusing the same AllowArea model $m so it is adding a single entry to your table and updating it 19 times. Move the $m = new AllowArea() into the loop:
try {
foreach ($_REQUEST['AllowArea']['city_name'] as $a=>$b)
{
$sql = "select AreaCode from area where CityNameFull = ':cityName'";
$res = Yii::$app->sds->createCommand($sql, [':cityName' => $b])->queryAll();
foreach ($res as $r)
{
$m = new AllowArea();
...
As an aside, your code is vulnerable to SQL injection since you aren't validating the value of $b so you should use a prepared statement instead as in the code above or consider using the ActiveRecord functions to fetch the AreaCodes.

yii2 kartik multi select with relation table error "Call to a member function isAttributeRequired() on array"

I encountered above error while update scenario, am trying to save the multi selected values into relation table('classification_vs_metric') along with master tables(classifications,metrics) id's in create metrics.
but when i click on edit button on already created record i encounter this error.
Metrics Master
id
name
type
3
Land
ha,m2
4
Floors
Nos
Classification Master
id
industry
sector
subsector
1
Construction
Commercial
Casino
2
Construction
Commercial
Cinema
3
Construction
Commercial
Convention Center
classification_vs_metric slave/relation table
id
metric_id
classification_id
1
3
1
2
3
2
3
3
3
4
4
1
5
4
2
and am using following method to get the slave table values in actionUpdate in metrics controller
public function getClassificationVsMetrics1()
{
return $this->hasMany(Classificationvsmetric::className(), ['metric_id' => 'id'])->select(['classification_id']);
}
as
public function actionUpdate($id)
{
$model = $this->findModel($id);
$classificationIndustry = array();
$releations = $model->getClassificationVsMetrics1()->asArray()->all();
if ($model->load(Yii::$app->request->post())) {
if($model->save()){
$classifications = Yii::$app->request->post()["Classificationvsmetric"]['classification_id'];
$classVsmetric = Classificationvsmetric::deleteAll(['metric_id'=>$model->id]);
foreach ($classifications as $key => $value) {
$Classificationvsmetric = new Classificationvsmetric();
$Classificationvsmetric->classification_id =(int)$value;
$Classificationvsmetric->metric_id = $model->id;
$Classificationvsmetric->save(false);
}
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('update', [
'model' => $model,
'Classificationvsmetric' => $releations
]);
}
and in _form.php
$classificationIndustry = ArrayHelper::map(\common\models\Classifications::find()->all(),'id',function($model,$default){
return $model["industry"]." - ".$model["sector"] ." - ".$model['sub_sector'];
});
echo $form->field($Classificationvsmetric[0], 'classification_id')->widget(Select2::classname(), [
'data' => $classificationIndustry, // error showing in this line
'value'=>(!$model->isNewRecord ? [$result] : ''),
'language' => 'en',
'options' => ['placeholder' => 'Select classification(s)','multiple' => true],
'pluginOptions' => [
'allowClear' => true,
],
]);
this is working fine with create scenario, but getting error "Call to a member function isAttributeRequired() on array" in edit scenario. Can any body help me !!
Finally after 2 days of head scratching i find solution myself.
I have made few minor changes like below
In metric master
public function getClassificationVsMetrics1()
{
return $this->hasMany(Classificationvsmetric::className(), ['metric_id' => 'id']);
}
In metric controller
public function actionUpdate($id)
{
$model = $this->findModel($id);
$releations = $model->getClassificationVsMetrics1()->all();
if ($model->load(Yii::$app->request->post())) {
if($model->save()){
$classifications = Yii::$app->request->post()["Classificationvsmetric"]['classification_id'];
$classVsmetric = Classificationvsmetric::deleteAll(['metric_id'=>$model->id]);
foreach ($classifications as $key => $value) {
$Classificationvsmetric = new Classificationvsmetric();
$Classificationvsmetric->classification_id =(int)$value;
$Classificationvsmetric->metric_id = $model->id;
$Classificationvsmetric->save(false);
}
if($Classificationvsmetric == true){
return $this->redirect(['view', 'id' => $model->id]);
}
}
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('update', [
'model' => $model,
'Classificationvsmetric' => $releations
]);
}
and in view am managed to pass the values stored in the slave table as default value for select2 widget.
<?php
$classificationIndustry = ArrayHelper::map(\common\models\Classifications::find()->all(),'id',function($model,$default){
return $model["industry"]." - ".$model["sector"] ." - ".$model['sub_sector'];
});
foreach ($Classificationvsmetric as $key => $value) {
$selected[] = $value['classification_id'];
}
echo $form->field($Classificationvsmetric[0], 'classification_id')->widget(Select2::classname(), [
'data' => $classificationIndustry,
'language' => 'en',
'options' => [ 'value'=>(!$model->isNewRecord ? $selected : ''),'placeholder' => 'Select classification(s)','multiple' => true],
'pluginOptions' => [
// 'disabled' => $is_readonly,
'allowClear' => true,
// 'maximumSelectionLength' => 3,
],
]);
?>
i know this is not feasible solution, but right now this will save my butt.
preselected values in select2 widget in update scenario with many to many relation

Create new record using 2amigos SelectizeDropDownList in Yii2

I am trying to implement the 2amigos SelectizeDropDownList widget in a form to add new values to a table directly within the dropdown.
I am using the model Book and the Model Author so basically want to be able to add a new author in the book form.
This is the book controller at the update function:
public function actionUpdate($id) {
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['index']);
} else {
return $this->render('update', [
'model' => $model,
'categories' => BookCategory::find()->active()->all(),
'publishers' => Publisher::find()->all(),
'copirights' => Copiright::find()->all(),
'authors' => Author::find()->all(),
]);
}
}
This is the form:
<?=
$form->field($model, 'author_id')->widget(SelectizeDropDownList::className(), [
// calls an action that returns a JSON object with matched
// tags
'loadUrl' => ['author/list'],
'value' => $authors,
'items' => \yii\helpers\ArrayHelper::map(\common\models\author::find()->orderBy('name')->asArray()->all(), 'id', 'name'),
'options' => [
'class' => 'form-control',
'id' => 'id'
],
'clientOptions' => [
'valueField' => 'id',
'labelField' => 'name',
'searchField' => ['name'],
'autosearch' => ['on'],
'create' => true,
'maxItems' => 1,
],
])
?>
And this is the function author controller:
public function actionList($query) {
$models = Author::findAllByName($query);
$items = [];
foreach ($models as $model) {
$items[] = ['id' => $model->id, 'name' => $model->name];
}
Yii::$app->response->format = \Yii::$app->response->format = 'json';
return $items;
}
The form works fine to load, filter, search and add new items.
But it is not inserting the new typed attribute in the author table.
Do I need to add something in the book controller?
How can I check if it is a new value or a change of an existing author?
Thanks a lot
I made it work with the following code, not sure the most elegant because i am checking the if the author_id is a number or a string.
In my case the author won't be a number anyway.
public function actionUpdate($id) {
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post())) {
$x = Yii::$app->request->post('Book');
$new_author = $x['author_id'];
if (!is_numeric($new_author)) {
$author = new Author();
$author->name = $new_author;
$author->save();
$model->author_id = $author->id;
}
if ($model->save()) {
return $this->redirect(['index']);
}
} else {
return $this->render('update', [
'model' => $model,
'categories' => BookCategory::find()->active()->all(),
'publishers' => Publisher::find()->all(),
'copirights' => Copiright::find()->all(),
'authors' => Author::find()->all(),
]);
}
}

Radio Button - Yii2-Basic-App

In radio button, value is coming. But, I want to display the name of that value.
my user_types (table)
id type status created_at
1 An Individual 1 2015
2 Firm 1 2015
UserController.php (controller)
public function actionRegister()
{
$model = new Users();
.
.
$modelUserType=UserType::find()->select(['id', 'type'])->where(['status' => 1])
->indexBy("id")->column();
return $this->render('register', [
'model' => $model,
'modelUserType'=>$modelUserType,
'module' => $this->module,
]);
}
register.php (view)
.
.
<?=
$form->field($model, 'user_type')
->radioList($type)
->label('Are You')
?>
.
.
It's coming like this.
I want like this
So any idea how to bring 'type' column to display instead of 'id' column.
Mr Partykar and now i understand you.This is my answer.This is work to me also for render list of radio buttons. Please, reply this is fix your problem
public function actionRegister()
{
$model = new Users();
.
.
$modelUserType=UserType::find()->select(['id', 'type'])->where(['status' => 1])->asArray()->all();
$type=[];
foreach($modelUserType as $k=>$v){
if(is_array($v))$type[$v["id"]]=$v["type"];
}
return $this->render('register', [
'model' => $model,
'type'=>$type,
'module' => $this->module,
]);
}

CMultiFileUpload class not inserting image names on the database yii

I'm working on multi file(images) uploading functionality.
I've tried everything I got.
It's not working.
It's uploading images on the path I specified but not inserting image's names on the table column.
The table's column name is "sample"
Here's the snippet of the view:
$this->widget('CMultiFileUpload', array(
'model' => $model,
'name' => 'sample',
'attribute' => 'sample',
'accept' => 'jpeg|jpg|gif|png',
'duplicate' => 'Duplicate file!',
'denied' => 'Invalid file type',
'remove' => '[x]',
'max' => 20,
));
This is the controller's code the(the function that dealing with the part):
public function actionCreate($project_id) {
$model = new Bid();
$project = $this->loadModel('Project', $project_id);
if (count($project->bids) == 5) {
Yii::app()->user->setFlash('warning', Yii::t('bids', 'This project has already reached its maximum number of bids, so you cannot post a new bid.'));
$this->redirect(array('project/view', 'id' => $project_id));
}
if (!empty($project->bid)) {
Yii::app()->user->setFlash('warning', Yii::t('bids', 'This project has a selected bid already, so you cannot post a new bid.'));
$this->redirect(array('project/view', 'id' => $project_id));
}
if ($project->closed) {
Yii::app()->user->setFlash('warning', Yii::t('bids', 'You cannot add bids as this project has been closed.'));
$this->redirect(array('project/view', 'id' => $project_id));
}
$model->project = $project;
if (isset($_POST['Bid'])) {
$model->attributes = $_POST['Bid'];
$photos = CUploadedFile::getInstancesByName('sample');
if (isset($photos) && count($photos) > 0) {
foreach ($photos as $image => $pic) {
$pic->name;
if ($pic->saveAs(Yii::getPathOfAlias('webroot').'/images/'.$pic->name)) {
// add it to the main model now
$img_add = new Bid();
$img_add->filename = $pic->name;
$img_add->save();
}
else {
}
}
}
$model->project_id = $project->id;
$model->freelancer_id = $this->currentUser->id;
if ($model->save()) {
$this->redirect(array('project/view', 'id' => $project->id, '#' => 'bidslist'));
}
}
$this->render('create', array(
'model' => $model,
));
}
Thanks in Advance.
Please let me know if anyone needs anything else for better understanding.
If i underssot you correctly when you saving the model
$img_add = new Bid();
$img_add->sample = $pic->name;
$img_add->save();

Categories