Yii Framework Forum: [EXTENSION] JToggleColumn - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

[EXTENSION] JToggleColumn CGridView column which toggles the boolean value of model attribute Rate Topic: -----

#1 User is offline   johonunu 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 18
  • Joined: 26-November 10

Posted 25 March 2012 - 06:41 AM

Column for CGridView which toggles the boolean ( TINYINT(1) ) value of model attribute. Tested with Yii 1.10.

www.yiiframework.com/extension/jtogglecolumn

Posted Image

Download: http://www.yiiframew...ogglecolumn.zip

Usage

Extract downloaded zip to your components or extensions directory.

If you extracted to extensions directory add this line to import array in your /config/main.php :

<?php

'import'=>array(
    ...
    'application.extensions.jtogglecolumn.*', 
)

?>


Define a JToggleColumn in your CGrid widget:

<?php $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'user-grid',
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'columns'=>array(
            'id',
            'username',
            'password',
            'email',
            'role',
            array(
                    'class'=>'JToggleColumn',
                    'name'=>'is_active', // boolean model attribute (tinyint(1) with values 0 or 1)
                    'filter' => array('0' => 'No', '1' => 'Yes'), // filter
                    'htmlOptions'=>array('style'=>'text-align:center;min-width:60px;')
            ),
            array(
                    'class'=>'JToggleColumn',
                    'name'=>'visible', // boolean model attribute (tinyint(1) with values 0 or 1)
                    'filter' => array('0' => 'No', '1' => 'Yes'), // filter
                    'checkedButtonImageUrl'=>'/auth/images/check.png', // checked image
                    'uncheckedButtonImageUrl'=>'/auth/images/uncheck.png', // unchecked image
                    'checkedButtonLabel'=>'Uncheck this', // tooltip
                    'uncheckedButtonLabel'=>'Check this', // tooltip
                    'htmlOptions'=>array('style'=>'text-align:center;min-width:60px;')
    ),
    array(
        'class'=>'CButtonColumn',
    ),
),
)); ?>


Create action in your controller:

public function actionToggle($id,$attribute)
{
    if(Yii::app()->request->isPostRequest)
    {
        // we only allow deletion via POST request
        $model = $this->loadModel($id);
        $model->$attribute = !$model->$attribute;
        $model->save();

        // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
        if(!isset($_GET['ajax']))
            $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
        }
        else
        throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
    }

?>


Don't forget to add this action to controllers accessRules.

This is my first extension.

All suggestions are welcome!

GIT Repository
http://bitbucket.org...u/jtogglecolumn
0

#2 User is offline   migueArgentina 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 133
  • Joined: 09-March 11

Posted 30 March 2012 - 06:44 PM

Man, this is incredibly useful for my project, but i can't make it work.
I've done everything you said but i'm getting the message in the picture.
What am i doing wrong?

Attached File(s)

  • Attached File  cap.png (28.27K)
    Number of downloads: 27

0

#3 User is offline   Hypfvieh 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 25-April 12

Posted 25 April 2012 - 03:18 AM

Yeah I also find this extension very useful for my current project.

Sadly it doesnt work with CArrayDataProvider as it always tries to read $data->primaryKey which is not available in CArrayDataProvider.

I'm pretty new to Yii and OOP in PHP in general, but I tried to fix this issue.
I also changed the way the column-data is provided.
In my case I needed to know the row-id (provided with $data[$this->grid->dataProvider->keyField]) and the column-id (using $data[$this->name]).
It may be a better solution to use another property than "name" for this... :)

Maybe someone else can use it or contribute a better solution...

In Main Class after :
 private $_assetsUrl;


Add:

 private $_isArrayData = false;


Add this to "public function init()" (this after the if-statements,before $this->initDefaultButtons)
        if (get_class($this->grid->dataProvider) === 'CArrayDataProvider')
            $this->_isArrayData = true;


In "protected function initDefaultButtons()", replace:
            $this->toggle_button = array(
                'url' => 'Yii::app()->controller->createUrl("toggle",array("id"=>$data->primaryKey,"attribute"=>"' . $this->name . '"))',
                'options' => array('class' => $this->name . '_toggle'),
            );



with:

        if ($this->_isArrayData) {
            $this->toggle_button = array(
                'url' => 'Yii::app()->controller->createUrl("toggle",array("id"=>$data[$this->grid->dataProvider->keyField],"attribute"=>$data[$this->name]))',
                'options' => array('class' => $this->name . '_toggle'),
            );
        }
        else {
            $this->toggle_button = array(
                'url' => 'Yii::app()->controller->createUrl("toggle",array("id"=>$data->primaryKey,"attribute"=>"' . $this->name . '"))',
                'options' => array('class' => $this->name . '_toggle'),
            );

        }

0

#4 User is offline   ReekrScream 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 24
  • Joined: 06-May 12

Posted 03 July 2012 - 01:39 PM

Hello everyone,

