jQuery .ajax() is breaking TinyMCE 3.5.6 - javascript

I've built a simple CMS with multiple layers of jQuery.ajax(), like so:
function navto(destination, pageToEdit, insertInto) {
// use JQuery's ajax method to control main navigation
if (pageToEdit == "undefined") {
var request = $.ajax({
url: destination
});
} else {
var request = $.ajax({
type: "POST",
url: destination,
data: pageToEdit
});
}
request.done(function(msg) {
if (insertInto) { $(insertInto).html( msg ); }
else { $("#mana_content").html( msg ); }
//alert(msg);
});
request.fail(function(jqXHR, textStatus) {
alert( textStatus + ". This page could not be found." );
});
}
For example, index.php uses <li class="child" onclick="navto('inc/edit_pages.php');">Edit Pages</li> to load edit_pages.php into <div id="content"></div>
edit_pages.php uses $(document).on("click", "a.editPage", function(e) { load_page_for_edit(e); return false; }); (where load_page_for_edit() gathers and readies the information to be sent to the navto() function) to send something like edit_page.php?t=template.php&c=contentID
edit_page.php uses those values to look up the info it needs in the corresponding databases and then outputs something like template.php&c=content into its own <div id="page_to_edit"></div>... again, with another navto().
A user can then click on $('.edit_text') elements to un-hide a div with a TinyMCE textarea (called $('#editor')) inside.
The content is captured by var content = $('.edit_text').html()
Here's the problem: when I try to load the content variable into the TinyMCE textarea -- $('#editor').html(content); -- the textarea does not receive it. I can immediately follow this up with alert($('#mana_editor').html());, which outputs the correct content, but with HTML characters made safe (eg, <p> becomes <p&rt;). However, the content does not load into TinyMCE.
I'm guessing that I have an .ajax scope issue? That perhaps jQuery is trying to $('#editor').html(content); to a non-existent #editor on the template.php (recall that the #editor is on edit_page.php)? Any good resources for figuring out multiple layers of .ajax?
Tid-bits, clues, and things I've tried:
All of my jQuery functions are in a functions.js file, except for the TinyMCE init, which is at the end of edit_page.php.
Only index.php links to functions.js
I'm using TinyMCE 3.5.6, jQuery plugin package and jQuery 1.7.2.
I've attempted TinyMCE's pseudo-selector as well ($('textarea:tinymce') instead of $('#editor')), which throws an error in Firebug: "Error: Syntax error, unrecognized expression: tinymce" in jq.min.js (line 4).
After a user makes their changes in TinyMCE, an update button will load the new content into the $('.edit_text') that was clicked. Instead of loading what I type in, it loads the "safe" HTML mentioned above -- as though TinyMCE was bypassed entirely.
If I don't use the whole CMS and start by manually typing `get_page.php?t=template&c=content' into FireFox it works fine.
If I don't load TinyMCE, the jQuery will load the content into the textarea
This guy might be on to something... seems similar, but I'm not sure what his head.js contains, how to implement head.ready();, or if his problem is the same as mine.
This is my first project using Ajax, so I have a lot to learn. Any insights/suggested reading/solutions would be greatly appreciated!

Here's the problem: when I try to load the content variable into the
TinyMCE textarea -- $('#editor').html(content); -- the textarea does
not receive it. I can immediately follow this up with
alert($('#mana_editor').html());, which outputs the correct content,
but with HTML characters made safe (eg, becomes <p&rt;).
However, the content does not load into TinyMCE.
You need to know that tinymce is not equal your textarea.
On initialization of an editor instance the former textarea gets hidden and tinymce creates a contenteditable iframe - the tinymce editor. The former textarea gets updated with the actual content of the editor from time to time (on special events).
So what i think what you want to achieve is to write your content into the editor. To do this addressing the textarea using jQuery won't work (as you found put yourself).
You need to employ the javascript tinymce API here:
tinymce.get('your_former_textarea_id_needs_to_be_here').setContent(content);

