Skip to content

Commit

Permalink
Merge pull request #196 from MITLibraries/refactor-js
Browse files Browse the repository at this point in the history
Refactor search form JS
  • Loading branch information
jazairi authored Jun 24, 2024
2 parents f5a2e3c + ee75285 commit 0dde7fb
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 127 deletions.
24 changes: 16 additions & 8 deletions app/assets/stylesheets/partials/_search.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,6 @@
font-family: FontAwesome;
margin-right: 1rem;
}

&.closed:before {
content: '\f054';
}

&.open:before {
content: '\f078';
}
}

&::-webkit-details-marker {
Expand All @@ -71,6 +63,22 @@
color: $black;
}
}
#advanced-search-label,
#geobox-search-label,
#geodistance-search-label {
&::before {
content: '\f054';
}
}
&[open] {
#advanced-search-label,
#geobox-search-label,
#geodistance-search-label {
&::before {
content: '\f078';
}
}
}
}

#geobox-search-panel,
Expand Down
163 changes: 60 additions & 103 deletions app/javascript/search_form.js
Original file line number Diff line number Diff line change
@@ -1,123 +1,80 @@
function disableAdvanced() {
advanced_field.setAttribute('value', '');
if (geobox_label.classList.contains('closed') && geodistance_label.classList.contains('closed')) {
keyword_field.toggleAttribute('required');
keyword_field.classList.toggle('required');
keyword_field.setAttribute('placeholder', 'Enter your search');
}
[...details_panel.getElementsByClassName('field')].forEach(
field => field.value = ''
);
advanced_label.classList = 'closed';
};
var keywordField = document.getElementById('basic-search-main');
var advancedPanel = document.getElementById('advanced-search-panel');
var geoboxPanel = document.getElementById('geobox-search-panel');
var geodistancePanel = document.getElementById('geodistance-search-panel');
var allPanels = document.getElementsByClassName('form-panel');

