@countriesdb/widget 0.1.19 → 0.1.21
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/dist/dom-manipulation.d.ts +1 -1
- package/dist/dom-manipulation.js +9 -2
- package/dist/index.esm.js +58 -27
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +58 -27
- package/dist/index.js.map +1 -1
- package/dist/initialization.d.ts +4 -0
- package/dist/initialization.js +6 -9
- package/package.json +1 -1
|
@@ -23,7 +23,7 @@ export declare function applyPreselectedValue(select: SelectElement, apiKey?: st
|
|
|
23
23
|
/**
|
|
24
24
|
* Handle API error by showing error message in select
|
|
25
25
|
*/
|
|
26
|
-
export declare function handleApiError(select: SelectElement, errorMessage: string | Error): void;
|
|
26
|
+
export declare function handleApiError(select: SelectElement, errorMessage: string | Error, replace?: boolean): void;
|
|
27
27
|
/**
|
|
28
28
|
* Parse boolean from string value
|
|
29
29
|
*/
|
package/dist/dom-manipulation.js
CHANGED
|
@@ -142,12 +142,19 @@ export function applyPreselectedValue(select, apiKey) {
|
|
|
142
142
|
/**
|
|
143
143
|
* Handle API error by showing error message in select
|
|
144
144
|
*/
|
|
145
|
-
export function handleApiError(select, errorMessage) {
|
|
145
|
+
export function handleApiError(select, errorMessage, replace = false) {
|
|
146
146
|
const message = errorMessage instanceof Error ? errorMessage.message : errorMessage;
|
|
147
147
|
const defaultValue = select.dataset.defaultValue ?? '';
|
|
148
148
|
// Add "Error: " prefix to match old widget behavior and test expectations
|
|
149
149
|
const formattedMessage = message.startsWith('Error: ') ? message : `Error: ${message}`;
|
|
150
|
-
|
|
150
|
+
if (replace) {
|
|
151
|
+
select.innerHTML = `<option value="${defaultValue}" disabled>${formattedMessage}</option>`;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
select.innerHTML += `<option value="${defaultValue}" disabled>${formattedMessage}</option>`;
|
|
155
|
+
}
|
|
156
|
+
// Ensure select is enabled so users can see the error
|
|
157
|
+
select.disabled = false;
|
|
151
158
|
}
|
|
152
159
|
/**
|
|
153
160
|
* Parse boolean from string value
|
package/dist/index.esm.js
CHANGED
|
@@ -143,12 +143,19 @@ function applyPreselectedValue(select, apiKey) {
|
|
|
143
143
|
/**
|
|
144
144
|
* Handle API error by showing error message in select
|
|
145
145
|
*/
|
|
146
|
-
function handleApiError(select, errorMessage) {
|
|
146
|
+
function handleApiError(select, errorMessage, replace = false) {
|
|
147
147
|
const message = errorMessage instanceof Error ? errorMessage.message : errorMessage;
|
|
148
148
|
const defaultValue = select.dataset.defaultValue ?? '';
|
|
149
149
|
// Add "Error: " prefix to match old widget behavior and test expectations
|
|
150
150
|
const formattedMessage = message.startsWith('Error: ') ? message : `Error: ${message}`;
|
|
151
|
-
|
|
151
|
+
if (replace) {
|
|
152
|
+
select.innerHTML = `<option value="${defaultValue}" disabled>${formattedMessage}</option>`;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
select.innerHTML += `<option value="${defaultValue}" disabled>${formattedMessage}</option>`;
|
|
156
|
+
}
|
|
157
|
+
// Ensure select is enabled so users can see the error
|
|
158
|
+
select.disabled = false;
|
|
152
159
|
}
|
|
153
160
|
|
|
154
161
|
/**
|
|
@@ -458,8 +465,7 @@ async function setupSubdivisionSelection(apiKey, backendUrl, state, config) {
|
|
|
458
465
|
: null;
|
|
459
466
|
// Check if linked country select is multi-select (not allowed)
|
|
460
467
|
if (linkedCountrySelect && linkedCountrySelect.hasAttribute('multiple')) {
|
|
461
|
-
|
|
462
|
-
select.innerHTML = `<option value="${defaultValue}" disabled>Error: Cannot link to multi-select country. Use data-country-code instead.</option>`;
|
|
468
|
+
handleApiError(select, 'Cannot link to multi-select country. Use data-country-code instead.', true);
|
|
463
469
|
continue;
|
|
464
470
|
}
|
|
465
471
|
// No direct link → maybe data-country-code
|
|
@@ -469,8 +475,7 @@ async function setupSubdivisionSelection(apiKey, backendUrl, state, config) {
|
|
|
469
475
|
await updateSubdivisionSelect(select, apiKey, backendUrl, state, config, select.dataset.countryCode);
|
|
470
476
|
}
|
|
471
477
|
else {
|
|
472
|
-
|
|
473
|
-
select.innerHTML += `<option value="${defaultValue}" disabled>Error: No country select present</option>`;
|
|
478
|
+
handleApiError(select, 'No country select present');
|
|
474
479
|
}
|
|
475
480
|
}
|
|
476
481
|
// Always dispatch an update event for user-initiated subdivision changes
|
|
@@ -516,7 +521,8 @@ async function updateSubdivisionSelect(select, apiKey, backendUrl, state, config
|
|
|
516
521
|
// Use GeoIP only if data-preselected attribute is not set at all
|
|
517
522
|
const shouldUseGeoIP = preselectedValue === undefined || preselectedValue === null;
|
|
518
523
|
// Check if this subdivision select prefers official subdivisions
|
|
519
|
-
const preferOfficial = select.hasAttribute('data-prefer-official')
|
|
524
|
+
const preferOfficial = select.hasAttribute('data-prefer-official') ||
|
|
525
|
+
config.preferOfficialSubdivisions;
|
|
520
526
|
const languageHeaders = CountriesDBClient.getLanguageHeaders(config.forcedLanguage, config.defaultLanguage);
|
|
521
527
|
const subdivisionsResult = await CountriesDBClient.fetchSubdivisions({
|
|
522
528
|
apiKey,
|
|
@@ -613,8 +619,7 @@ async function updateSubdivisionSelect(select, apiKey, backendUrl, state, config
|
|
|
613
619
|
}
|
|
614
620
|
else if (!select.dataset.country ||
|
|
615
621
|
!document.querySelector(`.country-selection[data-name="${select.dataset.country}"]`)) {
|
|
616
|
-
|
|
617
|
-
select.innerHTML += `<option value="${defaultValue}" disabled>Error: No country select present</option>`;
|
|
622
|
+
handleApiError(select, 'No country select present');
|
|
618
623
|
}
|
|
619
624
|
}
|
|
620
625
|
/**
|
|
@@ -643,8 +648,7 @@ async function setupCountrySelection(apiKey, backendUrl, state, config, subdivis
|
|
|
643
648
|
if (name && seenNames[name]) {
|
|
644
649
|
select.removeAttribute('data-name');
|
|
645
650
|
initializeSelect(select, '—');
|
|
646
|
-
|
|
647
|
-
select.innerHTML += `<option value="${defaultValue}" disabled>Error: Duplicate field</option>`;
|
|
651
|
+
handleApiError(select, 'Duplicate field');
|
|
648
652
|
continue;
|
|
649
653
|
}
|
|
650
654
|
if (name) {
|
|
@@ -808,6 +812,7 @@ async function CountriesWidgetLoad(options = {}) {
|
|
|
808
812
|
followUpward: config.followUpward || false,
|
|
809
813
|
showSubdivisionType: config.showSubdivisionType !== false,
|
|
810
814
|
allowParentSelection: config.allowParentSelection || false,
|
|
815
|
+
preferOfficialSubdivisions: config.preferOfficialSubdivisions || false,
|
|
811
816
|
subdivisionRomanizationPreference: config.subdivisionRomanizationPreference,
|
|
812
817
|
preferLocalVariant: config.preferLocalVariant || false,
|
|
813
818
|
subdivisionNameFilter: config.subdivisionNameFilter,
|
|
@@ -817,6 +822,7 @@ async function CountriesWidgetLoad(options = {}) {
|
|
|
817
822
|
followUpward: config.followUpward || false,
|
|
818
823
|
showSubdivisionType: config.showSubdivisionType !== false,
|
|
819
824
|
allowParentSelection: config.allowParentSelection || false,
|
|
825
|
+
preferOfficialSubdivisions: config.preferOfficialSubdivisions || false,
|
|
820
826
|
subdivisionRomanizationPreference: config.subdivisionRomanizationPreference,
|
|
821
827
|
preferLocalVariant: config.preferLocalVariant || false,
|
|
822
828
|
forcedLanguage: config.forcedLanguage,
|
|
@@ -849,6 +855,10 @@ async function CountriesWidgetLoad(options = {}) {
|
|
|
849
855
|
* Get configuration from options or script URL parameters
|
|
850
856
|
*/
|
|
851
857
|
function getConfigFromOptionsOrScript(options) {
|
|
858
|
+
// Check for global config first (for bundled widgets that need config before auto-init)
|
|
859
|
+
const globalConfig = typeof window !== 'undefined' && window.CountriesDBConfig
|
|
860
|
+
? window.CountriesDBConfig
|
|
861
|
+
: null;
|
|
852
862
|
// Try to get config from script URL (for backward compatibility with widget.blade.php)
|
|
853
863
|
let scriptUrl = null;
|
|
854
864
|
try {
|
|
@@ -877,36 +887,57 @@ function getConfigFromOptionsOrScript(options) {
|
|
|
877
887
|
// Ignore errors
|
|
878
888
|
}
|
|
879
889
|
const config = {
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
890
|
+
// Priority: options > globalConfig > scriptUrl params > defaults
|
|
891
|
+
publicKey: options.publicKey ?? globalConfig?.publicKey ?? scriptUrl?.searchParams.get('public_key') ?? '',
|
|
892
|
+
backendUrl: options.backendUrl ?? globalConfig?.backendUrl ?? scriptUrl?.searchParams.get('backend_url') ?? getBackendUrlFromScript(),
|
|
893
|
+
defaultLanguage: options.defaultLanguage ?? globalConfig?.defaultLanguage ?? scriptUrl?.searchParams.get('default_language') ?? undefined,
|
|
894
|
+
forcedLanguage: options.forcedLanguage ?? globalConfig?.forcedLanguage ?? scriptUrl?.searchParams.get('forced_language') ?? undefined,
|
|
884
895
|
showSubdivisionType: options.showSubdivisionType !== undefined
|
|
885
896
|
? options.showSubdivisionType
|
|
886
|
-
:
|
|
897
|
+
: globalConfig?.showSubdivisionType !== undefined
|
|
898
|
+
? globalConfig.showSubdivisionType
|
|
899
|
+
: parseBoolean(scriptUrl?.searchParams.get('show_subdivision_type') ?? '1'),
|
|
887
900
|
followRelated: options.followRelated !== undefined
|
|
888
901
|
? options.followRelated
|
|
889
|
-
:
|
|
902
|
+
: globalConfig?.followRelated !== undefined
|
|
903
|
+
? globalConfig.followRelated
|
|
904
|
+
: parseBoolean(scriptUrl?.searchParams.get('follow_related') ?? 'false'),
|
|
890
905
|
followUpward: options.followUpward !== undefined
|
|
891
906
|
? options.followUpward
|
|
892
|
-
:
|
|
907
|
+
: globalConfig?.followUpward !== undefined
|
|
908
|
+
? globalConfig.followUpward
|
|
909
|
+
: parseBoolean(scriptUrl?.searchParams.get('follow_upward') ?? 'false'),
|
|
893
910
|
allowParentSelection: options.allowParentSelection !== undefined
|
|
894
911
|
? options.allowParentSelection
|
|
895
|
-
:
|
|
912
|
+
: globalConfig?.allowParentSelection !== undefined
|
|
913
|
+
? globalConfig.allowParentSelection
|
|
914
|
+
: parseBoolean(scriptUrl?.searchParams.get('allow_parent_selection') ?? 'false'),
|
|
896
915
|
isoCountryNames: options.isoCountryNames !== undefined
|
|
897
916
|
? options.isoCountryNames
|
|
898
|
-
:
|
|
917
|
+
: globalConfig?.isoCountryNames !== undefined
|
|
918
|
+
? globalConfig.isoCountryNames
|
|
919
|
+
: parseBoolean(scriptUrl?.searchParams.get('iso_country_names') ?? 'false'),
|
|
920
|
+
preferOfficialSubdivisions: options.preferOfficialSubdivisions !== undefined
|
|
921
|
+
? options.preferOfficialSubdivisions
|
|
922
|
+
: globalConfig?.preferOfficialSubdivisions !== undefined
|
|
923
|
+
? globalConfig.preferOfficialSubdivisions
|
|
924
|
+
: parseBoolean(scriptUrl?.searchParams.get('prefer_official') ?? 'false'),
|
|
899
925
|
subdivisionRomanizationPreference: options.subdivisionRomanizationPreference ||
|
|
926
|
+
globalConfig?.subdivisionRomanizationPreference ||
|
|
900
927
|
scriptUrl?.searchParams.get('subdivision_romanization_preference') ||
|
|
901
928
|
undefined,
|
|
902
929
|
preferLocalVariant: options.preferLocalVariant !== undefined
|
|
903
930
|
? options.preferLocalVariant
|
|
904
|
-
:
|
|
905
|
-
|
|
906
|
-
|
|
931
|
+
: globalConfig?.preferLocalVariant !== undefined
|
|
932
|
+
? globalConfig.preferLocalVariant
|
|
933
|
+
: parseBoolean(scriptUrl?.searchParams.get('prefer_local_variant') ?? 'false'),
|
|
934
|
+
countryNameFilter: options.countryNameFilter ?? globalConfig?.countryNameFilter,
|
|
935
|
+
subdivisionNameFilter: options.subdivisionNameFilter ?? globalConfig?.subdivisionNameFilter,
|
|
907
936
|
autoInit: options.autoInit !== undefined
|
|
908
937
|
? options.autoInit
|
|
909
|
-
:
|
|
938
|
+
: globalConfig?.autoInit !== undefined
|
|
939
|
+
? globalConfig.autoInit
|
|
940
|
+
: parseBoolean(scriptUrl?.searchParams.get('auto_init') ?? 'true'),
|
|
910
941
|
};
|
|
911
942
|
// Resolve filter functions from global scope if specified by name
|
|
912
943
|
if (scriptUrl) {
|
|
@@ -1006,14 +1037,14 @@ function parseBoolean(value) {
|
|
|
1006
1037
|
* Show error when both follow_related and follow_upward are enabled
|
|
1007
1038
|
*/
|
|
1008
1039
|
function showParamConflictError() {
|
|
1009
|
-
const errorMessage = '
|
|
1040
|
+
const errorMessage = 'Cannot enable both follow_related and follow_upward';
|
|
1010
1041
|
const countrySelects = Array.from(document.querySelectorAll('.country-selection'));
|
|
1011
1042
|
for (const select of countrySelects) {
|
|
1012
|
-
select
|
|
1043
|
+
handleApiError(select, errorMessage, true);
|
|
1013
1044
|
}
|
|
1014
1045
|
const subdivisionSelects = Array.from(document.querySelectorAll('.subdivision-selection'));
|
|
1015
1046
|
for (const select of subdivisionSelects) {
|
|
1016
|
-
select
|
|
1047
|
+
handleApiError(select, errorMessage, true);
|
|
1017
1048
|
}
|
|
1018
1049
|
}
|
|
1019
1050
|
// Expose public loader
|