Related

how to get actual page load after replacing content by using Jquery replaceWith()

I am working on a project that has a html page that has links to libraries- in addition it dynamically prints part of the page with Jquery replaceWith().
The dynamically printed part includes src to images, etc.
What is happening is the images are not loaded, so the page is not rendering immediately.
I need to somehow get the equivalent of a window.onload event that tells me when the page
has loaded all that stuff, so that I start the code, etc that affects the page.
I have tried tacking it on at the end of the script- that does not seem to work-
any suggestions/ideas anyone?
I have tried window.onload, etc, I am wondering if I attach
$("#content").ready() that would work vs load, or if I have to write a window onload inside the content that is written in by replaceWith(). I have actually tried some of this already and nothing seems to work, but I may be implementing it incorectly.
Thanks!
Note, No html , js appear at original post.
Try below (adjustable) pattern, i.e.g., assign different class to "original content" (.ocontent) , "new content" (.ncontent), check utilizing $.is()
var callback = function (status) {
if (status === false) {
console.log(status);
// new content ready
// do stuff
};
if (status === true) {
console.log(status);
// old content present
// do stuff
};
};
$.when($(".ocontents").replaceWith("<img class=ncontents />"))
.done(function(o) {
callback($("#content *").is(o));
});
jsfiddle http://jsfiddle.net/guest271314/6agJz/
See http://api.jquery.com/is/

shadowbox stops working after jquery function call

