jQuery UI menu loses focus when any item is selected - jquery-ui

I've created a simple Jquery menu but have run into a problem I cannot isolate:
The first item I mouseover is fine, but as soon as I move to another item (parent and child items alike) the menu loses focus.
What I've done to try and isolate the problem:
removed all CSS from my page
using base theme for Jquery UI 1.10.3
removed all other javascript from the page
using Jquery 1.7.2
Tried debugging, I get no errors
Code works in fiddle
Included menu.js, widget.js, ui.js, position.js and core.js in the <head>
Here is my HTML
<body>
<form>
<div style="width:50%">
<ul id="buildingmenu">
<li>Social Update</li>
<li>Building Update
<ul>
<li>building 1</li>
<li>building 2</li>
</ul>
</li>
</ul>
</div>
</form>
</body>
And my javascript
$(document).ready(function () {
$("#buildingmenu").menu();
});
I'm pulling out my hair, what have I missed??
EDIT: Here's a screencast of the problem with chrome inspector open

With full jQuery UI version included works fine: http://jsfiddle.net/B2HFE/
Reading the docs I see the dependecies of jQuery UI menu are:
UI Core
Widget Factory
Position
I think you miss the last one.

Related

Can tab refer to other context element(panel) instead of the tab's context when I use jQuery UI 1.9 Tabs

I want to use jQuery UI 1.9 Tabs like this way:
HTML:
<!-- this is the tab's context -->
<div id="tabs">
<ul id="tabs-ul">
<li id="tabs-email"><a href="#Email" title="Email">Email</li>
<li id="tabs-setting"><a href="#Settings" title="Settings">Setting</li>
</ul>
</div>
<!-- this is the other context -->
<div id="Email">someting</div>
<div id="Settings">someting</div>
JS:
$("#tabs").tabs({});
When I do like blow and click one tab,there will be :
Uncaught Error: jQuery UI Tabs: Mismatching fragment identifier.
What I want is the tab("li#tabs-email"/"li#tabs-setting") can automatic refers to the other div context's panel("div#Email"/"div#Settings").But I can't find the way to change panel context.What am I missing?
I don't think this is possible without significant work. Mainly because the whole "globalPanels" thing is semantically wrong, and is why it's been removed.
The way it works now means that all tab content is implicitly related to the tabs.

Dynamic navbar not enhanced on first page of multi-page document

