Pushstate in pjax only when redirecting - yii2

In one of my pages I have a link that is handled by pjax. Basically the user clicks an item, this item becomes "checked" (and saved in the DB).
I have disabled pushState for these requests, because it makes no sense, user effectively stays in the same page, so it's counter-intuitive to change the url.
However, there is a case when this pjax request results in redirect to login page (when the user is not logged in). And this is when I really need pushState to work, and it doesn't because I disabled it in the first place.
Would it be possible to configure pjax in such a way that normal responses work without pushState, but redirect responses (done with X-Pjax-Url header) do perform pushState?

There's no way to do it using current functionality. I've added two more options to pjax and my PR has been accepted to yii2 branch of pjax. So, without further ado:
https://github.com/yiisoft/jquery-pjax
//pushRedirect - Whether to pushState the URL for redirects. Defaults to false.
//replaceRedirect - Whether to replaceState the URL for redirects. Defaults to true.
// ...
jQuery(document).pjax("#example_selector", {
"push": false,
"replace": false,
"pushRedirect": true,
"replaceRedirect": false
});

Use a linkSelector to specify which links trigger the pjax calls
<?php Pjax::begin([
'enablePushState' => false, // don't change the Browser URL
'linkSelector' => 'pjax-btn', // pjax links that
]); ?>
<?= GridView::widget([
//...
[ // no pjax, normal linl
'label' => 'link with state replace',
'format' => 'raw',
'value' => function ($model, $key, $index, $column) {
return Html::a($model->title, Url::to(['/controllet/action', 'id' => $model->id]));
}
],
[
'class' => 'yii\grid\ActionColumn',
//'class' => 'common\widgets\ActionColumn',
'template' => '{toggle} {view} {update} {delete}',
'buttons' => [
'toggle' => function ($url, $model, $key) {
$options = [
'title' => 'Privacy',
'aria-label' => 'Privacy',
'class' => 'pjax-btn', // no state replacement, load with pjax
];
$icon = Html::tag('span', '', ['class' => 'glyphicon glyphicon-check']);
return Html::a($icon, $url, $options);
},
]
]]) ?>
<?php Pjax::end(); ?>

Related

Yii2 Pagination + PrettyURL Cannot Find site/index

I have pagination setup in site/index, with pretty url working. But my site/index is hidden by either the rewrite engine of Apache, or by UrlManager. In any case, my index page address is simply "X.COM' and pagination wishes to redirect a page change to "X.COM/index?PAGINATIONQUERY", so it always returns a 404.
Example Pagination Request (Returns 404):
x.com/index?page=2&per-page=12
Here is my UrlManager
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
// '<alias:\w+>' => 'site/<alias>',
'<action:\w+>' => 'site/<action>',
],
],
How would I either remove the 'index' portion from pagination requests, or allow myself to see /index in Url again?
Thank you!
Edit:
This is my Index action
public function actionIndex()
{
$query = Shout::find()->orderBy(['id' => SORT_DESC]);
$countQuery = $query->count();
$pagination = new Pagination(['totalCount' => $countQuery, 'pageSize' => 12]);
$shouts = $query->offset($pagination->offset)
->limit($pagination->limit)
->all();
return $this->render('index', [
'shouts' => $shouts,
'pagination' => $pagination,
]);
}
Use Yii2 Gii for Generating Crud Modules with Inbuilt Pagination & Searching.
Yii2 Gii - https://www.yiiframework.com/doc/guide/2.0/en/start-gii
Make Sure Pjax enable when create crud with Gii.

In Yii2 Kartik Select2 widget how to make an ajax call on select event?

In select2 widget of yii2, how can we make an ajax call from the widget to a function in our controller:
Scenario is I need to create a custom ID for a table the id depends upon the two dropdown value and on select event of the select2 drop down I need to fetch the record and construct the ID and put the value of the newly created id in the form filed.
I just have problem in making an ajax call from the select2 dropdown widget
Try following:
You can use select2:select event to make ajax call.
echo $form->field($model, 'state_1')->widget(Select2::classname(), [
'data' => $data,
'options' => ['placeholder' => 'Select a state ...'],
'pluginOptions' => [
'allowClear' => true
],
'pluginEvents' => [
"select2:select" => "function() { // function to make ajax call here }",
]
]);
'pluginEvents' => [
'change' => 'function() {
var selectedIds = $(this).val();
$.pjax.reload({container: "#testing", data:{tags:selectedIds}});
}'

Displaying subdirectory name in the url in Yii2 for static pages

