Reputation: 5433
JQuery Mobile is making my cry tonight. I'm trying to build custom controls so I don't repeat certain elements through my app, and it's giving me a hard time. Specifically, I have the following in an HTML file:
<div id="custom-header" data-role="header" data-position="inline" data-theme="f">
<a href="index.html" data-icon="back" style="margin-top:5px" data-theme="b">Back</a>
<div style="text-align: center; padding-top: 5px; padding-bottom: 3px"><img src="../images/logo.png" ></div>
<a href="index.html" data-icon="home" style="margin-top:5px" data-theme="b">Home</a>
</div>
In my main file I'm essentially doing:
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0rc2/jquery.mobile-1.0rc2.min.js"></script>
<div data-role="page" id="test-console" data-theme="m">
<div id="me-header"></div>
<script>
$.get('header.html', function (retData) {
$('me-header').html(retData).trigger('create');
});
</script>
</div>
So here's the problem - The header doesn't render the same as it does as when I paste the contents of header.html directly into my JQM page. It almost feels like trigger('create') isn't doing anything.
Any ideas? I've burned about three hours and tutorials like http://jquerymobiledictionary.pl/faq.html don't seem to be applying..
Upvotes: 21
Views: 31066
Reputation: 3612
Calling:
trigger('pagecreate');
immediately after:
trigger('create');
works for me.
Upvotes: 0
Reputation: 339
As others it make me nuts to inject header in a page. As said by anthony the problem is header is not a "basic" widget. The classes are not added by jqm doing the injection.
I do not like some much to add class ui by my self.
My (crazy?) proposal is to create a brand new page (including the header) and then extract the header tag including all the class ui ceremony added by jqm. I really do not know the perf impact, ... but it seems to work and seems more realiable than adding class by hands.
below is an example. Do you like?
$( '[data-role=page]' ).on( 'pageinit', function ( event, ui ) {
var sHeader = '<div data-role="header" id="tobechanged" data-position="fixed" data-id="CPL">';
sHeader += '<a href="#panelImageDetailLeft" data-icon="bars" data-iconpos="notext" data-shadow="false" data-iconshadow="false">Menu1</a>';
sHeader += '<h1>What a nice title </h1 >';
sHeader += '<a href="#panelImageDetailRight" data-icon="bars" data-iconpos="notext" data-shadow="false" data-iconshadow="false">Menu2</a>';
sHeader += '</div>';
//Create a temporary page to initialize all the ui-class
//var sId = core.misc.GUID_new();
var sId = "azerty";
$( '#body' ).append( '<div data-role="page" id="' + sId + '">' + sHeader + '<div data-role="content">content</div></div>' );
$.mobile.initializePage(); //do not know if needed
$( '#' + sId ).page(); //very important to let jqm generate the class ui
//console.log( "page():\n" + $( '#' + sId ).html() );
var $myHeader = $( '#tobechanged' );
//console.log( "tobechanged:\n" + $myHeader.html());
//clean the temporary page
$( '#' + sId ).empty();
$.mobile.initializePage(); //do not know if needed
//replace the id
//console.log( "myheader id: ... " + $myHeader.attr( "id" ) );
$myHeader.attr( "id", $( "#" + event.target.id ).attr("id") + "Header" );
//console.log( "myheader id: ... " + $myHeader.attr( "id" ) );
$( "#" + event.target.id ).find( "[data-role=header]" ).replaceWith( $myHeader );
});
Upvotes: 0
Reputation: 5063
This is not the answer to the specific issue of the OP, but one cause for .trigger('create') not working could be that jQuery Mobile is not loaded properly in the current scope and thus not reacting to the trigger - which can happen in a poorly configured RequireJS-setup for instance.
It doesn't hurt to check console.log($.mobile) in case it shows undefined...
Upvotes: 0
Reputation: 944
For me, .trigger('create');
always works if applied to the element with data-role="page"
Try This : $('#test-console').trigger('create');
Hope it helps..
Upvotes: 2
Reputation: 935
this question is old enough by now, but I just ran into the problem so here is how I handled it -- (this maintains the set data-theme and applies the correct roles for the containing divs and headers)
$('your_selector').find('div[data-role="header"], div[data-role="footer"]').each(
function( ){
var dR = $(this).attr('data-role');
var dT = $(this).attr('data-theme');
$(this).addClass('ui-' + dR + ' ui-bar-' + dT).attr('role', (dR == 'header' ? 'banner' : 'contentinfo') ).children('h1, h2, h3, h4').each(
function( ){
$(this).addClass('ui-title').attr({'role':'heading', 'aria-level':'1'});
}
)
}
);
depending on your code, it might be more convenient to set this up as a function and send your selector as an argument. Hope it helps.
Upvotes: 2
Reputation: 613
When changing header, footer or content, you can trigger pagecreate
on the page:
$('#me-header').closest(":jqmData(role='page')").trigger('pagecreate');
This is a jQM bug: https://github.com/jquery/jquery-mobile/issues/2703.
According to a comment in the issue report, calling pagecreate
multiple times may cause problems though, as elaborated in https://github.com/jquery/jquery-mobile/issues/2703#issuecomment-4677293.
Upvotes: 14
Reputation: 12403
I've found that the trigger('create');
Works when applied to the body like so:
$('body').append(html).trigger('create');
But the issue I am running into now is the ul list are throwing an undefined error.
Upvotes: 2
Reputation: 5433
I believe I've found the 'best' answer available. In short, the 'header' and 'footer' type data-role elements are not standard widgets. They are some sort of hybrid construct. I found this out by just going through the source code of JQueryMobile. They don't have a 'create' method, so it can't be called.
My workaround was to just apply the classes directly to my code, instead of expecting the widget to do it for me. Not ideal, but it works well enough.
Upvotes: 8
Reputation: 139
$('me-header').html(retData).trigger('create');
should be:
$('me-header').append(retData).trigger('create');
Upvotes: 1