UI not updating on 'pageinit', probably timing issue - jquery-mobile

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.

Related

Rails 5 beta Turbolinks events not firing, progress bar not working

I'm kind of new to Rails and web development as a whole.
I'm trying to set up the default progress bar in Turbolinks for rails just like described here.
At first, I thought it might have to do with the fact that the progress bar only shows if a page takes longer than 500ms to load. I tried testing this using sleep 10 in my controller but it doesn't seem to work.
Then I tried debugging the actual turbolink events to see if the callbacks are registering using vanilla js straight in my application.js:
document.addEventListener("turbolinks:load", function () {
console.log("load");
});
document.addEventListener("turbolinks:request-start", function () {
console.log("request start");
});
document.addEventListener("turbolinks:visit", function () {
console.log("visit");
});
document.addEventListener("turbolinks:render", function () {
console.log("render");
});
For some reason, only the turbolinks:load function seems to work.
What am I not seeing or doing wrong?
Thanks.

Rails 4 breaks Stellar.js after link

My rails 4 app breaks stellar.js after link_to.
I know that is something related with turbolinks.
I installed jquery.turbolinks and my js functions from uikit are all working now.
But the stellar.js still don't..
It works when I type the address in browser: 0.0.0.0:3000, but do not after clicking any link.
I am calling stellar.js from my assets/javascripts/my-js.js like this:
$(function(){
$.stellar();
});
I also tried with no success:
function initialize() {
$.stellar();
}
$(document).ready(initialize);
$(document).on('page:load', initialize);
Thank you
Your issue is most certainly related to Turbolinks. I have a feeling that when you call $.stellar() after a Turbolink request, the call has no effect since it's already attached to the window object and that doesn't go away during a the request. Try destroying it prior to initializing it again in the initialize function.
var initialize = function() {
$.stellar( 'destroy' );
$.stellar();
}
$(document).ready( initialize );
$(document).on( 'page:load', initialize );
You can also bind the destroy method to the turbolink before-cache event :
$(document).on "turbolinks:before-cache", ->
$.stellar('destroy')

Why do I lose draggable after drag?

