requirejs modules does not catch pageinit event - jquery-mobile

I am working on an application using jquery mobile and in the process of re-factoring the app into modules with RequireJS. I have almost completed the task but ran into one a problem which I need a little help with.
I am manually loading my script files (jquery, jqm, knockout etc) and define these libraries as the first thin in my main.js file.
(function(){
var root = this
define('jquery', [], function () { return root.jQuery; });
define('ko', [], function () { return root.ko; });
....
})();
Next I load the jquery mobile plugin and boot the application
....
require([
'Scripts/lib/mobile/jquery.mobile-1.2.0'
], function () {
$(document).on('pageinit' function(){ alert('page init event triggere'); });
boot();
});
My problem is that 'pageinit' event is already triggered by the time requirejs executes factory function, which attaches to the event. Subsequent pageinit events are catched as expected but im missing the initial one when the app first loads. If I move the event binding out of the require module it works fine. Any ideas how I register and handle these jqm events?
Thanks in advance.

I had the same problem and I found that you shouldn't load jquery mobile module as a global dependency, but directly in the core of the function :
require(["jquery"], function($) {
console.log("requireJS loaded");
require(["jquery.mobile"]);
$( document ).on( 'pagecreate pageinit pageshow', '#mappage', function( event ) {
var eventType = event.type;
switch(eventType) {
case 'pagecreate':
console.log("mappage : pagecreate");
break;
case 'pageinit':
console.log("mappage : pageinit");
break;
case 'pageshow':
console.log("mappage : pageshow");
break;
};
});
});

Related

Making offline.js work with turbolinks

I am using offline.js with turbolinks and on initial page load it works fine. But if I click another links then this wont work until I refresh the page. I can see the Offline.state is down but still the view is not showing. Is there any way to manually trigger the popup window?
Update
Other than the offline.js file the only js I have is this
var
$online = $('.online'),
$offline = $('.offline');
Offline.on('confirmed-down', function () {
$online.fadeOut(function () {
$offline.fadeIn();
});
});
Offline.on('confirmed-up', function () {
$offline.fadeOut(function () {
$online.fadeIn();
});
});
This is an old question, but I ran into the same problem, maybe it can help someone.
offline.js creating these dom elements on page load inside the body HTML
<div class="offline-ui offline-ui-up">
<div class="offline-ui-content"></div>
</div>
The reason why offline.js not working after page change is that on-page change the body HTML replaced with the new content returned by the server and the code above removed.
This is how Turbolinks works, so page load will be not triggered and the offline.js dom elements will be not created.
One solution will be to warp the offline.js inside a function and call it on every page change, but it will cause eventually memory leak (as "offline" and "online" event listener will be added to 'window' on each change)
Other solution will be to save the 'offline-ui' HTML before the new page loaded and bring it back after load:
# will fire before page change and save offline.js UI
document.addEventListener("turbolinks:before-render", function() {
if (!document.offlineHtml) {
document.offlineHtml = $('.offline-ui');
}
});
# will fire afterload and will check if there is a UI to append to the body
document.addEventListener("turbolinks:load", function() {
if (document.offlineHtml) {
$(document.body).append(document.offlineHtml);
}
});
At the moment this is the best way that I could find to fix that.
This could be a turbolinks issue. In app/assets/javascripts/application.js, wrap your javascript code within:
$(document).on('turbolinks:load', function() {
// your code
});

Jquery mobile, init bind page events only once

I'm using jquery mobile v1.3.2
For some reasons I want to set an global pagechange event to prepare all of my pages :
var Front = {
initDom : function($dom) {
// here i can bind some events in my page
$(".someButton",$dom).bind("tap",function(){
alert("some actions");
});
// etc.....
});
}
$(document).on("pagechange", function(event, data) {
Front.initDom($(data.toPage));
});
This works well. But it is triggered at each page change. And some times it will init the same event twice and that will lead to some bugs.
Now i have tested to do it with the event pageinit or pagecreate but both are triggered before the page is ready and $("ui-page-active"); is empty.
I have though about some setTimeout, but that's definitively a bad idea.
I have also though to init everything at the first pageinit and unbind it. But ajax called page wont be bound.
It there some good workarround ?
You can use pageinit and then get the id of the page from the event target object:
$(document).on("pageinit", function(e){
alert(e.target.id);
});
DEMO

UI not updating on 'pageinit', probably timing issue

