예제 #1
0
 /**
  * Tests rewriting the #states selectors.
  *
  * @covers ::rewriteStatesSelector
  */
 function testRewriteStatesSelector()
 {
     // Simple selectors.
     $value = array('value' => 'medium');
     $form['foo']['#states'] = array('visible' => array('select[name="fields[foo-id][settings_edit_form][settings][image_style]"]' => $value));
     FormHelper::rewriteStatesSelector($form, 'fields[foo-id][settings_edit_form]', 'options');
     $expected_selector = 'select[name="options[settings][image_style]"]';
     $this->assertSame($form['foo']['#states']['visible'][$expected_selector], $value, 'The #states selector was not properly rewritten.');
     // Complex selectors.
     $form = array();
     $form['bar']['#states'] = array('visible' => array(array(':input[name="menu[type]"]' => array('value' => 'normal')), array(':input[name="menu[type]"]' => array('value' => 'tab')), ':input[name="menu[type]"]' => array('value' => 'default tab')), 'disabled' => array('[name="menu[options][dependee_1]"]' => array('value' => 'ON'), array(array('[name="menu[options][dependee_2]"]' => array('value' => 'ON')), array('[name="menu[options][dependee_3]"]' => array('value' => 'ON'))), array(array('[name="menu[options][dependee_4]"]' => array('value' => 'ON')), 'xor', array('[name="menu[options][dependee_5]"]' => array('value' => 'ON')))));
     $expected['bar']['#states'] = array('visible' => array(array(':input[name="options[type]"]' => array('value' => 'normal')), array(':input[name="options[type]"]' => array('value' => 'tab')), ':input[name="options[type]"]' => array('value' => 'default tab')), 'disabled' => array('[name="options[options][dependee_1]"]' => array('value' => 'ON'), array(array('[name="options[options][dependee_2]"]' => array('value' => 'ON')), array('[name="options[options][dependee_3]"]' => array('value' => 'ON'))), array(array('[name="options[options][dependee_4]"]' => array('value' => 'ON')), 'xor', array('[name="options[options][dependee_5]"]' => array('value' => 'ON')))));
     FormHelper::rewriteStatesSelector($form, 'menu', 'options');
     $this->assertSame($expected, $form, 'The #states selectors were properly rewritten.');
 }
 /**
  * Build the form to let users create the group of exposed filters.
  * This form is displayed when users click on button 'Build group'
  */
 protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form_state)
 {
     if (empty($this->options['exposed']) || empty($this->options['is_grouped'])) {
         return;
     }
     $form['#theme'] = 'views_ui_build_group_filter_form';
     // #flatten will move everything from $form['group_info'][$key] to $form[$key]
     // prior to rendering. That's why the preRender for it needs to run first,
     // so that when the next preRender (the one for fieldsets) runs, it gets
     // the flattened data.
     array_unshift($form['#pre_render'], array(get_class($this), 'preRenderFlattenData'));
     $form['group_info']['#flatten'] = TRUE;
     if (!empty($this->options['group_info']['identifier'])) {
         $identifier = $this->options['group_info']['identifier'];
     } else {
         $identifier = 'group_' . $this->options['expose']['identifier'];
     }
     $form['group_info']['identifier'] = array('#type' => 'textfield', '#default_value' => $identifier, '#title' => $this->t('Filter identifier'), '#size' => 40, '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank.'));
     $form['group_info']['label'] = array('#type' => 'textfield', '#default_value' => $this->options['group_info']['label'], '#title' => $this->t('Label'), '#size' => 40);
     $form['group_info']['description'] = array('#type' => 'textfield', '#default_value' => $this->options['group_info']['description'], '#title' => $this->t('Description'), '#size' => 60);
     $form['group_info']['optional'] = array('#type' => 'checkbox', '#title' => $this->t('Optional'), '#description' => $this->t('This exposed filter is optional and will have added options to allow it not to be set.'), '#default_value' => $this->options['group_info']['optional']);
     $form['group_info']['multiple'] = array('#type' => 'checkbox', '#title' => $this->t('Allow multiple selections'), '#description' => $this->t('Enable to allow users to select multiple items.'), '#default_value' => $this->options['group_info']['multiple']);
     $form['group_info']['widget'] = array('#type' => 'radios', '#default_value' => $this->options['group_info']['widget'], '#title' => $this->t('Widget type'), '#options' => array('radios' => $this->t('Radios'), 'select' => $this->t('Select')), '#description' => $this->t('Select which kind of widget will be used to render the group of filters'));
     $form['group_info']['remember'] = array('#type' => 'checkbox', '#title' => $this->t('Remember'), '#description' => $this->t('Remember the last setting the user gave this filter.'), '#default_value' => $this->options['group_info']['remember']);
     if (!empty($this->options['group_info']['identifier'])) {
         $identifier = $this->options['group_info']['identifier'];
     } else {
         $identifier = 'group_' . $this->options['expose']['identifier'];
     }
     $form['group_info']['identifier'] = array('#type' => 'textfield', '#default_value' => $identifier, '#title' => $this->t('Filter identifier'), '#size' => 40, '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank.'));
     $form['group_info']['label'] = array('#type' => 'textfield', '#default_value' => $this->options['group_info']['label'], '#title' => $this->t('Label'), '#size' => 40);
     $form['group_info']['optional'] = array('#type' => 'checkbox', '#title' => $this->t('Optional'), '#description' => $this->t('This exposed filter is optional and will have added options to allow it not to be set.'), '#default_value' => $this->options['group_info']['optional']);
     $form['group_info']['widget'] = array('#type' => 'radios', '#default_value' => $this->options['group_info']['widget'], '#title' => $this->t('Widget type'), '#options' => array('radios' => $this->t('Radios'), 'select' => $this->t('Select')), '#description' => $this->t('Select which kind of widget will be used to render the group of filters'));
     $form['group_info']['remember'] = array('#type' => 'checkbox', '#title' => $this->t('Remember'), '#description' => $this->t('Remember the last setting the user gave this filter.'), '#default_value' => $this->options['group_info']['remember']);
     $groups = array('All' => $this->t('- Any -'));
     // The string '- Any -' will not be rendered see @theme_views_ui_build_group_filter_form
     // Provide 3 options to start when we are in a new group.
     if (count($this->options['group_info']['group_items']) == 0) {
         $this->options['group_info']['group_items'] = array_fill(1, 3, array());
     }
     // After the general settings, comes a table with all the existent groups.
     $default_weight = 0;
     foreach ($this->options['group_info']['group_items'] as $item_id => $item) {
         if (!$form_state->isValueEmpty(array('options', 'group_info', 'group_items', $item_id, 'remove'))) {
             continue;
         }
         // Each rows contains three widgets:
         // a) The title, where users define how they identify a pair of operator | value
         // b) The operator
         // c) The value (or values) to use in the filter with the selected operator
         // In each row, we have to display the operator form and the value from
         // $row acts as a fake form to render each widget in a row.
         $row = array();
         $groups[$item_id] = $this->t('Grouping @id', array('@id' => $item_id));
         $this->operatorForm($row, $form_state);
         // Force the operator form to be a select box. Some handlers uses
         // radios and they occupy a lot of space in a table row.
         $row['operator']['#type'] = 'select';
         $row['operator']['#title'] = '';
         $this->valueForm($row, $form_state);
         // Fix the dependencies to update value forms when operators changes. This
         // is needed because forms are inside a new form and their IDs changes.
         // Dependencies are used when operator changes from to 'Between',
         // 'Not Between', etc, and two or more widgets are displayed.
         FormHelper::rewriteStatesSelector($row['value'], ':input[name="options[operator]"]', ':input[name="options[group_info][group_items][' . $item_id . '][operator]"]');
         // Set default values.
         $children = Element::children($row['value']);
         if (!empty($children)) {
             foreach ($children as $child) {
                 foreach ($row['value'][$child]['#states']['visible'] as $state) {
                     if (isset($state[':input[name="options[group_info][group_items][' . $item_id . '][operator]"]'])) {
                         $row['value'][$child]['#title'] = '';
                         if (!empty($this->options['group_info']['group_items'][$item_id]['value'][$child])) {
                             $row['value'][$child]['#default_value'] = $this->options['group_info']['group_items'][$item_id]['value'][$child];
                         }
                         // Exit this loop and process the next child element.
                         break;
                     }
                 }
             }
         } else {
             if (isset($this->options['group_info']['group_items'][$item_id]['value']) && $this->options['group_info']['group_items'][$item_id]['value'] != '') {
                 $row['value']['#default_value'] = $this->options['group_info']['group_items'][$item_id]['value'];
             }
         }
         if (!empty($this->options['group_info']['group_items'][$item_id]['operator'])) {
             $row['operator']['#default_value'] = $this->options['group_info']['group_items'][$item_id]['operator'];
         }
         $default_title = '';
         if (!empty($this->options['group_info']['group_items'][$item_id]['title'])) {
             $default_title = $this->options['group_info']['group_items'][$item_id]['title'];
         }
         // Per item group, we have a title that identifies it.
         $form['group_info']['group_items'][$item_id] = array('title' => array('#title' => $this->t('Label'), '#title_display' => 'invisible', '#type' => 'textfield', '#size' => 20, '#default_value' => $default_title), 'operator' => $row['operator'], 'value' => $row['value'], 'remove' => array('#type' => 'checkbox', '#id' => 'views-removed-' . $item_id, '#attributes' => array('class' => array('views-remove-checkbox')), '#default_value' => 0), 'weight' => array('#title' => $this->t('Weight'), '#title_display' => 'invisible', '#type' => 'weight', '#delta' => 10, '#default_value' => $default_weight++, '#attributes' => array('class' => array('weight'))));
     }
     // From all groups, let chose which is the default.
     $form['group_info']['default_group'] = array('#type' => 'radios', '#options' => $groups, '#default_value' => $this->options['group_info']['default_group'], '#required' => TRUE, '#attributes' => array('class' => array('default-radios')));
     // From all groups, let chose which is the default.
     $form['group_info']['default_group_multiple'] = array('#type' => 'checkboxes', '#options' => $groups, '#default_value' => $this->options['group_info']['default_group_multiple'], '#attributes' => array('class' => array('default-checkboxes')));
     $form['group_info']['add_group'] = array('#prefix' => '<div class="views-build-group clear-block">', '#suffix' => '</div>', '#type' => 'submit', '#value' => $this->t('Add another item'), '#submit' => array(array($this, 'addGroupForm')), '#attributes' => array('class' => array('use-ajax-submit')));
     $js = array();
     $js['tableDrag']['views-filter-groups']['weight'][0] = array('target' => 'weight', 'source' => NULL, 'relationship' => 'sibling', 'action' => 'order', 'hidden' => TRUE, 'limit' => 0);
     $js_settings = $form_state->get('js_settings');
     if ($js_settings && is_array($js)) {
         $js_settings = array_merge($js_settings, $js);
     } else {
         $js_settings = $js;
     }
     $form_state->set('js_settings', $js_settings);
 }
