blob: db404b8ecef43612b07a1e5bb48abf8f5c0dda73 [file] [log] [blame]
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Enhances and consistently styles text inputs.
//>>label: Text Inputs & Textareas
//>>group: Forms
//>>css.structure: ../css/structure/jquery.mobile.forms.textinput.css
//>>css.theme: ../css/themes/default/jquery.mobile.theme.css
define( [ "jquery", "../../jquery.mobile.core", "../../jquery.mobile.widget", "../../jquery.mobile.degradeInputs", "../../jquery.mobile.buttonMarkup", "../../jquery.mobile.zoom" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {
$.widget( "mobile.textinput", $.mobile.widget, {
options: {
theme: null,
// This option defaults to true on iOS devices.
preventFocusZoom: /iPhone|iPad|iPod/.test( navigator.platform ) && navigator.userAgent.indexOf( "AppleWebKit" ) > -1,
initSelector: "input[type='text'], input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea, input[type='time'], input[type='date'], input[type='month'], input[type='week'], input[type='datetime'], input[type='datetime-local'], input[type='color'], input:not([type])",
disabled: false
},
_create: function() {
var self = this,
input = this.element,
o = this.options,
theme = o.theme || $.mobile.getInheritedTheme( this.element, "c" ),
themeclass = " ui-body-" + theme,
mini = $.mobile.getAttrFixed( input[0], "data-" + $.mobile.ns + "mini" ) === true,
miniclass = mini ? " ui-mini" : "",
focusedEl, clearbtn;
function toggleClear() {
setTimeout( function() {
clearbtn.toggleClass( "ui-input-clear-hidden", !input.val() );
}, 0 );
}
$( "label[for='" + input.attr( "id" ) + "']" ).addClass( "ui-input-text" );
focusedEl = input.addClass("ui-input-text ui-body-"+ theme );
switch ( input.attr( "type" ) ) {
case "text":
case "password":
case "number":
case "email":
case "url":
case "tel":
input.attr( { "role" : "textbox", "aria-label" : "Keyboard opened" } );
break;
default:
if ( input.prop( "tagName" ).toLowerCase() === "textarea" ) {
input.attr( { "role" : "textbox", "aria-label" : "Keyboard opened" } );
}
}
// XXX: Temporary workaround for issue 785 (Apple bug 8910589).
// Turn off autocorrect and autocomplete on non-iOS 5 devices
// since the popup they use can't be dismissed by the user. Note
// that we test for the presence of the feature by looking for
// the autocorrect property on the input element. We currently
// have no test for iOS 5 or newer so we're temporarily using
// the touchOverflow support flag for jQM 1.0. Yes, I feel dirty. - jblas
if ( typeof input[0].autocorrect !== "undefined" && !$.support.touchOverflow ) {
// Set the attribute instead of the property just in case there
// is code that attempts to make modifications via HTML.
input[0].setAttribute( "autocorrect", "off" );
input[0].setAttribute( "autocomplete", "off" );
}
input.focus(function() {
focusedEl.addClass( $.mobile.focusClass );
})
.blur(function() {
focusedEl.removeClass( $.mobile.focusClass );
})
// In many situations, iOS will zoom into the select upon tap, this prevents that from happening
.bind( "focus", function() {
if ( o.preventFocusZoom ) {
$.mobile.zoom.disable( true );
}
})
.bind( "blur", function() {
if ( o.preventFocusZoom ) {
$.mobile.zoom.enable( true );
}
});
// Autogrow
if ( input.is( "textarea" ) ) {
var extraLineHeight = 15,
keyupTimeoutBuffer = 100,
keyupTimeout;
this._keyup = function() {
var scrollHeight = input[ 0 ].scrollHeight,
clientHeight = input[ 0 ].clientHeight;
if ( clientHeight < scrollHeight && window.innerHeight / 2 > scrollHeight ) {
input.height(scrollHeight + extraLineHeight);
}
};
input.keyup(function() {
clearTimeout( keyupTimeout );
keyupTimeout = setTimeout( self._keyup, keyupTimeoutBuffer );
});
// binding to pagechange here ensures that for pages loaded via
// ajax the height is recalculated without user input
this._on( $.mobile.$document, {"pagechange": "_keyup" });
// Issue 509: the browser is not providing scrollHeight properly until the styles load
if ( $.trim( input.val() ) ) {
// bind to the window load to make sure the height is calculated based on BOTH
// the DOM and CSS
this._on( $.mobile.$window, {"load": "_keyup"});
}
}
if ( input.attr( "disabled" ) ) {
this.disable();
}
},
disable: function() {
var $el;
if ( this.element.attr( "disabled", true ) ) {
$el = this.element;
} else {
return;
}
$el.addClass( "ui-disabled" );
return this._setOption( "disabled", true );
},
enable: function() {
var $el;
// TODO using more than one line of code is acceptable ;)
if ( this.element.attr( "disabled", false ) ) {
$el = this.element;
} else {
return;
}
$el.removeClass( "ui-disabled" );
return this._setOption( "disabled", false );
}
});
//auto self-init widgets
$.mobile.$document.bind( "pagecreate create", function( e ) {
$.mobile.textinput.prototype.enhanceWithin( e.target, true );
});
})( jQuery );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");