Pagination in gridview Yii2 without page reload - ajax

I am a Yii2 beginner. I have almost completed all of my grid-view except for pagination. I tried to use pjax but can't find a solution.

You have to set timeout for Pjax (default is 1000 ms). Sometimes it is not enough and plugin will reload the page completely.
<?php \yii\widgets\Pjax::begin(['timeout' => 10000, 'clientOptions' => ['container' => 'pjax-container']]); ?>
<?= GridView::widget([
// ... configuration here
]);?>
<?php \yii\widgets\Pjax::end(); ?>
see here

Put your code between Pjax::begin and Pjax::end this work for every thing not only the gridview
<?php \yii\widgets\Pjax::begin(); ?>
<?= GridView::widget([
// ... configuration here
]);?>
<?php \yii\widgets\Pjax::end(); ?>

This May Help...:)
Just start and end Pjax thats all..
<?php
use yii\widgets\Pjax;
<?php Pjax::begin(['id'=>'type_id']); //id is used for jquery opertaion ?>
<?php echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'id',
//'user_id',
'type',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
<?php Pjax::end(); ?>

Related

Validating array of inputs in a form Yii2

I have been developing a system to create a dynamic questioner, where an organizer can create questions for a user to respond, but I have been having trouble validating the answers of the users to the questioners. I have three types of inputs available for the organizer to create, a short answer, a long answer and an input field. I tried using the Each validation rule, but it doesn’t seem to be working. I search all around for an answer to this, but I didn't find anything that worked.
Here is my code.
View
<?php $form = ActiveForm::begin([ 'id' => 'respuesta-form', 'enableAjaxValidation' => true, 'options' => ['enctype' => 'multipart/form-data'], ]); ?>
<?php foreach ($preguntas as $i => $pregunta): ?>
<?php if($pregunta->tipo == 1): ?>
<?= $form->field($model, "respuesta[$i]")->textInput(['maxlength' => true])->label("<strong>" . $pregunta->descripcion . "</strong>") ?>
<?php endif; ?>
<?php if($pregunta->tipo == 2): ?>
<?= $form->field($model, "respuesta[$i]")->textarea(['maxlength' => true], ["style" => "resize: none;"])->label("<strong>" . $pregunta->descripcion . "</strong>") ?>
<?php endif; ?>
<?php if($pregunta->tipo == 3): ?>
<?= $form->field($model, "respuesta[$i]")->fileInput()->label("<strong>" . $pregunta->descripcion . "</strong>") ?>
<?php endif; ?>
<?php endforeach; ?>
<div class="form-group">
<?= Html::submitButton('Guardar', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
Model
public function rules()
{
return [
[['idpregunta', 'idinscripcion'], 'required'],
['respuesta', 'each', 'rule' => ['required']],
[['idpregunta', 'idinscripcion'], 'integer'],
[['respuesta'], 'string', 'max' => 500],
[['idpregunta'], 'exist', 'skipOnError' => true, 'targetClass' => Pregunta::className(), 'targetAttribute' => ['idpregunta' => 'id']],
[['idinscripcion'], 'exist', 'skipOnError' => true, 'targetClass' => Inscripcion::className(), 'targetAttribute' => ['idinscripcion' => 'idInscripcion']],
];
}
Controller
public function actionResponderFormulario($slug){
$evento = $this->findModel("", $slug);
$inscripcion = Inscripcion::find()->where(["idEvento" => $evento->idEvento, "idUsuario" => Yii::$app->user->identity->idUsuario])->one();
$preguntas = Pregunta::find()->where(["idevento" => $evento->idEvento])->all();
$model = new Pregunta();
if($inscripcion ==null){
$preguntas = Pregunta::find()->where(["idevento" => $evento->idEvento])->all();
return $this->render('responderFormulario',
["preguntas" => $preguntas,
"eventos" => $evento,
"model" => $model]);
}
}
The most important thing for me is for the questions to validate in general, I don’t care that much to validate each type separately, because I may remove this later.
Thank you in advance
I think this part of string validation with max length should change to this:
['respueusta', 'each', 'rule' => ['string', 'max' => 500]]
Sometime respuesta field receives the file in tipo=3 , you can not do this for clean and structured code. define another field for files.

Ajax Filtering with GridView in Yii

I want to use PJax in Yii Grid View, not with the associative filter that comes inside the Grid View, but with the Search Filter that's outside it, so it can filter the results inside.
Here is the source of the index file:
<div class="cars-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::a('Create Cars', ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
'id',
'name',
['attribute' => 'code',
'label' => 'Colour',
'format' => 'raw',
'value' => 'colour',
'contentOptions' => function ($model, $key, $index, $column){
return ['style' => ' text-align: center; width: 100px;color:white;background-color:#'. $model -> code];
},
'headerOptions' => ['style' => 'text-align: center;'],
],
'price',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
Am I supposed to create an active form just for the part I want to filter? Or is there another way?
If You can't simply add the filter to you table like this
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
I suggest you use a proper action and a proper search function called by submit based on a specified active form
for action form eg:
<?php $form = ActiveForm::begin([
'id' => 'search-form',
'method' => 'post',
'action' => ['controller/yourAction']
]); ?>
in the controller
$model = new yourActiveForm();
if ($model->load(Yii::$app->request->post()) ) {
$dataProvider = $searchModel->search( [ 'yuorSearchModel'=> ['your_att1' => $model->yourValue1]]);
}
then your render
Conforming to yii2 doc
Pjax only deals with the content enclosed between its begin() and
end() calls, called the body content of the widget. By default, any
link click or form submission (for those forms with data-pjax
attribute) within the body content will trigger an AJAX request. In
responding to the AJAX request, Pjax will send the updated body
content (based on the AJAX request) to the client which will replace
the old content with the new one. The browser's URL will then be
updated using pushState. The whole process requires no reloading of
the layout or resources (js, css).
You may configure $linkSelector to specify which links should trigger
pjax, and configure $formSelector to specify which form submission may
trigger pjax.
You must add the
<?php Pjax::begin(); ?>
.... your active form
<?php Pjax::end(); ?>
and configure the proper $linkSelect and $formSelector
In your filter view:
<div id="myFilter">
<?php $form = ActiveForm::begin([
'id' => 'myFilterForm',
'method' => 'post',
'action' => [...],
]); ?>
...
</div>
And make sure you render filter between Pjax::begin and Pjax::end
Yet here comes the trick. If your server does not respond within default timeout, Pjax gets ignored and page reloaded, so make sure the timeout is big enough:
<?php Pjax::begin([
'id'=>'myGrid',
'timeout' => 10000, // <------------ THIS !!!!!!!
'formSelector' => '#myFilterForm'
]); ?>
<?= $this->render('myFilter', ['model' => $searchModel]); ?>
<?= GridView::widget([
...
]); ?>
<?php Pjax::end(); ?>
Also in your controller, you might want to "reset" the search model, so only data from the request used are attributes actually used by search:
public function actionSearch()
{
$searchModel = new MySearch();
if ($searchModel->load(Yii::$app->request->post())) {
$searchModel = new MySearch(); // "reset"
$dataProvider = $searchModel->search(Yii::$app->request->post());
} else {
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
}
return $this->render('search', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
Hope this helps. Cheers!

Yii2 KCFinder : How to upload images to "Common" or "Frontend" directory

I run into a problem. I use CKEditor to crete HTML Editor and also use KCFinder to upload&insert images within the HTML editor. My problem is, I cannot show the images,that i uploaded via KCFinder, in my FrontEnd website
My code (In backend/view/_form)
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use backend\modules\CKEditor;
use iutbay\yii2kcfinder\KCFinder;
$kcfOptions = array_merge(KCFinder::$kcfDefaultOptions, [
//'uploadURL' => Yii::getAlias('#web').'/upload',
'uploadURL' => Yii::getAlias('#common').'/upload',
'access' => [
'files' => [
'upload' => true,
'delete' => true,
'copy' => true,
'move' => true,
'rename' => true,
],
'dirs' => [
'create' => true,
'delete' => true,
'rename' => true,
],
],
]);
// Set kcfinder session options
Yii::$app->session->set('KCFINDER', $kcfOptions);
?>
<div class="emails-form">
<?php yii\widgets\Pjax::begin(['id' => 'new_email']) ?>
<?php $form = ActiveForm::begin(['options' => ['enctype'=>'multipart/form-data' ]]); ?>
<?= $form->field($model, 'receiver_name')->textInput(['maxlength' => 200]) ?>
<?= $form->field($model, 'receiver_email')->textInput(['maxlength' => 200]) ?>
<?= $form->field($model, 'subject')->textInput(['maxlength' => 200]) ?>
<?//= $form->field($model, 'content')->textarea(['maxlength' => 200]) ?>
<?= $form->field($model, 'content')->widget(CKEditor::className(), [
'options' => ['rows' => 6],
'preset' => 'full'
//'preset' => 'basic'
])
?>
<?= $form->field($model, 'attachment')->fileInput(['maxlength' => 200]) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
<?php yii\widgets\Pjax::end() ?>
</div>
Now my code can work correctly but the images will be uploaded to "backend/web/upload" How can i upload the images via KCFinder to "frontend/web/upload" ?
Or Is there any suggestion solution for the case? I need to use CKEditor+KCFinder to create a news form then I can show the content in Frontend Website.
Thank you very much for your help.
Look the Yii2 provided both frontend/backend for our use. i recommend forget that it is in backend for now.
what you can do is set param which will go to backend/web/updloads and save file names only in db i mean file name/path after upload folder.
like this :
This will be your bakcend : backend.example.com/uploads/
and file names in your db after upload : file.jpg, profile/firstuser.png.
when you able to access it from the frontend just copy your upload folder from backend to frontend.
See i know this is not write solutions however it worked for me. i think it will help me .
This is my first answer please ask if i am unclear :)
Thanks
Finally, I found the solution. I created the link by using command :
cd /path/to/project/frontend/web
ln -s ../../backend/web/upload upload
After that, I edited the httpd-vhosts.conf to allow "Options +FollowSymlinks".
<VirtualHost *:80>
ServerName example.com
DocumentRoot "/path/to/project/frontend/web"
Options +FollowSymlinks
...
</VirtualHost>
Do not forget to "restart" apache service. :)
Reference site -> http://www.yiiframework.com/wiki/799/yii2-app-advanced-on-single-domain-apache-nginx/

Yii2 ajax validate and submit form

I have very little AJAX's Information. That's why I asked my question here...
in yii2 how can create and submit form with ajax validation?
So I searched but could not find the right solution...
for example: (according to the official training site)
<?php $form = ActiveForm::begin([
'id' => $model->formName(),
'enableAjaxValidation' => true,
]); ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'extra_txt')->textInput(['maxlength' => true]) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
and in controller:
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = 'json';
return ActiveForm::validate($model);
} else {
return $this->render('create', [
'model' => $model,
]);
}
My problems:
1- ajax validation
2- submit form with ajax
Why don't you use Pjax? Use yii\widgets\Pjax and add Pjax::begin() and Pjax::end() around your form.
A decent guide over here:
http://www.yiiframework.com/wiki/772/pjax-on-activeform-and-gridview-yii2/

