| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 | <?php/** * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */namespace yii\widgets;use yii\base\InvalidConfigException;use yii\helpers\Html;use yii\helpers\Json;use yii\web\JsExpression;use yii\web\View;/** * MaskedInput generates a masked text input. * * MaskedInput is similar to [[Html::textInput()]] except that an input mask will be used to force users to enter * properly formatted data, such as phone numbers, social security numbers. * * To use MaskedInput, you must set the [[mask]] property. The following example * shows how to use MaskedInput to collect phone numbers: * * ```php * echo MaskedInput::widget([ *     'name' => 'phone', *     'mask' => '999-999-9999', * ]); * ``` * * You can also use this widget in an [[ActiveForm]] using the [[ActiveField::widget()|widget()]] * method, for example like this: * * ```php * <?= $form->field($model, 'from_date')->widget(\yii\widgets\MaskedInput::className(), [ *     'mask' => '999-999-9999', * ]) ?> * ``` * * The masked text field is implemented based on the * [jQuery input masked plugin](https://github.com/RobinHerbots/Inputmask). * * @author Kartik Visweswaran <kartikv2@gmail.com> * @since 2.0 */class MaskedInput extends InputWidget{    /**     * The name of the jQuery plugin to use for this widget.     */    const PLUGIN_NAME = 'inputmask';    /**     * @var string|array|JsExpression the input mask (e.g. '99/99/9999' for date input). The following characters     * can be used in the mask and are predefined:     *     * - `a`: represents an alpha character (A-Z, a-z)     * - `9`: represents a numeric character (0-9)     * - `*`: represents an alphanumeric character (A-Z, a-z, 0-9)     * - `[` and `]`: anything entered between the square brackets is considered optional user input. This is     *   based on the `optionalmarker` setting in [[clientOptions]].     *     * Additional definitions can be set through the [[definitions]] property.     */    public $mask;    /**     * @var array custom mask definitions to use. Should be configured as `maskSymbol => settings`, where     *     * - `maskSymbol` is a string, containing a character to identify your mask definition and     * - `settings` is an array, consisting of the following entries:     *   - `validator`: string, a JS regular expression or a JS function.     *   - `cardinality`: int, specifies how many characters are represented and validated for the definition.     *   - `prevalidator`: array, validate the characters before the definition cardinality is reached.     *   - `definitionSymbol`: string, allows shifting values from other definitions, with this `definitionSymbol`.     */    public $definitions;    /**     * @var array custom aliases to use. Should be configured as `maskAlias => settings`, where     *     * - `maskAlias` is a string containing a text to identify your mask alias definition (e.g. 'phone') and     * - `settings` is an array containing settings for the mask symbol, exactly similar to parameters as passed in [[clientOptions]].     */    public $aliases;    /**     * @var array the JQuery plugin options for the input mask plugin.     * @see https://github.com/RobinHerbots/Inputmask     */    public $clientOptions = [];    /**     * @var array the HTML attributes for the input tag.     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.     */    public $options = ['class' => 'form-control'];    /**     * @var string the type of the input tag. Currently only 'text' and 'tel' are supported.     * @see https://github.com/RobinHerbots/Inputmask     * @since 2.0.6     */    public $type = 'text';    /**     * @var string the hashed variable to store the pluginOptions     */    protected $_hashVar;    /**     * Initializes the widget.     *     * @throws InvalidConfigException if the "mask" property is not set.     */    public function init()    {        parent::init();        if (empty($this->mask) && empty($this->clientOptions['alias'])) {            throw new InvalidConfigException("Either the 'mask' property or the 'clientOptions[\"alias\"]' property must be set.");        }    }    /**     * {@inheritdoc}     */    public function run()    {        $this->registerClientScript();        echo $this->renderInputHtml($this->type);    }    /**     * Generates a hashed variable to store the plugin `clientOptions`.     *     * Helps in reusing the variable for similar     * options passed for other widgets on the same page. The following special data attribute will also be     * added to the input field to allow accessing the client options via javascript:     *     * - 'data-plugin-inputmask' will store the hashed variable storing the plugin options.     *     * @param View $view the view instance     * @author [Thiago Talma](https://github.com/thiagotalma)     */    protected function hashPluginOptions($view)    {        $encOptions = empty($this->clientOptions) ? '{}' : Json::htmlEncode($this->clientOptions);        $this->_hashVar = self::PLUGIN_NAME . '_' . hash('crc32', $encOptions);        $this->options['data-plugin-' . self::PLUGIN_NAME] = $this->_hashVar;        $view->registerJs("var {$this->_hashVar} = {$encOptions};", View::POS_HEAD);    }    /**     * Initializes client options.     */    protected function initClientOptions()    {        $options = $this->clientOptions;        foreach ($options as $key => $value) {            if (                !$value instanceof JsExpression                && in_array($key, [                    'oncomplete', 'onincomplete', 'oncleared', 'onKeyUp', 'onKeyDown', 'onBeforeMask',                    'onBeforePaste', 'onUnMask', 'isComplete', 'determineActiveMasksetIndex',                ], true)            ) {                $options[$key] = new JsExpression($value);            }        }        $this->clientOptions = $options;    }    /**     * Registers the needed client script and options.     */    public function registerClientScript()    {        $js = '';        $view = $this->getView();        $this->initClientOptions();        if (!empty($this->mask)) {            $this->clientOptions['mask'] = $this->mask;        }        $this->hashPluginOptions($view);        if (is_array($this->definitions) && !empty($this->definitions)) {            $js .= ucfirst(self::PLUGIN_NAME) . '.extendDefinitions(' . Json::htmlEncode($this->definitions) . ');';        }        if (is_array($this->aliases) && !empty($this->aliases)) {            $js .= ucfirst(self::PLUGIN_NAME) . '.extendAliases(' . Json::htmlEncode($this->aliases) . ');';        }        $id = $this->options['id'];        $js .= 'jQuery("#' . $id . '").' . self::PLUGIN_NAME . '(' . $this->_hashVar . ');';        MaskedInputAsset::register($view);        $view->registerJs($js);    }}
 |