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

Problem with dynamic layout in page with fixed footer and a dialog #8511

Open
Eccenux opened this issue Sep 1, 2016 · 3 comments
Open

Problem with dynamic layout in page with fixed footer and a dialog #8511

Eccenux opened this issue Sep 1, 2016 · 3 comments

Comments

@Eccenux
Copy link

Eccenux commented Sep 1, 2016

Source code

Hi. I have a problem with my app that I was able to minimize to this app:
https://build.phonegap.com/apps/2238062/share
Built from this code base:
https://github.com/Eccenux/mJappis-test/tree/test/autocomplete-and-dialog

I could probably minimize it more but it took me 5 days to get to this one and maybe someone will have an idea what is going on :-).

Steps to reproduce

In app:

  1. Open app (I was not able to reproduce in a standard browser).
  2. Click on search options (the button with a cog wheel).
  3. Close the search options dialog.
  4. Type 5 letters in the text box (5 auto-complete-like hints will appear).
  5. Click on the first hint.

In Chrome in device emulation mode:

  1. Open options dialog.
  2. Close dialog.
  3. Type in about 14 characters (so many that footer will not be visible on screen + 2).
  4. Click anywhere outside of the input box.

What supposed to happen

The text box should be filled with text from the selected hint.

What actually happens

The search options dialog is shown. And what is worse it is not active (clicking on buttons does nothing).

"Fun" facts...

After some hours of digging through weinre I've noticed some weird behaviours...

Android L, M and iOS 9 problem

Seems like problem occurs on both of them so is not even Android specific. What is even weirder is that older versions are fine -- both Android 4.1.2 and iOS 6.1.6 work fine.

Page activation not navigation

I noticed ui-page-activated is remove from the start page and added to the dialog. So what kind of "work" is:

$('.ui-page-active').removeClass('ui-page-active');
$('#page-start').addClass('ui-page-active');

BUT the dialog is not actually opened (not navigated to). I know this because hash tag of the page is not changed. Also navigation back to the start page does nothing ($.mobile.navigate('#page-start') will not work).

Problem is input-blur not list-click

The dialog appears after about 300 ms from input blur. Also clicking on the listview is not crucial for the error to occur (just clicking outside of the input box also trigger the dialog).

Scrolling

If you scroll the view (either user scroll or with jQuery.mobile.silentScroll(50)) the problem will not occur.

Keyboard

If you hide the keyboard the problem will not occur.

Non-fixed position of the footer

If you change position of the footer to be non-fixed the problem will not occur. For the app in question you can change position of the footer/toolbar in its settings.

@Eccenux
Copy link
Author

Eccenux commented Sep 1, 2016

One more important "fun fact" -- the problem occurs if the autocomplete listview (hints) contain more then 5 elements. BUT in a different layout (if you have something below the hints) you need much less elements for the problem to occur.

This originally made me think the problem was in my code, but now I'm convinced it's some weird problem with fixed toolbar positioning. I'm guessing it's either a memory leak or a problem with this/scope.

@Eccenux
Copy link
Author

Eccenux commented Sep 1, 2016

Adding ui-listview to tapToggleBlacklist helps for the scenario when you select a list item.

But even then the problem still occurs when you click outside of the list (even outside the window e.g. you click the developer console). The problem occurs both on Chrome 52 and latest 53, but NOT on Firefox 47.

See logs from my blur test here: https://github.com/Eccenux/mJappis-test/tree/test/autocomplete-and-dialog/tests/onblur

Notice how after input.blur Firefox simply does:

[widget-debug] [_bindToggleHandlers focusout] page:  #page-start
[widget-debug] [show] page:  #page-start
[widget-debug] [_useTransition] height treshold?:  (boolean) true
[widget-debug] [_handleAnimationStart_animationstart] page:  #page-start

But Chrome does above and then:

[widget-debug] [doneOut] form:  #page-start
[widget-debug] [SerialTransition.beforeDoneOut] form:  #page-start
[widget-debug] [cleanFrom] form:  #page-start
[widget-debug] [doneIn] $to:  #page-start
[widget-debug] [doneIn] $to:  #page-searchOptions

PS: Firefox dev (50.0a2) behaves like Chrome.

@Eccenux Eccenux changed the title Problem with fixed footer and dialog (webview only?) Problem with fixed footer and dialog Sep 1, 2016
@Eccenux Eccenux changed the title Problem with fixed footer and dialog Problem with growing layout height of page with fixed footer after opening a dialog Sep 5, 2016
@Eccenux Eccenux changed the title Problem with growing layout height of page with fixed footer after opening a dialog Problem with dynamic layout in page with fixed footer and a dialog Sep 5, 2016
@Eccenux
Copy link
Author

Eccenux commented Sep 5, 2016

Right. So I'm giving up on this one. Here is a crazy workaround.

The workaround

You have to add this to all pages that has a button that opens a dialog and that has a dynamic layout.

    $(document).on("pageinit", "#page-with-dialog-open,#another-page-with-dialog", function() {
        // JQM bug workaround
        var properPageId = this.id;
        $("[name=query]", this).on('blur.jqmBug', function(){
            // wait for the bug to occur
            var intervalId = setInterval(function (){
                var currentPageId = $('.ui-page-active').attr('id');
                // wait until page changed
                if (currentPageId !== properPageId) {
                    // apply workaround if this is a dialog but url state is not set
                    if (location.hash.indexOf("ui-state=dialog") < 0
                        && $('.ui-page-active').data('role') === 'dialog') {
                        $('.ui-page-active').removeClass('ui-page-active');
                        $('#'+properPageId).addClass('ui-page-active');
                    }
                    clearInterval(intervalId);
                    clearTimeout(timeoutId);
                }
            }, 10);
            // assuming bug will occur after around 300 ms, so clear wait interval after that time
            var timeoutId = setTimeout(function (){
                clearInterval(intervalId);
            }, 400);
        });
    });

Assumptions

Ids of two pages that layout is dynamic (it's height can grow) are:

  • page-with-dialog-open
  • another-page-with-dialog

Selector of an input that changes layout height is [name=query] (e.g. an input box that has auto-complete).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant