How to trigger a JQuery plugin method from within a JQuery .load callback - ajax

I have written a JQuery plugin for some content which is tabbed content on desktop devices and an accordion on mobile devices. I've used the JQuery Boilerplate (https://github.com/jquery-boilerplate/jquery-boilerplate/blob/master/src/jquery.boilerplate.js) as a start point pattern for the plugin file.
I now need to use this plugin on the site within an ajax-loaded modal window. The HTML for the plugin is loading into the modal window fine but the javascript for the plugin is not running.
I believe I need to trigger the init function of my plugin from within the jQuery .load() function which loads the content of the modal window. The function for the ajax overlay looks like this:
menuOverlays = (function(){
var toggleMenuOverlay = function(){
//Toggle a class on the body which triggers styles for the overlay's appearance
$("body").toggleClass('overlay');
//Set the overlay expected to active
var $activeOverlay = $("#"+$(this).data("overlay-element"));
$activeOverlay.toggleClass('active');
//If there is a href on the link that the user clicked on, grab the URL from the link and load the content from that URL into the modal
if($(this).attr("href")){
var urlToLoad = $(this).attr("href") + " #ajaxContent";
$activeOverlay.find(".ajax-content").empty().load(urlToLoad);
}
return false;
};
return{
init: function(){
$("[data-overlay-element]").on("click", toggleMenuOverlay);
}
};
}()),
I have read the following on how to trigger JQuery Boilerplate plugin methods:
Call methods using jQuery Plugin design pattern
and thus tried this:
$activeOverlay.find(".ajax-content").empty().load(urlToLoad, function({
var $t2a = $('.tabs2accordion').tabs2Accordion().data('plugin_tabs2Accordion');
$t2a.init();
});
But I get:
Uncaught TypeError: Cannot read property 'data' of undefined
Any ideas?

Related

jQuery's .load() function breaks modal from opening after .load() completes

I am using jQuery's .load() method and Loading Page Fragments. Below is my current code:
$("#submit").click(function() {
$("#results").load('/ajax/box/ #box');
});
This code is in a moda, which is called when a.ajax-modal is clicked. The problem is that when .load() has completed, the a.ajax-modal in #box that was loaded into #results is not working... it doesn't not open the modal but instead just opens a new page. It seems like the contents of #box are not bound/attached to any event handlers.
Here is an outline of what is happening:
Load page
Click on a.ajax-modal and modal shows
Submit form in modal, run .click() function in modal
Content in #results on page refreshes
Click on new a.ajax-modal that was loaded in #results but modal does not show
Why is the modal not opening after .load() is complete?
No event has been added to your element because events are added when the document is ready. You need to use .on() method of jQuery to prevent this.
$(function()
$(document).on('click', 'a.ajax-modal', function() {
// Your code here.
});
});
So the event is added to document instead of the element itself.

Loading a hidden div into an AJAX jQuery UI tab (future DOM element)

I have been trying to manipulate content that is loaded into jQuery UI tabs via AJAX.
As you can imagine, these elements are "future" DOM elements and aren't manipulated by normal $(".someClass")functions.
I've read using .live() for event handling is now deprecated using jQuery 1.7+ and is replaced by the new .on() method.
My issue is that the div I want to hide, when it loads in an AJAX tab, must be manipulated after the initial DOM load and is not bound to a click event at first.
My functions, which are currently wrapped in $() are below.
I think I have the syntax correct for links that use a click handler, but I'm not sure of the correct way to ".hide()" my "hiddenStory" div at load.
I also think that the functions themselves shouldn't be wrapped in an overall $()?
Any help or advice would be greatly appreciated.
$(function(){
// this .hiddenStory div below is what I want to hide on AJAX load
// need syntax and/or new methods for writing this function
$(".hiddenStory").hide();
// this is a function that allows me to toggle a "read more/read less" area
// on the "hiddenStory" div
$(".showMoreOrLess").on('click', (function() {
if (this.className.indexOf('clicked') != -1 ) {
$(this).removeClass('clicked');
$(this).prev().slideUp(500);
$(this).html("Read More" + "<span class='moreUiIcon'></span>");
}
else {
$(this).addClass('clicked');
$(this).prev().slideDown(500);
$(this).html("See Less" + "<span class='lessUiIcon'></span>");
}
}));
});
// prevents default link behavior
// on BBQ history stated tab panes with
// "showMoreOrLess" links
$('.showMoreOrLess').click(function (event)
{
event.preventDefault();
// here you can also do all sort of things
});
// /prevents default behavior on "showMoreOrLess" links
Could you set the display: none via CSS and override it when you wanted to show the element's content? Another option, if you have to do it this way would be to add the `$(".hiddenStory").hide() in the callback from the AJAX load that is populating the element. For example:
$(".hiddenStory").load("http://myurl.com", function(){
$(".hiddenStory").hide();
}
);
If you aren't using the .load method, you should have some sort of call back to tie into (e.g. success if using $.ajax...)

