1: <?php
  2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23: 
 24: 
 25: App::uses('AppHelper', 'View/Helper');
 26: App::uses('JsBaseEngineHelper', 'View/Helper');
 27: 
 28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38: 
 39: class JqueryEngineHelper extends JsBaseEngineHelper {
 40: 
 41:  42:  43:  44:  45: 
 46:     protected $_optionMap = array(
 47:         'request' => array(
 48:             'type' => 'dataType',
 49:             'before' => 'beforeSend',
 50:             'method' => 'type',
 51:         ),
 52:         'sortable' => array(
 53:             'complete' => 'stop',
 54:         ),
 55:         'drag' => array(
 56:             'snapGrid' => 'grid',
 57:             'container' => 'containment',
 58:         ),
 59:         'drop' => array(
 60:             'leave' => 'out',
 61:             'hover' => 'over'
 62:         ),
 63:         'slider' => array(
 64:             'complete' => 'stop',
 65:             'direction' => 'orientation'
 66:         )
 67:     );
 68: 
 69:  70:  71:  72:  73: 
 74:     protected $_callbackArguments = array(
 75:         'slider' => array(
 76:             'start' => 'event, ui',
 77:             'slide' => 'event, ui',
 78:             'change' => 'event, ui',
 79:             'stop' => 'event, ui'
 80:         ),
 81:         'sortable' => array(
 82:             'start' => 'event, ui',
 83:             'sort' => 'event, ui',
 84:             'change' => 'event, ui',
 85:             'beforeStop' => 'event, ui',
 86:             'stop' => 'event, ui',
 87:             'update' => 'event, ui',
 88:             'receive' => 'event, ui',
 89:             'remove' => 'event, ui',
 90:             'over' => 'event, ui',
 91:             'out' => 'event, ui',
 92:             'activate' => 'event, ui',
 93:             'deactivate' => 'event, ui'
 94:         ),
 95:         'drag' => array(
 96:             'start' => 'event, ui',
 97:             'drag' => 'event, ui',
 98:             'stop' => 'event, ui',
 99:         ),
100:         'drop' => array(
101:             'activate' => 'event, ui',
102:             'deactivate' => 'event, ui',
103:             'over' => 'event, ui',
104:             'out' => 'event, ui',
105:             'drop' => 'event, ui'
106:         ),
107:         'request' => array(
108:             'beforeSend' => 'XMLHttpRequest',
109:             'error' => 'XMLHttpRequest, textStatus, errorThrown',
110:             'success' => 'data, textStatus',
111:             'complete' => 'XMLHttpRequest, textStatus',
112:             'xhr' => ''
113:         )
114:     );
115: 
116: 117: 118: 119: 120: 121: 
122:     public $jQueryObject = '$';
123: 
124: 125: 126: 127: 128: 129: 130: 131: 132: 
133:     protected function _methodTemplate($method, $template, $options, $extraSafeKeys = array()) {
134:         $options = $this->_mapOptions($method, $options);
135:         $options = $this->_prepareCallbacks($method, $options);
136:         $callbacks = array_keys($this->_callbackArguments[$method]);
137:         if (!empty($extraSafeKeys)) {
138:             $callbacks = array_merge($callbacks, $extraSafeKeys);
139:         }
140:         $options = $this->_parseOptions($options, $callbacks);
141:         return sprintf($template, $this->selection, $options);
142:     }
143: 
144: 145: 146: 147: 148: 149: 
150:     public function get($selector) {
151:         if ($selector === 'window' || $selector === 'document') {
152:             $this->selection = $this->jQueryObject . '(' . $selector . ')';
153:         } else {
154:             $this->selection = $this->jQueryObject . '("' . $selector . '")';
155:         }
156:         return $this;
157:     }
158: 
159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 
172:     public function event($type, $callback, $options = array()) {
173:         $defaults = array('wrap' => true, 'stop' => true);
174:         $options += $defaults;
175: 
176:         $function = 'function (event) {%s}';
177:         if ($options['wrap'] && $options['stop']) {
178:             $callback .= "\nreturn false;";
179:         }
180:         if ($options['wrap']) {
181:             $callback = sprintf($function, $callback);
182:         }
183:         return sprintf('%s.bind("%s", %s);', $this->selection, $type, $callback);
184:     }
185: 
186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 
197:     public function domReady($functionBody) {
198:         return $this->jQueryObject . '(document).ready(function () {' . $functionBody . '});';
199:     }
200: 
201: 202: 203: 204: 205: 206: 
207:     public function each($callback) {
208:         return $this->selection . '.each(function () {' . $callback . '});';
209:     }
210: 
211: 212: 213: 214: 215: 216: 217: 218: 
219:     public function effect($name, $options = array()) {
220:         $speed = null;
221:         if (isset($options['speed']) && in_array($options['speed'], array('fast', 'slow'))) {
222:             $speed = $this->value($options['speed']);
223:         }
224:         $effect = '';
225:         switch ($name) {
226:             case 'slideIn':
227:             case 'slideOut':
228:                 $name = ($name === 'slideIn') ? 'slideDown' : 'slideUp';
229:             case 'hide':
230:             case 'show':
231:             case 'fadeIn':
232:             case 'fadeOut':
233:             case 'slideDown':
234:             case 'slideUp':
235:                 $effect = ".$name($speed);";
236:                 break;
237:         }
238:         return $this->selection . $effect;
239:     }
240: 
241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 
251:     public function request($url, $options = array()) {
252:         $url = html_entity_decode($this->url($url), ENT_COMPAT, Configure::read('App.encoding'));
253:         $options = $this->_mapOptions('request', $options);
254:         if (isset($options['data']) && is_array($options['data'])) {
255:             $options['data'] = $this->_toQuerystring($options['data']);
256:         }
257:         $options['url'] = $url;
258:         if (isset($options['update'])) {
259:             $wrapCallbacks = isset($options['wrapCallbacks']) ? $options['wrapCallbacks'] : true;
260:             $success = '';
261:             if (isset($options['success']) && !empty($options['success'])) {
262:                 $success .= $options['success'];
263:             }
264:             $success .= $this->jQueryObject . '("' . $options['update'] . '").html(data);';
265:             if (!$wrapCallbacks) {
266:                 $success = 'function (data, textStatus) {' . $success . '}';
267:             }
268:             $options['dataType'] = 'html';
269:             $options['success'] = $success;
270:             unset($options['update']);
271:         }
272:         $callbacks = array('success', 'error', 'beforeSend', 'complete', 'xhr');
273:         if (!empty($options['dataExpression'])) {
274:             $callbacks[] = 'data';
275:             unset($options['dataExpression']);
276:         }
277:         $options = $this->_prepareCallbacks('request', $options);
278:         $options = $this->_parseOptions($options, $callbacks);
279:         return $this->jQueryObject . '.ajax({' . $options . '});';
280:     }
281: 
282: 283: 284: 285: 286: 287: 288: 289: 290: 
291:     public function sortable($options = array()) {
292:         $template = '%s.sortable({%s});';
293:         return $this->_methodTemplate('sortable', $template, $options);
294:     }
295: 
296: 297: 298: 299: 300: 301: 302: 303: 304: 
305:     public function drag($options = array()) {
306:         $template = '%s.draggable({%s});';
307:         return $this->_methodTemplate('drag', $template, $options);
308:     }
309: 
310: 311: 312: 313: 314: 315: 316: 317: 318: 
319:     public function drop($options = array()) {
320:         $template = '%s.droppable({%s});';
321:         return $this->_methodTemplate('drop', $template, $options);
322:     }
323: 
324: 325: 326: 327: 328: 329: 330: 331: 332: 
333:     public function slider($options = array()) {
334:         $callbacks = array('start', 'change', 'slide', 'stop');
335:         $template = '%s.slider({%s});';
336:         return $this->_methodTemplate('slider', $template, $options, $callbacks);
337:     }
338: 
339: 340: 341: 342: 343: 344: 345: 346: 
347:     public function serializeForm($options = array()) {
348:         $options += array('isForm' => false, 'inline' => false);
349:         $selector = $this->selection;
350:         if (!$options['isForm']) {
351:             $selector = $this->selection . '.closest("form")';
352:         }
353:         $method = '.serialize()';
354:         if (!$options['inline']) {
355:             $method .= ';';
356:         }
357:         return $selector . $method;
358:     }
359: 
360: }
361: