Yii2 transfer logic from view to model - yii2

I would like to arrange my code a little bit better. I have this in view, generated by giiant:
$form->field($model, 'land_id')->dropDownList(ArrayHelper::map(app\models\Land::find()->orderBy('name')->all(), 'id', 'name'), [
'prompt' => Yii::t('app', 'Select'),
'disabled' => (isset($relAttributes) && isset($relAttributes['land_id'])),]);
Somebody has told me here on stackoverflow that it's not really nice. So I would like to transfer this part:
ArrayHelper::map(app\models\Land::find()->orderBy('name')->all(), 'id', 'name'
into model. The same applies to grid filter dropdowns:
'filter' => ArrayHelper::map(\app\models\base\Land::find()->asArray()->all(), 'id', 'name'),
Does it make sense? I think so, I hope so. I've tried to implement it in model Land 2 ways:
public function getAllAsArray() {
return ArrayHelper::map(app\models\Land::find()->orderBy('name')->all(), 'id', 'name');
}
or
public function getAllAsArray() {
return ArrayHelper::map($this->find()->orderBy('name')->all(), 'id', 'name');
}
and I wanted to call it from View/Grid (Zip - Land):
'filter' => $model->land->allAsArray,
but I'm getting the following error:
Undefined variable: model
then tried this way:
'filter' => function ($model) {$model->getLand()->one()->getAllAsArray();},
'filter' => function ($model) {$model->getLand()->getAllAsArray();},
then I get no error messages, but it's also not working.
and in Form (Zip - Land) the same way:
$form->field($model, 'land_id')->dropDownList($model->land->allAsArray(), [
'prompt' => Yii::t('app', 'Select'),
'disabled' => (isset($relAttributes) && isset($relAttributes['land_id'])),]);
but I'm getting the following error:
Call to a member function getAllAsArray() on null
Can you please point me to the right direction? I think I don't understand something basically and this disturbes me. Thank you very much in advance!

Land model
public static function getAllAsArray() {
return ArrayHelper::map(Land::find()->orderBy('name')->all(), 'id', 'name');
}
index
use app\models\Land;
'filter' => Land::getAllAsArray(),
form
use app\models\Land;
$form->field($model, 'land_id')->dropDownList(Land::getAllAsArray(), [
'prompt' => Yii::t('app', 'Select'),
'disabled' => (isset($relAttributes) && isset($relAttributes['land_id']))]);

Related

Don't create field in database

I hava code like below. It creates a field in database and show in another places. I would like to block create a database field if message field is not exit. Rest fields are taken from system. What is wrong in my code.
$delivery->comments_buro()->create([
'name' => auth()->user()->firstname,
'user_id' => auth()->user()->id,
'message' => $request['repair_report_buro'],
'icon' => 'fa fa-commenting-o',
'style' => $position->style,
]);
Thanks for help.
You need Laravel Validations for that. Please read this: https://laravel.com/docs/5.8/validation
For example:
//controller
public function index(Request $request)
{
$validator = Validator::make($request->all(), [
'message' => 'required|string',
]);
if ($validator->fails()) {
//do validation error handling here
}
// create new row in database.
}
I have a right code. It works with it. I close this question. The right code is:
if(isset($request['repair_report_buro']) && !empty($request['repair_report_buro'])){
$delivery->comments_buro()->create([
'name' => auth()->user()->firstname,
'user_id' => auth()->user()->id,
'message' => $request['repair_report_buro'],
'icon' => 'fa fa-commenting-o',
'style' => $position->style,
]);
}

Yii2: How to use map() to show two fields in a Select2?

I am using a Select2 widget for Yii2. It shows a list with the ids of the users.
I need to show two fields defined in my model called Users: first_name_user and last_name_user. Like this:
Daniel Gates
John Connor
John Doe
Maria Key
But I don't know how use map() to show more than one field.
<?= $form
->field($model, 'id_user')
->widget(\common\widgets\Select2::classname(), [
'items' => \yii\helpers\ArrayHelper::map(\app\models\Users::find()->orderBy('name_user')->all(), 'id_user', 'name_user')
])
?>
Model
Add use app\models\Users; and use yii\helpers\ArrayHelper; at top.
public function userList()
{
$userList = [];
$users = Users::find()->orderBy('first_name_user')->all();
$userList = ArrayHelper::map($users, 'id_user', function ($user) {
return $user->first_name_user.' '.$user->last_name_user;
});
return $userList;
}
_form
<?= $form->field($model, 'id_user')->widget(Select2::className(), [
'data' => $model->userList(),
'options' => ['placeholder' => 'Select User'],
]) ?>
You need to use data option instead of items for Select2.
You need to modify your query to show the concatenated first_name_user and last_name_user as an alias and then return it along with the id column to be used in Select2 by ArrayHelper::map().
It's better to add a function to the model you are using to populate the form and return the results from there to the ArrayHelper::map().
Your query should look like
function userList(){
return \app\models\Users::find()
->select([new \yii\db\Expression('[[id_user]],CONCAT([[first_name_user]]," ",[[last_name_user]]) as full_user_name')])
->orderBy('name_user')
->all();
}
Your form field should look like below
<?=
$form->field($model, 'id_user')->widget(Select2::className(), [
'data' => \yii\helpers\ArrayHelper::map($model->userList(), 'id_user', 'full_user_name'),
'options' => [
'placeholder' => 'Select User',
'id' => 'id_user'
],
'theme' => Select2::THEME_DEFAULT,
'pluginOptions' => [
'allowClear' => true
],
]);
?>

Handle Image update in yii2

Hi everyone i am using FileInput kartik widget in yii2 project and uploading and saving works fine but i am having problem while updating the images
I can get the images path on the update form and create and array and display in as initialpreview in the widget but the problem is that my files field is required field so even there are some values in initialpreview the form gives error to upload image as its required field. So what should i do here?
I only want to give preview of their uploaded pics to the user but if they dont make any changes than i dont want to update anything for images
Following is my view code and model code
return [
[[ 'price', 'created_date', 'created_by', 'updated_date', 'updated_by','file','address'], 'required'],
[['price'], 'number'],
[['address'], 'string', 'max' => 255],
[['file'], 'file', 'extensions'=>'jpg, gif, png', 'maxFiles' => 4],
];
<?php
$initalpreview = array();
foreach($model->adsImages as $images) {
$initalpreview[] = Html::img('/upload/'.$images->image, ['class'=>'file-preview-image']);
}
?>
<?=$form->field($model, 'file[]')->widget(FileInput::classname(), [
'options' => ['accept' => 'image/*',
'multiple'=>true],
'pluginOptions' => [
'maxFileCount' => 5,
'initialPreview'=> $initalpreview,
'showUpload' => false,
]
]); ?>
So what should i do here?
Thank you
try this
In Model create a scenario named 'update' and mention the fields that are required when update action works
return [
[['price', 'created_date', 'created_by','updated_date','updated_by','address'], 'required', 'on' => 'update'],
];
Now inside controller action update call the scenario
public function actionUpdate(){
//Model Declaration
$model->scenario = 'update';
// update code
}

yii2 Kartik-V Typeahead Basic autocomplete on name but store integer value

Updates have been made below
I am trying to use the Kartik-V Typeahead Basic widget with the Yii2 Framework.
The code below is working to display the required data, the user can search via the university name and it appears in the autocomplete list.
The issue is, the model needs to the university id, not the name. Thus the rules are this field can only store an integer and returns a validation error once you select one of the typeahead results.
<?= $form->field($model, 'university_id')->widget(TypeaheadBasic::classname(), [
'data' => ArrayHelper::map(University::find()->all(),'id','uni_name'),
'pluginOptions' => ['highlight' => true],
'options' => ['placeholder' => 'Filter as you type ...'],
]); ?>
I am hoping someone can help me understand if there is a setting that needs to be changed so when saving, the user friendly 'uni_name' data is changed back to the uni 'id'.
UPDATE:
I have gotten the code partly working thanks to "Insane Skull".
The new code is:
<?= $form->field($model, 'name')->widget(TypeaheadBasic::classname(), [
'data' => ArrayHelper::map(University::find()->all(),'id','uni_name'),
'pluginOptions' => ['highlight' => true],
'options' => ['placeholder' => 'Filter as you type ...', 'id' => 'testID'],
'pluginEvents' => [
'typeahead:select' => new yii\web\JsExpression("function(event, ui) { $('#testing123').val(ui.item.id); }"),
]
]); ?>
<?= Html::activeHiddenInput($model, 'university_id', array ('id' => 'testing123'))?>
Now I am unfortunately getting the error:
Method yii\web\JsExpression::__toString() must return a string value
I would rather use Select2 instead of Typeahead, you are basically trying to implement the functionality that already exists on Select2 but using Typeahead.
<?= $form->field($model, 'university_id')->widget(Select2::classname(), [
'data' => ArrayHelper::map(University::find()->all(),'id','uni_name'),
'options' => ['placeholder' => 'Filter as you type ...'],
]); ?>
You can use activeHiddenInput() for this purpose.
Create one public variable in model say name.
Then:
<?= $form->field($model, 'name')->widget(TypeaheadBasic::classname(), [
'data' => ArrayHelper::map(University::find()->all(),'id','uni_name'),
'pluginOptions' => ['highlight' => true],
'options' => ['placeholder' => 'Filter as you type ...'],
'select' => new yii\web\JsExpression("function( event, ui ) {
$('#id_of_hiddenField').val(ui.item.id);
}")
]); ?>
<?= Html::activeHiddenInput($model, 'university_id')?>
And in Controller Get the value of activeHiddenField.

How to change label text of the ActiveField?

I have created new Yii2 basic project and want to dig in.
There is a Username field on login page:
I want to change label 'Username' to a custom one, e.g. 'My superb label'.
I have read the manual:
http://www.yiiframework.com/doc-2.0/yii-widgets-activefield.html
After investigating a little I've got the next result:
I have changed only template and it has changed the layout:
<?= $form->field($model, 'username', [
"template" => "<label> My superb label </label>\n{input}\n{hint}\n{error}"
])?>
How to change the text of the label in a correct way?
What is best practice?
<?= $form->field($model, 'username')->textInput()->label('My superb label') ?>
http://www.yiiframework.com/doc-2.0/yii-bootstrap-activefield.html#label()-detail
there is an another cool way.
<?= $form->field($model, 'username')->textInput(['class'=>'field-class'])->label('Your Label',['class'=>'label-class']) ?>
Okay, just override attributeLabels in LoginForm.php:
/**
* Returns the attribute labels.
*
* See Model class for more details
*
* #return array attribute labels (name => label).
*/
public function attributeLabels()
{
return [
'username' => 'Логин',
'password' => 'Пароль',
];
}
You can also add such function to model:
public function attributeLabels()
{
return [
'username' => 'My Login',
'password' => 'My Pasword',
'rememberMe' => 'Remember Me, please',
];
}
just change the lable from modles like this
'symptomsBefore' => Yii::t('app', 'Has The Patient Suffered from the same or similar symptoms before'),