diff --git a/modules/format_strawberryfield_facets/src/Plugin/facets_summary/processor/LastActiveFacetsProcessor.php b/modules/format_strawberryfield_facets/src/Plugin/facets_summary/processor/LastActiveFacetsProcessor.php index 19e6f2b4..692b6568 100644 --- a/modules/format_strawberryfield_facets/src/Plugin/facets_summary/processor/LastActiveFacetsProcessor.php +++ b/modules/format_strawberryfield_facets/src/Plugin/facets_summary/processor/LastActiveFacetsProcessor.php @@ -133,7 +133,7 @@ public function build(FacetsSummaryInterface $facets_summary, array $build, arra $exposed_input = $view->getExposedInput(); $view->getRequest()->getRequestUri(); $keys_to_filter = []; - $key_with_search_value = [] ; + $key_with_search_value = []; // Oh gosh, blocks... if (!$view->getDisplay()->isDefaultDisplay() && empty($view->getDisplay()->options['filters'] ?? [] )) { $filters = $view->getDisplay()->handlers['filter']; @@ -147,9 +147,17 @@ public function build(FacetsSummaryInterface $facets_summary, array $build, arra elseif ($filter->getPluginId() == 'sbf_advanced_search_api_fulltext' && $filter->isExposed() ) { + $current_count = 1; + if ($filter->options['expose']['identifier'] ?? NULL ) { + $field_count_field = $filter->options['expose']['identifier'] . '_advanced_search_fields_count'; + $current_count = $exposed_input[$field_count_field] ?? ($filter->options['expose']['advanced_search_fields_count'] ?? 1); + } $extra_keys_to_filter = []; - $keys_to_filter[] =$filter->options['expose']['operator_id'] ?? NULL; + $keys_to_filter[] = $filter->options['expose']['operator_id'] ?? NULL; $keys_to_filter[] = $filter->options['expose']['identifier'] ?? NULL; + if ($filter->options['expose']['identifier'] ?? NULL ) { + $keys_to_filter[] = $filter->options['expose']['identifier'] . '_advanced_search_fields_count'; + } $key_with_search_value[] = $filter->options['expose']['identifier'] ?? NULL; $keys_to_filter[] = $filter->options['expose']['searched_fields_id'] ?? NULL; $keys_to_filter[] = $filter->options['expose']['advanced_search_operator_id'] @@ -160,17 +168,20 @@ public function build(FacetsSummaryInterface $facets_summary, array $build, arra $i < $filter->options['expose']['advanced_search_fields_count'] ?? 1; $i++ ) { - $extra_keys_to_filter[] = $key_to_filter . '_' . $i; if (in_array($key_to_filter, $key_with_search_value)){ - $key_with_search_value[] = $key_to_filter . '_' . $i; + if ($i < $current_count) { + $key_with_search_value[] = $key_to_filter . '_' . $i; + } } } } - $keys_to_filter = array_filter($keys_to_filter); + $keys_to_filter = array_merge( $keys_to_filter, $extra_keys_to_filter ); + $keys_to_filter = array_unique($keys_to_filter); + $keys_to_filter = array_filter($keys_to_filter); } } } @@ -187,9 +198,20 @@ public function build(FacetsSummaryInterface $facets_summary, array $build, arra elseif ($filter['plugin_id'] == 'sbf_advanced_search_api_fulltext' && $filter['exposed'] ) { + $current_count = 1; + if ($filter['expose']['identifier'] ?? NULL ) { + $field_count_field = $filter['expose']['identifier'] . '_advanced_search_fields_count'; + $current_count = $exposed_input[$field_count_field] ?? ($filter['expose']['advanced_search_fields_count'] ?? 1); + } + $extra_keys_to_filter = []; $keys_to_filter[] = $filter['expose']['operator_id'] ?? NULL; $keys_to_filter[] = $filter['expose']['identifier'] ?? NULL; + // fields count = $filter['expose']['identifier'] + if ($filter['expose']['identifier'] ?? NULL ) { + $keys_to_filter[] + = $filter['expose']['identifier'] . '_advanced_search_fields_count'; + } $key_with_search_value[] = $filter['expose']['identifier'] ?? NULL; $keys_to_filter[] = $filter['expose']['searched_fields_id'] ?? @@ -203,17 +225,19 @@ public function build(FacetsSummaryInterface $facets_summary, array $build, arra $i < $filter['expose']['advanced_search_fields_count'] ?? 1; $i++ ) { - $extra_keys_to_filter[] = $key_to_filter . '_' . $i; if (in_array($key_to_filter, $key_with_search_value)) { - $key_with_search_value[] = $key_to_filter . '_' . $i; + if ($i < $current_count) { + $key_with_search_value[] = $key_to_filter . '_' . $i; + } } } } - $keys_to_filter = array_filter($keys_to_filter); $keys_to_filter = array_merge( $keys_to_filter, $extra_keys_to_filter ); + $keys_to_filter = array_unique($keys_to_filter); + $keys_to_filter = array_filter($keys_to_filter); } } } diff --git a/modules/format_strawberryfield_views/css/advanced_search.css b/modules/format_strawberryfield_views/css/advanced_search.css new file mode 100644 index 00000000..22cd11c2 --- /dev/null +++ b/modules/format_strawberryfield_views/css/advanced_search.css @@ -0,0 +1,7 @@ +.adv-search-delone { + margin-right: 0.275rem; +} + +.adv-search-addone { + margin-right: 0.275rem; +} diff --git a/modules/format_strawberryfield_views/format_strawberryfield_views.libraries.yml b/modules/format_strawberryfield_views/format_strawberryfield_views.libraries.yml index 1bae7086..919b7bb5 100644 --- a/modules/format_strawberryfield_views/format_strawberryfield_views.libraries.yml +++ b/modules/format_strawberryfield_views/format_strawberryfield_views.libraries.yml @@ -42,3 +42,13 @@ view-ajax-interactions: - core/views - core/views.ajax - format_strawberryfield/iiif_formatstrawberryfield_utils + +advanced-search-default-submit: + js: + js/sbf-advanced-search-default-submit.js: {minified: false} + css: + component: + css/advanced_search.css: { } + dependencies: + - core/drupal + - core/jquery diff --git a/modules/format_strawberryfield_views/format_strawberryfield_views.module b/modules/format_strawberryfield_views/format_strawberryfield_views.module index 4dd63405..7046d9ac 100644 --- a/modules/format_strawberryfield_views/format_strawberryfield_views.module +++ b/modules/format_strawberryfield_views/format_strawberryfield_views.module @@ -141,8 +141,17 @@ function format_strawberryfield_views_block_view_views_exposed_filter_block_sbf_ */ function format_strawberryfield_views_form_alter(&$form, FormStateInterface $form_state, $form_id) { if ($form_id == 'views_exposed_form') { + if (isset($form['actions']['submit'])) { + $form['actions']['#attached']['library'][] = 'format_strawberryfield_views/advanced-search-default-submit'; + $form['actions']['submit']['#attributes']['autofocus'] = ''; + $form['actions']['submit']['#attributes']['tabindex'] = 1; + $form['actions']['submit']['#attributes']['data-default-submit'] = ''; + // Needed when multiple buttons are on the same form, by default the name is empty + // making \Drupal\Core\Form\FormBuilder::buttonWasClicked fail! + $form['actions']['submit']['#name'] = 'op'; + } foreach ($form as $key => $value) { - if (is_array($value) && isset ($value['#group']) && isset($value['#type']) && $value['#group'] == 'actions' && $value['#type'] == 'submit') { + if (is_array($value) && isset ($value['#group']) && isset($value['#type']) && $value['#group'] == 'actions' && ($value['#type'] == 'submit' || $value['#type'] == 'button' || $value['#type'] == 'link')) { $form['actions'][$key] = $value; unset($form[$key]); } diff --git a/modules/format_strawberryfield_views/js/modal-exposed-form-ajax.js b/modules/format_strawberryfield_views/js/modal-exposed-form-ajax.js index d704cf31..e30adee0 100644 --- a/modules/format_strawberryfield_views/js/modal-exposed-form-ajax.js +++ b/modules/format_strawberryfield_views/js/modal-exposed-form-ajax.js @@ -190,7 +190,6 @@ } }); if (reloadfacets) { - console.log('reloading!'); Drupal.AjaxFacetsView.updateFacetsBlocks(href, options.extraData.view_name, options.extraData.view_display_id); } } @@ -215,8 +214,6 @@ if (ajax_views_call && view_name && view_display_id) { var exposed_form_selector = '#views-exposed-form-' + view_name.replace(/_/g, '-') + '-' + view_display_id.replace(/_/g, '-'); var $exposed_form = $(exposed_form_selector).length; - console.log($exposed_form); - console.log(exposed_form_selector); if ($exposed_form > 0) { $exposed_form = 1; } @@ -258,10 +255,7 @@ }; Drupal.AjaxCommands.prototype.SbfSetBrowserUrl = function (ajax, response) { - console.log(response.url); window.history.replaceState(null, '', response.url); } - - })(jQuery, Drupal, once, drupalSettings); diff --git a/modules/format_strawberryfield_views/js/sbf-advanced-search-default-submit.js b/modules/format_strawberryfield_views/js/sbf-advanced-search-default-submit.js new file mode 100644 index 00000000..055b4b35 --- /dev/null +++ b/modules/format_strawberryfield_views/js/sbf-advanced-search-default-submit.js @@ -0,0 +1,53 @@ +(function ($, Drupal) { + Drupal.behaviors.sbfAdvancedSearchViewsForm = { + attach(context) { + var formInterception = function(defaultSubmitInput, ev) { + if (ev.keyCode == 13) { + ev.preventDefault(); + ev.stopPropagation(); + defaultSubmitInput.click(); + } + }; + + var addMoreInterception = function(defaultSubmitInput, ev) { + ev.preventDefault(); + ev.stopPropagation(); + const $form = defaultSubmitInput.closest('.views-exposed-form'); + let $count = $form.querySelector('input[name="sbf_advanced_search_api_fulltext_advanced_search_fields_count"]'); + $count.value = Number($count.value) + 1; + defaultSubmitInput.click(); + }; + + var delOneInterception = function(defaultSubmitInput, ev) { + ev.preventDefault(); + ev.stopPropagation(); + if (typeof ev.target.dataset.advancedSearchPrefix !== 'undefined') { + const $name = ev.target.dataset.advancedSearchPrefix + '_advanced_search_fields_count'; + const $form = defaultSubmitInput.closest('.views-exposed-form'); + let $count = $form.querySelector('input[name="'+$name+'"]'); + if ($count) { + $count.value = Number($count.value) - 1; + const $tounsetSelector = ev.target.dataset.advancedSearchPrefix + '_' + $count.value; + let $tounset = $form.querySelector('input[name="' + $tounsetSelector + '"]'); + if ($tounset) { + $tounset.value = ''; + } + } + } + defaultSubmitInput.click(); + }; + + for (const defaultSubmitInput of document.querySelectorAll('.views-exposed-form [data-default-submit]')) { + for (const formInput of defaultSubmitInput.form.querySelectorAll('input')) { + formInput.addEventListener('keypress', formInterception.bind(null, defaultSubmitInput)); + } + for (const addMore of document.querySelectorAll('.views-exposed-form [data-advanced-search-addone]')) { + addMore.addEventListener('click', addMoreInterception.bind(null, defaultSubmitInput)); + } + for (const delOne of document.querySelectorAll('.views-exposed-form [data-advanced-search-delone]')) { + delOne.addEventListener('click', delOneInterception.bind(null, defaultSubmitInput)); + } + } + } + } +})(jQuery, Drupal); diff --git a/modules/format_strawberryfield_views/src/Controller/FormatStrawberryfieldViewAjaxController.php b/modules/format_strawberryfield_views/src/Controller/FormatStrawberryfieldViewAjaxController.php index 8e4d8582..3b62369a 100644 --- a/modules/format_strawberryfield_views/src/Controller/FormatStrawberryfieldViewAjaxController.php +++ b/modules/format_strawberryfield_views/src/Controller/FormatStrawberryfieldViewAjaxController.php @@ -145,6 +145,8 @@ public function ajaxView(Request $request) { $response = new ViewAjaxResponse(); + + // Remove all of this stuff from the query of the request so it doesn't // end up in pagers and tablesort URLs. // @todo Remove this parsing once these are removed from the request in @@ -172,12 +174,44 @@ public function ajaxView(Request $request) { } $view = $this->executableFactory->get($entity); if ($view && $view->access($display_id) && $view->setDisplay($display_id) && $view->display_handler->ajaxEnabled()) { - $response->setView($view); + // Fix the current path for paging. if (!empty($path)) { $this->currentPath->setPath('/' . ltrim($path, '/'), $request); } + // Because Exposed filters use Get and our form is submitting via POST + // We end with stale old values. + + // Let's check if our view has our advanced search filter + + $filters = $view->getDisplay($display_id)->display['display_options']['filters'] ?? []; + foreach ($filters as $filter) { + /* @var \Drupal\views\Plugin\views\ViewsHandlerInterface $filter */ + if ($filter['plugin_id'] == 'sbf_advanced_search_api_fulltext' + && $filter['exposed'] == TRUE + ) { + if ($filter['expose']['identifier'] ?? NULL ) { + // At this stage the loaded View has already processed + // the whole GET bag as its own input based on the active request + // We need to alter that. Let's check if we have the id in both GET and POST + // If in POST, POST wins and replaces/needs to replace GET in the view + $views_post = $view->getRequest()->request->all(); + unset($views_post['ajax_page_state']); + $views_get = $view->getRequest()->query->all(); + if (isset($views_post[$filter['expose']['identifier']])) { + foreach ($views_get as $get_args_keys => $value) { + if (strpos($get_args_keys, $filter->options['expose']['identifier']) === 0) { + unset($views_get[$get_args_keys]); + } + } + } + } + $view->getRequest()->query->replace($views_post + $views_get); + } + } + + // Add all POST data, because AJAX is always a post and many things, // such as tablesorts, exposed filters and paging assume GET. $request_all = $request->request->all(); @@ -185,6 +219,7 @@ public function ajaxView(Request $request) { $query_all = $request->query->all(); $request->query->replace($request_all + $query_all); + $response->setView($view); // Overwrite the destination. // @see the redirect.destination service. $origin_destination = $path; @@ -236,7 +271,7 @@ public function ajaxView(Request $request) { ->merge($bubbleable_metadata) ->applyTo($exposed_form); } - $response->addCommand(new ReplaceCommand("#views-exposed-form-" . $view_id, $this->renderer->render($exposed_form))); + $response->addCommand(new ReplaceCommand("#views-exposed-form-" . $view_id, $this->renderer->render($exposed_form))); } return $response; diff --git a/modules/format_strawberryfield_views/src/Plugin/views/filter/AdvancedSearchApiFulltext.php b/modules/format_strawberryfield_views/src/Plugin/views/filter/AdvancedSearchApiFulltext.php index 73452d4c..7f30789e 100644 --- a/modules/format_strawberryfield_views/src/Plugin/views/filter/AdvancedSearchApiFulltext.php +++ b/modules/format_strawberryfield_views/src/Plugin/views/filter/AdvancedSearchApiFulltext.php @@ -5,6 +5,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\StringTranslation\PluralTranslatableMarkup; +use Drupal\Core\Url; use Drupal\search_api\Entity\Index; use Drupal\search_api\ParseMode\ParseModePluginManager; use Drupal\search_api_solr\Utility\Utility; @@ -61,10 +62,14 @@ public function defineOptions() { $options = parent::defineOptions(); $options['expose']['contains']['advanced_search_fields_multiple'] = ['default' => FALSE]; $options['expose']['contains']['advanced_search_fields_count'] = ['default' => 2]; + $options['expose']['contains']['advanced_search_fields_count_min'] = ['default' => 1]; $options['expose']['contains']['advanced_search_use_operator'] = ['default' => FALSE]; $options['expose']['contains']['advanced_search_operator_id'] = ['default' => '']; $options['expose']['contains']['advanced_search_fields_add_one_label'] = ['default' => 'add one']; $options['expose']['contains']['advanced_search_fields_remove_one_label'] = ['default' => 'remove one']; + $options['advanced_search_fields_add_one_label'] = ['default' => ['add one']]; + $options['advanced_search_fields_remove_one_label'] = ['default' => ['remove one']]; + $options['fields_label_replace'] = ['default' => NULL]; return $options; } @@ -73,10 +78,11 @@ public function defaultExposeOptions() { parent::defaultExposeOptions(); $this->options['expose']['advanced_search_fields_multiple'] = FALSE; $this->options['expose']['advanced_search_fields_count'] = 2; + $this->options['expose']['advanced_search_fields_count_min'] = 1; $this->options['expose']['advanced_search_use_operator'] = FALSE; $this->options['expose']['advanced_search_operator_id'] = $this->options['id'] . '_group_operator'; - $this->options['expose']['advanced_search_fields_add_one_label'] = 'add one'; - $this->options['expose']['advanced_search_fields_remove_one_label'] = 'remove one'; + $this->options['expose']['advanced_search_fields_add_one_label'] = $this->options['advanced_search_fields_add_one_label']; + $this->options['expose']['advanced_search_fields_remove_one_label'] = $this->options['advanced_search_fields_remove_one_label']; } /** @@ -110,6 +116,20 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) { ], ], ]; + $form['expose']['advanced_search_fields_count_min'] = [ + '#type' => 'number', + '#default_value' => $this->options['expose']['advanced_search_fields_count_min'], + '#title' => $this->t('Min number of Multiple/add more Search Fields the user will see. Number must be less or equal to the max. If not it will cap automatically'), + '#size' => 5, + '#min' => 1, + '#max' => 10, + '#description' => $this->t('The number of search Fields with the same general exposed settings the user will see by default.'), + '#states' => [ + 'visible' => [ + ':input[name="options[expose][advanced_search_fields_multiple]"]' => ['checked' => TRUE], + ], + ], + ]; $form['expose']['advanced_search_fields_add_one_label'] = [ '#type' => 'textfield', @@ -161,6 +181,28 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) { ]; } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, FormStateInterface $form_state) { + parent::buildOptionsForm($form, $form_state); + + if (isset($form['fields']['#options'])) { + foreach ($form['fields']['#options'] as $key => $value) { + $replacement[] = $key . '|' . $value; + } + $replacement = implode("\n", $replacement); + $form['fields_label_replace'] = [ + '#type' => 'textarea', + '#default_value' => $this->options['fields_label_replace'] ?? $replacement, + '#rows' => 8, + '#title' => $this->t('Replacement pattern for user facing Fields. '), + '#size' => 40, + '#description' => $this->t('Use a Pipe (|) to separate value from desired label. One per line'), + ]; + } + } /** * {@inheritdoc} */ @@ -407,7 +449,8 @@ public function query() { if ($negation) { $manual_keys[0]['#negation'] = $negation; } - + // @TODO: Check that manual_keys is an array;, that $query_able_datum_internal['real_solr_fields'] exists. + // if not abort the query. $flat_key = \Drupal\search_api_solr\Utility\Utility::flattenKeys( $manual_keys, $query_able_datum_internal['real_solr_fields'], $parse_mode->getPluginId() @@ -425,12 +468,13 @@ public function query() { if ($j > 0) { if ($query_able_datum_internal['interfield_operator'] == 'and') { - $flat_key = ' && '.$flat_key; + $flat_key = ' && '. $flat_key; } } $flat_keys[] = $flat_key; $j++; } + if (count($flat_keys)) { /** @var \Drupal\search_api\ParseMode\ParseModeInterface $parse_mode */ $parse_mode_direct = $this->getParseModeManager() @@ -544,12 +588,16 @@ public function query() { } public function submitExposed(&$form, FormStateInterface $form_state) { - if ($form_state->getTriggeringElement()['#op'] ?? NULL == $this->options['id'] . '_addone') { - $current_count = &$form_state->getValue($this->options['id'].'_advanced_search_fields_count',1); + if (!$form_state->isValueEmpty('op') && + !empty($this->options['exposed']) && + $form_state->getTriggeringElement()['#parents'] ?? NULL && + ($form_state->getTriggeringElement()['#parents'][0] ?? NULL) == 'reset') { + $form_state->setRebuild(FALSE); + } + elseif (!$form_state->isValueEmpty('op') && + !empty($this->options['exposed'])) { $form_state->setRebuild(TRUE); } - // OR HOW THE RESET BUTTON DOES IT - //if (!$form_state->isValueEmpty('op') && $form_state->getValue('op') == $this->options['reset_button_label']) parent::submitExposed( $form, $form_state ); @@ -584,14 +632,13 @@ public function acceptExposedInput($input) { if ($return && $realcount = $input[$this->options['expose']['identifier'].'_advanced_search_fields_count']) { $this->value = []; $this->value[$this->options['expose']['identifier']] = $input[$this->options['expose']['identifier']]; - for($i=1;$i < $realcount && $realcount > 1; $i++) { + for($i=1; $i < $realcount && $realcount > 1; $i++) { if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id']) && isset($input[$this->options['expose']['operator_id'].'_'.$i])) { $this->operatorAdv[$this->options['expose']['identifier'] . '_' . $i] = $input[$this->options['expose']['operator_id'].'_'.$i]; } $this->value[$this->options['expose']['identifier'] . '_' . $i] = $input[$this->options['expose']['identifier'].'_'.$i] ?? ''; } } - if (!$return) { // Override for the "(not) empty" operators. $operators = $this->operators(); @@ -614,11 +661,15 @@ public function buildExposedForm(&$form, FormStateInterface $form_state) { if ($this->options['expose']['expose_fields']) { $fields = $this->getFulltextFields(); $configured_fields = $this->options['fields']; + + // Only keep the configured fields. if (!empty($configured_fields)) { $configured_fields = array_flip($configured_fields); $fields = array_intersect_key($fields, $configured_fields); } + $fields = $this->rewriteFieldLabels($fields); + //Now the searched fields if exposed. $searched_fields_identifier = $this->options['id'] . '_searched_fields'; if (!empty($this->options['expose']['searched_fields_id'])) { @@ -626,7 +677,6 @@ public function buildExposedForm(&$form, FormStateInterface $form_state) { = $this->options['expose']['searched_fields_id']; } - // Remove the group operator if found unset($form[$searched_fields_identifier]); $multiple_exposed_fields = $this->options['expose']['multiple'] ?? FALSE ? min(count($fields), 5) : 1; @@ -651,7 +701,6 @@ public function buildExposedForm(&$form, FormStateInterface $form_state) { $advanced_search_operator_id = $this->options['id'] . '_group_operator'; // And our own settings. if (!empty($this->options['expose']['advanced_search_use_operator']) && !empty($this->options['expose']['advanced_search_operator_id'])) { - if (!empty($this->options['expose']['advanced_search_operator_id'])) { $advanced_search_operator_id = $this->options['expose']['advanced_search_operator_id']; } @@ -676,37 +725,57 @@ public function buildExposedForm(&$form, FormStateInterface $form_state) { // Yes over complicated but so far the only way i found to keep the state // Of this value between calls/rebuilds and searches. // @TODO move this into Accept input. That is easier? - $nextcount = (int) ($form_state->getUserInput()['sbf_advanced_search_api_fulltext_advanced_search_fields_count'] ?? 1); - $prevcount = $this->view->exposed_raw_input[$this->options['id'].'_advanced_search_fields_count'] ?? NULL; - $form_state_count = $form_state->getValue('sbf_advanced_search_api_fulltext_advanced_search_fields_count', NULL); - $realcount = $prevcount ?? ($form_state_count ?? $nextcount); + $nextcount = (int) ($form_state->getUserInput()[$this->options['id'] . '_advanced_search_fields_count'] ?? 1); + //$prevcount = $this->view->exposed_raw_input[$this->options['id'].'_advanced_search_fields_count'] ?? NULL; + $form_state_count = $form_state->getValue($this->options['id'] . '_advanced_search_fields_count', NULL); + + // $realcount = $prevcount ?? ($form_state_count ?? $nextcount); + $realcount = $form_state_count ?? $nextcount; // Cap it to the max limit $realcount = ($realcount <= $this->options['expose']['advanced_search_fields_count']) ? $realcount : $this->options['expose']['advanced_search_fields_count']; // Only enable if setup and the realcount is less than the max. $enable_more = $realcount < $this->options['expose']['advanced_search_fields_count'] && $this->options['expose']['advanced_search_fields_multiple']; $enable_less = $realcount > 1; - // This fails on Preview (because of competing Ajax and replace calls) - // @TODO Re-test without the IF bc of Sunday refactor that should have fixed it? if (empty($this->view->live_preview)) { $form[$this->options['id'].'_addone'] = [ - '#type' => 'submit', - '#op' => $this->options['id'] . '_addone', - '#value' => $this->t('@label', [ - '@label' => $this->options['exposed']['advanced_search_fields_add_one_label'] ?? 'add one' - ]), + '#type' => 'link', + '#title' => t($this->options['expose']['advanced_search_fields_add_one_label'] ?? 'add one'), + '#url' => Url::fromRoute(''), + '#attributes' => [ + 'data-disable-refocus' => "true", + 'data-advanced-search-addone' => "true", + 'data-advanced-search-max' => $this->options['expose']['advanced_search_fields_count'], + 'data-advanced-search-prefix' => $this->options['id'], + 'tabindex' => 2, + 'class' => [ + 'adv-search-addone', + 'button', + 'btn', + 'btn-secondary' + ], + ], '#access' => $enable_more, '#weight' => '-100', '#group' => 'actions', ]; - /* Note: #group does not work for buttons but we use this to bring them into - 'actions' key in a form alter */ $form[$this->options['id'].'_delone'] = [ - '#type' => 'submit', - '#op' => $this->options['id'] . '_delone', - '#value' => $this->t('@label', [ - '@label' => $this->options['exposed']['advanced_search_fields_remove_one_label'] ?? 'remove one' - ]), + '#type' => 'link', + '#title' => t($this->options['expose']['advanced_search_fields_remove_one_label'] ?? 'delete one'), + '#url' => Url::fromRoute(''), + '#attributes' => [ + 'data-disable-refocus' => "true", + 'data-advanced-search-delone' => "true", + 'data-advanced-search-min' => $this->options['expose']['advanced_search_fields_count_min'], + 'data-advanced-search-prefix' => $this->options['id'], + 'tabindex' => 3, + 'class' => [ + 'adv-search-delone', + 'button', + 'btn', + 'btn-secondary' + ], + ], '#access' => $enable_less, '#weight' => '-101', '#group' => 'actions', @@ -774,30 +843,7 @@ public function validateExposed(&$form, FormStateInterface $form_state) { $current_count = &$form_state->getValue( $this->options['id'] . '_advanced_search_fields_count', 1 ); - if ((($triggering_element = $form_state->getTriggeringElement()['#op'] ?? - NULL) == $this->options['id'] . '_addone') - && ($form_state->getUserInput()['op'] ?? NULL == $this->options['expose']['advanced_search_fields_add_one_label']) - && $this->options['expose']['advanced_search_fields_multiple'] - ) { - $this->searchedFieldsCount = $this->searchedFieldsCount - < ($this->options['expose']['advanced_search_fields_count'] ?? 1) - ? $this->searchedFieldsCount++ - : ($this->options['expose']['advanced_search_fields_count'] ?? 1); - // Check if the state was set already - $current_count++; - } - elseif ((($triggering_element = $form_state->getTriggeringElement()['#op'] ?? - NULL) == $this->options['id'] . '_delone') - && ($form_state->getUserInput()['op'] ?? NULL == $this->options['expose']['advanced_search_fields_remove_one_label']) - && $this->options['expose']['advanced_search_fields_multiple'] - ) { - $this->searchedFieldsCount = $this->searchedFieldsCount - > ($this->options['expose']['advanced_search_fields_count'] ?? 1) - ? $this->searchedFieldsCount-- - : ($this->options['expose']['advanced_search_fields_count'] ?? 1); - // Check if the state was set already - $current_count--; - } + $this->searchedFieldsCount = $current_count; if ($this->options['expose']['advanced_search_fields_multiple']) { for ($i = 1; $i < $current_count; $i++) { @@ -814,12 +860,31 @@ public function validateExposed(&$form, FormStateInterface $form_state) { } } + $identifiers[] = $identifiers_to_keep[] = $this->options['expose']['identifier']; + + for ($i = 1; $i < $this->options['expose']['advanced_search_fields_count']; $i++) { + if ($i < $current_count) { + $identifiers_to_keep[] = $this->options['expose']['identifier'] . '_' + . $i; + } + $identifiers[] = $this->options['expose']['identifier'] . '_' + . $i; + } - $identifiers[] = $this->options['expose']['identifier']; - for ($i = 1; $i < $current_count; $i++) { - $identifiers[] = $this->options['expose']['identifier'] . '_' . $i; + foreach ($identifiers as $index => $identifier) { + if (!in_array($identifier, $identifiers_to_keep)) { + $form_state->unsetValue($identifier); + $form_state->unsetValue($index > 0 ? $searched_fields_identifier . '_' . $index : $searched_fields_identifier); + $form_state->unsetValue($index > 0 ? $advanced_search_operator_id . '_' . $index : $advanced_search_operator_id); + $userInput = $form_state->getUserInput(); + unset($userInput[$identifier]); + unset($userInput[$index > 0 ? $searched_fields_identifier . '_' . $index : $searched_fields_identifier]); + unset($userInput[$index > 0 ? $advanced_search_operator_id . '_' . $index : $advanced_search_operator_id]); + $form_state->setUserInput($userInput); + } } - foreach ($identifiers as $identifier) { + + foreach ($identifiers_to_keep as $index => $identifier) { $input = &$form_state->getValue($identifier, ''); /// @TODO Add all inputs here... /// @@ -828,7 +893,8 @@ public function validateExposed(&$form, FormStateInterface $form_state) { ) { $this->operator = $this->options['group_info']['group_items'][$input]['operator']; - $input = &$this->options['group_info']['group_items'][$input]['value']; + $input + = &$this->options['group_info']['group_items'][$input]['value']; } // Under some circumstances, input will be an array containing the string @@ -840,7 +906,9 @@ public function validateExposed(&$form, FormStateInterface $form_state) { // No input was given by the user. If the filter was set to "required" and // there is a query (not the case when an exposed filter block is // displayed stand-alone), abort it. - if (!empty($this->options['expose']['required']) && $this->getQuery()) { + if (!empty($this->options['expose']['required']) + && $this->getQuery() + ) { $this->getQuery()->abort(); } // If the input is empty, there is nothing to validate: return early. @@ -874,4 +942,27 @@ protected function canBuildGroup() { // Building groups here makes no sense. We disable it. return FALSE; } + + protected function prepareFilterSelectOptions(&$options) { + parent::prepareFilterSelectOptions( + $options + ); // TODO: Change the autogenerated stub + } + + private function rewriteFieldLabels($options) { + $lines = explode("\n", trim($this->options['fields_label_replace'])); + foreach ($lines as $line) { + if (strpos($line, '|') !== FALSE) { + [$search, $replace] = array_map('trim', explode('|', $line)); + if (!empty($search)) { + if (isset($options[$search])) { + $options[$search] = $replace; + } + } + } + } + return $options; + } + + } diff --git a/src/Plugin/Field/FieldFormatter/StrawberryPdfFormatter.php b/src/Plugin/Field/FieldFormatter/StrawberryPdfFormatter.php index fb9d9d82..b6a5968a 100644 --- a/src/Plugin/Field/FieldFormatter/StrawberryPdfFormatter.php +++ b/src/Plugin/Field/FieldFormatter/StrawberryPdfFormatter.php @@ -388,7 +388,6 @@ public static function changePdfCallBack( array $form, FormStateInterface $form_state ) { - error_log('changeSceneCallBack called'); $button = $form_state->getTriggeringElement(); $element = NestedArray::getValue( $form,