TinyMCE not working in http request xhr ajax generated page

So i I have a page that contains links that call an httpRequest. The request calls a php file that grabs data from mysql and pre populates a form which is then returned to the browser/webpage. My problem is that when the page is returned to the browser via the httpRequest/ajax the text area does not display the tinymce editor, it just displays a normal text area. It looks like my request and ajax is working fine the text area just doesn't have the tinycme editor on it.
When i don't use ajax it works fine but when i put it in a separate file and call it via ajax it doesn't bring in the tinymce editor.
Does anyone know how to fix this problem so that my ajax generated page displays the text area with the tinymce editor. Thank you.
Lets presume that your thinyMCE instance is initialized with code below
// initialize tinyMCE in page
tinyMCE.init({
mode: "textareas",
theme: "advanced"
});
and you have some kind of button somewhere in the page. For purpose of this tip, i will not give it any ID but you may. Now, using jQuery you can easily attach event handler to that button which will call through AJAX your server and take content which you want to put tinyMCE editor. Code which will do such job would look somehow like below.
$(function() {
$("button").bind("click", function() {
var ed = tinyMCE.get('content');
ed.setProgressState(1); // Show progress
$.getJSON('/page/12.json', { /* your data */
}, function(data) {
ed.setProgressState(0); // Hide progress
ed.setContent(data["body"]);
}
});
});
});
You can see that on button.click ajax will call url /page/12.json which will return JSON as response. bare minimum of that response could be:
{
title: "Page title",
body: "<html><head><title>Page title</title>......</html>"
}
I attached anonymous function as callback which will handle response from server. and hide progress indicator which is shown before ajax call.
About JSON
JSON is shorten of JavaScript Object Notation. It is JavaScript code!!! So don't be confused about it. Using JSON you can make javascript object which can have attributes you can use later in your code to access particular peace of data which that object "holds". You can look at it as some kind of data structure if it is easier to you.
Anyway, to show you how this JSON can be created by hand look at examples below
var data = new Object();
data.title = "Page title";
data.body = "<html....";
or
var data = {
title: "page title",
body: "<html...."
};
it is very same thing.
If you want to learn more about JSON point your browser to http://json.org.
===== alternative =====
Alternative to json solution could be just plane ajax call to server and response can be plain HTML (from your question I can assume that you have something like this already). So instad of calling $.getJSON you can use $.get(url, callback); to do same thing. The code at the top of my answer will not dramatically change. Instead of geting JSON in response you will get string which is HTML.
----------- BOTTOM LINE -------
I prefer JSON since it can be easily extended later with other attributes, so there is no painful code changes later ;)
Problem here will be that when you return the full page and render it using the ajax response, your tinymce instance has not been shut down before.
In order to do this you can call this small piece of code before you render the ajax response:
tinymce.execCommand('mceRemoveControl',true,'editor_id');
In this case the editor should initialize correctly. You are not allowed to initialize a tinymce editor with the same id before shutting the first one down.
Strangely i ran into this problem yesterday. Following code should work, but YMMV. Trick is to use the correct steps in ajax events. I used the Regular TinyMCE and made use of the jQuery library already included.
Following goes into your tinyMCE initialization tinyMCE.init() . All of the below block should be outside the document.ready.
myTinyInit = {
//.......All essential keys/values ...........
setup : function(ed) {
ed.onChange.add(function( ed ) {
tinyMCE.triggerSave();
}) }
//.....................
};
// Init the tinyMCE
tinyMCE.init(myTinyInit);
This ensures the content is being saved regularly onto the textarea that holds the value. Next step is setting up the request events.
Normally tinyMCE mceAddControl before the ajax post and mceRemoveControl after the ajax success should do the trick. But I found that often does not work.
I used the form as the jQuery selector in my case.
jQuery( '.myForm' )
.find( 'textarea#myTextArea' )
.ajaxStart(function() {
// If you need to copy over the values, you can do it here.
// If you are using jQuery form plugin you can bind to form-pre-serialize event instead.
// jQuery( this ).val( tinyMCE.get( jQuery( this ).attr( 'id' )).getContent() );
}).ajaxSend( function() {
// ! - step 2
// My case was multiple editors.
myEds = tinyMCE.editors;
for( edd in myEds ) {
myEds[ eds ].remove();
}
// tinyMCE.get( 'myTextarea' ).remove();
// strangely mceRemoveControl didnt work for me.
// tinyMCE.execCommand( 'mceRemoveControl', false, jQuery( this ).attr('id'));
}).ajaxSuccess(function() {
// Now we got the form again, Let's put up tinyMCE again.
txtID = jQuery( this ).attr( 'id' );
// ! - step 3
tinyMCE.execCommand( 'mceAddControl', false, txtID );
// Restore the contents into TinyMCE.
tinyMCE.get( txtID ).setContent( jQuery( this ).val());
});
Problems i came across :
Using mceRemoveControl always gave me r is undefined error persistently.
If you get a blank tinyMCE editor, check the DOM whether the ID of the textarea is replaced with something like mce_02, this means that TinyMCE is being initialized again or something is wrong with the order. If so, the tinyMCE is duplicated with each save.
if you are new to JS, I recommend using jQuery with the form plugin, it might be easier for you. But do use the regular non-jquery tinyMCE, as it is well documented.
I fixed this problem by recalling the function after the ajax call. In this part of my ajax:
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("Content").innerHTML=xmlhttp.responseText;
tinymce();
Now it works fine.

