Make any containers collapsible (fieldset,portlet,div,ul ...). The lightweight extension uses the jQuery function 'slideToggle' to collapse/expand the containers. An arrow will be added to the title of the container by default, but you can switch off this feature.
Note:
- If you update to v1.1.2 don't forget to delete the published assets.
Requirements ¶
Should work with Yii 1.1 or above
Usage ¶
- extract the files under .../protected/extensions
In the Yii blog demo add this code at the top of views/post/index.php
<?php
$this->widget('ext.slidetoggle.ESlidetoggle',
array(
'itemSelector' => 'div.post',
'titleSelector' => 'div.post .title',
'collapsed' => 'div.post',
));
?>
All posts should appear collapsible now, collapsed by default.
Details
The properties
- itemSelector (container)
- titleSelector (title to click)
- collapsed (selector for containers collapsed by default)
have to be assigned as jQuery selector terms.
More options
- arrow: true/false
- duration: 'slow','fast' or time in ms
- easing: 'linear','swing','easeInExpo','easeInSine' ... see jQuery Easing Plugin
- cssFile: if you want to display a custom arrow. See assets/css/jquery.slidetoggle.css
Note: The title tag must be a child of the container tag.
Example view:
<?php
/**
* 1. Fieldsets
*
* Default settings of the widget.
* This will make all fieldsets in a view collapsible, expanded by default.
* An arrow will be added to the legend.
*
* Note - see HTML:
* Better to use a single div as wrapper in the fieldset for all elements,
* otherwise each child element will be toggled separately
*/
$this->widget('ext.slidetoggle.ESlidetoggle');
/**
* 2. Standard Yii portlets
* This will make all portlets in a view collapsible, expanded by default.
*/
$this->widget('ext.slidetoggle.ESlidetoggle',
array(
'itemSelector' => '.portlet',
'titleSelector' => '.portlet-decoration',
//'collapsed' => '.portlet', //uncomment to show all collapsed
'arrow' => false, //comment to show the toggle arrow
));
/**
* 3. Custom div tags
*
* Note - see HTML:
* The title must be a child of the collapsible div in the HTML code.
*
*/
$this->widget('ext.slidetoggle.ESlidetoggle',
array(
'itemSelector' => 'div.collapsible',
'titleSelector' => 'div.collapsible h3',
//only the collapsible div container with the class 'closed' is collapsed by default
'collapsed' => 'div.collapsible.closed', //a subset of the itemSelector
));
/**
* 4. Unordered lists
*
* Note - see HTML:
* Add the title as a child of the ul-tag in the HTML code.
* Every li-tag will be toggled separately.
*/
$this->widget('ext.slidetoggle.ESlidetoggle',
array(
'itemSelector' => 'ul.collapsible',
'collapsed' => 'ul.collapsible', //all collapsed
'titleSelector' => 'ul.collapsible .caption',
));
?>
<fieldset>
<legend>The first fieldset</legend>
<div>
<label>Input</label>
<input type="text"/>
<label>Radio</label>
<input type="radio"/>
</div>
</fieldset>
<fieldset>
<legend>The second fieldset</legend>
<div>
<label>Input</label>
<input type="text"/>
<label>Checbox</label>
<input type="checkbox"/>
</div>
</fieldset>
<div class="collapsible">
<h3>Title 1</h3>
<p>The first collapsible content</p>
</div>
<div class="collapsible closed">
<h3>Title 2</h3>
<p>The second collapsible content 2</p>
</div>
<ul class="collapsible">
<span class="caption" style="margin-left:-1.5em;">Collapsible caption</span>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
</ul>
Change the effect of toggle movement by setting the 'duration' and 'easing' property.
$this->widget('mongocms.extensions.slidetoggle.ESlidetoggle',
array(
'duration' => 'slow', //'fast' or time in ms between 200 and 600
'easing' => 'swing', //'linear','easeInOutSine','easeInCirc','easeInElastic' ...
));
Notes ¶
You can change the image and position of the arrow in jquery.slidetoggle.css, so you can use a [+]/[-] at the right side instead an arrow at the left. Don't forget to delete the assets folder after changing the css file.
Values for 'easing': See jQuery Easing Plugin
Change log ¶
- v1.1 Added jQuery Easing Plugin for more easing methods
- v1.1.1 Bugfix: removed comma from last options array item in jquery.slidetoggle.js; slidetoggle didn't work in IE
- v1.1.2
- Bugfix in css file: Arrow did change background color to transparent;
- Should work with Yii version < 1.1.6
changing the toggling effect (currently doubles up / down action)
Hi
thanks for your extension
how can I change the effect of the toggle movement?
easing
The 'easing' method for jQuery 'slideToggle' can be set with the property 'easing' of the widget. By default the jQuery core only supports: 'linear' and 'swing'.
For more possiblities you have to register additional scripts - for example:
or
The extension 'slidetoggle' registers none of these scripts so you have to do it manually in the view. Then more easing methods are available:
Yii::app()->clientScript->registerCoreScript('jquery.ui'); //or Yii::app()->clientScript->registerScriptFile('Path to jquery.easing.1.3.js'); //Usage for standard Yii portlets $this->widget('mongocms.extensions.slidetoggle.ESlidetoggle', array( 'itemSelector' => '.portlet', 'titleSelector' => '.portlet-decoration', 'easing' => 'easeInBounce', //possible effects see the links above ));
Hope that helps.
Easing support
Added the jQuery Easing Plugin.
See the usage above.
Problems?
One has reported problems with 'slidetoggle' and Firefox 3.6.
Please let me know if you have problems too with a specific browser.
The examples above have been tested with:
Some remarks
Hi, thanks for a great extension. Here you have some remarks and things I found:
I used your example from comment "easing (#3656)" for giving standard Yii portlets slide-functionality and found out that your extension changes style (background-color) of title of such protlet. It was light blue by default, it is now white.
Your extension won't work in Yii earlier than 1.1.6 because in line 108 of ESlidetoggle.php you're using method chaining, not available in any previous version. Consider changing this line into standard method-by-method call and you can easily make your extension available for users of earlier versions of Yii.
Thanks again,
Trejder
fixed in 1.1.2
Thanks trejder for your feedback.
Portlet specificity
Great extension. Thank you. What I need is a plan for having each portal on a page specified separately. I want some portals to initialize collapsed and others to initialize expanded.
Any ideas on how best to accomplish this?
Thanks,
Alex
@Alex - multiple portlets (collapsed on page load)
I've come across the very same problem this morning as either all my "portals" completely disappeared or the title div was visible but the content wouldn't expand anymore... catch22. After checking the generated source code (the jquery stuff) I figured to rather use unique id's for each portlet (instead of css class names). So...
First, you have to change your portlet's code as follows:
public $model_id = null; public function init() { $this->id='my-portlet-'.$this->model_id; $this->decorationCssClass='portlet-decoration-'.$this->model_id; //to keep the default class name just append the new class //$this->decorationCssClass='portlet-decoration portlet-decoration-'.$this->model_id; //you can do the same here for titleCssClass & contentCssClass but it's not needed for slidetoggle effect parent::init(); }
Second, you need to pass the (unique) id's to the slidetoggle widget:
$this->widget('ext.slidetoggle.ESlidetoggle', array( 'itemSelector' => '#my-portlet-'.$model->id, 'titleSelector' => '.portlet-decoration-'.$model->id, 'collapsed' => '#my-portlet-'.$model->id, 'arrow' => false, 'easing' => 'linear', ));
Make sure "titleSelector" remains a class name (no id).
Third, do not forget to pass the unique id's to your portlet as parameter "model_id" (see portlet code).
That'll do the job.
If you have multiple portlets one after another you may want to add some additional margin (top+bottom) otherwise there is no spacing when collapsed. I've done this for all portlets with the following 2 lines:
.portlet {margin-bottom:20px;} .portlet-content {margin-bottom:0; padding-bottom:0;}
You can surely play around with the values for your liking.
Have fun!
@joblo
This works well on Safari 5+ & FF 3.6++ on Mac too.
animation issues
I have noticed if I have a smaller div section all of the animations work fine. However, if I have a larger div section (40+ lines of text inside the div) the animation is ignored and the collapse/expand just opens or closes so fast that you cannot even see it.
Example:
I have 3 collapse-able div sections on a page. The first div is a CGridView with 5 rows, inside each of the others is a CDetailView widget with around 40 rows. I populate the widgets with data from the same model/data, just different parts (Work notes history in the CGridView, Contact Info in one CDetailView div and job history in the other).
It is the div sections with the CDetailView widgets in them that the animation is broken in. Since the type of contents in the div should not make a difference I do not think that it is due to 1 being CGridView while the others are CDetailView. I believe this is more directly related to the "amount" of data in the div.
Is this a known issue with jquery (as I am new to jquery and do not know) or something introduced in this extension?
I am willing to test any ideas/solutions you may have since this is a hobby project and just for fun anyway.
dont forget about the element:contains("foo") selector of jQuery
this example attaches the widget only to the portlet with "admin" in the portlet decoration (admin is my title..).
'itemSelector' => '.portlet:contains("admin")',
'titleSelector' => '.portlet-decoration:contains("admin")', //'collapsed' => '.portlet:contains("admin")', //uncomment to show all collapsed
Spent some time to realise this...
When I first worked with my portlets I had no problems.
Then I wanted to add the widget on another page aswell, and it actually took me some time before I realised what I was doing wrong.
What didn't work ( only the arrow showed up ):
Bug? Unbalanced unit/spell? Exploit?
If you have detected a bug or any unbalanced unit/spell we would appriciate if you attached a replay
in a email to info [at] legiontdpro.com . Please write a short text describing where and when the bug appears, thank you!
How I fixed it:
Bug? Unbalanced unit/spell? Exploit?
If you have detected a bug or any unbalanced unit/spell we would appriciate if you attached a replay
in a email to info [at] legiontdpro.com . Please write a short text describing where and when the bug appears, thank you!
I missed a second child element to the selectorItem (in my example
Great extension!
Simple to implement
Extension doesn't work with Twitter Bootstrap
Hi everyone.
I found a bug in this extension. It doesn't work with Twitter Bootstrap plugin ( http://www.yiiframework.com/extension/bootstrap/ )
In order to solve this problem you shoud rename your javascript function from "collapse" to something else ("eslidetoggle" im my case).
Here is the example:
Wrong code (jquery.slidetoggle.js):
/** * jquery.slidetoggle.js * * Part of Yii extension 'slidetoggle' * @author Joe Blocher * */ jQuery.fn.collapse = function(options) { .... ....
Correct code:
/** * jquery.slidetoggle.js * * Part of Yii extension 'slidetoggle' * @author Joe Blocher * */ jQuery.fn.eslidetoggle = function(options) { // "collapse" function is already defined in Bootstrap .... ....
After that you shoud also edit ESlidetoggle.php:
public function registerClientScript() { .... .... $jsOptions = CJavaScript::encode($options); $jsCode .= "jQuery('{$this->titleSelector}').eslidetoggle($jsOptions);";
After that everything shoud be alright.
Please fix and update the extension.
Thank you!
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.