Yii2 : kartik Select2 - php

I have 2 select2 dropdownlist the second depends on data from the first one
the first one code :
<?= $form->field($model, 'patient_id')->widget(select2::className(),[
'data'=> arrayhelper::map(patient::find()->all(),'patient_id','patient_name'),
'options'=>['placeholder'=>'select patient Name ... '],
'pluginOptions'=>[
'allowClear'=>true
],
])?>
the second one code :
<?= $form->field($model, 'doctor_id')->widget(select2::className(),[
'data'=> arrayhelper::map(doctors::find()->all(),'doctor_id','doctor_name'),
'options'=>['placeholder'=>'أختر اسم الطبيب '],
'pluginOptions'=>[
'allowClear'=>true
],
])?>
i know the sql code in the second one is :
select doctor_name from doctors
so i need it to be :
SELECT DISTINCT doctor_name from doctors where doctor_id in (SELECT doctor_id from patient_services WHERE patient_id="THE VALUE FROM THE 1st DROPDOWNLIST" )
in the regular dropdownlist it work by like this way Yii2 Lesson - 20 Dependent Drop Down Lists By DoingITeasyChannel but in select2 i didn't find how to do it .
------------------------------- after update ----
as the comments there is DepDrop but i got confused how to use it.
i've changed
<?= $form->field($model, 'patient_id')->widget(Select2::classname(), [
'data' => ArrayHelper::map(patient::find()->asArray()->all(), 'patient_id', 'patient_name')]);
?>
and the other one is :
<?= $form->field($model, 'doctor_id')->widget(DepDrop::classname(), [
'options' => ['placeholder' => 'Select ...'],
'type' => DepDrop::TYPE_SELECT2,
'select2Options'=>['pluginOptions'=>['allowClear'=>true]],
'pluginOptions'=>[
'depends'=>['receipts-doctor_id'], // here i got confused
'url' => Url::to(['/receipts/child']),
'loadingText' => 'Loading child level 1 ...',
]
]);
?>
in controller
public function actionChild() {
$out = [];
if (isset($_POST['depdrop_parents'])) { // what they meaning by depdrop_parents or what i should change it ?
$id = end($_POST['depdrop_parents']);
$list = Account::find()->andWhere(['parent'=>$id])->asArray()->all();
$selected = null;
if ($id != null && count($list) > 0) {
$selected = '';
foreach ($list as $i => $account) {
$out[] = ['id' => $account['id'], 'name' => $account['name']];
if ($i == 0) {
$selected = $account['id'];
}
}
// Shows how you can preselect a value
echo Json::encode(['output' => $out, 'selected'=>$selected]);
return;
}
}
echo Json::encode(['output' => '', 'selected'=>'']);
}

