Skip to content

Commit 3384436

Browse files
authored
Merge pull request #2303 from davidmillen50/issue-1827-add-how-you-found-us-to-onboarding
feat: add checkboxes for how you found us options during onboarding
2 parents 63b5311 + d5932bb commit 3384436

File tree

10 files changed

+199
-5
lines changed

10 files changed

+199
-5
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: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +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,
14-
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: []
1515
).tap do |params|
1616
# We want to keep Rails' hidden blank field in the form so that all dietary restrictions for a member can be
1717
# removed by submitting the form with all check boxes unticked. However, we want to remove the blank value
@@ -29,5 +29,14 @@ def suppress_notices
2929
def set_member
3030
@member = current_user
3131
end
32+
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
38+
39+
how_found_present != other_reason_present
40+
end
3241
end
3342
end

app/controllers/member/details_controller.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,26 @@ class Member::DetailsController < ApplicationController
88

99
def edit
1010
accept_terms
11-
1211
flash[notice] = I18n.t('notifications.signing_up')
1312
@member.newsletter ||= true
1413
end
1514

1615
def update
17-
return render :edit unless @member.update(member_params)
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')
21+
return render :edit
22+
end
23+
attrs[:how_you_found_us] = params[:member][:how_you_found_us] if params[:member][:how_you_found_us].present?
24+
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
29+
30+
return render :edit unless @member.update(attrs)
1831

1932
member_params[:newsletter] ? subscribe_to_newsletter(@member) : unsubscribe_from_newsletter(@member)
2033
redirect_to step2_member_path

app/models/member.rb

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

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+
}
11+
412
has_many :attendance_warnings
513
has_many :bans
614
has_many :eligibility_inquiries

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,30 @@
1919
label_method: ->(r) { r.humanize.upcase_first }
2020
= f.input :other_dietary_restrictions, placeholder: 'Other dietary restrictions',
2121
wrapper_html: { class: class_names('mt-n3', 'd-none': !@member.other_dietary_restrictions?) }, label_html: { class: 'sr-only' }
22+
- if @member.errors.any?
23+
#error_explanation
24+
%h2= "#{pluralize(@member.errors.count, 'error')} prohibited this member from being saved:"
25+
%ul
26+
- @member.errors.full_messages.each do |msg|
27+
%li= msg
28+
- if @member.errors[:how_you_found_us]&.any?
29+
%span.text-danger= @member.errors[:how_you_found_us].first
30+
.col-12.mb-3
31+
%fieldset
32+
= f.input :how_you_found_us,
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',
39+
label_item: true,
40+
input_html: { class: 'form-check-input me-2', style: 'margin-top: 0;' },
41+
label_html: { class: 'form-check-label', style: 'margin-left: 0;' }
42+
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' }
2246
= f.input :newsletter, as: :boolean, checked_value: true, unchecked_value: false
2347
.text-right.mb-4
2448
= hidden_field_tag :next_page, step2_member_path(member_type: @type)

