Yii, Update CGridView dataprovider based on AJAX result - php

I'm not sure that I am going about this the right way but here goes.
I have a dropdown list, when I change the values of this list I wish to update the dataprovider of a CGridView via Ajax.
dropDownList
<?php echo $form->dropDownList(
$model,
'assigned_to',
CHtml::listData(Users::model()->findAll(), 'id', 'username'),
array(
'empty' => 'Please Select',
'ajax' => array(
'type'=>'POST',
'url'=>Yii::app()->createUrl('CrmCalendar/Create', array('id'=>$model->model_id,'modelId'=>$model->model, 'updateGrid'=>1)),
'dataType' => 'json',
'success'=>'function(data)
{
alert(data);
$.fn.yiiGridView.update("user-activites-grid", {
data: data
});
}',
),
)
); ?>
CGridView Widget
<?php $this::widget('zii.widgets.grid.CGridView', array(
'id'=>'user-activites-grid',
'ajaxUpdate' => true,
'dataProvider'=>$model->dpUserActivities(),
));
?>
Controller Action
public function actiongetUserActivitesUpdate($id, $modelId)
{
$model=new CrmCalendar;
$model->model = $modelId;
$model->model_id = $id;
if(isset($_GET['updateGrid']))
{
$model->attributes=$_POST['CrmCalendar'];
$newDp = $model->dpUserActivities();
echo serialize($newDp);
}
}
dpUserActivities
public function dpUserActivities($size=20)
{
$date = DateTime::createFromFormat('d/m/Y H:i:s', $this->StartTime);
$date = $date->format('Y-m-d');
$dataProvider=new CActiveDataProvider($this, array(
'criteria'=>array('condition'=>'assigned_to=:assigned_to AND DATE(StartTime) = :date', 'params'=>array(':assigned_to'=>$this->assigned_to, ':date'=>$date),),
'pagination'=>array('pageSize'=>$size,),
'sort'=>array('defaultOrder'=>'Starttime ASC',),
));
return $dataProvider;
}
What I am trying to achieve is that when the drop down for assigned to is changed then the the value is stored back into the $model and the dpUserActivites is re run with the new data and then the CGridView is updated.
Sorry if this makes no sense.
Let me know if you need any more information
Regards.

Related

Yii dropdown with AJAX not working as expected

I have the following view named 'findreseller.php':
<?php
$countries = CHtml::listData(Country::model()->findAll(), 'id', 'name');
echo CHtml::dropdownlist('find_reseller', '', $countries,
array('ajax'=>array(
'type'=>'POST',
'url'=>Yii::app()->getController()->createAbsoluteUrl('/webcare/reseller/loadAjaxData'),
'update' =>'#data',
)
)
);
?>
<div id="data">
<?php $this->renderPartial('_ajaxContent', array('dataProvider'=>$dataProvider))?>
</div>
_ajaxContent just echoes the result, nothing special there...
The dropdown, as you can see is generated with CHtml because I dont't need a form. I just need an onChange event to do something...
As per the code that follows, in '/webcare/reseller/loadAjaxData' I have:
public function actionLoadAjaxData() {
$country = $_POST['find_reseller'];
//do something...
$dataProvider=new CArrayDataProvider($country_reseller);
$this->render('findreseller', array('dataProvider' => $dataProvider));
}
I can tell that I am missing something, but I am not sure what exactly.
Edit
Modified like this:
<?php
//CHtml::form();
$countries = CHtml::listData(Country::model()->findAll(), 'id', 'name');
echo CHtml::dropdownlist('find_reseller', '', $countries,
array(
'ajax' => array(
'type'=>'POST', //request type
'url'=>CController::createUrl('/webcare/reseller/loadAjaxData'), //url to call.
//Style: CController::createUrl('currentController/methodToCall')
'update'=>'#city_id', //selector to update
'data'=>'js: $(this).val()',
//leave out the data key to pass all form values through
)
)
);
//empty since it will be filled by the other dropdown
echo CHtml::dropDownList('city_id','', array());
//CHtml::endForm();
?>
<div id="data">
<?php $this->renderPartial('_ajaxContent', array('dataProvider'=>$dataProvider))?>
</div>
And now I get:
http://prntscr.com/42wwx6
And I have the following controller action:
public function actionLoadAjaxData() {
$country = $_POST['country_id'];
...
$dataProvider=new CArrayDataProvider($country_reseller);
$data = User::model()->findAll('country_id=:country_id AND reseller=:reseller',
array(':country_id'=>(int) $_POST['country_id'], ':reseller'=>1));
$data=CHtml::listData($data,'city','city');
foreach($data as $value=>$name)
{
echo CHtml::tag('option',
array('value'=>$value),CHtml::encode($name),true);
}
$this->render('action_name', array('dataProvider' => $dataProvider));
}
Edit 2
If I write a die in actionLoadAjaxData(), right at the beginning, the method is loaded fine, the action is ok and the server answers 200.

Problems with a form in SocialEngine/Zend

I have created a module in SocialEngine(*which is built on Zend framework v1.9) that contains an admin form with a few options.
The problem I have with it is that it seems to no get the values of the fields from database after I refresh the page and it shows me the default values.
It shows the correct values immediately after I save(*but I am not sure if the page is refreshed after saving), but not after I refresh.
controller /application/modules/Mymodule/controllers/AdminSomesettingsController.php :
class Mymodule_AdminSomesettingsController extends Core_Controller_Action_Admin
{
public function indexAction()
{
$this->view->form = $form = new Mymodule_Form_Admin_Someform();
$settings = Engine_Api::_()->getApi('settings', 'core');
if(!$form->isValid($settings->mymodule))
{ return $form->populate($settings->mymodule); }
if( !$this->getRequest()->isPost() ) { return; }
if( !$form->isValid($this->getRequest()->getPost()) ) { return; }
$db = Engine_Api::_()->getDbTable('settings','core')->getAdapter();
$db->beginTransaction();
try {
$values = $form->getValues();
$settings->mymodule = $values;
$db->commit();
} catch( Exception $e ) {
$db->rollback();
throw $e;
}
$form->saveValues();
$form->addNotice('Your changes have been saved.');
}
}
form /application/modules/Mymodule/Form/Admin/Someform.php :
class Mymodule_Form_Admin_Someform extends Engine_Form
{
public function init()
{
$this
->setTitle('My Settings')
->setDescription('Settings');
$this->addElement('Radio', 'some_setting', array(
'label' => 'Some Setting',
'description' => '',
'multiOptions' => array(
0 => 'Option One',
1 => 'Option Two',
2 => 'Option Three',
),
'value' => 1,
'escape' => false,
));
// Add submit button
$this->addElement('Button', 'submit', array(
'label' => 'Save Changes',
'type' => 'submit',
'ignore' => true
));
}
public function saveValues()
{
}
}
I have checked with other plugins and it seems to me that $form->populate($settings->mymodule); repopulates the form after refresh, but it does not work for me.
Any idea how I could make it show the values from the database(*when these values exist) instead of the default values?
I myself am new to socialengine and zend.My understanding of socialengine says, make a function saveValues() inside ur form class, then call it from controller action as $form->saveValues(),passing parameter as needed.This is the convention that socialengine seems to follow, and inside the saveValues() of form class,u can save valus as needed.Ur form shud be populated only if validation fails
(!$form->isValid($formData ))
{ return $form->populate($formData); }
Instead of default adapter,U should try this-
$db =Engine_Api::_()->getDbTable('settings','core')->getAdapter(),
$db->beginTransaction();
If u want to set the value of a particular field try - $form->populate(array('formField'=>'urValue')); in ur case maybe -
$val=$settings->mymodule,
$form->populate('formField'=>$val);
You can add the code in controller $form->some_setting->setValue('1');

How to customize dataProvider using CListView in Yii