function enableAdvanced() {
advanced_field.setAttribute('value', 'true');
if (geobox_label.classList.contains('closed') && geodistance_label.classList.contains('closed')) {
keyword_field.toggleAttribute('required');
keyword_field.classList.toggle('required');
keyword_field.setAttribute('placeholder', 'Keyword anywhere');
function togglePanelState(currentPanel) {
// Only the geoboxPanel and geodistancePanel inputs need to be required. Advanced search inputs do not.
if (currentPanel === geoboxPanel || currentPanel === geodistancePanel) {
toggleRequiredFieldset(currentPanel);
}
advanced_label.classList = 'open';
};

function disableGeobox() {
if (advanced_label.classList.contains('closed') && geodistance_label.classList.contains('closed')) {
keyword_field.toggleAttribute('required');
keyword_field.classList.toggle('required');
keyword_field.setAttribute('placeholder', 'Enter your search');
}
geobox_field.setAttribute('value', '');
[...geobox_details_panel.getElementsByClassName('field')].forEach(function(field) {
field.value = '';
field.classList.toggle('required');
field.toggleAttribute('required');
});
geobox_label.classList = 'closed';
};
// These two functions are delayed to ensure that events have propagated first. Otherwise, they will fire before
// the `open` attribute has toggled on the currentPanel, resulting in unexpected behavior.
setTimeout(toggleKeywordRequired, 0);
setTimeout(updateKeywordPlaceholder, 0);

function enableGeobox() {
if (advanced_label.classList.contains('closed') && geodistance_label.classList.contains('closed')) {
keyword_field.toggleAttribute('required');
keyword_field.classList.toggle('required');
keyword_field.setAttribute('placeholder', 'Keyword anywhere');
}
geobox_field.setAttribute('value', 'true');
[...geobox_details_panel.getElementsByClassName('field')].forEach(function(field) {
field.value = '';
field.classList.toggle('required');
field.toggleAttribute('required');
});
geobox_label.classList = 'open';
};
// Finally, enable or disable the search type of the current panel, based on whether it is open or not.
toggleSearch(currentPanel);
}

function disableGeodistance() {
if (advanced_label.classList.contains('closed') && geobox_label.classList.contains('closed')) {
keyword_field.toggleAttribute('required');
keyword_field.classList.toggle('required');
keyword_field.setAttribute('placeholder', 'Enter your search');
}
geodistance_field.setAttribute('value', '');
[...geodistance_details_panel.getElementsByClassName('field')].forEach(function(field) {
function toggleRequiredFieldset(panel) {
[...panel.getElementsByClassName('field')].forEach((field) => {
field.value = '';
field.classList.toggle('required');
field.toggleAttribute('required');
});
geodistance_label.classList = 'closed';
};
}

function enableGeodistance() {
if (advanced_label.classList.contains('closed') && geobox_label.classList.contains('closed')) {
keyword_field.toggleAttribute('required');
keyword_field.classList.toggle('required');
keyword_field.setAttribute('placeholder', 'Keyword anywhere');
}
geodistance_field.setAttribute('value', 'true');
[...geodistance_details_panel.getElementsByClassName('field')].forEach(function(field) {
field.value = '';
field.classList.toggle('required');
field.toggleAttribute('required');
});
geodistance_label.classList = 'open';
};


var advanced_field = document.getElementById('advanced-search-field');
var advanced_label = document.getElementById('advanced-search-label');
var advanced_toggle = document.getElementById('advanced-summary');
var details_panel = document.getElementById('advanced-search-panel');
var keyword_field = document.getElementById('basic-search-main');
var geobox_field = document.getElementById('geobox-search-field');
var geobox_label = document.getElementById('geobox-search-label');
var geobox_toggle = document.getElementById('geobox-summary');
var geobox_details_panel = document.getElementById('geobox-search-panel');
var geodistance_field = document.getElementById('geodistance-search-field');
var geodistance_label = document.getElementById('geodistance-search-label');
var geodistance_toggle = document.getElementById('geodistance-summary');
var geodistance_details_panel = document.getElementById('geodistance-search-panel');

geobox_toggle.addEventListener('click', event => {
if (geobox_details_panel.attributes.hasOwnProperty('open')) {
disableGeobox();
// Each panel has a hidden input that, when true, enables that type of search.
function toggleSearch(panel) {
let input = panel.querySelector('.fieldset-toggle');
if (panel.open) {
input.setAttribute('value', '');
} else {
enableGeobox();
input.setAttribute('value', 'true');
}
});
}

geodistance_toggle.addEventListener('click', event => {
if (geodistance_details_panel.attributes.hasOwnProperty('open')) {
disableGeodistance();
// The keyword field is required only if all panels are closed.
function toggleKeywordRequired() {
if (Array.from(allPanels).every((panel) => !panel.open)) {
keywordField.setAttribute('required', '');
keywordField.classList.add('required');
} else {
enableGeodistance();
keywordField.removeAttribute('required');
keywordField.classList.remove('required');
}
});
}

advanced_toggle.addEventListener('click', event => {
if (details_panel.attributes.hasOwnProperty('open')) {
disableAdvanced();
// Placeholder text should be 'Keyword anywhere' if any panels are open, and 'Enter your search' otherwise.
function updateKeywordPlaceholder() {
if (Array.from(allPanels).some((panel) => panel.open)) {
keywordField.setAttribute('placeholder', 'Keyword anywhere');
} else {
enableAdvanced();
keywordField.setAttribute('placeholder', 'Enter your search');
}
});
}

// Add event listeners for all panels in the DOM. For GDT, this is currently both geospatial panels and the advanced
// panel. In all other TIMDEX UI apps, it's just the advanced panel.
if (Array.from(allPanels).includes(geoboxPanel && geodistancePanel)) {
document.getElementById('geobox-summary').addEventListener('click', () => {
togglePanelState(geoboxPanel);
});

document.getElementById('geodistance-summary').addEventListener('click', () => {
togglePanelState(geodistancePanel);
});

document.getElementById('advanced-summary').addEventListener('click', () => {
togglePanelState(advancedPanel);
});
} else {
document.getElementById('advanced-summary').addEventListener('click', () => {
togglePanelState(advancedPanel);
});
}

console.log('search_form.js loaded');
32 changes: 16 additions & 16 deletions app/views/search/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
<%
# Initial form setup is determined by the advanced parameter. Thereafter it is altered by javascript.
advanced_label = "Search by title, author, etc."
advanced_label_class = "closed"
search_required = true
if params[:advanced] == "true"
advanced_label_class = "open"
search_required = false
end

geobox_label = "Geospatial bounding box search"
geobox_label_class = "closed"
if params[:geobox] == "true"
geobox_label_class = "open"
geobox_required = true
search_required = false
end

geodistance_label = "Geospatial distance search"
geodistance_label_class = "closed"
if params[:geodistance] == "true"
geodistance_label_class = "open"
geodistance_required = true
search_required = false
end

# Placeholder text for the keyword input changes if any of the search panels are open.
keyword_placeholder = search_required ? "Enter your search" : "Keyword anywhere"
%>

<form id="basic-search" class="form-horizontal basic-search" action="<%= results_path %>" method="get" role="search">
<div class="form-group">
<input id="basic-search-main" type="search"
class="field field-text basic-search-input <%= "required" if search_required %>" name="q"
title="Keyword anywhere" placeholder="Enter your search"
title="Keyword anywhere" placeholder="<%= keyword_placeholder %>"
value="<%= params[:q] %>" <%= 'required' if search_required %>
<%= 'aria-describedby=site-desc' if Flipflop.enabled?(:gdt) %>>

<% if Flipflop.enabled?(:gdt) %>
<details id="geobox-search-panel" <%= "open" if params[:geobox] == "true" %>>
<details id="geobox-search-panel" class="form-panel" <%= "open" if params[:geobox] == "true" %>>
<summary class="btn button-secondary" id="geobox-summary">
<span id="geobox-search-label" class="<%= geobox_label_class %>"><%= geobox_label %></span>
<span id="geobox-search-label"><%= geobox_label %></span>
</summary>
<input id="geobox-search-field" type="hidden" name="geobox" value="<%= params[:geobox] %>">
<input id="geobox-search-field" class="fieldset-toggle" type="hidden" name="geobox"
value="<%= params[:geobox] %>">
<fieldset>
<legend>Search within a geospatial bounding box</legend>
<p>* All fields in this section are required</p>
Expand Down Expand Up @@ -94,11 +92,12 @@ end
</div>
</fieldset>
</details>
<details id="geodistance-search-panel" <%= "open" if params[:geodistance] == "true" %>>
<details id="geodistance-search-panel" class="form-panel" <%= "open" if params[:geodistance] == "true" %>>
<summary class="btn button-secondary" id="geodistance-summary">
<span id="geodistance-search-label" class="<%= geodistance_label_class %>"><%= geodistance_label %></span>
<span id="geodistance-search-label"><%= geodistance_label %></span>
</summary>
<input id="geodistance-search-field" type="hidden" name="geodistance" value="<%= params[:geodistance] %>">
<input id="geodistance-search-field" class="fieldset-toggle" type="hidden" name="geodistance"
value="<%= params[:geodistance] %>">
<fieldset>
<legend>Search within a distance of a geographic point</legend>
<p>* All fields in this section are required</p>
Expand Down Expand Up @@ -145,11 +144,12 @@ end
</details>
<% end %>

<details id="advanced-search-panel" <%= "open" if params[:advanced] == "true" %>>
<details id="advanced-search-panel" class="form-panel" <%= "open" if params[:advanced] == "true" %>>
<summary class="btn button-secondary" id="advanced-summary">
<span id="advanced-search-label"class="<%= advanced_label_class %>"><%= advanced_label %></span>
<span id="advanced-search-label"><%= advanced_label %></span>
</summary>
<input id="advanced-search-field" type="hidden" name="advanced" value="<%= params[:advanced] %>">
<input id="advanced-search-field" class="fieldset-toggle" type="hidden" name="advanced"
value="<%= params[:advanced] %>">
<div class="field-container">
<div class="field-wrap">
<label for="advanced-title" class="field-label">Title</label>
Expand Down

0 comments on commit 0dde7fb

Please sign in to comment.