config/locales/en.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +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_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"
445453
coach:
446454
about_you: What experience do you have? What languages do you like to use? Tell us a little bit about yourself!
447455
student:
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
RSpec.describe Member::DetailsController do
2+
render_views
3+
let(:member) { Fabricate(:member) }
4+
5+
before do
6+
allow(controller).to receive(:current_user).and_return(member)
7+
allow_any_instance_of(Services::MailingList).to receive(:subscribe).and_return(true)
8+
end
9+
10+
describe 'PATCH #update' do
11+
context 'with valid params' do
12+
it 'updates how_you_found_us with radio option' do
13+
patch :update, params: {
14+
id: member.id,
15+
member: {
16+
how_you_found_us: 'social_media',
17+
newsletter: 'true'
18+
}
19+
}
20+
21+
member.reload
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)
24+
expect(response).to redirect_to(step2_member_path)
25+
end
26+
27+
it 'adds other_reason to how_you_found_us when provided' do
28+
patch :update, params: {
29+
id: member.id,
30+
member: {
31+
how_you_found_us: 'other',
32+
how_you_found_us_other_reason: 'Saw a pamphlet',
33+
newsletter: 'false'
34+
},
35+
}
36+
37+
member.reload
38+
expect(member.how_you_found_us).to eq('other')
39+
expect(member.how_you_found_us_other_reason).to eq('Saw a pamphlet')
40+
expect(response).to redirect_to(step2_member_path)
41+
end
42+
43+
it 'updates how_you_found_us with only other_reason' do
44+
patch :update, params: {
45+
id: member.id,
46+
member: {
47+
how_you_found_us: 'other',
48+
how_you_found_us_other_reason: 'At a meetup',
49+
newsletter: 'true'
50+
},
51+
}
52+
53+
member.reload
54+
expect(member.how_you_found_us).to eq('other')
55+
expect(member.how_you_found_us_other_reason).to eq('At a meetup')
56+
expect(response).to redirect_to(step2_member_path)
57+
end
58+
59+
it 'removes duplicates and blank entries' do
60+
patch :update, params: {
61+
id: member.id,
62+
member: {
63+
how_you_found_us: 'other',
64+
how_you_found_us_other_reason: 'From a colleague',
65+
newsletter: 'true'
66+
},
67+
}
68+
69+
member.reload
70+
expect(member.how_you_found_us).to eq('other')
71+
expect(member.how_you_found_us_other_reason).to eq('From a colleague')
72+
expect(response).to redirect_to(step2_member_path)
73+
end
74+
end
75+
76+
context 'when update fails (invalid data)' do
77+
it 'error raised when no how you found us selection given' do
78+
patch :update, params: {
79+
id: member.id,
80+
member: {
81+
how_you_found_us: 'other',
82+
how_you_found_us_other_reason: nil,
83+
}
84+
}
85+
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')
99+
end
100+
end
101+
end
102+
end

spec/features/member_joining_spec.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
end
1616

1717
scenario 'A visitor must fill in all mandatory fields in order to sign up' do
18-
member = Fabricate(:member, name: nil, surname: nil, email: nil, about_you: nil)
18+
member = Fabricate(:member, name: nil, surname: nil, email: nil, about_you: nil, how_you_found_us: nil, how_you_found_us_other_reason: nil)
1919
member.update(can_log_in: true)
2020
login member
2121

@@ -27,6 +27,7 @@
2727
expect(page).to have_content "Surname can't be blank"
2828
expect(page).to have_content "Email address can't be blank"
2929
expect(page).to have_content "About you can't be blank"
30+
expect(page).to have_content "You must select one option"
3031
end
3132

3233
scenario 'A new member details are successfully captured' do
@@ -43,6 +44,11 @@
4344
check 'Vegan'
4445
check 'Other'
4546
fill_in 'Other dietary restrictions', with: 'peanut allergy'
47+
find('#member_how_you_found_us_from_a_friend').click
48+
49+
find('#member_how_you_found_us_other').click
50+
expect(page).to have_content('Please specify how you found us')
51+
fill_in 'member_how_you_found_us_other_reason', with: 'found on a poster', id: true
4652
click_on 'Next'
4753

4854
expect(page).to have_current_path(step2_member_path)

spec/features/subscribing_to_newsletter_spec.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
fill_in 'member_surname', with: 'Doe'
2828
fill_in 'member_email', with: 'jane@codebar.io'
2929
fill_in 'member_about_you', with: Faker::Lorem.paragraph
30+
find('#member_how_you_found_us_from_a_friend').click
3031

3132
click_on 'Next'
3233
end
@@ -46,6 +47,8 @@
4647
fill_in 'member_surname', with: 'Doe'
4748
fill_in 'member_email', with: 'jane@codebar.io'
4849
fill_in 'member_about_you', with: Faker::Lorem.paragraph
50+
find('#member_how_you_found_us_other').click
51+
fill_in 'member_how_you_found_us_other_reason', with: Faker::Lorem.paragraph, id: true
4952

5053
uncheck 'newsletter'
5154

0 commit comments

Comments
 (0)