예제 #3
0
 /**
  * {@inheritdoc}
  */
 public function buildOptionsForm(&$form, FormStateInterface $form_state)
 {
     parent::buildOptionsForm($form, $form_state);
     $field = $this->getFieldDefinition();
     $formatters = $this->formatterPluginManager->getOptions($field->getType());
     $column_names = array_keys($field->getColumns());
     // If this is a multiple value field, add its options.
     if ($this->multiple) {
         $this->multiple_options_form($form, $form_state);
     }
     // No need to ask the user anything if the field has only one column.
     if (count($field->getColumns()) == 1) {
         $form['click_sort_column'] = array('#type' => 'value', '#value' => isset($column_names[0]) ? $column_names[0] : '');
     } else {
         $form['click_sort_column'] = array('#type' => 'select', '#title' => $this->t('Column used for click sorting'), '#options' => array_combine($column_names, $column_names), '#default_value' => $this->options['click_sort_column'], '#description' => $this->t('Used by Style: Table to determine the actual column to click sort the field on. The default is usually fine.'));
     }
     $form['type'] = array('#type' => 'select', '#title' => $this->t('Formatter'), '#options' => $formatters, '#default_value' => $this->options['type'], '#ajax' => array('url' => views_ui_build_form_url($form_state)), '#submit' => array(array($this, 'submitTemporaryForm')), '#executes_submit_callback' => TRUE);
     $form['field_api_classes'] = array('#title' => $this->t('Use field template'), '#type' => 'checkbox', '#default_value' => $this->options['field_api_classes'], '#description' => $this->t('If checked, field api classes will be added by field templates. This is not recommended unless your CSS depends upon these classes. If not checked, template will not be used.'), '#fieldset' => 'style_settings', '#weight' => 20);
     if ($this->multiple) {
         $form['field_api_classes']['#description'] .= ' ' . $this->t('Checking this option will cause the group Display Type and Separator values to be ignored.');
     }
     // Get the settings form.
     $settings_form = array('#value' => array());
     $format = isset($form_state->getUserInput()['options']['type']) ? $form_state->getUserInput()['options']['type'] : $this->options['type'];
     if ($formatter = $this->getFormatterInstance($format)) {
         $settings_form = $formatter->settingsForm($form, $form_state);
         // Convert field UI selector states to work in the Views field form.
         FormHelper::rewriteStatesSelector($settings_form, "fields[{$field->getName()}][settings_edit_form]", 'options');
     }
     $form['settings'] = $settings_form;
 }
