CTreeView.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. /**
  3. * CTreeView class file.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright 2008-2013 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CTreeView displays a tree view of hierarchical data.
  12. *
  13. * It encapsulates the excellent tree view plugin for jQuery
  14. * ({@link http://bassistance.de/jquery-plugins/jquery-plugin-treeview/}).
  15. *
  16. * To use CTreeView, simply sets {@link data} to the data that you want
  17. * to present and you are there.
  18. *
  19. * CTreeView also supports dynamic data loading via AJAX. To do so, set
  20. * {@link url} to be the URL that can serve the tree view data upon request.
  21. *
  22. * @author Qiang Xue <qiang.xue@gmail.com>
  23. * @package system.web.widgets
  24. * @since 1.0
  25. */
  26. class CTreeView extends CWidget
  27. {
  28. /**
  29. * @var array the data that can be used to generate the tree view content.
  30. * Each array element corresponds to a tree view node with the following structure:
  31. * <ul>
  32. * <li>text: string, required, the HTML text associated with this node.</li>
  33. * <li>expanded: boolean, optional, whether the tree view node is expanded.</li>
  34. * <li>id: string, optional, the ID identifying the node. This is used
  35. * in dynamic loading of tree view (see {@link url}).</li>
  36. * <li>hasChildren: boolean, optional, defaults to false, whether clicking on this
  37. * node should trigger dynamic loading of more tree view nodes from server.
  38. * The {@link url} property must be set in order to make this effective.</li>
  39. * <li>children: array, optional, child nodes of this node.</li>
  40. * <li>htmlOptions: array, additional HTML attributes (see {@link CHtml::tag}).
  41. * This option has been available since version 1.1.7.</li>
  42. * </ul>
  43. * Note, anything enclosed between the beginWidget and endWidget calls will
  44. * also be treated as tree view content, which appends to the content generated
  45. * from this data.
  46. */
  47. public $data;
  48. /**
  49. * @var mixed the CSS file used for the widget. Defaults to null, meaning
  50. * using the default CSS file included together with the widget.
  51. * If false, no CSS file will be used. Otherwise, the specified CSS file
  52. * will be included when using this widget.
  53. */
  54. public $cssFile;
  55. /**
  56. * @var string|array the URL to which the treeview can be dynamically loaded (in AJAX).
  57. * See {@link CHtml::normalizeUrl} for possible URL formats.
  58. * Setting this property will enable the dynamic treeview loading.
  59. * When the page is displayed, the browser will request this URL with a GET parameter
  60. * named 'root' whose value is 'source'. The server script should then generate the
  61. * needed tree view data corresponding to the root of the tree (see {@link saveDataAsJson}.)
  62. * When a node has a CSS class 'hasChildren', then expanding this node will also
  63. * cause a dynamic loading of its child nodes. In this case, the value of the 'root' GET parameter
  64. * is the 'id' property of the node.
  65. */
  66. public $url;
  67. /**
  68. * @var string|integer animation speed. This can be one of the three predefined speeds
  69. * ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
  70. * If not set, no animation is used.
  71. */
  72. public $animated;
  73. /**
  74. * @var boolean whether the tree should start with all branches collapsed. Defaults to false.
  75. */
  76. public $collapsed;
  77. /**
  78. * @var string container for a tree-control, allowing the user to expand, collapse and toggle all branches with one click.
  79. * In the container, clicking on the first hyperlink will collapse the tree;
  80. * the second hyperlink will expand the tree; while the third hyperlink will toggle the tree.
  81. * The property should be a valid jQuery selector (e.g. '#treecontrol' where 'treecontrol' is
  82. * the ID of the 'div' element containing the hyperlinks.)
  83. */
  84. public $control;
  85. /**
  86. * @var boolean set to allow only one branch on one level to be open (closing siblings which opening).
  87. * Defaults to false.
  88. */
  89. public $unique;
  90. /**
  91. * @var string Callback when toggling a branch. Arguments: "this" refers to the UL that was shown or hidden
  92. */
  93. public $toggle;
  94. /**
  95. * @var string Persist the tree state in cookies or the page location. If set to "location", looks for
  96. * the anchor that matches location.href and activates that part of the treeview it.
  97. * Great for href-based state-saving. If set to "cookie", saves the state of the tree on
  98. * each click to a cookie and restores that state on page load.
  99. */
  100. public $persist;
  101. /**
  102. * @var string The cookie name to use when persisting via persist:"cookie". Defaults to 'treeview'.
  103. */
  104. public $cookieId;
  105. /**
  106. * @var boolean Set to skip rendering of classes and hitarea divs, assuming that is done by the serverside. Defaults to false.
  107. */
  108. public $prerendered;
  109. /**
  110. * @var array additional options that can be passed to the constructor of the treeview js object.
  111. */
  112. public $options=array();
  113. /**
  114. * @var array additional HTML attributes that will be rendered in the UL tag.
  115. * The default tree view CSS has defined the following CSS classes which can be enabled
  116. * by specifying the 'class' option here:
  117. * <ul>
  118. * <li>treeview-black</li>
  119. * <li>treeview-gray</li>
  120. * <li>treeview-red</li>
  121. * <li>treeview-famfamfam</li>
  122. * <li>filetree</li>
  123. * </ul>
  124. */
  125. public $htmlOptions;
  126. /**
  127. * Initializes the widget.
  128. * This method registers all needed client scripts and renders
  129. * the tree view content.
  130. */
  131. public function init()
  132. {
  133. if(isset($this->htmlOptions['id']))
  134. $id=$this->htmlOptions['id'];
  135. else
  136. $id=$this->htmlOptions['id']=$this->getId();
  137. if($this->url!==null)
  138. $this->url=CHtml::normalizeUrl($this->url);
  139. $cs=Yii::app()->getClientScript();
  140. $cs->registerCoreScript('treeview');
  141. $options=$this->getClientOptions();
  142. $options=$options===array()?'{}' : CJavaScript::encode($options);
  143. $cs->registerScript('Yii.CTreeView#'.$id,"jQuery(\"#{$id}\").treeview($options);");
  144. if($this->cssFile===null)
  145. $cs->registerCssFile($cs->getCoreScriptUrl().'/treeview/jquery.treeview.css');
  146. elseif($this->cssFile!==false)
  147. $cs->registerCssFile($this->cssFile);
  148. echo CHtml::tag('ul',$this->htmlOptions,false,false)."\n";
  149. echo self::saveDataAsHtml($this->data);
  150. }
  151. /**
  152. * Ends running the widget.
  153. */
  154. public function run()
  155. {
  156. echo "</ul>";
  157. }
  158. /**
  159. * @return array the javascript options
  160. */
  161. protected function getClientOptions()
  162. {
  163. $options=$this->options;
  164. foreach(array('url','animated','collapsed','control','unique','toggle','persist','cookieId','prerendered') as $name)
  165. {
  166. if($this->$name!==null)
  167. $options[$name]=$this->$name;
  168. }
  169. return $options;
  170. }
  171. /**
  172. * Generates tree view nodes in HTML from the data array.
  173. * @param array $data the data for the tree view (see {@link data} for possible data structure).
  174. * @return string the generated HTML for the tree view
  175. */
  176. public static function saveDataAsHtml($data)
  177. {
  178. $html='';
  179. if(is_array($data))
  180. {
  181. foreach($data as $node)
  182. {
  183. if(!isset($node['text']))
  184. continue;
  185. if(isset($node['expanded']))
  186. $css=$node['expanded'] ? 'open' : 'closed';
  187. else
  188. $css='';
  189. if(isset($node['hasChildren']) && $node['hasChildren'])
  190. {
  191. if($css!=='')
  192. $css.=' ';
  193. $css.='hasChildren';
  194. }
  195. $options=isset($node['htmlOptions']) ? $node['htmlOptions'] : array();
  196. if($css!=='')
  197. {
  198. if(isset($options['class']))
  199. $options['class'].=' '.$css;
  200. else
  201. $options['class']=$css;
  202. }
  203. if(isset($node['id']))
  204. $options['id']=$node['id'];
  205. $html.=CHtml::tag('li',$options,$node['text'],false);
  206. if(!empty($node['children']))
  207. {
  208. $html.="\n<ul>\n";
  209. $html.=self::saveDataAsHtml($node['children']);
  210. $html.="</ul>\n";
  211. }
  212. $html.=CHtml::closeTag('li')."\n";
  213. }
  214. }
  215. return $html;
  216. }
  217. /**
  218. * Saves tree view data in JSON format.
  219. * This method is typically used in dynamic tree view loading
  220. * when the server code needs to send to the client the dynamic
  221. * tree view data.
  222. * @param array $data the data for the tree view (see {@link data} for possible data structure).
  223. * @return string the JSON representation of the data
  224. */
  225. public static function saveDataAsJson($data)
  226. {
  227. if(empty($data))
  228. return '[]';
  229. else
  230. return CJavaScript::jsonEncode($data);
  231. }
  232. }