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

Contents of /contributions/modules/explainfield/explainfield.module

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


Revision 1.2 - (show annotations) (download) (as text)
Wed Sep 12 13:47:14 2007 UTC (2 years, 2 months ago) by snufkin
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--1
Changes since 1.1: +13 -6 lines
File MIME type: text/x-php
Explain label is configurable.
1 <?php
2 // $Id: explainfield.module,v 1.1 2007/09/12 12:56:44 snufkin Exp $
3
4 /**
5 * Implementation of hook_field_info().
6 */
7 function explainfield_field_info() {
8 return array(
9 'explainfield' => array('label' => 'Explain Field'),
10 );
11 }
12
13 function explainfield_field_settings($op, $field) {
14 switch($op) {
15 case 'form':
16 $form = array();
17 $form['allowed_values'] = array(
18 '#type' => 'textarea',
19 '#title' => t('Allowed values list'),
20 '#default_value' => isset($field['allowed_values']) ? $field['allowed_values'] : '',
21 '#required' => FALSE,
22 '#multiple' => FALSE,
23 '#rows' => 5,
24 '#description' => t('The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database and it must match the field storage type, %type. The label is optional and the key will be used as the label if no label is specified.', array('%type' => $field['type'])),
25 );
26 $form['trigger_value'] = array(
27 '#type' => 'textfield',
28 '#title' => t('Trigger key'),
29 '#default_value' => isset($field['trigger_value']) ? $field['trigger_value'] : '',
30 '#required' => FALSE,
31 '#description' => t('Select the key on which the explain field will trigger'),
32 );
33 $form['explain_options'] = array(
34 '#type' => 'fieldset',
35 '#title' => t('Explain field options'),
36 /*'#collapsible' => TRUE,*/
37 '#collapsed' => FALSE,
38 );
39 $form['explain_options']['explain_label'] = array(
40 '#type' => 'textfield',
41 '#title' => 'Label',
42 '#default_value' => isset($field['explain_label']) ? $field['explain_label'] : '',
43 '#required' => FALSE,
44 '#description' => t('Label that will appear over the explain field, and when viewing the node.'),
45 );
46 $form['explain_options']['explain_text'] = array(
47 '#type' => 'textarea',
48 '#title' => 'Help text for the explain field',
49 '#default_value' => isset($field['explain_text']) ? $field['explain_text'] : '',
50 '#required' => FALSE,
51 '#rows' => 3,
52 '#description' => t('Instructions on what to write into the appearing explain field.'),
53 );
54 $form['explain_options']['max_length'] = array(
55 '#type' => 'textfield',
56 '#title' => t('Maximum length'),
57 '#default_value' => isset($field['max_length']) ? $field['max_length'] : '',
58 '#required' => FALSE,
59 '#description' => t('The maximum length of the field in characters. Leave blank for an unlimited size.'),
60 );
61 $form['explain_options']['explain_rows'] = array(
62 '#type' => 'textfield',
63 '#title' => t('Textfield size'),
64 '#default)value' => isset($field['explain_rows']) ? $field['explain_rows'] : '',
65 '#required' => FALSE,
66 '#description' => t('The height of the explain field. Leave blank for default 3.'),
67 );
68 return $form;
69 case 'save':
70 return array('allowed_values', 'trigger_value', 'explain_text', 'explain_rows', 'explain_label', 'max_length');
71 case 'database columns':
72 $columns = array(
73 'value' => array('type' => 'longtext', 'not null' => TRUE, 'default' => "''", 'sortable' => TRUE),
74 'explainfield' => array('type' => 'longtext', 'not null' => TRUE, 'default' => "''", 'sortable' => TRUE),
75 );
76 return $columns;
77 case 'validate':
78 if( ($field['field_name'] == 'field_explainfield') && ($field['required'] == 0)) break;
79 elseif ( $field['field_name'] == 'field_explainfield' ) {
80 $trigger = $field['trigger_value'];
81 /* Check if trigger is set correctly */
82 $values = explode("\n", $field['allowed_values']);
83 foreach($values as $n => $line) {
84 $values[$n] = explode('|', $line);
85 $keys[] = $values[$n][0];
86 }
87 if(!in_array($trigger, $keys) ) {
88 form_set_error('trigger_value', t('Incorrect trigger key is set.'));
89 }
90 break;
91 }
92 case 'filters':
93 return array(
94 'substring' => array(
95 'operator' => 'views_handler_operator_like',
96 'handler' => 'views_handler_filter_like',
97 ),
98 'alpha_order' => array(
99 'name' => 'alphabetical order',
100 'operator' => 'views_handler_operator_gtlt',
101 ),
102 );
103
104 }
105 }
106
107 /**
108 * Implementation of hook_field_formatter_info().
109 */
110 function explainfield_field_formatter_info() {
111 return array(
112 'default' => array(
113 'label' => 'Default',
114 'field types' => array('explainfield'),
115 ),
116 'replace' => array(
117 'label' => 'Replace with explanation',
118 'field types' => array('explainfield'),
119 ),
120 'valueonly' => array(
121 'label' => 'Value only',
122 'field types' => array('explainfield'),
123 ),
124 'explanation' => array(
125 'label' => 'Explanation only',
126 'field types' => array('explainfield'),
127 ),
128 );
129 }
130
131 /**
132 * Implementation of hook_field_formatter().
133 *
134 * The $node argument is necessary so that filter access can be checked on
135 * node preview.
136 */
137 function explainfield_field_formatter($field, $item, $formatter, $node) {
138 if (!isset($item['value'])) {
139 return '';
140 }
141
142 if ($allowed_values = explainfield_allowed_values($field)) {
143 $values = $allowed_values[$item['value']];
144 }
145
146 switch ($formatter) {
147 case 'valueonly':
148 unset($item['explainfield']);
149 $text = strip_tags($values);
150 break;
151
152 case 'default':
153 $explanation = !empty($item['explainfield']) ?
154 '<div class="field-label">' . $field['explain_label'] . ': </div><div class="field-items">'. check_plain($item['explainfield']) . '</div>' : '';
155 $text = $values . $explanation;
156 break;
157
158 case 'replace':
159 $explanation = !empty($item['explainfield']) ? check_plain($item['explainfield']) : '';
160
161 /** If the key is the trigger key output the explanation only. In this case
162 * $explanation is set, because we validate for this at form submission
163 */
164 if($item['value'] == $field['trigger_value']) { $text = $explanation; }
165 else {
166 $text = $values;
167 }
168 break;
169 case 'explanation':
170 $text = check_plain($item['explainfield']);
171 break;
172 }
173
174 return $text;
175 /*return check_plain($text);*/
176 }
177
178 function explainfield_field($op, &$node, $field, &$items, $teaser, $page) {
179 switch($op) {
180 case 'validate':
181 if ($field['max_length'] > 0) {
182 foreach ($items as $delta => $data) {
183 $error_field = $field['field_name'] .']['. $delta .'][value';
184 if (strlen($data['explainfield']) > $field['max_length']) {
185 form_set_error($error_field, t('There is a limit of %max characters on %label.', array('%max' => $field['max_length'], '%label' => $field['widget']['label'] )));
186 }
187 }
188 }
189 break;
190 }
191 }
192
193
194 /**
195 * Implementation of hook_widget_info().
196 */
197 function explainfield_widget_info() {
198 $option_types = array('explainfield',);
199 return array(
200 'explainfield_select' => array(
201 'label' => 'Explainfield in select list',
202 'field types' => $option_types,
203 ),
204 'explainfield_buttons' => array(
205 'label' => 'Explainfield in list of check boxes/radio buttons',
206 'field types' => $option_types,
207 ),
208 );
209 }
210
211 /**
212 * Implementation of hook_widget_settings().
213 */
214 function explainfield_widget_settings() {
215 }
216
217 /**
218 * Implementation of hook_widget().
219 */
220 function explainfield_widget($op, &$node, $field, &$items) {
221 switch ($op) {
222 case 'prepare form values':
223 $options = _explainfield_options($field, $node);
224 $items_transposed = content_transpose_array_rows_cols($items);
225 $values = (isset($items_transposed['value']) && is_array($items_transposed['value'])) ? $items_transposed['value'] : array();
226 $explains = (isset($items_transposed['explainfield']) && is_array($items_transposed['explainfield'])) ? $items_transposed['explainfield'] : array();
227
228 $keys = array();
229 foreach ($values as $value) {
230 $key = array_search($value, array_keys($options));
231 if (isset($key)) {
232 $keys[] = $value;
233 }
234 }
235 $explainfields = array();
236 foreach ($explains as $text) {
237 if (isset($text) && !(empty($text))) {
238 $explainfields[] = $text;
239 }
240 }
241 if ($field['multiple'] || $field['widget']['type'] == 'explainfield_onoff') {
242 $items['default keys'] = $keys;
243 $items['default explain'] = reset($explainfields);
244 }
245 else {
246 $items['default key'] = reset($keys);
247 $items['default explain'] = $items[0]['explainfield'];
248 }
249 break;
250
251 case 'form':
252 $options = _explainfield_options($field, $node);
253
254 $form = array();
255
256 $form[$field['field_name']] = array('#tree' => TRUE);
257
258 switch ($field['widget']['type']) {
259 case 'explainfield_select':
260 /* JavaScript for select */
261 $extra_select = '
262 <script language="javascript">
263 $(document).ready(function() {
264
265 if( $("select#edit-'._misc_formize($field['field_name']).'-key").val() != \''.$field['trigger_value'] . '\') { $("#explainfield-'._misc_formize($field['field_name']).'").hide(); }
266
267 $("select#edit-'._misc_formize($field['field_name']).'-key").change( function () {
268 if ( $(this).val() == \''.$field['trigger_value'] . '\') { $("#explainfield-'._misc_formize($field['field_name']).'").show(); }
269 else { $("#explainfield-'._misc_formize($field['field_name']).'").hide(); }
270 });
271
272 });
273 </script>';
274 $form[$field['field_name']]['key'] = array(
275 '#type' => 'select',
276 '#title' => t($field['widget']['label']),
277 '#default_value' => $items['default key'],
278 '#multiple' => FALSE,
279 '#options' => $options,
280 '#required' => $field['required'],
281 '#description' => t($field['widget']['description']) . $extra_select,
282 );
283 $form[$field['field_name']]['explain'] = array(
284 '#type' => 'textarea',
285 '#title' => t($field['explain_label']),
286 '#default_value' => $items['default explain'],
287 '#rows' => isset($field['explain_rows']) ? $field['explain_rows'] : 3,
288 '#prefix' => '<div id="explainfield-'._misc_formize($field['field_name']).'">',
289 '#suffix' => '</div>',
290 '#description' => t($field['explain_text']),
291 );
292 break;
293
294 case 'explainfield_buttons':
295 if ($field['multiple']) {
296 /* JavaScript for checkbox */
297 $extra = '
298 <script language="javascript">
299 $(document).ready(function() {
300 if( !$("#edit-'._misc_formize($field['field_name']).'-keys-'.$field['trigger_value'].'").is(":checked")) {
301 $("#explainfield-'._misc_formize($field['field_name']).'").hide();
302 }
303
304 $(\'input[@type="checkbox"]\').click( function () {
305 if( $("#edit-'._misc_formize($field['field_name']).'-keys-'.$field['trigger_value'].'").is(":checked")) {
306 $("#explainfield-'._misc_formize($field['field_name']).'").show();
307 }
308
309 else {
310 $("#explainfield-'._misc_formize($field['field_name']).'").hide();
311 }
312 $(this).blur();
313 });
314
315 });
316 </script>';
317 $form[$field['field_name']]['keys'] = array(
318 '#type' => 'checkboxes',
319 '#title' => t($field['widget']['label']),
320 '#default_value' => $items['default keys'],
321 '#options' => $options,
322 '#required' => $field['required'],
323 '#description' => t($field['widget']['description']) . $extra,
324 );
325 }
326 else {
327
328 /* JavaScript for radiobuttons */
329 $extra = '
330 <script language="javascript">
331 $(document).ready(function() {
332
333 if( $(\'input[@type="radio"][@checked]\').val() != \''.$field['trigger_value'].'\') {
334 $("#explainfield-'._misc_formize($field['field_name']).'").hide();
335 }
336
337 $(\'input[@type="radio"][@name="'.$field['field_name'].'[key]"]\').click( function () {
338 if ( $(this).attr(\'value\') == \''.$field['trigger_value'] . '\') { $("#explainfield-'._misc_formize($field['field_name']).'").show(); }
339 else { $("#explainfield-'._misc_formize($field['field_name']).'").hide(); }
340 $(this).blur();
341 });
342
343 });
344 </script>';
345 $form[$field['field_name']]['key'] = array(
346 '#type' => 'radios',
347 '#prefix' => '<div id="#edit-field-'. _misc_formize($field['widget']['label']) .'-keys">',
348 '#suffix' => '</div>',
349 '#title' => t($field['widget']['label']),
350 '#default_value' => $items['default key'],
351 '#options' => $options,
352 '#required' => $field['required'],
353 '#description' => t($field['widget']['description']) . $extra,
354 );
355 }
356 $form[$field['field_name']]['explain'] = array(
357 '#type' => 'textarea',
358 '#title' => t($field['explain_label']),
359 '#default_value' => $items['default explain'],
360 '#rows' => isset($field['explain_rows']) ? $field['explain_rows'] : 3,
361 '#prefix' => '<div id="explainfield-'._misc_formize($field['field_name']).'">',
362 '#suffix' => '</div>',
363 '#description' => t($field['explain_text']),
364 );
365 break;
366 }
367 return $form;
368 case 'validate':
369 /** We can't set the explain field to required, because it belongs to the options. E.g. if
370 * the user is on a non-trigger field it complains about the field being not filled.
371 * Need to validate manually.
372 */
373
374 if(_explainfield_is_trigger_fieldcheck($items,$field)) {
375 $error_field = isset($item['error_field']) ? $item['error_field'] : $field['field_name'];
376 form_set_error($error_field, t('Please fill the optional form in %label if you select this option.', array('%label' => t($field['widget']['label'])) ));
377 }
378 break;
379
380 case 'process form values':
381 $options = _explainfield_options($field, $node);
382 $explanation = $items['explain'];
383
384 if ($field['multiple'] || $field['widget']['type'] == 'explainfield_onoff') {
385 $keys = (array) $items['keys'];
386 }
387 else {
388 $keys = array($items['key']);
389 }
390
391 $values = array();
392 foreach ($keys as $key) {
393 if (isset($options[$key])) {
394 $values[] = $key;
395 }
396 }
397
398 $items = content_transpose_array_rows_cols(array('value' => $values));
399
400 /* Only save explanation when it is necessary (the field exists all along) */
401 if( $delta = _explainfield_is_trigger($items, $field) ) {
402 $items[$delta-1]['explainfield'] = $explanation;
403 }
404
405 // Remove the widget's data representation so it isn't saved.
406 unset($items['keys']);
407 unset($items['key']);
408 break;
409 }
410 }
411
412 function _explainfield_options($field, $node) {
413 $types = _content_field_types();
414 $field_allowed_values = $types[$field['type']]['module'] .'_allowed_values';
415 if (function_exists($field_allowed_values)) {
416 $allowed_values = $field_allowed_values($field);
417 }
418 else {
419 $allowed_values = array();
420 }
421
422 if ($field['widget']['type'] == 'explainfield_select' ||
423 ($field['widget']['type'] == 'explainfield_buttons' && !$field['multiple'])) {
424 if (!$field['required']) {
425 $allowed_values = array('' => theme('explainfield_none', $field['widget']['type'], $field['field_name'], $node->type)) + $allowed_values;
426 }
427 }
428
429 return $allowed_values;
430 }
431
432 /**
433 * Function returns the $delta + 1 (so we spare return 0 for false) if trigger is set,
434 * where $delta means where it is set
435 */
436 function _explainfield_is_trigger($items, $field) {
437 $trigger = $field['trigger_value'];
438 if($field['multiple']) {
439 foreach($items as $delta => $values) {
440 if($values['value'] == $trigger) return $delta+1;
441 }
442 }
443 else {
444 if($items[0]['value'] == $trigger) return 1;
445 }
446 return false;
447 }
448
449 /**
450 * Function returns true if the trigger is set, but the extra textfield is empty
451 */
452 function _explainfield_is_trigger_fieldcheck($items, $field) {
453 $trigger = $field['trigger_value'];
454 if(empty($items['key']) && empty($items['explain'])) { return false;}
455 if($field['multiple']) {
456 if( in_array($trigger, $items['keys']) && empty($items['explain']) ) {
457 return true;
458 }
459 }
460 else if( in_array($trigger, $items) && empty($items['explain']) ) {
461 return true;
462 }
463
464 else return false;
465 }
466
467 /**
468 * Theme the label for the empty value for options that are not required.
469 * The default theme will display N/A for a radio list and blank for a select.
470 */
471 function theme_explainfield_none($widget_type, $field_name, $node_type) {
472 switch ($widget_type) {
473 case 'explainfield_buttons':
474 return t('N/A');
475 default :
476 return '';
477 }
478 }
479
480 /**
481 * Create an array of the allowed values for this field
482 */
483 function explainfield_allowed_values($field) {
484 static $allowed_values;
485
486 if ($allowed_values[$field['field_name']]) {
487 return $allowed_values[$field['field_name']];
488 }
489
490 $allowed_values[$field['field_name']] = array();
491 if ($field['allowed_values_php']) {
492 ob_start();
493 $result = eval($field['allowed_values_php']);
494 if (is_array($result)) {
495 $allowed_values[$field['field_name']] = $result;
496 }
497 ob_end_clean();
498 }
499 if (!$allowed_values[$field['field_name']]) {
500
501 $list = explode("\n", $field['allowed_values']);
502 $list = array_map('trim', $list);
503 $list = array_filter($list, 'strlen');
504 foreach ($list as $opt) {
505 list($key, $value) = explode('|', $opt);
506 $allowed_values[$field['field_name']][$key] = $value ? $value : $key;
507 }
508 }
509
510 return $allowed_values[$field['field_name']];
511 }
512
513 function _misc_formize($string) {
514 return strtolower(str_replace('_', '-', $string));
515 }

  ViewVC Help
Powered by ViewVC 1.1.2