Skip to content

Commit

Permalink
Advanced Search Close better Dirty Check (#945)
Browse files Browse the repository at this point in the history
* chore: update close in advanced search to check if the form is dirty e.g. modified before confirming close

* chore: change dirty method to be private and add in a test case where just the field was changed
  • Loading branch information
ericenns authored Feb 13, 2025
1 parent b987b2f commit 5c7825f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 5 deletions.
20 changes: 16 additions & 4 deletions app/javascript/controllers/advanced_search_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ export default class extends Controller {
event.preventDefault();
event.stopImmediatePropagation();
}
else if (
this.searchGroupsContainerTarget.innerHTML.trim() ===
this.searchGroupsTemplateTarget.innerHTML.trim()
) {
else if (!this.#dirty()) {
this.clear();
} else {
if (window.confirm(this.confirmCloseTextValue)) {
Expand Down Expand Up @@ -181,4 +178,19 @@ export default class extends Controller {
.replace(/CONDITION_INDEX_PLACEHOLDER/g, condition_index);
group.lastElementChild.insertAdjacentHTML("beforebegin", newCondition);
}

#dirty() {
let dirty = true;
if (this.searchGroupsContainerTarget.innerHTML.trim() === this.searchGroupsTemplateTarget.innerHTML.trim()) {
dirty = false;
const currentInputs = this.searchGroupsContainerTarget.querySelectorAll("[id^='q_groups_attributes_']");
const originalInputs = this.searchGroupsTemplateTarget.content.querySelectorAll("[id^='q_groups_attributes_']");
originalInputs.forEach((item, index) => {
if (item.value !== currentInputs[index].value) {
dirty = true;
}
});
}
return dirty;
}
}
43 changes: 43 additions & 0 deletions test/components/advanced_search_component_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,49 @@ class AdvancedSearchComponentTest < ApplicationSystemTestCase
assert_includes text, I18n.t(:'advanced_search_component.confirm_close_text')
assert_no_selector 'h1', text: I18n.t(:'advanced_search_component.title')
end

click_button I18n.t(:'advanced_search_component.title')
within 'dialog' do
# verify accessibility
assert_accessible

# verify the form is pre-populated
assert_selector 'h1', text: I18n.t(:'advanced_search_component.title')
assert_selector "div[data-advanced-search-target='groupsContainer']", count: 1
within all("div[data-advanced-search-target='groupsContainer']")[0] do
assert_selector "div[data-advanced-search-target='conditionsContainer']", count: 1
end

# verify the dialog has a close button
assert_selector ".dialog--header button[aria-label='#{I18n.t('components.dialog.close')}']"

# select a value for field
within all("div[data-advanced-search-target='groupsContainer']")[0] do
within all("div[data-advanced-search-target='conditionsContainer']")[0] do
find("select[name$='[field]']").find("option[value='metadata.age']").select_option
end
end

# verify that the dialog close action prompts a confirm dialog if unapplied filters
text = dismiss_confirm do
click_button I18n.t('components.dialog.close')
end
assert_includes text, I18n.t(:'advanced_search_component.confirm_close_text')

# verify that dismissing the confirm keeps the unapplied filters and dialog open
within all("div[data-advanced-search-target='groupsContainer']")[0] do
within all("div[data-advanced-search-target='conditionsContainer']")[0] do
assert_equal 'metadata.age', find("select[name$='[field]']").find("option[value='metadata.age']").value
end
end

# verify that accepting the confirm discards the unapplied filters and closes the dialog
text = accept_confirm do
click_button I18n.t('components.dialog.close')
end
assert_includes text, I18n.t(:'advanced_search_component.confirm_close_text')
assert_no_selector 'h1', text: I18n.t(:'advanced_search_component.title')
end
end
end
end
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<%= form_with model: search, url: "#", data: { controller: "advanced-search" } do |form| %>
<%= form_with model: search, scope: :q, url: "#" do |form| %>
<%= render AdvancedSearchComponent.new(search:, form:, fields:, operations:) %>
<% end %>

0 comments on commit 5c7825f

Please sign in to comment.