diff --git a/modules/islandora_advanced_search/js/islandora_advanced_search.form.js b/modules/islandora_advanced_search/js/islandora_advanced_search.form.js index 7b068bb4..f81b3509 100644 --- a/modules/islandora_advanced_search/js/islandora_advanced_search.form.js +++ b/modules/islandora_advanced_search/js/islandora_advanced_search.form.js @@ -7,7 +7,8 @@ // Gets current parameters minus ones provided by the form. function getParams(query_parameter, recurse_parameter) { - var params = Drupal.Views.parseQueryString(window.location.href); + const url_search_params = new URLSearchParams(window.location.search); + const params = Object.fromEntries(url_search_params.entries()); // Remove Advanced Search Query Parameters. const param_match = "query\\[\\d+\\]\\[.+\\]".replace("query", query_parameter); const param_regex = new RegExp(param_match, "g"); @@ -97,13 +98,19 @@ // // Logic server side / client side should match to generate the // appropriate URL with javascript enabled or disable. - $form.submit(function (e) { - e.preventDefault(); - e.stopPropagation(); - const inputs = $form.serializeArray(); - const href = url(inputs, settings.islandora_advanced_search_form); - window.history.pushState(null, document.title, href); - }); + // + // If a route is set for the view display that this form is derived + // from, and we are not on the same page as that route, rely on the + // normal submit which will redirect to the appropriate page. + if (!settings.islandora_advanced_search_form.redirect) { + $form.submit(function (e) { + e.preventDefault(); + e.stopPropagation(); + const inputs = $form.serializeArray(); + const href = url(inputs, settings.islandora_advanced_search_form); + window.history.pushState(null, document.title, href); + }); + } // Reset should trigger refresh of AJAX Blocks / Views. $form.find('input[data-drupal-selector = "edit-reset"]').mousedown(function (e) { const inputs = []; diff --git a/modules/islandora_advanced_search/src/AdvancedSearchQuery.php b/modules/islandora_advanced_search/src/AdvancedSearchQuery.php index 45fe3ee0..f3083b32 100644 --- a/modules/islandora_advanced_search/src/AdvancedSearchQuery.php +++ b/modules/islandora_advanced_search/src/AdvancedSearchQuery.php @@ -3,6 +3,8 @@ namespace Drupal\islandora_advanced_search; use Drupal\block\Entity\Block; +use Drupal\Core\EventSubscriber\MainContentViewSubscriber; +use Drupal\Core\Form\FormBuilderInterface; use Drupal\Core\Url; use Drupal\islandora_advanced_search\Form\SettingsForm; use Drupal\islandora_advanced_search\Plugin\Block\AdvancedSearchBlock; @@ -223,9 +225,18 @@ class AdvancedSearchQuery { * @return \Drupal\Core\Url * Url for the given request combined with search query parameters. */ - public function toUrl(Request $request, array $terms, bool $recurse) { - $url = Url::createFromRequest($request); + public function toUrl(Request $request, array $terms, bool $recurse, $route = NULL) { $query_params = $request->query->all(); + if ($route) { + $url = Url::fromRoute($route); + // The form that built the url may use AJAX, but we are redirecting to a + // new page, so it should be disabled. + unset($query_params[FormBuilderInterface::AJAX_FORM_REQUEST]); + unset($query_params[MainContentViewSubscriber::WRAPPER_FORMAT]); + } + else { + $url = Url::createFromRequest($request); + } unset($query_params[$this->queryParameter]); foreach ($terms as $term) { $query_params[$this->queryParameter][] = $term->toQueryParams(); diff --git a/modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php b/modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php index 7b0c6683..513f20b6 100644 --- a/modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php +++ b/modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php @@ -5,10 +5,15 @@ namespace Drupal\islandora_advanced_search\Form; use Drupal\Component\Utility\Html; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\islandora_advanced_search\AdvancedSearchQuery; use Drupal\islandora_advanced_search\AdvancedSearchQueryTerm; use Drupal\islandora_advanced_search\GetConfigTrait; +use Drupal\views\DisplayPluginCollection; +use Drupal\views\Entity\View; +use Drupal\views\Plugin\views\display\PathPluginBase; +use Drupal\views\Views; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -46,11 +51,19 @@ class AdvancedSearchForm extends FormBase { */ protected $request; + /** + * The current route match. + * + * @var \Drupal\Core\Routing\RouteMatchInterface + */ + protected $currentRouteMatch; + /** * Class constructor. */ - public function __construct(Request $request) { + public function __construct(Request $request, RouteMatchInterface $current_route_match) { $this->request = $request; + $this->currentRouteMatch = $current_route_match; } /** @@ -58,7 +71,8 @@ class AdvancedSearchForm extends FormBase { */ public static function create(ContainerInterface $container) { return new static( - $container->get('request_stack')->getMasterRequest() + $container->get('request_stack')->getMasterRequest(), + $container->get('current_route_match') ); } @@ -186,13 +200,39 @@ class AdvancedSearchForm extends FormBase { return [$recursive, $term_values]; } + /** + * Gets the route name for the view display used to derive this forms block. + * + * @return string|null + * The route name for the view display that was used to create this + * forms block. + */ + protected function getRouteName(FormStateInterface $form_state) { + $view = $form_state->get('view'); + $display = $form_state->get('display'); + $display_handlers = new DisplayPluginCollection($view->getExecutable(), Views::pluginManager('display')); + $display_handler = $display_handlers->get($display['id']); + if ($display_handler instanceof PathPluginBase) { + return $display_handler->getRouteName(); + } + return NULL; + } + /** * {@inheritdoc} */ - public function buildForm(array $form, FormStateInterface $form_state, array $fields = [], string $context_filter = NULL) { + public function buildForm(array $form, FormStateInterface $form_state, View $view = NULL, array $display = [], array $fields = [], string $context_filter = NULL) { + // Keep reference to view and display as the submit handler may use them + // to redirect the user to the search page. + $form_state->set('view', $view); + $form_state->set('display', $display); + $route_name = $this->getRouteName($form_state); + $requires_redirect = $route_name ? $this->currentRouteMatch->getRouteName() !== $route_name : FALSE; + $form['#attached']['library'][] = 'islandora_advanced_search/advanced.search.form'; $form['#attached']['drupalSettings']['islandora_advanced_search_form'] = [ 'id' => Html::getId($this->getFormId()), + 'redirect' => $requires_redirect, 'query_parameter' => AdvancedSearchQuery::getQueryParameter(), 'recurse_parameter' => AdvancedSearchQuery::getRecurseParameter(), 'mapping' => [ @@ -353,8 +393,9 @@ class AdvancedSearchForm extends FormBase { } $terms = array_filter($terms); $recurse = filter_var($values['recursive'], FILTER_VALIDATE_BOOLEAN); + $route = $this->getRouteName($form_state); $advanced_search_query = new AdvancedSearchQuery(); - return $advanced_search_query->toUrl($this->request, $terms, $recurse); + return $advanced_search_query->toUrl($this->request, $terms, $recurse, $route); } /** diff --git a/modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php b/modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php index 19e6a290..c5f5adb8 100644 --- a/modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php +++ b/modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php @@ -371,7 +371,7 @@ class AdvancedSearchBlock extends BlockBase implements ContainerFactoryPluginInt foreach ($this->configuration[self::SETTING_FIELDS] as $identifier) { $configured_fields[$identifier] = $fields[$identifier]; } - return $this->formBuilder->getForm('Drupal\islandora_advanced_search\Form\AdvancedSearchForm', $configured_fields, $this->configuration[self::SETTING_CONTEXTUAL_FILTER]); + return $this->formBuilder->getForm('Drupal\islandora_advanced_search\Form\AdvancedSearchForm', $this->view, $this->display, $configured_fields, $this->configuration[self::SETTING_CONTEXTUAL_FILTER]); } /**