AngularJS and jquery mobile - jquery-mobile

I load a html-partial into a ng-view directiv via a controller in AngularJS. The html-partial looks like this:
<div>
<ul data-role="listview" data-inset="true" data-theme="c">
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</div>
The problem is that the listview does not get rendered into a jquery-mobile-control. What is wrong?

I got it to work. Here is what I did:
I made a new directive that I append on the ul-element. It waits until the last li-element is rendered, then I call the trigger on the jqueryMobileTpl directive.
app.directive('jqueryMobileTpl', function () {
return {
link: function (scope, elm, attr) {
//elm.trigger('create');
}
};
});
app.directive('repeatDone', function () {
return function (scope, element, attrs) {
// When the last element is rendered
if (scope.$last) {
element.parent().parent().trigger('create');
}
}
});
and
<div jquery-mobile-tpl>
<ul data-role="listview" data-inset="true" data-theme="c" data-ng-repeat="customer in customers | orderBy:'lastName'" repeat-done="" ng-cloak>
<li>{{customer.firstName + ' ' + customer.lastName}}</li>
</ul>
</div>
Thank you #CaioToOn and #Omar !!!

This problem is not related to AngularJs. It happend that jQuery Mobile is not aware of every DOM change, and you need to give it a tip. To adivice jQuery Mobile about the change, you need to trigger a create event on the element.
According to the docs (look at "Enhancing new markup"):
However, if you generate new markup client-side or load in content via Ajax and inject it into a page, you can trigger the create event to handle the auto-initialization for all the plugins contained within the new markup. This can be triggered on any element (even the page div itself), saving you the task of manually initializing each plugin (listview button, select, etc.).
So all you got to do is to trigger the create event just after the content has been included.
I'd suggest you to create a directive that simply triggers the event on the templates for you. Something like:
app.directive('jqueryMobileTpl', function() {
return {
link: function(scope, elm, attr) {
elm.trigger('create');
}
};
});
Then you just add this directive to the root element of the template:
<div jquery-mobile-tpl>
<ul data-role="listview" data-inset="true" data-theme="c">
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</div>
You could make this directive low priority, so if you use other directives that might change the template, this one would wait for all changes before telling jQuery Mobile to render. Working sample here.

Related

how to add class 'ui-btn-active 'on li tag in jquery mobile at runtime

i am using jQuery Mobile Navigation Tabs. i take a common footer for all pages like footer.html, and load this footer on a footer div at run time. this is working good as i want.
here is my code of footer.html
<div data-role="footer" data-id="foo1" data-position="fixed">
<div data-role="navbar">
<ul id="footertab">
<li id="home"><a href="#page1" data-transition="none" data-icon="tab-home" ></span>Home</a></li>
<li>6</span>Alerts</li>
<li><a href="#page3" data-transition="none" data-icon="tab-services" >Services</a></li>
<li>Learn</li>
<li>Settings</li>
</ul>
</div><!-- /navbar -->
</div><!-- /footer -->
</div><!-- /page -->
And i add this footer on run time using this code.
$(document).on('pageinit', function(event){
$(".addfooter").load('footer.html', function(){
$(this).trigger("create");
});
});
this running fine. but i have some issue with this code.it does not show the active tab.
i know that i have to add class='ui-btn-active ui-state-persist' in my selected tab.
but i do not sure that how to add and replace it with java script.
i dont want to use to write this footer at all pages.
for this task i use this code in side my script
$(document).delegate('[data-role="navbar"] a', 'click', function () {
alert("calling tab click");
$(this).addClass('ui-btn-active ui-state-persist');
});
This function call every time when i click any tab. but it does show selected tab.
all tabs are deselected.
How can i solve this problem.
please suggest me
Hello try this code.
$(document).live('pageshow',function(event,ui){
// disable previous selected links
$('[data-role=navbar] a').removeClass("ui-btn-active");
// select link
var menuLink = $('[data-role=navbar] a[href="#'+$.mobile.activePage.attr('id')+'"]');
menuLink.addClass("ui-btn-active");
});

Why is my dynamically-added content not rendering with jQuery Mobile?

