yii2 how to simplify repetitive code index,ph - php

new in php and use yii2 as foundation to web development. please help me to simplify this code, im trying to show in popup ActionColumn buttons e.g. view, update and delete buttons. here's my code
'class' => 'yii\grid\ActionColumn',
'buttons'=>[
'view'=>function($url,$model){
return Html::a('<span class="glyphicon glyphicon-eye-open")></span>',$url,['class'=>'view', 'data-pjax'=>0]);
},
'update'=>function($url,$model){
return Html::a('<span class="glyphicon glyphicon-pencil")></span>',$url,['class'=>'update', 'data-pjax'=>0]);
}
],
],
],
]);
$this->registerJs(
"$(document).on('ready pjax:success', function() { // 'pjax:success' use if you have used pjax
$('.view').click(function(e){
e.preventDefault();
$('#pModal').modal('show')
.find('#modalContent')
.load($(this).attr('href'));
});
});
");
Modal::begin([
//'header'=>'<span id="modalHeaderTitle"></span>',
//'headerOptions'=>['id'=>'modalHeader'],
'id'=>'pModal',
'size'=>'modal-lg',
//keeps from closing modal with esc key or by clicking out of the modal.
// user must click cancel or X to close
'clientOptions' => ['backdrop' => 'static', 'keyboard' => FALSE]
]);
echo "<div id='modalContent'></div>";
Modal::end();
$this->registerJs(
"$(document).on('ready pjax:success', function() { // 'pjax:success' use if you have used pjax
$('.update').click(function(e){
e.preventDefault();
$('#qModal').modal('show')
.find('#modalContent')
.load($(this).attr('href'));
});
});
");
Modal::begin([
//'header'=>'<span id="modalHeaderTitle"></span>',
//'headerOptions'=>['id'=>'modalHeader'],
'id'=>'qModal',
'size'=>'modal-lg',
//keeps from closing modal with esc key or by clicking out of the modal.
// user must click cancel or X to close
'clientOptions' => ['backdrop' => 'static', 'keyboard' => FALSE]
]);
echo "<div id='modalContent'></div>";
Modal::end()
?>
please assist me

'buttons'=>[
'view'=>function($url,$model){
return Html::a('<span class="glyphicon glyphicon-eye-open")></span>',$url,['class'=>'view action-btn', 'data-pjax'=>0]);
},
'update'=>function($url,$model){
return Html::a('<span class="glyphicon glyphicon-pencil")></span>',$url,['class'=>'update action-btn', 'data-pjax'=>0]);
}
],
],
],
action-btn added for both button. Now call a ajax from your view and write your modal code in there.
$this->registerJs( "$.ajax({
url: '$url',
type: 'POST',
data: { },
success: function(data) {
//your code
}
});");
$url = \Yii::$app->urlManager->createUrl(['/your-action-here']);
Write modal code on the view file you are redirecting.

'buttons' => [
'view' => function ($url, $model) {
return Html::a(
'<span class="glyphicon glyphicon-eye-open")></span>',
$url,
[
'class' => 'openModal',
'data-pjax' => 0
]
);
},
'update' => function ($url, $model) {
return Html::a(
'<span class="glyphicon glyphicon-pencil")></span>',
$url,
[
'class' => 'openModal',
'data-pjax' => 0
]
);
},
]
Modal
Modal::begin([
'id' => 'modal-popup',
'size' => 'modal-lg',
'clientOptions' => [
'backdrop' => 'static',
'keyboard' => FALSE
]
]);
echo "<div id='modalContent'></div>";
Modal::end();
JS
$this->registerJs(
"$(document).on('ready pjax:success', function() {
$('.openModal').click(function(e) {
e.preventDefault();
$('#modal-popup').modal('show').find('#modalContent').load($(this).attr('href'));
});
});
");

Related

Add to cart button Yii2

