Is it possible to get random values using ArrayHelper? Yii2 - php

How do I get random values from another table? In my employee php I have 3 records, so there is 3 id values. In my ticket.php once I create a ticket it will automatically get the id value from the employee table but it is not randomise how do I do it?
Mine is currently getting the same value from employee whenever I create a ticket.
In the ticketcontroller.php
public function actionCreate()
{
$model = new Ticket();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
$model->time_start = date('y-m-d h:i:s');
$model->status = ('On Going');
$model->employee_respond_id = array_rand('id');
return $this->render('create', [
'model' => $model,
]);
}
}
In the _form.php
<?= $form->field($model, 'employee_respond_id')->dropDownlist(
ArrayHelper::map(Employee::find()->all(), 'id', 'id'),
[
'readOnly' => true,
'style' => 'width:200px'
]
); ?>

Try this way:
public function actionCreate()
{
$model = new Ticket();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
$employeeIDs = ArrayHelper::map(Employee::find()->all(), 'id', 'id'),
$model->time_start = date('y-m-d h:i:s');
$model->status = ('On Going');
$model->employee_respond_id = array_rand($employeeIDs);
return $this->render('create', [
'model' => $model,
'employeeIDs' => $employeeIDs
]);
}
}
_form.php
<?= $form->field($model, 'employee_respond_id')->dropDownlist(
$employeeIDs,
[
'readOnly' => true,
'style' => 'width:200px'
]
); ?>
Better use employee name as label and id as value in dropdown, still it will work for random function.

Related

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

Yii2 - Save form in modal with Ajax

I have two models one is "register-products" (where I have a dropdown with all brands) and another form is "brands". I need to render form "brands" inside the form "register-products" to create a new brand using bootstrap Modal widow and it works, but I need the newly created brand to be available inside the dropdown of the register-products form so that I don't have to refresh the page each time.
At this moment what happens is that after creating a new brand is redirecting to the view with details of the new brand.
register-products form
<?php
Modal::begin([
'header' => 'Test',
'id' => 'modal',
'size' => 'modal-lg',
]);
echo "<div id='modalContent'></div>";
Modal::end();
?>
Html::a('+', ['/brands/create'], ['id' => 'open_modal', 'class' => 'btn btn-success']);
js
$(function(){
$('#open_modal').click(function (){
$.get($(this).attr('href'), function(data) {
$('#modal').modal('show').find('#modalContent').html(data)
});
return false;
});
BrandsController
public function actionCreate()
{
$model = new Brands();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} elseif (Yii::$app->request->isAjax) {
return $this->renderAjax('create', [
'model' => $model
]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}

Yii2 custom client validation with ajax rendering in modal

I have a model with a custom validation method. For testing it always returns an error message.
public function rules()
{
return [
...
['staff_ids', 'each', 'rule' => ['string']],
[['staff_ids'], 'validateStaffIds'],
...
];
}
public function validateStaffIds($attribute, $params, $validator) {
$this->addError($attribute, 'There is an error in the staff ids');
}
In the view.php is the modal element
<p>
<?= Html::button('Add Ensemble Staff',
['value' => Url::to(['ensemble/add', 'id' => $model->id]),
'title' => 'Adding New Ensemble Staff',
'class' => 'showModalButton btn btn-primary']);
?>
</p>
<?php
Modal::begin([
'closeButton' => [
'label' => 'x',
],
'headerOptions' => ['id' => 'modalHeader'],
'id' => 'modal',
'size' => 'modal-lg',
]);
echo "<div id='modalContent'></div>";
Modal::end();
?>
The js code which fires everything up...
$(function(){
$(document).on('click', '.showModalButton', function(){
if ($('#modal').data('bs.modal').isShown) {
$('#modal').find('#modalContent')
.load($(this).attr('value'));
} else {
//if modal isn't open; open it and load content
$('#modal').modal('show')
.find('#modalContent')
.load($(this).attr('value'));
}
//dynamiclly set the header for the modal
...
});
});
And the ensemble controller which handles the add action
public function actionAdd($id)
{
$model = $this->findModel($id);
// in the post ( 'ensembleStaff_ids' => [0 => '2']); where the id actually is staff_id
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $id]);
} else {
return $this->renderAjax('add', [
'model' => $model,
]);
}
}
And the form which is injected by the js into the model (Url::to(['ensemble/add', 'id' => $model->id]), )
<?php $form = ActiveForm::begin(['id' => 'add-theater-stuff-form']); ?>
<?= $form->field($model, 'staff_ids')->widget(Select2::className(), [
'model' => $model,
'data' => ArrayHelper::map(app\models\TheaterStaff::find()->where(['theater_id' => $model->theater_id])->all(), 'staff_id', 'staff.fullname'),
'options' => [
'multiple' => true,
'prompt' => 'Ensemble Staff',
],
'pluginOptions' => [
'tags' => true
]
]); ?>
<div class="form-group">
<?= Html::submitButton('Add', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
Clicking on the Add Ensemble Staff Button works fine and brings up the modal window. The form itself works fine so far; also the default validation works. Even the custom validation is called, but return $this->renderAjax(...) isn't load in the modal window anymore; it is separately.
A picture showing the modal loaded, the result after submit and a modal with default validation.
I found a similar problem here. But adding an id to the form, doesn't solve the problem. So how to get the default validation showing up properly in the modal window? Does anyone have a clue?
Solution
Thanks for the response. For me the solution was:
Enable ajax in the form
<?php $form = ActiveForm::begin(['id' => 'add-ensemble-stuff-form', 'enableAjaxValidation' => true]); ?>
And to add the following logic in the controller
public function actionAdd($id)
{
$model = $this->findModel($id);
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
} else {
// in the post ( 'ensembleStaff_ids' => [0 => '2']); where the id actually is staff_id
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $id]);
} else {
return $this->renderAjax('add', [
'model' => $model,
]);
}
}
}
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}else{/* your code */}
add this in controller use yii\web\Response

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(),
]);
}
}

