Skip to content
This repository was archived by the owner on Oct 8, 2021. It is now read-only.

added 'refresh' method to textinput #6048

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
273 changes: 181 additions & 92 deletions js/widgets/forms/textinput.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//>>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 ) {
define( [ "jquery", "../../jquery.mobile.core", "../../jquery.mobile.widget", "../../jquery.mobile.degradeInputs", "../../jquery.mobile.buttonMarkup", "../../jquery.mobile.zoom", "../../jquery.mobile.registry" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {

Expand All @@ -15,79 +15,58 @@ $.widget( "mobile.textinput", $.mobile.widget, {
mini: false,
// 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='search'], :jqmData(type='search'), 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]), input[type='file']",
clearBtn: false,
clearSearchButtonText: null, //deprecating for 1.3...
clearBtnText: "clear text",
disabled: false
},

_create: function() {
this._refresh(true);
},

_refresh: function (create) {
var self = this,
input = this.element,
o = this.options,
theme = o.theme || $.mobile.getInheritedTheme( this.element, "c" ),
themeclass = " ui-body-" + theme,
miniclass = o.mini ? " ui-mini" : "",
isSearch = input.is( "[type='search'], :jqmData(type='search')" ),
focusedEl,
clearbtn,
clearBtnText = o.clearSearchButtonText || o.clearBtnText,
clearBtnBlacklist = input.is( "textarea, :jqmData(type='range')" ),
inputNeedsClearBtn = !!o.clearBtn && !clearBtnBlacklist,
inputNeedsWrap = input.is( "input" ) && !input.is( ":jqmData(type='range')" );
clearBtnText,
focusedEl,
miniclass,
inputNeedsClearBtn,
theme,
themeclass,
isSearch = input.is("[type='search'], :jqmData(type='search')"),
clearBtnBlacklist = input.is("textarea, :jqmData(type='range')"),
inputNeedsWrap = input.is( "input" ) && !input.is( ":jqmData(type='range')" ),
extraLineHeight = 15,
keyupTimeoutBuffer = 100,
keyupTimeout;

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 );

// 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" );
}

//"search" and "text" input widgets
if ( isSearch ) {
focusedEl = input.wrap( "<div class='ui-input-search ui-shadow-inset ui-btn-corner-all ui-btn-shadow ui-icon-searchfield" + themeclass + miniclass + "'></div>" ).parent();
} else if ( inputNeedsWrap ) {
focusedEl = input.wrap( "<div class='ui-input-text ui-shadow-inset ui-corner-all ui-btn-shadow" + themeclass + miniclass + "'></div>" ).parent();
}

if( inputNeedsClearBtn || isSearch ) {
clearbtn = $( "<a href='#' class='ui-input-clear' title='" + clearBtnText + "'>" + clearBtnText + "</a>" )
.bind( "click", function( event ) {
function buildClearBtn() {
clearbtn = $( "<a href='#' class='ui-input-clear' title='" + clearBtnText + "'>" + clearBtnText + "</a>")
.bind( "click" , function( event ) {
input
.val( "" )
.focus()
.trigger( "change" );
.val("")
.focus()
.trigger( "change" );
clearbtn.addClass( "ui-input-clear-hidden" );
event.preventDefault();
})
.appendTo( focusedEl )
.appendTo(focusedEl)
.buttonMarkup({
icon: "delete",
iconpos: "notext",
corners: true,
shadow: true,
mini: o.mini
icon: "delete",
iconpos: "notext",
corners: true,
shadow: true,
mini: o.mini
});

if ( !isSearch ) {
focusedEl.addClass( "ui-input-has-clear" );
}
Expand All @@ -96,66 +75,176 @@ $.widget( "mobile.textinput", $.mobile.widget, {

input.bind( "paste cut keyup input focus change blur", toggleClear );
}
else if ( !inputNeedsWrap && !isSearch ) {
input.addClass( "ui-corner-all ui-shadow-inset" + themeclass + miniclass );
}

input.focus(function() {
if ( !create ) {
var oldTheme, dataMini, refreshMini = false;

focusedEl = input;
oldTheme = o.theme || $.mobile.getInheritedTheme( input , "c");
theme = input.attr( "data-" + $.mobile.ns + "theme" ) || ( o.theme || $.mobile.getInheritedTheme( input , "c" ) );
o.clearBtn = input.attr( "data-" + $.mobile.ns + "clear-btn" ) === 'true';
inputNeedsClearBtn = !!o.clearBtn && !clearBtnBlacklist;

if ( isSearch || inputNeedsWrap) {
focusedEl = input.parent();
focusedEl.removeClass( "ui-body-" + oldTheme ).addClass( "ui-body-" + theme );
}

input.removeClass( "ui-body-" + oldTheme ).addClass( "ui-body-" + theme );

o.theme = theme;

//is data-mini changed?
dataMini = input.attr( "data-" + $.mobile.ns + "mini" ) === 'true';

if ( o.mini !== dataMini ) {
o.mini = dataMini;
refreshMini = true;
miniclass = o.mini ? "ui-mini" : "";
focusedEl.removeClass( "ui-mini" ).addClass( miniclass );
}

//if textinput or search
if ( inputNeedsClearBtn || isSearch ) {
clearBtnText = input.attr( "data-" + $.mobile.ns + "clear-btn-text" );

//accept even an empty string
if ( typeof clearBtnText === "undefined") {
clearBtnText = o.clearBtnText;
}

clearbtn = focusedEl.find( ".ui-input-clear" );

if ( !clearbtn.length ) {
buildClearBtn();
} else {
clearbtn[0].title = clearBtnText;
clearbtn.find( ".ui-btn-text" ).text( clearBtnText );
}

clearbtn.removeClass( "ui-btn-up-" + oldTheme ).addClass( "ui-btn-up-" + theme );

if ( refreshMini ) {
if ( miniclass ) {
clearbtn.removeClass( "ui-fullsize" ).addClass( miniclass );
} else {
clearbtn.removeClass( "ui-mini" ).addClass( "ui-fullsize" );
}
}

clearbtn.attr( "data-theme", theme );
clearbtn.toggleClass( "ui-input-clear-hidden" , !input.val() );

} else {
if (focusedEl.length) {
focusedEl.find(".ui-input-clear").remove();
}
}

if ( input.attr("disabled") ) {
this.disable();
} else {
this.enable();
}
} else {
theme = o.theme || $.mobile.getInheritedTheme(this.element, "c");
themeclass = " ui-body-" + theme;
miniclass = o.mini ? " ui-mini" : "";
inputNeedsClearBtn = !!o.clearBtn && !clearBtnBlacklist;
clearBtnText = o.clearBtnText;

$( "label[for='" + input.attr("id") + "']" ).addClass( "ui-input-text" );

focusedEl = input.addClass( "ui-input-text ui-body-" + theme );

// 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" );
}

//"search" and "text" input widgets
if ( isSearch ) {
focusedEl = input.wrap( "<div class='ui-input-search ui-shadow-inset ui-btn-corner-all ui-btn-shadow ui-icon-searchfield" + themeclass + miniclass + "'></div>" ).parent();
} else if (inputNeedsWrap) {
focusedEl = input.wrap( "<div class='ui-input-text ui-shadow-inset ui-corner-all ui-btn-shadow" + themeclass + miniclass + "'></div>" ).parent();
}

if (inputNeedsClearBtn || isSearch) {
buildClearBtn();
} else if (!inputNeedsWrap && !isSearch) {
input.addClass("ui-corner-all ui-shadow-inset" + themeclass + miniclass);
}

input.focus(function() {
// In many situations, iOS will zoom into the input upon tap, this prevents that from happening
if ( o.preventFocusZoom ) {
$.mobile.zoom.disable( true );
}
}
focusedEl.addClass( $.mobile.focusClass );
})
.blur(function() {
}).blur(function() {
focusedEl.removeClass( $.mobile.focusClass );
if ( o.preventFocusZoom ) {
$.mobile.zoom.enable( true );
}
})
}
} );

// Autogrow
if ( input.is( "textarea" ) ) {

this._keyup = function() {
var scrollHeight = input[0].scrollHeight,
clientHeight = input[0].clientHeight;

// Autogrow
if ( input.is( "textarea" ) ) {
var extraLineHeight = 15,
keyupTimeoutBuffer = 100,
keyupTimeout;
if ( clientHeight < scrollHeight ) {
var paddingTop = parseFloat( input.css("padding-top") ),
paddingBottom = parseFloat( input.css("padding-bottom") ),
paddingHeight = paddingTop + paddingBottom;

input.height( scrollHeight - paddingHeight + extraLineHeight );
}
};

input.on( "keyup change input paste" , function() {
clearTimeout( keyupTimeout );
keyupTimeout = setTimeout( self._keyup , keyupTimeoutBuffer );
});

this._keyup = function() {
var scrollHeight = input[ 0 ].scrollHeight,
clientHeight = input[ 0 ].clientHeight;
// binding to pagechange here ensures that for pages loaded via
// ajax the height is recalculated without user input
this._on( true , $.mobile.document , { "pagechange": "_keyup" });

if ( clientHeight < scrollHeight ) {
input.height( scrollHeight + extraLineHeight );
// 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( true , $.mobile.window , { "load": "_keyup" } );
}
};

input.on( "keyup change input paste", 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();
}
}
if ( input.attr( "disabled" ) ) {
this.disable();
}
},

refresh: function() {
this._refresh( false );
},

disable: function() {
var $el,
isSearch = this.element.is( "[type='search'], :jqmData(type='search')" ),
inputNeedsWrap = this.element.is( "input" ) && !this.element.is( ":jqmData(type='range')" ),
parentNeedsDisabled = this.element.attr( "disabled", true ) && ( inputNeedsWrap || isSearch );

if ( parentNeedsDisabled ) {
$el = this.element.parent();
} else {
Expand All @@ -181,10 +270,10 @@ $.widget( "mobile.textinput", $.mobile.widget, {
}
});

$.mobile.textinput.initSelector = "input[type='text'], input[type='search'], :jqmData(type='search'), 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]), input[type='file']";

//auto self-init widgets
$.mobile.document.bind( "pagecreate create", function( e ) {
$.mobile.textinput.prototype.enhanceWithin( e.target, true );
});
$.mobile._enhancer.add( "mobile.textinput" );

})( jQuery );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
Expand Down