diff --git a/components/ionKeyboard/ionFocus.js b/components/ionKeyboard/ionFocus.js new file mode 100644 index 0000000..f4bad11 --- /dev/null +++ b/components/ionKeyboard/ionFocus.js @@ -0,0 +1,46 @@ +Meteor.startup(function() { + if (Meteor.isCordova) { + + // Scroll to make input on top of the page + // #TODO Correct behavior should be: if the input is behind the keyboard, scroll to make it visible on top of the keyboard + var scrollToFocusedElement = function($focused) { + $focused = $focused || $(':focus'); + var $container = $($focused.parents('.content.overflow-scroll').get(0)); + if (!$focused.length || !$container.length) return; + var contentOffset = $container.offset().top; + var padding = 10; + var scrollTo = $container.scrollTop() + $focused.offset().top - contentOffset - padding; + setTimeout(function() { + $container.animate({ scrollTop: scrollTo }, 400, function() { + // #TODO fix floating input cursor bug (https://github.com/twbs/bootstrap/issues/14708, https://github.com/cubiq/iscroll/issues/178) + var display = $focused.css('display'); + $focused.css({ display: 'none' }).css({ display: display }); + }); + // $container.scrollTop(scrollTo); + }, 0); + } + + var scrollPosStart, scrollPosEnd, scrollDistance, scrollHappened, scrollThreshold = 10; + + // Fix for input not getting focused on long touch (more than a few ms) + $(document).on('touchstart', function(event) { + scrollPosStart = $('.content.overflow-scroll').scrollTop(); + }); + + $(document).on('touchend', function(event) { + scrollPosEnd = $('.content.overflow-scroll').scrollTop(); + scrollDistance = Math.abs(scrollPosStart - scrollPosEnd); + scrollHappened = scrollDistance > scrollThreshold; + var $target = $(event.target); + var isInput = _.contains(['INPUT', 'TEXTAREA'], event.target.tagName); + var isFocused = $target.is(':focus'); + if (!isInput || isFocused || scrollHappened) return; + $target.focus(); + }); + + $(document).delegate('input, textarea', 'focus', function(event) { + scrollToFocusedElement($(event.currentTarget)); + }); + + } +}); diff --git a/components/ionKeyboard/ionKeyboard.js b/components/ionKeyboard/ionKeyboard.js index 9de86ea..23ae409 100644 --- a/components/ionKeyboard/ionKeyboard.js +++ b/components/ionKeyboard/ionKeyboard.js @@ -66,26 +66,8 @@ window.addEventListener('native.keyboardshow', function (event) { }); -Meteor.startup(function() { - if (Meteor.isCordova) { - - // Scroll to make input on top of the page - // #TODO Correct behavior should be: if the input is behind the keyboard, scroll to make it visible on top of the keyboard - $(document).delegate('input, textarea', 'touchstart, focus', function(event) { - var $input = $(event.currentTarget); - var $container = $($(event.currentTarget).parents('.content.overflow-scroll').get(0)); - var contentOffset = $container.offset().top; - var padding = 10; - var scrollTo = $container.scrollTop() + $input.offset().top - contentOffset - padding; - setTimeout(function() { - $container.scrollTop(scrollTo); - }, 0); - }); - - } -}); - window.addEventListener('native.keyboardhide', function (event) { + // TODO: Android is having problems if (Platform.isAndroid()) { return; @@ -103,4 +85,5 @@ window.addEventListener('native.keyboardhide', function (event) { $('.content.overflow-scroll').each(function (index, el) { $(el).css({bottom: $(el).data('ionkeyboard.bottom')}); }); + }); diff --git a/package.js b/package.js index 4e54899..2efaab8 100644 --- a/package.js +++ b/package.js @@ -11,7 +11,14 @@ Cordova.depends({ Package.onUse(function(api) { api.versionsFrom("1.0"); - api.use(["templating", "underscore", "fastclick", "iron:router@1.0.0", "tracker", "session"], "client"); + api.use([ + "templating", + "underscore", + "fastclick", + "iron:router@1.0.0", + "tracker", + "session" + ], "client"); api.addFiles([ "vendor/snap.js", @@ -46,6 +53,7 @@ Package.onUse(function(api) { "components/ionItem/ionItem.js", "components/ionKeyboard/ionKeyboard.js", + "components/ionKeyboard/ionFocus.js", "components/ionList/ionList.html", "components/ionList/ionList.js",