I'm trying to output data into the CListView of the current user only. So far, if I put in the $dataProvider, it only outputs ALL the records from the database.
This is my current code:
$current = Yii::app()->user->id;
$currentid = Yii::app()->db->createCommand("select * from content where id = ". $current)->queryRow();
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider, //This is the original. I tried replacing it
//with $currentid but errors.
'itemView'=>'_view2',
'template'=>'{items}<div>{pager}</div>',
'ajaxUpdate'=>false,
));
From what I understand from the Yii Documentations, $dataProvider stores all the data within the database and places it inside the dataProvider itself and my "_view2" uses that to output all the records.
My Controller codes for the showing/view is as follows:
public function actionView()
{
$post=$this->loadModel();
if(Persons::model()->compare_country(explode("|",$post->country)))
{
$post->view_count = $post->view_count + 1;
Yii::app()->db->createCommand("UPDATE content SET view_count = {$post->view_count} WHERE id = {$post->id}")->execute();
//$post->save();
$comment=$this->newComment($post, 'view');
if (!empty(Yii::app()->session['announcement_message']))
{
Yii::app()->user->setFlash('message',Yii::app()->session['announcement_message']);
Yii::app()->session['announcement_message'] = null;
}
$this->render('view',array(
'model'=>$post,
'comment'=>$comment,
'view'=>'view',
));
}
else
{
$this->redirect(Yii::app()->createAbsoluteUrl('news/index',array('page'=>'1')));
}
}
public function actionShow($id)
{
$post=$this->loadModel($id);
$comment=$this->newComment($post);
$attachments=Attachments::model()->findAllByAttributes(array(
'content_id' => $id,
));
$this->render('show',array(
'model'=>$post,
'comment'=>$comment,
'attachments'=>$attachments
));
}
If you wanted to see my _view2, these are my codes:
<div class="profile-member-post-box announcement" >
<div class="events-post-bodytext profile-member-info">
<?php $person=Persons::model()->findByAttributes(array('party_id'=>$data->party_id));
if ($person->party_id === Yii::app()->user->id)
{
?>
<span><?=CHtml::link($data->title, array('view', 'id'=>$data->id), array('class' => 'titlelink'));?></span>
<?php
$country=Lookup_codes::model()->findByAttributes(array('id'=>$person->country));
$location = empty($country) ? '' : 'of '.$country->name;
$sysUser=User::model()->findByAttributes(array('party_id'=>$data->party_id));
?>
<p>
By: <?php echo CHtml::link($person->getusername(), array('persons/view/id/'.$person->showViewLinkId())); ?>
<span class="date2"> - <?php echo date('M j, Y',strtotime($data->date_created)); ?></span>
</p>
<div>
<?php if(Yii::app()->partyroles->isAdmin() || ((get_access('Announcement','edit') && (Yii::app()->user->id == $data->party_id)) || (get_local_access('sub-admin','edit',$data->id)))):?>
Edit | <?php endif;?> <?php echo (Yii::app()->partyroles->isAdmin() || (get_access('Announcement','delete') && (Yii::app()->user->id == $data->party_id)) || (get_local_access('sub-admin','delete',$data->id))) ? CHtml::link('Delete','#',array('submit'=>array('delete','id'=>$data["id"]),'confirm'=>'Are you sure you want to delete this item?')) : NULL?>
</div>
<?php
}
else
?>
</div>
I just need to be able to fix the view to show records only by the current user.
UPDATE!!------------
I'm going to add my actionIndex here:
public function actionIndex()
{
if(get_access('Announcement','view') || get_access('Announcement','view_local'))
{
$id = Yii::app()->user->id;
$condition = Persons::model()->get_view_condition('Announcement');
$criteria=new CDbCriteria(array(
'condition'=>'1=1 '.$condition,
'order'=>'date_modified DESC',
'with'=>'commentCount',
));
/*
if(isset($_GET['tag']))
$criteria->addSearchCondition('tags',$_GET['tag']);
*/
$items=SystemParameters::model()->findAllByAttributes(array(
'name' => 'blogs_per_page',
));
$dataProvider=new CActiveDataProvider('Announcement', array(
'pagination'=>array(
'pageSize'=>strip_tags($items[0]->value),
),
'criteria'=>$criteria,
));
/* $dataProvider=new CActiveDataProvider('Announcement', array(
'pagination'=>array(
'pageSize'=>5,
),
'criteria'=>$criteria,
));*/
//$dataProvider=Announcement::model()->findAll();
$attachments=Attachments::model()->findAllByAttributes(array(
'content_id' => $id,
));
if (!empty(Yii::app()->session['announcement_message']))
{
Yii::app()->user->setFlash('message',Yii::app()->session['announcement_message']);
Yii::app()->session['announcement_message'] = null;
}
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
}
else
{
$this->redirect(Yii::app()->createAbsoluteUrl('news/index',array('page'=>'1')));
}
}
Your question is very hard to follow... but I'll attempt to answer by giving an example of how to use the CDataProvider and CListView to display all of the Announcements owned by the current logged in User. This assumes the Announcement model's table has a user_id field which contains the id of the User who owns or created it.
First, in your indexAction() in your controller:
// get the logged in user's ID
$userId = Yii::app()->user->id;
// now define the dataprovider, which will do the SQL query for you
$dataProvider = new CActiveDataProvider( // declare a new dataprovider
'Announcement', // declare the type of Model you want to query and display
array( // here we build the SQL 'where' clause
'criteria' => array( // this is just building a CDbCriteria object
'condition' => 'user_id=:id', // look for content with the user_id we pass in
'params' => array(':id' => $userId), // pass in (bind) user's id to the query
//'order'=>'date_modified DESC', // add your sort order if you want?
//'with'=>'commentCount', // join in your commentCount table?
)
)
);
$this->render('index',array( // render the Index view
'dataProvider'=>$dataProvider, // pass in the data provider
));
Then in your index.php view:
// create the CListView and pass in the $dataProvider we created above, in the indexAction
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider, // this is the data provider we just created
'itemView'=>'_view2',
'template'=>'{items}<div>{pager}</div>',
'ajaxUpdate'=>false,
));

