Catch button in controller - yii2

I have this form in view
<?php
$form = ActiveForm::begin();
$items = [201 => 'Тест', 202 => 'Тест2'];
echo Html::dropDownList('list', 'null', $items);
?>
<div class="form-group">
<?=
Html::submitButton(
'Удалить отмеченные',[
'data' => ['confirm' => 'Вы действительно хотите перенести отмеченные товары в выбранную категорию?'],
'name' => 'deleteProduct',
'value' => 'delProduct', // добавить value
'class' => 'btn btn-danger'
])
?>
</div>
<?php ActiveForm::end(); ?>
And this in controller
if (Yii::$app->request->post('deleteProduct'))
{
$lk_number = $_POST['list'];
print_r($lk_number);exit();
}
But when click on button there is no catch in controller. What I do wrong?

Related

yii2 - multiple rows load into same table from one form

I am trying to save a schedule of working days on a table multiple rows at once...
I am doing this wrong, still giving me errors.
I have seen tabular inputs from others, but can't get this right.
I really need some other eyes on it.
I have a similar problem as https://phppedia.com/en/knowledge-base/32481399/yii2-insert-multiple-records-of-a-same-table
model:
public
function rules()
{
return [
['store_id', 'string'],
['day', 'string'],
['start_hour', 'string'],
['end_hour', 'string'],
['holiday','boolean'],
];
}
controler:
public function actionCreate()
{
$count = count(Yii::$app->request->post('Openhour', []));
$model = [new Openhours()];
for ($i = 1; $i < $count; $i++) {
$model[] = new Openhours();
}
if ($model->loadMultiple($model, Yii::$app->request->post())) {
foreach ($model as $model) {
$model->save(false);
}
}
return $this->render('create', ['model' => $model,]);
}
_form
<?php $stores = Stores::getAll() ?>
<?php foreach ($stores as $store): ?>
<?php if ($store->id !== 0): ?>
<?php $listData[$store->id] = [$store->id => $store->title]; ?>
<?php endif; ?>
<?php endforeach; ?>
<?php $form = ActiveForm::begin(['enableAjaxValidation' => true, 'options' => ['class' => 'model-form'],]); ?>
<?php foreach ($model as $index => $model): ?>
<div class="row row-cols-3">
<div class="col">
<h5>
<?php if ($store->title === Yii::$app->user->identity->username) : ?>
<?= $form->field($model, '[$index]store_id')->hiddenInput(['value' => $store->title])->label($store->title) ?>
<?php else: ?>
<?= $form->field($model, '[$index]store_id')->dropDownList($listData, ['prompt' => 'Select...']); ?>
<?php endif; ?>
</h5>
</div>
<div class="col">Opening</div>
<div class="col">Close</div>
</div>
<?php $days = Storedays::getAll() ?>
<?php foreach ($days as $day): ?>
<div class="row row-cols-3">
<div class="col">
<div class="row justify-content-between">
<div class="col">
<h6><?= $day->name ?></h6>
<?= $form->field($model, '[$index]day')->hiddenInput(['value' => $day->name, 'id' => 'day' . $day->id])->label(false) ?>
</div>
<div class="col">
<?= $form->field($model, '[$index]holiday')->checkbox(['selected' => $model->holiday, 'id' => 'holiday' . $day->id])->label(false) ?>
</div>
</div>
</div>
<div class="col">
<?= $form->field($model, '[$index]start_hour')->Input('text')->widget(TimePicker::class, ['options' => ['id' => 'start_hour' . $day->id], 'pluginOptions' => ['maxHours' => '8', 'template' => 'dropdown', 'showSeconds' => false, 'showMeridian' => false, 'minuteStep' => 15,]])->label(false) ?>
</div>
<div class="col">
<?= $form->field($model, '[$index]end_hour')->Input('text')->widget(TimePicker::class, ['options' => ['id' => 'end_hour' . $day->id], 'pluginOptions' => ['maxHours' => '8', 'template' => 'dropdown', 'showSeconds' => false, 'showMeridian' => false, 'minuteStep' => 15,]])->label(false) ?>
</div>
</div>
<?php endforeach; ?>
<?php if (IS_ROOT) : ?><?= $form->field($model, '[$index]slug') ?><?php endif; ?>
<?= Html::submitButton('save', ['class' => 'btn btn-primary']) ?>
<hr class="mb-3">
<?php endforeach; ?>
<?php ActiveForm::end(); ?>
First you have an array of objects and you must use plural name instead.
So model become models.
Second you must use functions for loading multiple models from request Model::loadMultiple($models) and for validate multiple models Model::validateMultiple($models).
Now in your controller:
public function actionCreate()
{
$count = count(Yii::$app->request->post('Openhour', []));
$models = [new Openhours()];
for ($i = 1; $i < $count; $i++) {
$models[] = new Openhours();
}
if (Model::loadMultiple($models, Yii::$app->request->post()) && Model::validateMultiple($models)) {
foreach ($models as $model) {
$model->save(false);
}
}
return $this->render('create', ['models' => $models]);
}
Now in your _form.php change the line:
<?php foreach ($model as $index => $model): ?>
To:
<?php foreach ($models as $index => $model): ?>

