]>
git.proxmox.com Git - sencha-touch.git/blob - src/src/field/Input.js
4 Ext
. define ( 'Ext.field.Input' , {
5 extend
: 'Ext.Component' ,
10 * Fires whenever the clear icon is tapped.
11 * @param {Ext.field.Input} this
12 * @param {Ext.EventObject} e The event object
17 * @preventable doMaskTap
18 * Fires whenever a mask is tapped.
19 * @param {Ext.field.Input} this
20 * @param {Ext.EventObject} e The event object.
25 * @preventable doFocus
26 * Fires whenever the input get focus.
27 * @param {Ext.EventObject} e The event object.
33 * Fires whenever the input loses focus.
34 * @param {Ext.EventObject} e The event object.
39 * Fires whenever the input is clicked.
40 * @param {Ext.EventObject} e The event object.
45 * Fires whenever keyup is detected.
46 * @param {Ext.EventObject} e The event object.
51 * Fires whenever paste is detected.
52 * @param {Ext.EventObject} e The event object.
57 * Fires whenever the input has a mousedown occur.
58 * @param {Ext.EventObject} e The event object.
62 * @property {String} tag The el tag.
69 * @cfg {String} cls The `className` to be applied to this input.
72 cls
: Ext
. baseCSSPrefix
+ 'form-field' ,
75 * @cfg {String} focusCls The CSS class to use when the field receives focus.
78 focusCls
: Ext
. baseCSSPrefix
+ 'field-focus' ,
81 maskCls
: Ext
. baseCSSPrefix
+ 'field-mask' ,
84 * @cfg {String/Boolean} useMask
85 * `true` to use a mask on this field, or `auto` to automatically select when you should use it.
92 * @cfg {String} type The type attribute for input fields -- e.g. radio, text, password.
94 * If you want to use a `file` input, please use the {@link Ext.field.File} component instead.
100 * @cfg {Boolean} checked `true` if the checkbox should render initially checked.
111 baseCls
: Ext
. baseCSSPrefix
+ 'field-input' ,
114 * @cfg {String} name The field's HTML name attribute.
115 * __Note:__ This property must be set if this field is to be automatically included with
116 * {@link Ext.form.Panel#method-submit form submit()}.
122 * @cfg {Mixed} value A value to initialize this field with.
128 * @property {Boolean} `true` if the field currently has focus.
134 * @cfg {Number} tabIndex The `tabIndex` for this field.
136 * __Note:__ This only applies to fields that are rendered, not those which are built via `applyTo`.
142 * @cfg {String} placeHolder A string value displayed in the input (if supported) when the control is empty.
148 * @cfg {Number} [minValue=undefined] The minimum value that this Number field can accept (defaults to `undefined`, e.g. no minimum).
154 * @cfg {Number} [maxValue=undefined] The maximum value that this Number field can accept (defaults to `undefined`, e.g. no maximum).
160 * @cfg {Number} [stepValue=undefined] The amount by which the field is incremented or decremented each time the spinner is tapped.
161 * Defaults to `undefined`, which means that the field goes up or down by 1 each time the spinner is tapped.
167 * @cfg {Number} [maxLength=0] The maximum number of permitted input characters.
173 * @cfg {Boolean} [autoComplete=undefined]
174 * `true` to set the field's DOM element `autocomplete` attribute to `"on"`, `false` to set to `"off"`. Defaults to `undefined`, leaving the attribute unset.
180 * @cfg {Boolean} [autoCapitalize=undefined]
181 * `true` to set the field's DOM element `autocapitalize` attribute to `"on"`, `false` to set to `"off"`. Defaults to `undefined`, leaving the attribute unset
184 autoCapitalize
: null ,
187 * `true` to set the field DOM element `autocorrect` attribute to `"on"`, `false` to set to `"off"`. Defaults to `undefined`, leaving the attribute unset.
188 * @cfg {Boolean} autoCorrect
194 * @cfg {Boolean} [readOnly=undefined]
195 * `true` to set the field DOM element `readonly` attribute to `"true"`. Defaults to `undefined`, leaving the attribute unset.
201 * @cfg {Number} [maxRows=undefined]
202 * Sets the field DOM element `maxRows` attribute. Defaults to `undefined`, leaving the attribute unset.
208 * @cfg {String} pattern The value for the HTML5 `pattern` attribute.
209 * You can use this to change which keyboard layout will be used.
211 * Ext.define('Ux.field.Pattern', {
212 * extend : 'Ext.field.Text',
213 * xtype : 'patternfield',
222 * Even though it extends {@link Ext.field.Text}, it will display the number keyboard.
229 * @cfg {Boolean} [disabled=false] `true` to disable the field.
231 * Be aware that conformant with the [HTML specification](http://www.w3.org/TR/html401/interact/forms.html),
232 * disabled Fields will not be {@link Ext.form.Panel#method-submit submitted}.
237 * @cfg {Mixed} startValue
238 * The value that the Field had at the time it was last focused. This is the value that is passed
239 * to the {@link Ext.field.Text#change} event which is fired if the value has been changed when the Field is blurred.
241 * __This will be `undefined` until the Field has been visited.__ Compare {@link #originalValue}.
247 * @cfg {Boolean} fastFocus
249 * Enable Fast Input Focusing on iOS, using this workaround will stop some touchstart events in order to prevent
250 * delayed focus issues.
258 * @cfg {String/Number} originalValue The original value when the input is rendered.
263 getTemplate : function () {
271 classList
: [ this . config
. maskCls
]
274 reference
: 'clearIcon' ,
282 initElement : function () {
291 keydown
: 'onKeyDown' ,
300 // Stock android has a delayed mousedown event that is dispatched
301 // this prevents the mousedown from focus's an input when not intended (click a message box button or picker button that lays over an input)
302 // we then force focus on touchend.
303 if ( Ext
. browser
. is
. AndroidStock
) {
304 me
. input
. dom
. addEventListener ( "mousedown" , function ( e
) {
305 if ( document
. activeElement
!= e
. target
) {
309 me
. input
. dom
. addEventListener ( "touchend" , function () { me
. focus (); });
319 tap
: 'onClearIconTap' ,
320 touchstart
: 'onClearIconPress' ,
321 touchend
: 'onClearIconRelease' ,
326 // Hack for IE10. Seems like keyup event is not fired for 'enter' keyboard button, so we use keypress event instead to handle enter.
327 if ( Ext
. browser
. is
. ie
&& Ext
. browser
. version
. major
>= 10 ){
330 keypress
: 'onKeyPress'
335 updateFastFocus : function ( newValue
) {
336 // This is used to prevent 300ms delayed focus bug on iOS
338 if ( this . getFastFocus () && Ext
. os
. is
. iOS
) {
341 touchstart
: "onTouchStart"
347 touchstart
: "onTouchStart"
353 * Manual Max Length processing is required for the stock "Browser" on Android
355 * @return {Boolean} 'true' if non-chrome browser is detected on Android
357 useManualMaxLength : function () {
358 return Boolean (( Ext
. os
. is
. Android
&& ! Ext
. browser
. is
. Chrome
));
361 applyUseMask : function ( useMask
) {
362 if ( useMask
=== 'auto' ) {
363 useMask
= Ext
. os
. is
. iOS
&& Ext
. os
. version
. lt ( '5' );
366 return Boolean ( useMask
);
370 * Updates the useMask configuration
372 updateUseMask : function ( newUseMask
) {
373 this . mask
[ newUseMask
? 'show' : 'hide' ]();
376 updatePattern : function ( pattern
) {
377 this . updateFieldAttribute ( 'pattern' , pattern
);
381 * Helper method to update a specified attribute on the `fieldEl`, or remove the attribute all together.
384 updateFieldAttribute : function ( attribute
, newValue
) {
385 var input
= this . input
;
387 if (! Ext
. isEmpty ( newValue
, true )) {
388 input
. dom
. setAttribute ( attribute
, newValue
);
390 input
. dom
. removeAttribute ( attribute
);
395 * Updates the {@link #cls} configuration.
397 updateCls : function ( newCls
, oldCls
) {
398 this . input
. addCls ( Ext
. baseCSSPrefix
+ 'input-el' );
399 this . input
. replaceCls ( oldCls
, newCls
);
403 * Updates the type attribute with the {@link #type} configuration.
406 updateType : function ( newType
, oldType
) {
407 var prefix
= Ext
. baseCSSPrefix
+ 'input-' ;
409 this . input
. replaceCls ( prefix
+ oldType
, prefix
+ newType
);
410 this . updateFieldAttribute ( 'type' , newType
);
414 * Updates the name attribute with the {@link #name} configuration.
417 updateName : function ( newName
) {
418 this . updateFieldAttribute ( 'name' , newName
);
422 * Returns the field data value.
423 * @return {Mixed} value The field value.
425 getValue : function () {
426 var input
= this . input
;
429 this . _value
= input
. dom
. value
;
436 applyValue : function ( value
) {
437 return ( Ext
. isEmpty ( value
)) ? '' : value
;
441 * Updates the {@link #value} configuration.
444 updateValue : function ( newValue
) {
445 var input
= this . input
;
448 input
. dom
. value
= newValue
;
452 setValue : function ( newValue
) {
453 var oldValue
= this . _value
;
455 this . updateValue ( this . applyValue ( newValue
));
457 newValue
= this . getValue ();
459 if ( String ( newValue
) != String ( oldValue
) && this . initialized
) {
460 this . onChange ( this , newValue
, oldValue
);
468 applyTabIndex : function ( tabIndex
) {
469 if ( tabIndex
!== null && typeof tabIndex
!= 'number' ) {
470 throw new Error ( "Ext.field.Field: [applyTabIndex] trying to pass a value which is not a number" );
477 * Updates the tabIndex attribute with the {@link #tabIndex} configuration
480 updateTabIndex : function ( newTabIndex
) {
481 this . updateFieldAttribute ( 'tabIndex' , newTabIndex
);
485 testAutoFn : function ( value
) {
486 return [ true , 'on' ]. indexOf ( value
) !== - 1 ;
490 applyMaxLength : function ( maxLength
) {
491 if ( maxLength
!== null && typeof maxLength
!= 'number' ) {
492 throw new Error ( "Ext.field.Text: [applyMaxLength] trying to pass a value which is not a number" );
499 * Updates the `maxlength` attribute with the {@link #maxLength} configuration.
502 updateMaxLength : function ( newMaxLength
) {
503 if (! this . useManualMaxLength ()) {
504 this . updateFieldAttribute ( 'maxlength' , newMaxLength
);
509 * Updates the `placeholder` attribute with the {@link #placeHolder} configuration.
512 updatePlaceHolder : function ( newPlaceHolder
) {
513 this . updateFieldAttribute ( 'placeholder' , newPlaceHolder
);
517 applyAutoComplete : function ( autoComplete
) {
518 return this . testAutoFn ( autoComplete
);
522 * Updates the `autocomplete` attribute with the {@link #autoComplete} configuration.
525 updateAutoComplete : function ( newAutoComplete
) {
526 var value
= newAutoComplete
? 'on' : 'off' ;
527 this . updateFieldAttribute ( 'autocomplete' , value
);
531 applyAutoCapitalize : function ( autoCapitalize
) {
532 return this . testAutoFn ( autoCapitalize
);
536 * Updates the `autocapitalize` attribute with the {@link #autoCapitalize} configuration.
539 updateAutoCapitalize : function ( newAutoCapitalize
) {
540 var value
= newAutoCapitalize
? 'on' : 'off' ;
541 this . updateFieldAttribute ( 'autocapitalize' , value
);
545 applyAutoCorrect : function ( autoCorrect
) {
546 return this . testAutoFn ( autoCorrect
);
550 * Updates the `autocorrect` attribute with the {@link #autoCorrect} configuration.
553 updateAutoCorrect : function ( newAutoCorrect
) {
554 var value
= newAutoCorrect
? 'on' : 'off' ;
555 this . updateFieldAttribute ( 'autocorrect' , value
);
559 * Updates the `min` attribute with the {@link #minValue} configuration.
562 updateMinValue : function ( newMinValue
) {
563 this . updateFieldAttribute ( 'min' , newMinValue
);
567 * Updates the `max` attribute with the {@link #maxValue} configuration.
570 updateMaxValue : function ( newMaxValue
) {
571 this . updateFieldAttribute ( 'max' , newMaxValue
);
575 * Updates the `step` attribute with the {@link #stepValue} configuration
578 updateStepValue : function ( newStepValue
) {
579 this . updateFieldAttribute ( 'step' , newStepValue
);
583 checkedRe
: /^(true|1|on)/i ,
586 * Returns the `checked` value of this field
587 * @return {Mixed} value The field value
589 getChecked : function () {
594 checked
= el
. dom
. checked
;
595 this . _checked
= checked
;
602 applyChecked : function ( checked
) {
603 return !! this . checkedRe
. test ( String ( checked
));
606 setChecked : function ( newChecked
) {
607 this . updateChecked ( this . applyChecked ( newChecked
));
608 this . _checked
= newChecked
;
612 * Updates the `autocorrect` attribute with the {@link #autoCorrect} configuration
615 updateChecked : function ( newChecked
) {
616 this . input
. dom
. checked
= newChecked
;
620 * Updates the `readonly` attribute with the {@link #readOnly} configuration
623 updateReadOnly : function ( readOnly
) {
624 this . updateFieldAttribute ( 'readonly' , readOnly
? true : null );
629 applyMaxRows : function ( maxRows
) {
630 if ( maxRows
!== null && typeof maxRows
!== 'number' ) {
631 throw new Error ( "Ext.field.Input: [applyMaxRows] trying to pass a value which is not a number" );
638 updateMaxRows : function ( newRows
) {
639 this . updateFieldAttribute ( 'rows' , newRows
);
642 doSetDisabled : function ( disabled
) {
643 this . callParent ( arguments
);
645 if ( Ext
. browser
. is
. Safari
&& ! Ext
. os
. is
. BlackBerry
) {
646 this . input
. dom
. tabIndex
= ( disabled
) ? - 1 : 0 ;
649 this . input
. dom
. disabled
= ( Ext
. browser
. is
. Safari
&& ! Ext
. os
. is
. BlackBerry
) ? false : disabled
;
657 * Returns `true` if the value of this Field has been changed from its original value.
658 * Will return `false` if the field is disabled or has not been rendered yet.
661 isDirty : function () {
662 if ( this . getDisabled ()) {
666 return String ( this . getValue ()) !== String ( this . originalValue
);
670 * Resets the current field value to the original value.
673 this . setValue ( this . originalValue
);
677 onInputTap : function ( e
) {
678 this . fireAction ( 'inputtap' , [ this , e
], 'doInputTap' );
682 doInputTap : function ( me
, e
) {
683 if ( me
. getDisabled ()) {
687 // Fast focus switching
688 if ( this . getFastFocus () && Ext
. os
. is
. iOS
) {
694 onMaskTap : function ( e
) {
695 this . fireAction ( 'masktap' , [ this , e
], 'doMaskTap' );
699 doMaskTap : function ( me
, e
) {
700 if ( me
. getDisabled ()) {
708 showMask : function () {
709 if ( this . getUseMask ()) {
710 this . mask
. setStyle ( 'display' , 'block' );
715 hideMask : function () {
716 if ( this . getUseMask ()) {
717 this . mask
. setStyle ( 'display' , 'none' );
722 * Attempts to set the field as the active input focus.
723 * @return {Ext.field.Input} this
729 if ( el
&& el
. dom
. focus
) {
736 * Attempts to forcefully blur input focus for the field.
737 * @return {Ext.field.Input} this
744 if ( el
&& el
. dom
. blur
) {
751 * Attempts to forcefully select all the contents of the input field.
752 * @return {Ext.field.Input} this
759 if ( el
&& el
. dom
. setSelectionRange
) {
760 el
. dom
. setSelectionRange ( 0 , 9999 );
765 onFocus : function ( e
) {
766 this . fireAction ( 'focus' , [ e
], 'doFocus' );
770 doFocus : function ( e
) {
775 if (! me
. getIsFocused ()) {
776 me
. setStartValue ( me
. getValue ());
778 me
. setIsFocused ( true );
781 onTouchStart : function ( e
) {
782 // This will prevent 300ms delayed focus from occurring on iOS
783 if ( document
. activeElement
!= e
. target
) {
788 onBlur : function ( e
) {
789 this . fireAction ( 'blur' , [ e
], 'doBlur' );
793 doBlur : function ( e
) {
795 value
= me
. getValue (),
796 startValue
= me
. getStartValue ();
800 me
. setIsFocused ( false );
802 if ( String ( value
) != String ( startValue
)) {
803 me
. onChange ( me
, value
, startValue
);
809 onClearIconTap : function ( e
) {
810 this . fireEvent ( 'clearicontap' , this , e
);
812 //focus the field after cleartap happens, but only on android.
813 //this is to stop the keyboard from hiding. TOUCH-2064
814 if ( Ext
. os
. is
. Android
) {
819 onClearIconPress : function () {
820 this . clearIcon
. addCls ( Ext
. baseCSSPrefix
+ 'pressing' );
823 onClearIconRelease : function () {
824 this . clearIcon
. removeCls ( Ext
. baseCSSPrefix
+ 'pressing' );
827 onClick : function ( e
) {
828 this . fireEvent ( 'click' , e
);
831 onChange : function ( me
, value
, startValue
) {
832 if ( this . useManualMaxLength ()) {
833 this . trimValueToMaxLength ();
835 this . fireEvent ( 'change' , me
, value
, startValue
);
838 onPaste : function ( e
) {
839 if ( this . useManualMaxLength ()) {
840 this . trimValueToMaxLength ();
842 this . fireEvent ( 'paste' , e
);
845 onKeyUp : function ( e
) {
846 if ( this . useManualMaxLength ()) {
847 this . trimValueToMaxLength ();
849 this . fireEvent ( 'keyup' , e
);
852 onKeyDown : function () {
853 // tell the class to ignore the input event. this happens when we want to listen to the field change
854 // when the input autocompletes
855 this . ignoreInput
= true ;
858 onInput : function ( e
) {
861 // if we should ignore input, stop now.
862 if ( me
. ignoreInput
) {
863 me
. ignoreInput
= false ;
867 // set a timeout for 10ms to check if we want to stop the input event.
868 // if not, then continue with the event (keyup)
869 setTimeout ( function () {
870 if (! me
. ignoreInput
) {
871 me
. fireEvent ( 'keyup' , e
);
872 me
. ignoreInput
= false ;
877 // Hack for IE10 mobile. Handle pressing 'enter' button and fire keyup event in this case.
878 onKeyPress : function ( e
) {
879 if ( e
. browserEvent
. keyCode
== 13 ){
880 this . fireEvent ( 'keyup' , e
);
884 onMouseDown : function ( e
) {
885 this . fireEvent ( 'mousedown' , e
);
888 trimValueToMaxLength : function () {
889 var maxLength
= this . getMaxLength ();
891 var value
= this . getValue ();
892 if ( value
. length
> this . getMaxLength ()) {
893 this . setValue ( value
. slice ( 0 , maxLength
));