summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLee Rowlands2018-07-13 22:09:39 (GMT)
committerLee Rowlands2018-07-13 22:11:44 (GMT)
commitab1b9a6c00743f8988e4034d9d0e5979ea00c245 (patch)
tree383beaf11cd0267293f922e1351757eb5377b52d
parent62e59a00f2c0c4f1577b307eb9f80b703060e981 (diff)
Issue #2861860 by samuel.mortenson, phenaproxima, drpal, Daniel Korte, mogio_hh, tim.plunkett, alexpott: View inside core modal doesn't refresh correctly when reopened
(cherry picked from commit ac310db40b288778205108f25e38cda5bd77b9af)
-rw-r--r--core/modules/views/js/ajax_view.es6.js20
-rw-r--r--core/modules/views/js/ajax_view.js22
-rw-r--r--core/modules/views/tests/modules/views_test_modal/src/Controller/TestController.php41
-rw-r--r--core/modules/views/tests/modules/views_test_modal/views_test_modal.info.yml9
-rw-r--r--core/modules/views/tests/modules/views_test_modal/views_test_modal.routing.yml6
-rw-r--r--core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php61
6 files changed, 150 insertions, 9 deletions
diff --git a/core/modules/views/js/ajax_view.es6.js b/core/modules/views/js/ajax_view.es6.js
index 0c85358..e4de7b3 100644
--- a/core/modules/views/js/ajax_view.es6.js
+++ b/core/modules/views/js/ajax_view.es6.js
@@ -13,14 +13,28 @@
* Attaches ajaxView functionality to relevant elements.
*/
Drupal.behaviors.ViewsAjaxView = {};
- Drupal.behaviors.ViewsAjaxView.attach = function () {
- if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) {
- const ajaxViews = drupalSettings.views.ajaxViews;
+ Drupal.behaviors.ViewsAjaxView.attach = function (context, settings) {
+ if (settings && settings.views && settings.views.ajaxViews) {
+ const { views: { ajaxViews } } = settings;
Object.keys(ajaxViews || {}).forEach((i) => {
Drupal.views.instances[i] = new Drupal.views.ajaxView(ajaxViews[i]);
});
}
};
+ Drupal.behaviors.ViewsAjaxView.detach = (context, settings, trigger) => {
+ if (trigger === 'unload') {
+ if (settings && settings.views && settings.views.ajaxViews) {
+ const { views: { ajaxViews } } = settings;
+ Object.keys(ajaxViews || {}).forEach((i) => {
+ const selector = `.js-view-dom-id-${ajaxViews[i].view_dom_id}`;
+ if ($(selector, context).length) {
+ delete Drupal.views.instances[i];
+ delete settings.views.ajaxViews[i];
+ }
+ });
+ }
+ }
+ };
/**
* @namespace
diff --git a/core/modules/views/js/ajax_view.js b/core/modules/views/js/ajax_view.js
index a10eb83..95a803d 100644
--- a/core/modules/views/js/ajax_view.js
+++ b/core/modules/views/js/ajax_view.js
@@ -7,14 +7,30 @@
(function ($, Drupal, drupalSettings) {
Drupal.behaviors.ViewsAjaxView = {};
- Drupal.behaviors.ViewsAjaxView.attach = function () {
- if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) {
- var ajaxViews = drupalSettings.views.ajaxViews;
+ Drupal.behaviors.ViewsAjaxView.attach = function (context, settings) {
+ if (settings && settings.views && settings.views.ajaxViews) {
+ var ajaxViews = settings.views.ajaxViews;
+
Object.keys(ajaxViews || {}).forEach(function (i) {
Drupal.views.instances[i] = new Drupal.views.ajaxView(ajaxViews[i]);
});
}
};
+ Drupal.behaviors.ViewsAjaxView.detach = function (context, settings, trigger) {
+ if (trigger === 'unload') {
+ if (settings && settings.views && settings.views.ajaxViews) {
+ var ajaxViews = settings.views.ajaxViews;
+
+ Object.keys(ajaxViews || {}).forEach(function (i) {
+ var selector = '.js-view-dom-id-' + ajaxViews[i].view_dom_id;
+ if ($(selector, context).length) {
+ delete Drupal.views.instances[i];
+ delete settings.views.ajaxViews[i];
+ }
+ });
+ }
+ }
+ };
Drupal.views = {};
diff --git a/core/modules/views/tests/modules/views_test_modal/src/Controller/TestController.php b/core/modules/views/tests/modules/views_test_modal/src/Controller/TestController.php
new file mode 100644
index 0000000..b89cf40
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_modal/src/Controller/TestController.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\views_test_modal\Controller;
+
+use Drupal\Component\Serialization\Json;
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Url;
+
+class TestController extends ControllerBase {
+
+ /**
+ * Renders a link to open the /admin/content view in a modal dialog.
+ */
+ public function modal() {
+ $build = [];
+
+ $build['open_admin_content'] = [
+ '#type' => 'link',
+ '#title' => $this->t('Administer content'),
+ '#url' => Url::fromUserInput('/admin/content'),
+ '#attributes' => [
+ 'class' => ['use-ajax'],
+ 'data-dialog-type' => 'modal',
+ 'data-dialog-options' => Json::encode([
+ 'dialogClass' => 'views-test-modal',
+ 'height' => '50%',
+ 'width' => '50%',
+ 'title' => $this->t('Administer content'),
+ ]),
+ ],
+ '#attached' => [
+ 'library' => [
+ 'core/drupal.dialog.ajax',
+ ],
+ ],
+ ];
+
+ return $build;
+ }
+
+}
diff --git a/core/modules/views/tests/modules/views_test_modal/views_test_modal.info.yml b/core/modules/views/tests/modules/views_test_modal/views_test_modal.info.yml
new file mode 100644
index 0000000..59be6d4
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_modal/views_test_modal.info.yml
@@ -0,0 +1,9 @@
+name: 'Views Test Modal'
+type: module
+description: 'Provides a test page that renders a View in a modal.'
+package: Testing
+version: VERSION
+core: 8.x
+dependencies:
+ - drupal:node
+ - drupal:views
diff --git a/core/modules/views/tests/modules/views_test_modal/views_test_modal.routing.yml b/core/modules/views/tests/modules/views_test_modal/views_test_modal.routing.yml
new file mode 100644
index 0000000..430bac1
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_modal/views_test_modal.routing.yml
@@ -0,0 +1,6 @@
+views_test_modal.modal:
+ path: '/views-test-modal/modal'
+ defaults:
+ _controller: '\Drupal\views_test_modal\Controller\TestController::modal'
+ requirements:
+ _access: 'TRUE'
diff --git a/core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php b/core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php
index 6aa52bc..c6cbaf5 100644
--- a/core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php
+++ b/core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php
@@ -19,12 +19,14 @@ class ExposedFilterAJAXTest extends WebDriverTestBase {
/**
* {@inheritdoc}
*/
- public static $modules = ['node', 'views'];
+ public static $modules = ['node', 'views', 'views_test_modal'];
/**
- * Tests if exposed filtering via AJAX works for the "Content" View.
+ * {@inheritdoc}
*/
- public function testExposedFiltering() {
+ protected function setUp() {
+ parent::setUp();
+
// Enable AJAX on the /admin/content View.
\Drupal::configFactory()->getEditable('views.view.content')
->set('display.default.display_options.use_ajax', TRUE)
@@ -43,7 +45,12 @@ class ExposedFilterAJAXTest extends WebDriverTestBase {
'edit any page content',
]);
$this->drupalLogin($user);
+ }
+ /**
+ * Tests if exposed filtering via AJAX works for the "Content" View.
+ */
+ public function testExposedFiltering() {
// Visit the View page.
$this->drupalGet('admin/content');
@@ -91,4 +98,52 @@ class ExposedFilterAJAXTest extends WebDriverTestBase {
$this->assertFalse($session->getPage()->hasButton('Reset'));
}
+ /**
+ * Tests if exposed filtering via AJAX works in a modal.
+ */
+ public function testExposedFiltersInModal() {
+ $this->drupalGet('views-test-modal/modal');
+
+ $assert = $this->assertSession();
+
+ $assert->elementExists('named', ['link', 'Administer content'])->click();
+ $dialog = $assert->waitForElementVisible('css', '.views-test-modal');
+
+ $session = $this->getSession();
+ // Ensure that the Content we're testing for is present.
+ $html = $session->getPage()->getHtml();
+ $this->assertContains('Page One', $html);
+ $this->assertContains('Page Two', $html);
+
+ // Search for "Page One".
+ $session->getPage()->fillField('title', 'Page One');
+ $assert->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Filter');
+ $this->assertSession()->assertWaitOnAjaxRequest();
+
+ // Verify that only the "Page One" Node is present.
+ $html = $session->getPage()->getHtml();
+ $this->assertContains('Page One', $html);
+ $this->assertNotContains('Page Two', $html);
+
+ // Close and re-open the modal.
+ $assert->buttonExists('Close', $dialog)->press();
+ $assert->elementExists('named', ['link', 'Administer content'])->click();
+ $assert->waitForElementVisible('css', '.views-test-modal');
+
+ // Ensure that the Content we're testing for is present.
+ $html = $session->getPage()->getHtml();
+ $this->assertContains('Page One', $html);
+ $this->assertContains('Page Two', $html);
+
+ // Search for "Page One".
+ $session->getPage()->fillField('title', 'Page One');
+ $assert->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Filter');
+ $this->assertSession()->assertWaitOnAjaxRequest();
+
+ // Verify that only the "Page One" Node is present.
+ $html = $session->getPage()->getHtml();
+ $this->assertContains('Page One', $html);
+ $this->assertNotContains('Page Two', $html);
+ }
+
}