Good morning again!
Well, after I following this example Example, I got almost what I want.
But the AJAX code fail.
When I click in gridview A, I get an error: “Request failed: error.” and I don’t know why. Therefore, the B gridview doesn’t refresh.
Here my code:
views/Books/admin.php
<?php
/* @var $this BooksController */
/* @var $model Books */
$this->breadcrumbs=array(
'Books'=>array('index'),
'Manage',
);
$this->menu=array(
array('label'=>'List', 'url'=>array('index')),
array('label'=>'New', 'url'=>array('create')),
);
Yii::app()->clientScript->registerScript('search', "
$('.search-button').click(function(){
$('.search-form').toggle();
return false;
});
$('.search-form form').submit(function(){
$.fn.yiiGridView.update('books-grid', {
data: $(this).serialize()
});
return false;
});
");
?>
<h1>Manage Books</h1>
<div class="span-5 last operations_ads">
<div id="sidebar">
<?php
$this->widget('zii.widgets.CMenu', array(
'items'=>$this->menu,
'htmlOptions'=>array('class'=>'operations'),
));
?>
</div><!-- sidebar -->
</div>
<?php
echo CHtml::link('Advanced Search','#',array('class'=>'search-button'));
?>
<div class="search-form" style="display:none">
<?php
$this->renderPartial('_search',array('modelBooks'=>$modelBooks,));
?>
</div><!-- search-form -->
<div id="parentView">
<?php
$this->widget('application.components.GridView', array(
'id'=>'books-grid',
'dataProvider'=>$modelBooks->search(),
'filter'=>$modelBooks,
'columns'=>array(
'IdBook',
'Book',
array('class'=>'CButtonColumn',),
),
'ajaxUpdate' => 'child-grid',
));
?>
</div>
<!-- Use this paragraph to display the loading.gif icon above the Child Gridview,
while waiting for the ajax response -->
<p id="loadingPic"></br></p>
<!-- The childView <div>, renders the _child form, which contains the Child Gridview.
The ajax response will replace/update the whole <div> and not just the gridview. -->
<div id="childView">
<?php
$this->renderPartial('_child', array(
'modelAuthorsBooks' => $modelAuthorsBooks, /* New */
'IdBook' => $IdBook, /* New */
))
?>
</div>
<?php
/*Load the javascript file that contains the ajax function*/
$path = Yii::app()->baseUrl.'/js/customFunctions.js';
Yii::app()->clientScript->registerScriptFile($path, CClientScript::POS_END);
?>
views/Books/_child.php
<p id="subsectionheading">Related Authors</p>
<div class="hint">(Please note: If no Book is selected, the Authors of the top-most Book are displayed.)</div>
<?php
$this->widget('application.components.GridView', array(
'id'=>'child-grid',
'dataProvider'=>$modelAuthorsBooks->searchIncludingAuthors($IdBook),
'filter'=>$modelAuthorsBooks,
'columns'=>array(
array(
'name'=>'AuthorName',
'value'=>'($data->FK_AB_Authors)?$data->
FK_AB_Authors->AuthorName:""',
/* Test for empty related fields not to crash the
* program */
'header'=>'Author Name',
'filter' => CHtml::activeTextField($modelAuthorsBooks,'AuthorName'),
),
array(
'class'=>'CButtonColumn',
'template'=>'{view}{update}{delete}',
'viewButtonUrl' => 'array("Authors/view",
"id"=>$data->IdAuthor)',
'updateButtonUrl' => 'array("Authors/update",
"id"=>$data->IdAuthor)',
'deleteButtonUrl' => 'array("Authors/delete",
"id"=>$data->IdAuthor)',
),
),
));
?>
controllers/BooksController.php
public function actionAdmin()
{
$modelBooks=new Books('search');
$modelBooks->unsetAttributes();
if(isset($_GET['Books']))
$modelBooks->attributes=$_GET['Books'];
if(!isset($_GET['IdBook']))
{
$group = "A";
$criteria=new CDbCriteria;
$criteria->compare('IdBook',$modelBooks->IdBook,true);
$criteria->compare('BookName',$modelBooks->BookName,true);
$dataProvider = new CActiveDataProvider('Books',
array(
'criteria'=>$criteria,
));
/* Test if the dataProvider found any data (filtering
parameters might have excluded all records)*/
If (count($dataProvider->getData()) > 0)
{
/* Extract the first model from the dataprovider */
$first_model=$dataProvider->getData();
/* Extract the record's PK, to be used to generate
the child-gridview's data records.*/
$IdBook= $first_model[0]->IdMedicamento;
}
else
{
/* Set $IdBook to 0, to return an empty child-
grid.*/
$IdBook= 0;
}
}
else
{
/* The event using this action, is from Group B: */
$group = "B";
/* Get the IdBook, which the event passed to this
action.*/
$IdBook= $_GET['IdBook'];
}
$modelAuthorsBooks = new AuthorsBooks("searchIncludingAuthors($IdBook)");
$modelAuthorsBooks ->unsetAttributes();
$modelAuthorsBooks ->scenario = 'searchIncludingAuthors';
if(isset($_GET['AuthorsBooks']))
$modelAuthorsBooks ->attributes=$_GET['AuthorsBooks'];
if($group == "A"){
$this->render('admin',array(
'modelBooks'=>$modelBooks,
'modelAuthorsBooks '=>$modelAuthorsBooks ,
'IdBook' => $IdBook,
));
}
else{
$this->renderPartial('_child', array(
'modelAuthorsBooks '=>$modelAuthorsBooks ,
'IdBook' => $IdBook,
));
}
}
AuthorsBooks model
public $AuthorName;
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('IdAuthor, IdBook', 'required'),
array('IdAuthor, IdBook', 'numerical', 'integerOnly'=>true),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('AuthorName, IdBook', 'safe', 'on'=>'search,
searchIncludingAuthors'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'FK_AB_Books' => array(self::BELONGS_TO, 'Books', 'IdBook'),
'FK_AB_Authors' => array(self::BELONGS_TO, 'Authors',
'IdAuthor'),
);
}
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('IdAuthor',$this->IdAuthor);
$criteria->compare('IdBook',$this->IdBook);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
public function searchIncludingAuthors($IdBook)
{
/* This function creates a dataprovider with RolePermission
models, based on the parameters received from the controller. It
also includes related Permission models, obtained via the
relPermission relation. */
$criteria=new CDbCriteria;
$criteria->with=array('FK_AB_Authors');
$criteria->together = true;
/* filter on books-grid PK ($IdBook) received from the
controller*/
$criteria->compare('t.IdBook',$IdBook,false);
/* Filter on default Model's column if user entered parameter*/
$criteria->compare('t.IdAuthor',$this->IdAuthor,true);
/* Filter on related Model's column if user entered parameter*/
$criteria->compare('FK_AB_Authors.AuthorName',
$this->AuthorName,true);
/* Sort on related Model's columns */
$sort = new CSort;
$sort->attributes = array(
'AuthorName' => array(
'asc' => 'AuthorName',
'desc' => 'AuthorName DESC',
), '*', /* Treat all other columns normally */
);
/* End: Sort on related Model's columns */
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'sort'=>$sort, /* Needed for sort */
));
}
AJAX–customFunctions.js
$('#parentView').on("click", "table tbody td:not(td:.button-column)", function(event){
try{
/*Extract the Primary Key from the CGridView's clicked row.
"this" is the CGridView's clicked column or <td>.
Go up one parent - which gives you the row.
Go down to child(1) - which gives you the first column,
containing the row's PK. */
var gridRowPK = $(this).parent().children(':nth-child(1)').text();
/*Display the loading.gif file via jquery and CSS*/
$("#loadingPic").addClass("loadGIF");
/* Call the Ajax function to update the Child CGridView via the
controller’s actionAdmin */
var request = $.ajax({
url: "Admin",
type: "GET",
cache: false,
data: {IdMedicamento : gridRowPK},
dataType: "html"
});
request.done(function(response) {
try{
/*since you are updating innerHTML, make sure the
received data does not contain any javascript -
for security reasons*/
if (response.indexOf('<script') == -1)
{
/*update the view with the data received
from the server*/
document.getElementById('childView').innerHTML = response;
}
else
{
throw new Error('Invalid Javascript in Response - possible hacking!');
}
}
catch (ex){
alert(ex.message); /*** Send this to the server
for logging when in production ***/
}
finally{
/*Remove the loading.gif file via jquery and CSS*/
$("#loadingPic").removeClass("loadGIF");
/*clear the ajax object after use*/
request = null;
};
});
request.fail(function(jqXHR, textStatus) {
try{
throw new Error('Request failed: ' + textStatus );
}
catch (ex){
alert(ex.message); /*** Send this to the server
for logging when in production ***/
}
finally{
/*Remove the loading.gif file via jquery and CSS*/
$("#loadingPic").removeClass("loadGIF");
/*clear the ajax object after use*/
request = null;
}
});
}
catch (ex){
alert(ex.message); /*** Send this to the server for logging when
in production ***/
}
});
AJAX fails in line
request.done(function(response) {
It’s what I need to get it!!. I need ideas!
Thanks.