/[drupal]/contributions/modules/taxonomy_widget/taxonomy_widget.module
ViewVC logotype

Contents of /contributions/modules/taxonomy_widget/taxonomy_widget.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (show annotations) (download) (as text)
Mon Oct 6 19:02:09 2008 UTC (13 months, 2 weeks ago) by shannonlucas
Branch: MAIN
CVS Tags: DRUPAL-5--1-3, HEAD
Changes since 1.3: +2 -2 lines
File MIME type: text/x-php
corrected defaults handling for multi-select options
1 <?php
2 // $Id: taxonomy_widget.module,v 1.3 2008/10/03 16:45:12 shannonlucas Exp $
3 /**
4 * @file
5 * Implements a new form element named 'taxonomy_widget' for selecting a
6 * vocabulary and then a term within that vocabulary. The term list is
7 * dynamically populated by jQuery when a vocabulary is selected.
8 *
9 * The element takes an array for the '#default_value' property with up to
10 * three keyed elements:
11 * - vid contains an integer representing the vocabulary ID. You set this if
12 * you want the list of terms to be pre-populated with terms from a
13 * specific vocabulary.
14 * - tid contains either a single integer or an array of integers
15 * representing the term IDs that should be selected by default in the
16 * element.
17 * - type contains a string with the machine readable name of a specific
18 * type. Set this value when you wish to constrain the list of
19 * vocabularies to those available only to a specific content type.
20 *
21 * Additionally, the element acknowledges the '#multiple' property. If set to
22 * TRUE (default), the term select element will allow multiple terms to be
23 * selected. If set to FALSE, the term select element allow only a single
24 * term to be selected and will be rendered as a drop-down box.
25 *
26 * An example usage of this element could be:
27 * $form['taxonomy-select'] = array(
28 * '#type' => 'taxonomy_widget',
29 * '#default_value' => array(
30 * 'vid' => 15,
31 * 'type' => 'story',
32 * ),
33 * );
34 *
35 * Data returned for this element by the Form API will be an associative array
36 * containing two keys: 'vid' and 'tid'. The value for 'vid' will be the
37 * selected vocabulary's ID. The value type for 'tid' will be depend on whether
38 * the element's '#multiple' property is set to TRUE or FALSE. If set to TRUE,
39 * the value will be an array containing the term IDs of the selected term.
40 * Data returned by this element with '#multiple' set to TRUE will resemble
41 * the following:
42 *
43 * taxonomy-select => Array (
44 * [vid] => 25
45 * [tid] => Array (
46 * [318] => 318
47 * [518] => 518
48 * )
49 * )
50 *
51 * If the element's '#multiple' property is set to FALSE, a single integer
52 * value will be returned for the 'tid'. Data returned by this element with
53 * '#multiple' set to FALSE will resemble the following:
54 *
55 * taxonomy-select => Array (
56 * [vid] => 25
57 * [tid] => 318
58 * )
59 *
60 * NOTE: This widget requires JavaScript to be enabled and does not
61 * gracefully degrade.
62 */
63
64 /** The CSS class for the form elements. */
65 define('TAXONOMY_WIDGET_CSS_TID', 'taxonomy-widget-term');
66
67 /** The CSS class for the form elements. */
68 define('TAXONOMY_WIDGET_CSS_VID', 'taxonomy-widget-vocab');
69
70 /** The CSS class for the wrapping fieldset. */
71 define('TAXONOMY_WIDGET_WRAPPER', 'taxonomy-widget-wrapper');
72
73
74 /**
75 * Implementation of hook_menu().
76 *
77 * @param boolean $may_cache TRUE if this invocation is for cacheable items,
78 * FALSE if not.
79 */
80 function taxonomy_widget_menu($may_cache) {
81 $items = array();
82
83 if (!$may_cache) {
84 $items[] = array(
85 'path' => 'taxonomy/widget/termlist/' . arg(3),
86 'title' => t('Fetch JavaScript Term List'),
87 'callback' => 'taxonomy_widget_termlist',
88 'callback arguments' => array(arg(3)),
89 'access' => user_access('access content'),
90 'type' => MENU_CALLBACK,
91 );
92 }
93
94 return $items;
95 }
96
97
98 /**
99 * Retrieve a flat, JavaScript-friendly list of the terms for the given
100 * vocabulary ID.
101 *
102 * @param int $vid The vocabulary ID to retrieve terms for.
103 */
104 function taxonomy_widget_termlist($vid) {
105 $terms = taxonomy_get_tree($vid);
106 $output = array();
107
108 foreach($terms as $term) {
109 $output[$term->tid] = str_repeat('-', $term->depth) . $term->name;
110 }
111
112 print drupal_to_js($output);
113 exit();
114 }
115
116
117 /**
118 * Implementation of hook_elements().
119 */
120 function taxonomy_widget_elements() {
121 $type = array();
122
123 $type['taxonomy_widget'] = array(
124 '#input' => TRUE,
125 '#process' => array('taxonomy_widget_expand' => array()),
126 '#tree' => TRUE,
127 '#multiple' => TRUE,
128 );
129
130 return $type;
131 }
132
133
134 /**
135 * Render the custom element.
136 *
137 * @param array $element The form element.
138 *
139 * @return string The rendered HTML.
140 */
141 function theme_taxonomy_widget($element) {
142 $wrapper = array(
143 '#type' => 'fieldset',
144 '#title' => empty($element['#title']) ? t('Taxonomy') : $element['#title'],
145 '#collapsible' => FALSE,
146 '#attributes' => array('class' => TAXONOMY_WIDGET_WRAPPER),
147 '#description' => $element['#description'],
148 '#weight' => $elements['#weight'],
149 );
150
151 $vid = theme('select', $element['vid']);
152 $tid = theme('taxonomy_term_select', $element['tid']);
153
154 $wrapper['#children'] = $vid . "\n" . $tid;
155
156 return theme('fieldset', $wrapper);
157 }
158
159
160 /**
161 * Expand the vocabulary-term selector element.
162 *
163 * @param array $element The form element to expand.
164 *
165 * @return array The expanded form element.
166 */
167 function taxonomy_widget_expand($element) {
168 static $vocabs = array();
169
170 $element['#tree'] = TRUE;
171
172 _taxonomy_widget_expand_add_js();
173
174 //---------------------------------------------------------------------------
175 // Set the default value if the caller did not.
176 if (empty($element['#default_value'])) {
177 $element['#default_value'] = array('type' => NULL,
178 'vid' => 0,
179 'tid' => 0);
180 }
181 else {
182 if (empty($element['#default_value']['type'])) {
183 $element['#default_value']['type'] = NULL;
184 }
185 if (empty($element['#default_value']['vid'])) {
186 $element['#default_value']['vid'] = 0;
187 }
188 if (empty($element['#default_value']['tid'])) {
189 $element['#default_value']['tid'] = 0;
190 }
191 }
192
193 //---------------------------------------------------------------------------
194 // Get the vocabulary for the type, if chosen, and add the vocabulary select
195 // box.
196 $type = ($element['#default_value']['type'] !== NULL) ? $element['#default_value']['type'] : '*';
197
198 if (empty($vocabs[$type])) {
199 $vocabs[$type] = ($type == '*') ? taxonomy_get_vocabularies() : taxonomy_get_vocabularies($type);
200 }
201
202 $options = array(0 => t('Select...'));
203 foreach ($vocabs[$type] as $vid => $vocab) {
204 $options[$vid] = $vocab->name;
205 }
206
207 $element['vid'] = array(
208 '#type' => 'select',
209 '#title' => t('Vocabulary'),
210 '#default_value' => $element['#default_value']['vid'],
211 '#options' => $options,
212 '#weight' => 1,
213 '#attributes' => array('class' => TAXONOMY_WIDGET_CSS_VID),
214 );
215
216 //---------------------------------------------------------------------------
217 // Add the term selector. If a specific vocabulary was selected, load its
218 // terms into that selector. If the element is #multiple = FALSE, all
219 // available terms must be loaded in order to pass the default form
220 // validation for single select items.
221 $options = array();
222
223 if ($element['#multiple'] == FALSE) {
224 $options = _taxonomy_widget_get_all_terms();
225 $options[0] = t('Select a vocabulary.');
226 }
227 else {
228 if ($element['#default_value']['vid'] > 0) {
229 $terms = taxonomy_get_tree($element['#default_value']['vid']);
230
231 foreach($terms as $term) {
232 $options[$term->tid] = str_repeat('-', $term->depth) . $term->name;
233 }
234 }
235 else {
236 $options[0] = t('Select a vocabulary.');
237 }
238 }
239
240 $element['tid'] = array(
241 '#type' => 'select',
242 '#title' => t('Term'),
243 '#multiple' => $element['#multiple'],
244 '#size' => $element['#multiple'] ? min(9, max(count($options), 3)) : 0,
245 '#weight' => 3,
246 '#options' => $options,
247 '#default_value' => array_values($element['#default_value']['tid']),
248 '#attributes' => array('class' => TAXONOMY_WIDGET_CSS_TID),
249 '#validate' => array('_taxonomy_widget_tid_validate' => array())
250 );
251
252 return $element;
253 }
254
255
256 /**
257 * Add the necessary JavaScript.
258 */
259 function _taxonomy_widget_expand_add_js() {
260 static $has_added;
261
262 if ($has_added !== TRUE) {
263 $url = url('taxonomy/widget/termlist', NULL, NULL, TRUE);
264 $jscript =
265 '$(document).ready(function() {
266 $(\'select.taxonomy-widget-vocab\').bind(
267 \'change\',
268 {callback: "' . $url .'"},
269 taxonomyWidgetVocabularyChange);
270 $(\'select.taxonomy-widget-vocab\').change();
271 });';
272
273 drupal_add_js(drupal_get_path('module', 'taxonomy_widget') . '/taxonomy_widget.min.js',
274 'module', 'footer', FALSE, TRUE);
275 drupal_add_js($jscript, 'inline', 'footer', FALSE, TRUE);
276
277 $has_added = TRUE;
278 }
279 }
280
281
282 /**
283 * Fetch a list of all the terms currently in the system.
284 *
285 * @return array An associative array mapping term IDs to term names.
286 */
287 function _taxonomy_widget_get_all_terms() {
288 $terms = array();
289
290 $result = db_query('SELECT tid, name FROM {term_data}');
291
292 while ($row = db_fetch_object($result)) {
293 $terms[$row->tid] = $row->name;
294 }
295
296 return $terms;
297 }

  ViewVC Help
Powered by ViewVC 1.1.2