Yii2 Call to a member function someFunction() on Integer and a non-object

I wanna show usernames in timeline index. It show error
Call to a member function getStatusesLabel() on integer
if use this code :
'status' =>$model->data['status']->getStatusesLabel(),
and
'author' => $model->data['author']->getAuthor(),
and another error
Trying to get property of non-object
if use this code :
'author' => ArrayHelper::map($model->data['author']->getAuthor, 'id','username'),
My Model
namespace common\models;
.....
class Article extends ActiveRecord
{
.....
public function getAuthor()
{
return $this->hasOne(User::className(), ['id' => 'author_id']);
}
public function getUpdater()
{
return $this->hasOne(User::className(), ['id' => 'updater_id']);
}
public function getCategory()
{
return $this->hasOne(ArticleCategory::className(), ['id' => 'category_id']);
}
public function getArticleAttachments()
{
return $this->hasMany(ArticleAttachment::className(), ['article_id' => 'id']);
}
public static function statuses()
{
return [
self::STATUS_PUBLISHED => Yii::t('common', 'Published'),
self::STATUS_DRAFT => Yii::t('common', 'Draft'),
];
}
public function afterCreate()
{
$this->refresh();
// use common\commands\AddToTimelineCommand;
Yii::$app->commandBus->handle(new AddToTimelineCommand([
'category' => 'articles',
'event' => '_item',
'data' => [
'title' => $this->title,
'published_at' => $this->published_at,
'created_at' => $this->created_at,
'slug' => $this->slug,
'author' => $this->author_id,
'category' => $this->category,
'status' => $this->status,
]
]));
}
public function afterUpdate()
{
$this->refresh();
// use common\commands\AddToTimelineCommand;
Yii::$app->commandBus->handle(new AddToTimelineCommand([
'category' => 'articles',
'event' => '_itemU',
'data' => [
'title' => $this->title,
'published_at' => $this->published_at,
'updated_at' => $this->updated_at,
'slug' => $this->slug,
'author' => $this->author_id,
'category' => $this->category,
'status' => $this->status,
]
]));
}
}
my controller article:
public function actionCreate()
{
$model = new Article();
$transaction = Yii::$app->db->beginTransaction();
try{
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$model->afterCreate();
$transaction->commit();
return $this->redirect(['index']);
} else {
return $this->render('create', [
'model' => $model,
'categories' => ArticleCategory::find()->active()->all(),
]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
controller timeline
public function actionIndex()
{
$searchModel = new TimelineEventSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->sort = [
'defaultOrder'=>['created_at'=>SORT_DESC]
];
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
command timeline :
class AddToTimelineCommand extends Object implements SelfHandlingCommand
{
public $category;
public $event;
public $data;
public function handle($command)
{
$model = new TimelineEvent();
$model->application = Yii::$app->id;
$model->category = $command->category;
$model->event = $command->event;
$model->data = json_encode($command->data, JSON_UNESCAPED_UNICODE);
return $model->save(false);
}
}
index timeline:
<ul class="timeline">
<?php foreach($dataProvider->getModels() as $model): ?>
<?php if(!isset($date) || $date != Yii::$app->formatter->asDate($model->created_at)): ?>
<!-- timeline time label -->
<li class="time-label">
<span class="bg-blue">
<?php echo Yii::$app->formatter->asDate($model->created_at) ?>
</span>
</li>
<?php $date = Yii::$app->formatter->asDate($model->created_at) ?>
<?php endif; ?>
<li>
<?php
try {
$viewFile = sprintf('%s/%s', $model->category, $model->event);
echo $this->render($viewFile, ['model' => $model]);
} catch (\yii\base\InvalidParamException $e) {
echo $this->render('_item', ['model' => $model]);
}
?>
</li>
view _item for index:
<div class="timeline-body">
<?php echo Yii::t('backend', 'Updated post <b>({title})</b>, published date : {published_at} ', [
'title' => Html::a($model->data['title'],
Url::to(Yii::$app->urlManager->hostInfo.'/article'.'/') .$model->data['slug'],
['target' => '_blank']),
//'author' => ArrayHelper::map($model->data['author']->getAuthor, 'id','username'),
//'author' => $model->data['author']->getAuthor(),
'author' => $model->data['author'],
'category' => $model->data['category'],
//'status' =>$model->data['status']->getStatusesLabel(),
'published_at' => Yii::$app->formatter->asDatetime($model->data['published_at']),
'updated_at' => Yii::$app->formatter->asDatetime($model->data['updated_at'])
])//.Html::a($model->data['title'], ["/article/$model->data['title']"]) ?>
</div>
what is wrong with the above code?
i was use in GridView / detailview, there is no errors
how do I fix it?
In a simple view (not based on gridview or detailView widget) that you render using eg:
return $this->render('your_view', [
'model' => $model,
]);
you can use directly the model and the attribute (or the depending function) eg:
'author' => $model->author
If you instead use a
return $this->render('your_view', [
'dataProvider' => $dataProvider,
]);
you can refer to the model instance
'author' => $dataProvider->models[i]['author']
where i is the index for the specific instance

Categories