yii2 pjax gridview issue - caching

I am using gridview with pjax in yii2 advanced. When i add/update/delete any record the pjax loads the very first html of page. For example, i have 10 records after deleting a record there should be 9 records, but it still loads 10 records and this continues even if you have deleted all the records. Same goes for add and update as well.
But if i hit F5 then it loads the actual records fetched from the database table and if i do any of the actions again then it again shows 10 records.
Here is the Gridview code with Pjax
$this->registerJs("$('.js-delete').on('click', function(e) {
ajax_actions(this, true, {
'pjax_container': '#products-grid'
});
return false;
});");
Pjax::begin([
"id" => "products-grid",
"enablePushState" => false
]);
echo GridView::widget([
'dataProvider' => $dataProvider,
"summary" => '',
"rowOptions" => function($model) {
if($model->status == Common::STATUS_INACTIVE)
{
return ["class" => "inactive"];
}
},
'columns' => [
[
"class" => 'yii\grid\SerialColumn',
"headerOptions" => [
"class" => 'hidden-480'
],
"contentOptions" => [
"class" => 'hidden-480'
]
], [
"attribute" => "title",
"label" => "Product"
], [
"attribute" => "companies_id",
"label" => "Companies",
"value" => "companies.title"
], [
"attribute" => "product_types_id",
"header" => "Category",
"value" => "productTypes.title"
], [
"attribute" => "part_number",
"header" => "<span class=\"hidden-360\">Part </span>Number"
], [
"attribute" => "created_on",
"label" => "Added On",
"format" => ["date", "php:" . Common::DATETIME_FORMAT_DISPLAY],
"headerOptions" => [
"class" => 'textRight hidden-360'
],
"contentOptions" => [
"class" => 'textRight hidden-360'
]
], [
"class" => 'yii\grid\ActionColumn',
"header" => "Actions",
"headerOptions" => [
"class" => "textRight actions"
],
"contentOptions" => [
"class" => "textRight actions"
],
"template" => "{view} {edit} {delete}",
"buttons" => [
'view' => function($url, $model) {
return Html::a('<i class="' . Common::ICON_VIEW . '"></i> <span class="hidden-640">View</span>', ['view', 'token' => $model->token], ["class" => "call-ajax"]);
},
'edit' => function($url, $model) {
return Html::a('<i class="' . Common::ICON_EDIT . '"></i> <span class="hidden-640">Edit</span>', ['update', 'token' => $model->token], ["class" => "call-ajax"]);
},
'delete' => function($url, $model) {
return Html::a('<i class="' . Common::ICON_DELETE . '"></i> <span class="hidden-640">Delete</span>', ['delete', 'token' => $model->token], [
'class' => 'js-delete'
]);
}
]
]
]
]);
Pjax::end();
functions
function ajax_submit(element, pjax_container)
{
var form = $(element);
if(form.find('.has-error').length) return false;
$.post(form.attr('action'),form.serialize()).done(function(result){
var result = JSON.parse(result);
if(result.type=='error')
{
result.container = '.error-container';
messages(result)
}
else
{
if(pjax_container) $.pjax.reload({container: pjax_container});
$('.overlay').click();
result.container = '.message-container';
messages(result);
}
});
return false;
}
function ajax_actions(element, ask_me, params)
{
if(ask_me == true && ask() == false)
{
return false;
}
var $this = $(element);
var $params = {
callBacks: {
beforeSendAfter: function() {},
completeAfter: function() {}
}
};
if(params != undefined) $.extend(true, $params, params);
$.ajax({
type: 'POST',
url: $this.attr("href"),
cache: false,
beforeSend: function() {
if($params.callBacks.beforeSendAfter != undefined && $.isFunction($params.callBacks.beforeSendAfter)) $params.callBacks.beforeSendAfter();
},
success: function(response) {},
complete: function(response) {
var result = $.parseJSON(JSON.parse(response.responseText));
if(result.type=='error')
{
result.container = '.error-container';
messages(result)
}
else
{
result.container = '.message-container';
$('.overlay').click();
$.pjax.reload({container: $params.pjax_container});
messages(result);
}
if($params.callBacks.completeAfter != undefined && $.isFunction($params.callBacks.completeAfter)) $params.callBacks.completeAfter();
}
})
return false;
}

Related

Dropzone.js vuejs laravel message: "Undefined index: width"

