diff --git a/core/modules/views/js/ajax_view.js b/core/modules/views/js/ajax_view.js index c76e7073f5..f0ccb9ecf4 100644 --- a/core/modules/views/js/ajax_view.js +++ b/core/modules/views/js/ajax_view.js @@ -100,24 +100,29 @@ this.settings = settings; // Add the ajax to exposed forms. - this.$exposed_form = $( - `form#views-exposed-form-${settings.view_name.replace( - /_/g, - '-', - )}-${settings.view_display_id.replace(/_/g, '-')}`, - ); + this.$exposed_form = []; + if (this.settings.ajaxOptions.hasOwnProperty('use_ajax_exposed_filters')) { + this.$exposed_form = $( + `form#views-exposed-form-${settings.view_name.replace( + /_/g, + '-', + )}-${settings.view_display_id.replace(/_/g, '-')}`, + ); + } once('exposed-form', this.$exposed_form).forEach( this.attachExposedFormAjax.bind(this), ); // Add the ajax to pagers. - once( - 'ajax-pager', - this.$view - // Don't attach to nested views. Doing so would attach multiple behaviors - // to a given element. - .filter(this.filterNestedViews.bind(this)), - ).forEach(this.attachPagerAjax.bind(this)); + if (this.settings.ajaxOptions.hasOwnProperty('use_ajax_paging')) { + once( + 'ajax-pager', + this.$view + // Don't attach to nested views. Doing so would attach multiple behaviors + // to a given element. + .filter(this.filterNestedViews.bind(this)), + ).forEach(this.attachPagerAjax.bind(this)); + } // Add a trigger to update this view specifically. In order to trigger a // refresh use the following code. diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php index dd2014e86a..e9144d709b 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php @@ -320,6 +320,16 @@ public function isPagerEnabled() { return FALSE; } + /** + * {@inheritdoc} + */ + public function getAjaxOptions() { + if ($this->usesAJAX()) { + return $this->getOption('use_ajax_options'); + } + return FALSE; + } + /** * {@inheritdoc} */ @@ -1462,6 +1472,34 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#title' => $this->t('Use AJAX'), '#default_value' => $this->getOption('use_ajax') ? 1 : 0, ]; + + $options = [ + 'use_ajax_paging' => $this->t('Apply to paging.'), + 'use_ajax_sorting' => $this->t('Apply to sorting.'), + 'use_ajax_exposed_filters' => $this->t('Apply to exposed filters.'), + ]; + + if (empty($this->options['use_ajax_options'])) { + $this->options['use_ajax_options'] = []; + } + + $form['use_ajax_options'] = [ + '#type' => 'checkboxes', + '#title' => $this->t('AJAX options'), + '#options' => $options, + '#default_value' => $this->options['use_ajax_options'], + '#description' => $this->t('Select the options on which to apply ajax'), + '#states' => [ + 'disabled' => [ + ':input[name="use_ajax"]' => ['checked' => FALSE], + ], + ], + ]; + + if (empty($this->options['use_ajax_options'])) { + $form['use_ajax_options']['#states']['checked'] = [':input[name="use_ajax"]' => ['checked' => TRUE]]; + } + break; case 'hide_attachment_summary': @@ -1977,6 +2015,10 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { break; case 'use_ajax': + $this->setOption($section, (bool) $form_state->getValue($section)); + $this->setOption('use_ajax_options', array_filter($form_state->getValue('use_ajax_options'))); + break; + case 'hide_attachment_summary': case 'show_admin_links': case 'exposed_block': @@ -2317,6 +2359,10 @@ public function access(AccountInterface $account = NULL) { */ public function preExecute() { $this->view->setAjaxEnabled($this->ajaxEnabled()); + if ($this->ajaxEnabled()) { + $this->view->setAjaxOptions($this->getAjaxOptions()); + } + if ($this->isMoreEnabled() && !$this->useMoreAlways()) { $this->view->get_total_rows = TRUE; } diff --git a/core/modules/views/src/ViewExecutable.php b/core/modules/views/src/ViewExecutable.php index b76f10ea7d..46766521fa 100644 --- a/core/modules/views/src/ViewExecutable.php +++ b/core/modules/views/src/ViewExecutable.php @@ -73,6 +73,13 @@ class ViewExecutable { */ protected $ajaxEnabled = FALSE; + /** + * List of options where activating AJAX. + * + * @var array + */ + protected $ajaxOptions = []; + /** * The plugin name. */ @@ -674,6 +681,25 @@ public function ajaxEnabled() { return $this->ajaxEnabled; } + /** + * Sets options where AJAX should be used. + * + * If AJAX is used, users can select if using with paging, table sorting, or exposed filters will be fetched + * via an AJAX call rather than a page refresh. + * + * @param bool $ajax_options + * list of options where activating AJAX. + */ + public function setAjaxOptions($ajax_options): void { + if($this->ajaxEnabled) { + $this->ajaxOptions = $ajax_options; + } + } + + public function getAjaxOptions(): array { + return $this->ajaxOptions; + } + /** * Sets the exposed filters input to an array. * diff --git a/core/modules/views/views.module b/core/modules/views/views.module index c5d89194d2..94cea35a95 100644 --- a/core/modules/views/views.module +++ b/core/modules/views/views.module @@ -65,6 +65,7 @@ function views_views_pre_render($view) { // To fit multiple views on a page, the programmer may have // overridden the display's pager_element. 'pager_element' => isset($view->pager) ? $view->pager->getPagerId() : 0, + 'ajaxOptions' => $view->getAjaxOptions(), ], ], ];