diff --git a/app/assets/javascripts/spotlight/blacklight_configuration.js b/app/assets/javascripts/spotlight/blacklight_configuration.js index 2376b48ec..c49f796bc 100644 --- a/app/assets/javascripts/spotlight/blacklight_configuration.js +++ b/app/assets/javascripts/spotlight/blacklight_configuration.js @@ -1,4 +1,7 @@ Spotlight.onLoad(function() { + // Add Select/Deselect all button behavior + addCheckboxToggleBehavior(); + // Initialize Nestable for nested pages $('#nested-fields .metadata_fields').nestable({maxDepth: 1, listNodeName: "tbody", itemNodeName: "tr", expandBtnHTML: "", collapseBtnHTML: "" }); $('#nested-fields.facet_fields').nestable({maxDepth: 1}); @@ -35,3 +38,46 @@ Spotlight.onLoad(function() { return false; }); }); + +// Add Select/Deselect all button behavior +function addCheckboxToggleBehavior() { + $("[data-behavior='metadata-select']").each(function(){ + var button = $(this) + var parentCell = button.parents("th"); + var table = parentCell.closest("table"); + var columnRows = $("tr td:nth-child(" + (parentCell.index() + 1) + ")", table); + var checkboxes = $("input[type='checkbox']", columnRows); + swapSelectAllButtonText(button, columnRows); + // Add the check/uncheck behavior to the button + // and swap the button text if necessary + button.on('click', function(e){ + e.preventDefault(); + var allChecked = allCheckboxesChecked(columnRows); + columnRows.each(function(){ + $("input[type='checkbox']", $(this)).prop('checked', !allChecked); + swapSelectAllButtonText(button, columnRows); + }); + }); + // Swap button text when a checkbox value changes + checkboxes.each(function(){ + $(this).on('change', function(){ + swapSelectAllButtonText(button, columnRows); + }); + }); + }); + // Check number of checkboxes against the number of checked + // checkboxes to determine if all of them are checked or not + function allCheckboxesChecked(elements) { + return ($("input[type='checkbox']", elements).length == $("input[type='checkbox']:checked", elements).length) + } + // Swap the button text to "Deselect all" + // when all the checkboxes are checked and + // "Select all" when any are unchecked + function swapSelectAllButtonText(button, elements) { + if ( allCheckboxesChecked(elements) ) { + button.text(button.data('deselect-text')); + } else { + button.text(button.data('select-text')); + } + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/spotlight/_blacklight_configuration.css.scss b/app/assets/stylesheets/spotlight/_blacklight_configuration.css.scss index 2e41cf114..4ea6e1abb 100644 --- a/app/assets/stylesheets/spotlight/_blacklight_configuration.css.scss +++ b/app/assets/stylesheets/spotlight/_blacklight_configuration.css.scss @@ -56,5 +56,8 @@ } text-align:center; } - + .metadata-select { + display: inline-block; + min-width: 72px; + } } diff --git a/app/helpers/spotlight/application_helper.rb b/app/helpers/spotlight/application_helper.rb index 52aa6ed5a..111482ec8 100644 --- a/app/helpers/spotlight/application_helper.rb +++ b/app/helpers/spotlight/application_helper.rb @@ -95,6 +95,18 @@ def render_save_this_search? (params[:controller] != "spotlight_catalog_controller" && params[:action] != "admin") end + def select_deselect_button + button_tag( + t(:".deselect_all"), + class: "btn btn-default btn-xs metadata-select", + data: { + :behavior => "metadata-select", + :'deselect-text' => t(:".deselect_all"), + :'select-text' => t(:".select_all") + } + ) + end + private def field_enabled? field, view = nil diff --git a/app/views/spotlight/blacklight_configurations/edit_metadata_fields.html.erb b/app/views/spotlight/blacklight_configurations/edit_metadata_fields.html.erb index b6a08eff5..a3786546f 100644 --- a/app/views/spotlight/blacklight_configurations/edit_metadata_fields.html.erb +++ b/app/views/spotlight/blacklight_configurations/edit_metadata_fields.html.erb @@ -10,10 +10,19 @@ <%= t :'.fields.label' %> - <%= t :'.view.show', default: t(:'blacklight.search.view.show') %> + +
+ <%= t :'.view.show', default: t(:'blacklight.search.view.show') %> +
+ <%= select_deselect_button %> + <% @blacklight_configuration.blacklight_config.view.keys.each do |type| %> - - <%= t :".view.#{type}", default: t(:".view.#{type}") %> + +
+ <%= t :".view.#{type}", default: t(:".view.#{type}") %> +
+ <%= select_deselect_button %> + <% end %> diff --git a/config/locales/spotlight.en.yml b/config/locales/spotlight.en.yml index 93c3970b7..b5a815920 100644 --- a/config/locales/spotlight.en.yml +++ b/config/locales/spotlight.en.yml @@ -146,6 +146,8 @@ en: edit_metadata_fields: field: label: "Field name" + deselect_all: "Deselect all" + select_all: "Select all" header: "Metadata" order_header: "Display and Order Metadata Fields" exhibit_specific: diff --git a/spec/features/javascript/metadata_admin_spec.rb b/spec/features/javascript/metadata_admin_spec.rb new file mode 100644 index 000000000..eda3db810 --- /dev/null +++ b/spec/features/javascript/metadata_admin_spec.rb @@ -0,0 +1,38 @@ +require "spec_helper" + +feature "Metadata Administration", js: true do + let(:exhibit) { FactoryGirl.create(:exhibit) } + let(:admin) { FactoryGirl.create(:exhibit_admin, exhibit: exhibit) } + before { login_as admin } + describe "Select/Deselect all button" do + it "should deselect all checkboxes when all are selected" do + visit spotlight.exhibit_edit_metadata_path exhibit + # No checkboxes should be unchecked + expect(page).not_to have_css("tr td:nth-child(2) input[type='checkbox']:not(:checked)") + within("tr th:nth-child(2)") do + click_button "Deselect all" + expect(page).to have_css("button", text: "Select all", visible: true) + end + # No checkboxes should be checked + expect(page).not_to have_css("tr td:nth-child(2) input[type='checkbox']:checked") + end + it "should select all checkboxes when any are unselected" do + visit spotlight.exhibit_edit_metadata_path exhibit + # No checkboxes should be unchecked + expect(page).not_to have_css("tr td:nth-child(2) input[type='checkbox']:not(:checked)") + first_button_area = find("tr th:nth-child(2)") + within first_button_area do + expect(page).to have_css("button", text: "Deselect all") + end + # Uncheck first checkbox + find("tr:first-child td:nth-child(2) input[type='checkbox']").set(false) + # A checkbox should be checked + expect(page).to have_css("tr td:nth-child(2) input[type='checkbox']:checked") + within first_button_area do + click_button "Select all" + end + # No checkboxes should be unchecked + expect(page).not_to have_css("tr td:nth-child(2) input[type='checkbox']:not(:checked)") + end + end +end \ No newline at end of file