2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4 // +----------------------------------------------------------------------+
5 // | Akelos Framework - http://www.akelos.org |
6 // +----------------------------------------------------------------------+
7 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez |
8 // | Released under the GNU Lesser General Public License, see LICENSE.txt|
9 // +----------------------------------------------------------------------+
14 * @author Bermi Ferrer <bermi a.t akelos c.om>
15 * @author Jerome Loyet
16 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
17 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
21 require_once(AK_LIB_DIR
.DS
.'AkActionView'.DS
.'helpers'.DS
.'tag_helper.php');
22 require_once(AK_LIB_DIR
.DS
.'AkActionView'.DS
.'helpers'.DS
.'form_helper.php');
26 * Provides a set of helpers for creating JavaScript macros that rely on and often bundle methods from JavaScriptHelper into
27 * larger units. These macros are deprecated and will be removed on Akelos 0.9
31 class JavascriptMacrosHelper
extends AkActionViewHelper
35 * Makes an HTML element specified by the DOM ID +field_id+ become an in-place
36 * editor of a property.
38 * A form is automatically created and displayed when the user clicks the element,
39 * something like this:
40 * <form id="myElement-in-place-edit-form" target="specified url">
41 * <input name="value" text="The content of myElement"/>
42 * <input type="submit" value="ok"/>
43 * <a onclick="javascript to cancel the editing">cancel</a>
46 * The form is serialized and sent to the server using an AJAX call, the action on
47 * the server should process the value and return the updated value in the body of
48 * the reponse. The element will automatically be updated with the changed value
49 * (as returned from the server).
51 * Required +options+ are:
52 * <tt>url</tt>:: Specifies the url where the updated value should
53 * be sent after the user presses "ok".
55 * Addtional +options+ are:
56 * <tt>rows</tt>:: Number of rows (more than 1 will use a TEXTAREA)
57 * <tt>cancel_text</tt>:: The text on the cancel link. (default: "cancel")
58 * <tt>save_text</tt>:: The text on the save link. (default: "ok")
59 * <tt>external_control</tt>:: The id of an external control used to enter edit mode.
60 * <tt>options</tt>:: Pass through options to the AJAX call (see prototype's Ajax.Updater)
61 * <tt>with</tt>:: JavaScript snippet that should return what is to be sent
62 * in the AJAX call, +form+ is an implicit parameter
65 function in_place_editor($field_id, $options = array())
67 $function = "new Ajax.InPlaceEditor(";
68 $function .= "'{$field_id}', ";
69 $function .= "'".UrlHelper
::url_for($options['url'])."'";
71 $js_options = array();
72 if (!empty($options['cancel_text'])){
73 $js_options['cancelText'] = AK
::t("{$options['cancel_text']}");
75 if (!empty($options['save_text'])){
76 $js_options['okText'] = AK
::t("{$options['save_text']}");
78 if (!empty($options['rows'])){
79 $js_options['rows'] = $options['rows'];
81 if (!empty($options['external_control'])){
82 $js_options['externalControl'] = $options['external_control'] ;
84 if (!empty($options['options'])){
85 $js_options['ajaxOptions'] = $options['options'];
87 if (!empty($options['with'])){
88 $js_options['callback'] = "function(form) { return {$options['with']} }" ;
90 if (!empty($js_options)) {
91 $function .= (', ' . JavaScriptHelper
::_options_for_javascript($js_options));
95 return JavaScriptHelper
::javascript_tag($function);
100 * Adds AJAX autocomplete functionality to the text input field with the
101 * DOM ID specified by +field_id+.
103 * This function expects that the called action returns a HTML <ul> list,
104 * or nothing if no entries should be displayed for autocompletion.
106 * You'll probably want to turn the browser's built-in autocompletion off,
107 * so be sure to include a autocomplete="off" attribute with your text
110 * The autocompleter object is assigned to a Javascript variable named <tt>field_id</tt>_auto_completer.
111 * This object is useful if you for example want to trigger the auto-complete suggestions through
112 * other means than user input (for that specific case, call the <tt>activate</tt> method on that object).
114 * Required +options+ are:
115 * <tt>url</tt>:: URL to call for autocompletion results
118 * Addtional +options+ are:
119 * <tt>update</tt>:: Specifies the DOM ID of the element whose
120 * innerHTML should be updated with the autocomplete
121 * entries returned by the AJAX request.
122 * Defaults to field_id + '_auto_complete'
123 * <tt>with</tt>:: A JavaScript expression specifying the
124 * parameters for the XMLHttpRequest. This defaults
125 * to 'fieldname=value'.
126 * <tt>indicator</tt>:: Specifies the DOM ID of an element which will be
127 * displayed while autocomplete is running.
128 * <tt>tokens</tt>:: A string or an array of strings containing
129 * separator tokens for tokenized incremental
130 * autocompletion. Example: <tt>tokens => ','</tt> would
131 * allow multiple autocompletion entries, separated
133 * <tt>min_chars</tt>:: The minimum number of characters that should be
134 * in the input field before an Ajax call is made
136 * <tt>on_hide</tt>:: A Javascript expression that is called when the
137 * autocompletion div is hidden. The expression
138 * should take two variables: element and update.
139 * Element is a DOM element for the field, update
140 * is a DOM element for the div from which the
141 * innerHTML is replaced.
142 * <tt>on_show</tt>:: Like on_hide, only now the expression is called
143 * then the div is shown.
144 * <tt>select</tt>:: Pick the class of the element from which the value for
145 * insertion should be extracted. If this is not specified,
146 * the entire element is used.
149 function auto_complete_field($field_id, $options = array())
151 $function = "var {$field_id}_auto_completer = new Ajax.Autocompleter(";
152 $function .= "'{$field_id}', ";
153 $function .= !empty($options['update']) ?
"'{$options['update']}', " : "'{$field_id}_auto_complete', ";
154 $function .= "'".UrlHelper
::url_for($options['url'])."'";
156 $js_options = array();
157 if (!empty($options['tokens'])){
158 $js_options['tokens'] = JavaScriptHelper
::_array_or_string_for_javascript($options['tokens']) ;
160 if (!empty($options['with'])) {
161 $js_options['callback'] = "function(element, value) { return {$options['with']} }";
163 if (!empty($options['indicator'])) {
164 $js_options['indicator'] = "'{$options['indicator']}'";
166 if (!empty($options['select'])) {
167 $js_options['select'] = "'{$options['select']}'";
170 $default_options = array(
171 'on_show' => 'onShow',
172 'on_hide' => 'onHide',
173 'min_chars' => 'min_chars'
176 foreach ($default_options as $key=>$default_option) {
177 if (!empty($options[$key])) {
178 $js_options[$default_option] = $options[$key];
181 $function .= ', '.JavaScriptHelper
::_options_for_javascript($js_options).')';
182 return JavaScriptHelper
::javascript_tag($function);
186 * Use this method in your view to generate a return for the AJAX autocomplete requests.
190 * function auto_complete_for_item_title()
192 * $this->items = $Item->find('all', array('conditions' => array('strtolower($description).' LIKE ?', '%' . strtolower($this->_controller->Request->getRawPostData(). '%' ))))
193 * return $this->_controller->render(array('inline'=> '<?= $javascript_macros->auto_complete_result(@$items, 'description') ?>'));
196 * The auto_complete_result can of course also be called from a view belonging to the
197 * auto_complete action if you need to decorate it further.
201 function auto_complete_result($entries, $field, $phrase = null)
203 if (empty($entries)) {
206 foreach ($entries as $entry) {
207 $items[] = TagHelper
::content_tag('li',!empty($phrase) ? TextHelper
::highlight(TextHelper
::h($entry[$field]), $phrase) : TextHelper
::h(@$entry[$field]));
209 return TagHelper
::content_tag('ul', join('', array_unique($items)));
214 * Wrapper for text_field with added AJAX autocompletion functionality.
216 * In your controller, you'll need to define an action called
217 * auto_complete_for_object_method to respond the AJAX calls,
221 function text_field_with_auto_complete($object, $method, $tag_options = array(), $completion_options = array())
223 if (!isset($tag_options['autocomplete'])) $tag_options['autocomplete'] = "off";
226 !empty($completion_options['skip_style']) ?
"" : $this->_auto_complete_stylesheet()) .
227 $this->_controller
->form_helper
->text_field($object, $method, $tag_options) .
228 TagHelper
::content_tag('div', '', array('id' => "{$object}_{$method}_auto_complete", 'class' => 'auto_complete')) .
229 $this->auto_complete_field("{$object}_{$method}", array_merge(array('url' => array('action' => "auto_complete_for_{$object}_{$method}" )), $completion_options)
237 function _auto_complete_stylesheet()
239 return TagHelper
::content_tag('style',
245 div.auto_complete ul {
246 border:1px solid #888;
250 list-style-type:none;
252 div.auto_complete ul li {
256 div.auto_complete ul li.selected {
257 background-color: #ffb;
259 div.auto_complete ul strong.highlight {