Reload Ajax Tab with jquery UI 1.9+ - jquery-ui

While their are plenty of posts regarding reloading a jQueryUI tab via the load method, I can't seem to make it work in 1.9+. I wish I could see a way to show this in a fiddle, but as I don't... note that the refresh button/function works every time in the following nested tabs set-up under 1.8+ but works only once under 1.9+, and fails after that. In context, (loading dynamic content via php under wordpress) it doesn't work at all. According to the ajaxStart()ajaxStop() function calls, an ajax call is made every time the refresh button is clicked, however the content (watch the date/time under tab E or tab A/sub parent E) is only reloaded on the first click of the #refresh button, which fails to re-load the tab content on subsequent clicks.
stye.css
div.clear { clear:both; }
#refresh { position: relative; top:-40px; left:300px; }
#loading
{ display:none;
position: absolute;
top:100px;
left:300px;
font-size: 200%;
z-index:1001;
border:3px solid green;
background:#ffffff;
}
tabs.js
jQuery(function()
{ set_tabs();
jQuery('body').on("click", "#refresh", function()
{ jQuery('.tabset ul li a').each(function()
{ var link = jQuery(this);
var tab = link.parent();
var tabset = link.closest('div.tabset');
if(tabset.is(':visible') && tab.hasClass('ui-state-active')) index = link.text().replace(/ /g, '_');
});
jQuery(".tabset").tabs( "load" , index );
});
jQuery("#loading").ajaxStart(function() {jQuery(this).show();});
jQuery("#loading").ajaxStop(function(){ jQuery(this).fadeOut(1500); });
});
function set_tabs()
{ jQuery('.tabset').tabs({ cache:true }); }
index.html
<!--script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<link type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/themes/smoothness/jquery-ui.css" rel="stylesheet"-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
<link type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/themes/smoothness/jquery-ui.css" rel="stylesheet">
<script type="text/javascript" src="tabs.js"></script>
<link type="text/css" href="style.css" rel="stylesheet" />
<div id="parentTabSet" class="tabset">
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
</ul>
<input type='button' id='refresh' value='refresh' />
<div id='loading'>Loading...</div>
<div id="A" class="tabset">
<ul>
<li>A_1</li>
<li>A_2</li>
<li>parent E</li>
</ul>
<div id="A_1"><p>A_1 - FOO</p></div>
<div id="A_2"><p>A_2 - BAR</p></div>
</div>
<div id="B"><p>Div B</p></div>
<div id="C"><p>Div C</p></div>
<div id="D"><p>Div D</p></div>
</div>
tabs_e.html
<script>
jQuery( function()
{ set_tabs();
var d = new Date();
jQuery('#E_1 p').text(d);
jQuery('#E_2 p').text(d);
});
</script>
<div class="tabset">
<ul>
<li>E_1</li>
<li>E_2</li>
</ul>
<div id="E_1"><p>E_1 - BAR</p></div>
<div id="E_2" class='clear'><p>E_2 - BAZ</p></div>
</div>

The .live() function has been deprecated for a while now, and support is completely gone in jQuery 1.9+. Use this:
$(document).on("click", "#refresh", function() {
// your current "live" code
});

So it turns out that not only has the cache option been deprecated in 1.9+ it's legacy behavior has been altered such that (if used) the load method will not reload the tab content.
The approach I've come up with is -- I think -- an abomination which I'm hoping some one might provide a cleaner alternative to. (oh pleeeaazzz!) Anyway, FWIW... here's what I came up with.
tabs.js (revisited)
jQuery(function()
{ set_tabs();
jQuery(document).on("click", "#refresh", function()
{ refresh = {};
refresh.tab = true;
jQuery('.tabset ul li a').each(function()
{ var link = jQuery(this);
var tab = link.parent();
var tabset = link.closest('div.tabset');
if(tabset.is(':visible') && tab.hasClass('ui-state-active')) index = link.text().replace(/ /g, '_');
});
jQuery(".tabset").tabs( "load" , index );
});
jQuery("#loading").ajaxStart(function() {jQuery(this).show();});
jQuery("#loading").ajaxStop(function(){ jQuery(this).fadeOut(1500); });
});
function set_tabs()
{ jQuery('.tabset').tabs(
{ beforeLoad: function( event, ui)
{ if(typeof refresh.tab =='undefined')
{ if ( ui.tab.data( "loaded" ))
{ event.preventDefault();
return;
}
ui.jqXHR.success(function() { ui.tab.data( "loaded", true );});
} else refresh={};
}
});
}

Related

jquery ui (v1.8.20) dialog - destroy not remove added ui element and not return the element back to its original position

From what I read, the $(#selector).dialog("destroy") is supposed to remove all the added jquery ui elements and return the element, the dialog attached to, back to its original DOM position. I wrote a test html and it is not doing either. In firebug, after I clicked close, it simply makes it becomes invisible (display:none). Am I doing something wrong? Below is my test html:
<html>
<head>
<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type" />
<style type="text/css">
.modalDialogPopup {
display:none;
border:1px solid #4f8cc5;
}
</style>
<script src="/resources/default/1_0/js/jquery.js?v=081814" type="text/javascript" ></script>
<script src="/resources/default/1_0/js/jquery-ui-1.8.20.custom.min.js?v=081814" type="text/javascript" ></script>
<script>
var testPopUp = {
popUpID : '#testPopUp',
close:
function() {
$(this.popUpID).dialog("close");
},
open:
function() {
$(this.popUpID).dialog({
modal: true,
autoOpen: false,
title: 'Test Outer Pop Up',
dialogClass:'modalDialogPopup',
resizable: true,
close: function( event, ui ) {
$(this.popUpID).dialog( "destroy" );
alert('outer Pop Up Destroyed? '+$(testPopUp.popUpID).attr("class"));
}
});
$(this.popUpID).dialog("open");
}
}
$(document).ready(function() {
});
</script>
</head>
<body>
<div id="OuterDiv">
<a href="javascript:void(0)" onclick="testPopUp.open(); return false;" >Open PopUp</a>
<div id="testPopUp" class="modalDialogPopup">
<div id="testPopUpDiv" style="overflow: auto; display: table;">
<div id="testPopUpContent" >
This is a Pop Up Test
<br/>
<br/>
<a href="javascript:void(0)" onclick="testPopUp.close(); return false;" >Close PopUp</a>
</div>
</div>
</div>
</div>
</body>
</html>
Found two problems that cause the destroy to not working:
1) on this line ==>
close: function( event, ui ) {$(this.popUpID).dialog( "destroy" );
I shouldn't use this.popUpID. It should be testPopUp.popUpID, like below,
close: function( event, ui ) {$(testPopUp.popUpID).dialog( "destroy" );
Once I did that, it starts to remove all the added jquery ui elements. But it still does not put the element (id="testPopUp") back to it's original DOM position, which is resolved after I done #2 below.
2) Change my jquery ui version to jquery-ui-1.10.4.custom.min.js.

html2canvas take screenshot of DIV element?

I am trying to make div element screenshot, but combined with draggable jQuery, and have no luck, I can take screenshot of div and save it like png, but if I drag some elements on that div and then save screenshot I get only what is inside that div and draggable elements over that div? Any idea, this mine code so far
<script type="text/javascript" src="js/html2canvas.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script language="javascript">
$(document).ready(function() {
$("#myBtn").click(function () {
html2canvas($("#chartDiv"), {
onrendered: function (canvas) {
var imgSrc = canvas.toDataURL();
$("#myDiv").html('').show();
var url = "ajax.php";
$.post(url, {contentVar: imgSrc} ,function(data) {
$("#myDiv").html(data).show();
});
}
});
});
});
</script>
<script>
$(function() {
$( ".draggable" ).draggable();
});
</script>
I am using AJAX to save image and present in new element
AJAX.PHP
$contentVar = $_POST['contentVar'];
$filteredData=substr($_POST['contentVar'], strpos($_POST['contentVar'], ",")+1);
//Decode the string
$unencodedData=base64_decode($filteredData);
//Save the image
file_put_contents('img.png', $unencodedData);
echo "<img src="img.png">";
And here is the HTML:
<div id="chartDiv"><img src="img/assets/logo.png"></div>
<button id="myBtn">Create image</button>
<div id="myDiv"></div>
<img src="img/assets/logo.png" class="draggable" />
<img src="img/assets/logo.png" class="draggable" />
Why not disable the the draggalbe elements before taking the screenshot, then re-enabling them. This will remove the jquery_ui draggable elements and css.

jQuery Mobile changePage with swipe transition

I can't seem to make the "reverse" slide effect while handling the "swiperight" event. So, the code below works fine but I would like when I make the "swiperight" that the next page would slide in from the left side and not right hand side. I did search the documentation and added the reverse: true as as it recomends in to the "swiperight":
$.mobile.changePage("#page"+nextPage, {transition : "slide", reverse:true});
but this does not provide the wanted effect. Can you point out where am I doing it wrong?
I have the following code on jsFiddle:
html:
<!DOCTYPE html>
<html>
<head>
<title>jQuery Mobile Application</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
<script src="http://code.jquery.com/jquery-1.5.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
</head>
<body>
<section id="page1" data-role="page">
<header data-role="header"><h1>jQuery Mobile</h1></header>
<div data-role="content" class="content">
<p>First page!</p>
</div>
<footer data-role="footer"><h1>O'Reilly</h1></footer>
</section>
<section id="page2" data-role="page">
<header data-role="header"><h1>jQuery Mobile</h1></header>
<div data-role="content" class="content">
<p>Second page!</p>
</div>
<footer data-role="footer"r><h1>O'Reilly</h1></footer>
</section>
<section id="page3" data-role="page">
<header data-role="header"><h1>jQuery Mobile</h1></header>
<div data-role="content" class="content">
<p>Third page!</p>
</div>
<footer data-role="footer"><h1>O'Reilly</h1></footer>
</section>
</body>
</html>​
jQuery:
(function($) {
var methods = {
init : function(options) {
var settings = {
callback: function() {}
};
if ( options ) {
$.extend( settings, options );
}
$(":jqmData(role='page')").each(function() {
$(this).bind("swiperight", function() {
var nextPage = parseInt($(this).attr("id").split("page")[1]) - 1;
if (nextPage === 0)
nextPage = 3;
$.mobile.changePage("#page"+nextPage, "slide");
});
$(this).bind("swipeleft", function() {
var nextPage = parseInt($(this).attr("id").split("page")[1]) +1;
if (nextPage === 4)
nextPage = 1;
$.mobile.changePage("#page"+nextPage, "slide");
});
})
}
}
$.fn.initApp = function(method) {
if ( methods[method] ) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
}
else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
}
else {
$.error( 'Method ' + method + ' does not exist' );
}
}
})(jQuery);
$(document).ready(function(){
$().initApp();
});
​
OK first off you're using a Alpha version of jQM and the docs you are referring to a for jQM 1.1.1. I've updated your jsfiddle to use the latest jQM 1.2
http://jsfiddle.net/GYAB7/2/
And I've added the correct syntax for the reverse swipe transition
$.mobile.changePage("#page"+nextPage, {
transition: "slide",
reverse: false
});
});
and the reverse transition
$.mobile.changePage("#page"+nextPage, {
transition: "slide",
reverse: true
});
});