Jquery in apex 4 Click event help

I have an image that is in my apex application with the id tag of submit_button. I want to display an alert when the user tries to click this image but for some reason nothing is happening. In my header on the page I have this code
<script type="text/javascript">
$(document).ready(function() {
$('#submit_button').click(function) {
alert('hi');
}
});
</script>
Any ideas?
I don't know why that doesn't work (it doesn't work for me either, I just tried), but it is very simple to do via a dynamic action with the following properties:
Event = click
Selection Type = DOM Object
DOM Object = submit_button
"True" Action = Execute Javascript Code
Fire on page load = (unchecked)
Code = alert('hi');

Ajaxed div hide and show hides only after div load

I have this issue. I'm working on a jquery ajaxed site. I have the main content div in the middle and on top the navigation. I need to AJAX the content, because I have flash backgound so that the flash video won't start from beginning after every page load. The only way I was able to do this was with this sort of code:
$(document).ready(function(){
$.ajaxSetup ({
cache: false
});
//For loading
var ajax_load = "<img src='img/load.gif' alt='loading...' /><p>";
// Var
var loadPage1 = "page1.html";
// Load page
$("#page1").click(function(){
$("#content").hide(2000);
$("#content").html(ajax_load).load(loadPage1);
$("#content").show(2000);
});
All other ways to get the div didn't work because there was issues on getting plugins etc. working in the ajaxed div (content).
So... everythig is working fine - but, the div loads it's content from page1.html and shows it and only after this does it hide it and show it. So it loads the page and then does the effects I want to.
Do I need to queue this some how or what's the proper jquery way? I tried delay, stop etc.. but can't seem to solve this out. It's propably very simple.
Thanks.
Show the element in the load callback handler.
i.e:
$("#page1").click(function(){
$("#content").hide();
$("#content").html(ajax_load).load(loadPage1, function(){
$("#content").show(2000)
});
});
.load() takes 2 arguments, the URI and a callback to fire after load.
API is found here: http://api.jquery.com/load/
function() {
$("#content").hide(2000);
$("#content").html(ajax_load).load(loadPage1, function() {
$("#content").show(2000);
});
}

Resources