Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow restricting PhoneNumberPrefixWidget country choices #525

Merged
merged 1 commit into from
Aug 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions phonenumber_field/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,16 @@ def localized_choices(language):
class PhonePrefixSelect(Select):
initial = None

def __init__(self, initial=None, attrs=None):
def __init__(self, initial=None, attrs=None, choices=None):
language = translation.get_language() or settings.LANGUAGE_CODE
choices = localized_choices(language)
if choices is None:
choices = localized_choices(language)
choices.sort(key=lambda item: item[1])
if initial is None:
initial = getattr(settings, "PHONENUMBER_DEFAULT_REGION", None)
if initial in REGION_CODE_TO_COUNTRY_CODE:
self.initial = initial
super().__init__(attrs=attrs, choices=sorted(choices, key=lambda item: item[1]))
super().__init__(attrs=attrs, choices=choices)

def get_context(self, name, value, attrs):
attrs = (attrs or {}).copy()
Expand All @@ -67,9 +69,23 @@ class PhoneNumberPrefixWidget(MultiWidget):
- an input for local phone number
"""

def __init__(self, attrs=None, initial=None, country_attrs=None, number_attrs=None):
def __init__(
self,
attrs=None,
initial=None,
country_attrs=None,
country_choices=None,
number_attrs=None,
):
"""
:param country_choices: Limit the country choices.
:type country_choices: list of 2-tuple, optional
The first element is the value, which must match a country code
recognized by the phonenumbers project.
The second element is the label.
"""
widgets = (
PhonePrefixSelect(initial, attrs=country_attrs),
PhonePrefixSelect(initial, attrs=country_attrs, choices=country_choices),
TextInput(attrs=number_attrs),
)
super().__init__(widgets, attrs)
Expand Down
15 changes: 15 additions & 0 deletions tests/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,21 @@ def test_custom_attrs(self):
'<input type="text" name="widget_1" class="number-input">', html, count=1
)

def test_custom_choices(self):
widget = PhoneNumberPrefixWidget(
country_choices=[("FR", "France"), ("BE", "Belgium")]
)
self.assertHTMLEqual(
widget.render(name="widget", value=None),
"""
<select name="widget_0">
<option value="FR">France</option>
<option value="BE">Belgium</option>
</select>
<input name="widget_1" type="text">
""",
)


class PhoneNumberInternationalFallbackWidgetTest(SimpleTestCase):
def test_fallback_widget_switches_between_national_and_international(self):
Expand Down