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

controlgroups not getting enhanced because pagecreate handler is in mobile.init? #4773

Closed
frequent opened this issue Jul 30, 2012 · 11 comments
Closed
Assignees
Milestone

Comments

@frequent
Copy link
Contributor

I'm doing a site using requireJS for on-demand loading with requireJS, Jquery and Jquery Mobile being the main plugins being required.

Ever since I got requireJS to work properly, I started having problems with controlgroups not being enhanced anymore. The elements contained enhanced, but a 4-button controlgroup would be 4 individual buttons with the wrapping controlgroup-div not being enhanced.

If I load page "straight" the first load usually works but on all subsequent pages being pulled in, all controlgroups are broken. If I disable pushstate and start from a deeplinked page like

  www.some.com/folder/index.html#/folder/page.html

all controlgroups break right away.

Today I found this comment in the latest JQM:

// The pagecreate handler for controlgroup is in jquery.mobile.init because of the soft-dependency on the wrapped widgets

which would explain, why this is the only widget that does not get enhanced, wouldn't it?

I'm currently using this function, which I need to run on every page load and AJAX content request:

 var enhanceControlgroups = 
      function( page ){
           page.find( 'div:jqmData(role="controlgroup")').closest('div').trigger('create').controlgroup('refresh').end();
           }

Which fixes controlgroups. Because I get an error "can't call refresh prior to initializiation" if I only run controlgroup('refresh') without trigger('create') I assume the controlgroups are not getting enhanced out of the box.

@frequent
Copy link
Contributor Author

My fix also is still buggy. If someone wants to take a look, I can email some login data into my project (non-public).

@jaspermdegroot
Copy link
Contributor

@frequent

Actually controlgroup() is just a function that takes options as parameter. It is not a real widget. This means there are no methods like controlgroup( "refresh" ) or triggger( "create" ). There is just a call to the function: controlgroup().

This is the code in jquery.mobile.init that should make sure controlgroups are enhanced:

        if ( $.fn.controlgroup ) {
            $( document ).bind( "pagecreate create", function( e ) {
                $( ":jqmData(role='controlgroup')", e.target )
                    .jqmEnhanceable()
                    .controlgroup({ excludeInvisible: false });
            });
        }

I am not an expert on requireJS but could it be the IF statement is causing the problem?

@frequent
Copy link
Contributor Author

hm. Let me have a look.

@ghost ghost assigned jaspermdegroot Nov 7, 2012
@gabrielschulhof
Copy link

I turned controlgroup into a proper widget, and I moved its enhancement hook into the widget source file. In jquery.mobile.init.js, the enhancement hook was being added at dom-ready, so I did the same in the widget source file in this commit.

@geiregjo
Copy link

geiregjo commented Feb 8, 2013

Is this issue really resolved? I just bumbed into it. The buttons inside the controlgroup are enhanced but the controlgroup isn't. First I tried JQM 1.2.0 which doesn't have controlgroup as a widget. This didn't work. Then I tried the latest version of JQM with the same result. The fix provided by uGoMobi does work.

@jaspermdegroot
Copy link
Contributor

@geiregjo - Can you provide a test page that illustrates the issue?

@ghost
Copy link

ghost commented Feb 11, 2013

I am having a very similar problem when adding checkboxes to a controlgroup. I have tried every possible way of refreshing that I have read about. I was hoping JQM 1.3.0 RC1 would solve it but I get the same result. The created ui-checkbox elements will never become placed inside the ui-controlgroup-controls element. See here: http://jsfiddle.net/leen666/jSYUG/1/ Compare when running noWrap with onDomReady.

@jaspermdegroot
Copy link
Contributor

@leen666

This is because you work with checkboxes that are already enhanced by the framework.
See: http://jsbin.com/erezak/23/edit

@ghost
Copy link

ghost commented Feb 11, 2013

@uGoMobi

I see. Big thanks for looking in to it, I have spent days on this. Another way of solving it is to put the template outside the page div.

@jaspermdegroot
Copy link
Contributor

@leen666

No problem. Yes you can put the checkbox template outside the page to prevent enhancement or set data-role="none" on the input. However, for semantic reasons I woudn't recommend that approach.

@arobinson
Copy link

I'm not seeing this issue fixed. I have jQueryMobile initialization turned off as I am using Backbone.js. When I initialize the page, the control group is only occasionally styled. Refreshing the page leads to erratic results, sometimes it works, sometimes it doesn't. The HTML is simple:

    <div data-role="fieldcontain">
      <fieldset data-role="controlgroup" id="edit-pray-for-container"
        data-type="horizontal">
        <legend>Edit</legend>
        <a id="edit-pray-for" href="#" data-role="button">Facebook</a>
        <a id="custom-values" href="#" data-role="button">Custom</a>
      </fieldset>
    </div>

Sometimes I get two buttons, sometimes I get the controlgroup.

This is my code that executes on loading my "View" page:

      changePage: function(page, changePageOptions)
      {
        var oldPage = this.activePage;

        this.activePage = page;

        page.router = this;
        page.render();

        $("body").append(page.$el);

        //page.$el.trigger("create");

        var $oldJqmPage = $.mobile.activePage;

        if ($oldJqmPage == null)
        {
          $.mobile.initializePage();
        }
        else
...

I think the issue is happening because jQM 1.3.2 is assuming that the page is initialize during page load (relying on domReady) instead of allowing it to be initialized later manually as shown above.

How can I fix the controlgroup so that it properly initializes when the domReady has already been kicked off?

Note that I am also using Require.js so that the jquerymobile JS script is loaded asynchronously

Here is a hack I put in place to get it to work:
First, modify jquery.mobile-1.3.2.js:

  $(document).on("lateinit",
    function (e)
    {
      $.mobile.document.bind( "pagecreate create", function( e )  {
        $.mobile.controlgroup.prototype.enhanceWithin( e.target, true );
      });
    });

Then in the code using require.js to load jquerymobile:

define(
  [ "jquery", "jqm" ],
  function ($, jqm)
  {
    $(document).trigger("lateinit");
  });

Really, it seems like jQM needs an ordering feature to ensure that the items are loaded in the required order and not relying on timing hacks like domReady

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

5 participants