I want to make a button that when it's pressed insert data into table name 'cart'
This is my button in index
'cart' => function ($url, $model, $key) {
$modelId = $model->id;
return Html::button('<i class="fas fa-shopping-cart"></i>',
[
'class' => 'btn btn-xs btn-outline-success',
'style' => 'width:80px; margin-top: 5px',
'data-toggle' => 'tooltip',
'title' => Yii::t('app', 'Cart'),
'onClick' => 'addProduct('. "{$modelId}" . ');'
]);
},
And this is my function
public function addProduct($id)
{
$product = Product::find()->where(['id' => $id])->one();
if (isset($product)) {
Yii::$app->db->createCommand()->insert("cart", [
"product_id" => $product->id,
"name" => $product->name,
"price" => $product->price,
"image" => $product->image,
])->execute();
Yii::$app->session->setFlash('success', 'Item added successfully');
}
}
And I have this error
Uncaught ReferenceError: addProduct is not defined
at HTMLButtonElement.onclick
comment need 50 reputation, so I send answer.
if public function addProduct is a PHP function,
on click event is javascript event, maybe you must write a js function in page?
like there:
$this->registerJs(
"$('#myButton').on('click', function() { alert('Button clicked!'); });",
View::POS_READY,
'my-button-handler'
);
the function() { alert('Button clicked!'); }); is js function.(Registering inline scripts)

Yii2- Unable to upload image

