Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions admin/class-searchcraft-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -1034,8 +1034,11 @@ private function searchcraft_on_layout_settings_config_request( $request ) {
if ( isset( $request['searchcraft_search_experience'] ) ) {
$experience = sanitize_text_field( wp_unslash( $request['searchcraft_search_experience'] ) );

// Validate the experience value.
$valid_experiences = array( 'full', 'popover' );
// Validate the experience value. Map legacy 'popover' to 'modal'.
if ( 'popover' === $experience ) {
$experience = 'modal';
}
$valid_experiences = array( 'full', 'modal', 'inline' );
if ( ! in_array( $experience, $valid_experiences, true ) ) {
$experience = 'full';
}
Expand Down Expand Up @@ -1485,6 +1488,30 @@ private function searchcraft_on_layout_settings_config_request( $request ) {
update_option( 'searchcraft_popover_element_behavior', $popover_element_behavior );
}

// Handle enable view all results setting.
$enable_view_all_results = isset( $request['searchcraft_enable_view_all_results'] ) ? true : false;
update_option( 'searchcraft_enable_view_all_results', $enable_view_all_results );

// Handle view all results label.
if ( isset( $request['searchcraft_view_all_results_label'] ) ) {
$view_all_results_label = sanitize_text_field( wp_unslash( $request['searchcraft_view_all_results_label'] ) );
update_option( 'searchcraft_view_all_results_label', $view_all_results_label );
}

// Handle overlay results per page setting.
if ( isset( $request['searchcraft_overlay_results_per_page'] ) ) {
$overlay_results_per_page = absint( wp_unslash( $request['searchcraft_overlay_results_per_page'] ) );

// Validate the overlay results per page value (between 1 and 20).
if ( $overlay_results_per_page < 1 ) {
$overlay_results_per_page = 1;
} elseif ( $overlay_results_per_page > 20 ) {
$overlay_results_per_page = 20;
}

update_option( 'searchcraft_overlay_results_per_page', $overlay_results_per_page );
}

// Handle retain get_search_form setting.
$retain_get_search_form = isset( $request['searchcraft_retain_get_search_form'] ) ? true : false;
update_option( 'searchcraft_retain_get_search_form', $retain_get_search_form );
Expand Down
62 changes: 36 additions & 26 deletions admin/js/searchcraft-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,27 @@ function toggleFormFields() {
row.classList.toggle('hidden', !isFullSelected);
});

// Show/hide popover fields
// Show/hide popover fields (modal and inline are both popover variants)
popoverOnlyRows.forEach((row) => {
row.classList.toggle('hidden', isFullSelected);
});
}

/**
* Toggle view all label row visibility based on checkbox state
*/
function toggleViewAllLabelRow() {
const checkbox = document.getElementById('searchcraft_enable_view_all_results');
const labelRows = document.querySelectorAll('.searchcraft-view-all-label-row');
if (!checkbox || !labelRows.length) {
return;
}
const isChecked = checkbox.checked;
labelRows.forEach((row) => {
row.style.display = isChecked ? '' : 'none';
});
}

/**
* Toggle filter panel options visibility
*/
Expand Down Expand Up @@ -647,32 +662,28 @@ function updateFilterPanelOrder() {
}