I am very happy I found this extension and I am using it in my project.

Unfortunately, I am having a very strange error. The extension does not work on table rows that have a datetime set to default "0000-00-00". This is my schema:

-------------------------------------------------------------------------------------------------
| content_id | index_id | active | name | content_url 	| description      | release_date | ...
-------------------------------------------------------------------------------------------------
| 1      	| 1    	| 0  	| KTK  | NULL        	| KTK Description  | 0000-00-00   | ...
| 2      	| 2    	| 0  	| VTV  | NULL        	| VTV Description  | 0000-00-00   | ...
| 3      	| 3    	| 0  	| RTP  | NULL        	| RTP Description  | 2012-06-15   | ...


When I click the toggle icon on the CGridView for row #1 or #2, it does not work. When I click the toggle icon for #3, it works fine. If I add a date into #1's "release_date" then toggling #1 works fine.

Can someone help me figure this out please? I am using Yii 1.1.10

Thank you very much!

EDIT:
Found the solution, in fact it was in the Extension page of Yii Wiki. The solution is to open up ToggleAction.php (or the SwitchAction.php) file and change:
$model->save();


to:
$model->save(false);


Hope this helps the next guy. Thank you for a great extension :)

This post has been edited by ReekrScream: 03 July 2012 - 02:22 PM

0

#5 User is offline   johonunu 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 18
  • Joined: 26-November 10

Posted 07 July 2012 - 11:23 AM

View PostReekrScream, on 03 July 2012 - 01:39 PM, said:

Hello everyone,

I am very happy I found this extension and I am using it in my project.

Unfortunately, I am having a very strange error. The extension does not work on table rows that have a datetime set to default "0000-00-00". This is my schema:

-------------------------------------------------------------------------------------------------
| content_id | index_id | active | name | content_url 	| description      | release_date | ...
-------------------------------------------------------------------------------------------------
| 1      	| 1    	| 0  	| KTK  | NULL        	| KTK Description  | 0000-00-00   | ...
| 2      	| 2    	| 0  	| VTV  | NULL        	| VTV Description  | 0000-00-00   | ...
| 3      	| 3    	| 0  	| RTP  | NULL        	| RTP Description  | 2012-06-15   | ...


When I click the toggle icon on the CGridView for row #1 or #2, it does not work. When I click the toggle icon for #3, it works fine. If I add a date into #1's "release_date" then toggling #1 works fine.

Can someone help me figure this out please? I am using Yii 1.1.10

Thank you very much!

EDIT:
Found the solution, in fact it was in the Extension page of Yii Wiki. The solution is to open up ToggleAction.php (or the SwitchAction.php) file and change:
$model->save();


to:
$model->save(false);


Hope this helps the next guy. Thank you for a great extension :)


I'm glad you found solution. I will correct it as soon as I have some time ;)
0

#6 User is offline   ReekrScream 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 24
  • Joined: 06-May 12

Posted 07 July 2012 - 06:57 PM

@johonunu:

I am having trouble achieving something with JToggleColumn. I would like that on every toggle, the action to be logged to a specified Log table in the database.

For example, I have 2 models: Contents and ContentsLog. I already have it working so that each time a record (in Contents model) is created/updated/deleted, the ContentsLog model is written a row. So, if a Contents record is created, a new row in ContentsLog is created at actionCreate() that reads something like "Content (XYZ) was created at 12:10 PM on July 7, 2012" (it's divided into columns but I'm keeping it simple for sake of example).

I am still searching the right spot in JToggleColumn code where I could add this logging capability. I will report if I figure it out before you post :)

But please if you have any tips, let me know.

I appreciate the great plugin!


[EDIT]:
Wow! Figured it out! I cannot be the only Yii user who posts a question on the forum and then finds the answer a couple hours after. This feels so good. I guess it's the power of Yii and developers like @johonunu. Anyway, on to my solution:


In the Contents controller, I added the following "logger" function:
public function dataLogger($logData)
{
  	$contentsLog=new ContentsLog;
  	$contentsLog->content_id = $logData["content_id"];
  	$contentsLog->user_id = $logData["user_id"];
  	$contentsLog->description = $logData["description"];

  	$contentsLog->validate(); // Validate the data against the ContentsLog model
  	if ( !$contentsLog->save() ) {
  	  	return false;
  	}else{
  	  	return true;
  	}
}


