Skip to content

Commit d5932bb

Browse files
committed
feat: convert to radio buttons and make other reason text field hidden until other clicked
1 parent ae7cc23 commit d5932bb

File tree

13 files changed

+107
-59
lines changed

13 files changed

+107
-59
lines changed

app/assets/javascripts/application.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
//= require dietary-restrictions
2828
//= require cocoon
2929
//= require font_awesome5
30+
//= require how-you-found-us
3031

3132
$(function() {
3233
$("body").removeClass("no-js");
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
$(document).ready(function() {
2+
const $otherRadioButton = $('#member_how_you_found_us_other');
3+
const $otherReason = $('#member_how_you_found_us_other_reason');
4+
const $elementToToggle = $otherReason.parent();
5+
6+
function toggleOtherReason() {
7+
if ($otherRadioButton.is(':checked')) {
8+
$elementToToggle.removeClass('d-none').hide().slideDown(50);
9+
$otherReason.prop('disabled', false).focus(); // Optional — disabling is not needed
10+
} else {
11+
$elementToToggle.slideUp(50, function() {
12+
$elementToToggle.addClass('d-none');
13+
$otherReason.val('');
14+
});
15+
}
16+
}
17+
18+
toggleOtherReason();
19+
$('input[name="member[how_you_found_us]"]').on('change', toggleOtherReason);
20+
});

app/controllers/concerns/member_concerns.rb

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ module InstanceMethods
1010

1111
def member_params
1212
params.require(:member).permit(
13-
:pronouns, :name, :surname, :email, :mobile, :about_you, :skill_list, :newsletter, :other_dietary_restrictions, :other_reason, :how_you_found_us_other_reason, how_you_found_us: [], dietary_restrictions: []
13+
:pronouns, :name, :surname, :email, :mobile, :about_you, :skill_list, :newsletter, :other_dietary_restrictions, :how_you_found_us,
14+
:how_you_found_us_other_reason, dietary_restrictions: []
1415
).tap do |params|
1516
# We want to keep Rails' hidden blank field in the form so that all dietary restrictions for a member can be
1617
# removed by submitting the form with all check boxes unticked. However, we want to remove the blank value
@@ -29,18 +30,13 @@ def set_member
2930
@member = current_user
3031
end
3132

32-
def how_you_found_us_selections
33-
how_found = Array(member_params[:how_you_found_us]).reject(&:blank?)
34-
other_reason = member_params[:how_you_found_us_other_reason]
33+
def how_you_found_us_selections_valid?
34+
how_found_present = member_params[:how_you_found_us].present?
35+
other_reason_present = member_params[:how_you_found_us_other_reason].present?
36+
return false if member_params[:how_you_found_us] == 'other' && !other_reason_present
37+
return true if member_params[:how_you_found_us] == 'other' && other_reason_present
3538

36-
how_found << other_reason if other_reason.present?
37-
how_found.uniq!
38-
39-
how_found
40-
end
41-
42-
def member_params_without_how_you_found_us_other_reason
43-
member_params.to_h.except(:how_you_found_us_other_reason)
39+
how_found_present != other_reason_present
4440
end
4541
end
4642
end

app/controllers/member/details_controller.rb

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,19 @@ def edit
1313
end
1414

1515
def update
16-
if how_you_found_us_selections.blank?
17-
@member.assign_attributes(member_params_without_how_you_found_us_other_reason)
18-
@member.errors.add(:how_you_found_us, 'You must select at least one option')
16+
attrs = member_params
17+
attrs[:how_you_found_us_other_reason] = nil if attrs[:how_you_found_us] != 'other'
18+
19+
unless how_you_found_us_selections_valid?
20+
@member.errors.add(:how_you_found_us, 'You must select one option')
1921
return render :edit
2022
end
23+
attrs[:how_you_found_us] = params[:member][:how_you_found_us] if params[:member][:how_you_found_us].present?
2124

22-
attrs = member_params_without_how_you_found_us_other_reason
23-
attrs[:how_you_found_us] = how_you_found_us_selections
25+
if params[:member][:how_you_found_us_other_reason].present? && attrs[:how_you_found_us] == 'other'
26+
attrs[:how_you_found_us_other_reason] =
27+
params[:member][:how_you_found_us_other_reason]
28+
end
2429

2530
return render :edit unless @member.update(attrs)
2631

app/models/member.rb

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
class Member < ApplicationRecord
22
include Permissions
33

4-
HOW_YOU_FOUND_US_OPTIONS = [
5-
'From a friend',
6-
'Search engine (Google etc.)',
7-
'Social Media',
8-
"One of Codebar's hosts or partners"
9-
].freeze
4+
enum how_you_found_us: {
5+
from_a_friend: 0,
6+
search_engine: 1,
7+
social_media: 2,
8+
codebar_host_or_partner: 3,
9+
other: 4
10+
}
1011

1112
has_many :attendance_warnings
1213
has_many :bans
@@ -52,7 +53,7 @@ class Member < ApplicationRecord
5253

5354
acts_as_taggable_on :skills
5455

55-
attr_accessor :attendance, :newsletter, :how_you_found_us_other_reason
56+
attr_accessor :attendance, :newsletter
5657

5758
def banned?
5859
bans.active.present? || bans.permanent.present?

app/views/member/details/edit.html.haml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,20 @@
2929
%span.text-danger= @member.errors[:how_you_found_us].first
3030
.col-12.mb-3
3131
%fieldset
32-
%legend= t('member.details.edit.how_you_found_us')
33-
%span *
34-
3532
= f.input :how_you_found_us,
36-
as: :check_boxes,
37-
collection: Member::HOW_YOU_FOUND_US_OPTIONS,
38-
item_wrapper_class: 'form-check',
33+
as: :radio_buttons,
34+
collection: Member.how_you_found_us.keys,
35+
label_method: ->(option) { t("member.details.edit.how_you_found_us_options.#{option}") },
36+
value_method: :to_s,
37+
label: t('member.details.edit.how_you_found_us_label'),
38+
item_wrapper_class: 'form-check d-flex align-items-center mb-2',
3939
label_item: true,
40-
input_html: { class: 'form-check-input' },
41-
label_html: { class: 'form-check-label', style: 'margin-left: 8px;' }
40+
input_html: { class: 'form-check-input me-2', style: 'margin-top: 0;' },
41+
label_html: { class: 'form-check-label', style: 'margin-left: 0;' }
4242

43-
= f.input :how_you_found_us_other_reason,
44-
label: t('member.details.edit.how_you_found_us_other_reason'),
45-
placeholder: 'Please specify how you heard about us',
46-
input_html: { class: 'form-control w-100' }
43+
= f.input :how_you_found_us_other_reason,
44+
label: t('member.details.edit.how_you_found_us_other_reason'),
45+
input_html: { class: 'form-control w-100' }
4746
= f.input :newsletter, as: :boolean, checked_value: true, unchecked_value: false
4847
.text-right.mb-4
4948
= hidden_field_tag :next_page, step2_member_path(member_type: @type)

config/locales/en.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,14 @@ en:
442442
edit:
443443
title: Almost there...
444444
summary: We need some more details from you to finish creating your account. We use these to help run our events.
445-
how_you_found_us: "How did you find out about us?"
446-
how_you_found_us_other_reason: "Please specify (if Other)"
445+
how_you_found_us_label: "How did you find out about us?*"
446+
how_you_found_us_other_reason: "Please specify how you found us"
447+
how_you_found_us_options:
448+
from_a_friend: "From a friend"
449+
search_engine: "Search engine (Google etc.)"
450+
social_media: "Social media"
451+
codebar_host_or_partner: "One of Codebar's hosts or partners"
452+
other: "Other"
447453
coach:
448454
about_you: What experience do you have? What languages do you like to use? Tell us a little bit about yourself!
449455
student:
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
class AddHowYouFoundUsOptions < ActiveRecord::Migration[7.0]
22
def change
3-
add_column :members, :how_you_found_us, :text, array: true, default: []
3+
add_column :members, :how_you_found_us, :integer
4+
add_column :members, :how_you_found_us_other_reason, :string
45
end
56
end

db/schema.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,8 @@
397397
t.datetime "opt_in_newsletter_at", precision: nil
398398
t.enum "dietary_restrictions", default: [], array: true, enum_type: "dietary_restriction_enum"
399399
t.string "other_dietary_restrictions"
400-
t.text "how_you_found_us", default: [], array: true
400+
t.integer "how_you_found_us"
401+
t.string "how_you_found_us_other_reason"
401402
t.index ["email"], name: "index_members_on_email", unique: true
402403
end
403404

spec/controllers/member/details_controller_spec.rb

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,76 +9,93 @@
99

1010
describe 'PATCH #update' do
1111
context 'with valid params' do
12-
it 'updates how_you_found_us with checkbox options' do
12+
it 'updates how_you_found_us with radio option' do
1313
patch :update, params: {
1414
id: member.id,
1515
member: {
16-
how_you_found_us: ['Social Media', 'From a friend'],
16+
how_you_found_us: 'social_media',
1717
newsletter: 'true'
1818
}
1919
}
2020

2121
member.reload
22-
expect(member.how_you_found_us).to contain_exactly('Social Media', 'From a friend')
22+
expect(I18n.t("member.details.edit.how_you_found_us_options.#{member.how_you_found_us}")).to eq('Social media')
23+
expect(member.how_you_found_us_other_reason).to eq(nil)
2324
expect(response).to redirect_to(step2_member_path)
2425
end
2526

2627
it 'adds other_reason to how_you_found_us when provided' do
2728
patch :update, params: {
2829
id: member.id,
2930
member: {
30-
how_you_found_us: ['Search engine (Google etc.)'],
31+
how_you_found_us: 'other',
3132
how_you_found_us_other_reason: 'Saw a pamphlet',
3233
newsletter: 'false'
3334
},
3435
}
3536

3637
member.reload
37-
expect(member.how_you_found_us).to contain_exactly('Search engine (Google etc.)', 'Saw a pamphlet')
38+
expect(member.how_you_found_us).to eq('other')
39+
expect(member.how_you_found_us_other_reason).to eq('Saw a pamphlet')
3840
expect(response).to redirect_to(step2_member_path)
3941
end
4042

4143
it 'updates how_you_found_us with only other_reason' do
4244
patch :update, params: {
4345
id: member.id,
4446
member: {
45-
how_you_found_us: [],
47+
how_you_found_us: 'other',
4648
how_you_found_us_other_reason: 'At a meetup',
4749
newsletter: 'true'
4850
},
4951
}
5052

5153
member.reload
52-
expect(member.how_you_found_us).to eq(['At a meetup'])
54+
expect(member.how_you_found_us).to eq('other')
55+
expect(member.how_you_found_us_other_reason).to eq('At a meetup')
5356
expect(response).to redirect_to(step2_member_path)
5457
end
5558

5659
it 'removes duplicates and blank entries' do
5760
patch :update, params: {
5861
id: member.id,
5962
member: {
60-
how_you_found_us: ['From a friend', '', 'From a friend'],
61-
how_you_found_us_other_reason: 'From a friend',
63+
how_you_found_us: 'other',
64+
how_you_found_us_other_reason: 'From a colleague',
6265
newsletter: 'true'
6366
},
6467
}
6568

6669
member.reload
67-
expect(member.how_you_found_us).to eq(['From a friend'])
70+
expect(member.how_you_found_us).to eq('other')
71+
expect(member.how_you_found_us_other_reason).to eq('From a colleague')
6872
expect(response).to redirect_to(step2_member_path)
6973
end
7074
end
7175

7276
context 'when update fails (invalid data)' do
73-
it 'renders the edit template' do
77+
it 'error raised when no how you found us selection given' do
7478
patch :update, params: {
7579
id: member.id,
7680
member: {
77-
how_you_found_us: []
81+
how_you_found_us: 'other',
82+
how_you_found_us_other_reason: nil,
7883
}
7984
}
8085

81-
expect(response.body).to include('You must select at least one option')
86+
expect(response.body).to include('You must select one option')
87+
end
88+
89+
it 'error raised when both how you found us fields popoulated' do
90+
patch :update, params: {
91+
id: member.id,
92+
member: {
93+
how_you_found_us: 'from_a_friend',
94+
how_you_found_us_other_reason: 'something else',
95+
}
96+
}
97+
98+
expect(response.body).to include('You must select one option')
8299
end
83100
end
84101
end

0 commit comments

Comments
 (0)