Yii2 Pjax reloads the page even with renderPartial

I am sending Pjax request which reloads the whole page even when I am using renderPartial. The pjax container is #promo-products than why it reloads the whole page not only fill the container with the desired results ? If I var_dump($child_products);die; it shows the result right in the container but without die it reloads the page. Also tried to render a partial view ( like _children lets say ) but the result was the same. What is my mistake?
Controller:
public function actionCreate()
{
$model = new Promotion();
$products = [];
$success = null;
$child_products = [];
if(Yii::$app->request->isPjax){
$parent_id = Yii::$app->request->get('parent_id');
if($parent_id){
$parent_children = ProductChild::find()->where(['id_in' => $parent_id])->all();
foreach ($parent_children as $child){
$child_products[$child['id']][] = $child;
}
}
}
if (!Yii::$app->request->isPjax && $model->load(Yii::$app->request->post())) {
$transaction = Yii::$app->db->beginTransaction();
try{
if($model->save()){
//save products
$model->saveProducts();
$transaction->commit();
return $this->redirect(['index', 'success' => 1]);
} else {
throw new \Exception("Some error occurred.");
}
}catch (\Exception $e){
$success = 3;
$model = new Promotion();
$transaction->rollBack();
}
}
if(Yii::$app->request->isPjax){
return $this->renderPartial('create', [
'child_products' => $child_products,
]);
}
return $this->render('create', [
'model' => $model,
'products' => $products,
'success' => $success,
'child_products' => $child_products,
]);
}
And my view:
<?php
use yii\widgets\ActiveForm;
use backend\helpers\Header;
use kartik\select2\Select2;
use yii\web\JsExpression;
use backend\helpers\CGrowl;
\backend\assets\JquerySteps::register($this);
\backend\assets\DateTimePickerAsset::register($this);
/* #var $this yii\web\View */
/* #var $model backend\models\Contact */
/* #var $form yii\widgets\ActiveForm */
$this->registerJs("
$('#promotion-start_date').bootstrapMaterialDatePicker({ format: 'YYYY-MM-DD HH:mm:ss' });
$('#promotion-end_date').bootstrapMaterialDatePicker({ format: 'YYYY-MM-DD HH:mm:ss' });
",
\yii\web\View::POS_LOAD,
'datetime-picker-init'
);
if (isset($success)) {
echo CGrowl::setFormResult((int)$success, $this);
}
?>
<div class="row page-titles" style="background-image: url('<?= Yii::getAlias('#backend-image') ?>/theme/images/heading-title-bg.jpg')">
<div class="col-md-12">
<h4 class="text-white"><?= Yii::t('app', 'Promotion') ?></h4>
</div>
<div class="col-md-6">
<?= Header::renderBreadcrumbs($this) ?>
</div>
</div>
<div class="row" id="validation">
<div class="col-12">
<div class="card wizard-content">
<div class="card-body">
<div class="panel-body">
<?php $form = ActiveForm::begin([
'options' => [
'class' => 'validation-wizard wizard-circle'
],
]); ?>
<h6><?= Yii::t('app', 'Main info') ?></h6>
<section>
<div class="row">
<div class="col-sm-6">
<?= $form->field($model, 'type')->widget(Select2::class, [
'data' => [
1 => Yii::t('app', 'Percentage'),
2 => Yii::t('app', 'Price'),
],
'options' => [
'placeholder' => Yii::t('app', 'Type')
],
'pluginOptions' => [
'allowClear' => true
]
]) ?>
</div>
<div class="col-sm-6">
<?= $form->field($model, 'value')->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-6">
<?= $form->field($model, 'start_date')->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-6">
<?= $form->field($model, 'end_date')->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-4">
<?= $form->field($model, 'products')->widget(Select2::class, [
'initValueText' => $products,
'options' => [
'multiple' => true
],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 3,
'language' => [
'errorLoading' => new JsExpression("function(){return 'Waiting for results ...'; }"),
],
'ajax' => [
'url' => \yii\helpers\Url::to(['async/products']),
'dataType' => 'json',
'data' => new JsExpression("function(params){return {q:params.term}; }")
],
'escapeMarkup' => new JsExpression("function(markup){return markup;}"),
'templateResult' => new JsExpression("function(city){return city.text;}"),
'templateSelection' => new JsExpression("function(city){return city.text;}")
],
'pluginEvents' => [
'select2:select' => "function(){
let url = location.href.split('?')[0]
$.pjax.defaults.timeout = false
$.pjax({
url: url,
data: {
parent_id: this.value
},
container: '#promo-products'
})
}"
]
]) ?>
</div>
<div class="col-sm-8">
<label for=""><?= Yii::t('app', 'Varieties')?></label>
<div class="table-responsive">
<table>
<?php \yii\widgets\Pjax::begin(['id' => 'promo-products']) ?>
<tbody>
<?php
foreach ($child_products as $child){
echo $child->id;
}
?>
</tbody>
<?php \yii\widgets\Pjax::end() ?>
</table>
</div>
</div>
<div class="col-sm-12">
</div>
</div>
</section>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
</div>
</div>

