2 * This script refer to:
3 * Title: International Telephone Input
4 * Author: Jack O'Connor
5 * Code version: v12.1.12
6 * Availability: https://github.com/jackocnr/intl-tel-input.git
9 Roo.bootstrap.PhoneInput = function(config) {
10 Roo.bootstrap.PhoneInput.superclass.constructor.call(this, config);
13 Roo.extend(Roo.bootstrap.PhoneInput, Roo.bootstrap.TriggerField, Roo.bootstrap.PhoneInput.AllCountries, {
19 selectedClass: 'active',
21 dialCodeMapping: false,
23 defaultDialCode: '+852',
25 preferedCountries: false,
29 getAutoCreate : function()
31 var align = this.labelAlign || this.parentLabelAlign();
34 for (var i = 0; i < this.Roo.bootstrap.PhoneInput.AllCountries.length; i++) {
35 var c = this.Roo.bootstrap.PhoneInput.AllCountries[i];
36 this.allCountries[i] = {
41 areaCodes: c[4] || null
43 this.dialCodeMapping[c[2]] = {
47 areaCodes: c[4] || null
60 cls : 'form-control tel-input',
61 autocomplete: 'new-password'
65 input.name = this.name;
69 input.disabled = true;
72 var flag_container = {
89 cls: this.hasFeedback ? 'has-feedback' : '',
94 cls: 'dial-code-holder',
101 cls: 'roo-select2-container input-group',
108 if (this.fieldLabel.length) {
111 tooltip: 'This field is required'
117 cls: 'control-label',
123 html: this.fieldLabel
126 indicator.cls = 'roo-required-indicator text-danger fa fa-lg fa-star left-indicator';
132 if(this.indicatorpos == 'right') {
133 indicator.cls = 'roo-required-indicator text-danger fa fa-lg fa-star right-indicator';
140 if(align == 'left') {
148 if(this.labelWidth > 12){
149 label.style = "width: " + this.labelWidth + 'px';
151 if(this.labelWidth < 13 && this.labelmd == 0){
152 this.labelmd = this.labelWidth;
154 if(this.labellg > 0){
155 label.cls += ' col-lg-' + this.labellg;
156 input.cls += ' col-lg-' + (12 - this.labellg);
158 if(this.labelmd > 0){
159 label.cls += ' col-md-' + this.labelmd;
160 container.cls += ' col-md-' + (12 - this.labelmd);
162 if(this.labelsm > 0){
163 label.cls += ' col-sm-' + this.labelsm;
164 container.cls += ' col-sm-' + (12 - this.labelsm);
166 if(this.labelxs > 0){
167 label.cls += ' col-xs-' + this.labelxs;
168 container.cls += ' col-xs-' + (12 - this.labelxs);
180 ['xs','sm','md','lg'].map(function(size){
181 if (settings[size]) {
182 cfg.cls += ' col-' + size + '-' + settings[size];
186 this.store = new Roo.data.Store({
187 proxy : new Roo.data.MemoryProxy({}),
188 reader : new Roo.data.JsonReader({
207 'name' : 'areaCodes',
214 this.store.proxy.data = {
216 data: this.allCountries
222 initEvents : function()
225 Roo.bootstrap.PhoneInput.superclass.initEvents.call(this);
227 this.indicator = this.indicatorEl();
228 this.flag = this.flagEl();
229 this.dialCodeHolder = this.dialCodeHolderEl();
231 this.trigger = this.el.select('div.flag-box',true).first();
232 this.trigger.on("click", this.onTriggerClick, this, {preventDefault:true});
237 var lw = _this.listWidth || Math.max(_this.inputEl().getWidth(), _this.minListWidth);
238 _this.list.setWidth(lw);
241 this.list.on('mouseover', this.onViewOver, this);
242 this.list.on('mousemove', this.onViewMove, this);
243 //this.list.on('scroll', this.onViewScroll, this);
245 this.tpl = '<li><a href="#"><div class="flag {iso2}"></div>{name} <span class="dial-code">+{dialCode}</span></a></li>';
247 this.view = new Roo.View(this.list, this.tpl, {
248 singleSelect:true, store: this.store, selectedClass: this.selectedClass
251 this.view.on('click', this.onViewClick, this);
252 this.setValue(this.defaultDialCode);
255 onTriggerClick : function(e)
257 Roo.log('trigger click');
258 if(this.disabled || !this.triggerList){
262 if(this.isExpanded()){
264 this.hasFocus = false;
267 this.hasFocus = true;
272 isExpanded : function()
274 return this.list.isVisible();
277 collapse : function()
279 if(!this.isExpanded()){
283 Roo.get(document).un('mousedown', this.collapseIf, this);
284 Roo.get(document).un('mousewheel', this.collapseIf, this);
285 this.fireEvent('collapse', this);
293 if(this.isExpanded() || !this.hasFocus){
297 var lw = this.listWidth || Math.max(this.inputEl().getWidth(), this.minListWidth);
298 this.list.setWidth(lw);
301 this.restrictHeight();
303 Roo.get(document).on('mousedown', this.collapseIf, this);
304 Roo.get(document).on('mousewheel', this.collapseIf, this);
306 this.fireEvent('expand', this);
309 restrictHeight : function()
311 this.list.alignTo(this.inputEl(), this.listAlign);
312 this.list.alignTo(this.inputEl(), this.listAlign);
315 onViewOver : function(e, t)
320 var item = this.view.findItemFromChild(t);
323 var index = this.view.indexOf(item);
324 this.select(index, false);
329 onViewClick : function(view, doFocus, el, e)
331 var index = this.view.getSelectedIndexes()[0];
333 var r = this.store.getAt(index);
336 this.onSelect(r, index);
338 if(doFocus !== false && !this.blockFocus){
339 this.inputEl().focus();
343 onViewMove : function(e, t)
345 this.inKeyMode = false;
348 select : function(index, scrollIntoView)
350 this.selectedIndex = index;
351 this.view.select(index);
352 if(scrollIntoView !== false){
353 var el = this.view.getNode(index);
355 this.list.scrollChildIntoView(el, false);
360 createList : function()
362 this.list = Roo.get(document.body).createChild({
364 cls: 'typeahead typeahead-long dropdown-menu tel-list',
365 style: 'display:none'
367 this.list.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';;
370 collapseIf : function(e)
372 var in_combo = e.within(this.el);
373 var in_list = e.within(this.list);
374 var is_list = (Roo.get(e.getTarget()).id == this.list.id) ? true : false;
376 if (in_combo || in_list || is_list) {
382 onSelect : function(record, index)
384 if(this.fireEvent('beforeselect', this, record, index) !== false){
386 this.setFlagClass(record.data.iso2);
387 this.setDialCode(record.data.dialCode);
388 this.hasFocus = false;
390 this.fireEvent('select', this, record, index);
396 var flag = this.el.select('div.flag',true).first();
403 dialCodeHolderEl : function()
405 var d = this.el.select('input.dial-code-holder',true).first();
412 setDialCode : function(v)
414 this.dialCodeHolder.dom.value = '+'+v;
417 setFlagClass : function(n)
419 this.flag.dom.className = 'flag '+n;
422 getValue : function()
424 var v = this.inputEl().getValue();
425 if(this.dialCodeHolder) {
426 v = this.dialCodeHolder.dom.value+this.inputEl().getValue();
431 setValue : function(v)
433 var d = this.getDialCode(v);
436 if(!d || d.length == 0) {
438 this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
443 this.setFlagClass(this.dialCodeMapping[d].iso2);
445 this.inputEl().dom.value = v.replace('+'+d,'');
448 getDialCode : function(v = '')
451 return this.dialCodeHolder.dom.value;
455 // only interested in international numbers (starting with a plus)
456 if (v.charAt(0) != "+") {
459 var numericChars = "";
460 for (var i = 1; i < v.length; i++) {
464 if (this.dialCodeMapping[numericChars]) {
465 dialCode = v.substr(1, i);
467 if (numericChars.length == 4) {
475 validate : function()