Login with CakePHP and jQuery Mobile

I'm building a mobile application with CakePHP 2.3 and jQuery Mobile.
I'm having a tough time making the login work.
I send out links that contain surveys, and if the user is not logged in on their mobile browser, it first makes them sign in.
The problem is that the first time, it just refreshes to a blank page. If you close the page and reopen the link, it works, but that sucks. I'd like it to just redirect correctly.
Here's the view for login:
<div class="users form">
<?= $this->Session->flash('auth'); ?>
<?= $this->Form->create('User'); ?>
<fieldset>
<?
echo $this->Form->input('username');
echo $this->Form->input('password');
?>
</fieldset>
<?
$options = array(
'label' => 'Login',
'rel' => 'external',
'data-ajax' => false
);
?>
<?= $this->Form->end($options); ?>
</div>
As you can see, I tried rel=external and data-ajax=false.
Putting the login on the same page somehow might solve the issue, but that seems like it defeats the purpose of using CakePHP in the first place.
Any ideas? I'm stumped.
That's not going to create an AJAX form in Cake.
You have to disable the default action of the form, and then submit the data via Javascript. You can use the built in JsHelper in Cake to do this.
To disable auto submitting of the form you need to pass this to the create method.
Form->create('User',array('default'=>false)); ?>
You can then use the serializeForm method of the JsHelper.
<?php
$data = $this->Js->get('#UserForm')->serializeForm(array('isForm' => true, 'inline' => true));
$this->Js->get('#UserForm')->event(
'submit',
$this->Js->request(
array('action' => 'save'),
array(
'update' => '#UserForm',
'data' => $data,
'async' => true,
'dataExpression'=>true,
'method' => 'POST'
)
)
);
?>
Note: The above requires that you place the output from JsHelper in the proper location of your layout.
You can now render the form like this.
<div class="users form">
<?= $this->Session->flash('auth'); ?>
<?= $this->Form->create('User',array('default'=>false)); ?>
<fieldset>
<?
echo $this->Form->input('username');
echo $this->Form->input('password');
?>
</fieldset>
<?
$options = array(
'label' => 'Login',
);
?>
<?= $this->Form->end($options); ?>
</div>
This off the top of my head. So it's not test.

Resources