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'
]); ?>
Related
I have the following tables:
customers[id, name, surname, phone, text, balance, created]
service_types[id, title, price, length, is_subscription, created, payment]
customer_service_types[id, customer_id, service_type_id, price, created]
And the relations:
ServiceTypesTable.php:
$this->hasMany('CustomerServiceTypes', [
'foreignKey' => 'service_type_id'
]);
CustomerServiceTypesTable.php:
$this->belongsTo('Customers', [
'foreignKey' => 'customer_id',
'joinType' => 'INNER'
]);
$this->belongsTo('ServiceTypes', [
'foreignKey' => 'service_type_id',
'joinType' => 'INNER'
]);
In CustomerServiceTypes\add.ctp I have a dropdown with the services and a field for the price:
echo $this->Form->control('customer_id', ['options' => $customers,'label' => 'Customer']);
echo $this->Form->control('service_type_id', ['options' => $serviceTypes, 'label' => 'Service']);
echo $this->Form->control('price', ['label' => 'Price']);
In the CustomerServiceTypesController.php:
public function add($customerid = null)
{
$customerServiceType = $this->CustomerServiceTypes->newEntity();
if ($this->request->is('post')) {
$customerServiceType = $this->CustomerServiceTypes->patchEntity($customerServiceType, $this->request->getData());
if ($this->CustomerServiceTypes->save($customerServiceType)) {
//debug($this->request->getData("customer_id"),true);
$this->Flash->success(__('Success'));
return $this->redirect(['controller' => 'customers', 'action' => 'edit', $customerid]);
}
$this->Flash->error(__('Fail'));
}
$customers = $this->CustomerServiceTypes->Customers->find('list', ['limit' => 200])->where(['Customers.id =' => $customerid]);
$serviceTypes = $this->CustomerServiceTypes->ServiceTypes->find('list', [
'valueField' => function ($row) {
return $row['title'] . ' (Suggested price: ' . $row['price'] . ')';
}
], ['limit' => 200]);
$this->set(compact('customerServiceType', 'customers', 'serviceTypes'));
}
Which adds in the services dropdown valuefield the value of the specific service:
Service_1 (Suggested price: 100)
Service_2 (Suggested price: 150)
.....
But what I want to achieve is to update the price field with the suggested price when user makes a selection in the dropdown field. Is it possible to achieve that server side? Without the use of javascript? Because my knowledge is very limited in javascript. If not can you provide a working example based on my question?
Make Following changes:
add.ctp
<div ng-app="" ng-init='servicePrices = <?php echo json_encode($servicePrices); ?>;' >
<?php
echo $this->Form->create();
echo $this->Form->control('customer_id', ['options' => $customers,'label' => 'Customer']);
echo $this->Form->control('service_type_id', [
'options' => $serviceTypes, 'label' => 'Service',
'ng-model'=>'service_type_id'
]);
echo $this->Form->control('price', [
'label' => 'Price',
'ng-model'=>'servicePrices[service_type_id]'
]);
echo $this->Form->submit('submit');
?>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js" ></script>
CustomerServiceTypesController.php
// add this
$servicePrices = $this->CustomerServiceTypes
->ServiceTypes
->find()
->limit(200)
->combine('id','price');
$this->set(compact('customerServiceType', 'customers', 'serviceTypes','servicePrices'));
I have users, orders and plans. When client buy plan, data is save in orders , plans are in account_plan and the information for user is in table users. In table orders is when the plan start and when it is expired. I use for Select2 ArrayHelper, but do not show the column
here is a query
$masAcc[0] = Yii::t('app', 'Choose plan');
$masAcc['----------------'] =
ArrayHelper::map(
\backend\models\Orders::find()
->select('orders.*,account_planLang.name as name')
->leftJoin('orders_props','`orders_props`.`order_id`= `orders`.`id`')
->leftJoin('account_plan','`orders_props`.`product_id`=`account_plan`.`id`')
->leftJoin('account_planLang','account_plan.id=account_planLang.plan_id')
->where('`orders`.`dt_end`<CURDATE() + INTERVAL 5 DAY AND `orders`.`dt_end`<CURDATE()')
->all(), 'id', 'name');
but the error is :
Getting unknown property: backend\models\Orders::name
here is Select2:
$form->field($model, 'account')->widget(Select2::classname(), [
'model' => $model,
'theme' => 'bootstrap',
'options' => [
'placeholder' => Yii::t('app', 'app.choose'),
'class' => 'form-control select2'
],
'data' => $masAcc,
'pluginOptions' => [
'allowClear' => true,
],
]);
}
That is because your query returns list of Orders models, which does not have name column, so it cannot represent result of this query. You need to use asArray() when you want to query field that is not available in model:
ArrayHelper::map(
\backend\models\Orders::find()
->select('orders.*,account_planLang.name as name')
->leftJoin('orders_props','`orders_props`.`order_id`= `orders`.`id`')
->leftJoin('account_plan','`orders_props`.`product_id`=`account_plan`.`id`')
->leftJoin('account_planLang','account_plan.id=account_planLang.plan_id')
->where('`orders`.`dt_end`<CURDATE() + INTERVAL 5 DAY AND `orders`.`dt_end`<CURDATE()')
->asArray() // <- this
->all(),
'id',
'name'
);
Or add name field to your model:
class Orders extends ActiveRecord {
public $name;
// ...
}
I guess there is no need to use ArrayHepler::map(). Try this way:
Orders::find()
->select('account_planLang.name as name, table_name.id as id')
->leftJoin('orders_props','`orders_props`.`order_id`= `orders`.`id`')
->leftJoin('account_plan','`orders_props`.`product_id`=`account_plan`.`id`')
->leftJoin('account_planLang','account_plan.id=account_planLang.plan_id')
->where('`orders`.`dt_end`<CURDATE() + INTERVAL 5 DAY AND `orders`.`dt_end`<CURDATE()')
->indexBy('id')
->column();
I have this kind of problem. I have an input text that have template of radio in it.
the problem is that I want to get the value of that radio when I check it and store it to the database field.
my idea is to create a variable from model but i can't pass the radio value to that variable when i save it.
please help me I am stuck with it.
here is the images of view:
Controller action:
public function actionCreate()
{
$model = new QbQuestion();
if ($model->load(Yii::$app->request->post())) {
$answer = $model->answer;
$model->$answer;
$model->save();
return $this->redirect(Url::to(['qb-question/index']));
} else {
return $this->renderAjax('create', [
'model' => $model,
]);
}
}
View:
<div class="qb-question-form">
<?php $form = ActiveForm::begin([
'layout' => 'horizontal',
'fieldConfig' => [
'horizontalCssClasses' => [
'label' => 'col-sm-4',
'offset' => 'col-sm-offset-4',
'wrapper' => 'col-sm-8',
'button' => 'col-sm-8',
'error' => '',
'hint' => '',
],
],
]); ?>
<?php echo $form->errorSummary($model); ?>
<?= $form->field($model, 'q_cat')->dropDownList(
ArrayHelper::map(QbCategory::find()->all(), 'id', 'category'),
[
'prompt' => 'Select Category'
]) ?>
<?= $form->field($model, 'q_date')->dropDownList(
ArrayHelper::map(QbDate::find()->asArray()->all(), 'id',
function($model, $defaultValue) {
return $model['month'].' '.$model['year'];
}),
[
'prompt' => 'Select Date'
]) ?>
<?php echo $form->field($model, 'question')->textarea(['rows' => 5]) ?>
<?= $form->field($model, 'q_c1', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
Html::radio('answer').'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c2', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
Html::radio('answer').'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c3', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
Html::radio('answer').'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c4', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
Html::radio('answer').'</span>{input}</div>',
]); ?>
<?php echo Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
</div>
thanks in advance.
radio field that you have take will always return 1, So you can't identify selected answer. You can do it normal html as below:
Change in Your Form file :
<?= $form->field($model, 'q_c1', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
'<input type="radio" name="QbQuestion[answer]" value="q_c1">'.'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c2', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
'<input type="radio" name="QbQuestion[answer]" value="q_c2">'.'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c3', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
'<input type="radio" name="QbQuestion[answer]" value="q_c3">'.'</span>{input}</div>',
]); ?>
<?= $form->field($model, 'q_c4', [
'inputTemplate' => '<div class="input-group"><span class="input-group-addon">'.
'<input type="radio" name="QbQuestion[answer]" value="q_c4">'.'</span>{input}</div>',
]); ?>
Here ,QbQuestion['answer'] return you the selected answer.
Change in controller:
public function actionCreate()
{
$model = new QbQuestion();
if ($model->load(Yii::$app->request->post())) {
// if you have answer attribute in model class than load that attribute
// no need of this line $answer = $model->answer;
// no need of this line $model->$answer;
// you can do it manually as below
$model->answer=$_REQEST['QbQuestion']['answer'];
$model->save();
return $this->redirect(Url::to(['qb-question/index']));
} else {
return $this->renderAjax('create', [
'model' => $model,
]);
}
}
The reason your attributes are not saving is because you haven't tied the field to the model, so incorrect field names are being submitted in the form.
It seems to me as if what you need is a radioList. The Html::radio() method just adds a radio button, not tied to any model. To use a radioList you need to do something like this;
First, create an array of possible answers in your view file;
$answers = array('q_c1' => $model->q_c1, 'q_c2' => $model=>q_c2, 'q_c3' => $model=>q_c3, 'q_c4' => $model=>q_c4);
Now, because it's a radio list, it will only submit data for one of the radio button. It will not allow selection of more than one radio button. Because of the way you are storing your data, you will need a temporary model attribute to store this value oin while the model gets populated and validated. Create this in your model like so;
public $answerToQuestion;
And allow it to be massively assigned;
public function rules() {
return [
[['answerToQuestion'], 'safe]
];
}
Now you can create your form field like this;
echo $form->field($model, 'answerToQuestion')->radioList($answers);
Yii should now generate the list of radio buttons with the correct names to tie them into your model and allow them to be massively assigned.
The attributes submitted by the form will be of the form (assuming your model is called Question;
Question[answerToQuestion] => 'q_c2'
It will pass validation. It's now up to your model logic to decode the selected answer into the relevant fields in your database.
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
}
}
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>";