A lot of my clients complain that it's hard to always use the CTRL button and it' so easy to make a mistake. When the list is sometimes 200 values long, it's a pain when you suddenly remember to hold down that button. I've implemented a simple javascript into the nodereferece.module (in 4.7, but I think it should be fairly easy to implement it into 5.x) which makes it possible to select the values without holding down the CTRL button. There 's also a handy 'select all' and 'deselect all' link beneath the select box.

Note: you should look at the MultiSelect module rather than hacking the nodereference module.

Open up the nodereference.module, look for line 192 and add following lines:


if ($field['multiple'] == "1") {
  $extra = '<a href="#" onclick="setall_'.$field['field_name'].'(true); return false">select all</a>
    <a href="#" onclick="setall_'.$field['field_name'].'(false); return false">deselect all</a>

    <script type="text/javascript"><!--
      var list_'.$field['field_name'].' = document.getElementById(\'edit-'.$field["field_name"].'-nids\');
      var savedlist_'.$field['field_name'].' = new Array(list_'.$field["field_name"].'.length);

      function setall_'.$field['field_name'].'(selected) {
        for (var i = list_'.$field["field_name"].'.length - 1; i >= 0; i--) {
          list_'.$field['field_name'].'.options[i].selected = selected;
        }
      }

      function updatelist_'.$field['field_name'].'() {
        for (var i = list_'.$field['field_name'].'.length - 1; i >= 0; i--) {
          list_'.$field['field_name'].'[i].selected = list_'.$field['field_name'].'[i].selected ^ savedlist_'.$field['field_name'].'[i];
        }
      }

      function savelist_'.$field['field_name'].'() {
        for (var i = list_'.$field['field_name'].'.length - 1; i >= 0; i--) {
          savedlist_'.$field['field_name'].'[i] = list_'.$field['field_name'].'[i].selected;
        }
      }
    //--></script>';
  } 
  else { 
    $extra = "";
}

After that, underneath is the form array, replace '$field['widget']['description']' with $extra (or concatenate it) and add 3 lines after the array to add onmousedown and onchange events to the select if it's multiple. It should become something like this.

$form[$field['field_name']]['nids'] = array(
          '#type' => 'select',
          '#title' => t($field['widget']['label']),
          '#default_value' => $node_field['default nids'],
          '#multiple' => $field['multiple'],
          '#options' => $options,
          '#required' => $field['required'],
          '#description' => $extra,
        );
        if ($field['multiple'] == "1") {
          $form[$field['field_name']]['nids']['#attributes'] = array('onmousedown' => 'savelist_'.$field['field_name'].'()','onchange' => 'updatelist_'.$field['field_name'].'()');
        }

You can also add a '#size' to the multiple select, because the select field loses it focus when you click on an option when you have scrolled down in the select box. So count the options and add the size.


$form[$field['field_name']]['nids'] = array(
          '#type' => 'select',
          '#title' => t($field['widget']['label']),
          '#default_value' => $node_field['default nids'],
          '#multiple' => $field['multiple'],
          '#options' => $options,
          '#required' => $field['required'],
          '#description' => $extra,
        );
        if ($field['multiple'] == "1") {
        $form[$field['field_name']]['nids']['#attributes'] = array('onmousedown' => 'savelist_'.$field['field_name'].'()','onchange' => 'updatelist_'.$field['field_name'].'()');
        // make the select box as long as the options, so the scrolling focus is away
        $size = count($options);
        $form[$field['field_name']]['nids']['#size'] = $size;
        }


Happy multiple selecting !
This javascript was inspired by http://labs.mininova.org/simpleselect/

Comments

ksohail’s picture

How can we use this code for selected option,
Means selected="selected"

domidc’s picture