document.addEventListener('DOMContentLoaded', () => {
// Initialize color pickers
initColorPickers();

// Initialize password toggle functionality
initPasswordToggle();

// Initialize button with spinner functionality
initButtonWithSpinner();

// Initialize custom post type checkboxes
initCustomPostTypeCheckboxes();

// Initialize excerpt override inputs with datalist
initExcerptOverrideInputs();

// layout tab functionality
if (document.querySelector('.searchcraft-layout')) {
const fullRadio = document.querySelector('input[name="searchcraft_search_experience"][value="full"]');
const popoverRadio = document.querySelector('input[name="searchcraft_search_experience"][value="popover"]');
// Search behavior toggle for input container description
const onPageRadio = document.querySelector('input[name="searchcraft_search_behavior"][value="on_page"]');
const standAloneRadio = document.querySelector('input[name="searchcraft_search_behavior"][value="stand_alone"]');

// Initial state
toggleFormFields();
updateSearchInputContainerDescription();

// Add event listeners
fullRadio?.addEventListener('change', toggleFormFields);
popoverRadio?.addEventListener('change', toggleFormFields);
// Add event listeners for all three experience radio buttons
document.querySelectorAll('input[name="searchcraft_search_experience"]').forEach((radio) => {
radio.addEventListener('change', toggleFormFields);
});
onPageRadio?.addEventListener('change', updateSearchInputContainerDescription);
standAloneRadio?.addEventListener('change', updateSearchInputContainerDescription);

// Filter panel options toggle
const filterPanelCheckbox = document.getElementById('searchcraft_include_filter_panel');
Expand All @@ -684,20 +695,9 @@ document.addEventListener('DOMContentLoaded', () => {
filterPanelCheckbox.addEventListener('change', toggleFilterPanelOptions);
}

// Search behavior toggle for input container description
const onPageRadio = document.querySelector('input[name="searchcraft_search_behavior"][value="on_page"]');
const standAloneRadio = document.querySelector('input[name="searchcraft_search_behavior"][value="stand_alone"]');

// Initialize container ID tag UI
initContainerIdTagUI();

// Initial state
updateSearchInputContainerDescription();

// Add event listeners
onPageRadio?.addEventListener('change', updateSearchInputContainerDescription);
standAloneRadio?.addEventListener('change', updateSearchInputContainerDescription);

// Facets options toggle
const facetsCheckbox = document.getElementById('searchcraft_enable_facets');
if (facetsCheckbox) {
Expand All @@ -708,6 +708,16 @@ document.addEventListener('DOMContentLoaded', () => {
facetsCheckbox.addEventListener('change', toggleFacetsOptions);
}

// View all label row toggle
const viewAllCheckbox = document.getElementById('searchcraft_enable_view_all_results');
if (viewAllCheckbox) {
// Initial state
toggleViewAllLabelRow();

// Add event listener
viewAllCheckbox.addEventListener('change', toggleViewAllLabelRow);
}

// AI summary banner text toggle
const aiSummaryCheckbox = document.getElementById('searchcraft_enable_ai_summary');
if (aiSummaryCheckbox) {
Expand Down
65 changes: 62 additions & 3 deletions admin/partials/searchcraft-admin-layout-tab.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
$search_experience = get_option( 'searchcraft_search_experience', 'full' );
$include_filter_panel = get_option( 'searchcraft_include_filter_panel', false );
$results_per_page = get_option( 'searchcraft_results_per_page', 10 );
$overlay_results_per_page = get_option( 'searchcraft_overlay_results_per_page', 5 );
$enable_most_recent_toggle = get_option( 'searchcraft_enable_most_recent_toggle', '1' );
$enable_exact_match_toggle = get_option( 'searchcraft_enable_exact_match_toggle', '1' );
$enable_date_range = get_option( 'searchcraft_enable_date_range', '1' );
Expand Down Expand Up @@ -89,6 +90,10 @@
<td>
<?php
$search_experience = get_option( 'searchcraft_search_experience', 'full' );
// Legacy: treat old 'popover' value as 'modal'.
if ( 'popover' === $search_experience ) {
$search_experience = 'modal';
}
?>
<fieldset>
<legend class="screen-reader-text"><span>Search Experience Type</span></legend>
Expand All @@ -98,12 +103,17 @@
</label>
<br><br>
<label>
<input type="radio" name="searchcraft_search_experience" value="popover" <?php checked( $search_experience, 'popover' ); ?> />
<strong>Popover</strong> - Compact search overlay that appears on demand
<input type="radio" name="searchcraft_search_experience" value="modal" <?php checked( $search_experience, 'modal' ); ?> />
<strong>Modal</strong> - Compact search overlay triggered by a search button, appearing in a modal
</label>
<br><br>
<label>
<input type="radio" name="searchcraft_search_experience" value="inline" <?php checked( $search_experience, 'inline' ); ?> />
<strong>Inline</strong> - Renders inline on the page, with results appearing as an overlay below
</label>
</fieldset>
<p class="description">
Choose how you want search to be presented to your users. The full experience provides deep filtering controls while the popover offers a simple, single input experience.
Choose how you want search to be presented to your users. The full experience provides deep filtering controls, while Modal and Inline offer a compact popover experience.
</p>
</td>
</tr>
Expand Down Expand Up @@ -233,6 +243,55 @@
</p>
</td>
</tr>
<tr class="searchcraft-popover-only">
<th scope="row">
<label for="searchcraft_enable_view_all_results">Enable View All Results</label>
</th>
<td>
<label for="searchcraft_enable_view_all_results">
<input
type="checkbox"
name="searchcraft_enable_view_all_results"
id="searchcraft_enable_view_all_results"
value="1"
<?php checked( get_option( 'searchcraft_enable_view_all_results', false ), true ); ?>
/>
Enable a &ldquo;View All Results&rdquo; link in the popover search form.
</label>
<p class="description">
When enabled, a link will appear in the search form directing users to the full search results page.
</p>
</td>
</tr>
<tr class="searchcraft-popover-only searchcraft-view-all-label-row">
<th scope="row">
<label for="searchcraft_view_all_results_label">View All Label</label>
</th>
<td>
<?php
$view_all_results_label = get_option( 'searchcraft_view_all_results_label', '' );
?>
<input type="text" name="searchcraft_view_all_results_label" id="searchcraft_view_all_results_label" value="<?php echo esc_attr( $view_all_results_label ); ?>" class="regular-text" placeholder="View All" />
<p class="description">
The label text for the &ldquo;View All Results&rdquo; link.
</p>
</td>
</tr>
<tr class="searchcraft-popover-only">
<th scope="row">
<label for="searchcraft_overlay_results_per_page">Results in Overlay</label>
</th>
<td>
<select name="searchcraft_overlay_results_per_page" id="searchcraft_overlay_results_per_page" class="regular-text">
<?php for ( $i = 1; $i <= 20; $i++ ) : ?>
<option value="<?php echo esc_attr( $i ); ?>" <?php selected( $overlay_results_per_page, $i ); ?>><?php echo esc_html( $i ); ?></option>
<?php endfor; ?>
</select>
<p class="description">
Number of search results to display in the modal or inline overlay. Default is 5 results.
</p>
</td>
</tr>
</tbody>
</table>
</div>
Expand Down
4 changes: 3 additions & 1 deletion public/class-searchcraft-public.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,8 @@ public function get_js_config() {
$oldest_post_year = $admin_instance->get_oldest_post_year();
$js_config['oldestPostYear'] = $oldest_post_year;

$js_config['resultsPerPage'] = intval( get_option( 'searchcraft_results_per_page', 10 ) );
$js_config['resultsPerPage'] = intval( get_option( 'searchcraft_results_per_page', 10 ) );
$js_config['overlayResultsPerPage'] = intval( get_option( 'searchcraft_overlay_results_per_page', 5 ) );

// Filter taxonomies.
$filter_taxonomies = get_option( 'searchcraft_filter_taxonomies', array() );
Expand Down Expand Up @@ -387,6 +388,7 @@ private function prepare_script_data() {
'resultsContainerId' => $results_container_id,
'popoverContainerId' => $popover_container_id,
'popoverInsertBehavior' => $popover_insert_behavior,
'isSearchPage' => is_search(),
);
}

Expand Down
11 changes: 10 additions & 1 deletion public/js/searchcraft-sdk-integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,21 @@
return;
}
const isWPSearchPage = searchcraft_config.isWPSearchPage || false;

// Determine which results per page setting to use
// Use overlayResultsPerPage for modal/inline when NOT on search page
// Use regular resultsPerPage for full experience or when on search page
let resultsPerPage = parseInt(searchcraft_config.resultsPerPage) || 10;
if (!isWPSearchPage && searchcraft_config.overlayResultsPerPage) {
resultsPerPage = parseInt(searchcraft_config.overlayResultsPerPage) || 5;
}

const config = {
indexName: searchcraft_config.indexName,
readKey: searchcraft_config.readKey,
endpointURL: searchcraft_config.endpointURL,
searchDebounceDelay: 50,
searchResultsPerPage: parseInt(searchcraft_config.resultsPerPage) || 10
searchResultsPerPage: resultsPerPage
};

// Add cortexURL if AI summary is enabled
Expand Down
26 changes: 20 additions & 6 deletions public/js/searchcraft-sdk-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,31 @@

templatesInjected = true;

// Handle full experience or popover with no container specified
if (settings.searchExperience === 'full' ||
(settings.searchExperience === 'popover' && !settings.popoverContainerId)) {
const isPopover = settings.searchExperience === 'modal' || settings.searchExperience === 'inline'
// Legacy support for old 'popover' value.
|| settings.searchExperience === 'popover';

const isSearchPage = settings.isSearchPage == 1;
// On search page with modal/inline, always inject full header + results
if (isSearchPage && isPopover) {
injectSearchHeader(settings.headerContent, settings.inputContainerId);
// Inject results content for full experience
if (settings.searchExperience === 'full' && settings.resultsContent) {
if (settings.resultsContent) {
injectSearchResults(settings.resultsContent, settings.resultsContainerId);
}
}
// Handle full experience
else if (settings.searchExperience === 'full') {
injectSearchHeader(settings.headerContent, settings.inputContainerId);
if (settings.resultsContent) {
injectSearchResults(settings.resultsContent, settings.resultsContainerId);
}
}
// Handle popover with no container specified
else if (isPopover && !settings.popoverContainerId) {
injectSearchHeader(settings.headerContent, settings.inputContainerId);
}
// Handle popover with specific container
else if (settings.searchExperience === 'popover' && settings.popoverContainerId) {
else if (isPopover && settings.popoverContainerId) {
injectPopoverContent(
settings.headerContent,
settings.popoverContainerId,
Expand Down
46 changes: 23 additions & 23 deletions public/sdk/components/defineCustomElements.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { defineCustomElement as define_searchcraft_ad } from './searchcraft-ad.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_button } from './searchcraft-button.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_error_message } from './searchcraft-error-message.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_facet_list } from './searchcraft-facet-list.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_filter_panel } from './searchcraft-filter-panel.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_input_form } from './searchcraft-input-form.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_input_label } from './searchcraft-input-label.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_loading } from './searchcraft-loading.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_pagination } from './searchcraft-pagination.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_popover_button } from './searchcraft-popover-button.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_popover_footer } from './searchcraft-popover-footer.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_popover_form } from './searchcraft-popover-form.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_popover_list_item } from './searchcraft-popover-list-item.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_popover_list_view } from './searchcraft-popover-list-view.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_results_info } from './searchcraft-results-info.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_search_result } from './searchcraft-search-result.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_search_results_per_page } from './searchcraft-search-results-per-page.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_search_results } from './searchcraft-search-results.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_select } from './searchcraft-select.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_slider } from './searchcraft-slider.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_summary_box } from './searchcraft-summary-box.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_theme } from './searchcraft-theme.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_toggle_button } from './searchcraft-toggle-button.js?v=0.13.3';
import { defineCustomElement as define_searchcraft_ad } from './searchcraft-ad.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_button } from './searchcraft-button.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_error_message } from './searchcraft-error-message.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_facet_list } from './searchcraft-facet-list.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_filter_panel } from './searchcraft-filter-panel.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_input_form } from './searchcraft-input-form.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_input_label } from './searchcraft-input-label.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_loading } from './searchcraft-loading.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_pagination } from './searchcraft-pagination.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_popover_button } from './searchcraft-popover-button.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_popover_footer } from './searchcraft-popover-footer.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_popover_form } from './searchcraft-popover-form.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_popover_list_item } from './searchcraft-popover-list-item.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_popover_list_view } from './searchcraft-popover-list-view.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_results_info } from './searchcraft-results-info.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_search_result } from './searchcraft-search-result.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_search_results_per_page } from './searchcraft-search-results-per-page.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_search_results } from './searchcraft-search-results.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_select } from './searchcraft-select.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_slider } from './searchcraft-slider.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_summary_box } from './searchcraft-summary-box.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_theme } from './searchcraft-theme.js?scv=0.14.0';
import { defineCustomElement as define_searchcraft_toggle_button } from './searchcraft-toggle-button.js?scv=0.14.0';

export const defineCustomElements = () => {
define_searchcraft_ad();
Expand Down
Loading