protected function MediaForm::mediaElement in GridStack 8.2
Returns Media Library form elements adapted from MediaLibraryWidget.
1 call to MediaForm::mediaElement()
- Form::styleForm in src/
Plugin/ gridstack/ stylizer/ Form.php
File
- src/
Plugin/ gridstack/ stylizer/ MediaForm.php, line 273
Class
- MediaForm
- Provides the media form for Layout Builder integration.
Namespace
Drupal\gridstack\Plugin\gridstack\stylizerCode
protected function mediaElement(array &$element, $optionset, FormStateInterface $form_state, array $settings, array $extras = []) {
if (empty($settings['field_name'])) {
return;
}
$data = [];
$media = NULL;
$context = $settings['_scope'];
$delta = $settings['_delta'];
$main = [
'layout_settings',
'settings',
'styles',
];
$extra = [
'layout_settings',
'regions',
$context,
'styles',
];
$parents = $context == GridStackDefault::ROOT ? $main : $extra;
// Add a button that will load the Media library in a modal using AJAX.
// Create an ID suffix from the parents to make sure each widget is unique.
$remaining = 1;
$field_name = $settings['field_name'];
$id_suffix = $parents ? '-' . implode('-', $parents) : '';
$field_widget_id = implode(':', array_filter([
$field_name,
$id_suffix,
]));
$wrapper_id = $field_name . '-media-library-wrapper' . $id_suffix;
$view_builder = $this->manager
->getEntityTypeManager()
->getViewBuilder('media');
$cardinality = $this
->getFieldCardinality($field_name);
// Create a new media library URL with the correct state parameters.
$allowed_media_type_ids = [
'image',
'remote_video',
'video',
];
$selected_type_id = reset($allowed_media_type_ids);
$limit_validation_errors = [
array_merge($parents, [
$field_name,
]),
];
// This particular media library opener needs some extra metadata.
$opener_parameters = [
'field_widget_id' => $field_widget_id,
'entity_type_id' => $extras['entity_type_id'],
'bundle' => $extras['bundle'],
'field_name' => $field_name,
];
$state = MediaLibraryState::create('media_library.opener.field_widget', $allowed_media_type_ids, $selected_type_id, $remaining, $opener_parameters);
$form_state
->set('media_library_state', $state);
$add = $this
->t('Add media');
$mid = $this
->saveMediaId($settings, $form_state);
$target_bundles = isset($this
->getFieldSettings($field_name)['target_bundles']) ? $this
->getFieldSettings($field_name)['target_bundles'] : [];
$element += [
'#type' => 'details',
'#open' => TRUE,
'#tree' => TRUE,
'#title' => $this
->t('Styles'),
'#cardinality' => $cardinality,
'#delta' => $delta,
'#target_bundles' => $target_bundles,
'#attributes' => [
'id' => $wrapper_id,
'class' => [
'js-media-library-widget',
'form-wrapper--styles',
],
],
'#attached' => [
'library' => [
'media_library/widget',
],
],
'#parents' => $parents,
];
if ($optionset
->isFramework()) {
$element['#description'] = $this
->t('Requires <code>Min height</code> at <code>Preset classes</code>, else collapsed.');
}
// Do not use the global current_selection.
$new_settings = self::getUserInputValues($element, $form_state);
if ($new_settings) {
$new_mid = $new_settings['media_library_selection'];
if ($new_mid && $new_mid != $mid) {
$mid = $new_mid;
}
}
// This hidden field and button are used to add new items to the widget.
$element['media_library_selection'] = [
'#type' => 'hidden',
'#attributes' => [
// This is used to pass the selection from the modal to the widget.
'data-media-library-widget-value' => $field_widget_id,
],
];
if (empty($mid)) {
$element['#attributes']['class'][] = 'ig-gs-media-empty';
}
$element['selection'] = [
'#type' => 'container',
'#theme_wrappers' => [
'container__media_library_widget_selection',
],
'#attributes' => [
'class' => [
'js-media-library-selection',
],
],
'#prefix' => '<div class="form-wrapper form-wrapper--media">',
'#field_name' => $field_name,
];
$element['selection'][$delta] = [
'#theme' => 'media_library_item__widget',
'#attributes' => [
'class' => [
'js-media-library-item',
'form-wrapper--media__item',
],
'tabindex' => '-1',
'data-media-library-item-delta' => $delta,
],
];
$element['selection'][$delta]['#field_name'] = $field_name;
$element['selection'][$delta]['thumbnail'] = [];
if ($mid) {
$add = $this
->t('Replace media');
$media = Media::load($mid);
$data = $this
->getMediaData($media);
// @todo Make the view mode configurable.
$element['selection'][$delta]['rendered_entity'] = $view_builder
->view($media, 'media_library');
$element['selection'][$delta]['remove_button'] = [
'#type' => 'submit',
'#name' => $field_name . '-' . $delta . '-media-library-remove-button' . $id_suffix,
'#value' => $this
->t('Remove'),
'#media_id' => $media
->id(),
'#attributes' => [
'aria-label' => $this
->t('Remove @label', [
'@label' => $media
->label(),
]),
'class' => [
'form-submit--gs-remove',
],
'title' => $this
->t('Remove'),
],
'#ajax' => [
'callback' => [
static::class,
'updateWidget',
],
'wrapper' => $wrapper_id,
'progress' => [
'type' => 'throbber',
'message' => $this
->t('Removing @label.', [
'@label' => $media
->label(),
]),
],
],
'#submit' => [
[
static::class,
'removeItem',
],
],
// Prevent errors in other widgets from preventing removal.
'#limit_validation_errors' => $limit_validation_errors,
];
}
$element['selection'][$delta]['target_id'] = [
'#type' => 'hidden',
'#default_value' => $mid,
'#attributes' => [
'data-gs-media-storage' => TRUE,
],
];
// This hidden value can be toggled visible for accessibility.
$element['selection'][$delta]['weight'] = [
'#type' => 'number',
'#theme' => 'input__number__media_library_item_weight',
'#title' => $this
->t('Weight'),
'#default_value' => $delta,
'#attributes' => [
'class' => [
'js-media-library-item-weight',
],
],
];
$element['open_button'] = [
'#type' => 'button',
'#value' => $add,
'#name' => $field_name . '-media-library-open-button' . $id_suffix,
'#attributes' => [
'class' => [
'js-media-library-open-button',
'form-submit--gs-add-replace',
],
// 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',
],
'#media_library_state' => $state,
'#ajax' => [
'callback' => [
MediaLibraryWidget::class,
'openMediaLibrary',
],
'progress' => [
'type' => 'throbber',
'message' => $this
->t('Opening media library.'),
],
],
// Allow the media library to be opened even if there are form errors.
'#limit_validation_errors' => [],
'#attached' => [
'library' => [
'media_library/widget',
],
],
];
// When a selection is made this hidden button is pressed to add new media
// items based on the "media_library_selection" value.
$element['media_library_update_widget'] = [
'#type' => 'submit',
'#value' => $this
->t('Update widget'),
'#name' => $field_name . '-media-library-update' . $id_suffix,
'#ajax' => [
'callback' => [
static::class,
'updateWidget',
],
'wrapper' => $wrapper_id,
'progress' => [
'type' => 'throbber',
'message' => $this
->t('Adding selection.'),
],
],
'#attributes' => [
'data-media-library-widget-update' => $field_widget_id,
'class' => [
'js-hide',
'visually-hidden',
],
],
// @todo '#validate' => [[MediaLibraryWidget::class, 'validateItems']],
'#submit' => [
[
static::class,
'addItems',
],
],
// We need to prevent the widget from being validated when no media items
// are selected. When a media field is added in a subform, entity
// validation is triggered in EntityFormDisplay::validateFormValues().
// Since the media item is not added to the form yet, this triggers errors
// for required media fields.
'#limit_validation_errors' => empty($mid) ? [] : $limit_validation_errors,
];
$element['metadata'] = [
'#type' => 'hidden',
'#default_value' => $data ? Json::encode($data) : '',
'#suffix' => '</div>',
];
}