You found a bug! We've classified it as TOUCH-1941 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #1
    Sencha Premium Member
    Join Date
    Feb 2012
    Posts
    36
    Vote Rating
    2
    mangvlad is on a distinguished road

      0  

    Default TextArea scroll on iOS not working

    TextArea scroll on iOS not working


    On any iOs device, when text area is used there is not way to scroll it...

    In Sencha Touch 1 this was posted as a fix:

    Code:
    // overrides a class and preserves overridden functions in a new property of the prototype, 'original'
    Ext.overrideOriginal = function(obj, overrides) {
    	var original = {};
    
    
    	for(prop in overrides)
    		if(overrides.hasOwnProperty(prop) && Ext.isFunction(obj.prototype[prop]))
    			original[prop] = obj.prototype[prop];
    
    
    	Ext.override(obj, Ext.applyIf(overrides, { original: original }));
    };
    
    
    Ext.overrideOriginal(Ext.form.TextArea, !Ext.is.iOS ? {} : {
    	lastY: undefined,
    
    
    	handleTouch: function(e) { this.lastY = e.pageY; },
    
    
    	handleMove: function(e) {
    		var textArea = e.target;
    		var top = textArea.scrollTop <= 0;
    		var bottom = textArea.scrollTop + textArea.clientHeight >= textArea.scrollHeight;
    		var up = e.pageY > this.lastY;
    		var down = e.pageY < this.lastY;
    
    
    		this.lastY = e.pageY;
    		
    // default (mobile safari) action when dragging past the top or bottom of a scrollable
    // textarea is to scroll the containing div, so prevent that.
    		if((top && up) || (bottom && down))
    			e.preventDefault();
    		
    // Sencha disables textarea scrolling on iOS by default,
    // so stop propagating the event to delegate to iOS.
    		if(!(top && bottom))
    			e.stopPropagation();
    	},
    
    
    	initEvents: function() {
    		var textArea = this.fieldEl.dom;
    // have to add these events directly to the DOM textarea (as opposed to this.fieldEl.on),
    // otherwise they're handled after Ext.gesture.Manager and preventDefault will already have been called.
    
    
    		textArea.addEventListener(
    			Ext.supports.Touch ? 'touchstart' : 'mousedown',
    			Ext.createDelegate(this.handleTouch, this),
    			false);
    		
    		textArea.addEventListener(
    			Ext.supports.Touch ? 'touchmove' : 'mousemove',
    			Ext.createDelegate(this.handleMove, this),
    			false);
    			
    		this.original.initEvents.apply(this, arguments);
    	},
    });
    Can this be adopted for Touch 2?

    Thanks.

  2. #2
    Sencha User Jamie Avins's Avatar
    Join Date
    Mar 2007
    Location
    Redwood City, California
    Posts
    3,661
    Vote Rating
    20
    Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough

      0  

    Default


    We will review it and report back.

    Sencha Inc

    Jamie Avins

    @jamieavins

  3. #3
    Sencha User Jacky Nguyen's Avatar
    Join Date
    Jul 2009
    Location
    Palo Alto, California
    Posts
    469
    Vote Rating
    14
    Jacky Nguyen has a spectacular aura about Jacky Nguyen has a spectacular aura about

      0  

    Default


    We will be putting this in the library, but it will be after 2.0.0 release
    Sencha Touch Lead Architect

  4. #4
    Sencha Premium Member
    Join Date
    Feb 2012
    Posts
    36
    Vote Rating
    2
    mangvlad is on a distinguished road

      0  

    Default


    Any way there could be a temp fix for this, based on the code above?

  5. #5
    Sencha Premium Member
    Join Date
    Oct 2011
    Posts
    3
    Vote Rating
    0
    ricmelia is on a distinguished road

      0  

    Default


    Any ideas when a fix for this will be added to the library?

    The inability to scroll is the only negative feedback we're getting for our Touch application - the fix posted below for Touch 1 doesn't appear to work anymore (possibly due to iOS 5+ changing the gesture for scrolling textareas?).

    We'd like to upgrade to Touch 2 but don't want to spend the effort just yet if we're going to be left with this problem.

    Thanks

  6. #6
    Sencha User siebmanb's Avatar
    Join Date
    Aug 2011
    Location
    Geneva (CH) - Grenoble (FR)
    Posts
    253
    Vote Rating
    15
    siebmanb will become famous soon enough

      0  

    Default


    Just tried the sample code on iOS 5 and ST 1.x. It works great.

    Thank you

  7. #7
    Sencha Premium Member
    Join Date
    Oct 2011
    Posts
    3
    Vote Rating
    0
    ricmelia is on a distinguished road

      0  

    Default


    Unfortunately, it only works if the containing form / formPanel is not set to scroll vertically as well.

    If it is, the fix doesn't work properly - for example, page also attempts to scroll when the text box scrolls.

  8. #8
    Sencha User siebmanb's Avatar
    Join Date
    Aug 2011
    Location
    Geneva (CH) - Grenoble (FR)
    Posts
    253
    Vote Rating
    15
    siebmanb will become famous soon enough

      0  

    Default


    You are right, I am in that situation. You can scroll the text area but when you stop, the page scrolls as well. It is a "good enough" solution, waiting for a proper one.

  9. #9
    Sencha User
    Join Date
    Nov 2011
    Posts
    39
    Vote Rating
    0
    uksencha is on a distinguished road

      0  

    Default


    Hi

    I am using version 1 of Sencha Touch but this problem seems to be the same there.

    I need to come up with a solution to this issue quite quickly because I have a deadline to meet so I have been working to see if I can come up with anything.

    So far I have created the following and seems to work (ie it allows you to scroll the form and textareas independently).

    The only remaining issue seems to be that if you scroll a text area that is at the bottom of a long form (ie off the top scroll area) then the system seems to perform a window scroll to (0,0) or something like it when I set the scroll back to vertical for the form.

    I was wondering if anyone had any ideas as to how to solve this - its frustrating because its very close to what I want. Please post if you have any improvements as well.

    If anyone is wondering why I disable the keyboard while scrolling - I got an issue sometimes on the ipad where the keyboard appeared mid scroll - this fixes it you just get a slight flicker in the text if your disabledCls for the textarea is not black.

    PHP Code:
      Ext.overrideOriginal(Ext.form.TextArea, !Ext.is.iOS ? {} : {
       
    lastYundefined,

       
    handleTouch: function(e) { 
        
    this.lastY e.pageY;
       },

       
    handleMove: function(e) {
        var 
    textArea e.target;
        var 
    top textArea.scrollTop <= 0;
        var 
    bottom textArea.scrollTop textArea.clientHeight >= textArea.scrollHeight;
        var 
    up e.pageY this.lastY;
        var 
    down e.pageY this.lastY;

        var 
    textAreaCmp Ext.getCmp(textArea.parentElement.parentElement.id);
        var 
    form textAreaCmp.up('form');
        
    form.setScrollable(false);

        
    textArea.setAttribute('readonly''readonly');
        
    textArea.setAttribute('disabled''true');
        
    Ext.defer(function() {
         
    textArea.blur();
         
    textArea.removeAttribute('readonly');
         
    textArea.removeAttribute('disabled');
        }, 
    10);

        
    this.lastY e.pageY;

        
    // default (mobile safari) action when dragging past the top or bottom of a scrollable
        // textarea is to scroll the containing div, so prevent that.
        
    if((top && up) || (bottom && down))
         
    e.preventDefault();

        
    // Sencha disables textarea scrolling on iOS by default,
        // so stop propagating the event to delegate to iOS.
        
    if(!(top && bottom))
         
    e.stopPropagation();
       },

       
    handleUp: function(e) {
        var 
    textArea e.target;
        var 
    textAreaCmp Ext.getCmp(textArea.parentElement.parentElement.id);
        var 
    form textAreaCmp.up('form');
        
    form.setScrollable('vertical');
       },

       
    initEvents: function() {
        var 
    textArea this.fieldEl.dom;
        
    // have to add these events directly to the DOM textarea (as opposed to this.fieldEl.on),
        // otherwise they're handled after Ext.gesture.Manager and preventDefault will already have been called.

        
    textArea.addEventListener(
         
    Ext.supports.Touch 'touchstart' 'mousedown',
         
    Ext.createDelegate(this.handleTouchthis),
         
    false);

        
    textArea.addEventListener(
         
    Ext.supports.Touch 'touchmove' 'mousemove',
         
    Ext.createDelegate(this.handleMovethis),
         
    false);

        
    textArea.addEventListener(
         
    Ext.supports.Touch 'touchend' 'dragend',
         
    Ext.createDelegate(this.handleUpthis),
         
    false);

        
    this.original.initEvents.apply(thisarguments);
       },
      }); 
    I realise that this will be fixed in future version of the library but it would be great if we could get a workaround working now.

    Thanks

    Chris

  10. #10
    Sencha Premium Member
    Join Date
    Oct 2011
    Posts
    3
    Vote Rating
    0
    ricmelia is on a distinguished road

      0  

    Default


    Hi Chris,

    hopefully this might help...

    We found that if the form was manually scrolled at all then the fix that mangvlad posted above didn't work properly. The workaround is to add some listeners to the textareas as we create them.

    I've edited the code, it's actually part of a helper library which creates the text area and sets all of the properties etc.

    "config.scrollingArea" is probably the equivalent of your "textAreaCmp.up('form')".

    Code:
    myTextArea.addListener('focus', function (sender, e) {
        config.scrollingArea.scroller.scrollTo({ x: 0, y: 0 });
        this.fieldEl.dom.scrollIntoView(true);
        config.scrollingArea.setScrollable(false);
    });
    myTextArea.addListener('blur', function () { config.scrollingArea.setScrollable('vertical'); });
    Ric

    [edit - removed a ".control" from the last line of the code snippet]