Reputation: 1024
I try without success to update the DataProvider of a listview when i submit a form through Ajax. It is working when i submit without ajax, but refresh the page. I would like to do it without refreshing the page. I don t know what exactly could be wrong in my code below:
Here is the form and the listview:
jobs.php
...
<div style="background-color: white;">
<div class="job_quick_search_container">
<?php $form = ActiveForm::begin([
'id' => 'quick_search_form',
'enableAjaxValidation'=>false,
'enableClientValidation'=>true,
'options' => ['class' => 'form-horizontal',
'onkeypress'=>" if(event.keyCode == 13){ searchJob(); }"
],
]); ?>
<table style="width:100%">
<colgroup>
<col style="width:20%">
<col style="width:20%">
<col style="width:20%">
<col style="width:40%">
</colgroup>
<tr>
<td style="padding-right: 50px;">
<?= $form->field($jobCompanyCategorySearchModel, 'ccCategory')->dropDownList( ArrayHelper::map(Companycategory::find()->all(),'ccID', 'ccCategory'), ['prompt'=>'Select a category'] )
?>
</td>
<td style="padding-right: 50px;">
<?= $form->field($jobUserSearchModel, 'uCountry')->dropDownList( ArrayHelper::map(User::find()->all(),
'uCountry', 'uCountry'),
['prompt'=>'Select a country'] )
?>
</td>
<td style="padding-right: 50px;">
<?= $form->field($jobUserSearchModel, 'uCompanyName')->dropDownList( ArrayHelper::map(User::find()->all(),
'uCompanyName', 'uCompanyName'),
['prompt'=>'Select a company'] )
?>
</td>
<td>
<div class="form-group">
<?= Html::Button('Find a job', ['class' => 'btn btn-primary',
'onclick' => 'searchJob();',
'style' => 'font-size:18px']) ?>
</div>
</td>
</tr>
</table>
<?php ActiveForm::end(); ?>
</div>
<table style="width:100%">
<colgroup>
<col style="width:65%">
<col style="width:35%">
</colgroup>
<tr>
<td>
//This partial view contains the listview
<?= $this->render( 'jobs_partial_view', ['dataProvider'=> $dataProvider] ); ?>
</td>
...
The partial view: jobs_partial_view.php
<?php
use yii\widgets\ListView;
?>
<div class="jobs_listView_container">
<?=
ListView::widget([
'dataProvider' => $dataProvider,
'options' => [
'tag' => 'div',
'class' => 'list_jobs_profile',
'id' => 'list_jobs_profile',
],
'layout' => "{items}\n{pager}",
'itemView' => function ($model, $key, $index, $widget) {
return $this->render('_job_view',['model' => $model]);
},
'itemOptions' => [
'tag' => false,
],
'pager' => [
'firstPageLabel' => 'first',
'lastPageLabel' => 'last',
'nextPageLabel' => 'next',
'prevPageLabel' => 'previous',
'maxButtonCount' => 3,
],
'emptyText' => "Sorry, No jobs found",
]);
?>
Here ist the Jquery function using Ajax:
function searchJob(){
var seach_data_job = $("#quick_search_form").serialize();
$.ajax({
type: 'POST',
url: 'jobs',
data: seach_data_job,
dataType: 'html',
success: function(e) {
},
/*
error: function(response, status){
console.log(response);
console.log(status);
}
*/
});
return false;
}
Here the Controller:
public function actionJobs()
{
$jobCompanyCategorySearchModel = new JobCompanycategorySearch();
$jobUserSearchModel = new JobUserSearch();
if ( $jobUserSearchModel->load( Yii::$app->request->post() ) &&
$jobCompanyCategorySearchModel->load( Yii::$app->request->post() ) ) {
$idCategorySearch = $jobCompanyCategorySearchModel->ccCategory;
$companyNameSearch = $jobUserSearchModel->uCompanyName;
$companyCountrySearch = $jobUserSearchModel->uCountry;
$dataProvider = new ActiveDataProvider([
'query' => Jobs::find()->where(['jCategory' => $idCategorySearch])
->orderBy('jID DESC'),
'pagination' => ['pageSize' => 10,],
]);
echo $this->renderPartial( 'jobs_partial_view',
['jobCompanyCategorySearchModel' => $jobCompanyCategorySearchModel,
'jobUserSearchModel' => $jobUserSearchModel,
'dataProvider' => $dataProvider
] );
}
else {
$dataProvider = new ActiveDataProvider([
'query' => Jobs::find()->orderBy('jID DESC'),
'pagination' => ['pageSize' => 10,],
]);
return $this->render('jobs', ['jobCompanyCategorySearchModel' => $jobCompanyCategorySearchModel,
'jobUserSearchModel' => $jobUserSearchModel,
'dataProvider' => $dataProvider
] );
}
}
After submitting the forms through Ajax, i get the data in the controller, but the funtion renderPartial is not updating the view with the new dataProvider.
Upvotes: 2
Views: 3699
Reputation: 1024
Finally I found myself the solution of my problem, but it could help the next readers.
Everything is perfect in the dataprovider and the ajax submit. What i didn't know before is that, after updating the Dataprovider and calling the function renderPartial(),
$dataProvider = new ActiveDataProvider([
'query' => Jobs::find()->where(['jCategory' => $idCategorySearch])
->orderBy('jID DESC'),
'pagination' => ['pageSize' => 10,],
]);
echo $this->renderPartial( 'jobs_partial_view',
['jobCompanyCategorySearchModel' => $jobCompanyCategorySearchModel,
'jobUserSearchModel' => $jobUserSearchModel,
'dataProvider' => $dataProvider
] );
I could get the view (The new Listview) in response of Ajax using jQuery and load it in the html content of the old list view's container:
function searchJob(){
var form = $("#quick_search_form");
var search_data_job = form.serialize();
var partialviewcontainer = $("#jobs_partial_view_container");
$.ajax({
type: 'POST',
url: 'jobs',
data: search_data_job,
dataType: 'html',
success: function(newPartialView) {
partialviewcontainer.html(newPartialView);
},
});
return false;
}
I have added the fadeIn and fadeOut functions to make the Reload smooth.
From:
partialviewcontainer.html(newPartialView);
To:
$(partialviewcontainer).fadeOut(800, function(){
partialviewcontainer.html(newPartialView).fadeIn().delay(2000);
});
Hope it will help.
Thanks to people who have tried to help me too.
Upvotes: 2
Reputation: 922
You could use Pjax in your case. So your from will be like below.
<?php \yii\widgets\Pjax::begin(['clientOptions' => ['method' => 'POST']]); ?>
<?php $form = ActiveForm::begin([
'id' => 'quick_search_form',
'enableAjaxValidation'=>false,
'enableClientValidation'=>true,
'options' => ['class' => 'form-horizontal']
]); ?>
.......
.......
<!-- your form htmls will goes here -->
.......
.......
<?php \yii\widgets\ActiveForm::end(); ?>
<?= $this->render( 'jobs_partial_view', ['dataProvider'=> $dataProvider] ); ?>
<?php \yii\widgets\Pjax::end(); ?>
Note: you no need to write ajax code for form submission. Pjax will take case of all ajax stuffs. Also you have to merge your two controller actions - actionJobs
, actionJobsearch
into single action. So all actionJobsearch
coding will come inside actionJobs
.
Upvotes: 2