Insert multiple records of a same table Yii2

I want to insert same record in one table. I have only one input array in the below form but i want to save multiple time record for label input array.
my form is
<div class="surveys-questions-form">
<?php $form = ActiveForm::begin(); ?>
<?php
if(isset($_GET['option_id']) and $_GET['option_id'] > 0)
$id= $_GET['option_id'];
else
$id= $model->option_id;
echo $form->field($model, 'question_id')->hiddenInput(['value' => $id])->label(false);
?>
<div class="col-md-6">
<div id="question_wrapper">
<?= $form->field($model, 'type')->dropDownList([ 'text' => 'Text', 'numbers' => 'Numbers', 'date' => 'Date', 'texarea' => 'Texarea', 'checkbox' => 'Checkbox', 'radio' => 'Radio', 'rating' => 'Rating', ], ['prompt' => '']) ?>
<div id="add_more_field">
<?= $form->field($model, 'label[]')->textInput(['maxlength' => true]) ?>
</div>
<div class="form-group">
<?php
echo Html::a('Add more', 'javascript:void(0);', [
'id' => 'surveys-questions-new-button',
'class' => 'pull-right btn btn-primary btn-xs'
])
?>
</div>
</div>
</div>
<div class="col-md-12">
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
and controller
public function actionCreate()
{
$model = new QuestionsOptions();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->option_id]);
} else {
return $this->renderAjax('create', [
'model' => $model,
]);
}
}
Give me the following error when i try to submit form.
Label must be a string.
My $_POST array
Array
(
[_csrf-backend] => LXBhajI3YVpOIikeRWYHYkNCAD4Kb1ZrQzwER21GL2MdCTgkWm5ZDQ==
[QuestionsOptions] => Array
(
[question_id] => 47
[type] => numbers
[label] => Array
(
[0] => Label1
[1] => Label2
[2] => Labe3
)
)
)
If you want to save multiple record use loop i suggest you to use foreach loop it is best
public function actionCreate()
{
$model = new QuestionsOptions();
if ($model->load(Yii::$app->request->post())) {
if(sizeof(array_filter($_POST['QuestionsOptions']['label'])) > 0){
foreach($_POST['QuestionsOptions']['label'] as $key => $row){
$model->setIsNewRecord(true);
$model->id = null;
$model->label = $row;
$model->save();
}
}
return $this->redirect(['view', 'id' => $model->option_id]);
} else {
return $this->renderAjax('create', [
'model' => $model,
]);
}
}

Yii2 upload image from modal issue

