Commit 2f2f9f5c authored by git's avatar git Committed by chr.fritsch

Issue #2823670 by mtodor: Improved MultiStep selection display (DropZone Widget)

parent 55c31580
......@@ -5,6 +5,9 @@ entity_browser.browser.widget.dropzonejs:
submit_text:
type: string
label: 'Submit button text'
auto_select:
type: boolean
label: 'Automatically submit selection'
upload_location:
type: string
label: 'Upload location'
......@@ -28,6 +31,9 @@ entity_browser.browser.widget.dropzonejs_media_entity:
submit_text:
type: string
label: 'Submit button text'
auto_select:
type: boolean
label: 'Automatically submit selection'
upload_location:
type: string
label: 'Upload location'
......
......@@ -31,7 +31,41 @@
if (item.instance.getRejectedFiles().length === 0) {
$submit.removeAttr('disabled');
}
// If there are no files in DropZone -> disable Button.
if (item.instance.getAcceptedFiles().length === 0) {
$submit.prop('disabled', true);
}
});
if (drupalSettings.entity_browser_widget && drupalSettings.entity_browser_widget.auto_select) {
item.instance.on('queuecomplete', function () {
var dzInstance = item.instance;
var filesInQueue = dzInstance.getQueuedFiles();
var acceptedFiles;
var i;
if (filesInQueue.length === 0) {
acceptedFiles = dzInstance.getAcceptedFiles();
// Ensure that there are some files that should be submitted.
if (acceptedFiles.length > 0 && dzInstance.getUploadingFiles().length === 0) {
// First submit accepted files and clear them from list of
// dropped files afterwards.
jQuery(dzInstance.element)
.parent()
.siblings('[name="auto_select_handler"]')
.trigger('auto_select_enity_browser_widget');
// Remove accepted files -> because they are submitted.
for (i = 0; i < acceptedFiles.length; i++) {
dzInstance.removeFile(acceptedFiles[i]);
}
}
}
});
}
}
});
}
......
......@@ -4,6 +4,8 @@ namespace Drupal\dropzonejs_eb_widget\Plugin\EntityBrowser\Widget;
use Drupal\Component\Utility\Bytes;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountProxyInterface;
......@@ -20,7 +22,8 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
* @EntityBrowserWidget(
* id = "dropzonejs",
* label = @Translation("DropzoneJS"),
* description = @Translation("Adds DropzoneJS upload integration.")
* description = @Translation("Adds DropzoneJS upload integration."),
* auto_select = TRUE
* )
*/
class DropzoneJsEbWidget extends WidgetBase {
......@@ -131,6 +134,26 @@ class DropzoneJsEbWidget extends WidgetBase {
$form['#attached']['library'][] = 'dropzonejs_eb_widget/common';
$original_form['#attributes']['class'][] = 'dropzonejs-disable-submit';
// Add hidden element used to make execution of auto-select of form.
if (!empty($config['settings']['auto_select'])) {
$form['auto_select_handler'] = [
'#type' => 'hidden',
'#name' => 'auto_select_handler',
'#id' => 'auto_select_handler',
'#attributes' => ['id' => 'auto_select_handler'],
'#submit' => ['::submitForm'],
'#executes_submit_callback' => TRUE,
'#ajax' => [
'wrapper' => 'auto_select_handler',
'callback' => [get_class($this), 'handleAjaxCommand'],
'event' => 'auto_select_enity_browser_widget',
'progress' => [
'type' => 'fullscreen',
],
],
];
}
return $form;
}
......@@ -203,7 +226,7 @@ class DropzoneJsEbWidget extends WidgetBase {
// Validate if we are in fact uploading a files and all of them have the
// right extensions. Although DropzoneJS should not even upload those files
// it's still better not to rely only on client side validation.
if ($trigger['#type'] == 'submit' && $trigger['#name'] == 'op') {
if (($trigger['#type'] == 'submit' && $trigger['#name'] == 'op') || $trigger['#name'] === 'auto_select_handler') {
$upload_location = $this->getUploadLocation();
if (!file_prepare_directory($upload_location, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
$form_state->setError($form['widget']['upload'], $this->t('Files could not be uploaded because the destination directory %destination is not configured correctly.', ['%destination' => $this->getConfiguration()['settings']['upload_location']]));
......@@ -237,10 +260,23 @@ class DropzoneJsEbWidget extends WidgetBase {
$files[] = $file;
}
if (!empty(array_filter($files))) {
$this->selectEntities($files, $form_state);
$this->clearFormValues($element, $form_state);
$this->selectEntities($files, $form_state);
$this->clearFormValues($element, $form_state);
}
/**
* {@inheritdoc}
*/
protected function selectEntities(array $entities, FormStateInterface $form_state) {
if (!empty(array_filter($entities))) {
$config = $this->getConfiguration();
if (empty($config['settings']['auto_select'])) {
parent::selectEntities($entities, $form_state);
}
}
$form_state->set(['dropzonejs', 'added_entities'], $entities);
}
/**
......@@ -360,4 +396,57 @@ class DropzoneJsEbWidget extends WidgetBase {
return array_diff(parent::__sleep(), ['files']);
}
/**
* Handling of automated submit of uploaded files.
*
* @param array $form
* Form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state.
*
* @return \Drupal\Core\Ajax\AjaxResponse|array
* Returns ajax commands that will be executed in front-end.
*/
public static function handleAjaxCommand(array $form, FormStateInterface $form_state) {
// If there are some errors during submitting of form they should be
// displayed, that's why we are returning status message here and generated
// errors will be displayed properly in front-end.
if (count($form_state->getErrors()) > 0) {
return [
'#type' => 'status_messages',
];
}
// Output correct response if everything passed without any error.
$ajax = new AjaxResponse();
if (($triggering_element = $form_state->getTriggeringElement()) && $triggering_element['#name'] === 'auto_select_handler') {
$entity_ids = [];
$added_entities = $form_state->get(['dropzonejs', 'added_entities']);
/** @var \Drupal\Core\Entity\EntityInterface $entity */
if (!empty($added_entities)) {
foreach ($added_entities as $entity) {
$entity_ids[] = $entity->getEntityTypeId() . ':' . $entity->id();
}
}
// Add command to clear list of uploaded files. It's important to set
// empty string value, in other case it will act as getter.
$ajax->addCommand(
new InvokeCommand('[data-drupal-selector="edit-upload-uploaded-files"]', 'val', [''])
);
// Add Invoke command to select uploaded entities.
$ajax->addCommand(
new InvokeCommand('.entities-list', 'trigger', [
'add-entities',
[$entity_ids],
])
);
}
return $ajax;
}
}
......@@ -24,7 +24,8 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
* @EntityBrowserWidget(
* id = "dropzonejs_media_entity_inline_entity_form",
* label = @Translation("Media Entity DropzoneJS with edit"),
* description = @Translation("Adds DropzoneJS upload integration that saves Media entities and allows to edit them.")
* description = @Translation("Adds DropzoneJS upload integration that saves Media entities and allows to edit them."),
* auto_select = FALSE
* )
*/
class InlineEntityFormMediaWidget extends MediaEntityDropzoneJsEbWidget {
......
......@@ -24,7 +24,8 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
* @EntityBrowserWidget(
* id = "dropzonejs_media_entity",
* label = @Translation("Media Entity DropzoneJS"),
* description = @Translation("Adds DropzoneJS upload integration that saves Media entities.")
* description = @Translation("Adds DropzoneJS upload integration that saves Media entities."),
* auto_select = TRUE
* )
*/
class MediaEntityDropzoneJsEbWidget extends DropzoneJsEbWidget {
......@@ -193,10 +194,8 @@ class MediaEntityDropzoneJsEbWidget extends DropzoneJsEbWidget {
$media_entity->save();
}
if (!empty(array_filter($media_entities))) {
$this->selectEntities($media_entities, $form_state);
$this->clearFormValues($element, $form_state);
}
$this->selectEntities($media_entities, $form_state);
$this->clearFormValues($element, $form_state);
}
}
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