intl-tel-input 18.5.3 → 19.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -28
- package/build/css/demo.css +1 -1
- package/build/css/intlTelInput.css +28 -20
- package/build/js/data.js +1 -1
- package/build/js/data.min.js +1 -1
- package/build/js/intlTelInput-jquery.js +158 -151
- package/build/js/intlTelInput-jquery.min.js +3 -3
- package/build/js/intlTelInput.js +158 -151
- package/build/js/intlTelInput.min.js +3 -3
- package/composer.json +1 -1
- package/demo.html +5 -5
- package/grunt/replace.js +1 -7
- package/package.json +1 -1
- package/spec.html +6 -4
- package/src/css/demo.scss +1 -1
- package/src/css/intlTelInput.scss +41 -30
- package/src/js/intlTelInput.js +76 -125
- package/src/spec/helpers/helpers.js +23 -10
- package/src/spec/tests/core/countrychangeEvent.js +1 -1
- package/src/spec/tests/core/dropdownShortcuts.js +3 -2
- package/src/spec/tests/core/initialValues.js +2 -3
- package/src/spec/tests/methods/getSelectedCountryData.js +1 -1
- package/src/spec/tests/methods/isValidNumber.js +15 -32
- package/src/spec/tests/methods/isValidNumberPrecise.js +73 -0
- package/src/spec/tests/methods/setCountry.js +4 -4
- package/src/spec/tests/options/allowDropdown.js +3 -3
- package/src/spec/tests/options/autoInsertDialCode.js +1 -3
- package/src/spec/tests/options/autoPlaceholder.js +5 -5
- package/src/spec/tests/options/{customContainer.js → containerClass.js} +3 -3
- package/src/spec/tests/options/countrySearch.js +63 -0
- package/src/spec/tests/options/customPlaceholder.js +1 -1
- package/src/spec/tests/options/preferredCountries.js +3 -1
- package/src/spec/tests/options/{separateDialCode.js → showSelectedDialCode.js} +7 -7
- package/src/spec/tests/methods/isPossibleNumber.js +0 -56
package/src/js/intlTelInput.js
CHANGED
|
@@ -23,9 +23,9 @@ const defaults = {
|
|
|
23
23
|
// add a placeholder in the input with an example number for the selected country
|
|
24
24
|
autoPlaceholder: "polite",
|
|
25
25
|
// add a country search input at the top of the dropdown
|
|
26
|
-
countrySearch:
|
|
26
|
+
countrySearch: true,
|
|
27
27
|
// modify the parentClass
|
|
28
|
-
|
|
28
|
+
containerClass: "",
|
|
29
29
|
// modify the auto placeholder
|
|
30
30
|
customPlaceholder: null,
|
|
31
31
|
// append menu to specified element
|
|
@@ -33,29 +33,29 @@ const defaults = {
|
|
|
33
33
|
// don't display these countries
|
|
34
34
|
excludeCountries: [],
|
|
35
35
|
// fix the dropdown width to the input width (rather than being as wide as the longest country name)
|
|
36
|
-
fixDropdownWidth:
|
|
36
|
+
fixDropdownWidth: true,
|
|
37
37
|
// format the input value during initialisation and on setNumber
|
|
38
38
|
formatOnDisplay: true,
|
|
39
39
|
// geoIp lookup function
|
|
40
40
|
geoIpLookup: null,
|
|
41
41
|
// inject a hidden input with this name, and on submit, populate it with the result of getNumber
|
|
42
|
-
hiddenInput:
|
|
42
|
+
hiddenInput: null,
|
|
43
|
+
// internationalise the plugin text e.g. search input placeholder, country names
|
|
44
|
+
i18n: {},
|
|
43
45
|
// initial country
|
|
44
46
|
initialCountry: "",
|
|
45
|
-
// localized country names e.g. { 'de': 'Deutschland' }
|
|
46
|
-
localizedCountries: null,
|
|
47
47
|
// national vs international formatting for numbers e.g. placeholders and displaying existing numbers
|
|
48
48
|
nationalMode: true,
|
|
49
49
|
// display only these countries
|
|
50
50
|
onlyCountries: [],
|
|
51
51
|
// number type to use for placeholders
|
|
52
52
|
placeholderNumberType: "MOBILE",
|
|
53
|
-
// the countries at the top of the list
|
|
54
|
-
preferredCountries: [
|
|
55
|
-
//
|
|
56
|
-
separateDialCode: false,
|
|
57
|
-
// option to hide the flags - must be used with separateDialCode, or allowDropdown=false
|
|
53
|
+
// the countries at the top of the list
|
|
54
|
+
preferredCountries: [],
|
|
55
|
+
// option to hide the flags - must be used with showSelectedDialCode, or allowDropdown=false
|
|
58
56
|
showFlags: true,
|
|
57
|
+
// display the international dial code next to the selected flag
|
|
58
|
+
showSelectedDialCode: false,
|
|
59
59
|
// use full screen popup instead of dropdown for country list
|
|
60
60
|
useFullscreenPopup:
|
|
61
61
|
typeof navigator !== "undefined" && typeof window !== "undefined"
|
|
@@ -90,26 +90,16 @@ const regionlessNanpNumbers = [
|
|
|
90
90
|
"889"
|
|
91
91
|
];
|
|
92
92
|
|
|
93
|
-
// utility function to iterate over an object. can't use Object.entries or native forEach because
|
|
94
|
-
// of IE11
|
|
95
|
-
const forEachProp = (obj, callback) => {
|
|
96
|
-
const keys = Object.keys(obj);
|
|
97
|
-
for (let i = 0; i < keys.length; i++) {
|
|
98
|
-
callback(keys[i], obj[keys[i]]);
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
93
|
// run a method on each instance of the plugin
|
|
103
94
|
const forEachInstance = (method) => {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
});
|
|
95
|
+
const { instances } = window.intlTelInputGlobals;
|
|
96
|
+
Object.values(instances).forEach((instance) => instance[method]());
|
|
107
97
|
};
|
|
108
98
|
|
|
109
99
|
// this is our plugin class that we will create an instance of
|
|
110
100
|
// eslint-disable-next-line no-unused-vars
|
|
111
101
|
class Iti {
|
|
112
|
-
constructor(input,
|
|
102
|
+
constructor(input, customOptions = {}) {
|
|
113
103
|
this.id = id++;
|
|
114
104
|
this.telInput = input;
|
|
115
105
|
|
|
@@ -117,15 +107,7 @@ class Iti {
|
|
|
117
107
|
this.highlightedItem = null;
|
|
118
108
|
|
|
119
109
|
// process specified options / defaults
|
|
120
|
-
|
|
121
|
-
const customOptions = options || {};
|
|
122
|
-
this.options = {};
|
|
123
|
-
forEachProp(defaults, (key, value) => {
|
|
124
|
-
this.options[key] = customOptions.hasOwnProperty(key)
|
|
125
|
-
? customOptions[key]
|
|
126
|
-
: value;
|
|
127
|
-
});
|
|
128
|
-
|
|
110
|
+
this.options = Object.assign({}, defaults, customOptions);
|
|
129
111
|
this.hadInitialPlaceholder = Boolean(input.getAttribute("placeholder"));
|
|
130
112
|
}
|
|
131
113
|
|
|
@@ -145,15 +127,15 @@ class Iti {
|
|
|
145
127
|
this.options.autoInsertDialCode = false;
|
|
146
128
|
}
|
|
147
129
|
|
|
148
|
-
// if
|
|
149
|
-
if (this.options.
|
|
130
|
+
// if showSelectedDialCode enabled, do not insert dial codes
|
|
131
|
+
if (this.options.showSelectedDialCode) {
|
|
150
132
|
this.options.autoInsertDialCode = false;
|
|
151
133
|
}
|
|
152
134
|
|
|
153
135
|
// force showFlags=true if there's a dropdown and we're not displaying the dial code,
|
|
154
136
|
// as otherwise you just have a down arrow on it's own which doesn't make sense
|
|
155
137
|
const forceShowFlags =
|
|
156
|
-
this.options.allowDropdown && !this.options.
|
|
138
|
+
this.options.allowDropdown && !this.options.showSelectedDialCode;
|
|
157
139
|
if (!this.options.showFlags && forceShowFlags) {
|
|
158
140
|
this.options.showFlags = true;
|
|
159
141
|
}
|
|
@@ -221,13 +203,11 @@ class Iti {
|
|
|
221
203
|
// process the preferredCountries
|
|
222
204
|
this._processPreferredCountries();
|
|
223
205
|
|
|
224
|
-
// translate
|
|
225
|
-
|
|
226
|
-
this._translateCountriesByLocale();
|
|
227
|
-
}
|
|
206
|
+
// translate country names according to i18n option
|
|
207
|
+
this._translateCountryNames();
|
|
228
208
|
|
|
229
209
|
// sort countries by name
|
|
230
|
-
if (this.options.onlyCountries.length || this.options.
|
|
210
|
+
if (this.options.onlyCountries.length || this.options.i18n) {
|
|
231
211
|
this.countries.sort(this._countryNameSort);
|
|
232
212
|
}
|
|
233
213
|
}
|
|
@@ -274,11 +254,11 @@ class Iti {
|
|
|
274
254
|
}
|
|
275
255
|
|
|
276
256
|
// Translate Countries by object literal provided on config
|
|
277
|
-
|
|
257
|
+
_translateCountryNames() {
|
|
278
258
|
for (let i = 0; i < this.countries.length; i++) {
|
|
279
259
|
const iso = this.countries[i].iso2.toLowerCase();
|
|
280
|
-
if (this.options.
|
|
281
|
-
this.countries[i].name = this.options.
|
|
260
|
+
if (this.options.i18n.hasOwnProperty(iso)) {
|
|
261
|
+
this.countries[i].name = this.options.i18n[iso];
|
|
282
262
|
}
|
|
283
263
|
}
|
|
284
264
|
}
|
|
@@ -354,7 +334,7 @@ class Iti {
|
|
|
354
334
|
_createEl(name, attrs, container) {
|
|
355
335
|
const el = document.createElement(name);
|
|
356
336
|
if (attrs) {
|
|
357
|
-
|
|
337
|
+
Object.entries(attrs).forEach(([key, value]) => el.setAttribute(key, value));
|
|
358
338
|
}
|
|
359
339
|
if (container) {
|
|
360
340
|
container.appendChild(el);
|
|
@@ -379,9 +359,9 @@ class Iti {
|
|
|
379
359
|
|
|
380
360
|
const {
|
|
381
361
|
allowDropdown,
|
|
382
|
-
|
|
362
|
+
showSelectedDialCode,
|
|
383
363
|
showFlags,
|
|
384
|
-
|
|
364
|
+
containerClass,
|
|
385
365
|
hiddenInput,
|
|
386
366
|
dropdownContainer,
|
|
387
367
|
fixDropdownWidth,
|
|
@@ -394,20 +374,23 @@ class Iti {
|
|
|
394
374
|
if (allowDropdown) {
|
|
395
375
|
parentClass += " iti--allow-dropdown";
|
|
396
376
|
}
|
|
397
|
-
if (
|
|
398
|
-
parentClass += " iti--
|
|
377
|
+
if (showSelectedDialCode) {
|
|
378
|
+
parentClass += " iti--show-selected-dial-code";
|
|
399
379
|
}
|
|
400
380
|
if (showFlags) {
|
|
401
381
|
parentClass += " iti--show-flags";
|
|
402
382
|
}
|
|
403
|
-
if (
|
|
404
|
-
parentClass += ` ${
|
|
383
|
+
if (containerClass) {
|
|
384
|
+
parentClass += ` ${containerClass}`;
|
|
385
|
+
}
|
|
386
|
+
if (!useFullscreenPopup) {
|
|
387
|
+
parentClass += " iti--inline-dropdown";
|
|
405
388
|
}
|
|
406
389
|
|
|
407
390
|
const wrapper = this._createEl("div", { class: parentClass });
|
|
408
391
|
this.telInput.parentNode.insertBefore(wrapper, this.telInput);
|
|
409
|
-
// only hide the flagsContainer if allowDropdown, showFlags and
|
|
410
|
-
const showFlagsContainer = allowDropdown || showFlags ||
|
|
392
|
+
// only hide the flagsContainer if allowDropdown, showFlags and showSelectedDialCode are all false
|
|
393
|
+
const showFlagsContainer = allowDropdown || showFlags || showSelectedDialCode;
|
|
411
394
|
if (showFlagsContainer) {
|
|
412
395
|
this.flagsContainer = this._createEl(
|
|
413
396
|
"div",
|
|
@@ -430,7 +413,7 @@ class Iti {
|
|
|
430
413
|
"aria-haspopup": "listbox",
|
|
431
414
|
"aria-controls": `iti-${this.id}__country-listbox`,
|
|
432
415
|
"aria-expanded": "false",
|
|
433
|
-
"aria-label": "
|
|
416
|
+
"aria-label": this.options.i18n.selectedCountryAriaLabel || "Selected country"
|
|
434
417
|
})
|
|
435
418
|
},
|
|
436
419
|
this.flagsContainer
|
|
@@ -448,7 +431,7 @@ class Iti {
|
|
|
448
431
|
this.selectedFlag.setAttribute("aria-disabled", "true");
|
|
449
432
|
}
|
|
450
433
|
|
|
451
|
-
if (
|
|
434
|
+
if (showSelectedDialCode) {
|
|
452
435
|
this.selectedDialCode = this._createEl(
|
|
453
436
|
"div",
|
|
454
437
|
{ class: "iti__selected-dial-code" },
|
|
@@ -479,7 +462,7 @@ class Iti {
|
|
|
479
462
|
{
|
|
480
463
|
type: "text",
|
|
481
464
|
class: "iti__search-input",
|
|
482
|
-
placeholder: "Search"
|
|
465
|
+
placeholder: this.options.i18n.searchPlaceholder || "Search"
|
|
483
466
|
},
|
|
484
467
|
this.dropdownContent
|
|
485
468
|
);
|
|
@@ -492,7 +475,7 @@ class Iti {
|
|
|
492
475
|
class: "iti__country-list",
|
|
493
476
|
id: `iti-${this.id}__country-listbox`,
|
|
494
477
|
role: "listbox",
|
|
495
|
-
"aria-label": "List of countries"
|
|
478
|
+
"aria-label": this.options.i18n.countryListAriaLabel || "List of countries"
|
|
496
479
|
},
|
|
497
480
|
this.dropdownContent
|
|
498
481
|
);
|
|
@@ -514,6 +497,8 @@ class Iti {
|
|
|
514
497
|
let dropdownClasses = "iti iti--container";
|
|
515
498
|
if (useFullscreenPopup) {
|
|
516
499
|
dropdownClasses += " iti--fullscreen-popup";
|
|
500
|
+
} else {
|
|
501
|
+
dropdownClasses += " iti--inline-dropdown";
|
|
517
502
|
}
|
|
518
503
|
if (countrySearch) {
|
|
519
504
|
dropdownClasses += " iti--country-search";
|
|
@@ -526,16 +511,8 @@ class Iti {
|
|
|
526
511
|
}
|
|
527
512
|
|
|
528
513
|
if (hiddenInput) {
|
|
529
|
-
|
|
530
|
-
const
|
|
531
|
-
if (name) {
|
|
532
|
-
const i = name.lastIndexOf("[");
|
|
533
|
-
// if input name contains square brackets, then give the hidden input the same name,
|
|
534
|
-
// replacing the contents of the last set of brackets with the given hiddenInput name
|
|
535
|
-
if (i !== -1) {
|
|
536
|
-
hiddenInputName = `${name.substr(0, i)}[${hiddenInputName}]`;
|
|
537
|
-
}
|
|
538
|
-
}
|
|
514
|
+
const telInputName = this.telInput.getAttribute("name");
|
|
515
|
+
const hiddenInputName = hiddenInput(telInputName);
|
|
539
516
|
this.hiddenInput = this._createEl("input", {
|
|
540
517
|
type: "hidden",
|
|
541
518
|
name: hiddenInputName
|
|
@@ -663,15 +640,6 @@ class Iti {
|
|
|
663
640
|
}
|
|
664
641
|
}
|
|
665
642
|
|
|
666
|
-
// iterate through parent nodes to find the closest label ancestor, if it exists
|
|
667
|
-
_getClosestLabel() {
|
|
668
|
-
let el = this.telInput;
|
|
669
|
-
while (el && el.tagName !== "LABEL") {
|
|
670
|
-
el = el.parentNode;
|
|
671
|
-
}
|
|
672
|
-
return el;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
643
|
// initialise the dropdown listeners
|
|
676
644
|
_initDropdownListeners() {
|
|
677
645
|
// hack for input nested inside label (which is valid markup): clicking the selected-flag to
|
|
@@ -685,7 +653,7 @@ class Iti {
|
|
|
685
653
|
e.preventDefault();
|
|
686
654
|
}
|
|
687
655
|
};
|
|
688
|
-
const label = this.
|
|
656
|
+
const label = this.telInput.closest("label");
|
|
689
657
|
if (label) {
|
|
690
658
|
label.addEventListener("click", this._handleLabelClick);
|
|
691
659
|
}
|
|
@@ -848,9 +816,10 @@ class Iti {
|
|
|
848
816
|
|
|
849
817
|
// trigger a custom event on the input
|
|
850
818
|
_trigger(name) {
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
819
|
+
const e = new Event(name, {
|
|
820
|
+
bubbles: true,
|
|
821
|
+
cancelable: true
|
|
822
|
+
});
|
|
854
823
|
this.telInput.dispatchEvent(e);
|
|
855
824
|
}
|
|
856
825
|
|
|
@@ -892,7 +861,7 @@ class Iti {
|
|
|
892
861
|
}
|
|
893
862
|
}
|
|
894
863
|
|
|
895
|
-
// decide
|
|
864
|
+
// decide if should position dropdown above or below input (depends on position within viewport, and scroll)
|
|
896
865
|
_setDropdownPosition() {
|
|
897
866
|
if (this.options.dropdownContainer) {
|
|
898
867
|
this.options.dropdownContainer.appendChild(this.dropdown);
|
|
@@ -901,8 +870,7 @@ class Iti {
|
|
|
901
870
|
if (!this.options.useFullscreenPopup) {
|
|
902
871
|
const pos = this.telInput.getBoundingClientRect();
|
|
903
872
|
// windowTop from https://stackoverflow.com/a/14384091/217866
|
|
904
|
-
const windowTop =
|
|
905
|
-
window.pageYOffset || document.documentElement.scrollTop;
|
|
873
|
+
const windowTop = document.documentElement.scrollTop;
|
|
906
874
|
const inputTop = pos.top + windowTop;
|
|
907
875
|
const dropdownHeight = this.dropdownContent.offsetHeight;
|
|
908
876
|
// dropdownFitsBelow = (dropdownBottom < windowBottom)
|
|
@@ -941,27 +909,13 @@ class Iti {
|
|
|
941
909
|
}
|
|
942
910
|
}
|
|
943
911
|
|
|
944
|
-
// iterate through parent nodes to find the closest list item
|
|
945
|
-
_getClosestListItem(target) {
|
|
946
|
-
let el = target;
|
|
947
|
-
while (
|
|
948
|
-
el &&
|
|
949
|
-
el !== this.countryList &&
|
|
950
|
-
!el.classList.contains("iti__country")
|
|
951
|
-
) {
|
|
952
|
-
el = el.parentNode;
|
|
953
|
-
}
|
|
954
|
-
// if we reached the countryList element, then return null
|
|
955
|
-
return el === this.countryList ? null : el;
|
|
956
|
-
}
|
|
957
|
-
|
|
958
912
|
// we only bind dropdown listeners when the dropdown is open
|
|
959
913
|
_bindDropdownListeners() {
|
|
960
914
|
// when mouse over a list item, just highlight that one
|
|
961
915
|
// we add the class "highlight", so if they hit "enter" we know which one to select
|
|
962
916
|
this._handleMouseoverCountryList = (e) => {
|
|
963
917
|
// handle event delegation, as we're listening for this event on the countryList
|
|
964
|
-
const listItem =
|
|
918
|
+
const listItem = e.target.closest(".iti__country");
|
|
965
919
|
if (listItem) {
|
|
966
920
|
this._highlightListItem(listItem, false);
|
|
967
921
|
}
|
|
@@ -973,7 +927,7 @@ class Iti {
|
|
|
973
927
|
|
|
974
928
|
// listen for country selection
|
|
975
929
|
this._handleClickCountryList = (e) => {
|
|
976
|
-
const listItem =
|
|
930
|
+
const listItem = e.target.closest(".iti__country");
|
|
977
931
|
if (listItem) {
|
|
978
932
|
this._selectListItem(listItem);
|
|
979
933
|
}
|
|
@@ -1078,7 +1032,8 @@ class Iti {
|
|
|
1078
1032
|
if (
|
|
1079
1033
|
isReset ||
|
|
1080
1034
|
nameLower.includes(query) ||
|
|
1081
|
-
fullDialCode.includes(query)
|
|
1035
|
+
fullDialCode.includes(query) ||
|
|
1036
|
+
c.iso2.includes(query)
|
|
1082
1037
|
) {
|
|
1083
1038
|
this.countryList.appendChild(c.node);
|
|
1084
1039
|
// highlight the first item
|
|
@@ -1157,7 +1112,7 @@ class Iti {
|
|
|
1157
1112
|
) {
|
|
1158
1113
|
const useNational =
|
|
1159
1114
|
this.options.nationalMode ||
|
|
1160
|
-
(number.charAt(0) !== "+" && !this.options.
|
|
1115
|
+
(number.charAt(0) !== "+" && !this.options.showSelectedDialCode);
|
|
1161
1116
|
const { NATIONAL, INTERNATIONAL } = intlTelInputUtils.numberFormat;
|
|
1162
1117
|
const format = useNational ? NATIONAL : INTERNATIONAL;
|
|
1163
1118
|
number = intlTelInputUtils.formatNumber(
|
|
@@ -1194,9 +1149,9 @@ class Iti {
|
|
|
1194
1149
|
number = `+${number}`;
|
|
1195
1150
|
}
|
|
1196
1151
|
|
|
1197
|
-
// if
|
|
1152
|
+
// if showSelectedDialCode enabled, then consider the selected dial code to be part of the number
|
|
1198
1153
|
if (
|
|
1199
|
-
this.options.
|
|
1154
|
+
this.options.showSelectedDialCode &&
|
|
1200
1155
|
selectedDialCode &&
|
|
1201
1156
|
number.charAt(0) !== "+"
|
|
1202
1157
|
) {
|
|
@@ -1298,7 +1253,7 @@ class Iti {
|
|
|
1298
1253
|
// select the given flag, update the placeholder, title, and the active list item
|
|
1299
1254
|
// Note: called from _setInitialState, _updateFlagFromNumber, _selectListItem, setCountry
|
|
1300
1255
|
_setFlag(countryCode) {
|
|
1301
|
-
const { allowDropdown,
|
|
1256
|
+
const { allowDropdown, showSelectedDialCode, showFlags } = this.options;
|
|
1302
1257
|
|
|
1303
1258
|
const prevCountry = this.selectedCountryData.iso2
|
|
1304
1259
|
? this.selectedCountryData
|
|
@@ -1320,9 +1275,9 @@ class Iti {
|
|
|
1320
1275
|
);
|
|
1321
1276
|
}
|
|
1322
1277
|
|
|
1323
|
-
this._setSelectedCountryFlagTitleAttribute(countryCode,
|
|
1278
|
+
this._setSelectedCountryFlagTitleAttribute(countryCode, showSelectedDialCode);
|
|
1324
1279
|
|
|
1325
|
-
if (
|
|
1280
|
+
if (showSelectedDialCode) {
|
|
1326
1281
|
const dialCode = this.selectedCountryData.dialCode
|
|
1327
1282
|
? `+${this.selectedCountryData.dialCode}`
|
|
1328
1283
|
: "";
|
|
@@ -1368,13 +1323,13 @@ class Iti {
|
|
|
1368
1323
|
return prevCountry.iso2 !== countryCode;
|
|
1369
1324
|
}
|
|
1370
1325
|
|
|
1371
|
-
_setSelectedCountryFlagTitleAttribute(countryCode,
|
|
1326
|
+
_setSelectedCountryFlagTitleAttribute(countryCode, showSelectedDialCode) {
|
|
1372
1327
|
if (!this.selectedFlag) {
|
|
1373
1328
|
return;
|
|
1374
1329
|
}
|
|
1375
1330
|
|
|
1376
1331
|
let title;
|
|
1377
|
-
if (countryCode && !
|
|
1332
|
+
if (countryCode && !showSelectedDialCode) {
|
|
1378
1333
|
title = `${this.selectedCountryData.name}: +${this.selectedCountryData.dialCode}`;
|
|
1379
1334
|
} else if (countryCode) {
|
|
1380
1335
|
// For screen reader output, we don't want to include the dial code in the reader output twice
|
|
@@ -1389,7 +1344,7 @@ class Iti {
|
|
|
1389
1344
|
|
|
1390
1345
|
// when the input is in a hidden container during initialisation, we must inject some markup
|
|
1391
1346
|
// into the end of the DOM to calculate the correct offsetWidth
|
|
1392
|
-
// NOTE: this is only used when
|
|
1347
|
+
// NOTE: this is only used when showSelectedDialCode is enabled, so flagsContainer and selectedFlag
|
|
1393
1348
|
// will definitely exist
|
|
1394
1349
|
_getHiddenSelectedFlagWidth() {
|
|
1395
1350
|
// to get the right styling to apply, all we need is a shallow clone of the container,
|
|
@@ -1449,10 +1404,6 @@ class Iti {
|
|
|
1449
1404
|
|
|
1450
1405
|
// focus the input
|
|
1451
1406
|
this.telInput.focus();
|
|
1452
|
-
// put cursor at end - this fix is required for FF and IE11 (with auto inserting dial code),
|
|
1453
|
-
// who try to put the cursor at the beginning the first time
|
|
1454
|
-
const len = this.telInput.value.length;
|
|
1455
|
-
this.telInput.setSelectionRange(len, len);
|
|
1456
1407
|
|
|
1457
1408
|
if (flagChanged) {
|
|
1458
1409
|
this._triggerCountryChange();
|
|
@@ -1500,7 +1451,7 @@ class Iti {
|
|
|
1500
1451
|
_scrollTo(element, middle) {
|
|
1501
1452
|
const container = this.dropdownContent;
|
|
1502
1453
|
// windowTop from https://stackoverflow.com/a/14384091/217866
|
|
1503
|
-
const windowTop =
|
|
1454
|
+
const windowTop = document.documentElement.scrollTop;
|
|
1504
1455
|
const containerHeight = container.offsetHeight;
|
|
1505
1456
|
const containerTop = container.getBoundingClientRect().top + windowTop;
|
|
1506
1457
|
const containerBottom = containerTop + containerHeight;
|
|
@@ -1593,7 +1544,7 @@ class Iti {
|
|
|
1593
1544
|
return dialCode;
|
|
1594
1545
|
}
|
|
1595
1546
|
|
|
1596
|
-
// get the input val, adding the dial code if
|
|
1547
|
+
// get the input val, adding the dial code if showSelectedDialCode is enabled
|
|
1597
1548
|
_getFullNumber() {
|
|
1598
1549
|
const val = this.telInput.value.trim();
|
|
1599
1550
|
const { dialCode } = this.selectedCountryData;
|
|
@@ -1601,12 +1552,12 @@ class Iti {
|
|
|
1601
1552
|
const numericVal = this._getNumeric(val);
|
|
1602
1553
|
|
|
1603
1554
|
if (
|
|
1604
|
-
this.options.
|
|
1555
|
+
this.options.showSelectedDialCode &&
|
|
1605
1556
|
val.charAt(0) !== "+" &&
|
|
1606
1557
|
dialCode &&
|
|
1607
1558
|
numericVal
|
|
1608
1559
|
) {
|
|
1609
|
-
// when using
|
|
1560
|
+
// when using showSelectedDialCode, it is visible so is effectively part of the typed number
|
|
1610
1561
|
prefix = `+${dialCode}`;
|
|
1611
1562
|
} else {
|
|
1612
1563
|
prefix = "";
|
|
@@ -1614,11 +1565,11 @@ class Iti {
|
|
|
1614
1565
|
return prefix + val;
|
|
1615
1566
|
}
|
|
1616
1567
|
|
|
1617
|
-
// remove the dial code if
|
|
1568
|
+
// remove the dial code if showSelectedDialCode is enabled
|
|
1618
1569
|
// also cap the length if the input has a maxlength attribute
|
|
1619
1570
|
_beforeSetNumber(fullNumber) {
|
|
1620
1571
|
let number = fullNumber;
|
|
1621
|
-
if (this.options.
|
|
1572
|
+
if (this.options.showSelectedDialCode) {
|
|
1622
1573
|
let dialCode = this._getDialCode(number);
|
|
1623
1574
|
// if there is a valid dial code
|
|
1624
1575
|
if (dialCode) {
|
|
@@ -1695,7 +1646,7 @@ class Iti {
|
|
|
1695
1646
|
this._handleFlagsContainerKeydown
|
|
1696
1647
|
);
|
|
1697
1648
|
// label click hack
|
|
1698
|
-
const label = this.
|
|
1649
|
+
const label = this.telInput.closest("label");
|
|
1699
1650
|
if (label) {
|
|
1700
1651
|
label.removeEventListener("click", this._handleLabelClick);
|
|
1701
1652
|
}
|
|
@@ -1779,19 +1730,19 @@ class Iti {
|
|
|
1779
1730
|
return -99;
|
|
1780
1731
|
}
|
|
1781
1732
|
|
|
1782
|
-
// validate the input val - assumes the global function
|
|
1733
|
+
// validate the input val - assumes the global function isPossibleNumber (from utilsScript)
|
|
1783
1734
|
isValidNumber() {
|
|
1784
1735
|
const val = this._getFullNumber().trim();
|
|
1785
1736
|
return window.intlTelInputUtils
|
|
1786
|
-
? intlTelInputUtils.
|
|
1737
|
+
? intlTelInputUtils.isPossibleNumber(val, this.selectedCountryData.iso2)
|
|
1787
1738
|
: null;
|
|
1788
1739
|
}
|
|
1789
1740
|
|
|
1790
|
-
//
|
|
1791
|
-
|
|
1741
|
+
// validate the input val (precise) - assumes the global function isValidNumber (from utilsScript)
|
|
1742
|
+
isValidNumberPrecise() {
|
|
1792
1743
|
const val = this._getFullNumber().trim();
|
|
1793
1744
|
return window.intlTelInputUtils
|
|
1794
|
-
? intlTelInputUtils.
|
|
1745
|
+
? intlTelInputUtils.isValidNumber(val, this.selectedCountryData.iso2)
|
|
1795
1746
|
: null;
|
|
1796
1747
|
}
|
|
1797
1748
|
|
|
@@ -2,7 +2,8 @@ var input,
|
|
|
2
2
|
iti,
|
|
3
3
|
totalCountries = 244,
|
|
4
4
|
totalDialCodes = 228,
|
|
5
|
-
defaultPreferredCountries =
|
|
5
|
+
defaultPreferredCountries = 0,
|
|
6
|
+
afghanistanDialCode = "+93";
|
|
6
7
|
|
|
7
8
|
var intlSetup = function(utilsScript) {
|
|
8
9
|
// by default put us in desktop mode
|
|
@@ -50,6 +51,16 @@ var getParentElement = function(i) {
|
|
|
50
51
|
return i.parent();
|
|
51
52
|
};
|
|
52
53
|
|
|
54
|
+
var getDropdownContent = function(i) {
|
|
55
|
+
i = i || input;
|
|
56
|
+
return i.parent().find(".iti__dropdown-content");
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
var getSearchInput = function(i) {
|
|
60
|
+
i = i || input;
|
|
61
|
+
return i.parent().find(".iti__search-input");
|
|
62
|
+
};
|
|
63
|
+
|
|
53
64
|
var getListElement = function(i) {
|
|
54
65
|
i = i || input;
|
|
55
66
|
return i.parent().find(".iti__country-list");
|
|
@@ -111,29 +122,31 @@ var selectInputChars = function(start, end) {
|
|
|
111
122
|
|
|
112
123
|
// use this for focus/blur (instead of using .focus() and .blur() directly, which cause problems in IE11)
|
|
113
124
|
var triggerInputEvent = function(type) {
|
|
114
|
-
var e = new
|
|
125
|
+
var e = new Event(type);
|
|
115
126
|
input[0].dispatchEvent(e);
|
|
116
127
|
}
|
|
117
128
|
|
|
118
129
|
var triggerKey = function(el, type, key) {
|
|
119
|
-
var e = new
|
|
120
|
-
e.key = key;
|
|
130
|
+
var e = new KeyboardEvent(type, { key: key });
|
|
121
131
|
el.dispatchEvent(e);
|
|
122
132
|
};
|
|
123
133
|
|
|
124
134
|
// trigger keydown, then keypress, then add the key, then keyup
|
|
125
|
-
var triggerKeyOnInput = function(key) {
|
|
126
|
-
|
|
127
|
-
triggerKey(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
135
|
+
var triggerKeyOnInput = function(key, customInput) {
|
|
136
|
+
const inputEl = customInput || input;
|
|
137
|
+
triggerKey(inputEl[0], 'keydown', key);
|
|
138
|
+
triggerKey(inputEl[0], 'keypress', key);
|
|
139
|
+
var previousVal = inputEl.val();
|
|
140
|
+
inputEl.val(previousVal + key);
|
|
141
|
+
triggerKey(inputEl[0], 'keyup', key);
|
|
142
|
+
triggerKey(inputEl[0], 'input', key);
|
|
131
143
|
};
|
|
132
144
|
|
|
133
145
|
var triggerKeyOnBody = function(key) {
|
|
134
146
|
triggerKey(document, 'keydown', key);
|
|
135
147
|
triggerKey(document, 'keypress', key);
|
|
136
148
|
triggerKey(document, 'keyup', key);
|
|
149
|
+
triggerKey(document, 'input', key);
|
|
137
150
|
};
|
|
138
151
|
|
|
139
152
|
var triggerKeyOnFlagsContainerElement = function(key) {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
describe("dropdown shortcuts: init plugin (with nationalMode=false, autoInsertDialCode=true) to test keyboard shortcuts", function() {
|
|
3
|
+
describe("dropdown shortcuts: init plugin (with countrySearch=false, nationalMode=false, autoInsertDialCode=true) to test keyboard shortcuts", function() {
|
|
4
4
|
|
|
5
5
|
beforeEach(function() {
|
|
6
6
|
intlSetup();
|
|
7
7
|
input = $("<input>").appendTo("body");
|
|
8
8
|
iti = window.intlTelInput(input[0], {
|
|
9
|
+
countrySearch: false,
|
|
9
10
|
nationalMode: false,
|
|
10
11
|
autoInsertDialCode: true,
|
|
11
12
|
});
|
|
@@ -138,7 +139,7 @@ describe("dropdown shortcuts: init plugin (with nationalMode=false, autoInsertDi
|
|
|
138
139
|
});
|
|
139
140
|
|
|
140
141
|
it("updates the dial code", function() {
|
|
141
|
-
expect(getInputVal()).toEqual("+
|
|
142
|
+
expect(getInputVal()).toEqual("+355");
|
|
142
143
|
});
|
|
143
144
|
|
|
144
145
|
});
|
|
@@ -25,14 +25,13 @@ describe("initial values:", function() {
|
|
|
25
25
|
|
|
26
26
|
it("has the right number of list items", function() {
|
|
27
27
|
expect(getListLength()).toEqual(totalCountries + defaultPreferredCountries);
|
|
28
|
-
expect(getPreferredCountriesLength()).toEqual(defaultPreferredCountries);
|
|
29
28
|
// only 1 active list item
|
|
30
29
|
expect(getActiveListItem().length).toEqual(1);
|
|
31
30
|
});
|
|
32
31
|
|
|
33
32
|
it("sets the state correctly: selected flag and active list item", function() {
|
|
34
|
-
expect(getSelectedFlagElement()).toHaveClass("
|
|
35
|
-
expect(getActiveListItem().attr("data-country-code")).toEqual("
|
|
33
|
+
expect(getSelectedFlagElement()).toHaveClass("iti__af");
|
|
34
|
+
expect(getActiveListItem().attr("data-country-code")).toEqual("af");
|
|
36
35
|
});
|
|
37
36
|
|
|
38
37
|
});
|
|
@@ -13,7 +13,7 @@ describe("getSelectedCountryData: init plugin to test public method getSelectedC
|
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
it("gets the right default country data", function() {
|
|
16
|
-
expect(iti.getSelectedCountryData().iso2).toEqual("
|
|
16
|
+
expect(iti.getSelectedCountryData().iso2).toEqual("af");
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
it("change country by number gets the right country data", function() {
|