jQuery href behavior (waiting on a form completion from href link)

As you can see below.. I would like to embed a simple HTML form in a hidden DIV.. I would like to SHOW that div on click.. Folding out the DIV and allowing the user to complete the form.. Once the Form Submit happens.. I would like to resume the action i.e. proceed to google.com
I'm stuck on the slide out and redirect behavior.. (is it possible to force the toggle open until form completion is successful?)
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
body{
font-family:Verdana, Geneva, sans-serif;
font-size:14px;}
.slidingDiv {
height:300px;
background-color: #99CCFF;
padding:20px;
margin-top:10px;
border-bottom:5px solid #3399FF;
}
.show_hide {
display:none;
}
</style>
</head>
<body>
<div id="container">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".slidingDiv").hide();
$(".show_hide").show();
$('.show_hide').click(function(){
$(".slidingDiv").slideToggle();
});
});
</script>
check out google.com!<br />
<div class="slidingDiv">
<form>
some form... AJAX post
</form>
</div>
</div>
</body>
</html>
So you're looking for a link that triggers a form, and then after that form is submitted, to proceed with the link?
You need to disable the default behavior of the link and cache the URL. Then slide open the form and allow the user to do whatever. When the user submits the form (which is either a "Are you sure you want to leave?" question or a collection form processed with with AJAX) you then proceed with the link.
You want something to the effect of (on http://jsfiddle.net/Sb6CD/ too):
CSS:
body{
font-family:Verdana, Geneva, sans-serif;
font-size:14px;
}
.slidingDiv {
display:none;
height:300px;
background-color: #99CCFF;
padding:20px;
margin-top:10px;
border-bottom:5px solid #3399FF;
}
JS:
$(document).ready(function(){
$('a.show_hide').click(function(e){
e.preventDefault();
e.stopImmediatePropagation();
var url = $(this).attr('href');
$('.slidingDiv').slideDown();
$('form').submit(function() {
document.location = url;
return false;
})
});
});
I think I got your question. You want to follow the link only after the toggle is done sliding.. right?
This should be done like this:
<script type="text/javascript">
$(document).ready(function(){
$(".slidingDiv").hide();
$(".show_hide").show();
$('.show_hide').click(function(){
var el_link = $(this);
$(".slidingDiv").slideToggle(1000, function() {
document.location.href = el_link.attr('href');
});
return false;
});
});
</script>
Or something like this...

jquery-ui .tabs ajax load specific content of page?

I'm trying to use jQuery UI's .tabs() to obtain content via AJAX, but the default behavior is to grab the entire page's content. How would I obtain content from a specific #id and/or multiple #id's?
I have a feeling I will need to use the load: event (http://docs.jquery.com/UI/Tabs#event-load), but I need an assist figuring this out.
Example:
The Page with the tabs that is getting and displaying the tabbed content. I have placed #content after the first #the_tabs link to retrieve in an attempt to obtain that specific region of the content, but the entire page is still loaded.
<div id="tabs">
<div id="tabs_display">
</div>
<ul id="the_tabs">
<li><span>1</span></li>
<li><span>2</span></li>
<li><span>3</span></li>
<li><span>4</span></li>
</ul>
</div><!-- /#tabs -->
The page being retrieved by the previous markup:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Remote HTML Page Example</title>
</head>
<body>
<div id="content">
I want this content
</div>
<div id="other_stuff">
Not this content
</div>
</body>
</html>
the JS (for setup purposes):
$(document).ready(function(){
/* Tabs
--------------------*/
$(function() {
var $tabs = $('#tabs').tabs({
});
});
});
In Jquery-UI 1.9, "ajaxOptions" is depreciated; so instead the code below worked for me:
(ref: http://jqueryui.com/upgrade-guide/1.9/#deprecated-ajaxoptions-and-cache-options-added-beforeload-event)
$(function() {
$( "#the_tabs" ).tabs({
beforeLoad: function( event, ui ) {
ui.ajaxSettings.dataType = 'html';
ui.ajaxSettings.dataFilter = function(data) {
return $(data).filter("#content").html();
};
}
});
});
$(document).ready(function(){
/* Tabs
--------------------*/
var $tabs = $('#the_tabs').tabs({
ajaxOptions: {
dataFilter: function(data, type){
return $(data).filter("#content").html();
}
}
});
});
Solution props to Supavisah in #jquery on irc.freenode.net
I have had luck using .find, rather than .filter. Like this:
$(document).ready(function(){
$('#the_tabs').tabs({
ajaxOptions: {
cache : true,
dataFilter: function(data){
return $(data).find('#content');
},
}
});
});

Resources