1<?php
2/*
3 * EDatePicker class file.
4 *
5 * @author ironic
6 * @version 2.4.1
7 * @link http://www.yiiframework.com/
8 * @copyright Copyright &copy; 2009 ironic
9 * @license dual GPL (3.0 or later) and MIT, at your choice.
10 * @license http://www.opensource.org/licenses/mit-license.php
11 * @license http://www.opensource.org/licenses/gpl-3.0.php
12 *
13 * See doc/gpl-3.0.txt and doc/MIT-LICENSE.txt for the full text of the
14 * licenses.
15 *
16 * The MIT license:
17 *
18 * Copyright (c) 2009 ironic
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining a copy
21 * of this software and associated documentation files (the "Software"), to deal
22 * in the Software without restriction, including without limitation the rights
23 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24 * copies of the Software, and to permit persons to whom the Software is
25 * furnished to do so, subject to the following conditions:
26 *
27 * The above copyright notice and this permission notice shall be included in
28 * all copies or substantial portions of the Software.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
36 * THE SOFTWARE.
37 *
38 * The GPL license:
39 *
40 * Copyright (C) 2009 ironic
41 *
42 * This program is free software: you can redistribute it and/or modify
43 * it under the terms of the GNU General Public License as published by
44 * the Free Software Foundation, either version 3 of the License, or
45 * (at your option) any later version.
46 *
47 * This program is distributed in the hope that it will be useful,
48 * but WITHOUT ANY WARRANTY; without even the implied warranty of
49 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
50 * GNU General Public License for more details.
51 *
52 * You should have received a copy of the GNU General Public License
53 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
54 */
55
56require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'EJqueryUiWidget.php');
57
58/**
59 *
60 * EAccordion: some rails for the jQuery UI widget "Accordion".
61 *
62 * @see: http://jqueryui.com/demos/accordion/
63 * @see: http://docs.jquery.com/UI/Accordion
64 *
65 * @author: ironic
66 * @package: application.extensions.jui
67 * @since: 1.0.2
68 *
69 */
70class EAccordion extends EJqueryUiWidget
71{
72   //***************************************************************************
73   // Configuration
74   //***************************************************************************
75
76   /**
77    * The body of the widget
78    *
79    * @var string
80    */
81   private $body = '';
82
83	/**
84	 * The panels of the accordion widget.
85	 * @var array
86	 */
87	private $_panels = array();
88
89	/**
90	 * The wrapping html tag for the header-part
91	 * of a accordion panel.
92	 * @var string
93	 */
94	private $_headerHtml = 'h3';
95
96	/**
97	 * The functions supported by the
98	 * jquery accordion script
99	 * @var array
100	 */
101	private $_functions = array();
102
103	/**
104	 * determines wether to use the jquery.easing
105	 * plugin or not...
106	 * @var boolean
107	 */
108	private $_useEasing = false;
109
110   //***************************************************************************
111   // Internal properties
112   //***************************************************************************
113
114	/**
115	 * The valid script Options for the accordion widget.
116	 *
117	 * See @link http://jqueryui.com/demos/accordion/#options
118	 *
119	 * @var array
120	 */
121	protected $validOptions = array(
122      'active'=>array('type'=>array('boolean', 'number')), // Selector for the active element. Set to false to display none at start. Needs «collapsible: true». Default: first child
123      'animated'=>array('type'=>array('boolean', 'string')), // Choose your favorite animation, or disable them (set to false). In addition to the default, 'bounceslide' and 'easeslide' are supported (both require the easing plugin). Default: false
124      'autoHeight'=>array('type'=>'boolean'), // If set, the highest content part is used as height reference for all other parts. Provides more consistent animations. Default: true
125      'clearStyle'=>array('type'=>'boolean'), // If set, clears height and overflow styles after finishing animations. This enables accordions to work with dynamic content. Won't work together with autoHeight. Default: false
126      'collapsible'=>array('type'=>'boolean'), // Whether all the sections can be closed at once. Allows collapsing the active section by the triggering event (click is the default). Default: false
127      'event'=>array('type'=>'string'), // The event on which to trigger the accordion. Default: 'click'
128      'fillSpace'=>array('type'=>'boolean'), // If set, the accordion completely fills the height of the parent element. Overrides autoheight. Default: false
129      'header'=>array('type'=>'string'), // Selector for the header element. Default: '> li > :first-child,> :not(li):even'
130      'icons'=>array('type'=>'array'), // Icons to use for headers. Icons may be specified for 'header' and 'headerSelected', and we recommend using the icons native to the jQuery UI CSS Framework manipulated by jQuery UI ThemeRoller. Default: { 'header': 'ui-icon-triangle-1-e', 'headerSelected': 'ui-icon-triangle-1-s' }
131      'navigation'=>array('type'=>'boolean'), // If set, looks for the anchor that matches location.href and activates it. Great for href-based state-saving. Use navigationFilter to implement your own matcher. Default: false
132	);
133
134   /**
135	* See @link http://jqueryui.com/demos/accordion/#options
136	*
137	* @var array
138	*/
139	protected $validFunctions = array('navigationFilter');
140
141   /**
142	* See @link http://jqueryui.com/demos/accordion/#events
143	*
144	* @var array
145	*/
146   protected $validCallbacks = array('change');
147
148   //***************************************************************************
149   // Setters and getters
150   //***************************************************************************
151
152   /**
153	* Sets the panels property.
154	* Format:
155	* array(
156	*	'Panel 1 Header' => '<p>Panel 1 Content</p>',
157	*	'Panel 2 Header' => '<ul><li>Panel 2 Content</li></ul>',
158	* )
159	* @param array
160	*/
161	public function setPanels(array $panels)
162	{
163		$this->_panels = $panels;
164	}
165
166   /**
167	* Returns the panels property.
168	* @return array
169	*/
170	public function getPanels()
171	{
172		return $this->_panels;
173	}
174
175   /**
176	* Sets the header html tag.
177	* @param string
178	*/
179	public function setHeaderHtml($headerHtml)
180	{
181		if(is_string($headerHtml))
182			$this->_headerHtml = $headerHtml;
183	}
184
185   /**
186	* Returns the header html tag.
187	* @return string
188	*/
189	public function getHeaderHtml()
190	{
191		return $this->_headerHtml;
192	}
193
194   /**
195	* Sets the functions property.
196	* Format:
197    * array(
198	*	'navigationFilter' => 'function() {
199	*		return this.href.toLowerCase()==location.href.toLowerCase();
200	*	}',
201	* )
202	* @param array
203	*/
204	public function setFunctions(array $functions)
205	{
206		$this->_functions = $functions;
207	}
208
209   /**
210	* Returns the functions property.
211	* @return array
212	*/
213	public function getFunctions()
214	{
215		return $this->_functions;
216	}
217
218   /**
219	* Sets the useEasing property.
220	* @return array
221	*/
222	public function setUseEasing($useEasing)
223	{
224		if(is_bool($useEasing))
225			$this->_useEasing = $useEasing;
226	}
227
228   /**
229	* Returns the useEasing property.
230	* @return array
231	*/
232	public function getUseEasing()
233	{
234		return $this->_useEasing;
235	}
236
237   //***************************************************************************
238   // Utilities
239   //***************************************************************************
240
241   protected function makeOptions()
242   {
243		$options = array();
244		$options['header'] = $this->_headerHtml;
245		$options = CJavaScript::encode(array_merge($options, $this->options));
246		return $options;
247   }
248
249   /**
250	* Generates the javascript code for the widget
251	* @return string
252	*/
253	protected function jsCode($id)
254	{
255		$options = $this->makeOptions();
256		$script = '$("#'.$id.'").accordion('.$options.');';
257
258		$pattern = array("\r\n", "\n", "\r", "\t");
259
260		foreach($this->callbacks as $key => $val) {
261			$val = str_replace($pattern, "", $val);
262			$script .= "\n$('#".$id."').accordion('option', '".$key."', ".$val.");";
263		}
264
265		foreach($this->functions as $key => $val) {
266			$val = str_replace($pattern, "", $val);
267			$script .= "\n$('#".$id."').accordion('option', '".$key."', ".$val.");";
268		}
269
270		return $script;
271	}
272
273   /**
274	* Generates the html code for the widget
275	* @return string
276	*/
277	public function htmlCode()
278	{
279      $html = '';
280      if (!empty($this->_panels)) {
281         foreach ($this->_panels as $panelHeader => $panelBody) {
282            $anchor = sprintf("#%s", strtolower(trim($panelHeader)));
283            $anchor = str_replace(array("\r\n", "\n", "\r", "\t", " "), "", $anchor);
284            $header_link = CHtml::link($panelHeader, $anchor);
285            $html .= CHtml::openTag('div');
286            $html .= CHtml::tag($this->_headerHtml, array(), $header_link);
287            $html .= CHtml::tag('div', array(), $panelBody);
288            $html .= CHtml::closeTag('div');
289         }
290      }
291      else {
292         $html = CHtml::tag('div', array(), $this->body);
293      }
294
295		return $html;
296	}
297
298	public function registerClientScripts()
299	{
300		parent::registerClientScripts();
301		if($this->useEasing)
302			$this->clientScript->registerScriptFile($this->baseUrl.'/external/easing/jquery.easing.1.3.js');
303	}
304
305   //***************************************************************************
306   // Run Lola, Run
307   //***************************************************************************
308
309   /**
310    * Inits the widget.
311    */
312   public function init()
313   {
314      if (empty($this->_panels)) {
315         ob_start();
316      }
317   }
318
319	/**
320	 * Executes the widget.
321	 * This method is called by {@link CBaseController::endWidget}.
322	 */
323	public function run()
324	{
325      if (empty($this->_panels)) {
326         $this->body = ob_get_contents();
327         ob_end_clean();
328      }
329
330		list($name, $id) = $this->resolveNameID();
331
332		$this->publishAssets();
333		$this->registerClientScripts();
334
335		$this->clientScript->registerScript('Yii.'.get_class($this).'#'.$id,
336											$this->jsCode($name),
337											CClientScript::POS_READY);
338
339		echo CHtml::tag('div', array('id'=>$id), $this->htmlCode());
340	}
341}