Iam creating static pages for a client using Yii2. I am using yii2 because the client has some other requirements to scale up the web later. I use Yii2 Basic app. The yii2 basic has default pages like about, contact etc.
The url for those pages after enabling pretty url is
www.example.com/about
etc
Now i need to create pages
"xyz.php"
under a sub directory like
"abc"
. So i need my url to be www.example.com/abc/xyz
How do i achieve this? to be informed iam a learner, I followed url rules, helpers but did not find a strong solution.
create a controller like StaticController.php and use the yii\web\ViewAction
http://www.yiiframework.com/doc-2.0/yii-web-viewaction.html
As an example:
namespace app\controllers;
use Yii;
use yii\web\Controller;
use yii\filters\AccessControl;
/**
* StaticController is only for displaying static pages.
*/
class StaticController extends Controller
{
public $defaultAction = 'page';
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['page'],
'allow' => true,
'roles' => ['#'],
],
],
],
];
}
public function actions()
{
return [
'page'=>array(
'class'=>'yii\web\ViewAction',
'viewPrefix'=>null, // or set a specific directory e.g. 'static-pages' if you want to store the static pages in a subdirectory
),
];
}
}
And add this Rule to your UrlManager (where static is your controller name)
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'<controller:static>/<view:.*>' => '<controller>',
...
]
]
Now you can store your static pages in the directory /view/static/
e.g. index.php, test.php or even in subdirectories /sub/test2.php
The urls would be like /static (or /static/index), /static/test1, /static/sub/test2
The 1st pathname is of course the controller name, but you can also change the url rule to something else or rename the controller.
config/web.php
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'abc/<view:\S+>' => 'site/page',
]
]
I had a situation where I wanted the URL to indicate a sub page (like 'website/page/sub-page) but I didn't think it made sense to have a separate controller. (At the moment I just have one controller; SiteController.php.)
I am recreating the site structure of an existing site in a new Yii2 Basic site.
Client has a page called 'laptop-repair' in their existing site with a number of pages linked from it, e.g. 'laptop-overheating'. So the URI needed to look like 'laptop-repair/laptop-overheating'.
The solution:
In urlManager in config>web.php I add a new rule (Nb. the order of rules is important, the earlier rules are prioritised):
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'/' => 'site/index',
[
'pattern' => 'laptop-repair/<page:.*>',
'route' => 'site/laptop-repair',
'defaults' => ['page' => 'index'],
],
...
],
],
In SiteController.php I already had an action for the page which I wanted to make into a parent page:
public function actionLaptopRepair()
{
return $this->render('laptop-repair');
}
which I replaced with:
public function actionLaptopRepair($page)
{
return $this->render("/site/laptop-repair/$page");
}
The leading slash is necessary to override the default behaviour of the Yii application, which is to look for the view in 'views>{controllerName}'. For example with render('laptop-repair'); the view file laptop-repair.php would need to be in 'views>site' since the name of the controller is SiteController, whereas render("/site/laptop-repair/$page"); corresponds to a view file ($page) in 'views>site>laptop-repair'. This allows you to organise your views in subdirectories.
I created a new folder called 'laptop-repair' in 'views>site', moved the view for the parent page (laptop-repair.php) into the new directory and renamed it index.php. I put the new sub pages' view files in that new directory ('views>site>laptop-repair'), alongside the parent view (index.php).
Everything worked except for the URL creation in my nav widget. Where the following worked fine before, the 'laptop-repair' link broke after I implemented the above:
echo Nav::widget([
'options' => ['class' => 'navbar-nav ml-auto'],
'items' => [
['label' => 'Home', 'url' => ['/site/index']],
[
'label' => 'Repair Services',
'items' => [
['label' => 'Desktop PC Repairs', 'url' => ['/site/pc-repair']],
['label' => 'Laptop Repairs', 'url' => ['site/laptop-repair']],
['label' => 'Mobile Phone Repairs', 'url' => ['/site/mobile-phone-repair']],
...
The fix was simply changing the relevant line to:
['label' => 'Laptop Repairs', 'url' => ['/laptop-repair']],
Creating a link from the parent page to a sub page looks like this:
<?= Html::a('Laptop overheating?', ['laptop-repair/laptop-overheating'], ['class' => '', 'title' => 'Laptop overheating']) ?>
To add a link to the parent page to the breadcrumbs of the sub page, I replaced:
$this->title = 'Laptop Over Heating?';
$this->params['breadcrumbs'][] = $this->title;
with:
$this->title = 'Laptop Over Heating?';
$this->params['breadcrumbs'][] = ['label' => 'Laptop repair', 'url' => ['/laptop-repair']];
$this->params['breadcrumbs'][] = $this->title;
in the view file of the sub page.

Send serialize data on kartik file input

I am implementing \kartik\file\FileInput widget.
Here is my code:
<?php
echo FileInput::widget([
'name' => 'dataSiswa',
'options' => [
'multiple' => false
],
'pluginOptions' => [
'uploadUrl' => Url::toRoute('pesertadidikuploadproses'),
'uploadExtraData' => ['folderId' => ""],
'showUpload' => true
],
'pluginEvents' => [
'fileuploaded' => "function(event, data, previewId, index) {
$('#pesan').show();
$('#pesan').html(data.response.pesan);
}"
]
]);
?>
I want the value of uploadExtraData should be get as serialize data form --> $('#formid').serialize();
Like said in this post, you can't direct access to files on a user computer. One technique is to use and iframe to do the submission and that way you won't have to refresh the page.
So use this plugin and just do something as below:
$(function() {
$('#ifoftheform').ajaxForm(function(result) {
alert('the form was successfully processed');
});
});

html to pdf converter in yii2 with pagination in table

view:
<p>
<?= Html::a('Download This page', ['report'], ['class' => 'btn btn-danger']) ?>
</p>
controller:
public function actionReport()
{
// setup kartik\mpdf\Pdf component
$pdf = new Pdf([
'content' => $content,
'options' => ['title' => 'Krajee Report Title'],
'methods' => [
'SetHeader' => ['Krajee Report Header'],
'SetFooter' => ['{PAGENO}'],
]
]);
return $pdf->render();
}
This function works perfectly but my html table has pagination . so i am confused how to deal with table that has pagination.
You should disable the pagination. it all depends on how you define your data provider (read more about data providers here http://www.yiiframework.com/doc-2.0/guide-output-data-providers.html). Probably you should do something like this
************* = new ActiveDataProvider([
'pagination' => false,
..............
]);
I think you can also call it like
$dataProvider->pagination =false;
Just in case you need to disable it in a specific case.