I'm using jQuery Mobile + Backbone + RequireJS. After successful login I do the following:
require(['app/view/main'], function(MainView) {
var mainView = new MainView();
$('body').html(mainView.render().el);
});
and render() looks like
render: function() {
this.$el.html(this.template);
return this;
}
Upon doing so, my page is blank. Inspecting the body, I do see the following HTML inside the body:
<div data-role="page" id="main">
<div data-role="header" data-position="inline">
<h1>Accounts</h1>
</div>
<div data-role="content">
hello
</div>
</div>
I've also tried doing this inside render():
this.$el.html(this.template).trigger('create');
as well as
this.$el.html(this.template).page();
but the page is still blank. Any ideas why?
If I simply put the HTML inside the body and load the page, it displays fine, like a normal jQuery Mobile app would.
Are you waiting until after pageinit to trigger / create your page?
$(document).bind('pageinit', function() {
// trigger
});
Also, jQM may be interpreting your markup as a single page template and then by injecting a data-role='page' element, you are marking up a multiple page document (with only a single page). Try leaving the <div data-role='page'> element in your default markup and then dynamically add the header, content and footer. jQM should then correctly interprete the markup and enhance it accordingly.

Close panel from link in listview

I have a jquery mobile page which has a panel. Inside the panel I have a listview, and on each listitem there is a where I've added a data-rel="close" attribute. I want to be able to close the panel when ever a listitem is clicked.
Note that I also has a binding to angular.
<ul data-role="listview" data-icon="arrow-l" class="ui-icon-alt" data-inset="true" >
<li ng-repeat="task in tasks" >
{{task.Name}}
</li>
</ul>
I've testes on a link outside the listview and it works fine. I'm not sure id angularjs is playing a trick on me here or it is something else.
best regards
Rasmus
Markup
{{task.Name}}
JS
$('#closepanel').on('click', function {} {
$( "#PanelID" ).panel( "close" );
});

How to use a template for all jQuery Mobile pages?

Behold: a footer template:
<!-- Templates -->
<script type="text/template" id="templateFooter">
<div data-role="navbar">
<ul>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</script>
In every mobile page I have:
<div data-role="footer" data-position="fixed">footer</div>
The way I'm currently loading the template is:
$(function() {
$('div[data-role=footer]').html($('#templateFooter').html());
$.mobile.activePage.trigger('create');
});
This works, but I don't really like using $(function(), but I need to load it if any page shows, so pageinit or pageshow does not help. I'll be using knockout.js going forward, if that is of any help.
Is there a better way to do this?
function getTemplateFooter() {
//return footer text here
}
$("div:jqmData(role='page')").live("pagebeforecreate",function() {
// get the footer of the page
// if footer doesn't exist on page, insert it where you want it... in this case after role="content"?
var $content =$(this).page().find('div:jqmData(role="content")');
$content.after(getTemplateFooter());
}
there is also a pageshow event, that one fires even if the user navigates to the page, through a back button press etc... it bubbles up to the page div
I use it for pages where lots of dynamic data could change between subsequent visits, or even when the user just presses back

Jquery UI Tabs - tab active only with content

any help gratefully received
I am trying to get a tab to be active ("clickable") only if there is content present within the div. The content will come from a php sql query.
In it's simplest form
<script>
$(function() {
$( "#tabs" ).tabs();
});
</script>
<div id="tabs">
<ul>
<li>Hello</li>
<li>Goodbye</li>
</ul>
<div id="tabs-1">
if Query returned result, echo results, tabs-1 active
</div>
<div id="tabs-2">
if Query returned 0 results, nothing to echo tabs-2 inactive
</div>
</div>
I guess the active/inactive part does not have to be based on the query result - number of characters in the div or size of div may both be indicators I could use to see if the div is empty.
I know very little about javascript so if there is a solution out there is it possible you could explain it as you were speaking to a small child...
Many thanks in advance and I hope my question is clear enough.
You can intercept the tab change event using select, something like:
$("#tabs").tabs({
select: function(event, ui) {
if ($(ui.panel).html().length < 1) {
alert('no content!');
return false;
}
}
});

Resources