예제 #4
0
 /**
  * {@inheritdoc}
  */
 public function buildOptionsForm(&$form, FormStateInterface $form_state)
 {
     $form['field_rendering'] = array('#type' => 'checkbox', '#title' => $this->t('Use entity field rendering'), '#description' => $this->t("If checked, Drupal's built-in field rendering mechanism will be used for rendering this field's values, which requires the entity to be loaded. If unchecked, a type-specific, entity-independent rendering mechanism will be used."), '#default_value' => $this->options['field_rendering']);
     // Wrap the (immediate) parent options in their own field set, to clean up
     // the UI when (un)checking the above checkbox.
     $form['parent_options'] = array('#type' => 'fieldset', '#title' => $this->t('Render settings'), '#states' => array('visible' => array(':input[name="options[field_rendering]"]' => array('checked' => TRUE))));
     // Include the parent options form and move all fields that were added by
     // our direct parent (\Drupal\views\Plugin\views\field\Field) to the
     // "parent_options" fieldset.
     parent::buildOptionsForm($form, $form_state);
     $parent_keys = array('multiple_field_settings', 'click_sort_column', 'type', 'field_api_classes', 'settings');
     foreach ($parent_keys as $key) {
         if (!empty($form[$key])) {
             $form[$key]['#fieldset'] = 'parent_options';
         }
     }
     // The Core boolean formatter hard-codes the field name to "field_boolean".
     // This breaks the parent class's call of rewriteStatesSelector() for fixing
     // "#states". We therefore apply that behavior again here.
     if (!empty($form['settings'])) {
         FormHelper::rewriteStatesSelector($form['settings'], "fields[field_boolean][settings_edit_form]", 'options');
     }
     // Get the options form for the fallback handler.
     $fallback_form = array();
     $this->fallbackHandler->buildOptionsForm($fallback_form, $form_state);
     // Remove all fields from FieldPluginBase from the fallback form, but leave
     // those in that were only added by our immediate parent,
     // \Drupal\views\Plugin\views\field\Field. (E.g., the "type" option is
     // especially prone to conflicts here.) The others come from the plugin base
     // classes and will be identical, so it would be confusing to include them
     // twice.
     $parent_keys[] = '#pre_render';
     $remove_from_fallback = array_diff_key($form, array_flip($parent_keys));
     $fallback_form = array_diff_key($fallback_form, $remove_from_fallback);
     // Fix the "#states" selectors in the fallback form, and put an additional
     // "#states" directive on it to only be visible for the corresponding
     // "field_rendering" setting.
     if ($fallback_form) {
         FormHelper::rewriteStatesSelector($fallback_form, '"options[', '"options[fallback_options][');
         $form['fallback_options'] = $fallback_form;
         $form['fallback_options']['#type'] = 'fieldset';
         $form['fallback_options']['#title'] = $this->t('Render settings');
         $form['fallback_options']['#states']['visible'][':input[name="options[field_rendering]"]'] = array('checked' => FALSE);
     }
 }