Commander Alchemy Commander Alchemy - 5 months ago 38
Javascript Question

Jquery mobile, change part of a page

I'm trying to change a part of a page, I know that this has been asked before but I cannot really find a good solution to my issue.

The red colour is the part of the page I want to change dynamically depending on what you click on the left side that is a panel.

Image: http://wstaw.org/m/2014/04/24/ask.png

HTML Code: http://pastebin.ubuntu.com/7322513/

<body id="framework">
<div data-role="page" class="page ui-responsive-panel">
<!-- header -->
<div data-role="header" data-theme="a">
<h1 id="titlepage">ICU</h1>
<a href="#nav-panel" data-icon="bars" data-iconpos="notext">Menu</a>
<a href="#right-panel" data-icon="gear" data-iconpos="notext">Add</a>
</div>
<!-- /header -->

<!-- content that is replaced by ajax -->
<div id="content" data-role="content">
<h2>content</h2>
</div>
<!-- /content -->

<!-- Left menu panel -->
<div data-role="panel" data-position="left" data-position-fixed="false" data-display="overlay" id="nav-panel" data-theme="b">

<ul data-role="listview" data-theme="a" data-divider-theme="a" style="margin-top:-16px;" class="nav-search" id="nav">
<li data-icon="delete" style="background-color:#111;" data-theme="b">
<!--Removed data-rel="close" since there is a bug in jquery mobile https://github.com/jquery/jquery-mobile/issues/1405 -->
<a href="#closemenu">Close menu</a>
</li>

<li data-filtertext="Inbox">

<a href="html/dummy.html">
<span class="ui-mail-icon-blue nav-ui-thumbnail"></span>
<span class="ui-li-count ui-btn-up-a ui-btn-corner-all" id="mail#">2</span>
<h1 class="ui-li-headline">Inbox</h1>
<p class="ui-li-desc" id="gotMail">Du har mail!</p>
</a>
</li>

<li data-filtertext="Startsida">
<a href="html/dummy2.html">
<span class="ui-start-icon nav-ui-thumbnail"></span>
<h1 class="ui-li-headline">Startsida</h1>

</a>
</li>

<li data-filtertext="Översikt">
<a href="html/dummy2.html">
<span class="ui-overview-icon nav-ui-thumbnail"></span>
<h1 class="ui-li-headline">Översikt</h1>
<p class="ui-li-desc">Antal elever (2)</p>

</a>
</li>

<!--Nav list divider-->
<li data-role="list-divider" role="heading" class="ui-button ui-li-divider ui-bar-a ui-li-has-count">
Avdelningar
<span id="departments#" class="ui-li-count ui-btn-up-a ui-btn-corner-all">2</span>
</li>
<!--/Nav list divider-->


<!--Auto generated departments-->
<li data-filtertext="Testpage">
<a href="html/dummy.html">
<span class="ui-department-placeholder nav-ui-thumbnail"></span>
<h1 class="ui-li-headline">Avdelning 1</h1>
<p class="ui-li-desc">Antal elever (2)</p>
</a>
</li>

<li data-filtertext="Testpage2">
<a href="html/dummy2.html">
<span class="ui-department-placeholder nav-ui-thumbnail"></span>
<h1 class="ui-li-headline">Avdelning 2</h1>
<p class="ui-li-desc">Antal elever (3)</p>
</a>
</li>

</ul>
</div>


Jquery Code:

function loadPage(page, title) {
$.ajax({
url: page,
async: false
}).done(function (data) {
$("#content").html(data);
$("#titlepage").html(title);
}).fail(function () {
alert("Gick inte att ladda");
});
}


I have done my own ajax loadpage that works but is there a way to use the jquery mobile internal since it feels like a hack.

Conclusion, is there a way to do this better? and how should i load script for each page, using the main-page header to load all of them at once or is there a way to load the script when that content is loaded.

Im using
Jquery jquery-2.1.0
JqueryMobile jquery.mobile-1.4.2

Best Regards

Answer

I have done my own ajax loadpage that works but is there a way to use the jquery mobile internal since it feels like a hack.

jQuery Mobile is based on Ajax Navigation; it uses Ajax to retrieve pages, load them into DOM and then initialize them before showing them. This been said, when you use Ajax to load external data, you are doing it the right way.

You can use $.ajax(), .load() or $.get(). However, bear in mind that you need to manually initialize data retrieved - in case it contains jQM widgets - using enhancement methods e.g. .enhanceWithin().

Should I load script for each page, using the main-page header to load all of them at once or is there a way to load the script when that content is loaded.

As you're using Single Page Model, it is safer (maybe you should) load all JS libraries and style sheets in head for each and every page. Nevertheless, jQM will load those links only once on first page's initialization, the rest of pages will be loaded/retrieved via Ajax. jQM loads first data-role=page it finds in any external page and neglects any thing else.

Why to load all JS and style sheets? Is to get jQM working again in case a user refreshes current page. In this case, the current refreshed / reloaded page becomes first page.

Binding events and adding listeners:

When using jQM, you need to stay away from .ready() and/or $(function(){}) and use Page Events. Except for some cases e.g. using External toolbars, panels or popups. Those External widgets need to be initialized manually on first run before page is loaded.

$(function () {
  $("#ExternalPanel").panel();
});

As for adding listeners, use pagecreate event.

$(document).on("pagecreate", "#pageID", function () {
  $("foo").off("click").on("click", function () {
    /* do something */
  });
});

You need to remove .off() previous bindings and then .on() add them again, since external pages go through pagecreate whenever they are shown. Because jQM removes external pages from DOM once hidden.

One final point on appending elements to active page. You need to be specific as where you want to add those elements retrieved by Ajax.

var activePage = $.mobile.pageContainer.pagecontainer("getActivePage");
$.get("URL", function (data) {
    $("#foo", activePage).html(data).enhanceWithin();
}, "html");

Demo (1) - Code

(1) Click "inbox"

Comments