Dynamically inserted header and footer don't appear - javascript

Hello guys I have one question...
I use JQM 1.4 ... and it sometimes happens that when i click a button an get reddirected (to a new HTML5 file)... on the new page the header and footer are without style... it doesn't happen always but I cant have a page like this...
For the footer and header I use external HTML files (header.html and footer.html) and i call them with
$('#pageprostoriheader').load('header.html').trigger("create");
$('#pageprostorifooter').load('footer.html').trigger("create");
As I said it doesn't happen very often but when it does is ugly ...
I have a multiPage template and i think maybe this is caused because the header and footer don't get loaded quick enough .... so its possible to make like a loader that waits till is everything ready till it shows the page ?

As of jQuery Mobile 1.4, .trigger("create") is deprecated and will be removed on 1.5. Moreover, to create header/footer you should have used .trigger("pagecreate"), however, it is also deprecated and will be removed.
The replacement of the aforementioned functions is .enhanceWthin() to be called on parent element. This issue has several solutuins
Enhance toolbars after successful .load(), using .toolbar().
$('#pageprostoriheader').load('header.html', function () {
$(this).toolbar();
});
$('#pageprostorifooter').load('footer.html', function () {
$(this).toolbar();
});
Enhance toolbars after successful .load(), using .enhanceWithin() on active page.
$('#pageprostoriheader').load('header.html', function () {
$.mobile.pageContainer.pagecontainer("getActivePage").enhanceWithin();
});
$('#pageprostorifooter').load('footer.html', function () {
$.mobile.pageContainer.pagecontainer("getActivePage").enhanceWithin();
});
If you're using the same toolbars on all pages, I recommend using External toolbars.
Add HTML markup of header and footer in <body> not inside page div, and then add the below code in head after jQuery Mobile.js.
$(function () {
$("[data-role=header], [data-role=footer]").toolbar();
});

Related

Javascript In Header Conflict Error - $ is not defined

I have an interesting problem. I'm working on a wordpress/woocommerce child theme. In the header, I have javascript that helps create a loading overlay until everything on the webpage is loaded using document ready to add a class to the overlay element.
$(document).ready(function(){ document.getElementById("page-load").className = "loaded" });
It's not working because of a javascript/jQuery conflict i reckon. I need this script in the header for obvious reasons(loaded asap), but I don't have control over the other scripts in the theme that are mostly in the footer.
How can I prevent the error:
$ is not defined
If it's a matter of waiting for document load you can try:
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("page-load").className = "loaded";
});

Infinite Scroll + Swipe.js

Background:
I'm making a portfolio site utilising both Swipe.js and Infinite Ajax Scroll (JQ).
Problem:
When the content from extra pages is loaded into the current page, it is not processed by the already-loaded Swipe.js script. This means that the new content doesn't have it's mark-up changed (needed for the swipe functionality to work).
I think I need to get the Swipe.js script to fire after each page re-load. Would that fix it? Please explain this to me like I'm an 8yr old. JS is not a strong suit...
Demo:
http://hatchcreative.co.nz/tomo
You can see that as the page loads new content, the buttons on either side of the sliders no longer work.
Yes you're right, after the images are loaded you have to create a new Swipe instance on these new elements (as they weren't there at the beginning, when the page was loaded).
Based on the docs of infinite scroll you can use onRenderComplete.
So you had your jQuery.ias constructor like this:
jQuery.ias({
// ... your settings...
onRenderComplete: function(items) {
$(items).each(function(index, element) {
new Swipe(element);
});
}
});
This should work this way somehow, but I am not exactly sure; I haven't worked with these libraries yet.
Edit:
After some more inspection of your code, I saw you had some inline click handler like: onclick='two.prev();return false;'.
You need to remove this and add your onclick handle in the same onRenderComplete function.
onRenderComplete: function(items) {
var swipe;
$(items).each(function(index, element) {
swipe = new Swipe(element);
});
// find tags with the class 'forward' inside the current element and add the handler
$(element).find('.forward').on('click', function() {
swipe.next();
});
// ... also for previous
}
By the way: Usually you should provide a jsFiddle with your important code parts, so it's easier for us to get the problem, and the question is not getting obsolote when the linked page changes.