I have a shadowbox script. When I load the page everything works fine, but when I call this jquery load function and then try to trigger the shadowbox by clicking on the image, the large image opens in new window instead.
Here's the code:
<link href="CSS/main.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="shadowbox-3.0.3/shadowbox.js"></script>
<script type="text/javascript">
Shadowbox.init();
</script>
<p id="compas"></p>
Any idea why this is happening?
EDIT
So, we finally get the bottom of this. 15 hours after first commenting on this issue, and at least 50 iterations later, we finally have identified what the problem is and how to fix it.
It actually struck me suddenly when I was creating local aaa.html and bbb.html on my server. That was when it hit me that the element nodes for the content that was being replaced was being removed altogether from the DOM when $.load() runs the callback function. So, once the #menu-home content elements were replaced, they were removed from the DOM and no longer had Shadowbox applied to them.
Once I figured this out, it was just a matter of a single web search and I found:
Nabble-Shadowbox - Reinit Shadowbox
Specifically, the response from mjijackson. What he describes is how to "restart" (reinitialize) Shadowbox using:
Shadowbox.clearCache();
Shadowbox.setup();
So once the #menu-home content was reloaded, what needs to happen is the Shadowbox cache needs to be cleared (essentially, shutting it down on the page), then the Shadowbox.setup() is run, which will detect the elements all over again. You don't run the Shadowbox.init() method again either.
I noticed that you had tried to copy/paste the Shadowbox.setup() in after the $.load(), at least sequentially in the code. However, this wasn't going to work, due to the cache clearing that needs to happen first, and primarily because the .clearCache() and .setup() functions need to be run after the $.load() completes (finishes and runs any callbacks). Those two functions need to be run in the $.load() callback handler; otherwise, you're running it's immediately, but the $.load() is asynchronous and will complete at some later time.
I'm going to go over some other changes I made, just so you understand what, why and wherefore.
Note, I'm not sure if you're familiar with <base>, but the following is at the top of the HEAD element:
<base href="http://62.162.170.125/"/>
This just let's me use the resource files on your computer. You'll not want to use this on your actual site more than likely. If you copy/paste, make sure and remove this line.
<div id="menu">
<ul>
<li><a id="menu-home" href="index.html" rel="http://jfcoder.com/test/homecontent.html">Home</a></li>
<li><a id="menu-services" href="services.html" rel="http://jfcoder.com/test/servicescontent.html">Services</a></li>
<li><a id="menu-tour" href="tour.html" rel="http://jfcoder.com/test/tourcontent.html">Tour</a></li>
<li><a id="menulogin" href="login.html">Login</a></li>
</ul>
</div>
Here, you'll notice I have a relative url in the HREF attribute, and a link to some pages on my server. The reason for the links to my server is that I couldn't access your aaa.html and bbb.html files through AJAX due to cross-site scripting limitations. The links to my website should be removed as well.
Now, the reason I'm using the rel attribute here is that I want allow for the links by way of the href attribute to continue to work in case the JS doesn't function correctly or there's some other error. If you have separate files, one for full HTML document and another for just the fragments, this is what you'll want to do. If you can serve both the full document AND the content-only from the linked file, then you probably don't need the rel attribute, but you'll need to manage the request so the server knows how to respond (full document or just the content part).
var boxInitialize = function(){
try {
if (!Shadowbox.initialized) {
Shadowbox.init();
Shadowbox.initialized = true;
} else {
Shadowbox.clearCache();
Shadowbox.setup();
}
} catch(e) {
try {
Shadowbox.init();
} catch(e) {};
}
};
All I've done here is create a central location for the initialization/setup requests. Fairly straightforward. Note, I added the Shadowbox.initialized property so I could keep track of if the Shadowbox.init() had run, which can only be run once. However, keeping it all in one spot is a good idea if possible.
I also created a variable function which can be called either as a regular function:
boxInitialize();
Or as a function reference:
window.onload = boxInitialize; // Note, no () at the end, which execute the function
You'll probably notice I removed the $() and replaced them with jQuery() instead. This can turn into a real nightmare if you end up with an environment with multiple frameworks and libraries competing for $(), so it's best to avoid it. This actually just bit me real good the other day.
Since we have a closure scope within the .ready() callback, we can take advantage of that to save several "private" variables for ow use at different times in the scripts execution.
var $ = jQuery,
$content = jQuery("#content"), // This is "caching" the jQuery selected result
view = '',
detectcachedview = '',
$fragment,
s = Object.prototype.toString,
init;
Note the , at the end of all but the last line. See how I "imported" the $ by making it equal to the jQuery variable, which means you could actually use it in that#.
var loadCallback = function(response, status, xhr){
if (init != '' && s.call(init) == '[object Function]') {
boxInitialize();
}
if (xhr.success()
&& view != ''
&& typeof view == 'string'
&& view.length > 1) {
$fragment = $content.clone(true, true);
cacheContent(view, $fragment);
}
};
This runs when the $.load() completes the process of the AJAX request. Note, the content returned in the request has already been placed on the DOM by the time this runs. Note as well that we're storing the actual cached content in the $content.data(), which should never be removed from the page; only the content underneath it.
var cacheContent = function(key, $data){
if (typeof key == 'string'
&& key.length > 1
&& $data instanceof jQuery) {
$content.data(key, $data.html());
$content.data(detectcachedview, true);
}
};
cacheContent() is one a method you may not want; essentially, if it was already loaded on a previous request, then it will be cached and then directly retrieved instead of initiating another $.load() to get the content from the server. You may not want to do this; if so, just comment out the second if block in the menuLoadContent() function.
var setContent = function(html){
$content.empty().html(html);
if (init != '' && s.call(init) == '[object Function]') {
boxInitialize();
}
};
What this does is first empty the $content element of it's contents/elements, then add the specified string-based markup that we saved earlier by getting the $content.html(). This is what we'll re-add when possible; you can see once the different links have been clicked and loaded, reclicking to get that to redisplay is really quick. Also, if it's the same request as currently loaded, it also will skip running the code altogether.
(We use $content like because it is a reference to a variable containing a jQuery element. I am doing this because it's in a closure-scope, which means it doesn't show up in the global scope, but will be available for things like event handlers.
Look for the inline comments in the code.
var menuLoadContent = function(){
// This is where I cancel the request; we're going to show the same thing
// again, so why not just cancel?
if (view == this.id || !this.rel) {
return false;
}
// I use this in setContent() and loadCallback() functions to detect if
// the Shadowbox needs to be cleared and re-setup. This and code below
// resolve the issue you were having with the compass functionality.
init = this.id == 'menu-home' ? boxInitialize : '';
view = this.id;
detectcachedview = "__" + view;
// This is what blocks the superfluous $.load() calls for content that's
// already been cached.
if ($content.data(detectcachedview) === true) {
setContent($content.data(view));
return false;
}
// Now I have this in two different spots; there's also one up in
// loadCallback(). Why? Because I want to cache the content that
// loaded on the initial page view, so if you try to go back to
// it, you'll just pickup what was sent with the full document.
// Also note I'm cloning $content, and then get it's .html()
// in cacheContent().
$fragment = $content.clone(true, true);
cacheContent(view, $fragment);
// See how I use the loadCallback as a function reference, and omit
// the () so it's not called immediately?
$content.load(this.rel, loadCallback);
// These return false's in this function block the link from navigating
// to it's href URL.
return false;
};
Now, I select the relevant menu items differently. You don't need a separate $.click() declaration for each element; instead, I select the #menu a[rel], which will get each a element in the menu that has a rel="not empty rel attribute". Again, note how I use menuLoadContent here as a function reference.
jQuery("#menu a[rel]").click(menuLoadContent);
Then, at the very bottom, I run the boxInitialize(); to setup Shadowbox.
Let me know if you have any questions.
I think I might be getting to the bottom of this. I think the flaw is the way you're handling the $.load() of the new content when clicking a menu item, coupled with an uncaught exception I saw having to do with an iframe:
Uncaught exception: Unknown player iframe
This Nabble-Shadowbox forum thread deals with this error. I'm actually not getting that anymore, however I think it came up with I clicked on the tour menu item.
Now, what you're doing to load the content for the menu items really doesn't make any sense. You're requesting an entire HTML document, and then selecting just an element with a class="content". The only benefit I can see for doing this is that the page never reloads, but you need to take another approach to how to get and display the data that doesn't involve downloading the entire page through AJAX and then trying to get jQuery to parse out just the part you want.
I believe handling the content loading this way is the root cause of your problem, hence the $.load() toggling of menu views breaks your page in unexpected ways.
Question: Why don't you just link to the actual page and skip all the $.load() fanciness? Speed-wise, it won't make that much of an impact, if any at all. It just doesn't make sense to use AJAX like this, when you could just link them to the same content without issue.
There are two alternatives that would allow you to prevent roundtrip page reloads:
Setup your AJAX calls to only request the .content portion of the markup if you have the ?contentonly=true flag in the URL, not the entire HTML document. This is how it's traditionally done, and is usually relative simple to do if you have a scripting environment.
$(".content").load('index.html?contentonly=true');
Then your server responds only with the content view requested.
Serve all of the content views within the same HTML document, then show as appropriate:
var $content = $('.content');
$content.find('.content-view').hide();
$content.find('#services-content').show();
It doesn't look like you have a whole lot of content to provide, so the initial page load probably won't have that much of an impact with this particular approach. You might have to look into how to preload images, but that's a very well known technique with many quality scripts and tutorials out there.
Either one of these techniques could use the #! (hashbang) technique to load content, although I believe there are some issues with this for search engines. However, here is a link to a simple technique I put together some time ago:
http://jfcoder.com/test/hash.html
Also, this is just a tip, but don't refer to your "content" element with a class, ie, .content. There should only be one content-displaying element in the markup, right? There's not more than one? Use an id="content"; that's what ID attributes are for, to reference a single element. classes are meant to group elements by some characteristic they share, so above when I .hide() the inline content views (see #2), I look for all of the class="content-view" elements, which are all similar (they contain content view markup). But the $content variable should refer to $('#content');. This is descriptive of what the elements are.
This worked for us, we made a site that used vertical tabs and called in the pages with our shadowbox images using jQuery.load
Just give all of your anchor tags the class="sbox" and paste this script in the header.
<script>
Shadowbox.init({
skipSetup:true,
});
$(document).ready(function() {
Shadowbox.setup($('.sbox'));//set up links with class of sbox
$('a.sbox').live('click',function(e){
Shadowbox.open(this);
//Stops loading link
e.preventDefault();
});
});
</script>
Note: we had to put the .sbox class on all our rel="shadowbox" anchors as well as the on the anchor for the tab that called the .load
Thanks to this guy-> http://www.webmuse.co.uk/blog/shadowbox-ajax-and-other-generated-content-with-jquery-and-javascript/
Well, based on Shem's answer, this is my solution.
Every click on specific class, setup and open shadowbox with elements from same class:
jQuery('.sb-gallery a').live('click',function(e){
Shadowbox.setup(jQuery('.sb-gallery a'));
Shadowbox.open(this);
//Stops loading link
e.preventDefault();
});
Thanks to all

Reload? Javascript after Jquery .live/.load

I wanted to load some fragments of external content inside a div, through a menu.
Found "load" and "live", found a tutorial used it = success!
Except, like what's explicit in the documentation, it doesn't load JavaScript.
The thing is, the destination page already loads, inside the header, that same JavaScript, 'cause Wordpress loads it in every page. In this particular page, I'm only using the plugin (nextgen gallery) through the jQuery AJAX call.
So, what I believe is my problem is that I somehow need to alert/reload the JavaScript, right?
And how can I do this?
<script type="text/javascript" charset="utf-8">
jQuery(document).ready(function(){
// ajax pagination
jQuery('#naveg a').live('click', function(){ // if not using wp-page-numbers, change this to correct ID
var link = jQuery(this).attr('href');
// #main is the ID of the outer div wrapping your posts
jQuery('#fora').html('<div class="loading"><h2>Loading...</h2></div>');
// #entries is the ID of the inner div wrapping your posts
jQuery('#fora').load(link+' #dentro')
return false;
});
}); // end ready function
</script>
PS: I've substituted "live" with "on" but didn't work either.
I'm not sure if I understand... your load() command is puling in some Javascript that you want executed? I'm not sure if you can do that. But if you just need to call some JS upon load() completion, you can pass it a function like so:
jQuery('#fora').load(link+' #dentro', function() {
console.log("load completed");
// JS code to be executed...
});
If you want to execute Javascript code included in the loaded page (the page you retrieve via .load()), than you have to use the url-parameter without the "suffixed selector expression". See jQuery documentation for (.load()):
Note: When calling .load() using a URL without a suffixed selector expression, the content is passed to .html() prior to scripts being
removed. This executes the script blocks before they are discarded. If
.load() is however called with a selector expression appended to the
URL, the scripts are stripped out prior to the DOM being updated,
which is why they are never executed. An example of both cases can be
seen below:
Here, any JavaScript loaded into #a as a part of the document will
successfully execute.
$('#a').load('article.html');
However in this case, script blocks in the document being loaded into
#b are stripped out prior to being executed:
$('#b').load('article.html #target');
I think that's your problem (although I have no solution for you, sorry).
Proposal: Maybe you can load the whole page (including the Scripts) and remove (or hide) the parts you don't need?
Cheers.

reinitialize processing.js sketch after ajax request

I would like to refire the styling and processing.js scripts that i linked to in the head so that they display correctly when brought in through an ajax-request. I see where in the ajax request this code needs to be, but i don't know how to tell the code to simply reapply the script. I've seen people using getScript() to do this, but from what i can tell this reloads the script, rather than simply telling it repeat or refire. Do all of the scripts need their own reinitialization? I found the syntax highlighters .highlight() method, but i am yet to get the processing script to load. currently, Processing.loadSketchFromSources($('#processing'), ['mysketch.pde']); does not work. I am using current versions of all libraries. Surprised i haven't been able to find the answer yet, as a lot of people seem to have the same problem. Thanks for your help!
index page:
$(document).ready(function () {
// put all your jQuery here.
//Check if url hash value exists (for bookmark)
$.history.init(pageload);
//highlight the selected link
$('a[href=' + document.location.hash + ']').addClass('selected');
//Search for link with REL set to ajax
$('a[rel=ajax]').live("click",function(){
//grab the full url
var hash = this.href;
//remove the # value
hash = hash.replace(/^.*#/, '');
//for back button
$.history.load(hash);
//clear the selected class and add the class class to the selected link
$('a[rel=ajax]').removeClass('selected');
$(this).addClass('selected');
//hide the content and show the progress bar
//$('#content').hide();
$('#loading').show();
//run the ajax
getPage();
//cancel the anchor tag behaviour
return false;
});
});
function pageload(hash) {
//if hash value exists, run the ajax
if (hash) getPage();
}
function getPage() {
//generate the parameter for the php script
var data = 'page=' + encodeURIComponent(document.location.hash);
$.ajax({
url: "loader.php",
type: "GET",
data: data,
cache: false,
success: function (html) {
//hide the progress bar
$('#loading').hide();
//add the content retrieved from ajax and put it in the #content div
$('#content').html(html);
//display the body with fadeIn transition
$('#content').fadeIn('fast');
//reapply styles?
//apply syntax highlighting. this works
SyntaxHighlighter.highlight();
//relaod processing sketch, currently displays nothing
Processing.loadSketchFromSources($('#processing'), ['mysketch.pde']);
}
});
}
This the ajax-loaded content:
<!--ajax'd content-->
<??>
<h2>code</h2>
<pre class="brush: php">
$last_modified = filemtime("header.php");
echo("last modified: ");
echo(date("m.j.y h:ia", $last_modified));
</pre>
<script type="application/processing">
</script>
<canvas data-processing-sources="mysketch.pde" id="processing">
</canvas>
</div>
</body>
</html>
<??>
So, let's analyze what usually happens when you include an (external or internal) Javascript code: It will automatically execute only the code that is available in the global scope. "Good" scripts will only add one command to the global scope which will then execute the initialization code somewhere in a function/method.
All you need to do is view the external Javascript file and find out what is being executed from the global scope. There is no general answer to that ... some scripts use an object and call its init() method ... but that is totally subject to the imagination of the developer.
If you have javascript that needs to trigger, you MUST add this to the head element:
var head = document.head || document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.innerHTML = "your AJAX-obtained js code";
head.appendChild(script);
The same trick goes for CSS. Add a element to the head with your CSS declarations as innerHTML. So: make sure to preprocess your AJAX response and split out the JavaScript and CSS elements, then add those to the document header. It's probably easier to make your response a JSON object along the lines of:
{
html: "<html>string<goes>here</goes></html>",
scripts: ["url1","url2","url2",...],
style: ...
}
and then parsing that JSON for the html (which you use as innerHTML for a new document.createElement("div") or something, and then append wherever it needs appending), the scripts (which you turn into elements for HEAD insertion) and the style declarations (which you turn into elements for HEAD insertion).
(On a functional note, your example AJAX response looks like it has PHP code in it. I have no idea what you're using it for, but that looks like a bad response)
Just incase anyone stumbles upon this:
If you have processing.js already loaded, simply call Processing.reload() in your AJAX success/complete function.
Perhaps you already have an element with id="processing" on your page. In that case $("#processing") will only return the first one. If that is the case, change the id or use a class instead.
The other option, which I don't recommend, is to use $("[id=processing]"). That will return every element on the page with id="processing". But, don't use it. Use unique ids in your page, or switch to using classes, whichever works best for you.

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