'.t("Provides an easy to use control for adding multiple items.").'

'; break; } return $output; } /** * Implementation of hook_perm * @todo Need to check permissions make sense */ function multiselect_perm() { return array('access multiselect_module'); //? } /** * Implementation of hook_widget_info. * Specifies the label and that it is a widget for the nodereference field type */ function multiselect_widget_info() { return array( 'multiselect_select' => array( 'label' => t('Multiselect List'), 'field types' => array('nodereference'), ), ); } /** * Implementation of hook_widget * @todo Is the if ($field['widget']['type'] == 'multiselect_select' necessary? * @todo Doesn't seem to populate list when in 'preview' (see http://drupal.org/node/139595) */ function multiselect_widget($op, &$node, $field, &$node_field) { //necessary to get list of nodes that can be included in this nodereference include_once(drupal_get_path('module', 'content').'/nodereference.module'); if ($field['widget']['type'] == 'multiselect_select') { switch ($op) { case 'prepare form values': //puts node_field (original) values into a temporary bit of the array called default nids $node_field_transposed = content_transpose_array_rows_cols($node_field); $node_field['default nids'] = $node_field_transposed['nid']; break; case 'form': //generates form object $form = array(); $selectedoptions = array(); $notselectedoptions = array(); //gets list of all nodes we can reference $options = _nodereference_potential_references($field, true); //if we're only allowed to select a single item (multiple is disabled) generate a different widget if (!$field['multiple']) { $newoptions = array(); foreach ($options as $key => $value) { $newoptions[$key] = _nodereference_item($field, $value); } if (!$field['required']) { $newoptions = array(0 => t('')) + $newoptions; } $form[$field['field_name']] = array('#tree' => TRUE); $form[$field['field_name']]['nids'] = array( '#type' => 'select', '#title' => t($field['widget']['label']), '#default_value' => $node_field['default nids'], '#multiple' => $field['multiple'], '#size' => $field['multiple'] ? min(count($newoptions), 6) : 0, '#options' => $newoptions, '#required' => $field['required'], '#description' => $field['widget']['description'], ); return $form; }//end of if single-item only //inserts javascript $path = drupal_get_path('module','multiselect'); drupal_add_js($path . '/multiselect.js'); //insert CSS (based on http://www.lullabot.com/articles/how_to_properly_add_css_files) //but http://drupal.org/node/60096 says to use theme_add_style, but this fn doesn't exist, so using... drupal_add_css($path . '/multiselect.css','module','all',FALSE); //doesn't aggregate: as it's not used much(?) //for each node, check if it's already selected. If it is, add it to the selected list foreach ($options as $key => $value) { $inarray = FALSE; if (is_array($node_field['default nids'])) { foreach($node_field['default nids'] as $n => $nid) { if ($nid == $key) { $inarray = TRUE; } } } if ($inarray) { $selectedoptions[$key] = _nodereference_item($field, $value); } else { $notselectedoptions[$key] = _nodereference_item($field, $value); } } //useful variables $fieldname=$field['field_name']; $addbutton=$fieldname."_add"; $removebutton=$fieldname."_remove"; $selfield=$fieldname."_sel"; $unselfield=$fieldname."_unsel"; //call methods to create prefix (ie the non-selected table, etc) $prefix = ''; $prefix.= '
"; $prefix.= "\n
"; $prefix.= _html_for_notselected_box($notselectedoptions, $unselfield, $fieldname); $prefix.= _html_for_buttons($fieldname); //create the form item $form[$fieldname] = array('#tree' => TRUE); $form[$fieldname]['nids'] = array( '#type' => 'select', '#options' => $selectedoptions, '#size' => 10, '#prefix' => $prefix, '#suffix' => "\n
\n", '#multiple' => TRUE, '#attributes' => array('class' => "$selfield multiselect_sel", 'id' => $fieldname), '#default_value' => $node_field['default nids'], ); //return the form array return $form; case 'process form values': //Replace the node values if ($field['multiple']) { $node_field = content_transpose_array_rows_cols(array('nid' => $node_field['nids'])); } else { $node_field[0]['nid'] = $node_field['nids']; } unset($node_field['nids']);//removes widgets data representation, so it's not saved. //(unknown purpose, but nodereference.module has this code so we should too...) foreach($node_field as $delta => $item) { $node_field[$delta]['error_field'] = $field['field_name'].'][nids'; } break; case 'submit': break; } } } /** * Provides html to display the buttons on the form * @todo could I do this by putting items in the form array? (or would that be too complicated?) */ function _html_for_buttons($fieldname) { $path = base_path(); $path.= drupal_get_path('module','multiselect'); $path.= "/images"; $addremovebuttons = "\n\n"; $addremovebuttons.= "\n\n"; return $addremovebuttons; } /** * Provides html to draw the not selected box */ function _html_for_notselected_box($notselectedoptions, $unselfield, $fieldname) { $boxhtml = '
'; $boxhtml.= "\n"; $boxhtml.= "
\n"; return $boxhtml; } /** * Implementation of hook_nodeapi. * @todo The adding of javascript can be moved to the _widget function. */ function multiselect_nodeapi(&$node, $op, $teaser, $page) { /* switch ($op) { case 'prepare': }*/ } ?>