Commit 05fa2182 authored by alexpott's avatar alexpott

Issue #3035316 by seanB, andrewmacpherson, oknate, phenaproxima, rainbreaw:...

Issue #3035316 by seanB, andrewmacpherson, oknate, phenaproxima, rainbreaw: ‘Add media’ in MediaLibraryWidget should be a button, not a link
parent 5ce9bcd9
......@@ -27,6 +27,7 @@ widget:
js:
js/media_library.widget.js: {}
dependencies:
- core/drupal.dialog.ajax
- core/jquery.ui.sortable
- core/jquery.once
- media_library/style
......
......@@ -9,10 +9,10 @@
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\media\MediaInterface;
use Drupal\media\MediaTypeInterface;
use Drupal\media_library\Ajax\UpdateSelectionCommand;
use Drupal\media_library\MediaLibraryState;
use Drupal\media_library\MediaLibraryUiBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -85,19 +85,17 @@ public function getFormId() {
*
* @return \Drupal\media\MediaTypeInterface
* The media type.
*
* @throws \InvalidArgumentException
* If the selected media type does not exist.
*/
protected function getMediaType(FormStateInterface $form_state) {
if ($this->mediaType) {
return $this->mediaType;
}
$state = $form_state->get('media_library_state');
if (!$state) {
throw new \InvalidArgumentException('The media library state is not present in the form state.');
}
$selected_type_id = $form_state->get('media_library_state')->getSelectedTypeId();
$state = $this->getMediaLibraryState($form_state);
$selected_type_id = $state->getSelectedTypeId();
$this->mediaType = $this->entityTypeManager->getStorage('media_type')->load($selected_type_id);
if (!$this->mediaType) {
......@@ -115,6 +113,14 @@ public function buildForm(array $form, FormStateInterface $form_state) {
$form['#suffix'] = '</div>';
$form['#attached']['library'][] = 'media_library/style';
// The media library is loaded via AJAX, which means that the form action
// URL defaults to the current URL. However, to add media, we always need to
// submit the form to the media library URL, not whatever the current URL
// may be.
$form['#action'] = Url::fromRoute('media_library.ui', [], [
'query' => $this->getMediaLibraryState($form_state)->all(),
])->toString();
// The form is posted via AJAX. When there are messages set during the
// validation or submission of the form, the messages need to be shown to
// the user.
......@@ -420,7 +426,7 @@ public function updateWidget(array &$form, FormStateInterface $form_state) {
// contains the vertical tabs. Besides that, we also need to force the media
// library to create a new instance of the media add form.
// @see \Drupal\media_library\MediaLibraryUiBuilder::buildMediaTypeAddForm()
$state = MediaLibraryState::fromRequest($this->getRequest());
$state = $this->getMediaLibraryState($form_state);
$state->remove('media_library_content');
$state->set('_media_library_form_rebuild', TRUE);
$library_ui = $this->libraryUiBuilder->buildUi($state);
......@@ -431,6 +437,26 @@ public function updateWidget(array &$form, FormStateInterface $form_state) {
return $response;
}
/**
* Get the media library state from the form state.
*
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current form state.
*
* @return \Drupal\media_library\MediaLibraryState
* The media library state.
*
* @throws \InvalidArgumentException
* If the media library state is not present in the form state.
*/
protected function getMediaLibraryState(FormStateInterface $form_state) {
$state = $form_state->get('media_library_state');
if (!$state) {
throw new \InvalidArgumentException('The media library state is not present in the form state.');
}
return $state;
}
/**
* Returns the name of the source field for a media type.
*
......
......@@ -8,9 +8,11 @@
use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
use Drupal\Core\File\Exception\FileWriteException;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\ElementInfoManagerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Url;
use Drupal\file\FileInterface;
use Drupal\file\Plugin\Field\FieldType\FileFieldItemList;
use Drupal\file\Plugin\Field\FieldType\FileItem;
......@@ -113,7 +115,7 @@ protected function buildInputElement(array $form, FormStateInterface $form_state
$item = $this->createFileItem($media_type);
/** @var \Drupal\media_library\MediaLibraryState $state */
$state = $form_state->get('media_library_state');
$state = $this->getMediaLibraryState($form_state);
if (!$state->hasSlotsAvailable()) {
return $form;
}
......@@ -192,6 +194,16 @@ public function processUploadElement(array $element, FormStateInterface $form_st
$element['upload_button']['#ajax'] = [
'callback' => '::updateFormCallback',
'wrapper' => 'media-library-wrapper',
// Add a fixed URL to post the form since AJAX forms are automatically
// posted to <current> instead of $form['#action'].
// @todo Remove when https://www.drupal.org/project/drupal/issues/2504115
// is fixed.
'url' => Url::fromRoute('media_library.ui'),
'options' => [
'query' => $this->getMediaLibraryState($form_state)->all() + [
FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
],
],
];
return $element;
}
......
......@@ -3,7 +3,9 @@
namespace Drupal\media_library\Form;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\media\OEmbed\ResourceException;
use Drupal\media\OEmbed\ResourceFetcherInterface;
use Drupal\media\OEmbed\UrlResolverInterface;
......@@ -121,6 +123,16 @@ protected function buildInputElement(array $form, FormStateInterface $form_state
'#ajax' => [
'callback' => '::updateFormCallback',
'wrapper' => 'media-library-wrapper',
// Add a fixed URL to post the form since AJAX forms are automatically
// posted to <current> instead of $form['#action'].
// @todo Remove when https://www.drupal.org/project/drupal/issues/2504115
// is fixed.
'url' => Url::fromRoute('media_library.ui'),
'options' => [
'query' => $this->getMediaLibraryState($form_state)->all() + [
FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
],
],
],
'#attributes' => [
'class' => ['media-library-add-form-oembed-submit'],
......
......@@ -306,6 +306,12 @@ protected function buildMediaLibraryView(MediaLibraryState $state) {
$args = [$state->getSelectedTypeId()];
// Make sure the state parameters are set in the request so the view can
// pass the parameters along in the pager, filters etc.
$request = $view_executable->getRequest();
$request->query->add($state->all());
$view_executable->setRequest($request);
$view_executable->setDisplay($display_id);
$view_executable->preExecute($args);
$view_executable->execute($display_id);
......
......@@ -2,9 +2,10 @@
namespace Drupal\media_library\Plugin\Field\FieldWidget;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\SortArray;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
......@@ -12,7 +13,6 @@
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Drupal\media\Entity\Media;
use Drupal\media_library\MediaLibraryUiBuilder;
use Drupal\media_library\MediaLibraryState;
......@@ -395,23 +395,32 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
$opener_id = static::$openerIdPrefix . $field_name . $id_suffix;
$state = MediaLibraryState::create($opener_id, $allowed_media_type_ids, $selected_type_id, $remaining);
$dialog_options = Json::encode(MediaLibraryUiBuilder::dialogOptions());
// Add a button that will load the Media library in a modal using AJAX.
$element['media_library_open_button'] = [
'#type' => 'link',
'#title' => $this->t('Add media'),
'#type' => 'submit',
'#value' => $this->t('Add media'),
'#name' => $field_name . '-media-library-open-button' . $id_suffix,
'#url' => $url = Url::fromRoute('media_library.ui', [], [
'query' => $state->all(),
]),
'#attributes' => [
'class' => ['button', 'use-ajax', 'media-library-open-button'],
'data-dialog-type' => 'modal',
'data-dialog-options' => $dialog_options,
'class' => [
'media-library-open-button',
'js-media-library-open-button',
],
// The jQuery UI dialog automatically moves focus to the first :tabbable
// element of the modal, so we need to disable refocus on the button.
'data-disable-refocus' => 'true',
],
// Prevent errors in other widgets from preventing addition.
'#limit_validation_errors' => $limit_validation_errors,
'#media_library_state' => $state,
'#ajax' => [
'callback' => [static::class, 'openMediaLibrary'],
'progress' => [
'type' => 'throbber',
'message' => $this->t('Opening media library.'),
],
],
'#submit' => [],
// Allow the media library to be opened even if there are form errors.
'#limit_validation_errors' => [],
'#access' => $cardinality_unlimited || $remaining > 0,
];
......@@ -526,6 +535,25 @@ public static function removeItem(array $form, FormStateInterface $form_state) {
$form_state->setRebuild();
}
/**
* AJAX callback to open the library modal.
*
* @param array $form
* The form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* An AJAX response to open the media library.
*/
public static function openMediaLibrary(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state->getTriggeringElement();
$library_ui = \Drupal::service('media_library.ui_builder')->buildUi($triggering_element['#media_library_state']);
$dialog_options = MediaLibraryUiBuilder::dialogOptions();
return (new AjaxResponse())
->addCommand(new OpenModalDialogCommand($dialog_options['title'], $library_ui, $dialog_options));
}
/**
* Validates that newly selected items can be added to the widget.
*
......
......@@ -23,7 +23,12 @@ content:
field_twin_media:
type: media_library_widget
weight: 122
settings: { }
settings:
media_types:
- type_three
- type_one
- type_two
- type_four
third_party_settings: { }
region: content
field_single_media_type:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment