Jquery tab re-addition - jquery-ui

I am trying to add undo/redo functionality in Jquery tabs. I am able to store and restore li/divs for added/removed tab.
Issue is when I re-add tab to the form, though it is added properly as li and div for that particular tab are present and can be seen. But if I click on that tab 'tabsselect' event is not getting fired. Li and div for tab look in order. But I am not able to figure what is missing.
In my website I am dynamically adding and removing tabs and it is working fine but just readding of once removed tab isnt working
Here is the code for adding tab
var $tabs = $("#tabs").tabs({
tabTemplate: "<li><a href='#{href}'>#{label}</a> <span id='id1' class='ui-icon ui-icon-close'>Remove Tab</span></li>",
add: function (event, ui) {
var tab_content = $tab_content_input.val(); // || "Tab " + tab_counter + " content.";
}
});
Here is the removal code
$("#tabs span.ui-icon-close").live("click", function () {
if (imode == 1) {
var index = $("li", $tabs).index($(this).parent());
if ($tabs.tabs("length") > 1) {
$tabs.tabs("remove", index);
}
}
});
Nothing fancy really. Looking for answers.
Thanks

Try This code out this will give you a nice example to manipulate data in tabs using jquery.
JavaScript
$(document).ready(function(){
var $tabs = $('#tabs').tabs();
var $a = $('<a />').appendTo('body').attr('href','#').html('add new tab').click(function(){
var n = parseInt($tabs.tabs( "length" ),10)+1;
$('body').append('<div id="tabs-'+n+'">content for the tab # '+ n +'</div>');
$tabs.tabs("add",'#tabs-'+n,'Tab #'+n);
return false;
});
$('<a/>').html('<br><br>remove tab').attr('href','#').click(function(){
$tabs.tabs('remove',$tabs.tabs('length')-1);
return false;
}).appendTo('body');
});
HTML
<!DOCTYPE html>
<html>
<head>
<link class="jsbin" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"></link>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
article, aside, figure, footer, header, hgroup,
menu, nav, section { display: block; }
</style>
</head>
<body>
<div id="tabs">
<ul>
<li>Nunc tincidunt</li>
<li>Proin dolor</li>
<li>Aenean lacinia</li>
</ul>
<div id="tabs-1">
<p>Tab 1 content</p>
</div>
<div id="tabs-2">
<p>Tab 2 content</p>
</div>
<div id="tabs-3">
<p>Tab 3 content</p>
</div>
</div>
</body>
</html>
*
Just use the id's of the selected tabs and manipulate data in them. this will allow to add and remove tabs on your page
*
Tab Select Function
$('.ui-tabs-nav').bind('tabsselect', function(event, ui) {
ui.options // options used to intialize this widget
ui.tab // anchor element of the selected (clicked) tab
ui.panel // element, that contains the contents of the selected (clicked) tab
ui.index // zero-based index of the selected (clicked) tab
});
Use ui.index to get the index of the selected tab and then add then manipulate the selected tab .

Related

Navbar content loading all options

