/**
  * {@inheritdoc}
  */
 public function getForm(ViewStorageInterface $view, $display_id, $js)
 {
     $form_state = $this->getFormState($view, $display_id, $js);
     $view = $form_state->get('view');
     $key = $form_state->get('form_key');
     // @todo Remove the need for this.
     \Drupal::moduleHandler()->loadInclude('views_ui', 'inc', 'admin');
     \Drupal::moduleHandler()->loadInclude('views', 'inc', 'includes/ajax');
     // Reset the cache of IDs. Drupal rather aggressively prevents ID
     // duplication but this causes it to remember IDs that are no longer even
     // being used.
     Html::resetSeenIds();
     // check to see if this is the top form of the stack. If it is, pop
     // it off; if it isn't, the user clicked somewhere else and the stack is
     // now irrelevant.
     if (!empty($view->stack)) {
         $identifier = implode('-', array_filter([$key, $view->id(), $display_id, $form_state->get('type'), $form_state->get('id')]));
         // Retrieve the first form from the stack without changing the integer keys,
         // as they're being used for the "2 of 3" progress indicator.
         reset($view->stack);
         list($key, $top) = each($view->stack);
         unset($view->stack[$key]);
         if (array_shift($top) != $identifier) {
             $view->stack = array();
         }
     }
     // Automatically remove the form cache if it is set and the key does
     // not match. This way navigating away from the form without hitting
     // update will work.
     if (isset($view->form_cache) && $view->form_cache['key'] != $key) {
         unset($view->form_cache);
     }
     // With the below logic, we may end up rendering a form twice (or two forms
     // each sharing the same element ids), potentially resulting in
     // _drupal_add_js() being called twice to add the same setting. drupal_get_js()
     // is ok with that, but until \Drupal\Core\Ajax\AjaxResponse::ajaxRender()
     // is (http://drupal.org/node/208611), reset the _drupal_add_js() static
     // before rendering the second time.
     $drupal_add_js_original = _drupal_add_js();
     $drupal_add_js =& drupal_static('_drupal_add_js');
     $form_class = get_class($form_state->getFormObject());
     $response = views_ajax_form_wrapper($form_class, $form_state);
     // If the form has not been submitted, or was not set for rerendering, stop.
     if (!$form_state->isSubmitted() || $form_state->get('rerender')) {
         return $response;
     }
     // Sometimes we need to re-generate the form for multi-step type operations.
     if (!empty($view->stack)) {
         $drupal_add_js = $drupal_add_js_original;
         $stack = $view->stack;
         $top = array_shift($stack);
         // Build the new form state for the next form in the stack.
         $reflection = new \ReflectionClass($view::$forms[$top[1]]);
         /** @var $form_state \Drupal\Core\Form\FormStateInterface */
         $form_state = $reflection->newInstanceArgs(array_slice($top, 3, 2))->getFormState($view, $top[2], $form_state->get('ajax'));
         $form_class = get_class($form_state->getFormObject());
         $form_state->setUserInput(array());
         $form_path = views_ui_build_form_path($form_state);
         if (!$form_state->get('ajax')) {
             return new RedirectResponse(_url($form_path, array('absolute' => TRUE)));
         }
         $form_state->set('path', $form_path);
         $response = views_ajax_form_wrapper($form_class, $form_state);
     } elseif (!$form_state->get('ajax')) {
         // if nothing on the stack, non-js forms just go back to the main view editor.
         $display_id = $form_state->get('display_id');
         return new RedirectResponse($this->url('entity.view.edit_display_form', ['view' => $view->id(), 'display_id' => $display_id], ['absolute' => TRUE]));
     } else {
         $response = new AjaxResponse();
         $response->addCommand(new CloseModalDialogCommand());
         $response->addCommand(new Ajax\ShowButtonsCommand(!empty($view->changed)));
         $response->addCommand(new Ajax\TriggerPreviewCommand());
         if ($page_title = $form_state->get('page_title')) {
             $response->addCommand(new Ajax\ReplaceTitleCommand($page_title));
         }
     }
     // If this form was for view-wide changes, there's no need to regenerate
     // the display section of the form.
     if ($display_id !== '') {
         \Drupal::entityManager()->getFormObject('view', 'edit')->rebuildCurrentTab($view, $response, $display_id);
     }
     return $response;
 }
Example #2
0
 /**
  * {@inheritdoc}
  */
 public function buildOptionsForm(&$form, &$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' => t('Column used for click sorting'), '#options' => array_combine($column_names, $column_names), '#default_value' => $this->options['click_sort_column'], '#description' => 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' => t('Formatter'), '#options' => $formatters, '#default_value' => $this->options['type'], '#ajax' => array('path' => views_ui_build_form_path($form_state)), '#submit' => array(array($this, 'submitTemporaryForm')), '#executes_submit_callback' => TRUE);
     $form['field_api_classes'] = array('#title' => t('Use field template'), '#type' => 'checkbox', '#default_value' => $this->options['field_api_classes'], '#description' => 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'] .= ' ' . t('Checking this option will cause the group Display Type and Separator values to be ignored.');
     }
     // Get the currently selected formatter.
     $format = $this->options['type'];
     $settings = $this->options['settings'] + $this->formatterPluginManager->getDefaultSettings($format);
     $options = array('field_definition' => $field, 'configuration' => array('type' => $format, 'settings' => $settings, 'label' => '', 'weight' => 0), 'view_mode' => '_custom');
     // Get the settings form.
     $settings_form = array('#value' => array());
     if ($formatter = $this->formatterPluginManager->getInstance($options)) {
         $settings_form = $formatter->settingsForm($form, $form_state);
     }
     $form['settings'] = $settings_form;
 }