X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=web%2Fcore%2Fmodules%2Fviews%2Fsrc%2FPlugin%2Fviews%2Fstyle%2FTable.php;fp=web%2Fcore%2Fmodules%2Fviews%2Fsrc%2FPlugin%2Fviews%2Fstyle%2FTable.php;h=00e28b3c6dc46bde4276e17c5ac4b1c32465a478;hb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae;hp=0000000000000000000000000000000000000000;hpb=57c063afa3f66b07c4bbddc2d6129a96d90f0aad;p=yaffs-website diff --git a/web/core/modules/views/src/Plugin/views/style/Table.php b/web/core/modules/views/src/Plugin/views/style/Table.php new file mode 100644 index 000000000..00e28b3c6 --- /dev/null +++ b/web/core/modules/views/src/Plugin/views/style/Table.php @@ -0,0 +1,456 @@ + []]; + $options['default'] = ['default' => '']; + $options['info'] = ['default' => []]; + $options['override'] = ['default' => TRUE]; + $options['sticky'] = ['default' => FALSE]; + $options['order'] = ['default' => 'asc']; + $options['caption'] = ['default' => '']; + $options['summary'] = ['default' => '']; + $options['description'] = ['default' => '']; + $options['empty_table'] = ['default' => FALSE]; + + return $options; + } + + /** + * {@inheritdoc} + */ + public function buildSort() { + $order = $this->view->getRequest()->query->get('order'); + if (!isset($order) && ($this->options['default'] == -1 || empty($this->view->field[$this->options['default']]))) { + return TRUE; + } + + // If a sort we don't know anything about gets through, exit gracefully. + if (isset($order) && empty($this->view->field[$order])) { + return TRUE; + } + + // Let the builder know whether or not we're overriding the default sorts. + return empty($this->options['override']); + } + + /** + * Add our actual sort criteria + */ + public function buildSortPost() { + $query = $this->view->getRequest()->query; + $order = $query->get('order'); + if (!isset($order)) { + // check for a 'default' clicksort. If there isn't one, exit gracefully. + if (empty($this->options['default'])) { + return; + } + $sort = $this->options['default']; + if (!empty($this->options['info'][$sort]['default_sort_order'])) { + $this->order = $this->options['info'][$sort]['default_sort_order']; + } + else { + $this->order = !empty($this->options['order']) ? $this->options['order'] : 'asc'; + } + } + else { + $sort = $order; + // Store the $order for later use. + $request_sort = $query->get('sort'); + $this->order = !empty($request_sort) ? strtolower($request_sort) : 'asc'; + } + + // If a sort we don't know anything about gets through, exit gracefully. + if (empty($this->view->field[$sort])) { + return; + } + + // Ensure $this->order is valid. + if ($this->order != 'asc' && $this->order != 'desc') { + $this->order = 'asc'; + } + + // Store the $sort for later use. + $this->active = $sort; + + // Tell the field to click sort. + $this->view->field[$sort]->clickSort($this->order); + } + + /** + * 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. + * + * @return array + * An array of all the sanitized columns. + */ + public function sanitizeColumns($columns, $fields = NULL) { + $sanitized = []; + if ($fields === NULL) { + $fields = $this->displayHandler->getOption('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. + */ + public function buildOptionsForm(&$form, FormStateInterface $form_state) { + parent::buildOptionsForm($form, $form_state); + $handlers = $this->displayHandler->getHandlers('field'); + if (empty($handlers)) { + $form['error_markup'] = [ + '#markup' => '
', + ]; + return; + } + + $form['override'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Override normal sorting if click sorting is used'), + '#default_value' => !empty($this->options['override']), + ]; + + $form['sticky'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Enable Drupal style "sticky" table headers (Javascript)'), + '#default_value' => !empty($this->options['sticky']), + '#description' => $this->t('(Sticky header effects will not be active for preview below, only on live output.)'), + ]; + + $form['caption'] = [ + '#type' => 'textfield', + '#title' => $this->t('Caption for the table'), + '#description' => $this->t('A title semantically associated with your table for increased accessibility.'), + '#default_value' => $this->options['caption'], + '#maxlength' => 255, + ]; + + $form['accessibility_details'] = [ + '#type' => 'details', + '#title' => $this->t('Table details'), + ]; + + $form['summary'] = [ + '#title' => $this->t('Summary title'), + '#type' => 'textfield', + '#default_value' => $this->options['summary'], + '#fieldset' => 'accessibility_details', + ]; + + $form['description'] = [ + '#title' => $this->t('Table description'), + '#type' => 'textarea', + '#description' => $this->t('Provide additional details about the table to increase accessibility.'), + '#default_value' => $this->options['description'], + '#states' => [ + 'visible' => [ + 'input[name="style_options[summary]"]' => ['filled' => TRUE], + ], + ], + '#fieldset' => 'accessibility_details', + ]; + + // Note: views UI registers this theme handler on our behalf. Your module + // will have to register your theme handlers if you do stuff like this. + $form['#theme'] = 'views_ui_style_plugin_table'; + + $columns = $this->sanitizeColumns($this->options['columns']); + + // Create an array of allowed columns from the data we know: + $field_names = $this->displayHandler->getFieldLabels(); + + if (isset($this->options['default'])) { + $default = $this->options['default']; + if (!isset($columns[$default])) { + $default = -1; + } + } + else { + $default = -1; + } + + foreach ($columns as $field => $column) { + $column_selector = ':input[name="style_options[columns][' . $field . ']"]'; + + $form['columns'][$field] = [ + '#title' => $this->t('Columns for @field', ['@field' => $field]), + '#title_display' => 'invisible', + '#type' => 'select', + '#options' => $field_names, + '#default_value' => $column, + ]; + if ($handlers[$field]->clickSortable()) { + $form['info'][$field]['sortable'] = [ + '#title' => $this->t('Sortable for @field', ['@field' => $field]), + '#title_display' => 'invisible', + '#type' => 'checkbox', + '#default_value' => !empty($this->options['info'][$field]['sortable']), + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; + $form['info'][$field]['default_sort_order'] = [ + '#title' => $this->t('Default sort order for @field', ['@field' => $field]), + '#title_display' => 'invisible', + '#type' => 'select', + '#options' => ['asc' => $this->t('Ascending'), 'desc' => $this->t('Descending')], + '#default_value' => !empty($this->options['info'][$field]['default_sort_order']) ? $this->options['info'][$field]['default_sort_order'] : 'asc', + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ':input[name="style_options[info][' . $field . '][sortable]"]' => ['checked' => TRUE], + ], + ], + ]; + // Provide an ID so we can have such things. + $radio_id = Html::getUniqueId('edit-default-' . $field); + $form['default'][$field] = [ + '#title' => $this->t('Default sort for @field', ['@field' => $field]), + '#title_display' => 'invisible', + '#type' => 'radio', + '#return_value' => $field, + '#parents' => ['style_options', 'default'], + '#id' => $radio_id, + // because 'radio' doesn't fully support '#id' =( + '#attributes' => ['id' => $radio_id], + '#default_value' => $default, + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; + } + $form['info'][$field]['align'] = [ + '#title' => $this->t('Alignment for @field', ['@field' => $field]), + '#title_display' => 'invisible', + '#type' => 'select', + '#default_value' => !empty($this->options['info'][$field]['align']) ? $this->options['info'][$field]['align'] : '', + '#options' => [ + '' => $this->t('None'), + 'views-align-left' => $this->t('Left', [], ['context' => 'Text alignment']), + 'views-align-center' => $this->t('Center', [], ['context' => 'Text alignment']), + 'views-align-right' => $this->t('Right', [], ['context' => 'Text alignment']), + ], + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; + $form['info'][$field]['separator'] = [ + '#title' => $this->t('Separator for @field', ['@field' => $field]), + '#title_display' => 'invisible', + '#type' => 'textfield', + '#size' => 10, + '#default_value' => isset($this->options['info'][$field]['separator']) ? $this->options['info'][$field]['separator'] : '', + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; + $form['info'][$field]['empty_column'] = [ + '#title' => $this->t('Hide empty column for @field', ['@field' => $field]), + '#title_display' => 'invisible', + '#type' => 'checkbox', + '#default_value' => isset($this->options['info'][$field]['empty_column']) ? $this->options['info'][$field]['empty_column'] : FALSE, + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; + $form['info'][$field]['responsive'] = [ + '#title' => $this->t('Responsive setting for @field', ['@field' => $field]), + '#title_display' => 'invisible', + '#type' => 'select', + '#default_value' => isset($this->options['info'][$field]['responsive']) ? $this->options['info'][$field]['responsive'] : '', + '#options' => ['' => $this->t('High'), RESPONSIVE_PRIORITY_MEDIUM => $this->t('Medium'), RESPONSIVE_PRIORITY_LOW => $this->t('Low')], + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; + + // markup for the field name + $form['info'][$field]['name'] = [ + '#markup' => $field_names[$field], + ]; + } + + // Provide a radio for no default sort + $form['default'][-1] = [ + '#title' => $this->t('No default sort'), + '#title_display' => 'invisible', + '#type' => 'radio', + '#return_value' => -1, + '#parents' => ['style_options', 'default'], + '#id' => 'edit-default-0', + '#default_value' => $default, + ]; + + $form['empty_table'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Show the empty text in the table'), + '#default_value' => $this->options['empty_table'], + '#description' => $this->t('Per default the table is hidden for an empty view. With this option it is possible to show an empty table with the text in it.'), + ]; + + $form['description_markup'] = [ + '#markup' => '