I have a navbar in Jquery mobile which have 5 contents, each content have a text right now. The problem is that the first time that I load the page, in the first tab all the content is loaded, and as soon as you start pressing the buttons, the content is loaded normally, as shown in the image below:
Then when I start clicking the buttons the content shows correctly:
Below is the code that I'm using:
Javascript:
<script>
(function($) {
// Before handling a page change...
$(document).bind("pagebeforechange", function(e, data)
{
// If the new page is not being loaded by URL, bail
if (typeof data.toPage !== "string")
{
return;
}
// If the new page has a corresponding navbar link, activate its content div
var url = $.mobile.path.parseUrl(data.toPage);
var $a = $("div[data-role='navbar'] a[href='" + url.hash + "']");
if ($a.length)
{
// Suppress normal page change handling since we're handling it here for this case
e.preventDefault();
}
// If the new page has a navbar, activate the content div for its active item
else
{
$a = $(url.hash + " div[data-role='navbar']").find("a.ui-btn-active");
// Allow normal page change handling to continue in this case so the new page finishes rendering
}
// Show the content div to be activated and hide other content divs for this page
var $content = $($a.attr("href"));
$content.siblings().hide();
$content.show();
});
})(jQuery);
Here is the HTML:
<body>
<div data-role="page">
<div data-role="header">
<div data-role="navbar">
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
</ul>
</div>
</div>
<center>
<div data-role="content">
<div id="oneContent">First</div>
<div id="twoContent">Second</div>
<div id="threeContent">Third</div>
<div id="fourContent">Fourth</div>
<div id="fiveContent">Fifth</div>
</div>
</center>
</div>
</body>
How can avoid the problem of loading all content at first load?
UPDATED TO ANSWER NEW REQUEST BELOW
If you want the first tab to show up by default, set the CSS of them all individually then toggle them into view.
First put this in your <head> or in a linked CSS file:
<style>[data-role=content] > div { display: none; }</style>
Then insert these two lines into your Javascript at the beginning like so:
(function ($) {
$(document).ready(function() {
var path = (window.location.hash) ? window.location.hash : '#oneContent';
$(path).show();
});
$(document).bind("pagebeforechange", function (e, data) {
....
Here's an updated fiddle diddle skittle

Automatically open filtered collapsible set items - Jquery mobile

I've created a a simple page which has a jquery data-filter applied to collapsible set items (please see jsfiddle and code below). The collapsible set items are closed initially.
I want to be able to enter a word into the filter box and have the matching collapsible set items automatically opened when they are returned?
I can't find anything in the docs that will help me. Any ideas?
http://jsfiddle.net/mikewilsonuk/xpaGE/
<head>
<title>JQM latest</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/git/jquery.mobile-git.css">
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.0/jquery.mobile.min.js"></script>
</head>
<body>
<div data-role="page" id="page">
<div data-role="content">
<h1>Collapsible set with search</h1>
<div data-role="collapsible-set" >
<div data-role="listview" data-inset="true" data-filter="true">
<div data-role="collapsible">
<h1>Numero uno</h1>
<div>some text</div>
</div>
<div data-role="collapsible">
<h1>Number two</h1>
<div>some text</div>
</div>
<div data-role="collapsible">
<h1>Numero three <div>Grade: 25% (8th of 128)</div></h1>
<div>some potato</div>
</div>
<div data-role="collapsible">
<h1>Number four</h1>
<div>some text</div>
</div>
</div>
</div>
</div>
</div>
</body>
The filterable widget has an event (filterablefilter - http://api.jquerymobile.com/filterable/#event-filter) you can handle after it is done filtering. For convenience I added an id to your div with a data-filter.
<div id="filterMe" data-role="listview" data-inset="true" data-filter="true">...
Then on pagecreate, I added the event handler:
$(document).on("pagecreate", "#page", function(){
$("#filterMe").on( "filterablefilter", function( event, ui ) {
ui.items.each(function( index ) {
$(this).collapsible("option", "collapsed", $(this).hasClass("ui-screen-hidden")).removeClass("ui-screen-hidden");
});
});
});
The returned UI object is a jQuery object whose items collection is a list of the collapsible objects the filter handled. So using the each() function, you can iterate the list and set the collapsed state based on whether the class ui-screen-hidden has been applied by the filter. After that I remove the ui-screen-hidden class so that none of the items are hidden. If you still want items hidden as well, you can just remove the .removeClass("ui-screen-hidden").
Here is a working FIDDLE
Couldn't finish it, but maybe you can see what I had in mind:
$(document).on('keyup',function(){
var searchtext = $("input[data-type='search']").val();
var $cols = $(document).find('div[data-role='collapsible']');
$.each(cols, function(){
var col = this;
if(col.find(":contains(searchtext)").length() > 0)
{
col.trigger('expand');
}
else{
col.trigger('collapse');
}
});
});
});
Problem is, that keyup fires too fast and jqm collapses filtered collapsibles after the internal fiter() event. maybe you have to set a timeout around the keyup event.

Header back button with forced refreshing

I needed to force refreshing using this technique. When I navigate to a new page jQM correctly adds a back button in my header. But when I go back to the first page the back button incorrectly appears. Is it possible to conditionally create a back button? I have tried manually creating a back button and conditionally hiding it based on a parameter in the URI but it seems that once the button appears I can never hide it again.
Edit:
Here is some code that demonstrates the problem. Not only does it not hide the custom back button when you go back to page 1, but it doesn't hide the "page 1" content when you are on page 2, or visa versa. It seems that once something has been shown it cannot be rehidden.
<html>
<head>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
<script>
var backButtonVar = null;
var page1Var = null;
var page2Var = null;
</script>
</head>
<body>
<div data-role="page" data-add-back-btn="false">
<div data-role="header">
<h1>Test</h1>
<a id="backButton" data-role="button" data-direction="reverse" data-rel="back" data-icon="arrow-l" data-iconpos="left">MyBack</a>
</div>
<div id="page1" data-role="content">
Go to page 2
</div>
<div id="page2" data-role"content">
This is page 2
</div>
<script>
$(document).ready(function() {
jQuery(document).on('pagehide', 'div', function(event, ui) {
var page = jQuery(event.target);
page.remove();
});
backButtonVar = $('#backButton');
page1Var = $('#page1');
page2Var = $('#page2');
// Is this the root?
if (window.location.search == '') {
backButtonVar.hide();
page1Var.show()
page2Var.hide()
} else {
backButtonVar.show();
page1Var.hide()
page2Var.show()
}
});
</script>
</div>
</body>
</html>
Here is the fix. Give the back-button a class backButton. .hide() it if the active page is the home page page1, else .show() it.
Demo
$('.backButton').hide();
$(document).on('pagebeforeshow', function () {
var activePage = $.mobile.activePage;
if (activePage[0].id != 'page1') {
$('.backButton').show();
}
else {
$('.backButton').hide();
}
});
If you have any question, please let me know.

jquery load() will only load the html from the extermal page, no stylesheet or jquery ui

I have two pages. For explanations sake I'll call them page A and Page B. When I open page B in my browser it is rendered with all the styling and jquery ui code working properly, but when I open page B inside of a div in Page A via the load() method, the only thing that renders is the raw html, no styling, no interfaces. What is the problem? Directly below is the code from page B and all the way at the bottom is the code from page A:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script> //jquery ui
<link rel="stylesheet" href="http://spilot.koding.com/lbStyle.css"/> //stylesheet
<script src="http://www.parsecdn.com/js/parse-1.2.2.min.js"></script> //parse database
<script>
$(function(){
var crowd = ' ';
var ageGroup = ' ';
var activity = [];
var scene = [];
var neighborhood = [];
var date = [];
var details = [];
var time = [];
Parse.initialize("ivHLAO7z9ml1bBglUNuPSgcWabXe3UeE2yCgKM2x","gNeGt04lU7xcew893EvbEJ05qqc4POVhBsIBSCVj");
$(".menu").menu({
select: function (event, ui) {
$('.selected', this).removeClass('selected');
var selection = ui.item.addClass('selected').children('a').attr('name'); //add background color to selected menu item and get its attribute name
var choice = ui.item.text(); //get text of menu selection
if(selection == "ageGroup"){
$("#ageGroup").text(choice); //change the text in the first <a> of ageGroup menu to ageGroup selection.
ageGroup = $("#ageGroup").text();
}else{
crowd = selection;
};
} // closes select function
}); // closes menu
$("button").click(function(){
var city = JSON.parse( localStorage.getItem('city') );
var niche = Parse.Object.extend(crowd);
var query = new Parse.Query(niche);
query.equalTo("ageGroup", ageGroup);
query.equalTo("city", city);
//query.include([activity.date.details.location.neighborhood.time])
query.find({
success: function(results) {
for (i = 0; i < results.length; i++){
activity = results[i].get("activity");
scene = results[i].get("location");
neighborhood = results[i].get("neighborhood");
date = results[i].get("date");
details = results[i].get("details");
time = results[i].get("time");
};
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
//alert("working");
}); //closes click()
}); // close function()
</script>
<script>
$(function(){
$( "button" ).button();
});
</script>
</head>
<body>
<div id="div1">
<button>Button label</button>
<div id="div2">
<ul class="menu">
<li>
Age Group
<ul>
<li>18-21</li>
<li>21-30</li>
<li>30-40</li>
<li>40-50</li>
<li>50-60</li>
<li>60-70</li>
<li>70-80</li>
<li>80-90</li>
<li>90-100</li>
</ul>
</li>
</ul>
</div>
<div id="div3">
<ul class="menu" id="menu">
<li><img src="" alt="" /><h2>Academic: Art Studies</h2></li>
<li><img src="" alt="" /><h2>Academic: Literature</h2></li>
<li><img src="" alt="" /><h2>Academic: Social Sciences</h2></li>
<li><img src="" alt="" /><h2>Academic: Physical/Natural Sciences</h2></li>
</ul>
</div>
</div>
</body>
</html>
--------------//PAGE A//--------------
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script>
$(function(){
$("#mainDiv").load("http://myURl.com/find2.html"); //this is where I call load()
});
</script>
</head>
<body>
//this is the div where I want the other page to load
<div id="mainDiv">
</div>
</body>
</html>
since you are loading page "b" into page "a", you need to have all page "b" stylesheets/js in page "a" header.
please note that you are loading a complete html page into page "a", that includes html,header,body and that is not desirable, you should make page "b" a template that only contains the markup you need.
UPDATE:
you are embedding your scripts in the html, that is a bad practice, separate the JS code to different files.
When you include JS code in your file it will run as soon as the page loads, so if you put 'pageb' code in 'pagea' it will run as soon as 'pagea' was loaded and when you load 'pageb' the code will not run again.
You need to put 'pageb' code in a function and call it only after you loaded 'pageb' content.

How to get TabIndex for the current selected tab?

All,
I have nested JQuery UI tabs. I want to implement a reloadTab functionality for a nested tab. Currently the following code has static fragments for nested tabs, but eventually they will have urls, so the tabs can behave as ajax tabs. How can I achieve the reloadTab functionality?
<html>
<head>
<link type="text/css" rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/themes/ui-lightness/jquery-ui.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
$('#tabContainer').tabs({ selected: 0 });
$('#fragment-1').tabs({ selected: 1 });
});
function reloadTab(tabindex)
{
var smalltabs = $('#fragment-1').tabs({cache:false, spinner:'',selected:0});
$('#tabContainer').tabs('load', smalltabs.tabs('option','selected'));
$('#fragment-1').tabs('load', tabindex);
}
</script>
</head>
<body>
<div id="tabContainer">
<ul>
<li><span>TAB1</span></li>
<li><span>TAB2</span></li>
<li><span>TAB3</span></li>
</ul>
<div id="fragment-1">
<ul class="innerNav" >
<li><span>INNERTAB1</span></li>
<li><span>INNERTAB2</span></li>
</ul>
<div id="fragment-1a" class="innerFragment">Content of inner tab 1</div>
<div id="fragment-1b" class="innerFragment">Content of inner tab 2
<br>Reload tab content</div>
</div>
<div id="fragment-2"></div>
<div id="fragment-3"></div>
</div>
</body>
</html>
Thanks
From the docs:
var $tabs = $('#example').tabs();
var selected = $tabs.tabs('option', 'selected'); // => 0
EDIT
I copied your file, and made the following changes:
Change the reload link to look like this:
href="#" id="reload"
(markdown keeps converting my anchor tag to a link)
Change the jquery to this:
$(function() {
$('#tabContainer').tabs({ selected: 0 });
$('#fragment-1').tabs({ selected: 0 });
$('#reload').click(function(){
var $tabs = $('#fragment-1').tabs();
reloadTab($tabs.tabs('option', 'selected'));
});
});
function reloadTab(tabindex) {
//alert(tabindex); //un-comment for proof.
var smalltabs = $('#fragment-1').tabs({cache:false, spinner:'',selected:0});
$('#tabContainer').tabs('load', smalltabs.tabs('option','selected'));
$('#fragment-1').tabs('load', tabindex);
}

Resources