How to execute jQuery function after Ajax page load

I'm building Wordpress website where all content pages are loaded using Ajax. This is causing me a problem with jQuery localScroll plugin. This plugin will add animated scroll to all anchor links on the page. Problem is that using script below I'm able to have animation on that page only after one of the links on the page is clicked.
I think I understand why is this happening. My guess is that after I click on the main menu script will execute but since Ajax content is not yet loaded events are not attached to Ajax loaded content links. Now I'm stuck, I have no clue how to fix this. Would you mind helping me with this one?
Thank you in advance.
$(function(){
$('a').live('click', function() {
$('#portfolioWrap').localScroll({// Only the links inside that jquery object will be affected
target: '#portfolioWrap', // The element that gets scrolled
axis:'y', // Horizontal scrolling
duration:1500
});
});
});
EDIT
Just a note to others after I managed to make this work. I tried all suggestions here. My guess is that solutions suggested by o.v. and Ohgodwhy should work, but probably due to website complexity and maybe plugin limitations I wasn't able to make them work. For example .on function didn't work at all although I'm using jQuery 1.7.1. At the end I implemente ajaxComplete suggested by Just_Mad and that worked. Thank you all for your help!
This is the code:
$(function() {
$('#wrapperIn').ajaxComplete(function() {
$('#portfolioWrap').localScroll({
target: '#portfolioWrap', // The element that gets scrolled
axis:'y', // Horizontal scrolling
duration:1500
});
});
});
If you use jQuery.ajax to load AJAX content you can try to bind to ajaxComplete event, to get the moment, when any ajax is complete.
Elaborating on what GoldenNewby said, listen/attach with the .on() method introduced in jQuery 1.7.
$(function(){
$('body').on('click', 'a', function() {
$('#portfolioWrap').localScroll({
target: '#portfolioWrap', // The element that gets scrolled
axis:'y', // Horizontal scrolling
duration:1500
});
});
});
No need to use AJAX for callbacks for listening/binding to elements. The above function will place a click function on all elements found within the body{1} at/after page load. This includes all dynamically created links.
{1} - Change 'body' to whatever Container has the ajax data. I.E. #portfolioWrap
Add a callback to the ajax load, good place to start is at http://api.jquery.com/jQuery.ajax/ under "success callback"
I would have given more specific advice, but your snippet is a bit isolated, maybe if you created a jsfiddle?

jQuery Mobile styles for an asynchronously included div

