Yii 1.1: intl-phone-input

International phones input extension
3 followers

What is it?

A jQuery plugin for entering and validating international telephone numbers. It adds a flag dropdown to any input, which lists all the countries and their international dial codes next to their flags.

Features

  1. Automatically format the number as the user types
  2. Automatically set the input placeholder to an example number for the selected country
  3. Navigate the country dropdown by typing a country's name, or using up/down keys
  4. Selecting a country from the dropdown will update the dial code in the input
  5. Typing a different dial code automatically updates the displayed flag
  6. Dropdown appears above or below the input depending on available space/scroll position
  7. Lots of initialisation options for customisation, as well as public methods for interaction

Requirements

Yii 1.1 or above.

Download

from GitHub

Install

  1. Extract the contents of the package in /protected/extensions and rename the directory intl-tel-input-master to intlphoneinput.

  2. Create the file IntlPhoneInput.php in /protected/extensions/intlphoneinput.

File IntlPhoneInput.php:

<?php
 
/**
 * IntlPhoneInput class file.
 *
 * @author Odirlei Santos
 * @version 0.1
 */
class IntlPhoneInput extends CInputWidget
{
        /**
         * Use this property to set jQuery settings
         * See {@link https://github.com/Bluefieldscom/intl-tel-input/#options}
         * @var Array
         */
        public $options;
        /**
         * Use this property to update the data to only show localised country names.
         * @var Boolean
         */
        public $localisedCountryNames=true;
        /**
         * Use this property to get the current number formatted to the [E.164 standard]
         * See {@link http://en.wikipedia.org/wiki/E.164}
         * @var Boolean
         */
        public $E164=true;
        /**
         * Enable formatting/validation etc. by specifying the path to the included "utils.js" script
         * @var String
         */
        private $utilsScript;
 
        /**
         * Executes the widget.
         * This method registers all needed client scripts and renders
         * the text field.
         */
        public function run()
        {
                list($name, $id)=$this->resolveNameID();
                if(!isset($this->htmlOptions['id']))
                        $this->htmlOptions['id']=$id;
                if(!isset($this->htmlOptions['name']))
                        $this->htmlOptions['name']=$name;
 
                $this->registerClientScript();
 
                if($this->hasModel()) {
                        $value=$this->model->{$this->attribute};
                        echo CHtml::activeHiddenField($this->model, $this->attribute);
                }
                else {
                        $value=$this->value;
                        echo CHtml::hiddenField($this->htmlOptions['name'], $this->value);
                }
                $htmlOptions=$this->htmlOptions;
                unset($htmlOptions['id'], $htmlOptions['name']);
                echo CHtml::textField('intl-phone-input', $value, $htmlOptions);
        }
 
        /**
         * Registers the needed CSS and JavaScript.
         */
        private function registerClientScript()
        {
                $assets=Yii::app()->getAssetManager()->publish(dirname(__FILE__) . '/build');
                $lib=Yii::app()->getAssetManager()->publish(dirname(__FILE__) . '/lib');
                $this->utilsScript=$lib . '/libphonenumber/build/utils.js';
 
                // Configures JavaScript
                $config=$this->config();
                $options=CJavaScript::encode($config);
                $js="jQuery('#intl-phone-input').intlTelInput({$options});";
 
                $clone='val()';
                if($this->E164 === true)
                        $clone='intlTelInput(\'getNumber\')';
                $js.="jQuery('#intl-phone-input').change(function() {
                        jQuery('#{$this->htmlOptions['id']}').val(jQuery(this).{$clone});
                });";
 
                if($this->localisedCountryNames === true) {
                        $js.="var countryData = $.fn.intlTelInput.getCountryData();
                        $.each(countryData, function(i, country) {
                                country.name = country.name.replace(/.+\((.+)\)/,'$1');
                        });";
                }
 
                // Add other JavaScript methods to $js.
                // See https://github.com/Bluefieldscom/intl-tel-input#public-methods
                // See https://github.com/Bluefieldscom/intl-tel-input#static-methods
 
                $cs=Yii::app()->getClientScript();
                $cs->registerCssFile($assets . '/css/intlTelInput.css');
                $cs->registerScriptFile($assets . '/js/intlTelInput.min.js');
                $cs->registerScript(__CLASS__ . '#' . $this->htmlOptions['id'], $js);
        }
 
        /**
         * jQuery settings
         * See {@link https://github.com/Bluefieldscom/intl-tel-input/#options}
         * @return Array the options for the Widget
         */
        private function config()
        {
                // Predefined settings.
                $options=array(
                        'defaultCountry' => 'auto',
                        'numberType' => 'MOBILE',
                        'preferredCountries' => array('br'),
                        'responsiveDropdown' => true,
                );
                // Client options
                if(is_array($this->options)) {
                        foreach($this->options as $key => $value)
                                $options[$key]=$value;
                }
                // Specifies/overwrites the path to the included "utils.js" script
                $options['utilsScript']=$this->utilsScript;
                return $options;
        }
 
}

Usage

In your view file:

<div class="row">
    <?php echo $form->labelEx($model,'myAttribute'); ?>
    <?php $this->widget('ext.intlphoneinput.IntlPhoneInput', array(
            'model'=>$model,
            'attribute'=>'myAttribute',
            'options'=>array( // optional
                // Additional settings.
            ),
            //'localisedCountryNames'=>false, // other public properties
    )); ?>
    <?php echo $form->error($model,'myAttribute'); ?>
</div>

or:

<div class="row">
    <?php echo CHtml::label('labelName',false); ?>
    <?php $this->widget('ext.intlphoneinput.IntlPhoneInput', array(
            'name'=>'fieldName',
            'value'=>$fieldValue,
            'options'=>array( // optional
                // Additional settings.
            ),
            //'localisedCountryNames'=>false, // other public properties
    )); ?>
</div>

Resources

Total 2 comments

#19558 report it
Odirlei at 2015/09/07 02:45pm
Additional settings

It is only an outline, use other project settings, as Lookup user's country, see:

private function config()
{
    // Predefined settings.
    $options=array(
        'defaultCountry' => 'auto',
        // do not forget the "js:" before the callback function
        'geoIpLookup' => 'js:function(callback) {
            $.get(\'http://ipinfo.io\', function() {}, \'jsonp\').always(function(resp) {
                var countryCode = (resp && resp.country) ? resp.country : \'\';
                callback(countryCode);
            });
        }',
    );
}
#19552 report it
CodingMachine at 2015/09/04 06:49am
Great Work and great findings

minor changes here and there, works like a charm... Wish i could allow users not to change the country codes once appended to the text field

Leave a comment

Please to leave your comment.

Create extension