-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathjquery.mobile.subpage.js
161 lines (127 loc) · 5.69 KB
/
jquery.mobile.subpage.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
* jQuery Mobile Framework SubPage Widget, version 1.4.3
* Copyright(c) Achilles Software.
* Authored by Todd J. Thomson, [email protected]
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Based on the jQuery Mobile "listview" plugin.
* Copyright (c) jQuery Project
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
/*
* Tested with dependent libraries:
* jQuery Mobile version = 1.4.3
*/
/*
* Description
*
* A jQuery Mobile widget that allows subpages to be added to pages.
*
* Usage
*
* Add child divs with data-role="subpage" or data-role="subpage-dialog"
* to a parent div with data-role="page".
*
* Notes
*
* Subpages are detached from parent page and added/removed to/from the DOM.
* The functionality provided by this widget is a workaround for the jQuery Mobile
* loadPage() function which only loads the first page in an AJAX response.
*/
( function( $, undefined ) {
// Keeps track of the number of subpages per parent page UId
var subpageCountPerPage = {};
$.widget( "mobile.subpage", {
options: {
initSelector: ":jqmData(role='subpage'), :jqmData(role='subpage-dialog')"
},
_create: function() {
var self = this;
// Subpages may only be defined with pages dynamically loaded via loadPage().
// Pages loaded this way always have a unique data-url attribute set.
self.parentPage = self.element.closest( ":jqmData(role='page')" );
self.parentPageUrl = self.parentPage.jqmData( "url" );
// Only allow parent page removal based on the subpage widget event handlers
self.preventParentPageRemove = true;
self.element.addClass( function( i, orig ) {
return orig + " ui-subpage ";
} );
self._createSubPage();
},
_createSubPage: function() {
var self = this,
subpage = self.element,
subpageType = subpage.jqmData( "role" );
// Subpages should have an id attribute, but we cannot guarentee this.
// Fallback to the subpage count with the page as the UId
if ( typeof subpageCountPerPage[self.parentPageUrl] === "undefined" ) {
subpageCountPerPage[self.parentPageUrl] = -1;
}
var subpageUId = subpage.attr( "id" ) || ++subpageCountPerPage[self.parentPageUrl];
var subpageUrl = self.parentPageUrl + "&" + $.mobile.subPageUrlKey + "=" + subpageUId;
var newPage = subpage.detach();
newPage
.attr( "data-" + $.mobile.ns + "url", subpageUrl )
.attr( "data-" + $.mobile.ns + "role", 'page' );
// Work-around for dialogs not getting default content theme of "c"
var subpageContent = subpage.find( ":jqmData(role='content')" );
if ( subpageType === "subpage-dialog" && subpageContent.jqmData( "theme" ) === undefined ) {
subpageContent.attr( "data-" + $.mobile.ns + "theme", 'c' );
}
newPage.appendTo( $.mobile.pageContainer );
if ( subpageType === "subpage" ) {
newPage.page();
} else {
newPage.dialog();
}
self._addParentPageSubpage( newPage );
// On subpage parent pagehide.remove event, remove any subpages along with the parent page when navigation is away
// from the parent page to a page that is not a child of the parent page.
if ( !self.parentPage.data( "mobile-page" ).options.domCache &&
self.parentPage.is( ":jqmData(external-page='true')" ) ) {
var parentPageHideRemove = function( e, ui ) {
var nextPage = ui.nextPage, npURL;
if ( ui.nextPage ) {
npURL = nextPage.jqmData( "url" );
var parentUrlBase = self.parentPageUrl + "&" + $.mobile.subPageUrlKey;
var indx = npURL.indexOf( self.parentPageUrl + "&" + $.mobile.subPageUrlKey );
if ( indx < 0 ) {
self._removeParentPageSubpages();
// Allow the parent page to be removed
self.preventParentPageRemove = false;
} else {
// Don't allow the parent page to be removed
self.preventParentPageRemove = true;
}
return;
}
};
var parentPageRemove = function( e ) {
if ( self.preventParentPageRemove ) {
e.preventDefault();
}
};
// Unbind the original page remove and replace with our specialized version
self.parentPage
.off( "pageremove" )
.on( "pageremove", parentPageRemove );
self.parentPage
.unbind( "pagehide.remove" )
.bind( "pagehide.remove", parentPageHideRemove );
}
},
_removeParentPageSubpages: function() {
var $subpages = ( this.parentPage.jqmData( "subpages" ) || $() );
$subpages.remove();
},
_addParentPageSubpage: function( newSubpage ) {
var subpages = this.childPages();
this.parentPage.jqmData( "subpages", $( subpages ).add( newSubpage ) );
},
// API
childPages: function() {
return this.parentPage.jqmData( "subpages" ) || $();
}
} );
} )( jQuery );