First field (Select2):
<?= $form->field($model, 'patient_id')->widget(Select2::classname(), [
'data' => ArrayHelper::map(patient::find()->asArray()->all(), 'patient_id', 'patient_name')]);
?>
Second field (DepDrop):
<?= $form->field($model, 'doctor_id')->widget(DepDrop::classname(), [
'options' => ['placeholder' => 'Select ...'],
'type' => DepDrop::TYPE_SELECT2,
'select2Options'=> ['pluginOptions' => ['allowClear' => true]],
'pluginOptions'=> [
'depends' => ['receipts-doctor_id'],
'url' => Url::to(['/receipts/child']),
'loadingText' => 'Loading child level 1 ...',
]
]);
?>
Plugin option 'depends' => ['receipts-doctor_id'], shows which element (takes element's ID) must be changed (on click, on select, etc.) in order to send Ajax request and retrieve results from controller. In this case, an element with ID receipts-doctor_id should be present. If you don't know or you want to set ID for parent element, you can use 'options' => ['id' => 'receipts-doctor_id'], for your parent element.
And for controller, you can retrieve value like this:
public function actionChild()
{
$depdropParents = Yii::$app->request->post('depdrop_parents');
if ($depdropParents !== null) {
$value = $depdropParents[0];
// Now your $value contains what was being selected in parent element
}
}

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 - Removing an item from the dropDownList

In my ticket form I have a dropDownList for the employees, and in the employees model I have employee_status which is 'Available', 'Not Available'
If I change the status of the employee to 'Not Available' how am I going to remove it automatically from the dropDownList in Ticket form?
The Employee Dropdown from Ticket
<?= $form->field($model, 'employee_id')->dropDownlist(
ArrayHelper::map(Employee::find()->all(), 'id', 'employee_name'),
[
'prompt' => 'Select Employee ID',
'style' => 'width:200px'
]); ?>
You need to create a dependent dropdown for get employee list according to employee_status.Write down below code in view file for creating dependent dropdown :-
use yii\helpers\ArrayHelper;
echo $form->field($model, 'employee_status')->dropDownList([0=>'Available' , 1 => 'Not Available'],
[
'prompt' => 'Select Employee Status',
'style' => 'width:200px',
'onchange'=>'$.post( "'.Yii::$app->urlManager->createUrl('site/get-employee?status=').'"+$(this).val(), function( data ) {
$( "select#employee-employee_id" ).html( data );
});']);
<?= $form->field($model, 'employee_id')->dropDownlist(
ArrayHelper::map(Employee::find()->all(), 'id', 'employee_name'),
[
'prompt' => 'Select Employee ID',
'style' => 'width:200px'
]); ?>
Now write a controller action for get data for child dropdown. Controller action code like below :-
SiteController.php
public function actionGetEmployee($status)
{
$employee= \common\models\Employee::find()
->where(['status' => $status])
->orderBy('id DESC')
->all();
if (!empty($employee)) {
foreach($employee as $employee) {
echo "<option value='".$employee->id."'>".$employee->name."</option>";
}
} else {
echo "<option>-</option>";
}
}
Note : change the model namespace according to your code.
Perform a find query with your given criteria.
Since we only ever want available employees in our list, we can write:
Employee::find('status=:status', [
':status' => 'Available'
])->all();
I finally get it
<?= $form->field($model, 'employee_id')->dropDownlist(
ArrayHelper::map(Employee::find()->where(['status' => 'Available'])->all(), 'id', 'employee_name'),
[
'prompt' => 'Select Employee ID',
'style' => 'width:200px'
]); ?>

Yii2 Dependent Dropdown Data Not Show

I am using krajee yii2 depdrop in my form. I follow the instruction and my data still not show on depdrop.
This is my _form.php code :
<?php echo $form->field($model, 'id_trayek')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Trayek::find()->all(), 'id_trayek', 'nama_trayek'),
'language' => 'en',
'theme' => Select2::THEME_KRAJEE,
'options' => ['id' => 'id_trayek', 'placeholder' => '-- Pilih Trayek --', 'class' => 'form-control'],
]); ?>
<?php
echo $form->field($model, 'no_bus')->widget(DepDrop::classname(), [
'type'=>DepDrop::TYPE_SELECT2,
'options' => ['id'=>'no_bus', 'class'=>'form-control'],
'pluginOptions'=>[
'depends'=>['id_trayek'],
'placeholder' => '-- Pilih Bus --',
'url' => Url::to(['/surat-jalan/bus'])
]
]);
?>
This is my controller for depdrop url :
public function actionBus() {
$out = [];
if (isset($_POST['depdrop_parents'])) {
$id_trayek = end($_POST['depdrop_parents']);
$jenis_bus = Trayek::find()->select('jenis_bus')->andWhere(['id_trayek'=>$id_trayek]);
$list = Bus::find()->andWhere(['jenis_bus'=>$jenis_bus])->asArray()->all();
$selected = null;
if ($id_trayek != null && count($list) > 0) {
$selected = '';
foreach ($list as $i => $bus) {
$out[] = ['no_bus' => $bus['no_bus'], 'no_bus' => $bus['no_bus']];
}
echo Json::encode(['output' => $out, 'selected'=>$selected]);
return;
}
}
echo Json::encode(['output' => '', 'selected'=>'']);
}
in console, I found JSON response is OK and error : TypeError: id is undefined on file dependendent-dropdown.js (line 39, col 49)
Error from console
This line is not correct:
$out[] = ['no_bus' => $bus['no_bus'], 'no_bus' => $bus['no_bus']];
Dependent dropdown requires the first array element to be id and the second one to be name. Change to this:
$out[] = ['id' => $bus['no_bus'], 'name' => $bus['no_bus']];

Assigning function to value attribute in details view yii2 [duplicate]