I just migrated to backbone and have a strange behaviour.
I attach draggable to an element which is created by a script, thus not directly available in DOM.
EDIT:
The element that is created is .nav, $("#viewer") as container is already in the DOM.
In plain jQuery i used .on and mousemove event for this and it worked.
With backbone I use the same in the initialize method:
initialize: function(options) {
this.viewer = $("#viewer");
this.viewer.on("mousemove", '.nav', function() {
$(this).draggable();
});
This seems to work, but only one time.
After dragging the element one time, I can't drag it anymore.
Are there conflicts with the events? Am I missing something?
You have to refer to $('#viewer') after you've called render(). initialize is called before render, and so the DOM element doesn't exist.
Also, use this.$('#viewer'), and it will grab the element (after render) even if it hasn't been appended to your page's DOM.
myView = new ExampleView({ model: myModel });
$(body).append(myView.render().el);
myView.onRender();
// -------------
// Now on your view:
onRender: function() {
this.viewer = this.$('#viewer');
this.viewer.on("mousemove", '.nav', function() {
$(this).draggable();
});
},
UPDATE
You can also, to make such things simpler, customize Backbone to automatically call the onRender() function after rendering, by triggering an event or something.
Marionette.js (a Backbone.js extension) has this built in and I use it all the time.
The solution finally was pretty easy:
make sure you dont use outdated versions of backbone.js and underscore!!
After i updated the versions to latest I made it work with:
render: function() {
this.viewer.on("mouseover", '.nav', function() {
if (!$(this).data("init")) {
$(this).data("init", true);
$(this).draggable();
}
});
Probably still not very elegant but i couldnt made the suggested onRender method from dc2 work.

Getting error on $.mobile.changePage(): Uncaught TypeError: Cannot call method 'trigger' of undefined

I have a JQM apps and I am incorporating Backbone.
Since my initial javascript code is huge, I am only extracting what I believe is problematic.
I am following the advices and calls steps cited here:
jqm-config.js from http://coenraets.org/blog/2012/03/using-backbone-js-with-jquery-mobile/
http://jquerymobile.com/test/docs/pages/backbone-require.html
I have a major problem, and this is the behaviour, the problem comes from this code:
var r = Backbone.Router.extend
router: ...
"page": "pageDisplay"
...
pageDisplay: function(){
c = new AView(); // Backbone.View ...fetch() data...
$(c.el).page(); // Call to JQM to add its extra stuff; seems done correctly
$.mobile.changePage( "#" + c.id, {changeHash: false}); // line 50
}
When following the links of <a href="#page" >, I come as expected to the
page "#page" properly processed. But once there, if I click a refresh, which is indirectly reprocessed by the same router rule, I end up with the following error:
Uncaught TypeError: Cannot call method 'trigger' of undefined
I downloaded the jquery mobile development code and observed this:
// JQM1.1.2 - Line #3772 Show a specific page in the page container.
$.mobile.changePage = function( toPage, options ) {
if ( isPageTransitioning ) {
pageTransitionQueue.unshift(arguments );
return;
}
var settings = $.extend( {}, $.mobile.changePage.defaults, options);
// Make sure we have a pageContainer to work with.
settings.pageContainer = settings.pageContainer || $.mobile.pageContainer;
// Make sure we have a fromPage.
settings.fromPage = settings.fromPage || $.mobile.activePage;
// Line #3788
var mpc = settings.pageContainer, // Line #3789
pbcEvent = new $.Event("pagebeforechange" ),
triggerData = { toPage: toPage, options: settings };
// Let listeners know we're about to change the current page.
mpc.trigger( pbcEvent, triggerData ); // Line #3794
The Uncaught TypeError is caused by Line #3794, because mpc is undefined.
So, from JQM, In the Chrome inspector, I can see also that settings.fromPage is undefined and settings.pageContainer is undefined. I kind of imagine, that JQM cannot make an assumption on the fromPage, and therefore, cannot proceed on my refresh. All the options I have tried on the $mobile.changePage() have not succeed. I am out of ideas.
UPDATE/ Online site with the minimum to reproduce the problem:
apartindex, access the website with the bug
Any help will be appreciated.
The dextoInit function that calls the router code is called in $(document).ready() which does not guarantee that the jQuery mobile page has actually been set up successfully. But the router code calls $.mobile.changePage which depends on jQuery Mobile being initialized.
Putting it into mobileinit or pageinit should work.
(Unfortunately I can't modify the code and test it easily.)
Although, this fix it for the moment, it does have drawbacks. See below.
$(document).bind("pageinit", function(){
console.log('bindtomobileinit: event pageinit received');
if ( !window.AppNode.router ){
window.AppNode.router = new AppNode.singletons.router();
console.log("mobileRouter.js: Starting b history");
console.log('mobileRouter.js: About to launch Backbone history');
Backbone.history.start();
}
});
Registering to pageinit has a weird effect of being fired twice. I see that 2 nodes have been added to the Dom: the default "loading" jquery mobile div (related to pageinit:1), and my data-role page (pageinit:2). So on a "refresh browser click", my situation leaves me waiting for a first pageinit, creating an unexpected jquery mobile dom element (a default page created to display the waiting JQM circle animation), which trigger the router creation, and allows the Backbone.history call which then deal with my "" home page. The second pageinit do not interfere with the settings since I execute it only once.
I am really disappointed by this setup. I will leave this question for now, since it does sort of work.
I've found the source of the problem to be jquery-mobile version 1.3.0. When I fall back to either JSM 1.2.0 or 1.2.1, the "Uncaught TypeError: Cannot call method 'trigger' of undefined" problem goes away.
BTW, I am not using Backbone.
I had fixed this problem by using method append(), but not html()
$('body').append(view.render().$el);
I was able to resolve this issue by changing the page data property from "data-role" to "data-mobile-page" as what is referenced in line 4042 of jqm 1.3.2
fromPage.data( "mobile-page" )._trigger( "beforehide", null, { nextPage: toPage } );
Setting
$.mobile.autoInitializePage = true;
In your jquery mobile config file, some place like:
$(document).on("mobileinit", function () {...});
May help.

Jquery Mobile pagecreate function never completes

I am using the pagecreate initialization event to call a function which makes an AJAX call to populate a list.
The problem I have is that this event never completes. The page loading message persists.
I've search here and on the Jquery forum, without any luck.
My code looks like this:
$( "#events" ).live( 'pagecreate', function(event) {
// Executed once the page is loaded
var fromDate = new Date(),
toDate = new Date(fromDate.getFullYear(), fromDate.getMonth() + 3, fromDate.getDate());
update(fromDate, toDate);
//alert('done');
});
function update(from, to) {
var eventList = $('ul#event-list');
$.ajax({
url: 'events.php',
dataType: 'json',
data: {from: from, to: to},
success: function(data) {
showEvents(data, from, to, eventList); // Create list items and append to eventList
$('.value h2').formatCurrency({ negativeFormat: "-%s%n" }); // Format currency correctly using jQuery plugin
}
});
}
I get an "a.Deferred is not a function" error, which suggests to me it has something to do with the completion of the AJAX call, but I've checked, and the showEvents function is correctly creating the list items, so it's not hanging.
After reading this, I tried alternative initialization events: pageinit, and even changePage, without success.
Thanks for your help.
p.s. in case it helps, uncommenting that alert() gets the updated list to reformat correctly, without solving the problem. I figure I'd mention it, since I obviously don't understand what's going on.
If u want to run
the code only once when your project loaded then use
mobileinit. pageshow for every view of page and pagecreate for first
time when pagecreate in your project.

Resources