PageRenderTime 24ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/framework/Web/UI/TClientScriptManager.php

http://prado3.googlecode.com/
PHP | 829 lines | 444 code | 86 blank | 299 comment | 32 complexity | 6460a35fb0fa2c21c5af01fd29f3f575 MD5 | raw file
Possible License(s): Apache-2.0, IPL-1.0, LGPL-3.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * TClientScriptManager and TClientSideOptions class file.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @author Gabor Berczi <gabor.berczi@devworx.hu> (lazyload additions & progressive rendering)
  7. * @link http://www.pradosoft.com/
  8. * @copyright Copyright &copy; 2005-2012 PradoSoft
  9. * @license http://www.pradosoft.com/license/
  10. * @version $Id: TClientScriptManager.php 3208 2012-09-29 08:18:05Z ctrlaltca $
  11. * @package System.Web.UI
  12. */
  13. /**
  14. * TClientScriptManager class.
  15. *
  16. * TClientScriptManager manages javascript and CSS stylesheets for a page.
  17. *
  18. * @author Qiang Xue <qiang.xue@gmail.com>
  19. * @author Gabor Berczi <gabor.berczi@devworx.hu> (lazyload additions & progressive rendering)
  20. * @version $Id: TClientScriptManager.php 3208 2012-09-29 08:18:05Z ctrlaltca $
  21. * @package System.Web.UI
  22. * @since 3.0
  23. */
  24. class TClientScriptManager extends TApplicationComponent
  25. {
  26. /**
  27. * directory containing Prado javascript files
  28. */
  29. const SCRIPT_PATH='Web/Javascripts/source';
  30. /**
  31. * file containing javascript packages and their cross dependencies
  32. */
  33. const PACKAGES_FILE='Web/Javascripts/packages.php';
  34. /**
  35. * @var TPage page who owns this manager
  36. */
  37. private $_page;
  38. /**
  39. * @var array registered hidden fields, indexed by hidden field names
  40. */
  41. private $_hiddenFields=array();
  42. /**
  43. * @var array javascript blocks to be rendered at the beginning of the form
  44. */
  45. private $_beginScripts=array();
  46. /**
  47. * @var array javascript blocks to be rendered at the end of the form
  48. */
  49. private $_endScripts=array();
  50. /**
  51. * @var array javascript files to be rendered in the form
  52. */
  53. private $_scriptFiles=array();
  54. /**
  55. * @var array javascript files to be rendered in page head section
  56. */
  57. private $_headScriptFiles=array();
  58. /**
  59. * @var array javascript blocks to be rendered in page head section
  60. */
  61. private $_headScripts=array();
  62. /**
  63. * @var array CSS files
  64. */
  65. private $_styleSheetFiles=array();
  66. /**
  67. * @var array CSS declarations
  68. */
  69. private $_styleSheets=array();
  70. /**
  71. * @var array registered PRADO script libraries
  72. */
  73. private $_registeredPradoScripts=array();
  74. /**
  75. * Client-side javascript library dependencies, loads from PACKAGES_FILE;
  76. * @var array
  77. */
  78. private static $_pradoScripts;
  79. /**
  80. * Client-side javascript library packages, loads from PACKAGES_FILE;
  81. * @var array
  82. */
  83. private static $_pradoPackages;
  84. private $_renderedHiddenFields;
  85. private $_renderedScriptFiles=array();
  86. private $_expandedPradoScripts;
  87. /**
  88. * Constructor.
  89. * @param TPage page that owns this client script manager
  90. */
  91. public function __construct(TPage $owner)
  92. {
  93. $this->_page=$owner;
  94. }
  95. /**
  96. * @return boolean whether THead is required in order to render CSS and js within head
  97. * @since 3.1.1
  98. */
  99. public function getRequiresHead()
  100. {
  101. return count($this->_styleSheetFiles) || count($this->_styleSheets)
  102. || count($this->_headScriptFiles) || count($this->_headScripts);
  103. }
  104. public static function getPradoPackages()
  105. {
  106. return self::$_pradoPackages;
  107. }
  108. public static function getPradoScripts()
  109. {
  110. return self::$_pradoScripts;
  111. }
  112. /**
  113. * Registers Prado javascript by library name. See "Web/Javascripts/packages.php"
  114. * for library names.
  115. * @param string script library name.
  116. */
  117. public function registerPradoScript($name)
  118. {
  119. $this->registerPradoScriptInternal($name);
  120. $params=func_get_args();
  121. $this->_page->registerCachingAction('Page.ClientScript','registerPradoScript',$params);
  122. }
  123. /**
  124. * Registers a Prado javascript library to be loaded.
  125. */
  126. protected function registerPradoScriptInternal($name)
  127. {
  128. // $this->checkIfNotInRender();
  129. if(!isset($this->_registeredPradoScripts[$name]))
  130. {
  131. if(self::$_pradoScripts === null)
  132. {
  133. $packageFile = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::PACKAGES_FILE;
  134. list($packages,$deps)= include($packageFile);
  135. self::$_pradoScripts = $deps;
  136. self::$_pradoPackages = $packages;
  137. }
  138. if (isset(self::$_pradoScripts[$name]))
  139. $this->_registeredPradoScripts[$name]=true;
  140. else
  141. throw new TInvalidOperationException('csmanager_pradoscript_invalid',$name);
  142. if(($packages=array_keys($this->_registeredPradoScripts))!==array())
  143. {
  144. $base = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::SCRIPT_PATH;
  145. list($path,$baseUrl)=$this->getPackagePathUrl($base);
  146. $packagesUrl=array();
  147. $isDebug=$this->getApplication()->getMode()===TApplicationMode::Debug;
  148. foreach ($packages as $p)
  149. {
  150. foreach (self::$_pradoScripts[$p] as $dep)
  151. {
  152. foreach (self::$_pradoPackages[$dep] as $script)
  153. if (!isset($this->_expandedPradoScripts[$script]))
  154. {
  155. $this->_expandedPradoScripts[$script] = true;
  156. if($isDebug)
  157. {
  158. if (!in_array($url=$baseUrl.'/'.$script,$packagesUrl))
  159. $packagesUrl[]=$url;
  160. } else {
  161. if (!in_array($url=$baseUrl.'/min/'.$script,$packagesUrl))
  162. {
  163. if(!is_file($filePath=$path.'/min/'.$script))
  164. {
  165. $dirPath=dirname($filePath);
  166. if(!is_dir($dirPath))
  167. mkdir($dirPath, PRADO_CHMOD, true);
  168. file_put_contents($filePath, TJavaScript::JSMin(file_get_contents($base.'/'.$script)));
  169. chmod($filePath, PRADO_CHMOD);
  170. }
  171. $packagesUrl[]=$url;
  172. }
  173. }
  174. }
  175. }
  176. }
  177. foreach($packagesUrl as $url)
  178. $this->registerScriptFile($url,$url);
  179. }
  180. }
  181. }
  182. /**
  183. * @return string Prado javascript library base asset url.
  184. */
  185. public function getPradoScriptAssetUrl()
  186. {
  187. $base = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::SCRIPT_PATH;
  188. $assets = Prado::getApplication()->getAssetManager();
  189. return $assets->getPublishedUrl($base);
  190. }
  191. /**
  192. * Returns the URLs of all script files referenced on the page
  193. * @return array Combined list of all script urls used in the page
  194. */
  195. public function getScriptUrls()
  196. {
  197. $scripts = array_values($this->_headScriptFiles);
  198. $scripts = array_merge($scripts, array_values($this->_scriptFiles));
  199. $scripts = array_unique($scripts);
  200. return $scripts;
  201. }
  202. /**
  203. * @param string javascript package path.
  204. * @return array tuple($path,$url).
  205. */
  206. protected function getPackagePathUrl($base)
  207. {
  208. $assets = Prado::getApplication()->getAssetManager();
  209. if(strpos($base, $assets->getBaseUrl())===false)
  210. {
  211. if(($dir = Prado::getPathOfNameSpace($base)) !== null) {
  212. $base = $dir;
  213. }
  214. return array($assets->getPublishedPath($base), $assets->publishFilePath($base));
  215. }
  216. else
  217. {
  218. return array($assets->getBasePath().str_replace($assets->getBaseUrl(),'',$base), $base);
  219. }
  220. }
  221. /**
  222. * Returns javascript statement that create a new callback request object.
  223. * @param ICallbackEventHandler callback response handler
  224. * @param array additional callback options
  225. * @return string javascript statement that creates a new callback request.
  226. */
  227. public function getCallbackReference(ICallbackEventHandler $callbackHandler, $options=null)
  228. {
  229. $options = !is_array($options) ? array() : $options;
  230. $class = new ReflectionClass($callbackHandler);
  231. $clientSide = $callbackHandler->getActiveControl()->getClientSide();
  232. $options = array_merge($options, $clientSide->getOptions()->toArray());
  233. $optionString = TJavaScript::encode($options);
  234. $this->registerPradoScriptInternal('ajax');
  235. $id = $callbackHandler->getUniqueID();
  236. return "new Prado.CallbackRequest('{$id}',{$optionString})";
  237. }
  238. /**
  239. * Registers callback javascript for a control.
  240. * @param string javascript class responsible for the control being registered for callback
  241. * @param array callback options
  242. */
  243. public function registerCallbackControl($class, $options)
  244. {
  245. $optionString=TJavaScript::encode($options);
  246. $code="new {$class}({$optionString});";
  247. $this->_endScripts[sprintf('%08X', crc32($code))]=$code;
  248. $this->registerPradoScriptInternal('ajax');
  249. $params=func_get_args();
  250. $this->_page->registerCachingAction('Page.ClientScript','registerCallbackControl',$params);
  251. }
  252. /**
  253. * Registers postback javascript for a control. A null class parameter will prevent
  254. * the javascript code registration.
  255. * @param string javascript class responsible for the control being registered for postback
  256. * @param array postback options
  257. */
  258. public function registerPostBackControl($class,$options)
  259. {
  260. if($class === null) {
  261. return;
  262. }
  263. if(!isset($options['FormID']) && ($form=$this->_page->getForm())!==null)
  264. $options['FormID']=$form->getClientID();
  265. $optionString=TJavaScript::encode($options);
  266. $code="new {$class}({$optionString});";
  267. $this->_endScripts[sprintf('%08X', crc32($code))]=$code;
  268. $this->_hiddenFields[TPage::FIELD_POSTBACK_TARGET]='';
  269. $this->_hiddenFields[TPage::FIELD_POSTBACK_PARAMETER]='';
  270. $this->registerPradoScriptInternal('prado');
  271. $params=func_get_args();
  272. $this->_page->registerCachingAction('Page.ClientScript','registerPostBackControl',$params);
  273. }
  274. /**
  275. * Register a default button to panel. When the $panel is in focus and
  276. * the 'enter' key is pressed, the $button will be clicked.
  277. * @param TControl|string panel (or its unique ID) to register the default button action
  278. * @param TControl|string button (or its unique ID) to trigger a postback
  279. */
  280. public function registerDefaultButton($panel, $button)
  281. {
  282. $panelID=is_string($panel)?$panel:$panel->getUniqueID();
  283. if(is_string($button))
  284. $buttonID=$button;
  285. else
  286. {
  287. $button->setIsDefaultButton(true);
  288. $buttonID=$button->getUniqueID();
  289. }
  290. $options = TJavaScript::encode($this->getDefaultButtonOptions($panelID, $buttonID));
  291. $code = "new Prado.WebUI.DefaultButton($options);";
  292. $this->_endScripts['prado:'.$panelID]=$code;
  293. $this->_hiddenFields[TPage::FIELD_POSTBACK_TARGET]='';
  294. $this->registerPradoScriptInternal('prado');
  295. $params=array($panelID,$buttonID);
  296. $this->_page->registerCachingAction('Page.ClientScript','registerDefaultButton',$params);
  297. }
  298. /**
  299. * @param string the unique ID of the container control
  300. * @param string the unique ID of the button control
  301. * @return array default button options.
  302. */
  303. protected function getDefaultButtonOptions($panelID, $buttonID)
  304. {
  305. $options['ID'] = TControl::convertUniqueIdToClientId($panelID);
  306. $options['Panel'] = TControl::convertUniqueIdToClientId($panelID);
  307. $options['Target'] = TControl::convertUniqueIdToClientId($buttonID);
  308. $options['EventTarget'] = $buttonID;
  309. $options['Event'] = 'click';
  310. return $options;
  311. }
  312. /**
  313. * Registers the control to receive default focus.
  314. * @param string the client ID of the control to receive default focus
  315. */
  316. public function registerFocusControl($target)
  317. {
  318. $this->registerPradoScriptInternal('effects');
  319. if($target instanceof TControl)
  320. $target=$target->getClientID();
  321. $id = TJavaScript::quoteString($target);
  322. $this->_endScripts['prado:focus'] = 'new Effect.ScrollTo('.$id.'); Prado.Element.focus('.$id.');';
  323. $params=func_get_args();
  324. $this->_page->registerCachingAction('Page.ClientScript','registerFocusControl',$params);
  325. }
  326. /**
  327. * Registers a CSS file to be rendered in the page head
  328. *
  329. * The CSS files in themes are registered in {@link OnPreRenderComplete onPreRenderComplete} if you want to override
  330. * CSS styles in themes you need to register it after this event is completed.
  331. *
  332. * Example:
  333. * <code>
  334. * <?php
  335. * class BasePage extends TPage {
  336. * public function onPreRenderComplete($param) {
  337. * parent::onPreRenderComplete($param);
  338. * $url = 'path/to/your/stylesheet.css';
  339. * $this->Page->ClientScript->registerStyleSheetFile($url, $url);
  340. * }
  341. * }
  342. * ?>
  343. * </code>
  344. *
  345. * @param string a unique key identifying the file
  346. * @param string URL to the CSS file
  347. * @param string media type of the CSS (such as 'print', 'screen', etc.). Defaults to empty, meaning the CSS applies to all media types.
  348. */
  349. public function registerStyleSheetFile($key,$url,$media='')
  350. {
  351. if($media==='')
  352. $this->_styleSheetFiles[$key]=$url;
  353. else
  354. $this->_styleSheetFiles[$key]=array($url,$media);
  355. $params=func_get_args();
  356. $this->_page->registerCachingAction('Page.ClientScript','registerStyleSheetFile',$params);
  357. }
  358. /**
  359. * Registers a CSS block to be rendered in the page head
  360. * @param string a unique key identifying the CSS block
  361. * @param string CSS block
  362. */
  363. public function registerStyleSheet($key,$css,$media='')
  364. {
  365. $this->_styleSheets[$key]=$css;
  366. $params=func_get_args();
  367. $this->_page->registerCachingAction('Page.ClientScript','registerStyleSheet',$params);
  368. }
  369. /**
  370. * Returns the URLs of all stylesheet files referenced on the page
  371. * @return array Combined list of all stylesheet urls used in the page
  372. */
  373. public function getStyleSheetUrls()
  374. {
  375. $stylesheets = array_values(array_merge($this->_styleSheetFiles, $this->_styleSheets));
  376. foreach(Prado::getApplication()->getAssetManager()->getPublished() as $path=>$url)
  377. if (substr($url,strlen($url)-4)=='.css')
  378. $stylesheets[] = $url;
  379. $stylesheets = array_unique($stylesheets);
  380. return $stylesheets;
  381. }
  382. /**
  383. * Registers a javascript file in the page head
  384. * @param string a unique key identifying the file
  385. * @param string URL to the javascript file
  386. */
  387. public function registerHeadScriptFile($key,$url)
  388. {
  389. $this->checkIfNotInRender();
  390. $this->_headScriptFiles[$key]=$url;
  391. $params=func_get_args();
  392. $this->_page->registerCachingAction('Page.ClientScript','registerHeadScriptFile',$params);
  393. }
  394. /**
  395. * Registers a javascript block in the page head.
  396. * @param string a unique key identifying the script block
  397. * @param string javascript block
  398. */
  399. public function registerHeadScript($key,$script)
  400. {
  401. $this->checkIfNotInRender();
  402. $this->_headScripts[$key]=$script;
  403. $params=func_get_args();
  404. $this->_page->registerCachingAction('Page.ClientScript','registerHeadScript',$params);
  405. }
  406. /**
  407. * Registers a javascript file to be rendered within the form
  408. * @param string a unique key identifying the file
  409. * @param string URL to the javascript file to be rendered
  410. */
  411. public function registerScriptFile($key, $url)
  412. {
  413. $this->_scriptFiles[$key]=$url;
  414. $params=func_get_args();
  415. $this->_page->registerCachingAction('Page.ClientScript','registerScriptFile',$params);
  416. }
  417. /**
  418. * Registers a javascript script block at the beginning of the form
  419. * @param string a unique key identifying the script block
  420. * @param string javascript block
  421. */
  422. public function registerBeginScript($key,$script)
  423. {
  424. $this->checkIfNotInRender();
  425. $this->_beginScripts[$key]=$script;
  426. $params=func_get_args();
  427. $this->_page->registerCachingAction('Page.ClientScript','registerBeginScript',$params);
  428. }
  429. /**
  430. * Registers a javascript script block at the end of the form
  431. * @param string a unique key identifying the script block
  432. * @param string javascript block
  433. */
  434. public function registerEndScript($key,$script)
  435. {
  436. $this->_endScripts[$key]=$script;
  437. $params=func_get_args();
  438. $this->_page->registerCachingAction('Page.ClientScript','registerEndScript',$params);
  439. }
  440. /**
  441. * Registers a hidden field to be rendered in the form.
  442. * @param string a unique key identifying the hidden field
  443. * @param string|array hidden field value, if the value is an array, every element
  444. * in the array will be rendered as a hidden field value.
  445. */
  446. public function registerHiddenField($name,$value)
  447. {
  448. $this->_hiddenFields[$name]=$value;
  449. $params=func_get_args();
  450. $this->_page->registerCachingAction('Page.ClientScript','registerHiddenField',$params);
  451. }
  452. /**
  453. * @param string a unique key
  454. * @return boolean whether there is a CSS file registered with the specified key
  455. */
  456. public function isStyleSheetFileRegistered($key)
  457. {
  458. return isset($this->_styleSheetFiles[$key]);
  459. }
  460. /**
  461. * @param string a unique key
  462. * @return boolean whether there is a CSS block registered with the specified key
  463. */
  464. public function isStyleSheetRegistered($key)
  465. {
  466. return isset($this->_styleSheets[$key]);
  467. }
  468. /**
  469. * @param string a unique key
  470. * @return boolean whether there is a head javascript file registered with the specified key
  471. */
  472. public function isHeadScriptFileRegistered($key)
  473. {
  474. return isset($this->_headScriptFiles[$key]);
  475. }
  476. /**
  477. * @param string a unique key
  478. * @return boolean whether there is a head javascript block registered with the specified key
  479. */
  480. public function isHeadScriptRegistered($key)
  481. {
  482. return isset($this->_headScripts[$key]);
  483. }
  484. /**
  485. * @param string a unique key
  486. * @return boolean whether there is a javascript file registered with the specified key
  487. */
  488. public function isScriptFileRegistered($key)
  489. {
  490. return isset($this->_scriptFiles[$key]);
  491. }
  492. /**
  493. * @param string a unique key
  494. * @return boolean whether there is a beginning javascript block registered with the specified key
  495. */
  496. public function isBeginScriptRegistered($key)
  497. {
  498. return isset($this->_beginScripts[$key]);
  499. }
  500. /**
  501. * @param string a unique key
  502. * @return boolean whether there is an ending javascript block registered with the specified key
  503. */
  504. public function isEndScriptRegistered($key)
  505. {
  506. return isset($this->_endScripts[$key]);
  507. }
  508. /**
  509. * @return boolean true if any end scripts are registered.
  510. */
  511. public function hasEndScripts()
  512. {
  513. return count($this->_endScripts) > 0;
  514. }
  515. /**
  516. * @return boolean true if any begin scripts are registered.
  517. */
  518. public function hasBeginScripts()
  519. {
  520. return count($this->_beginScripts) > 0;
  521. }
  522. /**
  523. * @param string a unique key
  524. * @return boolean whether there is a hidden field registered with the specified key
  525. */
  526. public function isHiddenFieldRegistered($key)
  527. {
  528. return isset($this->_hiddenFields[$key]);
  529. }
  530. /**
  531. * @param THtmlWriter writer for the rendering purpose
  532. */
  533. public function renderStyleSheetFiles($writer)
  534. {
  535. $str='';
  536. foreach($this->_styleSheetFiles as $url)
  537. {
  538. if(is_array($url))
  539. $str.="<link rel=\"stylesheet\" type=\"text/css\" media=\"{$url[1]}\" href=\"".THttpUtility::htmlEncode($url[0])."\" />\n";
  540. else
  541. $str.="<link rel=\"stylesheet\" type=\"text/css\" href=\"".THttpUtility::htmlEncode($url)."\" />\n";
  542. }
  543. $writer->write($str);
  544. }
  545. /**
  546. * @param THtmlWriter writer for the rendering purpose
  547. */
  548. public function renderStyleSheets($writer)
  549. {
  550. if(count($this->_styleSheets))
  551. $writer->write("<style type=\"text/css\">\n/*<![CDATA[*/\n".implode("\n",$this->_styleSheets)."\n/*]]>*/\n</style>\n");
  552. }
  553. /**
  554. * @param THtmlWriter writer for the rendering purpose
  555. */
  556. public function renderHeadScriptFiles($writer)
  557. {
  558. $this->renderScriptFiles($writer,$this->_headScriptFiles);
  559. }
  560. /**
  561. * @param THtmlWriter writer for the rendering purpose
  562. */
  563. public function renderHeadScripts($writer)
  564. {
  565. $writer->write(TJavaScript::renderScriptBlocks($this->_headScripts));
  566. }
  567. public function renderScriptFilesBegin($writer)
  568. {
  569. $this->renderAllPendingScriptFiles($writer);
  570. }
  571. public function renderScriptFilesEnd($writer)
  572. {
  573. $this->renderAllPendingScriptFiles($writer);
  574. }
  575. public function markScriptFileAsRendered($url)
  576. {
  577. $this->_renderedScriptFiles[$url] = $url;
  578. $params=func_get_args();
  579. $this->_page->registerCachingAction('Page.ClientScript','markScriptFileAsRendered',$params);
  580. }
  581. protected function renderScriptFiles($writer, Array $scripts)
  582. {
  583. foreach($scripts as $script)
  584. {
  585. $writer->write(TJavaScript::renderScriptFile($script));
  586. $this->markScriptFileAsRendered($script);
  587. }
  588. }
  589. protected function getRenderedScriptFiles()
  590. {
  591. return $this->_renderedScriptFiles;
  592. }
  593. /**
  594. * @param THtmlWriter writer for the rendering purpose
  595. */
  596. public function renderAllPendingScriptFiles($writer)
  597. {
  598. if(!empty($this->_scriptFiles))
  599. {
  600. $addedScripts = array_diff($this->_scriptFiles,$this->getRenderedScriptFiles());
  601. $this->renderScriptFiles($writer,$addedScripts);
  602. }
  603. }
  604. /**
  605. * @param THtmlWriter writer for the rendering purpose
  606. */
  607. public function renderBeginScripts($writer)
  608. {
  609. $writer->write(TJavaScript::renderScriptBlocks($this->_beginScripts));
  610. }
  611. /**
  612. * @param THtmlWriter writer for the rendering purpose
  613. */
  614. public function renderEndScripts($writer)
  615. {
  616. $writer->write(TJavaScript::renderScriptBlocks($this->_endScripts));
  617. }
  618. public function renderHiddenFieldsBegin($writer)
  619. {
  620. $this->renderHiddenFieldsInt($writer,true);
  621. }
  622. public function renderHiddenFieldsEnd($writer)
  623. {
  624. $this->renderHiddenFieldsInt($writer,false);
  625. }
  626. /**
  627. * Flushes all pending script registrations
  628. * @param THtmlWriter writer for the rendering purpose
  629. * @param TControl the control forcing the flush (used only in error messages)
  630. */
  631. public function flushScriptFiles($writer, $control=null)
  632. {
  633. $this->_page->ensureRenderInForm($control);
  634. $this->renderAllPendingScriptFiles($writer);
  635. }
  636. /**
  637. * @param THtmlWriter writer for the rendering purpose
  638. */
  639. protected function renderHiddenFieldsInt($writer, $initial)
  640. {
  641. if ($initial) $this->_renderedHiddenFields = array();
  642. $str='';
  643. foreach($this->_hiddenFields as $name=>$value)
  644. {
  645. if (in_array($name,$this->_renderedHiddenFields)) continue;
  646. $id=strtr($name,':','_');
  647. if(is_array($value))
  648. {
  649. foreach($value as $v)
  650. $str.='<input type="hidden" name="'.$name.'[]" id="'.$id.'" value="'.THttpUtility::htmlEncode($value)."\" />\n";
  651. }
  652. else
  653. {
  654. $str.='<input type="hidden" name="'.$name.'" id="'.$id.'" value="'.THttpUtility::htmlEncode($value)."\" />\n";
  655. }
  656. $this->_renderedHiddenFields[] = $name;
  657. }
  658. if($str!=='')
  659. $writer->write("<div style=\"visibility:hidden;\">\n".$str."</div>\n");
  660. }
  661. public function getHiddenFields()
  662. {
  663. return $this->_hiddenFields;
  664. }
  665. /**
  666. * Checks whether page rendering has not begun yet
  667. */
  668. protected function checkIfNotInRender()
  669. {
  670. if ($form = $this->_page->InFormRender)
  671. throw new Exception('Operation invalid when page is already rendering');
  672. }
  673. }
  674. /**
  675. * TClientSideOptions abstract class.
  676. *
  677. * TClientSideOptions manages client-side options for components that have
  678. * common client-side javascript behaviours and client-side events such as
  679. * between ActiveControls and validators.
  680. *
  681. * @author <weizhuo[at]gmail[dot]com>
  682. * @version $Id: TClientScriptManager.php 3208 2012-09-29 08:18:05Z ctrlaltca $
  683. * @package System.Web.UI
  684. * @since 3.0
  685. */
  686. abstract class TClientSideOptions extends TComponent
  687. {
  688. /**
  689. * @var TMap list of client-side options.
  690. */
  691. private $_options;
  692. /**
  693. * Constructor, initialize the options list.
  694. */
  695. public function __construct()
  696. {
  697. $this->_options = Prado::createComponent('System.Collections.TMap');
  698. }
  699. /**
  700. * Adds on client-side event handler by wrapping the code within a
  701. * javascript function block. If the code begins with "javascript:", the
  702. * code is assumed to be a javascript function block rather than arbiturary
  703. * javascript statements.
  704. * @param string option name
  705. * @param string javascript statements.
  706. */
  707. protected function setFunction($name, $code)
  708. {
  709. if(!TJavaScript::isJsLiteral($code))
  710. $code = TJavaScript::quoteJsLiteral($this->ensureFunction($code));
  711. $this->setOption($name, $code);
  712. }
  713. /**
  714. * @return string gets a particular option, null if not set.
  715. */
  716. protected function getOption($name)
  717. {
  718. return $this->_options->itemAt($name);
  719. }
  720. /**
  721. * @param string option name
  722. * @param mixed option value.
  723. */
  724. protected function setOption($name, $value)
  725. {
  726. $this->_options->add($name, $value);
  727. }
  728. /**
  729. * @return TMap gets the list of options as TMap
  730. */
  731. public function getOptions()
  732. {
  733. return $this->_options;
  734. }
  735. /**
  736. * Ensure that the javascript statements are wrapped in a javascript
  737. * function block as <code>function(sender, parameter){ //code }</code>.
  738. */
  739. protected function ensureFunction($javascript)
  740. {
  741. return "function(sender, parameter){ {$javascript} }";
  742. }
  743. }