This question already has answers here:
Changing value of an attribute in DetailView widget
(2 answers)
Closed 6 years ago.
I am trying to assign a value of a function to 'value' in DetailView. But when I try that I get the error "Object of class Closure could not be converted to string"
I tried returning the value of the function by assigning it to another variable too but still the same error.
Can someone help me figure it out please?
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'Task_ID',
'Task_Title',
'Description',
'projects.project_name', //display project name instead of project id
// 'Assign_task_to',
//'tasksemp.Employee_ID',
[
'attribute' => 'Assign_task_to',
'format' => 'raw',
$data = function ($model) {
$assignEmpModel = Tasksemp::find()->where(['Task_ID' => $model->Task_ID])->all(); //get all the rows with teh same task_id
$employes = ''; //empty string
foreach ( $assignEmpModel as $employee ) {
$emp = Employee::find()->where(['Employee_ID'=>$employee->Employee_ID])->one(); //get all the employee_id
$name = $emp['employee_name']; //get the employee_name from the employees table
$employes .= ' '.$name.', '; //concatenate the names.
}
// return implode(', ',$employes);
//return $employes;
},
'value' => $data,
],
'start_date',
'due_date',
'priotiy_level',
'upload_documents',
],
]) ?>
I have tried assigning the function to a variable $data but doesn't work.
I have tried assigning the function directly to the value as well but same error.
[
'attribute' => 'Assign_task_to',
'format' => 'raw',
'value' => function ($model) { //<----- ERROR HERE!
$assignEmpModel = Tasksemp::find()->where(['Task_ID' => $model->Task_ID])->all(); //get all the rows with teh same task_id
$employes = ''; //empty string
foreach ( $assignEmpModel as $employee ) {
$emp = Employee::find()->where(['Employee_ID'=>$employee->Employee_ID])->one(); //get all the employee_id
$name = $emp['employee_name']; //get the employee_name from the employees table
$employes .= ' '.$name.', '; //concatenate the names.
}
return $employes;
},
],
Tried Bizley's solution like this:
<?php $assignEmpModel = Tasksemp::find()->where(['Task_ID' => $model->Task_ID])->all(); //get all the rows with teh same task_id
$employes = ''; //empty string
foreach ( $assignEmpModel as $employee ) {
$emp = Employee::find()->where(['Employee_ID'=>$employee->Employee_ID])->one(); //get all the employee_id
$name = $emp['employee_name']; //get the employee_name from the employees table
$employes .= ' '.$name.', '; //concatenate the names.
?>
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'Task_ID',
'Task_Title',
'Description',
'projects.project_name', //display project name instead of project id
// 'Assign_task_to',
//'tasksemp.Employee_ID',
[
'attribute' => 'Assign_task_to',
'format' => 'raw',
'value' => $employes,
],
'start_date',
'due_date',
'priotiy_level',
'upload_documents',
],
]) ?>
But now the error says unexpected end of file.
DetailView doesn't allow closure for the value because there is no need for it since DetailView operates on single model (doesn't iterate on many models like GridView).
Your first approach is totally bad because you try to push some code between the array elements. Second approach is ok but no closure allowed here.
Simply just take the code that is the body of your function ($model) (of course without the return part) and put it above the <?= DetailView::widget(... and then use the $employes variable for the value inside.
[
'attribute' => 'Assign_task_to',
'format' => 'raw',
'value' => $employes,
],
You can use custom functions to get a value in DetailView.
Use call_user_func() to achieve this:
<?= \yii\widgets\DetailView::widget([
'model' => $yourModel,
'attributes' => [
[
'label' => 'Your label',
'value' => call_user_func(function ($model) {
// do what you like
// return your value;
}, $yourModel),
],
// more attributes
]
]); ?>

how to get merged array list data in GridView Yii2

Here I have two tables
Employeedetails
Claimprocess
In employeedetails I have 8 columns:
Company_name, Employeecode, Employee_name, father_name, mother_name, wife_name, child1_name, and child2_name.
In Claimprocess table I have 5 columns:
Company_name, Employeecode, Employee_name, Healthcard_no, and claim_for.
In Claimprocess I set a dependent dropdown for employeecode. For example, if admin selects a company_name that automatically shows dependent employeecode, then again admin selects an employeecode that automatically shows the employee_name and employee relations name such as father_name, mother_name, wife_name etc...
This is the dependent dropdown code for employee_code by selecting company_name
claimform.php
<?= $form->field($model, 'company_id')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Company::find()->all(),'id','companyname'),
'language' => 'en',
'options' => [
'placeholder' => 'Select a company ...',
'onchange' => '
$.post( "index.php?r=employeedetails/lists&id='.'"+$(this).val(), function( data ) {
$( "select#claimprocess-employee_id" ).html( data );
});',
],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
employeedetailscontroller.php
public function actionLists($id)
{
$countEmployeedetails = Employeedetails::find()
->where(['company_id' => $id])
->count();
$employeedetails = Employeedetails::find()
->where(['company_id' => $id])
->all();
if($countEmployeedetails>0){
foreach($employeedetails as $employee){
echo "<option value='".$employee->id."'>".$employee->employeecode."</option>";
}
}
else{
echo "<option>-</option>";
}
}
This is dependent dropdown code for employee_name and relations_name by selecting employeecode
claimform.php
<?= $form->field($model, 'employee_id')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Employeedetails::find()- >all(),'id','employeecode'),
'language' => 'en',
'options' => [
'placeholder' => 'Select a employeecode ...',
'onchange' => '
$.post( "index.php?r=employeedetails/lists2&id='.'"+$(this).val(), function( data ) {
$( "select#claimprocess-claim_for" ).html( data );
}),
$.post( "index.php?r=employeedetails/lists1&id='.'"+$(this).val(), function( data ) {
$( "select#claimprocess-employee_name" ).html( data );
});',
],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
employeedetailscontroller.php
public function actionLists1($id)
{
$countEmployeedetails = Employeedetails::find()
->where(['id' => $id])
->count();
$employeedetails = Employeedetails::find()
->where(['id' => $id])
->all();
if($countEmployeedetails >= 0)
{
foreach($employeedetails as $employee)
{
echo "<option value='".$employee->id."'>".$employee->name."</option>";
}
}
else{
echo "<option>-</option>";
}
}
public function actionLists2($id)
{
$countEmployeedetails = Employeedetails::find()
->where(['id' => $id])
->count();
$employeedetails = Employeedetails::find()
->where(['id' => $id])
->all();
if($countEmployeedetails >= 0)
{
foreach($employeedetails as $employee)
{
echo "<option value='".$employee->id."'>".$employee->father_name."</option>";
echo "<option value='".$employee->id."'>".$employee->mother_name."</option>";
echo "<option value='".$employee->id."'>".$employee->wife_name."</option>";
echo "<option value='".$employee->id."'>".$employee->child1_name."</option>";
echo "<option value='".$employee->id."'>".$employee->child2_name."</option>";
}
}
else{
echo "<option>-</option>";
}
}
In claim_for field I have to select relation names of the particular employee, so what I did is combine all relation fields such as father_name, mother_name etc using array_merge and I got a name in form.
claimform.php
<?php
$em = ArrayHelper::map(Employeedetails::find()- >all(),'id','father_name');
$emp = ArrayHelper::map(Employeedetails::find()->all(),'id','mother_name');
$emp1 = ArrayHelper::map(Employeedetails::find()->all(),'id','wife_name');
$emp2 = ArrayHelper::map(Employeedetails::find()->all(),'id','child1_name');
$emp3 = ArrayHelper::map(Employeedetails::find()->all(),'id','child2_name');
$print = array_merge($em,$emp,$emp1,$emp2,$emp3);
// echo "<pre>";print_r($print);exit();echo "</pre>";
echo $form->field($model, 'claim_for')->dropDownList($print,['option' => '']);
?>
The problem:
While selecting relation I am getting all the relations name in the form, but while saving it in gridview I am getting employee_id instead of merge_array id.
So here I used this code to get relation name, but I dont know whether my write code is right or wrong:
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'id',
'company.companyname',
'employee.employeecode',
'employee.name',
'claim_for',
[
'attribute' => 'claim_for',
'format' => 'raw',
'value' => function($model, $key, $index, $grid) {
$temp = $model->claim_for;
$si = Employeedetails::find()->where(['id' => $temp])->one();
return $si['father_name'];// here how to bring merged array relation name
},
],
'healthcard_no',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
I've been searching for two days but am not able to get it. If anyone can help, I'd appreciate it.
create field in claimprocess table as claim_for and store the getting value from employeedetails in seperate table. thats it, Hope it will you
claimprocesscontroller.php
$commaList = explode('-', $model->claim_for);
$model->claimer_name = $commaList[1];
employeedetails.php
echo "<option value='".$employee->id. '-' .$employee->name. "'>".$employee-RelationName7."</option>";

Categories