-
Notifications
You must be signed in to change notification settings - Fork 112
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1568 from 18F/jmhooper-phone-number-format
Update international code as user types phone
- Loading branch information
Showing
9 changed files
with
191 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
app/assets/javascripts/app/modules/international-phone-formatter.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { Formatter } from 'field-kit'; | ||
import { asYouType as AsYouType } from 'libphonenumber-js'; | ||
|
||
const fixCountryCodeSpacing = (text, countryCode) => { | ||
// If the text is `+123456`, make it `+123 456` | ||
if (text[countryCode.length + 1] !== ' ') { | ||
return text.replace(`+${countryCode}`, `+${countryCode} `); | ||
} | ||
return text; | ||
}; | ||
|
||
const getFormattedTextData = (text) => { | ||
if (text === '1') { | ||
text = '+1'; | ||
} | ||
|
||
const asYouType = new AsYouType('US'); | ||
let formattedText = asYouType.input(text); | ||
const countryCode = asYouType.country_phone_code; | ||
|
||
if (asYouType.country_phone_code) { | ||
formattedText = fixCountryCodeSpacing(formattedText, countryCode); | ||
} | ||
|
||
return { | ||
text: formattedText, | ||
template: asYouType.template, | ||
countryCode, | ||
}; | ||
}; | ||
|
||
const cursorPosition = (formattedTextData) => { | ||
// If the text is `(23 )` the cursor goes after the 3 | ||
const match = formattedTextData.text.match(/\d[^\d]*$/); | ||
if (match) { | ||
return match.index + 1; | ||
} | ||
return formattedTextData.text.length + 1; | ||
}; | ||
|
||
class InternationalPhoneFormatter extends Formatter { | ||
format(text) { | ||
const formattedTextData = getFormattedTextData(text); | ||
return super.format(formattedTextData.text); | ||
} | ||
|
||
// eslint-disable-next-line class-methods-use-this | ||
parse(text) { | ||
return text.replace(/[^\d+]/g, ''); | ||
} | ||
|
||
isChangeValid(change, error) { | ||
const formattedTextData = getFormattedTextData(change.proposed.text); | ||
const previousFormattedTextData = getFormattedTextData(change.current.text); | ||
|
||
if (previousFormattedTextData.template && | ||
!formattedTextData.template && | ||
change.inserted.text.length === 1 | ||
) { | ||
return false; | ||
} | ||
|
||
change.proposed.text = formattedTextData.text; | ||
change.proposed.selectedRange.start = cursorPosition(formattedTextData); | ||
return super.isChangeValid(change, error); | ||
} | ||
} | ||
|
||
export default InternationalPhoneFormatter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,47 @@ | ||
require 'rails_helper' | ||
|
||
feature 'User edit' do | ||
scenario 'user sees error message if form is submitted without email', js: true, idv_job: true do | ||
sign_in_and_2fa_user | ||
context 'editing email' do | ||
before do | ||
sign_in_and_2fa_user | ||
visit manage_email_path | ||
end | ||
|
||
visit manage_email_path | ||
fill_in 'Email', with: '' | ||
click_button 'Update' | ||
scenario 'user sees error message if form is submitted without email', :js, idv_job: true do | ||
fill_in 'Email', with: '' | ||
click_button 'Update' | ||
|
||
expect(page).to have_content t('valid_email.validations.email.invalid') | ||
expect(page).to have_content t('valid_email.validations.email.invalid') | ||
end | ||
end | ||
|
||
scenario 'user sees error message if form is submitted without phone number', js: true do | ||
sign_in_and_2fa_user | ||
context 'editing 2FA phone number' do | ||
before do | ||
sign_in_and_2fa_user | ||
visit manage_phone_path | ||
end | ||
|
||
visit manage_phone_path | ||
fill_in 'Phone', with: '' | ||
click_button t('forms.buttons.submit.confirm_change') | ||
scenario 'user sees error message if form is submitted without phone number', js: true do | ||
fill_in 'Phone', with: '' | ||
click_button t('forms.buttons.submit.confirm_change') | ||
|
||
expect(page).to have_content t('errors.messages.improbable_phone') | ||
expect(page).to have_content t('errors.messages.improbable_phone') | ||
end | ||
|
||
scenario 'updates international code as user types', :js do | ||
fill_in 'Phone', with: '+81 54 354 3643' | ||
|
||
expect(page.find('#update_user_phone_form_international_code').value).to eq 'JP' | ||
|
||
fill_in 'Phone', with: '5376' | ||
select 'Morocco +212', from: 'International code' | ||
|
||
expect(find('#update_user_phone_form_phone').value).to eq '+212 5376' | ||
|
||
fill_in 'Phone', with: '54354' | ||
select 'Japan +81', from: 'International code' | ||
|
||
expect(find('#update_user_phone_form_phone').value).to include '+81' | ||
end | ||
end | ||
end |