I am working on yii2. In one of my view, I am trying to upload an image. But I am unable to upload it.
Model
class MeterAcceptanceHeader extends \yii\db\ActiveRecord
{
public static $status_titles =[
0 => 'Prepared',
1 => 'Created',
2 => 'Printed',
3 => 'Canceled',
];
/**
* #inheritdoc
*/
public static function tableName()
{
return 'meter_acceptance_header';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['sub_div', 'prepared_by'], 'required'],
[['prepared_by', 'updated_by'], 'integer'],
[['prepared_at', 'updated_at'], 'safe'],
[['sub_div', 'meter_type', 'status'], 'string', 'max' => 100],
[['images'], 'string', 'max' => 255],
[['images'], 'file', 'skipOnEmpty' => true, 'extensions' => 'png,jpg,pdf', 'maxFiles' => 4],
[['sub_div'], 'exist', 'skipOnError' => true, 'targetClass' => SurveyHescoSubdivision::className(), 'targetAttribute' => ['sub_div' => 'sub_div_code']],
[['prepared_by'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['prepared_by' => 'id']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'sub_div' => 'Sub Div',
'meter_type' => 'Meter Type',
'prepared_by' => 'Prepared By',
'prepared_at' => 'Prepared At',
'updated_at' => 'Updated At',
'status' => 'Status',
'updated_by' => 'Updated By',
'images' => 'Document Snap',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getMeterAcceptanceDetails()
{
return $this->hasMany(MeterAcceptanceDetails::className(), ['accpt_id' => 'id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getSubDiv()
{
return $this->hasOne(SurveyHescoSubdivision::className(), ['sub_div_code' => 'sub_div']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getPrepared()
{
return $this->hasOne(User::className(), ['id' => 'prepared_by']);
}
}
MeterAcceptanceHeader Table
MeterAcceptanceImages Table
There is a form1 in which user is prompt to select from the dropdown.
Form1 View
<div class="meter-acceptance-header-form">
<?php $model->status = common\models\MeterAcceptanceHeader::$status_titles[0]; ?>
<?php $form = ActiveForm::begin(['id'=>'acceptance-form','options' => ['enctype' => 'multipart/form-data']]); ?>
<?= $form->field($model, 'sub_div')->dropDownList([''=>'Please Select'] + \common\models\SurveyHescoSubdivision::toArrayList()) ?>
<?= $form->field($model, 'meter_type')->dropDownList([''=>'Please Select','Single-Phase' => 'Single-Phase', '3-Phase' => '3-Phase', 'L.T.TOU' => 'L.T.TOU']) ?>
<?= $form->field($model, 'status')->textInput(['maxlength' => true,'readonly' => true]) ?>
<div class="form-group">
<a class="btn btn-default" onclick="window.history.back()" href="javascript:;"><i
class="fa fa-close"></i>
Cancel</a>
<a class="<?= $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary' ?>" onclick="
$('#acceptance-form').submit();" href="javascript:">
<?= $model->isNewRecord ? 'Create' : 'Update' ?></a>
</div>
<?php ActiveForm::end(); ?>
After clicking on Create button the user is prompt to the second form in which a user will upload an image.
Below is my code for the controller from which I am trying to upload it.
public function actionSetpdf($id)
{
$model = $this->findModel($id);
$m = 0;
$accpt_id = $model->id;
$meter_type = $model->meter_type;
$ogp_sub_div = $model->sub_div;
$images=[];
$ic=0;
$files_uploaded = false;
if(Yii::$app->request->isAjax && Yii::$app->request->post())
{
$data = explode(',',$_POST['data']);
foreach($data as $value)
{
$m = new MeterAcceptanceDetails;
$m -> load(Yii::$app->request->post());
$m->accpt_id = $accpt_id;
$m->meter_type = $meter_type;
$m->created_at = date('Y-m-d H:i:s');
$m->created_by = Yii::$app->user->id;
$m->meter_id = $value;
$m->meter_msn = \common\models\Meters::idTomsn($value);
$m->flag = 1;// 1 means created
$m->ogp_sub_div = $ogp_sub_div;
if($m->save())
{
// Here the upload image code starts
if($ic==0)
{
$model->images = UploadedFile::getInstances($model, 'images');
foreach ($model->images as $file)
{
if (file_exists($file->tempName))
{
$img_s = new MeterAcceptanceImages;
$file_name = rand(0, 1000) . time().date('his') . '.' . $file->extension;
$file->saveAs('uploads/meter_acceptance/' . $file_name);
$img_s->file_path = $file_name;
$img_s->accpt_id = $accpt_id;
if ($img_s->save()) {
$images[] = $img_s;
} else {
print_r($img_s->getErrors());
}
}
}
}else{
foreach($images as $image){
$img_s = new MeterAcceptanceImages;
$img_s->file_path = $image->file_path;
$img_s->accpt_id = $accpt_id;
$img_s->save();
}
}
$model->status = MeterAcceptanceHeader::$status_titles[1];
$model->update();
}
else{
$this->renderAjax('viewcreated');
}
}
}
else{
$this->renderAjax('viewcreated');
}
return $this->redirect(Url::toRoute(['meteracceptanceheader/viewsetpdf','id' => $model->id,'model' => $this->findModel($id)]));
}
Form2 View
<div class="map-meters-form" id="doc">
<?php $form = ActiveForm::begin(['id' => 'map-form', 'enableClientValidation' => true, 'enableAjaxValidation' => false,
'options' => ['enctype' => 'multipart/form-data']]) ?>
<section class="content">
<div class="box">
<div id="chk" class="box-body">
<?php Pjax::begin(); ?>
<?= DetailView::widget([
'model' => $model,
'attributes' => [
[
'label'=>'Serial #',
'value' => function($d)
{
return $d->id;
}
],
[
'label' => 'Meter Type',
'value' => function ($d) {
if(is_object($d))
return $d->meter_type;
return ' - ';
},
],
'sub_div',
[
'label' => 'Sub Division Name',
'value' => function ($d) {
if(is_object($d))
return $d->subDiv->name;
return '-';
},
],
[
'label' => 'Prepared By',
'value' => function ($d) {
if(is_object($d))
return $d->prepared->name;
},
],
'prepared_at',
'status',
],
]) ?>
<br>
<div class="pre-scrollable">
<?= GridView::widget([
'dataProvider' => $dataProvider,
//'ajaxUpdate' => true,
'filterModel' => false,
//'id'=>'gv',
'columns' => [
['class' => 'yii\grid\SerialColumn'],
['class' => 'yii\grid\CheckboxColumn', 'checkboxOptions' => function($d) {
return ['value' => $d['meter_id']];
}],
'Meter_Serial_Number',
'Meter_Type',
'Sub_Division_Code',
'Sub_Division_Name',
],
]); ?>
</div>
<?php Pjax::end(); ?>
<?= $form->field($model, 'images[]')->fileInput(['multiple' => true, 'accept' => 'image/*'])?>
<br>
<form>
<p>
Submit
<br/>
</p>
</form>
</div>
</div>
</section>
<?php ActiveForm::end(); ?>
</div>
<?php
$url = Url::toRoute(['/meteracceptanceheader/setpdf','id'=>$model->id]);
$script = <<< JS
$(document).ready(function () {
$(document).on('pjax:end', function() {
$("#chk").find("input:checkbox").prop("checked", true);
});
$("#chk").find("input:checkbox").prop("checked", true);
$('#myid').on('click',function(e) {
e.preventDefault();
var strValue = "";
$('input[name="selection[]"]:checked').each(function() {
if(strValue!=="")
{
strValue = strValue + " , " + this.value;
}
else
strValue = this.value;
});
$.ajax({
url: '$url',
type: 'POST',
dataType: 'json',
data: {data:strValue},
success: function(data) {
alert(data);
}
});
})
});
JS;
$this->registerJs($script, \yii\web\View::POS_END);
?>
This will allow selecting an image. Now when I try to click submit button I am getting below error
PHP Notice 'yii\base\ErrorException' with message 'Undefined offset: 0'
in
E:\xampp\htdocs\inventory-web\vendor\yiisoft\yii2\db\Command.php:330
By debugging the controller code I found that the error comes at foreach ($model->images as $file) as print_r($model->images) return Array() empty.
By doing print_r($model) I got
common\models\MeterAcceptanceHeader Object ( [_attributes:yii\db\BaseActiveRecord:private] => Array ( [id] => 1 [sub_div] => 37111 [meter_type] => L.T.TOU [prepared_by] => 12 [prepared_at] => 2018-08-20 12:41:27 [updated_at] => [status] => Prepared [updated_by] => [images] => Array ( ) ) [_oldAttributes:yii\db\BaseActiveRecord:private] => Array ( [id] => 1 [sub_div] => 37111 [meter_type] => L.T.TOU [prepared_by] => 12 [prepared_at] => 2018-08-20 12:41:27 [updated_at] => [status] => Prepared [updated_by] => [images] => ) [_related:yii\db\BaseActiveRecord:private] => Array ( ) [_errors:yii\base\Model:private] => [_validators:yii\base\Model:private] => [_scenario:yii\base\Model:private] => default [_events:yii\base\Component:private] => Array ( ) [_behaviors:yii\base\Component:private] => Array ( ) )
I have used the same process in other modules as well and it works properly.
How can I get rid of this problem?
Update 1
<?php
use yii\helpers\Html;
use yii\grid\GridView;
use yii\helpers\Url;
use app\models\User;
use yii\widgets\DetailView;
use yii\widgets\ActiveForm;
use yii\widgets\Pjax;
use kartik\select2\Select2;
use kartik\file\FileInput;
/* #var $this yii\web\View */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = $model->id;
$this->title = 'Meter Acceptance Form';
$this->params['breadcrumbs'][] = $this->title;
?>
<section class="content-header">
<h1>Meter Acceptance</h1>
</section>
<div class="map-meters-form" id="doc">
<section class="content">
<div class="box">
<div id="chk" class="box-body">
<?php Pjax::begin(); ?>
<?=
DetailView::widget([
'model' => $model,
'attributes' => [
[
'label' => 'Serial #',
'value' => function($d){
return $d->id;
}
],
[
'label' => 'Meter Type',
'value' => function ($d){
if( is_object($d) )
return $d->meter_type;
return ' - ';
},
],
'sub_div',
[
'label' => 'Sub Division Name',
'value' => function ($d){
if( is_object($d) )
return $d->subDiv->name;
return '-';
},
],
[
'label' => 'Prepared By',
'value' => function ($d){
if( is_object($d) )
return $d->prepared->name;
},
],
'prepared_at',
'status',
],
])
?>
<br>
<div class="pre-scrollable">
<?=
GridView::widget([
'dataProvider' => $dataProvider,
//'ajaxUpdate' => true,
'filterModel' => false,
//'id'=>'gv',
'columns' => [
['class' => 'yii\grid\SerialColumn'],
['class' => 'yii\grid\CheckboxColumn', 'checkboxOptions' => function($d){
return ['value' => $d['meter_id']];
}],
'Meter_Serial_Number',
'Meter_Type',
'Sub_Division_Code',
'Sub_Division_Name',
],
]);
?>
</div>
<?php Pjax::end(); ?>
<?php
$form = ActiveForm::begin(['id' => 'map-form', 'enableClientValidation' => true, 'enableAjaxValidation' => false,
'options' => ['enctype' => 'multipart/form-data']])
?>
<?=$form->field($model, 'images[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?>
<br>
<p>
Submit
<br/>
</p>
<?php ActiveForm::end(); ?>
</div>
</div>
</section>
</div>
<?php
$url = Url::toRoute(['/meteracceptanceheader/setpdf','id'=>$model->id]);
$script = <<< JS
$(document).ready(function () {
$(document).on('pjax:end', function() {
$("#chk").find("input:checkbox").prop("checked", true);
});
$("#chk").find("input:checkbox").prop("checked", true);
$('#myid').on('click',function(e) {
e.preventDefault();
//START Append form data
var data = new FormData();
var files= $('input[name="MeterAcceptanceHeader[images][]"]')[0].files;
//append files
$.each(files,function(index,file){
data.append("MeterAcceptanceHeader[images][]",file,file.name);
});
var strValue = "";
$('input[name="selection[]"]:checked').each(function() {
if(strValue!=="")
{
strValue = strValue + " , " + this.value;
}
else
strValue = this.value;
});
//alert(strValue);
//append your query string to the form data too
data.append('data',strValue);
//END append form data
$.ajax({
url: '$url',
type: 'POST',
dataType: 'json',
contentType: false,
processData: false,
data: {data:strValue},
success: function(data) {
alert(data);
}
});
})
});
JS;
$this->registerJs($script, \yii\web\View::POS_END);
?>
Any help would be highly appreciated.
What looks like that you are trying to submit an image via Ajax call when you click on submit button in the step 2 for image upload as you are binding the click to the #myid which is the anchor button
Submit
And if you are trying to send the image via ajax you need to use the FormData interface.
The FormData interface provides a way to easily construct a set of
key/value pairs representing form fields and their values, which can
then be easily sent using the XMLHttpRequest.send() method. It uses
the same format a form would use if the encoding type were set to
"multipart/form-data".
But before I address how to do it, you need to look into some other issues related to Form2 view.
You are nesting the 2 forms which is technically wrong and you can't do that see Why.
Above all why are you creating a separate form for the submit button?
see this line on top
<?php $form = ActiveForm::begin(['id' => 'map-form', 'enableClientValidation' => true, 'enableAjaxValidation' => false,
'options' => ['enctype' => 'multipart/form-data']]) ?>
This is where your first form starts and the file input field
<?= $form->field($model, 'images[]')->fileInput(['multiple' => true, 'accept' => 'image/*'])?>
is inside this form, and on the very next line you have the anchor button that i mentioned above in the start but you are wrapping it inside a separate form and that too before you close the ActiveForm
<form>
<p>
Submit
<br/>
</p>
</form>
instead you are closing the ActiveForm after this form by calling <?php ActiveForm::end(); ?>. As you have seen in the previous question that you faced weird behavior with the filter inputs for the GridVew as you were wrapping the GridView inside the form, and you are repeating that same mistake here too and also nesting 2 forms within.
What i will advise you to do first
Remove the form that you are creating just for the anchor button, as you wont be needing it if you want to submit the image via ajax by clicking on the anchor just keep the anchor inside the main ActiveForm. And Move the ActiveForm::begin() just before the fileInput() and after the Pjax::end().
With that said you should now user FormData to upload the image via ajax and to do so you have to add these options contentType: false and processData: false inside your ajax call and use FormData.append() to append the input files to the FormData.
So your javascript for the click function will look like this, i assume the model used for the image upload is MeterAcceptanceImages
$('#myid').on('click',function(e) {
event.preventDefault();
//START Append form data
let data = new FormData();
let files= $("input[name='MeterAcceptanceImages[images][]']")[0].files;
//append files
$.each(files,function(index,file){
data.append('MeterAcceptanceImages[images][]',file,file.name);
});
var strValue = "";
$('input[name="selection[]"]:checked').each(function() {
if(strValue!==""){
strValue = strValue + " , " + this.value;
}else{
strValue = this.value;
}
});
//append your query string to the form data too
data.append('data',strValue);
//END append form data
$.ajax({
url: '$url',
type: 'POST',
dataType: 'json',
contentType: false,
processData: false,
data: data,
success: function(data) {
alert(data);
}
});
});
So overall your view Form2.php should look like below
<div class="map-meters-form" id="doc">
<section class="content">
<div class="box">
<div id="chk" class="box-body">
<?php Pjax::begin(); ?>
<?=
DetailView::widget([
'model' => $model,
'attributes' => [
[
'label' => 'Serial #',
'value' => function($d){
return $d->id;
}
],
[
'label' => 'Meter Type',
'value' => function ($d){
if( is_object($d) )
return $d->meter_type;
return ' - ';
},
],
'sub_div',
[
'label' => 'Sub Division Name',
'value' => function ($d){
if( is_object($d) )
return $d->subDiv->name;
return '-';
},
],
[
'label' => 'Prepared By',
'value' => function ($d){
if( is_object($d) )
return $d->prepared->name;
},
],
'prepared_at',
'status',
],
])
?>
<br>
<div class="pre-scrollable">
<?=
GridView::widget([
'dataProvider' => $dataProvider,
//'ajaxUpdate' => true,
'filterModel' => false,
//'id'=>'gv',
'columns' => [
['class' => 'yii\grid\SerialColumn'],
['class' => 'yii\grid\CheckboxColumn', 'checkboxOptions' => function($d){
return ['value' => $d['meter_id']];
}],
'Meter_Serial_Number',
'Meter_Type',
'Sub_Division_Code',
'Sub_Division_Name',
],
]);
?>
</div>
<?php Pjax::end(); ?>
<?php
$form = ActiveForm::begin(['id' => 'map-form', 'enableClientValidation' => true, 'enableAjaxValidation' => false,
'options' => ['enctype' => 'multipart/form-data']])
?>
<?=$form->field($model, 'images[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?>
<br>
<p>
Submit
<br/>
</p>
<?php ActiveForm::end(); ?>
</div>
</div>
</section>
</div>
<?php
$url = Url::toRoute(['/meteracceptanceheader/setpdf', 'id' => $model->id]);
$script = <<< JS
$(document).ready(function () {
$(document).on('pjax:end', function() {
$("#chk").find("input:checkbox").prop("checked", true);
});
$("#chk").find("input:checkbox").prop("checked", true);
$('#myid').on('click',function(e) {
event.preventDefault();
//START Append form data
let data = new FormData();
let files= $("input[name='MeterAcceptanceImages[images][]']")[0].files;
//append files
$.each(files,function(index,file){
data.append('MeterAcceptanceImages[images][]',file,file.name);
});
var strValue = "";
$('input[name="selection[]"]:checked').each(function() {
if(strValue!==""){
strValue = strValue + " , " + this.value;
}else{
strValue = this.value;
}
});
//append your query string to the form data too
data.append('data',strValue);
//END append form data
$.ajax({
url: '$url',
type: 'POST',
dataType: 'json',
contentType: false,
processData: false,
data: data,
success: function(data) {
alert(data);
}
});
});
});
JS;
$this->registerJs($script, \yii\web\View::POS_END);
?>
Now if you try to print_r(UploadedFile::getInstances('images')) should show you all the images you selected and submitted to upload. To troubleshoot in case of errors while uploading of the ajax call you can see my answer i posted previously related to ajax file uploads.

Missing Required Parameter in Yii2 Gridview Action Button

I'm trying to add my own action button in Yii2-Kartik Gridview.
This is my custom button:
This is my code in index.php
[
'class' => 'yii\grid\ActionColumn',
'template' => '{edit}',
'buttons' => [
'edit' => function ($url, $model) {
return Html::a('<button type="button" class="btn btn-edit-npwp"><i class="glyphicon glyphicon-plus-sign"></i></button>', $url, [
'title' => Yii::t('app', 'Edit'),
'data-toggle' => "modal",
'data-target' => "#myModal",
'data-method' => 'post',
]);
},
],
'urlCreator' => function ($action, $model, $key, $index) {
if ($action === 'edit') {
$url = Url::toRoute(['vatout-faktur-out/add-data', 'id' => $model->fakturId], ['data-method' => 'post',]);
return $url;
}
}
],
and this is my action in controller.php
public function actionAddData($id) {
$model = new VatoutFakturOut();
return $this->render('addData', [
'model' => $model,
]);
}
I want to process the data from the row that I've clicked the button.
But, this return error
Missing required parameters: id
Why does this happen? And how to fix this?
Thanks
In urlCreator you used if statement to check, if action is edit, and if it is, you add param id to your button url. Otherwise it doesnt have one, so there's two solutions:
Remove if statement from:
'urlCreator' => function ($action, $model, $key, $index) {
$url = Url::toRoute(['vatout-faktur-out/add-data', 'id' => $model->fakturId]);
return $url;
}
Or remove$id from your actionAddData() - because youre not using it at all:
public function actionAddData() {
$model = new VatoutFakturOut();
return $this->render('addData', [
'model' => $model,
]);
}

PHP: How do I can show data in modal box based on clicked button's row id in gridview?

I've a Yii2-basic application that has view of index.php that contain a kartik GridView. There is an action column that contain view button that will redirect the page to view of view.php if clicked.
If the view button clicked, page will redirect to view.php and show data based on id,
For example from image above, that table contain two button in view column. If the first(top) button clicked, it will show data base on id from id column (left side of table), so it will show data that has id = 1.
And I've successfully create this action.
But I need to show data in modal box. So I use yii\bootstrap\Modal. And I've succesfully show the data in modal box. For the first clicked, it will popup modal box that contain data based on id, but for the next click button it will also show the data based on id that got from the first clicked button.
For example from picture above:
For the first time I click the button from the second row (id = 2) and then popup a modal box that contain data that has id=2, and then I click the button from the first row(id = 1) and it will also popup modalbox that contain data that has id = 2.
Here's my code from index.php:
<?php
use yii\helpers\Html;
use kartik\grid\GridView;
use yii\widgets\Pjax;
use yii\helpers\Url;
use yii\bootstrap\Modal;
<div class="students-index">
<?=
GridView::widget([
'dataProvider' => $dataProvider,
'tableOptions' => ['class' => 'table table-hover'],
'columns' => [
[
'label' => 'id',
'value' => function($data) {
return $data->id;
}
],
[
'label' => 'Name',
'value' => function($data) {
return $data->name;
}
],
[
'label' => 'Birthdate',
'value' => function($data) {
return $data->Birthdate;
}
],
[
'label' => 'Sex',
'value' => function($data) {
return $data->Sex;
}
],
[
'class' => 'yii\grid\ActionColumn',
'header' => 'View',
'template' => '{view}',
'buttons' => [
'view' => function ($url, $model) {
$icon = '<span class="glyphicon glyphicon-eye-open"></span>';
return Html::a($icon, $url, [
'title' => Yii::t('app', 'View'),
'data-toggle' => "modal",
'data-target' => "#myModal",
]);
},
],
'urlCreator' => function ($action, $model, $key, $index) {
if ($action === 'view') {
$url = Url::toRoute(['/school/students/view', 'id' => $model->faktur_out_id], ['data-method' => 'post',]);
return $url;
}
}
]
],
]);
?>
</div>
<?php
Modal::begin([
'id' => 'myModal',
]);
Pjax::begin([
'id'=>'pjax-modal','timeout'=>false,
'enablePushState'=>false,
'enableReplaceState'=>false,
]);
Pjax::end();
Modal::end();
?>
<?php
$this->registerJs("
$('#myModal').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget)
var href = button.attr('href')
$.pjax.reload('#pjax-modal', {
'url' => href,
});
"); ?>
How do I can show the data in modal box based on id?
But actually I didn't understand $this->registerJs("......") yet.
Maybe anyone can explain about it in simple language.
Any help will be appreciated, thanks.
$this->registerJs(" ");
is simply a function in the Yii framework that allows you to write the javascript in between the " ".
Try this:
<?php
Modal::begin([
'id' => 'myModal',
]);
Pjax::begin([
'id'=>'myModal','timeout'=>false,
'enablePushState'=>false,
'enableReplaceState'=>false,
]);
Pjax::end();
Modal::end();
?>
<?php
$this->registerJs("
$('#myModal').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget)
var href = button.attr('href')
$.pjax.reload('#myModal', {
'url' => href,
});
"); ?>

yii2 Ajax Request Error 404

I want use ajax in yii2 (PHP framework)
I use the following code but it does not work.
My view file (PHP):
<script>
var url1='<?php echo Url::toRoute('Agehi/Ajaxshahr'); ?>';
</script>
<?php
$script= <<<JS
function selectshahr()
{
var ost = $("#ostan").val();
$.ajax(
{
type: "post",
url: url1,
data: ost,
cache: false,
success: function(data)
{
alert(data);
}
});
}
JS;
$this->registerJs($script,View::POS_BEGIN);
$form = ActiveForm::begin([
'id' => 'login-form',
'options' => ['class' => 'form-horizontal','enctype'=>'multipart/form-data'],
]);
echo $form->errorSummary($model,['header'=>'لطفا خطاهای زیر را برطرف نمایید','class'=>'']);
echo \vova07\imperavi\Widget::widget([
'selector' => '#content','name'=>'content',
'settings' => [
'lang' => 'fa',
'minHeight' => 200,
'plugins' => [
'clips',
'fullscreen'
]
]
]);
?>
<?= Html::label('استان','ostan',array()) ?>
<?= Html::dropDownList('ostan', null,
ArrayHelper::map($ostan, 'id', 'name'),array('class'=>'form-control','onchange'=>'selectshahr()','id'=>'ostan')) ?>
<?= Html::label('شهرستان/شهر','shahr',array()) ?>
<?= Html::dropDownList('shahr', null,
array(),array('class'=>'form-control')) ?>
and in my controller :
class AgehiController extends \yii\web\Controller
{
public function actionAjaxshahr($ostan)
{
$data = Shahr::findAll('condition', 'osid=' . $_POST['data']);
if(yii::$app->request->isAjax())
{
return $this->renderPartial('_Ajax_shahr', array('data' => $model));
}
return $this->renderPartial('_Ajax_shahr', array('data' => $model));
}
}
Everything seems okay but it does not respond to any request
I checked with Browser developer tools and it saw AJAX as a 404 error
Controller and action names in a route should be lowercase.

Categories