diff --git a/Gemfile b/Gemfile index c6ed51619..8a95d4106 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,8 @@ end gem 'erubis' gem 'govuk_admin_template', '~> 2.3.1' gem 'select2-rails', '3.5.9.1' +gem 'jquery-ui-rails', '~> 5.0.3' +gem 'selectize-rails', '0.12.1' gem 'momentjs-rails', '2.8.3' gem 'formtastic', '2.3.0' gem 'formtastic-bootstrap', '3.0.0' diff --git a/Gemfile.lock b/Gemfile.lock index e11d23942..2022ba92f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -148,6 +148,8 @@ GEM jquery-rails (3.1.3) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) + jquery-ui-rails (5.0.5) + railties (>= 3.2.16) json (1.8.3) json-schema (2.5.1) addressable (~> 2.3.7) @@ -275,6 +277,7 @@ GEM tilt (~> 1.3) select2-rails (3.5.9.1) thor (~> 0.14) + selectize-rails (0.12.1) shoulda (3.1.1) shoulda-context (~> 1.0) shoulda-matchers (~> 1.2) @@ -367,6 +370,7 @@ DEPENDENCIES has_scope inherited_resources jasmine (= 2.1.0) + jquery-ui-rails (~> 5.0.3) kaminari (= 0.13.0) launchy (= 2.1.1) logstasher (= 0.4.8) @@ -389,6 +393,7 @@ DEPENDENCIES reverse_markdown (= 0.3.0) sass-rails (= 3.2.6) select2-rails (= 3.5.9.1) + selectize-rails (= 0.12.1) shoulda (= 3.1.1) sidekiq (= 2.17.2) sidekiq-statsd (= 0.1.2) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index f4efd38ce..fe8609436 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,4 +1,6 @@ //= require select2 +//= require jquery-ui/sortable +//= require selectize //= require moment //= require mousetrap //= require jquery-ui.custom.min @@ -12,6 +14,7 @@ $(function () { $('a.preview').attr("target","_blank"); $('form.preview').attr("target","_blank"); $(".select2").select2({ allowClear: true }); + $(".selectize").selectize({ plugins: ['drag_drop','remove_button'], closeAfterSelect: true }); }) // System wide library functions diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 9ce45947a..40c84ef89 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -1,6 +1,8 @@ @import 'govuk_admin_template'; @import 'select2'; @import './vendor/select2-bootstrap'; +@import 'selectize'; +@import 'selectize.bootstrap3'; @import 'colors'; @import 'bootstrap_and_overrides'; @import 'forms'; @@ -17,3 +19,23 @@ // Pages @import 'downtime'; @import 'smart_answer_builder'; + +.selectize-dropdown-content { + .option { + span.highlight { + text-align: left; + padding: 0; + font-size: 14px; + color: #000000; + } + } +} + +.selectize-control.multi .selectize-input > div { + cursor: pointer; + margin: 0 3px 3px 0; + padding: 1px 3px; + background: #fff; + color: #555; + border: 1px solid #c1c1c1; +} \ No newline at end of file diff --git a/app/assets/stylesheets/forms.scss b/app/assets/stylesheets/forms.scss index 1e2b3941e..8370ab443 100644 --- a/app/assets/stylesheets/forms.scss +++ b/app/assets/stylesheets/forms.scss @@ -5,7 +5,7 @@ } .edition-tags { - .select2 { + .select2, .selectize { display: block; } } diff --git a/app/helpers/editions_helper.rb b/app/helpers/editions_helper.rb index 9cbc133fa..7aeed6f7f 100644 --- a/app/helpers/editions_helper.rb +++ b/app/helpers/editions_helper.rb @@ -35,4 +35,24 @@ def browse_options_for_select(grouped_collections) [parent_title, collections] end end + + def ordered_pages(unordered) + options = browse_options_for_select(unordered) + prioritise_data_container(options, @resource.browse_pages) + end + + # Re-orders the data container such that +selected+ ones appear first. + def prioritise_data_container(unprioritised_container, selected) + selected.reverse.each do |selected_value| + unprioritised_container.each do |topic, subtopics| + subtopics.each do |title, slug| + if selected_value == slug + subtopics.delete([title, slug]) + unprioritised_container.unshift( [topic, [[title, slug]]] ) + end + end + end + end + unprioritised_container + end end diff --git a/app/views/shared/_common_edition_tags.html.erb b/app/views/shared/_common_edition_tags.html.erb index b8ef62335..c93d1d20c 100644 --- a/app/views/shared/_common_edition_tags.html.erb +++ b/app/views/shared/_common_edition_tags.html.erb @@ -14,10 +14,10 @@ <%= f.label :browse_pages, "Mainstream browse pages", class: 'control-label remove-bottom-margin' %>

The first mainstream browse page will form the content’s breadcrumb

<%= f.select :browse_pages, - browse_options_for_select(Collections.grouped_mainstream_browse_pages), + ordered_pages(Collections.grouped_mainstream_browse_pages), {}, { multiple: true, - class: 'select2', + class: 'selectize', disabled: @resource.locked_for_edits?, data: { placeholder: 'Choose mainstream browse pages…' } } %> diff --git a/test/integration/tagging_to_collections_test.rb b/test/integration/tagging_to_collections_test.rb index efcdbe4ad..b79524a89 100644 --- a/test/integration/tagging_to_collections_test.rb +++ b/test/integration/tagging_to_collections_test.rb @@ -11,8 +11,7 @@ class TaggingToCollectionsTest < JavascriptIntegrationTest visit edition_path(edition) - select 'Tax: VAT', from: 'Mainstream browse pages' - select 'Tax: RTI (draft)', from: 'Mainstream browse pages' + selectize ['Tax: VAT', 'Tax: RTI (draft)'], 'Mainstream browse pages' save_edition_and_assert_success edition.reload diff --git a/test/integration_test_helper.rb b/test/integration_test_helper.rb index 5b110d82e..41c3226e4 100644 --- a/test/integration_test_helper.rb +++ b/test/integration_test_helper.rb @@ -139,6 +139,22 @@ def select2(value, scope) find(:xpath, "//body").find(".select2-results li", text: value).click end + def selectize(with, scope) + # clear any existing selections + page.execute_script("$('.selectize-input a.remove').click()"); + + select_field = page.find_field(scope, visible: false) + selectize_control = "select##{select_field[:id]} + .selectize-control" + + Array(with).each do |value| + # Fill in the value into the input field + page.execute_script("$('#{selectize_control} .selectize-input input').val('#{value}');") + # Simulate selecting the first option + page.execute_script("$('#{selectize_control} .selectize-input input').keyup();") + page.execute_script("$('#{selectize_control} div.option').first().mousedown();") + end + end + def assert_all_edition_fields_disabled(page) selector = '#edit input:not([disabled]):not([type="hidden"]), #edit select:not([disabled]), #edit textarea:not([disabled])' inputs = page.all(selector)