Yii dropdownlist using $form-> dropdownlist

i want to create a form from 2 different models,
1st is for countries, and the 2nd is for documents.
The problem is that i can't make a dropdown list, i get the errors all the time.
Here's the code, first my controller.php part
$model = new Country;
$model2 = new Product;
$this->performAjaxValidation(array($model, $model2));
if(isset($_POST['Country'],$_POST['Product']))
{
// populate input data to $model and $model2
$model->attributes=$_POST['Country'];
$model2->attributes=$_POST['Product'];
// validate BOTH $model and $model2
$valid=$model->validate();
$valid=$model2->validate() && $valid;
if($valid)
{
// use false parameter to disable validation
$model->save(false);
$model2->save(false);
$this->redirect('index');
}
}
...
$countriesIssued = Country::model()->findAll(array('select'=>'code, name', 'order'=>'name'));
...
$this->render('legalisation', array('model'=>$model, 'model2'=>$model2, 'documents'=>$documents, 'countriesIssued'=>$countriesIssued, 'countries'=>$countries, 'flag'=>$flag));
}
In my view script I use this code
<?php $form = $this->beginWidget('CActiveForm', array(
'id'=>'user-form',
'enableAjaxValidation'=>true,
)); ?>
<?php echo $form->errorSummary(array($model,$model2)); ?>
<?php echo $form->dropDownList($model, 'countriesIssued',
CHtml::listData($countriesIssued, 'code', 'name'));?>
<?php $this->endWidget(); ?>
but i get this error :
Property "Country.countriesIssued" is not defined.
Ok it's not defined, i try to change it to 'countriesIssued', then i got another error saying Invalid argument supplied for foreach() .
If anybody can help me please.
I know there is more solutions on net, i try it but not understand, Thanks.
By definition, the first param of listData is an array; Your is a object;
<?php
echo $form->dropDownList($model, 'classification_levels_id', CHtml::listData(ClassificationLevels::model()->findAll(), 'id', 'name'),$classification_levels_options);
?>
Make a list variable like this:
In your Model:
$countriesIssued = Country::model()->findAll(array('select'=>'code, name', 'order'=>'name'));
And in your view:
$list = CHtml::listData($countriesIssued, 'code', 'name'));
echo CHtml::dropDownList('Your variable', Your $model,
$list,
array('empty' => '(Select a category'));
dropDownList($model,'state',array('1' => 'Do 1', '2' => 'Do 2'),array('selected' => 'Choose')); ?>
Or Yii 2
field($model,'state')->dropDownList(
array('1' => 'Do 1','0' => 'Do 2'),array('options' => array('0' => array('selected' => true))))
->label('State')
?>

yii : how to ajax update the cgridview