When I select a file it is uploaded to the public/upload-images folder. In the laravel Controller the validation fails because the params are not included in the request. When I dump and die. This is what I get. As you can see... the params are missing. Below that is the Dropzone setup.
echo '<pre>';
print_r(request()->all());
echo '</pre>';
die();
$data = request()->validate([
'image' => '',
'width' => '',
'height' => '',
'location' => '',
]);
$image = $data['image']->store('user-images', 'public');
$userImage = auth()->user()->images()->create([
'path' => $image,
'width' => $data['width'],
'height' => $data['height'],
'location' => $data['location'],
]);
return new UserImageResource($userImage);
(
[image] => Illuminate\Http\UploadedFile Object
(
[test:Symfony\Component\HttpFoundation\File\UploadedFile:private] =>
[originalName:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 20220406_125155.jpg
[mimeType:Symfony\Component\HttpFoundation\File\UploadedFile:private] => image/jpeg
[error:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 0
[hashName:protected] =>
[pathName:SplFileInfo:private] => /tmp/phpdAwZvd
[fileName:SplFileInfo:private] => phpdAwZvd
)
)
props: [
'imageWidth',
'imageHeight',
'location',
],
data: () => {
return {
dropzone: null,
}
},
mounted() {
this.dropzone = new Dropzone(this.$refs.userImage, this.settings);
},
computed: {
settings() {
return {
paramName: 'image',
url: '/api/user-images',
acceptedFiles: 'image/*',
params: {
'width': this.imageWidth,
'height': this.imageHeight,
'location': this.location,
},
headers: {
'X-CSRF-TOKEN': document.head.querySelector('meta[name=csrf-token]').content,
},
success: (e, res) => {
alert('uploaded!');
},
error: (e, error) => {
console.log(error);
}
};
}
}

Display Each Column sum on footer Yajra Laravel

The following screenshot shows the list of database results by enabling server-side processing. It shows the column total computed by using the Yajra DataTables.
HTML Code for DataTables with Column Total
To display the footer using html builder, pass true as 2nd argument on $builder->table([], true) api.
{!! $dataTable->table([], true) !!}
script
update th values
#push('scripts')
{!! $dataTable->scripts() !!}
<script>
var hours = JSON.parse("{{json_encode($hours)}}");
$(document).ready(function(){
$("tfoot tr>th:nth-child(2)").text("Total")
for (let i = 0; i < hours.length; i++) {
$('tfoot tr>th:nth-child('+ (i+3) +')').text(hours[i])
}
})
</script>
#endpush
Report Datatable File
In Query function we are getting reports record from database and use query result in dataTable function make column according to our requirement and finally set values to getColumns function.
public function dataTable($query)
{
$reports = ($query['data']);
return datatables()->make($reports)
->addColumn('name', function ($reports) {
return isset($reports['user_name']) ? $reports['user_name'] : null;
})
->addColumn('monday', function ($reports) {
return isset($reports['Mon']) ? ($reports['Mon']) : '-';
})
->addColumn('tuesday', function ($reports) {
return isset($reports['Tue']) ? $reports['Tue'] : '-';
})
->addColumn('wednesday', function ($reports) {
return isset($reports['Wed']) ? $reports['Wed'] : '-';
})
->addColumn('thursday', function ($reports) {
return isset($reports['Thu']) ? $reports['Thu'] : '-';
})
->addColumn('friday', function ($reports) {
return isset($reports['Fri']) ? $reports['Fri'] : '-';
})
->addColumn('total', function ($reports) {
return (isset($reports['Mon']) ? $reports['Mon'] : 0) +
(isset($reports['Tue']) ? $reports['Tue'] : 0) +
(isset($reports['Wed']) ? $reports['Wed'] : 0) +
(isset($reports['Thu']) ? $reports['Thu'] : 0) +
(isset($reports['Fri']) ? $reports['Fri'] : 0);
})
->addIndexColumn();
}
public function query(Lot $model)
{
$data = Reports.....;
return compact('data');
}
public function html()
{
return $this->builder()
->setTableId('userrequestdatatable-table')
->columns($this->getColumns())
->minifiedAjax()
->dom('Bfrtip')
->orderBy(1)
->buttons(
Button::make('export'),
);
}
protected function getColumns()
{
return [
'#' => [
'data' => 'DT_RowIndex',
'name' => 'DT_RowIndex',
'orderable' => false,
'searchable' => false
],
'user name'=> [
'data' => 'name',
'name' => 'name',
],
'monday'=> [
'data' => 'monday',
'name' => 'monday',
],
'tuesday'=> [
'data' => 'tuesday',
'name' => 'tuesday',
],
'wednesday'=> [
'data' => 'wednesday',
'name' => 'wednesday',
],
'thursday'=> [
'data' => 'thursday',
'name' => 'thursday',
],
'friday'=> [
'data' => 'friday',
'name' => 'friday',
],
'total'=> [
'data' => 'total',
'name' => 'total',
]
];
}

Flatten laravel nested relationship (parent to descendants)

I have a parent children relationship on my model. What I want is to flatten all those collection including all those descendants of parent.
[
{
'name': 'Parent',
'another_array' => [
{
'name': 'Another Array Name'
}
],
'children': [
{
'name': 'First Child',
'address': 'lorem ipsum',
'contact_no': '92390',
'another_array' => [
{
'name': 'Another Array Name'
}
],
'children': [
{
'name': 'First Descendant',
'address': 'lorem ipsum',
'contact_no': '92390',
'children': [
{
'name': 'Descendant Child',
'address': 'lorem ipsum',
'contact_no': '92390',
'children': [
{
'name': 'Last Descendant',
'address': '',
'contact_no': '',
'children': []
}
]
}
]
}
]
}
]
}
]
I tried the code below. However it only displays the second depth of children. It does not display the next children of the collection.
User.php
public function parent()
{
return $this->belongsTo(User::class, 'id', 'parent_id');
}
public function children()
{
return $this->hasMany(User::class,'parent_id', 'id');
}
public function descendants()
{
return $this->children()->with('descendants');
}
UsersController.php
public function index()
{
$parent = User::find(1);
$parent->with('descendants')->find($parent->id);
$descendants = $this->traverseTree($parent->descendants);
return response($descendants);
}
protected function traverseTree($subtree)
{
$descendants = collect([]);
foreach ($subtree->descendants as $descendant) {
$descendants->push($descendant);
if($descendant->descendants instanceof Collection) {
foreach ($descendant->descendants as $node) {
$this->traverseTree($node);
$descendants->push($node);
}
}
}
return $descendants;
}
Desired Output
[
{
'name': 'Parent',
'address': 'lorem ipsum',
'contact_no': '92390'
},
{
'name': 'First Child',
'address': 'lorem ipsum',
'contact_no': '92390'
},
{
'name': 'First Descendant',
'address': 'lorem ipsum',
'contact_no': '92390',
},
{
'name': 'Descendant Child',
'address': 'lorem ipsum',
'contact_no': '92390',
},
{
'name': 'Last Descendant' ,
'address': '',
'contact_no': '',
}
]
I am looking forward for your help.
from your collection response convert it to an array by chaining the toArray() method so you output becomes and a multi-dimensional array instead of nested objects as shown below...
$my_array = [
'name' => 'Parent',
'children' => [
'name' => 'First Child',
'address' => 'lorem ipsum',
'contact_no' => '234',
'children' => [
'name' => 'First Descendant',
'address' => 'lorem ipsum',
'contact_no' => '567',
'children' => [
'name' => 'Descendant Child',
'address' => 'lorem ipsum',
'contact_no' => '8890',
'children' => [
'name' => 'Last Descendant',
'address' => '',
'contact_no' => '',
'children' => []
]
]
]
]
];
then you can use this helper function below:
protected function _flattened($array)
{
$flatArray = [];
if (!is_array($array)) {
$array = (array)$array;
}
foreach($array as $key => $value) {
if (is_array($value) || is_object($value)) {
$flatArray = array_merge($flatArray, $this->_flattened($value));
} else {
$flatArray[0][$key] = $value;
}
}
return $flatArray;
}
when you dump the $result = $this->_flattened($my_array);, you will have output like...
[
0 => [
"name" => "Parent"
],
1 => [
"name" => "First Child",
"address" => "lorem ipsum"
"contact_no" => "234"
],
2 => [
"name" => "First Descendant"
"address" => "lorem ipsum"
"contact_no" => "567"
],
3 => [
"name" => "Descendant Child"
"address" => "lorem ipsum"
"contact_no" => "8890"
],
4 => [
"name" => "Last Descendant"
"address" => ""
"contact_no" => ""
],
];

Yii2 Form submission through ajax

I have used check boxes in my gridview,like this
<?php
if(isset($dataProvider) && !empty($dataProvider)) {
echo \yii\grid\GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn',
'header' => 'No.'],
[
'class' => 'yii\grid\CheckboxColumn',
'header'=>'Select',
'checkboxOptions' => function ($model, $key, $index, $column) {
return ['value' => $model->dsItemId];
}
],
[
'label'=>'Category',
'value' => function ($model) {
return $model->getdscategoryName();
},
],
'dsItemName',
'qty',
[
'attribute' => 'image',
'enableSorting' => false,
'format' => 'image',
'value' => function ($model) {
return $model->getImageUrl();
},
],
],
]);
echo Html::submitButton('Save',['id' => 'saveBtn','class' => 'btn btn-danger']);
}?>
When I'm selecting check boxes and select savebutton, it will go to this function given below,
<script>
$( document ).ready(function() {
$('#saveBtn').click(function() {
var idVar = '';
$("input[name='selection[]']").each( function () {
if($(this).is(':checked')) {
if(idVar != '') {
idVar += ',' + $(this).val();
}else {
idVar = $(this).val();
}
}
});
$.ajax({
type: "POST",
url:"<?php echo Yii::$app->urlManager->createAbsoluteUrl(['dsproductitems/setproduct'])?>",
data: { dsItemId : idVar },
success:function(data) {
location.reload();
}
});
});
});
</script>
Here I'm trying to redirect my form to controller through ajax and the problem is, program control is failing to enter into flowing code.
$.ajax({
type: "POST",
url:"<?php echo Yii::$app->urlManager->createAbsoluteUrl(['dsproductitems/setproduct'])?>",
data: { dsItemId : idVar },
success:function(data) {
location.reload();
}
});
});
i'm failing to figure out why.. please help..

