Yii2 Pjax reloads entire page on second form submit - php

I cannot seem to figure out why pjax reloads the page on the second form submission. It works exactly as intended on the first form submission pulling from this url /site/profile?UserSearch%5Bsearchstring%5D=mi&_pjax=%23form-pjax, however, after that first one it loses the ending of the url /site/profile?UserSearch%5Bsearchstring%5D=m. I checked the actual html code and the form is retaining the data-ajax attribute. I tried increasing the timeout as had been suggested when pjax is reloading the entire page, but that did not change anything.
Below is the code from my view
<?php Pjax::begin(['timeout' => 5000, 'id' => 'form-pjax']); ?>
<?php $form = ActiveForm::begin([
'method' => 'get',
'action' => Url::to(['site/profile']),
'options' => ['data-pjax' => true ],
]); ?>
<?= $form->field($searchModel, 'searchstring', [
'template' => '<div class="input-group">{input}<span class="input-group-btn">' .
Html::submitButton('Search', ['class' => 'btn btn-default']) .
'</span></div>',
])->textInput(['placeholder' => 'Find friends by username or email']);
?>
<?php ActiveForm::end(); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
'username',
[
'label' => 'View Profile',
'format' => 'raw',
'value'=>function ($data) {
return Html::a(Html::encode("View Profile"),'/site/redirectprofile/'.$data->id);
},
],
[
'label' => 'Follow',
'format' => 'raw',
'value'=>function ($data) {
return Html::a(Html::encode(Follow::find()->where(['user_id' => $data->id, 'follower_id' => Yii::$app->user->Id])->exists() ? 'Unfollow' : 'Follow'),'/site/follow/'.$data->id.'/'.$data->username);
},
],
],
'summary'=>'',
]); ?>
<?php Pjax::end(); ?>

You must call needed javascript triggers/functions after every pjax reload like:
$('#form-pjax').on('pjax:success', function() {
/*call Your functions here, or copy from your generated page js code,
that bind event to pjax form,
at end of generated html You should have something like: */
jQuery(document).on('submit', "#form-pjax form[data-pjax]", function (event) {
jQuery.pjax.submit(event, '#form-pjax', {"push":true,"replace":false,"timeout":000,"scrollTo":false});
});
});
This is not yii2 issue, it's how javascript works, when You add dynamically content it's needed to bind triggers/events for every added element.

Related

Yii2 pjax corrupts styles

I'm using Yii2 and i have a view which displays a table:
<div class="table-responsive">
<?php yii\widgets\Pjax::begin()?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'summary'=> "",
'tableOptions' => ['id'=>'smartTable',
'class' => 'display table-bordered-custom',
'cellspacing' => 0,
'width' => "100%"
],
'columns' => [
[
'class' => 'yii\grid\SerialColumn'],
'product_code',
'product_name',
'product_status',
[
'class' => 'yii\grid\ActionColumn',
'header' => 'Operation',
'template' => '{view}',
'headerOptions' => ['class' => 'no-sort'],
'buttons' => [
'view' => function ($url, $model) {
return Html::a(
'Edit<i class="material-icons">chevron_right</i>',
['update', 'id'=>$model->product_id],
[
'class' => 'btn',
'data-pjax' => '',
]
);
},
],
],
],
]);
?>
<?php Pjax::end(); ?>
</div>
My controller:
class ProductController extends Controller
{
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::class,
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all Product models.
* #return mixed
*/
public function actionIndex()
{
$dataProvider = new ActiveDataProvider([
'query' => Product::find(),
'sort' => false,
'pagination'=> [
'pageSize' => 4
]
]);
return $this->render('index', [
'dataProvider' => $dataProvider,
]);
}
}
Edit: My controller has a simple action called index.
My problem is that when i click on the page number and get new info, all the styles I've given to my table disappear.
If i remove Pjax everything is okay because the entire page reloads.
Why? please help me.
I finally managed to fix this! but i'm not sure it's the best.
With pjax events you can solve such problems:
$(document).on("pjax:success", function() {
$('#smartTable').DataTable({
"paging": false,
"responsive": true,
"dom": 'iftlp',
"bProcessing": true,
"aoColumnDefs": [ // EXCEPT SORTING
{'bSortable': false, 'aTargets': ['no-sort']}
],
});
$('#simpleTable').DataTable({
"responsive": true,
"dom": 't'
});
});
So every time our pjax is successfully executed, we will re-apply the style we need.
That's it, i hope to be useful to others.
Thanks to pjax that we can reload selective content easily.
Issue
In Yii2, pjax also do try to loads the anchors (links) etc present inside the pjax container within the same container. Which means it doesn't allow such links to load, full pages. This causes crippling of the other parts / tags in followed pages.
Solution
In order to avoid this, you need to figure out a way to load your links/pages outside the pjax container. One method that worked for my action links is as following:
Example
This is my custom actions column:
[
'label'=>'Options',
'format' => 'raw',
'value'=>function ($data) {
return Html::a('<i class="glyphicon glyphicon-eye-open"></i>', ['short-message/conversation', 'id'=> $data["id"]], ['onclick' =>'window.location.href=this.getAttribute("href")']);
},
],
Explanation
You can see that I have used onclick method to follow the link using JavaScript:
['onclick' =>'window.location.href=this.getAttribute("href")']

