Index: includes/plugins.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/plugins.inc,v retrieving revision 1.152 diff -u -p -r1.152 plugins.inc --- includes/plugins.inc 7 Jan 2009 23:31:12 -0000 1.152 +++ includes/plugins.inc 24 Apr 2009 15:03:54 -0000 @@ -108,7 +108,7 @@ function views_views_plugins() { 'uses row plugin' => TRUE, 'uses options' => TRUE, 'type' => 'normal', - 'help topic' => 'style-list', + 'help topic' => 'style-table', ), 'grid' => array( 'title' => t('Grid'), Index: plugins/views_plugin_style_list.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_style_list.inc,v retrieving revision 1.1 diff -u -p -r1.1 views_plugin_style_list.inc --- plugins/views_plugin_style_list.inc 3 Sep 2008 19:21:30 -0000 1.1 +++ plugins/views_plugin_style_list.inc 24 Apr 2009 15:03:55 -0000 @@ -17,22 +17,163 @@ class views_plugin_style_list extends vi function option_definition() { $options = parent::option_definition(); - $options['type'] = array('default' => 'ul'); + $options['columns'] = array('default' => array()); + $options['default'] = array('default' => ''); + $options['info'] = array('default' => array()); + $options['override'] = array('default' => TRUE); + $options['sticky'] = array('default' => FALSE); + $options['order'] = array('default' => 'asc'); return $options; } /** + * Normalize a list of columns based upon the fields that are + * available. This compares the fields stored in the style handler + * to the list of fields actually in the view, removing fields that + * have been removed and adding new fields in their own column. + * + * - Each field must be in a column. + * - Each column must be based upon a field, and that field + * is somewhere in the column. + * - Any fields not currently represented must be added. + * - Columns must be re-ordered to match the fields. + * + * @param $columns + * An array of all fields; the key is the id of the field and the + * value is the id of the column the field should be in. + * @param $fields + * The fields to use for the columns. If not provided, they will + * be requested from the current display. The running render should + * send the fields through, as they may be different than what the + * display has listed due to access control or other changes. + */ + function sanitize_columns($columns, $fields = NULL) { + $sanitized = array(); + if ($fields === NULL) { + $fields = $this->display->handler->get_option('fields'); + } + + // Preconfigure the sanitized array so that the order is retained. + foreach ($fields as $field => $info) { + // Set to itself so that if it isn't touched, it gets column + // status automatically. + $sanitized[$field] = $field; + } + + foreach ($columns as $field => $column) { + // first, make sure the field still exists. + if (!isset($sanitized[$field])) { + continue; + } + + // If the field is the column, mark it so, or the column + // it's set to is a column, that's ok + if ($field == $column || $columns[$column] == $column && !empty($sanitized[$column])) { + $sanitized[$field] = $column; + } + // Since we set the field to itself initially, ignoring + // the condition is ok; the field will get its column + // status back. + } + + return $sanitized; + } + + /** * Render the given style. */ function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); + $handlers = $this->display->handler->get_handlers('field'); $form['type'] = array( '#type' => 'radios', '#title' => t('List type'), '#options' => array('ul' => t('Unordered list'), 'ol' => t('Ordered list')), '#default_value' => $this->options['type'], ); + + $columns = $this->sanitize_columns($this->options['columns']); + + // Create an array of allowed columns from the data we know: + foreach ($handlers as $field => $handler) { + if ($label = $handler->label()) { + $field_names[$field] = $label; + } + else { + $field_names[$field] = $handler->ui_name(); + } + } + + if (isset($this->options['default'])) { + $default = $this->options['default']; + if (!isset($columns[$default])) { + $default = -1; + } + } + else { + $default = -1; + } + + foreach ($columns as $field => $column) { + $safe = str_replace(array('][', '_', ' '), '-', $field); + // the $id of the column for dependency checking. + $id = 'edit-style-options-columns-' . $safe; + + $form['columns'][$field] = array( + '#type' => 'select', + '#options' => $field_names, + '#default_value' => $column, + ); + if ($handlers[$field]->click_sortable()) { + $form['info'][$field]['sortable'] = array( + '#type' => 'checkbox', + '#default_value' => !empty($this->options['info'][$field]['sortable']), + '#process' => array('views_process_dependency'), + '#dependency' => array($id => array($field)), + ); + // Provide an ID so we can have such things. + $radio_id = form_clean_id('edit-default-' . $field); + $form['default'][$field] = array( + '#type' => 'radio', + '#return_value' => $field, + '#parents' => array('style_options', 'default'), + '#id' => $radio_id, + // because 'radio' doesn't fully support '#id' =( + '#attributes' => array('id' => $radio_id), + '#default_value' => $default, + '#process' => array('views_process_dependency'), + '#dependency' => array($id => array($field)), + ); + } + $form['info'][$field]['separator'] = array( + '#type' => 'textfield', + '#size' => 10, + '#default_value' => isset($this->options['info'][$field]['separator']) ? $this->options['info'][$field]['separator'] : '', + '#process' => array('views_process_dependency'), + '#dependency' => array($id => array($field)), + ); + + // markup for the field name + $form['info'][$field]['name'] = array( + '#value' => $field_names[$field], + ); + } + + // Provide a radio for no default sort + $form['default'][-1] = array( + '#type' => 'radio', + '#return_value' => -1, + '#parents' => array('style_options', 'default'), + '#id' => 'edit-default-0', + '#default_value' => $default, + ); + + $form['description_markup'] = array( + '#prefix' => '