Phone input prefill country issue fixed (#213)
* fix prefill phone issue * js phone parse fixes * revert last change * fix phone UI * Code optimize --------- Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
parent
54f92f844f
commit
f7ecd6f233
|
@ -220,14 +220,14 @@ class AnswerFormRequest extends FormRequest
|
|||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
// Escape all '\' in select options
|
||||
$receivedData = $this->toArray();
|
||||
$mergeData = [];
|
||||
collect($this->form->properties)->filter(function ($property) {
|
||||
return in_array($property['type'], ['select', 'multi_select']);
|
||||
})->each(function ($property) use ($receivedData, &$mergeData) {
|
||||
$countryCodeMapper = json_decode(file_get_contents(resource_path('data/country_code_mapper.json')), true);
|
||||
collect($this->form->properties)->each(function ($property) use ($countryCodeMapper, $receivedData, &$mergeData) {
|
||||
$receivedValue = $receivedData[$property['id']] ?? null;
|
||||
if (!is_null($receivedValue)) {
|
||||
|
||||
// Escape all '\' in select options
|
||||
if(in_array($property['type'], ['select', 'multi_select']) && !is_null($receivedValue)){
|
||||
if (is_array($receivedValue)) {
|
||||
$mergeData[$property['id']] = collect($receivedValue)->map(function ($value) {
|
||||
$value = Str::of($value);
|
||||
|
@ -244,6 +244,10 @@ class AnswerFormRequest extends FormRequest
|
|||
)->toString();
|
||||
}
|
||||
}
|
||||
|
||||
if($property['type'] === 'phone_number' && (!isset($property['use_simple_text_input']) || !$property['use_simple_text_input']) && $receivedValue && in_array($receivedValue, $countryCodeMapper)){
|
||||
$mergeData[$property['id']] = null;
|
||||
}
|
||||
});
|
||||
|
||||
$this->merge($mergeData);
|
||||
|
|
|
@ -131,6 +131,11 @@ class StoreFormSubmissionJob implements ShouldQueue
|
|||
if($this->form->is_pro && $field['type'] == 'signature') {
|
||||
$finalData[$field['id']] = $this->storeSignature($answerValue);
|
||||
}
|
||||
|
||||
// For Phone
|
||||
if($field['type'] == 'phone_number' && $answerValue && ctype_alpha(substr($answerValue, 0, 2)) && (!isset($field['use_simple_text_input']) || !$field['use_simple_text_input'])) {
|
||||
$finalData[$field['id']] = substr($answerValue, 2);
|
||||
}
|
||||
}
|
||||
|
||||
return $finalData;
|
||||
|
|
|
@ -12,10 +12,13 @@ class ValidPhoneInputRule implements Rule
|
|||
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
if (!is_string($value) || !Str::startsWith($value, '+')) {
|
||||
if (!is_string($value) || !$value) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if(ctype_alpha(substr($value, 0, 2))){ // First 2 will be country code
|
||||
$value = substr($value, 2);
|
||||
}
|
||||
$phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
|
||||
$phone = $phoneUtil->parse($value);
|
||||
$this->reason = $phoneUtil->isPossibleNumberWithReason($phone);
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
[
|
||||
"AF+93",
|
||||
"AX+358",
|
||||
"AL+355",
|
||||
"DZ+213",
|
||||
"AS+1684",
|
||||
"AD+376",
|
||||
"AO+244",
|
||||
"AI+1264",
|
||||
"AQ+672",
|
||||
"AG+1268",
|
||||
"AR+54",
|
||||
"AM+374",
|
||||
"AW+297",
|
||||
"AU+61",
|
||||
"AT+43",
|
||||
"AZ+994",
|
||||
"BS+1242",
|
||||
"BH+973",
|
||||
"BD+880",
|
||||
"BB+1246",
|
||||
"BY+375",
|
||||
"BE+32",
|
||||
"BZ+501",
|
||||
"BJ+229",
|
||||
"BM+1441",
|
||||
"BT+975",
|
||||
"BO+591",
|
||||
"BA+387",
|
||||
"BW+267",
|
||||
"BV+47",
|
||||
"BR+55",
|
||||
"IO+246",
|
||||
"BN+673",
|
||||
"BG+359",
|
||||
"BF+226",
|
||||
"BI+257",
|
||||
"KH+855",
|
||||
"CM+237",
|
||||
"CA+1",
|
||||
"CV+238",
|
||||
"KY+345",
|
||||
"CF+236",
|
||||
"TD+235",
|
||||
"CL+56",
|
||||
"CN+86",
|
||||
"CX+61",
|
||||
"CC+61",
|
||||
"CO+57",
|
||||
"KM+269",
|
||||
"CG+242",
|
||||
"CD+243",
|
||||
"CK+682",
|
||||
"CR+506",
|
||||
"CI+225",
|
||||
"HR+385",
|
||||
"CU+53",
|
||||
"CY+357",
|
||||
"CZ+420",
|
||||
"DK+45",
|
||||
"DJ+253",
|
||||
"DM+1767",
|
||||
"DO+1849",
|
||||
"EC+593",
|
||||
"EG+20",
|
||||
"SV+503",
|
||||
"GQ+240",
|
||||
"ER+291",
|
||||
"EE+372",
|
||||
"ET+251",
|
||||
"FK+500",
|
||||
"FO+298",
|
||||
"FJ+679",
|
||||
"FI+358",
|
||||
"FR+33",
|
||||
"GF+594",
|
||||
"PF+689",
|
||||
"TF+262",
|
||||
"GA+241",
|
||||
"GM+220",
|
||||
"GE+995",
|
||||
"DE+49",
|
||||
"GH+233",
|
||||
"GI+350",
|
||||
"GR+30",
|
||||
"GL+299",
|
||||
"GD+1473",
|
||||
"GP+590",
|
||||
"GU+1671",
|
||||
"GT+502",
|
||||
"GG+44",
|
||||
"GN+224",
|
||||
"GW+245",
|
||||
"GY+592",
|
||||
"HT+509",
|
||||
"HM+672",
|
||||
"VA+379",
|
||||
"HN+504",
|
||||
"HK+852",
|
||||
"HU+36",
|
||||
"IS+354",
|
||||
"IN+91",
|
||||
"ID+62",
|
||||
"IR+98",
|
||||
"IQ+964",
|
||||
"IE+353",
|
||||
"IM+44",
|
||||
"IL+972",
|
||||
"IT+39",
|
||||
"JM+1876",
|
||||
"JP+81",
|
||||
"JE+44",
|
||||
"JO+962",
|
||||
"KZ+7",
|
||||
"KE+254",
|
||||
"KI+686",
|
||||
"KP+850",
|
||||
"KR+82",
|
||||
"XK+383",
|
||||
"KW+965",
|
||||
"KG+996",
|
||||
"LA+856",
|
||||
"LV+371",
|
||||
"LB+961",
|
||||
"LS+266",
|
||||
"LR+231",
|
||||
"LY+218",
|
||||
"LI+423",
|
||||
"LT+370",
|
||||
"LU+352",
|
||||
"MO+853",
|
||||
"MK+389",
|
||||
"MG+261",
|
||||
"MW+265",
|
||||
"MY+60",
|
||||
"MV+960",
|
||||
"ML+223",
|
||||
"MT+356",
|
||||
"MH+692",
|
||||
"MQ+596",
|
||||
"MR+222",
|
||||
"MU+230",
|
||||
"YT+262",
|
||||
"MX+52",
|
||||
"FM+691",
|
||||
"MD+373",
|
||||
"MC+377",
|
||||
"MN+976",
|
||||
"ME+382",
|
||||
"MS+1664",
|
||||
"MA+212",
|
||||
"MZ+258",
|
||||
"MM+95",
|
||||
"NA+264",
|
||||
"NR+674",
|
||||
"NP+977",
|
||||
"NL+31",
|
||||
"AN+599",
|
||||
"NC+687",
|
||||
"NZ+64",
|
||||
"NI+505",
|
||||
"NE+227",
|
||||
"NG+234",
|
||||
"NU+683",
|
||||
"NF+672",
|
||||
"MP+1670",
|
||||
"NO+47",
|
||||
"OM+968",
|
||||
"PK+92",
|
||||
"PW+680",
|
||||
"PS+970",
|
||||
"PA+507",
|
||||
"PG+675",
|
||||
"PY+595",
|
||||
"PE+51",
|
||||
"PH+63",
|
||||
"PN+64",
|
||||
"PL+48",
|
||||
"PT+351",
|
||||
"PR+1939",
|
||||
"QA+974",
|
||||
"RO+40",
|
||||
"RU+7",
|
||||
"RW+250",
|
||||
"RE+262",
|
||||
"BL+590",
|
||||
"SH+290",
|
||||
"KN+1869",
|
||||
"LC+1758",
|
||||
"MF+590",
|
||||
"PM+508",
|
||||
"VC+1784",
|
||||
"WS+685",
|
||||
"SM+378",
|
||||
"ST+239",
|
||||
"SA+966",
|
||||
"SN+221",
|
||||
"RS+381",
|
||||
"SC+248",
|
||||
"SL+232",
|
||||
"SG+65",
|
||||
"SK+421",
|
||||
"SI+386",
|
||||
"SB+677",
|
||||
"SO+252",
|
||||
"ZA+27",
|
||||
"SS+211",
|
||||
"GS+500",
|
||||
"ES+34",
|
||||
"LK+94",
|
||||
"SD+249",
|
||||
"SR+597",
|
||||
"SJ+47",
|
||||
"SZ+268",
|
||||
"SE+46",
|
||||
"CH+41",
|
||||
"SY+963",
|
||||
"TW+886",
|
||||
"TJ+992",
|
||||
"TZ+255",
|
||||
"TH+66",
|
||||
"TL+670",
|
||||
"TG+228",
|
||||
"TK+690",
|
||||
"TO+676",
|
||||
"TT+1868",
|
||||
"TN+216",
|
||||
"TR+90",
|
||||
"TM+993",
|
||||
"TC+1649",
|
||||
"TV+688",
|
||||
"UG+256",
|
||||
"UA+380",
|
||||
"AE+971",
|
||||
"GB+44",
|
||||
"US+1",
|
||||
"UY+598",
|
||||
"UZ+998",
|
||||
"VU+678",
|
||||
"VE+58",
|
||||
"VN+84",
|
||||
"VG+1284",
|
||||
"VI+1340",
|
||||
"WF+681",
|
||||
"YE+967",
|
||||
"ZM+260",
|
||||
"ZW+263"
|
||||
]
|
|
@ -13,7 +13,7 @@
|
|||
</small>
|
||||
</div>
|
||||
<div :id="id ? id : name" :name="name" :style="inputStyle" class="flex items-center">
|
||||
<v-select class="w-[110px]" dropdown-class="w-[350px]" input-class="rounded-r-none" :data="countries"
|
||||
<v-select class="w-[130px]" dropdown-class="w-[300px]" input-class="rounded-r-none" :data="countries"
|
||||
v-model="selectedCountryCode"
|
||||
:has-error="hasValidation && form.errors.has(name)"
|
||||
:disabled="disabled" :searchable="true" :search-keys="['name']" :option-key="'code'" :color="color"
|
||||
|
@ -54,64 +54,74 @@ import parsePhoneNumber from 'libphonenumber-js'
|
|||
|
||||
export default {
|
||||
phone: 'PhoneInput',
|
||||
components: {CountryFlag},
|
||||
components: { CountryFlag },
|
||||
directives: {
|
||||
onClickaway: onClickaway
|
||||
},
|
||||
mixins: [inputMixin],
|
||||
props: {
|
||||
canOnlyCountry: {type: Boolean, default: false}
|
||||
canOnlyCountry: { type: Boolean, default: false }
|
||||
},
|
||||
|
||||
data() {
|
||||
data () {
|
||||
return {
|
||||
selectedCountryCode: this.getCountryBy('US'), // Default US
|
||||
selectedCountryCode: null,
|
||||
countries: countryCodes,
|
||||
inputVal: null
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.compVal) {
|
||||
const phoneObj = parsePhoneNumber(this.compVal)
|
||||
if (phoneObj !== undefined && phoneObj) {
|
||||
if (phoneObj.country !== undefined && phoneObj.country) {
|
||||
this.selectedCountryCode = this.getCountryBy(phoneObj.country)
|
||||
watch: {
|
||||
inputVal: {
|
||||
handler (val) {
|
||||
if (val && val.startsWith('0')) {
|
||||
val = val.substring(1)
|
||||
}
|
||||
this.inputVal = phoneObj.nationalNumber
|
||||
} else if (this.compVal) {
|
||||
this.selectedCountryCode = this.getCountryBy(this.compVal, 'dial_code')
|
||||
if (this.canOnlyCountry) {
|
||||
this.compVal = (val) ? this.selectedCountryCode.code + this.selectedCountryCode.dial_code + val : this.selectedCountryCode.code + this.selectedCountryCode.dial_code
|
||||
} else {
|
||||
this.compVal = (val) ? this.selectedCountryCode.code + this.selectedCountryCode.dial_code + val : null
|
||||
}
|
||||
}
|
||||
},
|
||||
selectedCountryCode (newVal, oldVal) {
|
||||
if (this.compVal && newVal && oldVal) {
|
||||
this.compVal = this.compVal.replace(oldVal.code + oldVal.dial_code, newVal.code + newVal.dial_code)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
inputVal: {
|
||||
handler(val) {
|
||||
if (val && val.startsWith('0')) {
|
||||
val = val.substring(1)
|
||||
}
|
||||
this.compVal = (val) ? this.selectedCountryCode.dial_code + val : null
|
||||
}
|
||||
},
|
||||
selectedCountryCode(newVal, oldVal) {
|
||||
mounted () {
|
||||
if (this.compVal) {
|
||||
this.compVal = this.compVal.replace(oldVal.dial_code, newVal.dial_code)
|
||||
if(!this.compVal.startsWith('+')){
|
||||
this.selectedCountryCode = this.getCountryBy(this.compVal.substring(2, 0))
|
||||
}
|
||||
|
||||
const phoneObj = parsePhoneNumber(this.compVal)
|
||||
if (phoneObj !== undefined && phoneObj) {
|
||||
if (!this.selectedCountryCode && phoneObj.country !== undefined && phoneObj.country) {
|
||||
this.selectedCountryCode = this.getCountryBy(phoneObj.country)
|
||||
}
|
||||
this.inputVal = phoneObj.nationalNumber
|
||||
}
|
||||
}
|
||||
if(!this.selectedCountryCode){
|
||||
this.selectedCountryCode = this.getCountryBy()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCountryBy(code, type = 'code') {
|
||||
getCountryBy (code = 'US', type = 'code') {
|
||||
if(!code) code = 'US' // Default US
|
||||
return countryCodes.find((item) => {
|
||||
return item[type] === code
|
||||
})
|
||||
},
|
||||
onInput(event) {
|
||||
onInput (event) {
|
||||
this.inputVal = event.target.value.replace(/[^0-9]/g, '')
|
||||
},
|
||||
onChangeCountryCode() {
|
||||
onChangeCountryCode () {
|
||||
if (this.canOnlyCountry && (this.inputVal === null || this.inputVal === '' || !this.inputVal)) {
|
||||
this.compVal = this.selectedCountryCode.dial_code
|
||||
this.compVal = this.selectedCountryCode.code + this.selectedCountryCode.dial_code
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,8 @@
|
|||
</div>
|
||||
<template v-if="filteredOptions.length>0">
|
||||
<li v-for="item in filteredOptions" :key="item[optionKey]" role="option" :style="optionStyle"
|
||||
class="text-gray-900 cursor-default select-none relative py-2 pl-3 pr-9 cursor-pointer group hover:text-white hover:bg-form-color focus:outline-none focus:text-white focus:bg-nt-blue"
|
||||
:class="{'px-3 pr-9':multiple, 'px-3':!multiple}"
|
||||
class="text-gray-900 cursor-default select-none relative py-2 cursor-pointer group hover:text-white hover:bg-form-color focus:outline-none focus:text-white focus:bg-nt-blue"
|
||||
:dusk="dusk+'_option'" @click="select(item)"
|
||||
>
|
||||
<slot name="option" :option="item" :selected="isSelected(item)" />
|
||||
|
@ -69,7 +70,8 @@
|
|||
{{ (allowCreation ? 'Type something to add an option': 'No option available') }}.
|
||||
</p>
|
||||
<li v-if="allowCreation && searchTerm" role="option" :style="optionStyle"
|
||||
class="text-gray-900 cursor-default select-none relative py-2 pl-3 pr-9 cursor-pointer group hover:text-white hover:bg-form-color focus:outline-none focus:text-white focus:bg-nt-blue"
|
||||
:class="{'px-3 pr-9':multiple, 'px-3':!multiple}"
|
||||
class="text-gray-900 cursor-default select-none relative py-2 cursor-pointer group hover:text-white hover:bg-form-color focus:outline-none focus:text-white focus:bg-nt-blue"
|
||||
@click="createOption(searchTerm)"
|
||||
>
|
||||
Create <b class="px-1 bg-gray-300 rounded group-hover:text-black">{{ searchTerm }}</b>
|
||||
|
|
|
@ -44,7 +44,7 @@ class FormSubmissionDataFactory
|
|||
$value = $this->faker->url();
|
||||
break;
|
||||
case 'phone_number':
|
||||
$value = '+33749119783';
|
||||
$value = 'FR+33749119783';
|
||||
break;
|
||||
case 'date':
|
||||
$value = $this->faker->date();
|
||||
|
|
Loading…
Reference in New Issue