Balloon hint after hovering on gridview field

I have a simple gridview table, that shows data from one table only. It contains field named "comment" (of each product) and, since the comments can be very long, in gridview I show only first 50 characters. I would like, that after I hover on each comment, a balloon/bubble/not-sure-how-to-call-it appears, with the whole comment inside. Is it possible for GridView? No clicking, just right after hovering on comment.
<div class="comments">
<?=
GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
'place_rating',
'comment:longtext',
],
]);
?>
</div>
<div class="comments">
<?=
GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
'place_rating',
// 'comment:longtext',
[
'attribute' => 'comment',
'format' => 'longtext',
'contentOptions' => function($data) {
// needs to be closure because of title
return [
'class' => 'cell-with-tooltip',
'data-toggle' => 'tooltip',
'data-placement' => 'bottom', // top, bottom, left, right
'data-container' => 'body', // to prevent breaking table on hover
'title' => $data->comment,
];
}
]
],
]);
?>
</div>
Then in your in /views/layouts/main.php add this
<?php $this->registerJs("
$(function () {
$('[data-toggle=\"tooltip\"]').tooltip();
});
", $this::POS_END, 'tooltips'); ?>
or add it to your .js file without php code ofcourse

Get selected rows value from kartik gridView in modal and pass it to parent form

I try to get value from modal bootstrap (contain table kartik gridview), and i want to pass the selected value to parent form (action create form). How to do that? Please advice.
modal form contains fields like this
<?php
$gridColumns = [
'id',
'date',
[
'attribute' => 'agen_id',
'value' => 'agen.agen_name'
],
[
'attribute' => 'price',
'format' => ['decimal', 0],
],
'remark_1:ntext',
'remark_2:ntext',
] ?>
and this is the button in parent form
<div class="col-xs-8">
<div class="form-group field-poagen-price">
<br>
<?= Html::button('Price List', ['value' => Url::to('../pricelist/list'), 'class' => 'btn btn-primary', 'id' => 'BtnModalPriceList']) ?>
<?php
Modal::begin([
'header' => 'List Harga',
'id' => 'modal',
'size' => 'modal-md'
]);
echo "<div id='modalContent'></div>";
Modal::end();
?>
</div>
</div>
and i register my jquery like this
$('#BtnModalPriceList').click(function(){
$('#modal').modal('show')
.find('#modalContent')
.load($(this).attr('value'));});
I want to get the value from modal to pass to the parent in order to fill the required field.
I have searched for a few days and still have no luck.
Please advice for the master. Thanks before.
I have solved it. This is what i do.
Create custom button in the gridView
[
'class' => 'yii\grid\ActionColumn',
'template' => '{select}',
'buttons' => [
'select' => function($url, $model, $key){
return Html::button('Select', [
'title' => Yii::t('yii', 'Select'),
'aria-label' => Yii::t('yii', 'Select'),
'class' => 'btn btn-primary select-row',
'data-id' => $model->id,
]);
},
],
],
and then register to jquery to process the data
$(document).on('click', '.select-row', function(){
// get id from custom button
var id = $(this).attr('data-id');
$.get('../pricelist/get-price', {id : id}, function(data){
$('#poagen-price').val(data);
});
$('#modalPriceList').modal('hide');
$('#poagen-fee').focus();
});
got help from #milos-ozegovic

YII2 Insert records selected from one grid to another

i'm new in Yii2, previously i use self-made-mvc-php + extjs 4.2
So i working on Yii2 now, i'm starting to get the hang of it for simple CRUD, my pobrem starts when i need to make entry form for parent-child tables.
I have 3 tables
commission
commission_id
commission_name
commission_amount
commission_percent
commission_scheme
cscheme_id
cscheme_name
cscheme_amount
cscheme_percent
cscheme_bonus
cscheme_description
commission_scheme_detail
cscheme_detail_id
commission_id
cscheme_id
The entry form is for commission_scheme and commission_scheme_detail.
I have generated all the crud using gii
i modify _form.php, add a gridview of commission_scheme_detail after the active form
i also add modal containing selection grid from commission
this is _form.php
gridview
<?php Pjax::begin(['id' => 'pjaxCschemedetail',
'timeout' => false,
'enablePushState' => false,
'clientOptions' => ['method' => 'POST']
]);
echo GridView::widget([
'id' => 'gridCschemedetail',
'dataProvider' => $detailData,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'CSCHEME_DETAIL_ID',
'CSCHEME_ID',
'COMMISSION_ID',
[
'class' => 'yii\grid\ActionColumn',
'buttons' => [
'update' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', Yii::$app->urlManager->createUrl(['commission-scheme-detail/view','id' => $model->CSCHEME_DETAIL_ID,'edit'=>'t']), [
'title' => Yii::t('yii', 'Edit'),
]);}
],
],
],
'responsive'=>true,
'hover'=>true,
'condensed'=>true,
'floatHeader'=>true,
'panel' => [
'type'=>'info',
'before'=>
'after'=>Html::a('<i class="glyphicon glyphicon-repeat"></i> Reset List', ['index'], ['class' => 'btn btn-info']),
Html::button('Add', [
'id' => 'addDetailButton',
'class' => 'glyphicon glyphicon-plus btn btn-success btn-ajax-modal',
'value' => Url::to('#web/commission/listselect'),
'data-target' => '#modal_cschemedetail',
]),
'showFooter'=>false
],
]); Pjax::end();
Modal
Modal::begin([
'id' => 'modal_cschemedetail',
'header' => '<h4>Category</h4>',
]);
echo '<div id="modal-content"></div>';
echo Html::button('Add Selected', [
'id' => 'addCommissionsButton',
'class' => 'btn btn-success btn-ajax-modal'
]);
Modal::end();
?>
</div>
</div>
<div class="box-body">
</div>
</div>
selection grid
<?php Pjax::begin(); echo GridView::widget([
'id' => 'gridCommissionSelection',
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\CheckboxColumn'],
['class' => 'yii\grid\SerialColumn'],
[
'attribute' => 'COMMISSION_ID',
'visible' => false
],
'COMMISSION_NAME',
[
'attribute' => 'TRANSACTION_TYPE_ID',
'value' => 'transactionTypeName'
],
'COMMISSION_DESC:ntext',
'COMMISSION_AMOUNT',
]
'responsive'=>true,
'hover'=>true,
'condensed'=>true,
'floatHeader'=>true,
]); Pjax::end(); ?>
Is it possible to insert the selected records from the modal to the detail gridview, then after user click the create button, the form and the inserted records in gridview saved to respective tables?
How can i insert the selected records to gridview (not to db table, it will be done after user click create)?
I suggest you to simplify your flow. You can easily save your models (performing an insert/update) at Modal and then refresh the page or call the $.pjax.reload('#gridCommissionSelection') to redraw the grid-view with new entries.
Another way is to append new lines with JS and then save them via AJAX request. It will be rather dirty and unclear solution, I guess :)