How can I get the value from method in my model?

I have some trouble displaying my result from a method in my model. this is the method:
/**
* #return \yii\db\ActiveQuery
*/
public function getSchoolFee()
{
return $this->hasOne(SibuSchool::className(), ['school_fee_id' => 'school_fee_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getScholarshipFee()
{
return $this->hasOne(SibuScholarship::className(),['scholarship_id'=>'scholarship_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getDiscountFee()
{
$scholarship= $this->getScholarshipFee();
$school= $this->getSchoolFee();
$data= new SibuPayment();
$data->total_payment=$school->amount-($scholarship->school_discount*$school->amount);
return $data;
}
i want to display the result from getDiscountFee method. I use this code on my View:
<?php echo $this->render('_search3', ['model' => $searchModel]); ?>
<?=
GridView::widget([
'dataProvider' => $dataProvider,
// 'filterModel' => $searchModel,
'columns' => [
[
// 'filterModel'=>'dataProviderSearch',
'attribute' => 'Nama',
'value' => 'virtual.student_name'
],
[
'attribute' => 'Uang Sekolah',
'value' => 'discountFee.total_payment'
],
[
'attribute' => 'Uang Kantin',
'value' => 'canteenFee.total_amount'
],
[
'attribute' => 'Uang Asrama',
'value' => 'dormitoryFee.amount'
],
[
'attribute' => 'Uang Perpustakaan',
'value' => 'libraryFee.amount'
],
[
'attribute' => 'Uang Les',
'value' => 'courseFee.amount'
],
[
'attribute' => 'Adm. Bank',
'value' => 'administration'
],
[
'attribute' => 'status',
'value' => function ($model) {
if ($model->scholarship_id == 0) {
return 'Tanpa Beasiswa';
} else if ($model->scholarship_id == 1) {
return 'Beasiswa Ekonomi Kategori A 100%';
} else if ($model->scholarship_id == 2) {
return 'Beasiswa Ekonomi Kategori B 50%';
} else if ($model->scholarship_id == 3) {
return 'Beasiswa Prestasi Kategori 50%';
} else if ($model->scholarship_id == 4) {
return 'Beasiswa Prestasi Kategori 25%';
} else {
return 'Beasiswa Prestasi Kategori 10%';
}
},
],
//'payment_class',
[
'attribute' => 'payment_class',
'value' => function ($model) {
if ($model->payment_class == 0) {
return 'Tanpa Golongan';
} else if ($model->payment_class == 1) {
return 'Golongan 1';
} else if ($model->payment_class == 2) {
return 'Golongan 2';
} else if ($model->payment_class == 3) {
return 'Golongan 3';
} else if ($model->payment_class == 4) {
return 'Golongan 4';
}
},
],
[
'attribute' => 'Total',
'value' => 'total_payment'
],
['class' => 'yii\grid\ActionColumn',
'template' => '{update_r}{del}',
'buttons' => [
'update_r' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
'title' => Yii::t('yii', 'View_r'),
]);
},
'del' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [
'title' => Yii::t('yii', 'Del'),
]);
},
]
],
],
]);
?>
it works fine if i display this:
[
'attribute' => 'Uang Sekolah',
'value' => 'scholarshipFee.school_discount'
],
and this:
[
'attribute' => 'Uang Sekolah',
'value' => 'schoolFee.amount'
],
can anybody help me? if you need anything feel free to ask.
[
'attribute' => 'Uang Sekolah',
'value' => 'discountFee.total_payment'
],
discountFee is a function of a model, it will never work until you put there the model too. You can just do a
[
'attribute' => 'Uang Sekolah',
'value' => function ($model) {
return $model->getDiscountFee()->total_payment;
}
},
],

Resources