I have the following .js file for my project. This is running in a regular browser, using jquery 1.9.x and jquerymobile 1.3.1. The init function below appears to be running when the page loads and the UI is not updated. Though... I can copy the function into the console and run it, and the UI updates as it is supposed to, so this in not a case of incorrect file paths, or incorrect ids for the UI elements, but I suspect timing. I am also NOT using cordova or phone gap in this instance.
So, my question is, why is the UI not updating when the $(document).bind('pageinit', ...) function is called? If I put a breakpoint in the init method, it is getting called when the page loads. Any suggestions on using a different event or approach?
var simulator = simulator || {};
(function (feedback, $, undefined) { 'use-strict';
feedback.init = function () {
$.get('feedback-config.xml', function (data) {
$('#feedback-to').val($(data).find('email').text());
$('#feedback-subject').val($(data).find('emailSubject').text());
$('#feedback-display').html($(data).find('message').text());
$('#feedback-form').attr('action', $(data).find('serverurl').text()).ajaxForm({success: function () {
alert("Thank you for your feedback!");
}, error: function () {
alert("We're having difficulties sending your feedback, sorry for the inconvenience.");
}});
});
};
}(simulator.feedback = simulator.feedback || {}, jQuery));
$(document).bind('pageinit', function () { 'use strict';
simulator.feedback.init;
});
Thanks in advance.
Found it, simple mistake... In the 'pageinit' function I am calling simulator.feedback.init; instead of simulator.feedback.init(); Not sure why JSLint didn't pick that up initially, but it pointed it out when I tried again later. Thanks.

jquery mobile - event showpage on every page

I need to capture every showpage event on every div with data-role=page in my web application (jquery 1.7.1, jquerymobile 1.1.0) to run a function InitPage();
So in a Global.js, i made this
$(".ui-page").live("pageshow", function () { InitPage(); });
But, i don't know why, on some pages it works, but in others doesn't work.
Any suggestion?
Try this:
$('[data-role=page]').live('pageshow', function (event, ui) { InitPage(); });

Fancybox, getting Fancybox to bind using LIVE() to items being loaded onto the page after load

I have a page that loads and after it loads, it pulls in a list of LIs to populate a news feed.
<li>quick view</li>
<li>quick view</li>
<li>quick view</li>
I'm trying to get fancy box to trigger when a user clicks on quick view but haven't had any luck. Any Ideas?
$(document).ready(function() {
$('.quickview').fancybox();
});
also tried:
$(document).ready(function() {
$('a.quickview').live('click', function() {
$(this).fancybox();
});
});
http://fancybox.net/
Thanks for any ideas...
Old question, but might be useful for future searchers.
My preferred solution is to fire fancybox manually from within the live event, eg:
$('.lightbox').live('click', function() {
$this = $(this);
$.fancybox({
height: '100%',
href: $this.attr('href'),
type: 'iframe',
width: '100%'
});
return false;
});
EDIT: From jQuery 1.7 live() is deprecated and on() should be used instead. See http://api.jquery.com/live/ for more info.
this should work after every ajax request
$(document).ajaxStop(function() {
$("#whatever").fancybox();
});
The problems is to attach fancybox into AJAX loaded element, right?
I got same problems and I found this solution.
I copy paste it here, see the original bug report for more info:
$.fn.fancybox = function(options) {
$(this)
.die('click.fb')
.live('click.fb', function(e) {
$(this).data('fancybox', $.extend({}, options, ($.metadata ? $(this).metadata() : {})))
e.preventDefault();
[...]
Credit goes to jeff.gran.
Since .on is now recommended over .live, and after reading over the documentation on delegated events, here's a solution I came up with (assuming your elements have a class of 'trigger-modal'):
$(document).on('click', '.trigger-modal', function() {
// remove the class to ensure this will only run once
$(this).removeClass('trigger-modal');
// now attach fancybox and click to open it
$(this).fancybox().click();
// prevent default action
return false;
});
From my understanding of Fancybox, the call to fancybox() simple attaches the plugin to the selected element. Calling fancybox on a click event won't open anything.
I think you just need to add
$(li_element_that_you_create).fancybox();
to the code that creates the new LI elements in your list
EDIT
If you're using load, then you would do something like:
$('#ul_id_goes_here').load('source/of/news.feed', function() {
$('.quickview').fancybox();
});

Resources