Skip to content

Commit c748b19

Browse files
authored
Updating the department select to utilize LuxInputMultiSelect (#2251)
The component only allows an item to be selected once (only for non async results which departments are). fixes #2134
1 parent 2dcca6c commit c748b19

File tree

8 files changed

+96
-74
lines changed

8 files changed

+96
-74
lines changed

app/assets/stylesheets/_wizard.scss

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@
155155
.modal-content .text-input,
156156
.lux-field {
157157
width: 100%;
158+
159+
.search-icon {
160+
top: 0.5rem;
161+
}
158162
}
159163
}
160164

@@ -518,7 +522,8 @@
518522
}
519523

520524
.data-manager .text-input,
521-
.data-sponsor .text-input {
525+
.data-sponsor .text-input,
526+
.departments .text-input {
522527
width: 95%;
523528
}
524529

app/views/new_project_wizard/_form_department_input.html.erb

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,36 @@
22
<%= render partial: "/new_project_wizard/form_field_label",
33
locals: {field_label: "Department(s)", field_sub_label: "Required"} %>
44
<div class="input-frame">
5-
<div class="text-input">
5+
<div class="text-input lux-field">
66
<div class="horizontal-frame">
77
<div class="vertical-frame">
8-
<input class="form-input datalist" type="text" name="department_find" id="department_find"
9-
list="princeton_departments" placeholder="Search using department code or name" autocomplete="off"></input>
10-
<datalist id="princeton_departments">
11-
<% @princeton_departments.each do |department| %>
12-
<!-- Non breaking space &nbsp; is at the end of every option to indicate an option was selected not just the user typing -->
13-
<option data-value="<%= {code: department.code, name: department.name}.to_json %>" value="<%= "(#{department.code}) #{department.name}" %>&nbsp;"></option>
14-
<% end %>
15-
</datalist>
8+
<div class="lux-field">
9+
<lux-input-multiselect
10+
label="Departments"
11+
hide-label="true"
12+
selected-items-label=""
13+
none-selected-label="No departments selected"
14+
placeholder="Search using department code or name"
15+
:items='<%= @princeton_departments.map{|dep| {id: dep.code, label: "(#{dep.code}) #{dep.name}", value: dep.name }}.to_json %>'
16+
:default-values="<%= departments.map{|dep| {id: dep['code'], value: dep['name']}}.to_json %>"
17+
>
18+
<template #item="{itemProps}">
19+
<div class="info">
20+
<lux-badge class="badge">
21+
<div class="badge-text">{{ itemProps.id }}</div>
22+
</lux-badge>
23+
<div class="item-text">{{ itemProps.value }}</div>
24+
</div>
25+
</template>
26+
27+
<template v-slot:hidden-input="{ selectedItems }">
28+
<input v-for="item in selectedItems" type="hidden" name="request[departments][]" :value="JSON.stringify( {'code': item.id, 'name': item.value})" class="selected-item"></input>
29+
</template>
30+
</lux-input-multiselect>
31+
</div>
1632
<div class="input-error">
1733
<%= department_error %>
1834
</div>
19-
<ul class="selected-departments selected-items">
20-
<% departments.each do |department| %>
21-
<li class="selected-item">
22-
<%= "(#{department['code']}) #{department['name']}" %>
23-
<div tabindex="0" class="remove-department remove-item" title="Remove department"></div>
24-
<input type="hidden" name="request[departments][]" value="<%= {code: department['code'], name: department['name']}.to_json %>"> </input>
25-
</li>
26-
<% end %>
27-
</ul>
2835
<input type="hidden" id="request-departments" name="request[departments][]" value="" />
2936
</div>
3037
</div>

app/views/new_project_wizard/_review_and_submit_form.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="section">
1+
<div class="section lux">
22
<div class="section-title">
33
<div class="section-frame">
44
Project Information - Basic Details
Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
<% content_for :title, "New Project Request" %>
22
<% content_for :form_title, "Basic Details" %>
33
<% content_for :form_description, "Tell us a little about your project! These details are important for setting up and organizing your project." %>
4-
<%= render partial: "/new_project_wizard/form_project_title_input", locals: {project_title: @request_model.project_title || "", project_title_error: "", input_id: "project_title" } %>
5-
<%= render partial: "/new_project_wizard/form_project_path_input", locals: {project_folder: @request_model.project_folder || "", project_folder_error: "",
6-
parent_folder: @request_model.parent_folder || "", parent_folder_error: ""} %>
7-
<%= render partial: "/new_project_wizard/form_project_purpose_input", locals: {project_purpose: @request_model.project_purpose || "", project_purpose_error: "" } %>
8-
<%= render partial: "/new_project_wizard/form_project_description_input", locals: {description: @request_model.description || "", description_error: "" } %>
9-
<%= render partial: "/new_project_wizard/form_department_input", locals: {departments: @request_model.departments || [], department_error: "" } %>
4+
<div class="lux">
5+
<%= render partial: "/new_project_wizard/form_project_title_input", locals: {project_title: @request_model.project_title || "", project_title_error: "", input_id: "project_title" } %>
6+
<%= render partial: "/new_project_wizard/form_project_path_input", locals: {project_folder: @request_model.project_folder || "", project_folder_error: "",
7+
parent_folder: @request_model.parent_folder || "", parent_folder_error: ""} %>
8+
<%= render partial: "/new_project_wizard/form_project_purpose_input", locals: {project_purpose: @request_model.project_purpose || "", project_purpose_error: "" } %>
9+
<%= render partial: "/new_project_wizard/form_project_description_input", locals: {description: @request_model.description || "", description_error: "" } %>
10+
<%= render partial: "/new_project_wizard/form_department_input", locals: {departments: @request_model.departments || [], department_error: "" } %>
11+
</div>

spec/support/select_department.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
def select_and_verify_department(department:, department_code:, department_list:)
3+
select_department(department:, department_code:)
4+
5+
within(".departments") do
6+
# The user selected is visible on the page
7+
expect(page).to have_content(department)
8+
# the hidden input has all the users
9+
expect(page).to have_field("request[departments][]", type: :hidden, with: { code: department_code, name: department }.to_json)
10+
11+
department_list.each do |old_department|
12+
expect(page).to have_field("request[departments][]", type: :hidden, with: { code: old_department[:code], name: old_department[:name] }.to_json)
13+
end
14+
15+
# the javascript cleared the find to get ready for the next search
16+
expect(page.find(".lux-field input").value).to eq("")
17+
end
18+
end
19+
20+
def select_department(department:, department_code:)
21+
within(".departments") do
22+
page.find(".lux-field input").fill_in with: department_code
23+
expect(page).to have_content department
24+
find(".lux-autocomplete-result").click
25+
end
26+
end

spec/system/new_project_request_wizard_spec.rb

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,9 @@
8282
select "Teaching", from: :project_purpose
8383
fill_in :description, with: "An awesome project to show the wizard is magic"
8484
expect(page).to have_content "46/1000 characters"
85-
expect(page).not_to have_content("(77777) RDSS-Research Data and Scholarship Services")
86-
# Non breaking space `u00A0` is at the end of every option to indicate an option was selected
87-
select "(77777) RDSS-Research Data and Scholarship Services\u00A0", from: "department_find"
88-
# This is triggering the html5 element like it would normally if the page has focus
89-
page.find(:datalist_input, "department_find").execute_script("document.getElementById('department_find').dispatchEvent(new Event('input'))")
90-
expect(page).to have_content("(77777) RDSS-Research Data and Scholarship Services")
91-
expect(page).to have_field("request[departments][]", type: :hidden, with: "{\"code\":\"77777\",\"name\":\"RDSS-Research Data and Scholarship Services\"}")
85+
expect(page).not_to have_content("RDSS-Research Data and Scholarship Services")
86+
select_and_verify_department(department: "RDSS-Research Data and Scholarship Services", department_code: "77777", department_list: [])
87+
select_and_verify_department(department: "HPC-High Performance Computing", department_code: "66666", department_list: [{ code: "77777", name: "RDSS-Research Data and Scholarship Services" }])
9288

9389
select_user(current_user, "data_sponsor", "request[data_sponsor]")
9490
select_user(current_user, "data_manager", "request[data_manager]")
@@ -156,14 +152,9 @@
156152
fill_in :project_folder, with: "skeletor"
157153
fill_in :description, with: "An awesome project to show the wizard is magic"
158154
expect(page).to have_content "46/1000 characters"
159-
expect(page).not_to have_content("(77777) RDSS-Research Data and Scholarship Services")
160-
# Non breaking space `u00A0` is at the end of every option to indicate an option was selected
161-
select "(77777) RDSS-Research Data and Scholarship Services\u00A0", from: "department_find"
162155
select "Research", from: "project_purpose"
163-
# This is triggering the html5 element like it would normally if the page has focus
164-
page.find(:datalist_input, "department_find").execute_script("document.getElementById('department_find').dispatchEvent(new Event('input'))")
165-
expect(page).to have_content("(77777) RDSS-Research Data and Scholarship Services")
166-
expect(page).to have_field("request[departments][]", type: :hidden, with: "{\"code\":\"77777\",\"name\":\"RDSS-Research Data and Scholarship Services\"}")
156+
expect(page).not_to have_content("RDSS-Research Data and Scholarship Services")
157+
select_and_verify_department(department: "RDSS-Research Data and Scholarship Services", department_code: "77777", department_list: [])
167158

168159
# force a save and page reload to make sure all data is being saved to the model
169160
click_on "Next"
@@ -184,7 +175,7 @@
184175
expect(page).to have_field("parent_folder", with: "abc_lab")
185176
expect(page).to have_field("project_folder", with: "skeletor")
186177
expect(page).to have_field("description", with: "An awesome project to show the wizard is magic")
187-
expect(page).to have_content("(77777) RDSS-Research Data and Scholarship Services")
178+
expect(page).to have_content("RDSS-Research Data and Scholarship Services")
188179
expect(page).to have_field("request[departments][]", type: :hidden, with: "{\"code\":\"77777\",\"name\":\"RDSS-Research Data and Scholarship Services\"}")
189180
click_on "Next"
190181
# TODO: when the wizard is fully functional the correct next step(s) are below
@@ -273,17 +264,13 @@
273264
expect(page).to have_content "46/1000 characters"
274265

275266
# Select a department
276-
department_to_test = "(77777) RDSS-Research Data and Scholarship Services"
277-
expect(page).not_to have_content(department_to_test)
278-
# Non breaking space `u00A0` is at the end of every option to indicate an option was selected
279-
select "#{department_to_test}\u00A0", from: "department_find"
280-
# This is triggering the html5 element like it would normally if the page has focus
281-
page.find(:datalist_input, "department_find").execute_script("document.getElementById('department_find').dispatchEvent(new Event('input'))")
282-
expect(page).to have_content(department_to_test)
283-
expect(page).to have_field("request[departments][]", type: :hidden, with: "{\"code\":\"77777\",\"name\":\"RDSS-Research Data and Scholarship Services\"}")
267+
department_to_test = "RDSS-Research Data and Scholarship Services"
268+
select_and_verify_department(department: department_to_test, department_code: "77777", department_list: [])
284269

285270
# Remove the department
286-
page.execute_script("document.getElementsByClassName('remove-department')[0].click()")
271+
within(".departments") do
272+
page.execute_script("document.getElementsByClassName('remove-item')[0].click()")
273+
end
287274
expect(page).not_to have_content(department_to_test)
288275
end
289276

@@ -342,17 +329,21 @@
342329
sign_in current_user
343330
visit "new-project/project-info"
344331

345-
# Non breaking space `u00A0` is at the end of every option to indicate an option was selected
346-
select "(77777) RDSS-Research Data and Scholarship Services\u00A0", from: "department_find"
347-
select "(77777) RDSS-Research Data and Scholarship Services\u00A0", from: "department_find"
348-
# This is triggering the html5 element like it would normally if the page has focus
349-
page.find(:datalist_input, "department_find").execute_script("document.getElementById('department_find').dispatchEvent(new Event('input'))")
332+
select_and_verify_department(department: "RDSS-Research Data and Scholarship Services", department_code: "77777", department_list: [])
333+
# the option is no longer available
334+
within(".departments") do
335+
page.find(".lux-field input").fill_in with: "77777"
336+
within(".lux-autocomplete-input") do
337+
expect(page).not_to have_content "RDSS-Research Data and Scholarship Services"
338+
end
339+
end
340+
350341
expect(page).to have_field("request[departments][]", type: :hidden, with: "{\"code\":\"77777\",\"name\":\"RDSS-Research Data and Scholarship Services\"}")
351-
expect(page).to have_content("(77777) RDSS-Research Data and Scholarship Services").exactly(2).times
342+
expect(page).to have_content("RDSS-Research Data and Scholarship Services").exactly(1).times
352343

353344
click_on "Review and Submit"
354345
expect(page).to have_content("Take a moment to review your details and make any necessary edits before finalizing.")
355-
expect(page).to have_content("(77777) RDSS-Research Data and Scholarship Services").exactly(1).times
346+
expect(page).to have_content("RDSS-Research Data and Scholarship Services").exactly(1).times
356347

357348
fill_in :project_title, with: "No Duplicate Departments Project"
358349
fill_in :parent_folder, with: "abc_lab"

spec/system/skeletor_spec.rb

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,9 @@
4646
fill_in :description, with: "An awesome project to show the wizard is magic"
4747
select "Teaching", from: :project_purpose
4848
expect(page).to have_content "46/1000 characters"
49-
expect(page).not_to have_content("(77777) RDSS-Research Data and Scholarship Services")
50-
# Non breaking space `u00A0` is at the end of every option to indicate an option was selected
51-
select "(77777) RDSS-Research Data and Scholarship Services\u00A0", from: "department_find"
52-
# This is triggering the html5 element like it would normally if the page has focus
53-
page.find(:datalist_input, "department_find").execute_script("document.getElementById('department_find').dispatchEvent(new Event('input'))")
54-
expect(page).to have_content("(77777) RDSS-Research Data and Scholarship Services")
49+
expect(page).not_to have_content("RDSS-Research Data and Scholarship Services")
50+
select_and_verify_department(department: "RDSS-Research Data and Scholarship Services", department_code: "77777", department_list: [])
51+
expect(page).to have_content("RDSS-Research Data and Scholarship Services")
5552
expect(page).to have_field("request[departments][]", type: :hidden, with: "{\"code\":\"77777\",\"name\":\"RDSS-Research Data and Scholarship Services\"}")
5653
click_on "Roles and People"
5754
select_user(datasponsor, "data_sponsor", "request[data_sponsor]")
@@ -90,11 +87,8 @@
9087
select "Teaching", from: :project_purpose
9188
expect(page).to have_content "46/1000 characters"
9289
expect(page).not_to have_content("(77777) RDSS-Research Data and Scholarship Services")
93-
# Non breaking space `u00A0` is at the end of every option to indicate an option was selected
94-
select "(77777) RDSS-Research Data and Scholarship Services\u00A0", from: "department_find"
95-
# This is triggering the html5 element like it would normally if the page has focus
96-
page.find(:datalist_input, "department_find").execute_script("document.getElementById('department_find').dispatchEvent(new Event('input'))")
97-
expect(page).to have_content("(77777) RDSS-Research Data and Scholarship Services")
90+
select_and_verify_department(department: "RDSS-Research Data and Scholarship Services", department_code: "77777", department_list: [])
91+
expect(page).to have_content("RDSS-Research Data and Scholarship Services")
9892
expect(page).to have_field("request[departments][]", type: :hidden, with: "{\"code\":\"77777\",\"name\":\"RDSS-Research Data and Scholarship Services\"}")
9993
click_on "Roles and People"
10094
select_user(datasponsor, "data_sponsor", "request[data_sponsor]")

spec/system/space_ghost_spec.rb

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,9 @@
2525
fill_in :description, with: "An awesome project to show the wizard is magic"
2626
select "Teaching", from: :project_purpose
2727
expect(page).to have_content "46/1000 characters"
28-
expect(page).not_to have_content("(77777) RDSS-Research Data and Scholarship Services")
29-
# Non breaking space `u00A0` is at the end of every option to indicate an option was selected
30-
select "(77777) RDSS-Research Data and Scholarship Services\u00A0", from: "department_find"
31-
# This is triggering the html5 element like it would normally if the page has focus
32-
page.find(:datalist_input, "department_find").execute_script("document.getElementById('department_find').dispatchEvent(new Event('input'))")
33-
expect(page).to have_content("(77777) RDSS-Research Data and Scholarship Services")
28+
expect(page).not_to have_content("RDSS-Research Data and Scholarship Services")
29+
select_and_verify_department(department: "RDSS-Research Data and Scholarship Services", department_code: "77777", department_list: [])
30+
expect(page).to have_content("RDSS-Research Data and Scholarship Services")
3431
expect(page).to have_field("request[departments][]", type: :hidden, with: "{\"code\":\"77777\",\"name\":\"RDSS-Research Data and Scholarship Services\"}")
3532
click_on "Next"
3633

0 commit comments

Comments
 (0)