6
6
* Revealing Module Pattern from
7
7
* http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/
8
8
*
9
- * Bootstrap popover variable width workaround
9
+ * Bootstrap popover variable width
10
10
* http://stackoverflow.com/questions/10028218/twitter-bootstrap-popovers-multiple-widths-and-other-css-properties
11
- *
12
- * Lisence : MIT . See accompanied LICENSE file.
11
+ *
13
12
*/
14
13
15
14
$ ( document ) . ready ( function ( ) {
@@ -21,37 +20,110 @@ $(document).ready(function(){
21
20
var activeIndex = null ; //index of active item
22
21
23
22
var defaults = {
24
- nextButton : '<button class="btn btn-primary btn-mini bootstro-next-btn">Next »</button>' ,
25
- prevButton : '<button class="btn btn-primary btn-mini bootstro-prev-btn">« Prev</button>' ,
26
- finishButton : '<button class="btn btn-mini btn-success bootstro-finish-btn" type="button"><i class="icon-ok"></i> Ok I got it, get back to the site</button>' ,
23
+ nextButtonText : 'Next »' , //will be wrapped with button as below
24
+ //nextButton : '<button class="btn btn-primary btn-mini bootstro-next-btn">Next »</button>',
25
+ prevButtonText : '« Prev' ,
26
+ //prevButton : '<button class="btn btn-primary btn-mini bootstro-prev-btn">« Prev</button>',
27
+ finishButtonText : '<i class="icon-ok"></i> Ok I got it, get back to the site' ,
28
+ //finishButton : '<button class="btn btn-mini btn-success bootstro-finish-btn"><i class="icon-ok"></i> Ok I got it, get back to the site</button>',
27
29
stopOnBackdropClick : true ,
28
- stopOnEsc : true
30
+ stopOnEsc : true ,
31
+
32
+ //onComplete : function(params){} //params = {idx : activeIndex}
33
+ //onExit : function(params){} //params = {idx : activeIndex}
34
+ //onStep : function(params){} //params = {idx : activeIndex, direction : [next|prev]}
35
+ //url : String // ajaxed url to get show data from
36
+
37
+ margin : 100 , //if the currently shown element's margin is less than this value
38
+ // the element should be scrolled so that i can be viewed properly. This is useful
39
+ // for sites which have fixed top/bottom nav bar
29
40
} ;
30
41
var settings ;
31
- var onCompleteFunc ;
32
- var onExitFunc ;
33
- var onStepFunc ;
34
42
35
43
36
44
//===================PRIVATE METHODS======================
45
+ //http://stackoverflow.com/questions/487073/check-if-element-is-visible-after-scrolling
46
+ function is_entirely_visible ( $elem )
47
+ {
48
+ var docViewTop = $ ( window ) . scrollTop ( ) ;
49
+ var docViewBottom = docViewTop + $ ( window ) . height ( ) ;
50
+
51
+ var elemTop = $elem . offset ( ) . top ;
52
+ var elemBottom = elemTop + $elem . height ( ) ;
53
+
54
+ return ( ( elemBottom >= docViewTop ) && ( elemTop <= docViewBottom )
55
+ && ( elemBottom <= docViewBottom ) && ( elemTop >= docViewTop ) ) ;
56
+ }
57
+
37
58
//add the nav buttons to the popover content;
38
59
39
60
function add_nav_btn ( content , i )
40
61
{
41
- count = $elements . size ( ) ;
62
+ var $el = get_element ( i ) ;
63
+ var nextButton , prevButton , finishButton ;
64
+
42
65
content = content + "<div class='bootstro-nav-wrapper'>" ;
66
+ if ( $el . attr ( 'data-bootstro-nextButton' ) )
67
+ {
68
+ nextButton = $el . attr ( 'data-bootstro-nextButton' ) ;
69
+ }
70
+ else if ( $el . attr ( 'data-bootstro-nextButtonText' ) )
71
+ {
72
+ nextButton = '<button class="btn btn-primary btn-mini bootstro-next-btn">' + $el . attr ( 'data-bootstro-nextButtonText' ) + '</button>' ;
73
+ }
74
+ else
75
+ {
76
+ if ( typeof settings . nextButton != 'undefined' /*&& settings.nextButton != ''*/ )
77
+ nextButton = settings . nextButton ;
78
+ else
79
+ nextButton = '<button class="btn btn-primary btn-mini bootstro-next-btn">' + settings . nextButtonText + '</button>' ;
80
+ }
81
+
82
+ if ( $el . attr ( 'data-bootstro-prevButton' ) )
83
+ {
84
+ prevButton = $el . attr ( 'data-bootstro-prevButton' ) ;
85
+ }
86
+ else if ( $el . attr ( 'data-bootstro-prevButtonText' ) )
87
+ {
88
+ prevButton = '<button class="btn btn-primary btn-mini bootstro-prev-btn">' + $el . attr ( 'data-bootstro-prevButtonText' ) + '</button>' ;
89
+ }
90
+ else
91
+ {
92
+ if ( typeof settings . prevButton != 'undefined' /*&& settings.prevButton != ''*/ )
93
+ prevButton = settings . prevButton ;
94
+ else
95
+ prevButton = '<button class="btn btn-primary btn-mini bootstro-prev-btn">' + settings . prevButtonText + '</button>' ;
96
+ }
97
+
98
+ if ( $el . attr ( 'data-bootstro-finishButton' ) )
99
+ {
100
+ finishButton = $el . attr ( 'data-bootstro-finishButton' ) ;
101
+ }
102
+ else if ( $el . attr ( 'data-bootstro-finishButtonText' ) )
103
+ {
104
+ finishButton = '<button class="btn btn-primary btn-mini bootstro-finish-btn">' + $el . attr ( 'data-bootstro-finishButtonText' ) + '</button>' ;
105
+ }
106
+ else
107
+ {
108
+ if ( typeof settings . finishButton != 'undefined' /*&& settings.finishButton != ''*/ )
109
+ finishButton = settings . finishButton ;
110
+ else
111
+ finishButton = '<button class="btn btn-primary btn-mini bootstro-finish-btn">' + settings . finishButtonText + '</button>' ;
112
+ }
113
+
114
+
43
115
if ( count != 1 )
44
116
{
45
117
if ( i == 0 )
46
- content = content + settings . nextButton ;
118
+ content = content + nextButton ;
47
119
else if ( i == count - 1 )
48
- content = content + settings . prevButton ;
120
+ content = content + prevButton ;
49
121
else
50
- content = content + settings . nextButton + settings . prevButton
122
+ content = content + nextButton + prevButton
51
123
}
52
124
content = content + '</div>' ;
53
125
54
- content = content + '<div class="bootstro-finish-btn-wrapper">' + settings . finishButton + '</div>' ;
126
+ content = content + '<div class="bootstro-finish-btn-wrapper">' + finishButton + '</div>' ;
55
127
return content ;
56
128
}
57
129
@@ -79,7 +151,7 @@ $(document).ready(function(){
79
151
get_popup = function ( i )
80
152
{
81
153
var p = { } ;
82
- $el = get_element ( i ) ;
154
+ var $el = get_element ( i ) ;
83
155
//p.selector = selector;
84
156
var t = '' ;
85
157
if ( count > 1 )
@@ -123,10 +195,10 @@ $(document).ready(function(){
123
195
//destroy popover at stack index i
124
196
bootstro . destroy_popover = function ( i )
125
197
{
126
- i = i || 0 ;
198
+ var i = i || 0 ;
127
199
if ( i != 'all' )
128
200
{
129
- $el = get_element ( i ) ; //$elements.eq(i);
201
+ var $el = get_element ( i ) ; //$elements.eq(i);
130
202
$el . popover ( 'destroy' ) . removeClass ( 'bootstro-highlight' ) ;
131
203
}
132
204
/*
@@ -143,83 +215,131 @@ $(document).ready(function(){
143
215
//destroy active popover and remove backdrop
144
216
bootstro . stop = function ( )
145
217
{
146
- //call onExit callback function if needed
147
- if ( this . onExitFunc != undefined ) {
148
- this . onExitFunc . call ( this , { idx : activeIndex } ) ;
149
- }
150
218
bootstro . destroy_popover ( activeIndex ) ;
151
219
bootstro . unbind ( ) ;
152
220
$ ( "div.bootstro-backdrop" ) . remove ( ) ;
221
+ if ( typeof settings . onExit == 'function' )
222
+ settings . onExit . call ( this , { idx : activeIndex } ) ;
153
223
} ;
154
224
155
-
156
225
//go to the popover number idx starting from 0
157
226
bootstro . go_to = function ( idx )
158
227
{
159
- //call onStep callback function if needed
160
- if ( this . onStepFunc != undefined ) {
161
- this . onStepFunc . call ( this , { idx : idx } ) ;
162
- }
163
228
//destroy current popover if any
164
229
bootstro . destroy_popover ( activeIndex ) ;
165
230
if ( count != 0 )
166
231
{
167
- p = get_popup ( idx ) ;
168
- $el = get_element ( idx ) ;
232
+ var p = get_popup ( idx ) ;
233
+ var $el = get_element ( idx ) ;
169
234
170
235
$el . popover ( p ) . popover ( 'show' ) ;
171
236
172
- min = Math . min ( $ ( ".popover.in" ) . offset ( ) . top , $el . offset ( ) . top ) ;
173
- $ ( 'html,body' ) . animate ( {
174
- scrollTop : min - 20 } ,
175
- 'slow' ) ;
237
+ //scroll if neccessary
238
+ var docviewTop = $ ( window ) . scrollTop ( ) ;
239
+ var top = Math . min ( $ ( ".popover.in" ) . offset ( ) . top , $el . offset ( ) . top ) ;
240
+
241
+ //distance between docviewTop & min.
242
+ var topDistance = top - docviewTop ;
243
+
244
+ if ( topDistance < settings . margin ) //the element too up above
245
+ $ ( 'html,body' ) . animate ( {
246
+ scrollTop : top - settings . margin } ,
247
+ 'slow' ) ;
248
+ else if ( ! is_entirely_visible ( $ ( ".popover.in" ) ) || ! is_entirely_visible ( $el ) )
249
+ //the element is too down below
250
+ $ ( 'html,body' ) . animate ( {
251
+ scrollTop : top - settings . margin } ,
252
+ 'slow' ) ;
176
253
// html
177
254
178
255
$el . addClass ( 'bootstro-highlight' ) ;
179
256
activeIndex = idx ;
180
257
}
181
258
} ;
259
+
182
260
bootstro . next = function ( )
183
261
{
184
262
if ( activeIndex + 1 == count )
185
263
{
186
- //call onComplete callback function if needed
187
- if ( this . onCompleteFunc != undefined ) {
188
- this . onCompleteFunc . call ( this , { idx : activeIndex } ) ;
189
- }
264
+ if ( typeof settings . onComplete == 'function' )
265
+ settings . onComplete . call ( this , { idx : activeIndex } ) ; //
190
266
}
191
267
else
268
+ {
192
269
bootstro . go_to ( activeIndex + 1 ) ;
270
+ if ( typeof settings . onStep == 'function' )
271
+ settings . onStep . call ( this , { idx : activeIndex , direction : 'next' } ) ; //
272
+ }
193
273
} ;
194
274
195
275
bootstro . prev = function ( )
196
276
{
197
277
if ( activeIndex == 0 )
198
278
{
199
- alert ( 'At start of intros' ) ;
279
+ /*
280
+ if (typeof settings.onRewind == 'function')
281
+ settings.onRewind.call(this, {idx : activeIndex, direction : 'prev'});//
282
+ */
200
283
}
201
- else
284
+ else
285
+ {
202
286
bootstro . go_to ( activeIndex - 1 ) ;
287
+ if ( typeof settings . onStep == 'function' )
288
+ settings . onStep . call ( this , { idx : activeIndex , direction : 'prev' } ) ; //
289
+ }
203
290
} ;
204
291
205
- bootstro . start = function ( selector , options )
292
+ bootstro . _start = function ( selector )
206
293
{
207
-
208
- settings = $ . extend ( true , { } , defaults ) ; //deep copy
209
- //TODO: if options specifies a URL, get the intro text array from URL
210
- $ . extend ( settings , options || { } ) ;
211
-
212
294
selector = selector || '.bootstro' ;
295
+
213
296
$elements = $ ( selector ) ;
214
297
count = $elements . size ( ) ;
215
-
216
- if ( $ ( 'div.bootstro-backdrop' ) . length === 0 )
298
+ if ( count > 0 && $ ( 'div.bootstro-backdrop' ) . length === 0 )
217
299
{
218
300
// Prevents multiple copies
219
301
$ ( '<div class="bootstro-backdrop"></div>' ) . appendTo ( 'body' ) ;
220
302
bootstro . bind ( ) ;
221
303
bootstro . go_to ( 0 ) ;
222
- }
304
+ }
305
+ } ;
306
+
307
+ bootstro . start = function ( selector , options )
308
+ {
309
+ settings = $ . extend ( true , { } , defaults ) ; //deep copy
310
+ $ . extend ( settings , options || { } ) ;
311
+ //if options specifies a URL, get the intro configuration from URL via ajax
312
+ if ( typeof settings . url != 'undefined' )
313
+ {
314
+ //get config from ajax
315
+ $ . ajax ( {
316
+ url : settings . url ,
317
+ success : function ( data ) {
318
+ if ( data . success )
319
+ {
320
+ //result is an array of {selector:'','title':'','width', ...}
321
+ var popover = data . result ;
322
+ //console.log(popover);
323
+ var selectorArr = [ ] ;
324
+ $ . each ( popover , function ( t , e ) {
325
+ //only deal with the visible element
326
+ //build the selector
327
+ $ . each ( e , function ( j , attr ) {
328
+ $ ( e . selector ) . attr ( 'data-bootstro-' + j , attr ) ;
329
+ } ) ;
330
+ if ( $ ( e . selector ) . is ( ":visible" ) )
331
+ selectorArr . push ( e . selector ) ;
332
+ } ) ;
333
+ selector = selectorArr . join ( "," ) ;
334
+ bootstro . _start ( selector ) ;
335
+ }
336
+ }
337
+ } ) ;
338
+ }
339
+ else
340
+ {
341
+ bootstro . _start ( selector ) ;
342
+ }
223
343
224
344
} ;
225
345
@@ -269,28 +389,7 @@ $(document).ready(function(){
269
389
{
270
390
$ ( "html" ) . unbind ( 'click.bootstro' ) ;
271
391
$ ( document ) . unbind ( 'keydown.bootstro' ) ;
272
- } ;
392
+ }
273
393
274
- bootstro . on_complete = function ( callbackFunction )
275
- {
276
- if ( Object . prototype . toString . call ( callbackFunction ) == '[object Function]' ) {
277
- this . onCompleteFunc = callbackFunction ;
278
- }
279
- } ;
280
-
281
- bootstro . on_exit = function ( callbackFunction )
282
- {
283
- if ( Object . prototype . toString . call ( callbackFunction ) == '[object Function]' ) {
284
- this . onExitFunc = callbackFunction ;
285
- }
286
- } ;
287
-
288
- bootstro . on_step = function ( callbackFunction )
289
- {
290
- if ( Object . prototype . toString . call ( callbackFunction ) == '[object Function]' ) {
291
- this . onStepFunc = callbackFunction ;
292
- }
293
- } ;
294
-
295
394
} ( window . bootstro = window . bootstro || { } , jQuery ) ) ;
296
- } ) ;
395
+ } ) ;
0 commit comments