I'm dynamically creating the navbar in my multi-page document. My problem is that the navbar is not enhanced on the first page in the document, but - strangely - on every other page. The kicker is that if I add a page in the code before this actual first page and set up an event to forward to the "actual" first page, everything works fine. The code for the navbar is the same everywhere for now:
<div data-role="page" id="stdPage" data-theme="b">
<div data-role="content">
...
</div><!-- /content -->
<div data-role="footer" data-position="fixed" data-id="persFooter">
<div data-role="navbar">
<ul>
<li></li>
</ul>
</div><!-- /navbar -->
</div><!-- /footer -->
</div>
I'm populating the navbar on all the pages using:
$(function () {
$("div[data-role='navbar'] ul").empty();
$("div[data-role='navbar'] ul").append("<li>Test</li>");
$("div[data-role='navbar']").navbar();
});
When doing this, as I said, the navbar on the first page - the one already on display - is not enhanced. All the other pages have enhanced navbars.
I've tried messing around with .page() and trigger("pagecreate") etc. to no avail.
Any help would be greatly appreaciated.
The problem is that your navbar needs to be in the page when the 'pageinit' event fires the first time your browswer loads that page. This is when jQ Mobile enhances the content of your page.
It sounds like you're adding the navbars to your whole document after the 'pageinit' event fires on your first page. This is why when you navigate to any other page, it fires 'pageinit' and enhances your content properly.
What you should try is copying your common header on the 'mobileinit' event, copying it before jQuery mobile loads (put the script you're using before the jQ Mobile script tag), or put your header's markup on your first page and copy clones (.clone()) to everypage after the markup is enhanced.
As for the trigger the proper syntax is this: $(yourelement).trigger('create').
$(function () {
$("div[data-role='navbar'] ul").empty();
$("div[data-role='navbar'] ul").append("<li>Test</li>");
$("div[data-role='navbar']").trigger('create');
});
Good luck!
FOLLOW UP: Here's how I did it.
I had a header that I wanted to make common to certain pages on of which was my first page. So I made the header on that front page as I normally would. On my other pages I put a placeholder div with a class="commonHeader".
Then on 'mobileinit' I added the following instruction:
$(document).on('mobileinit', function(event){
$('.commonHeader').each(function(index, element) { //attach common header to all pages
$(element).replaceWith($('#frontPage [data-role="header"]').clone(true, true));
});
});
You can try using the same method only on the pages you need common header.

jquery mobile dynamically inserting new links into the DOM not working

I'm still new to jQuery mobile. I'm trying to fix a minor problem on one of my pages.
I have a page that has a simple list of links. There's nothing special here, just this:
<ul>
<li> One</li>
<li> Two</li>
<li> Three</li>
<li> Four</li>
<li> Five</li>
<ul>
More
I have a bit of js so that when the #list_more link is clicked, we do an ajax call that pulls the next five items and adds to the end of the ul.
$('#list_more').click(function(){
$.post("/scripts/ajax.php", function(data){
$('#list_more').attr('data-time',data.time);
$('ul li:last').after(data.out);
});
})
The pages are setup using multipage templates. Because the new pages are being added to the DOM dynamically, I'm getting an Error loading page message. I'm not sure how to fix this.
Have you tried refreshing your list? http://operationmobile.com/dont-forget-to-call-refresh-when-adding-items-to-your-jquery-mobile-list/

Adding scroll bars to a listview using JqueryMobile

Trying to add scrollbars to a listview within a dialog in JQueryMobile with no joy.
I'm using the following code:
<div class="content-primary">
<ul id="lvPages" data-role="listview" data-filter="true" data-inset="true" data-scroll="true"></ul>
</div>
Which works perfect on desktop browsers yet when I test this on an iPad the scrollbars don't appear.
Is there something obvious I'm missing?
Sorry, should actually add:
I'm adding the items via Javascript and am calling a " $("#lvPages").listview('refresh');" upon the end of these additions.
According to this forum article, you have to include the jquery.mobile.scrollview.js script (and its associated CSS file) for the data-scroll attribute to be recognized and acted upon.

jQuery Mobile proper way to initialize a listview

Here is my problem. I have a few hard coded pseudo pages in my index. Some filled with content, some empty which will be filled on user interaction only by ajax. This ajax content contains html lists. When they load they don't have the nice jquery mobile look so I have to call a .listview() method so the jqm framework parse it on my ajax callback. That is where I often get this JS error:
Uncaught TypeError: Cannot read property 'jQuery162027575719612650573' of undefined
The number is never the same...
I wonder if I use the proper way to parse a listview after the page loads the ajax content. the error seems to be triggered when there is slight lag for the loading and the complete event is triggered too soon and my listview is not yet in the DOM at that moment, just a guess. what is the recommended way to initialize a listview after an ajax call?
It is very unfortunate because when the js error occurs it seems to freeze any further js execution...
so here is my empty pseudo page:
<div data-role="page" id="playlist" data-add-back-btn="true">
<div data-role="header">
<h1><g:message code="pd.playlist" /></h1>
</div>
<div data-role="content"></div>
</div>
right under it there is a script tag with the bind an ajax call on pageshow to activate the listview
<script type="text/javascript">
$('#playlist').bind('pageshow', function () {
$.ajax({
url: "updatePlaylistTemplate.gsp",
error:function(x,e){handleAjaxError(x,e);},
beforeSend:function(){$.mobile.showPageLoadingMsg();},
complete:function(){
$.mobile.hidePageLoadingMsg();
$('[data-role="listview"]').listview(); //re-active all listview
},
success:function(data, textStatus, jqXHR){
$('#playlist').find('[data-role="content"]').html(data);
}
});
});
</script>
The updatePlaylistTemplate return this (extract):
<ul data-role="listview" data-split-theme="d">
<li data-icon="delete">
Provider: Bell
</li>
<li data-icon="delete">
Rock - Classic Rock
</li>
<li data-icon="refresh" data-theme="e">Refresh list</li>
<li data-role="list-divider">Next song</li>
<li>
<a href="urlToViewSongInfo">
<img src="images/song.gif" />
<h3>Albert Flasher</h3>
<p>The Guess Who</p>
<p class="ui-li-aside">Next</p>
</a>
</li>
<li data-role="list-divider">Now playing</li>
<li>
<a href="urlToviewSongInfo">
<img src="images/song.gif" />
<h3>Crime of the Century</h3>
<p>Supertramp</p>
<p class="ui-li-aside">14h49</p>
</a>
</li>
<li data-role="list-divider">Previous songs</li>
<li>
<a href="urlToViewSongInfo">
<img src="images/song.gif"" />
<h3>Desperado</h3>
<p>Alice Cooper</p>
<p class="ui-li-aside">14h45</p>
</a>
</li>
[...]
</ul>
What version of jQuery Mobile are you using? In the latest beta (1.0b2) you can trigger the create event on a dom element to have the framework initialize it:
New “create” event: Easily enhance all widgets at once
While the page plugin no longer calls each plugin specifically, it
does dispatch a “pagecreate” event, which most widgets use to
auto-initialize themselves. As long as a widget plugin script is
referenced, it will automatically enhance any instances of the widgets
it finds on the page, just like before. For example, if the selectmenu
plugin is loaded, it will enhance any selects it finds within a newly
created page.
This structure now allows us to add a new create event that can be
triggered on any element, saving you the task of manually initializing
each plugin contained in that element. Until now, if a developer
loaded in content via Ajax or dynamically generated markup, they
needed to manually initialize all contained plugins (listview button,
select, etc.) to enhance the widgets in the markup.
Now, our handy create event will initialize all the necessary plugins
within that markup, just like how the page creation enhancement
process works. If you were to use Ajax to load in a block of HTML
markup (say a login form), you can trigger create to automatically
transform all the widgets it contains (inputs and buttons in this
case) into the enhanced versions. The code for this scenario would be:
$( ...new markup that contains widgets... ).appendTo( ".ui-page"
).trigger( "create" );
Create vs. refresh: An important distinction
Note that there is an important difference between the create event
and refresh method that some widgets have. The create event is suited
for enhancing raw markup that contains one or more widgets. The
refresh method that some widgets have should be used on existing
(already enhanced) widgets that have been manipulated programmatically
and need the UI be updated to match.
For example, if you had a page where you dynamically appended a new
unordered list with data-role=listview attribute after page creation,
triggering create on a parent element of that list would transform it
into a listview styled widget. If more list items were then
programmatically added, calling the listview’s refresh method would
update just those new list items to the enhanced state and leave the
existing list items untouched.
Link: http://jquerymobile.com/blog/
You can also copy the output that jQuery Mobile creates and use that structure rather than using <li> tags and depending on jQM to inititialize it:
<li data-role="list-divider" class="ui-li ui-li-divider ui-btn ui-bar-a ui-btn-up-undefined" role="heading"><span>List Divider</span></li>
<li data-theme="b" class="ui-li ui-li-static ui-body-b">Regular LI</li>

Resources