I'm developing a mobile website using the jQuery Mobile library. I have a header, a footer and a content area on the main page, and any links are loaded into the content area using the following code:
$("a").click(function() {
var toLoad = $(this).attr('href');
// Loading image
$('#content-body').html('<table class="loader"><tr><td><img src="<?php echo SITE_ROOT; ?>/img/ico/loader.gif" /></td></tr></table>');
$('#content-body').load(toLoad);
This works fine, except that the jQuery Mobile styles don't apply to content included this way. For example, the home page includes buttons:
Inventory
But when I load that page asynchronously into the content div, the links do not appear as buttons. Is there any way to tell jQuery Mobile to apply the mobile styles every-time #content is reloaded?
You sure can. You want to use .trigger('create') to initialize any jQuery Mobile widget:
$("a").click(function() {
var toLoad = $(this).attr('href');
// Loading image
$('#content-body').html('<table class="loader"><tr><td><img src="<?php echo SITE_ROOT; ?>/img/ico/loader.gif" /></td></tr></table>');
$('#content-body').load(toLoad, function () {
$(this).trigger('create');//it's that easy :)
});
});
Note that you call .trigger('create') on the parent element of the widget you want to initialize. Also note that since you are loading content through an asynchronous function you will need to call .trigger('create') in the callback function for your .load() call so that the elements to initialize are actually present when you try to initialize them.
Also you can sometimes run into an issue where the widget has been initialized but then you changed it's HTML and want to refresh the widget instead. There are functions to do this such as: .listview('refresh'), .slider('refresh'), etc.
I just answered a question regarding widgets needing to be initialized or refreshed: how to refresh jquery mobile listviews
Also you will want to change that .click() to a .delegate() so the links that are loaded via AJAX will also have this event handler attached:
$('#content-body').delegate('a', 'click', function() {
var toLoad = this.href;//no need to use jQuery here since `this.href` will be available in all major browsers
// Loading image
$('#content-body').html('<table class="loader"><tr><td><img src="<?php echo SITE_ROOT; ?>/img/ico/loader.gif" /></td></tr></table>');
$('#content-body').load(toLoad, function () {
$(this).trigger('create');//it's that easy :)
});
});

Activate jquery ui widgets within dynamically loaded form

What is the best practice of activating jquery ui widgets for html loaded and inserted into the document by ajax?
I am an advocate of unobtrusive javascript and strongly believe that all functionality accessed by javascript should be also accessible without it. So in the ideal case, each form which opens in a popup, should also have its separate page and links to them should be replaced with javascript-based ajax loading.
I find this pattern very useful for loading and inserting a part of another page into the current document:
$('#placeholder').load('/some/path/ #content>*');
Or to make it more generic:
$('a.load').each(function() {
$(this).load($(this).attr('href') + ' #content>*');
});
However, I would also like to activate the javascripts from the dynamically loaded page, so that different widgets function correctly.
I know, I could add those javascripts to the current document and activate all of them in the callback of .load(), or I could use $.get() to get some JSON with html and javascripts separately, but I guess, there might be a more elegant generic solution to this.
What would you recommend?
BTW, I am using Django in the backend.
The question is how you're activating your javascript currently. If you're doing something like:
$(document).ready(function() {
$('a.foo').click(function() { ... });
})
You could consider changin things to:
$(document).ready(function() {
$('a.foo').live('click', function() { ... });
})
That way when new DOM objects are loaded the event handlers are attached.
What I've done is used the "load" option that is specifiable by jquery.ui widgets. Unfortunately, this isn't well documented, so you won't see the option here: http://jqueryui.com/demos/tabs/#options for example, but you will see it here: http://jqueryui.com/demos/tabs/#method-load
For the most part, each of the methods you invoke have an initial option that can be set, which is what prompted me to try using the load.
In my own application, I have 3 levels of nested tabs that are being created dynamically via AJAX. In order to have the javascript for each of the tabs applied dynamically, I have nested load functions that are first initiated when the document is loaded.
So my template file has:
<script type="text/javascript" src="{{ MEDIA_URL }}js/tabs.js"></script>
<script type="text/javascript">
$(function() {
$('.overall_tabs').tabs({
load: initializeOverallTabs
});
});
</script>
My tabs.js file has:
function initializeOverallTabs(event, ui){
...
$('.lvl_two_tabs').tabs({
load: initializeTabLevel2
});
...
}
function initializeTabLevel2(event, ui){
...
// So on and so forth
...
}
Also, I recommend when working inside the loaded areas to make your references be specific to that pane. This was extremely important when working with tabs. The best way I found to do this is below.
In your tabs.js file:
function initializeOverallTabs(event, ui){
$panel = $(ui.panel);
$panel.find('lvl_two_tabs').tabs(...);
}
I found this question strangely coincidental! I recently explained my solution to a few developers to the same situation with the same Jquery/Django Environment. I hope that helped!
One way I decided myself for handling widgets from external pages is parsing the HTML of the other page, searching for scripts and executing them in the current page.
For example, there is a form with autocomplete widget on another page which is loaded and inserted to this page. The autocomplete widget should be activated with specific properties, like available choices:
<script type="text/javascript">
//<![CDATA[
$(function() {
$("#colors").autocomplete({
source: ['red', 'green', 'blue', 'magenta', 'yellow', 'cyan']
});
});
//]]>
</script>
Then in the current page I can have the following script which loads HTML and additionally collects all javascripts within it and executes them:
var oRe = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
$('#placeholder').load(
'/some/path/ #content>*',
function(responseText, textStatus, XMLHttpRequest) { // <-- callback function
var sScripts = "";
responseText.replace(
oRe,
function($0, $1) {
sScripts += $1;
return $0;
}
);
eval(sScripts);
}
);
One drawback here is that the current document should initially be loading all the libraries which might appear in the included forms. For example, in this case, it would be the jquery-ui including the autocomplete widget. I guess I could extend the code by searching for script tags which load external scripts and loading them in the current document if they are not present.

Categories

Resources