Then in the ToggleAction.php file, I modified the code to look like this:
public function run($id,$attribute) {
   	$logContent = array(); // This must be declared at the start of function
   	if(Yii::app()->request->isPostRequest)
   	{
   	   	// we only allow deletion via POST request
   	   	$model = $this->controller->loadModel($id);
   	   	$model->$attribute = ($model->$attribute==0)?1:0;

   	   	$logContent["actOrDeact"] = ($model->$attribute==0)?"deactivated":"activated";

   	   	if ( $model->save(false) )
   	   	{
   	   	   	# Compile log message
   	   	   	$logContent['content_id']=$model->content_id;
   	   	   	$logContent['user_id']=1; // Hard-coding user for now until I setup user management
   	   	   	$logContent['description']= 'Content "'.$model->name.
           	   	   	   	   	  	'" (#'.$model->content_id.
           	   	   	   	   	  	') was '.$logContent["actOrDeact"].
           	   	   	   	   	  	' by user "1" (#'.$logContent["user_id"].')';

   	   	   	if ( $this->controller->dataLogger($logContent) )
   	   	   	{
   	   	   	   	echo "DATA LOGGED FINE!!!"; // Just my quasi-debugging here, you can ignore this
   	   	   	}else{
   	   	   	   	echo "DATA NOT LOGGED FOR SOME REASON!!"; // Quasi-debugging here
   	   	   	}

   	   	   	// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
   	   	   	if(!isset($_GET['ajax']))
   	   	   	   	$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
   	}
   	else
   	   	throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
}


I hope this helps someone who needs to include logging into the great JToggleColumn extension. As always, if more experienced developers have a better way to do this, please share your tips as I would love to make the code faster/shorter.

Happy coding!
0

#7 User is offline   johonunu 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 18
  • Joined: 26-November 10

Posted 08 July 2012 - 05:00 AM

View PostReekrScream, on 07 July 2012 - 06:57 PM, said:

@johonunu:

I am having trouble achieving something with JToggleColumn. I would like that on every toggle, the action to be logged to a specified Log table in the database.

For example, I have 2 models: Contents and ContentsLog. I already have it working so that each time a record (in Contents model) is created/updated/deleted, the ContentsLog model is written a row. So, if a Contents record is created, a new row in ContentsLog is created at actionCreate() that reads something like "Content (XYZ) was created at 12:10 PM on July 7, 2012" (it's divided into columns but I'm keeping it simple for sake of example).

I am still searching the right spot in JToggleColumn code where I could add this logging capability. I will report if I figure it out before you post :)

But please if you have any tips, let me know.

I appreciate the great plugin!


[EDIT]:
Wow! Figured it out! I cannot be the only Yii user who posts a question on the forum and then finds the answer a couple hours after. This feels so good. I guess it's the power of Yii and developers like @johonunu. Anyway, on to my solution:


In the Contents controller, I added the following "logger" function:
public function dataLogger($logData)
{
  	$contentsLog=new ContentsLog;
  	$contentsLog->content_id = $logData["content_id"];
  	$contentsLog->user_id = $logData["user_id"];
  	$contentsLog->description = $logData["description"];

  	$contentsLog->validate(); // Validate the data against the ContentsLog model
  	if ( !$contentsLog->save() ) {
  	  	return false;
  	}else{
  	  	return true;
  	}
}


Then in the ToggleAction.php file, I modified the code to look like this:
public function run($id,$attribute) {
   	$logContent = array(); // This must be declared at the start of function
   	if(Yii::app()->request->isPostRequest)
   	{
   	   	// we only allow deletion via POST request
   	   	$model = $this->controller->loadModel($id);
   	   	$model->$attribute = ($model->$attribute==0)?1:0;

   	   	$logContent["actOrDeact"] = ($model->$attribute==0)?"deactivated":"activated";

   	   	if ( $model->save(false) )
   	   	{
   	   	   	# Compile log message
   	   	   	$logContent['content_id']=$model->content_id;
   	   	   	$logContent['user_id']=1; // Hard-coding user for now until I setup user management
   	   	   	$logContent['description']= 'Content "'.$model->name.
           	   	   	   	   	  	'" (#'.$model->content_id.
           	   	   	   	   	  	') was '.$logContent["actOrDeact"].
           	   	   	   	   	  	' by user "1" (#'.$logContent["user_id"].')';

   	   	   	if ( $this->controller->dataLogger($logContent) )
   	   	   	{
   	   	   	   	echo "DATA LOGGED FINE!!!"; // Just my quasi-debugging here, you can ignore this
   	   	   	}else{
   	   	   	   	echo "DATA NOT LOGGED FOR SOME REASON!!"; // Quasi-debugging here
   	   	   	}

   	   	   	// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
   	   	   	if(!isset($_GET['ajax']))
   	   	   	   	$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
   	}
   	else
   	   	throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
}


I hope this helps someone who needs to include logging into the great JToggleColumn extension. As always, if more experienced developers have a better way to do this, please share your tips as I would love to make the code faster/shorter.

Happy coding!


Great! Nice to see some code examples for others to see. I am glad you like my extension ;)
0

#8 User is offline   digimanpk 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 5
  • Joined: 26-July 12

Posted 26 July 2012 - 08:44 AM

Hi,

I am using this extension in Yii's datagrid. However, whenever i toggle between column statuses, pagination and search criteria are reset and i am taken to page 1 again with clear filters. Can you please help me with that.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users