options['id'] . '--' . $row->index . '-->'; } /** * {@inheritdoc} */ public function render(ResultRow $values) { return ViewsRenderPipelineMarkup::create($this->getValue($values)); } /** * Form constructor for the media library select form. * * @param array $form * An associative array containing the structure of the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. */ public function viewsForm(array &$form, FormStateInterface $form_state) { // Only add the bulk form options and buttons if there are results. if (empty($this->view->result)) { return; } // Render checkboxes for all rows. $form[$this->options['id']]['#tree'] = TRUE; foreach ($this->view->result as $row_index => $row) { $entity = $this->getEntity($row); $form[$this->options['id']][$row_index] = [ '#type' => 'checkbox', '#title' => $this->t('Select @label', [ '@label' => $entity->label(), ]), '#title_display' => 'invisible', '#return_value' => $entity->id(), ]; } // @todo Remove in https://www.drupal.org/project/drupal/issues/2504115 // Currently the default URL for all AJAX form elements is the current URL, // not the form action. This causes bugs when this form is rendered from an // AJAX path like /views/ajax, which cannot process AJAX form submits. $url = parse_url($form['#action'], PHP_URL_PATH); $query = \Drupal::request()->query->all(); $query[FormBuilderInterface::AJAX_FORM_REQUEST] = TRUE; $form['actions']['submit']['#ajax'] = [ 'url' => Url::fromUserInput($url), 'options' => [ 'query' => $query, ], 'callback' => [static::class, 'updateWidget'], ]; $form['actions']['submit']['#value'] = $this->t('Select media'); $form['actions']['submit']['#field_id'] = $this->options['id']; } /** * Submit handler for the media library select form. * * @param array $form * An associative array containing the structure of the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. * * @return \Drupal\Core\Ajax\AjaxResponse * A command to send the selection to the current field widget. */ public static function updateWidget(array &$form, FormStateInterface $form_state) { $widget_id = \Drupal::request()->query->get('media_library_widget_id'); if (!$widget_id || !is_string($widget_id)) { throw new BadRequestHttpException('The "media_library_widget_id" query parameter is required and must be a string.'); } $field_id = $form_state->getTriggeringElement()['#field_id']; $selected = array_values(array_filter($form_state->getValue($field_id, []))); // Pass the selection to the field widget based on the current widget ID. return (new AjaxResponse()) ->addCommand(new InvokeCommand("[data-media-library-widget-value=\"$widget_id\"]", 'val', [implode(',', $selected)])) ->addCommand(new InvokeCommand("[data-media-library-widget-update=\"$widget_id\"]", 'trigger', ['mousedown'])) ->addCommand(new CloseDialogCommand()); } /** * {@inheritdoc} */ public function viewsFormValidate(array &$form, FormStateInterface $form_state) { $selected = array_filter($form_state->getValue($this->options['id'])); if (empty($selected)) { $form_state->setErrorByName('', $this->t('No items selected.')); } } /** * {@inheritdoc} */ public function clickSortable() { return FALSE; } }