Q : How to ajax update the CgridVeiw?
Status : I've done with cookie. but there are a problem. it is when the page upload, the date are always show in from-date and to-date text box. and When reload the page, it doesn't clear out.
This is my view
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'page-form',
'enableAjaxValidation'=>true,
)); ?>
<div style="margin-top:30px;">
<b>From :</b>
<?php
$this->widget('zii.widgets.jui.CJuiDatePicker', array(
'name'=>'from_date', // name of post parameter
//'value'=>Yii::app()->request->cookies['from_date']->value, // value comes from cookie after submittion
'options'=>array(
'showAnim'=>'fold',
'dateFormat'=>'yy-mm-dd',
),
'htmlOptions'=>array(
'style'=>'height:20px;'
),
));
?>
<span> </span>
<b>To :</b>
<?php
$this->widget('zii.widgets.jui.CJuiDatePicker', array(
'name'=>'to_date',
//'value'=>Yii::app()->request->cookies['to_date']->value,
'options'=>array(
'showAnim'=>'fold',
'dateFormat'=>'yy-mm-dd',
),
'htmlOptions'=>array(
'style'=>'height:20px;'
),
));
?>
<span> </span>
<?php echo CHtml::submitButton('Go'); ?>
<?php
echo CHtml::ajaxSubmitButton('Search', CHtml::normalizeUrl(array('index')),
array(
'success'=>'js:'
.'function(){'
.'$.fn.yiiGridView.update("acc-payment-recei-grid", {url:"index"});'
.'}',
),
array('id'=>'go', 'name'=>'go'));
?>
<?php $this->endWidget(); ?>
<p style="float:right;">
New Payment Receive
</p>
</div>
<style>
.items table tr:last-child td:first-child {
-moz-border-radius-bottomleft:10px;
-webkit-border-bottom-left-radius:10px;
border-bottom-left-radius:10px
}
.items table tr:last-child td:last-child {
-moz-border-radius-bottomright:10px;
-webkit-border-bottom-right-radius:10px;
border-bottom-right-radius:10px
}
</style>
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'acc-payment-recei-grid',
'dataProvider'=>$accpaymentrecei->search(),
//'filter'=>$accpaymentrecei,
'columns'=>array(
//'id',
array('name' => 'acc_category_id',
'value'=>'(isset($data->acccategories->name)) ? CHtml::encode($data->acccategories->name) :""',
),
array('name' => 'acc_recei_id',
'header'=> 'Account Received',
//'value'=>'(isset($data->method)) ? CHtml::encode($data->method) :""',
),
array(
'name' => 'date',
'value'=>'($data->date= 0) ? "" : date("d M yy",strtotime($data->date))',
),
array('name' => 'method',
'value'=>'(isset($data->method)) ? CHtml::encode($data->method) :""',
),
array('name' => 'description',
//'value'=>'(isset($data->method)) ? CHtml::encode($data->method) :""',
),
/*
'created_date',
'updated_date',
'file_name',
*/
array(
'class'=>'CButtonColumn',
),
),
));
This is controller
public function actionIndex()
{
$accpaymentrecei=new AccPaymentRecei('search');
$accpaymentrecei->unsetAttributes(); // clear any default values
if(isset($_GET['AccPaymentRecei']))
$accpaymentrecei->attributes=$_GET['AccPaymentRecei'];
$acccategory = AccCategory::model()->findAll();
$arr_method = array('Cash'=>'Cash', 'Cheque'=>'Cheque', 'Credit Card'=>'Credit Card', 'Bank Transfer'=>'Bank Transfer');
$this->from_to_date($accpaymentrecei);
//exit();
$this->render('index',array(
'accpaymentrecei'=>$accpaymentrecei,
'acccategory'=>$acccategory,
'arr_method'=>$arr_method,
));
}
protected function from_to_date($model)
{
unset(Yii::app()->request->cookies['from_date']); // first unset cookie for dates
unset(Yii::app()->request->cookies['to_date']);
//$model=new XyzModel('search'); // your model
$model->unsetAttributes(); // clear any default values
if(!empty($_POST))
{
Yii::app()->request->cookies['from_date'] = new CHttpCookie('from_date', $_POST['from_date']); // define cookie for from_date
Yii::app()->request->cookies['to_date'] = new CHttpCookie('to_date', $_POST['to_date']);
$model->from_date = $_POST['from_date'];
$model->to_date = $_POST['to_date'];
}else{
Yii::app()->request->cookies['from_date'] = new CHttpCookie('from_date', date("Y/m/d"));
Yii::app()->request->cookies['to_date'] = new CHttpCookie('to_date', date("Y/m/d"));
}
}
Code below - it's only example, main principles of solution. First principle: we don't need refresh page (by the submit), we need only refresh CGridView after request.
The solution has a few parts:
We need form with some parameters. In your case - fromDate and toDate. You have this one already. But we don't need any submit element. At all! We will use AJAX.
We need some function for initiate AJAX-request. For example, let's event for this request will be change of parameters *from_date* or *to_date*. This function also must update CGridView after request.
We need action in controller for processing AJAX-request.
Let's begin from part 2. It may be some like this:
Yii::app()->clientScript->registerScript('scriptId',
"var ajaxUpdateTimeout;
var ajaxRequest;
$('**selector_for_parameters_fields**').change(function(){
ajaxRequest = $(this).serialize();
clearTimeout(ajaxUpdateTimeout);
ajaxUpdateTimeout = setTimeout(function () {
$.fn.yiiGridView.update(
// this is the id of the CGridView
'acc-payment-recei-grid',
{data: ajaxRequest}
)
},
// this is the delay
300);
});"
);
Place this code into view. Notes:
$(this).serialize() - key moment. Look for more info
selector_for_parameters_fields - give them ( fromDate and toDate ) some unique
selector
We use some delay (300 ms) for decreasing loading from unnecessary AJAX-requests
Now - about action in Controller
public function actionIndex($fromDate='', $toDate='')
{
$criteria = new CDbCriteria();
if(!empty($fromDate))
$criteria->addSearchCondition('your search condition about fromDate');
if(!empty($toDate))
$criteria->addSearchCondition('your search condition about toDate');
$dataProvider=new CActiveDataProvider('YourModel',
array('criteria' => $criteria,));
$this->render('YourView',array('dataProvider'=>$dataProvider,));
}
It must works, but requires some tuning for concrete conditions.

Categories