1: <?php
2: /**
3: * CMaskedTextField class file.
4: *
5: * @author Qiang Xue <qiang.xue@gmail.com>
6: * @link http://www.yiiframework.com/
7: * @copyright 2008-2013 Yii Software LLC
8: * @license http://www.yiiframework.com/license/
9: */
10:
11: /**
12: * CMaskedTextField generates a masked text field.
13: *
14: * CMaskedTextField is similar to {@link CHtml::textField} except that
15: * an input mask will be used to help users enter properly formatted data.
16: * The masked text field is implemented based on the jQuery masked input plugin
17: * (see {@link http://digitalbush.com/projects/masked-input-plugin}).
18: *
19: * @author Qiang Xue <qiang.xue@gmail.com>
20: * @package system.web.widgets
21: * @since 1.0
22: */
23: class CMaskedTextField extends CInputWidget
24: {
25: /**
26: * @var string the input mask (e.g. '99/99/9999' for date input). The following characters are predefined:
27: * <ul>
28: * <li>a: represents an alpha character (A-Z,a-z).</li>
29: * <li>9: represents a numeric character (0-9).</li>
30: * <li>*: represents an alphanumeric character (A-Z,a-z,0-9).</li>
31: * <li>?: anything listed after '?' within the mask is considered optional user input.</li>
32: * </ul>
33: * Additional characters can be defined by specifying the {@link charMap} property.
34: */
35: public $mask;
36: /**
37: * @var array the mapping between mask characters and the corresponding patterns.
38: * For example, array('~'=>'[+-]') specifies that the '~' character expects '+' or '-' input.
39: * Defaults to null, meaning using the map as described in {@link mask}.
40: */
41: public $charMap;
42: /**
43: * @var string the character prompting for user input. Defaults to underscore '_'.
44: */
45: public $placeholder;
46: /**
47: * @var string a JavaScript function callback that will be invoked when user finishes the input.
48: */
49: public $completed;
50:
51: /**
52: * Executes the widget.
53: * This method registers all needed client scripts and renders
54: * the text field.
55: */
56: public function run()
57: {
58: if($this->mask=='')
59: throw new CException(Yii::t('yii','Property CMaskedTextField.mask cannot be empty.'));
60:
61: list($name,$id)=$this->resolveNameID();
62: if(isset($this->htmlOptions['id']))
63: $id=$this->htmlOptions['id'];
64: else
65: $this->htmlOptions['id']=$id;
66: if(isset($this->htmlOptions['name']))
67: $name=$this->htmlOptions['name'];
68:
69: $this->registerClientScript();
70:
71: if($this->hasModel())
72: echo CHtml::activeTextField($this->model,$this->attribute,$this->htmlOptions);
73: else
74: echo CHtml::textField($name,$this->value,$this->htmlOptions);
75: }
76:
77: /**
78: * Registers the needed CSS and JavaScript.
79: */
80: public function registerClientScript()
81: {
82: $id=$this->htmlOptions['id'];
83: $miOptions=$this->getClientOptions();
84: $options=$miOptions!==array() ? ','.CJavaScript::encode($miOptions) : '';
85: $js='';
86: if(is_array($this->charMap))
87: $js.='jQuery.mask.definitions='.CJavaScript::encode($this->charMap).";\n";
88: $js.="jQuery(\"#{$id}\").mask(\"{$this->mask}\"{$options});";
89:
90: $cs=Yii::app()->getClientScript();
91: $cs->registerCoreScript('maskedinput');
92: $cs->registerScript('Yii.CMaskedTextField#'.$id,$js);
93: }
94:
95: /**
96: * @return array the options for the text field
97: */
98: protected function getClientOptions()
99: {
100: $options=array();
101: if($this->placeholder!==null)
102: $options['placeholder']=$this->placeholder;
103:
104: if($this->completed!==null)
105: {
106: if($this->completed instanceof CJavaScriptExpression)
107: $options['completed']=$this->completed;
108: else
109: $options['completed']=new CJavaScriptExpression($this->completed);
110: }
111:
112: return $options;
113: }
114: }