I'm using yii2 bootstrap modal for uploading images, the issue is I need to double click on Create button then form submit works otherwise it don't work on single click.
On double click image is uploading and form data also saved to database.
Is this issue with my code?
Here is code:
//Form
<?php Pjax::begin(['id' => 'banner-form']) ?>
<?php $form = ActiveForm::begin([
'id' => 'banner-form',
'options' => [
'data-pjax' => true,
'enctype' => 'multipart/form-data'
]
]);
?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'banner')
->fileInput([
"accept"=>"image/*"
])
?>
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
<?php Pjax::end(); ?>
//Model
[['banner'], 'file', 'skipOnEmpty' => false,
'extensions' => ['jpg', 'jpeg', 'png', 'gif']
]
//index.php
<p>
<?= Html::a(Yii::t('app', 'Create Banner'), null, ['class' => 'btn btn-success', 'id'=>'createBannerButton',
'value'=>Url::to(['/banner/create'])]) ?>
</p>
<?php Pjax::begin(['id' => 'banner-index']) ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
....
]); ?>
<?php Pjax::end(); ?>
//Controller
use yii\web\UploadedFile;
class BannerController extends Controller
{
...
public function actionCreate()
{
$model = new Banner();
if ($model->load(Yii::$app->request->post())){
$file = UploadedFile::getInstance($model, 'banner');
if (!empty($file))
$model->banner = $file;
if($model->save()){
if (!empty($file))
$file->saveAs( Yii::getAlias('#root') .'/uploads/' . $file);
return $this->redirect(['view', 'id' => $model->id]);
}
}
else if (Yii::$app->request->isAjax) {
return $this->renderAjax('create', [
'model' => $model,
]);
}
else {
return $this->render('create', [
'model' => $model,
]);
}
}
...
}
//layouts/main.php
<?php
Modal::begin([
'header' => '',
'id' => 'modal',
'size' => 'modal-medium', //medium
'clientOptions' => ['backdrop' => 'static', 'keyboard' => false]
]);
echo "<div id='modalContentBackend'>
<div class='col-lg'>
<img src='/images/loading.gif' width='280' height='210' alt='loading...'>
</div>
</di>";
Modal::end();
?>
<?php $this->endBody() ?>
//backend/web/js/custom.js
$(function(){
$("#createBannerButton").click(function(){
$("#modal").modal('show')
.find('#modalContentBackend')
.load($(this).attr('value'));
});
});
//backend/assets/AppAsset
class AppAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/site.css',
];
public $js = [
'js/custom.js'
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
I got the issue, I'm including Pjax::begin() in index.php and _form.php, I have removed Pjax::begin() from _form.php and now it is working fine.

Yii2 Pjax on ActiveForm and GridView [ Got it Working]

I have a gridview
<?php Pjax::begin(['id' => 'members']) ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
// 'filterModel' => $searchModel,
'columns' => [
['header'=>'Remove Member',
'value'=> function($data)
{
return Html::a(Yii::t('app', ' {modelClass}', [
'modelClass' =>'',
]), ['members/stl_remove','id'=>$data->id],
['class' => 'btn btn-link fa fa-times fa-2x pop']
);
},
'format' => 'raw'
],
['class' => 'yii\grid\ActionColumn','template'=>'{update}'],
],
]); ?>
<?php Pjax::end() ?>
when i click on the Remove members link a modal popsup (delete.php)
<?php Pjax::begin(['id' => 'delete_members']) ?>
<?php $form = ActiveForm::begin(['options' => ['data-pjax' => true ]]); ?>
<div class="row">
<div class="col-md-5">
<?php echo $form->field($model, 'remarks')->dropDownList(['death' => 'Death',
'marriage' => 'Marriage', 'house_shift' => 'House Shift'],['prompt'=>'Select'])
->label("Reason For Removal"); ?>
</div>
</div>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Remove') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
<?php yii\widgets\Pjax::end() ?>
Now these are my controller code
[code]
public function actionStl_remove($id,$ajax=0)
{
$model = $this->findModel($id);
$model_delete = new Members();
$model->scenario = "remove";
if ($model_delete->load(Yii::$app->request->post()))
{
$model->remarks = $model_delete->remarks;
$model->status = 1;
$model->save();
// $model = new Members();
// return $this->redirect(['index']);
}
else
{
return $this->renderAjax('delete', [
'model' => $model_delete,
'id' => $id,
]);
}
}
I am not able to get data loaded into gridview. I click on the link modal popsup then i submit after that i go on to the index page and the page reloads
This is how i got it working. In delete.php i made following changes.
<?php $form = ActiveForm::begin([
'options' => ['data-pjax' => true,
'id'=> 'dynamic-form111',
// 'validationUrl' => 'validation-rul'
]]); ?>
<div class="row">
<div class="col-md-5">
<?php echo $form->field($model, 'remarks')->dropDownList(['death' => 'Death',
'marriage' => 'Marriage', 'house_shift' => 'House Shift'],['prompt'=>'Select'])
->label("Reason For Removal"); ?>
</div>
</div>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Remove') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
basically i gave an id to the from dynamic-form111.
Then in index.php along with gridview in pjax i added the below code
<?php
$this->registerJs(
'jQuery(document).ready(function($){
$(document).ready(function () {
$("body").on("beforeSubmit", "form#dynamic-form111", function () {
var form = $(this);
// return false if form still have some validation errors
if (form.find(".has-error").length)
{
return false;
}
// submit form
$.ajax({
url : form.attr("action"),
type : "post",
data : form.serialize(),
success: function (response)
{
$("#ajaxModal").modal("toggle");
$.pjax.reload({container:"#countries"}); //for pjax update
},
error : function ()
{
console.log("internal server error");
}
});
return false;
});
});
});'
);
?>
which via ajax check if delete.php has been submitted successfully if yes then reloads gridview using pjax and closes modal.