JqueryEngineHelper.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. <?php
  2. /**
  3. * jQuery Engine Helper for JsHelper
  4. *
  5. * Provides jQuery specific JavaScript for JsHelper.
  6. *
  7. * Implements the JsHelper interface for jQuery. All $options arrays
  8. * support all options found in the JsHelper, as well as those in the jQuery
  9. * documentation.
  10. *
  11. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  12. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  13. *
  14. * Licensed under The MIT License
  15. * For full copyright and license information, please see the LICENSE.txt
  16. * Redistributions of files must retain the above copyright notice.
  17. *
  18. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  19. * @link http://cakephp.org CakePHP(tm) Project
  20. * @package Cake.View.Helper
  21. * @since CakePHP(tm) v 1.3
  22. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  23. */
  24. App::uses('AppHelper', 'View/Helper');
  25. App::uses('JsBaseEngineHelper', 'View/Helper');
  26. /**
  27. * jQuery Engine Helper for JsHelper
  28. *
  29. * Provides jQuery specific JavaScript for JsHelper.
  30. *
  31. * Implements the JsHelper interface for jQuery. All $options arrays
  32. * support all options found in the JsHelper, as well as those in the jQuery
  33. * documentation.
  34. *
  35. * @package Cake.View.Helper
  36. */
  37. class JqueryEngineHelper extends JsBaseEngineHelper {
  38. /**
  39. * Option mappings for jQuery
  40. *
  41. * @var array
  42. */
  43. protected $_optionMap = array(
  44. 'request' => array(
  45. 'type' => 'dataType',
  46. 'before' => 'beforeSend',
  47. 'method' => 'type',
  48. ),
  49. 'sortable' => array(
  50. 'complete' => 'stop',
  51. ),
  52. 'drag' => array(
  53. 'snapGrid' => 'grid',
  54. 'container' => 'containment',
  55. ),
  56. 'drop' => array(
  57. 'leave' => 'out',
  58. 'hover' => 'over'
  59. ),
  60. 'slider' => array(
  61. 'complete' => 'stop',
  62. 'direction' => 'orientation'
  63. )
  64. );
  65. /**
  66. * Callback arguments lists
  67. *
  68. * @var string
  69. */
  70. protected $_callbackArguments = array(
  71. 'slider' => array(
  72. 'start' => 'event, ui',
  73. 'slide' => 'event, ui',
  74. 'change' => 'event, ui',
  75. 'stop' => 'event, ui'
  76. ),
  77. 'sortable' => array(
  78. 'start' => 'event, ui',
  79. 'sort' => 'event, ui',
  80. 'change' => 'event, ui',
  81. 'beforeStop' => 'event, ui',
  82. 'stop' => 'event, ui',
  83. 'update' => 'event, ui',
  84. 'receive' => 'event, ui',
  85. 'remove' => 'event, ui',
  86. 'over' => 'event, ui',
  87. 'out' => 'event, ui',
  88. 'activate' => 'event, ui',
  89. 'deactivate' => 'event, ui'
  90. ),
  91. 'drag' => array(
  92. 'start' => 'event, ui',
  93. 'drag' => 'event, ui',
  94. 'stop' => 'event, ui',
  95. ),
  96. 'drop' => array(
  97. 'activate' => 'event, ui',
  98. 'deactivate' => 'event, ui',
  99. 'over' => 'event, ui',
  100. 'out' => 'event, ui',
  101. 'drop' => 'event, ui'
  102. ),
  103. 'request' => array(
  104. 'beforeSend' => 'XMLHttpRequest',
  105. 'error' => 'XMLHttpRequest, textStatus, errorThrown',
  106. 'success' => 'data, textStatus',
  107. 'complete' => 'XMLHttpRequest, textStatus',
  108. 'xhr' => ''
  109. )
  110. );
  111. /**
  112. * The variable name of the jQuery Object, useful
  113. * when jQuery is put into noConflict() mode.
  114. *
  115. * @var string
  116. */
  117. public $jQueryObject = '$';
  118. /**
  119. * Helper function to wrap repetitive simple method templating.
  120. *
  121. * @param string $method The method name being generated.
  122. * @param string $template The method template
  123. * @param array $options Array of options for method
  124. * @param array $extraSafeKeys Extra safe keys
  125. * @return string Composed method string
  126. */
  127. protected function _methodTemplate($method, $template, $options, $extraSafeKeys = array()) {
  128. $options = $this->_mapOptions($method, $options);
  129. $options = $this->_prepareCallbacks($method, $options);
  130. $callbacks = array_keys($this->_callbackArguments[$method]);
  131. if (!empty($extraSafeKeys)) {
  132. $callbacks = array_merge($callbacks, $extraSafeKeys);
  133. }
  134. $options = $this->_parseOptions($options, $callbacks);
  135. return sprintf($template, $this->selection, $options);
  136. }
  137. /**
  138. * Create javascript selector for a CSS rule
  139. *
  140. * @param string $selector The selector that is targeted
  141. * @return $this
  142. */
  143. public function get($selector) {
  144. if ($selector === 'window' || $selector === 'document') {
  145. $this->selection = $this->jQueryObject . '(' . $selector . ')';
  146. } else {
  147. $this->selection = $this->jQueryObject . '("' . $selector . '")';
  148. }
  149. return $this;
  150. }
  151. /**
  152. * Add an event to the script cache. Operates on the currently selected elements.
  153. *
  154. * ### Options
  155. *
  156. * - 'wrap' - Whether you want the callback wrapped in an anonymous function. (defaults true)
  157. * - 'stop' - Whether you want the event to stopped. (defaults true)
  158. *
  159. * @param string $type Type of event to bind to the current dom id
  160. * @param string $callback The JavaScript function you wish to trigger or the function literal
  161. * @param array $options Options for the event.
  162. * @return string completed event handler
  163. */
  164. public function event($type, $callback, $options = array()) {
  165. $defaults = array('wrap' => true, 'stop' => true);
  166. $options += $defaults;
  167. $function = 'function (event) {%s}';
  168. if ($options['wrap'] && $options['stop']) {
  169. $callback .= "\nreturn false;";
  170. }
  171. if ($options['wrap']) {
  172. $callback = sprintf($function, $callback);
  173. }
  174. return sprintf('%s.bind("%s", %s);', $this->selection, $type, $callback);
  175. }
  176. /**
  177. * Create a domReady event. For jQuery. This method does not
  178. * bind a 'traditional event' as `$(document).bind('ready', fn)`
  179. * Works in an entirely different fashion than `$(document).ready()`
  180. * The first will not run the function when eval()'d as part of a response
  181. * The second will. Because of the way that ajax pagination is done
  182. * `$().ready()` is used.
  183. *
  184. * @param string $functionBody The code to run on domReady
  185. * @return string completed domReady method
  186. */
  187. public function domReady($functionBody) {
  188. return $this->jQueryObject . '(document).ready(function () {' . $functionBody . '});';
  189. }
  190. /**
  191. * Create an iteration over the current selection result.
  192. *
  193. * @param string $callback The function body you wish to apply during the iteration.
  194. * @return string completed iteration
  195. */
  196. public function each($callback) {
  197. return $this->selection . '.each(function () {' . $callback . '});';
  198. }
  199. /**
  200. * Trigger an Effect.
  201. *
  202. * @param string $name The name of the effect to trigger.
  203. * @param array $options Array of options for the effect.
  204. * @return string completed string with effect.
  205. * @see JsBaseEngineHelper::effect()
  206. */
  207. public function effect($name, $options = array()) {
  208. $speed = null;
  209. if (isset($options['speed']) && in_array($options['speed'], array('fast', 'slow'))) {
  210. $speed = $this->value($options['speed']);
  211. }
  212. $effect = '';
  213. switch ($name) {
  214. case 'slideIn':
  215. case 'slideOut':
  216. $name = ($name === 'slideIn') ? 'slideDown' : 'slideUp';
  217. case 'hide':
  218. case 'show':
  219. case 'fadeIn':
  220. case 'fadeOut':
  221. case 'slideDown':
  222. case 'slideUp':
  223. $effect = ".$name($speed);";
  224. break;
  225. }
  226. return $this->selection . $effect;
  227. }
  228. /**
  229. * Create an $.ajax() call.
  230. *
  231. * If the 'update' key is set, success callback will be overridden.
  232. *
  233. * @param string|array $url URL
  234. * @param array $options See JsHelper::request() for options.
  235. * @return string The completed ajax call.
  236. * @see JsBaseEngineHelper::request() for options list.
  237. */
  238. public function request($url, $options = array()) {
  239. $url = html_entity_decode($this->url($url), ENT_COMPAT, Configure::read('App.encoding'));
  240. $options = $this->_mapOptions('request', $options);
  241. if (isset($options['data']) && is_array($options['data'])) {
  242. $options['data'] = $this->_toQuerystring($options['data']);
  243. }
  244. $options['url'] = $url;
  245. if (isset($options['update'])) {
  246. $wrapCallbacks = isset($options['wrapCallbacks']) ? $options['wrapCallbacks'] : true;
  247. $success = '';
  248. if (isset($options['success']) && !empty($options['success'])) {
  249. $success .= $options['success'];
  250. }
  251. $success .= $this->jQueryObject . '("' . $options['update'] . '").html(data);';
  252. if (!$wrapCallbacks) {
  253. $success = 'function (data, textStatus) {' . $success . '}';
  254. }
  255. $options['dataType'] = 'html';
  256. $options['success'] = $success;
  257. unset($options['update']);
  258. }
  259. $callbacks = array('success', 'error', 'beforeSend', 'complete', 'xhr');
  260. if (!empty($options['dataExpression'])) {
  261. $callbacks[] = 'data';
  262. unset($options['dataExpression']);
  263. }
  264. $options = $this->_prepareCallbacks('request', $options);
  265. $options = $this->_parseOptions($options, $callbacks);
  266. return $this->jQueryObject . '.ajax({' . $options . '});';
  267. }
  268. /**
  269. * Create a sortable element.
  270. *
  271. * Requires both Ui.Core and Ui.Sortables to be loaded.
  272. *
  273. * @param array $options Array of options for the sortable.
  274. * @return string Completed sortable script.
  275. * @see JsBaseEngineHelper::sortable() for options list.
  276. */
  277. public function sortable($options = array()) {
  278. $template = '%s.sortable({%s});';
  279. return $this->_methodTemplate('sortable', $template, $options);
  280. }
  281. /**
  282. * Create a Draggable element
  283. *
  284. * Requires both Ui.Core and Ui.Draggable to be loaded.
  285. *
  286. * @param array $options Array of options for the draggable element.
  287. * @return string Completed Draggable script.
  288. * @see JsBaseEngineHelper::drag() for options list.
  289. */
  290. public function drag($options = array()) {
  291. $template = '%s.draggable({%s});';
  292. return $this->_methodTemplate('drag', $template, $options);
  293. }
  294. /**
  295. * Create a Droppable element
  296. *
  297. * Requires both Ui.Core and Ui.Droppable to be loaded.
  298. *
  299. * @param array $options Array of options for the droppable element.
  300. * @return string Completed Droppable script.
  301. * @see JsBaseEngineHelper::drop() for options list.
  302. */
  303. public function drop($options = array()) {
  304. $template = '%s.droppable({%s});';
  305. return $this->_methodTemplate('drop', $template, $options);
  306. }
  307. /**
  308. * Create a Slider element
  309. *
  310. * Requires both Ui.Core and Ui.Slider to be loaded.
  311. *
  312. * @param array $options Array of options for the droppable element.
  313. * @return string Completed Slider script.
  314. * @see JsBaseEngineHelper::slider() for options list.
  315. */
  316. public function slider($options = array()) {
  317. $callbacks = array('start', 'change', 'slide', 'stop');
  318. $template = '%s.slider({%s});';
  319. return $this->_methodTemplate('slider', $template, $options, $callbacks);
  320. }
  321. /**
  322. * Serialize a form attached to $selector. If the current selection is not an input or
  323. * form, errors will be created in the JavaScript.
  324. *
  325. * @param array $options Options for the serialization
  326. * @return string completed form serialization script.
  327. * @see JsBaseEngineHelper::serializeForm() for option list.
  328. */
  329. public function serializeForm($options = array()) {
  330. $options += array('isForm' => false, 'inline' => false);
  331. $selector = $this->selection;
  332. if (!$options['isForm']) {
  333. $selector = $this->selection . '.closest("form")';
  334. }
  335. $method = '.serialize()';
  336. if (!$options['inline']) {
  337. $method .= ';';
  338. }
  339. return $selector . $method;
  340. }
  341. }