diff --git a/core/lib/Drupal/Core/Entity/EntityListBuilder.php b/core/lib/Drupal/Core/Entity/EntityListBuilder.php index 7f46915..8114712 100644 --- a/core/lib/Drupal/Core/Entity/EntityListBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityListBuilder.php @@ -2,6 +2,7 @@ namespace Drupal\Core\Entity; +use Drupal\Component\Serialization\Json; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -150,6 +151,13 @@ protected function getDefaultOperations(EntityInterface $entity) { $operations['delete'] = [ 'title' => $this->t('Delete'), 'weight' => 100, + 'attributes' => [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'modal', + 'data-dialog-options' => Json::encode([ + 'width' => 'auto', + ]), + ], 'url' => $entity->urlInfo('delete-form'), ]; } @@ -201,6 +209,10 @@ public function buildOperations(EntityInterface $entity) { $build = [ '#type' => 'operations', '#links' => $this->getOperations($entity), + // Allow links to use modals. + '#attached' => [ + 'library' => ['core/drupal.ajax'], + ], ]; return $build; diff --git a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php index fc92ff9..8bf3957 100644 --- a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php +++ b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php @@ -45,7 +45,7 @@ public static function buildCancelLink(ConfirmFormInterface $form, Request $requ return [ '#type' => 'link', '#title' => $form->getCancelText(), - '#attributes' => ['class' => ['button']], + '#attributes' => ['class' => ['button', 'dialog-cancel']], '#url' => $url, '#cache' => [ 'contexts' => [ diff --git a/core/modules/config/src/Tests/ConfigEntityListTest.php b/core/modules/config/src/Tests/ConfigEntityListTest.php index e9950ea..9adf740 100644 --- a/core/modules/config/src/Tests/ConfigEntityListTest.php +++ b/core/modules/config/src/Tests/ConfigEntityListTest.php @@ -2,6 +2,7 @@ namespace Drupal\config\Tests; +use Drupal\Component\Serialization\Json; use Drupal\simpletest\WebTestBase; use Drupal\config_test\Entity\ConfigTest; use Drupal\Core\Entity\EntityStorageInterface; @@ -64,6 +65,13 @@ public function testList() { 'delete' => [ 'title' => t('Delete'), 'weight' => 100, + 'attributes' => [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'modal', + 'data-dialog-options' => Json::encode([ + 'width' => 'auto', + ]), + ], 'url' => $entity->urlInfo('delete-form'), ], ]; @@ -134,6 +142,13 @@ public function testList() { 'delete' => [ 'title' => t('Delete'), 'weight' => 100, + 'attributes' => [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'modal', + 'data-dialog-options' => Json::encode([ + 'width' => 'auto', + ]), + ], 'url' => $entity->urlInfo('delete-form'), ], ]; diff --git a/core/modules/views/tests/src/Kernel/Plugin/RowRenderCacheTest.php b/core/modules/views/tests/src/Kernel/Plugin/RowRenderCacheTest.php index 223963e..74e4e60 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/RowRenderCacheTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/RowRenderCacheTest.php @@ -2,6 +2,8 @@ namespace Drupal\Tests\views\Kernel\Plugin; +use Drupal\Component\Serialization\Json; +use Drupal\Component\Utility\Html; use Drupal\Core\Session\AccountInterface; use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; @@ -181,7 +183,7 @@ protected function doTestRenderedOutput(AccountInterface $account, $check_cache $this->assertEqual($output, $expected); $expected = $access ? '
' : ''; $output = $view->style_plugin->getField($index, 'operations'); $this->assertEqual($output, $expected); diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/Entity/EntityListBuilderTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/Entity/EntityListBuilderTest.php new file mode 100644 index 0000000..5f235e2 --- /dev/null +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Entity/EntityListBuilderTest.php @@ -0,0 +1,72 @@ +webUser = $this->drupalCreateUser(['administer entity_test content']); + $this->drupalLogin($this->webUser); + } + + /** + * Test that delete confirm forms use a modal dialog. + */ + public function testDeleteConfirmForm() { + /** @var \Drupal\entity_test\Entity\EntityTest[] $entities */ + $entities = []; + foreach (range(1, 10) as $i) { + $entities[$i] = EntityTest::create(['name' => 'Test entity ' . $i]); + $entities[$i]->save(); + } + + /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $entity_storage */ + $entity_storage = $this->container->get('entity_type.manager') + ->getStorage('entity_test'); + + $this->assertTrue($entity_storage->load($entities[3]->id())); + $this->drupalGet(Url::fromRoute('entity.entity_test.collection')); + + // Expand the operations for the 3rd entity. + $this->click('table tr:contains("Test entity 3") button .dropbutton-arrow'); + $this->click('table tr:contains("Test entity 3") .delete a'); + $this->assertSession()->assertWaitOnAjaxRequest(); + // Should still be on the listing page. + $this->assertSession() + ->addressEquals(Url::fromRoute('entity.entity_test.collection') + ->getInternalPath()); + // Delete the 3rd entity. + $this->click('.ui-dialog button:contains("' . t('Delete') . '")'); + $entity_storage->resetCache(); + $this->assertNull($entity_storage->load($entities[3]->id())); + $this->assertSession() + ->pageTextContains(t('The test entity Test entity 3 has been deleted.')); + } + +}