Yii2 - Render _search.php file inside index.php of a view

i have a view folder called eventos in Yii2. This view is an image gallery.
The _view2.php is for display of the images to general public. It works quite well.
But now i want to create a globalsearch input text inside _view2.php.
There i have already a GridView widget for display the images, but i don't want to use the $searchmodel boxes so i disable them.
What i want is to render the _search.php file with just one input field, inside the _view2.php file
My problem is in rendering the _search.php inside the _view2.php file.
Here is the code for _view2.php:
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'showOnEmpty'=>false,
'summary'=>'',
'showFooter'=>false,
'showHeader' => false,
'bordered' => false,
'striped' => false,
'hover' => true,
//'options' => ['class' => 'grid-view'],
//'layout' => "{summary}\n{items}\n{pager}",
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'id',
//'nome',
'descricao',
'data',
// No model -> getImageurl()
[
'label' => '',
'format' => 'raw',
'value'=> function($data) { return Html::a(Html::img($data->imageurl, ['width'=>'300', 'height' => "170"]), $data->foto); },
],
[
'label' => '',
'format' => 'raw',
'value'=> function($data) { return Html::a(Html::img($data->imageurl2, ['width'=>'300', 'height' => "170"]), $data->foto2); },
],
['class' => 'yii\grid\ActionColumn', 'template' => ''],
],
]); ?>
And i need to render the _search.php inside the _view2.php.
Code for _search.php:
<?php $form = ActiveForm::begin([
'action' => ['index'],
'method' => 'get',
]); ?>
<?= $form->field($model, 'globalsearch') ?>
Any ideas?
SOLVED.
_view2.php code:
use yii\base\view;
echo $this->render('_search', array('model'=>$searchModel));
You can use renderPartial to display a partil view inside another
For example adding this:
<?php echo $this->renderPartial('_search', array('model'=>$model)); ?>
This is an example that is generated with gii by the way
Here is the code of a file view/create.php:
<?php
/* #var $this EventsController */
/* #var $model Events */
$this->breadcrumbs=array(
'Events'=>array('index'),
'Create',
);
$this->menu=array(
array('label'=>'List Events', 'url'=>array('index')),
array('label'=>'Admin Events', 'url'=>array('admin')),
);
?>
<h1>Create Event</h1>
<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>
As you can see the view 'create' loads the partial view '_form' that is the way you acomplish this. So you can reuse the _form view in another views like in the update view for example.

Categories