JQuery and Custom Tabs using addClass & removeClass - jquery-ui

So I am pretty new to JQuery and just spent 5 hours getting this working. If anyone has a better approach please I would love to hear.
That is my basic question how can it be done cleaner, more streamline?
What I did was used the minitabs plugin and what the code below will do is toggle custom tabs back and forth. I needed a way to have the one tab blue and the other gray depending what tab I was on. What I hit against was tab1 would stay blue even when I clicked on tab2, just was funky until this fixed it. As you can see it's not the cleanest approach but it works. I am sure if you want to try this out the minitab plugin can be had here.
http://minitabs.googlecode.com/files/jquery.minitabs.js
JQuery:
$(document).ready(function(){
$("#tabs").minitabs('slow', 'fade');
$("#tab1").click(function()
{
var $this = $(this);
if( $this.is('.removed') )
{
$this.removeClass('removed');
$this.addClass('selected');
$('#tab2').removeClass('selected');
$("#tab2").addClass('removed');
} else {
$('#tab2').removeClass('selected');
}
return false;
});
$("#tab2").click(function()
{
var $this = $(this);
if( $this.is('.removed') )
{
$this.removeClass('removed');
$this.addClass('selected');
$("#tab1").removeClass('selected');
$("#tab1").addClass('removed');
} else {
$('#tab1').removeClass('selected');
}
return false;
});
});
Body:
<div id="tabs">
<ul>
<li>tab-l</li>
<li>tab-r</li>
</ul>
<div id="quick-links">
<ul>
<li>Look at me getting myself all in a frenzy!</li>
</ul>
</div>
<div id="newsletter-link">
Sometimes it's would be nice if they reported the fun news!
</div>
</div>

I looked at this briefly, and didn't see any problems with this less-complex setup which takes advantage of minitabs automatically applying the class "current" to the currently selected tab:
<head>
<style type="text/css">
.tabs a {
background: grey;
}
.tabs a.current {
background: blue;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
$("#tabs").minitabs('slow', 'fade');
});
</script>
</head>
<body>
<div id="tabs">
<ul class="tabs">
<li>tab-l</li>
<li>tab-r</li>
</ul>
<div id="quick-links">
<ul>
<li>Look at me getting myself all in a frenzy!</li>
</ul>
</div>
<div id="newsletter-link">
Sometimes it's would be nice if they reported the fun news!
</div>
</div>
</body>
For me that handles the case you describe perfectly.

Related

Cannot get jqueryui tabs to work properly in Ember view

I'm trying to run up a little prototype in Ember.JS at the moment with a view to completely re-writing the UI of a web application as an Ember Application running against a WebAPI, but although I've managed to get Ember running OK, I cannot get jqueryui to initialise the tabs correctly.
It seems to work fine if within the view I put static data for tabs to be created from, but if I'm using dynamic data then it just doesn't work.
I have an Ember view template
<script type="text/x-handlebars" id="index">
<div id="tabs" class="ui-tabs">
<ul>
{{#each model}}
<li>
<span class="ui-icon ui-icon-person"></span>
<a {{bindAttr href="route"}} {{bindAttr title="tabTitle"}}><span>{{title}}</span></a>
</li>
{{/each}}
</ul>
{{#each model}}
<div {{bindAttr id="tabTitle"}}>
<p>
Retrieving Data - {{title}}
</p>
</div>
{{/each}}
</div>
</script>
and a view
App.IndexView = Ember.View.extend({
templateName: 'index',
didInsertElement: function () {
var tabs = $("#tabs").tabs();
}
});
and a model
App.Section = DS.Model.extend({
name: DS.attr('string'),
title: DS.attr('string'),
tabTitle: function () {
return 'tab-' + this.get('name');
}.property("name"),
route: function () {
return '#' + this.get('tabTitle');
}.property("tabTitle")
});
App.Section.FIXTURES = [
{
id: 1,
name: 'home',
title: 'Home'
},
{
id: 2,
name: 'users',
title: 'Users'
}
];
It appears to generate the HTML correctly (from checking in Firebug), but this does not work, where as if I replace the template with
<script type="text/x-handlebars" id="index">
<div id="tabs" class="ui-tabs">
<ul>
<li>
<span class="ui-icon ui-icon-person"></span>
<span>Home</span>
</li>
<li>
<span class="ui-icon ui-icon-person"></span>
<span>Users</span>
</li>
</ul>
<div id="tab-home">
<p>
Retrieving Data - Home
</p>
</div>
<div id="tab-users">
<p>
Retrieving Data - Users
</p>
</div>
</div>
</script>
it works perfectly.
I'm assuming that it's something to do with the DOM not being completely rendered by the time the tabs are initialised, but everything I can find says that didInsertElement is the place to do it, and I have had time to dig deeper yet.
I'd be grateful for any ideas.
Edit: I've managed to make this work in a fashion by doing the following:
App.IndexView = Ember.View.extend({
templateName: 'index',
didInsertElement: function () {
Ember.run.next(this, function () {
if (this.$('#tab-users').length > 0) {
var tabs = $('#tabs').tabs();
} else {
Ember.run.next(this.didInsertElement);
}
});
},
});
The problem with this is that 1) it requires me to know what one of the last elements that will be written to the view is called (and obviously with dynamic data I won't necessarily know that), so that I can keep checking for it, and 2) the inefficiency of this technique makes me want to scream!
In addition, we get a good old FoUC (Flash of Unstyled Content) after things have been rendered, but before we then get JQueryUI to style them correctly.
Any suggestions gratefully received.
It's still not nice... but this at least does work, and is reasonably efficient...
From Ember.js - Using a Handlebars helper to detect that a subview has rendered I discovered how to write a trigger, and because of the way that the run loop seems to work, inserting the trigger in the last loop on the page causes it to be called n times, but only after the loop is complete, so a quick state check "hasBeenTriggered" ensures that you only execute the delgate function once.
My code now looks like this:
<script type="text/x-handlebars" id="index">
<div id="tabs" class="ui-tabs">
<ul>
{{#each model}}
<li>
<span class="ui-icon ui-icon-person"></span>
<a {{bindAttr href="route"}} {{bindAttr title="tabTitle"}}><span>{{title}}</span></a>
</li>
{{/each}}
</ul>
{{#each model}}
<div {{bindAttr id="tabTitle"}}>
<p>
Retrieving Data - {{title}}
</p>
</div>
{{trigger "triggered"}}
{{/each}}
</div>
</script>
with the trigger
Ember.Handlebars.registerHelper('trigger', function (evtName, options) {
options = arguments[arguments.length - 1];
var hash = options.hash,
view = options.data.view,
target;
view = view.get('concreteView');
if (hash.target) {
target = Ember.Handlebars.get(this, hash.target, options);
} else {
target = view;
}
Ember.run.next(function () {
target.trigger(evtName);
});
});
and view
App.IndexView = Ember.View.extend({
templateName: 'index',
hasBeenTriggered: false,
triggered: function () {
if (!this.get("hasBeenTriggered")) {
var tabs = $('#tabs').tabs();
this.set("hasBeenTriggered", true);
}
}
});
I'd love to know if there's a better way of doing this, as this still doesn't get round the FOUC problem either (which again can be done with more JS hacks)... :(

Jquerymobile - Listview -Ajax loading -CSS style

I am trying to load data using ajax, listview works charm on intialpage load, during ajax loading css is not loading.
nearly tried everything, like listview refresh,trigger etc..but nothing works out for me.
please help me
my code:
$('.more').live("click",function() {
var ID = $(this).attr("id");
var CASE = $(".case").attr("id");
var EXTRADATA = $(".extra_data").attr("id");
if(ID) {
$("#more"+ID).find("#loader").css('display', 'block');
$.ajax({
type: "POST",
url: "/ajax.php",
data: "lastpos=" + ID +"&case=" + CASE + "&extradata=" + EXTRADATA,
cache: false,
success: function(html){
$("#video_listing").append(html);
$("#more"+ID).remove(); // removing old more button
}
});
I had tried with
$('#video_listing').listview('refresh');
$(html).trigger('create');
.trigger( "enhance" );
Nothing works out...though lot of topics,covers this question,nothing worksout for me..please help
Here is a quick example: http://jsfiddle.net/Twisty/9SVPN/
JQuery:
$(document).ready(function() {
$('.more').live("click", function() {
$("#myList").append("<li>Added Item</li>");
$("#myList").listview("refresh");
});
});
HTML:
<html>
<head>
<title>Test</title>
</head>
<body>
<div data-role="page">
<div data-role="header">
<h2>Test Page</h2>
</div>
<div data-role="content">
<ul data-role="listview" id="myList">
<li>Item 1</li>
</ul>
<a id="actionBtn" data-role="button" class="more">Add LI</a>
</div>
</div>
</body>
</html>
Your question does not define what HTML is returned or what your HTML looks like before the AJAX event, so I am making somassumptions that your returned data is wrapped within <li></li>. Then you want to perform the .listview("refresh") on the <ul data-role="listview"> or <ol data-role="listview"> itself.

autodividersSelector of jquery mobile listview not working

I'm trying to use the autodividersSelector option of a jquery-mobile listview as described in the "Autodividers" section of the List views section of the jquery-mobile documentation.
The list renders fine, but no dividers whatsoever. The function assigned to autodividersSelector just never gets called.
There are some other complexities here like jsrender and such, so I'm leaving them intact, but you'll see them below and I don't expect they are part of the problem. What am I missing?
Relevant code below:
<div data-role="page" id="myListPage">
<div data-role="content">
<ul id="myListView"
data-role="listview"
data-autodividers="true"
>
</ul>
</div><!-- /content -->
</div><!-- /page -->
<script type="text/javascript">
$( "#myListPage" ).on("pagebeforecreate", function(event) {
renderTemplates();
});
function renderTemplates() {
var data = {
testItems: [
{name:1},
{name:2},
{name:3},
]
};
$('#myListView').html(
$('#myTemplate').render(data)
);
}
/********** FORMATTING **********/
$("#myListPage").on("pagecreate", function (event) {
console.log("pagecreate");
$("#myListView").listview({
autodividers: true,
autodividersSelector: function (li) {
console.log("autodividersSelector");
var out = "hi"; //var out = $(li).find("h3").text;
return out;
}
});
$("#myListView").listview("refresh");
});
/********** FORMATTING **********/
</script>
<script id="myTemplate" type="text/x-jsrender">
{{for testItems}}
<li><a href="#">
<h3>Name: {{:name}}</h3>
<p>Test: {{:name}}</p>
</a></li>
{{/for}}
</script>
The document you linked to is experimental. You are trying to implement something that isn't quite finished yet. Notice how the url says test.

UI jQuery Tabs - Create More than One Link to Tabs within Tabs on Same Page

My code so far:
$(function(){
$( "#tabs" ).tabs().find( ".ui-tabs-nav" ).sortable({ axis: "x" });
$(document).ready(function() {
var $tabs = $("#tabs").tabs();
$('#tabs-1 a').click( function(){
$tabs.tabs('select', 4); });
});
<div id="tabs">
<ul>
<li>Home</li>
<li>Alarms</li>
<li>Access Control</li>
<li>Services</li>
<li>Contact Us</li>
</ul>
<div id="tabs-1">
<p><span class="bodytext">Check our services</span></p> //want to link to tab 4(services)
<p><span class="bodytext">
Contact usfor free 24hours a day...</span></p>
As you can see from the code when you click on "Contact us" text in tab 1 there is a link to tab 5.
What i want to do is to create a link from "Check our services" to tab 4.
In general to create over 10 links withing tabs linking other tabs
I think i know that i have to change $tabs.tabs('select', 4); to $tabs.tabs('select', id); but i dont know how to call the "id" in html when i want to create my link.
Any suggestions?
I think I would handle this differently using the href on the link itself, perhaps with a class to indicate that it is an intra-tab link, to determine which tab to load and setting up the handlers in the tabs create event.
$('#tabs').tabs({
create: function(event,ui) {
$('a.intra-tab',ui.panel).unbind('click').click( function() {
var id = Number( $(this).attr('href').replace(/#tabs-/,'') ) - 1;
$('#tabs').tabs('select',id);
return false;
});
}
});
<div id="tabs">
<ul>
<li>Home</li>
<li>Alarms</li>
<li>Access Control</li>
<li>Services</li>
<li>Contact Us</li>
</ul>
<div id="tabs-1">
<p><span class="bodytext">Check our services</span></p>
</div>
...
You could also do it using live handlers.
$('#tabs').tabs();
$('a.intra-tab').live( 'click', function() {
var id = Number( $(this).attr('href').replace(/#tabs-/,'') ) - 1;
$('#tabs').tabs('select',id);
return false;
});

JQuery Hover Tip

I am trying to modify the following script to show/hide the Tip only when the "?" is hovered on and not the entire "li" Block
The HTML:
<ul class="tips">
<li>
? Feature 1
<div class="tip">
<h4>Tip Title 1</h4>
<h4>Tip Q</h4>
<p>Tip A</p>
</div>
</li>
<li>
? Feature 2
<div class="tip">
<h4>Tip Title 2</h4>
<h4>Tip Q</h4>
<p>Tip A</p>
</div>
</li>
<li>
? Feature 3
<div class="tip">
<h4>Tip Title 3</h4>
<h4>Tip Q</h4>
<p>Tip A</p>
</div>
</li>
</ul>
The JQuery script
$("ul.tips li").hover(function() {
$(this).find("div").stop()
.fadeIn()
.css("display","block")
}, function() {
$(this).find("div").stop()
.fadeOut()
});
The CSS:
.tips div {
display: none;
position: absolute;
bottom: 0;
width: 100%;
height;auto;
background: #e00;
left:0;
}​​​​​​​​​
I have tried to modify the script like so
$("ul.tips li a").hover(function() {
so it targets the "a" tag but the it ends up not showing anything.
You need to end your lines of js:
$("ul.tips li a").hover(function() {
$(this).siblings("div.tip").stop()
.fadeIn()
.css("display","block"); // <-- gotta put the semi-colon
}, function() {
$(this).siblings("div.tip").stop()
.fadeOut(); //<-- here too
});
That seems unusual as it seems like it should work, but try:
$(".tooltip").hover(function() { ... });
You should also change the $(this).find("div")... to $(this).next()...
You need to make sure that you wrap your event handler in the in jQuery's document ready function:
$(document).ready(function () {
$("ul.tips li").hover(function() {
$(this).find("div").stop()
.fadeIn()
.css("display","block")
}, function() {
$(this).find("div").stop()
.fadeOut()
});
});
Your hover event won't bind to the html elements unless the html elements have been loaded into the DOM tree already. $(document).ready() delays running the JS included in the passed anonymous function until the rest of the html document is loaded and the DOM tree is ready.
More reading at: http://docs.jquery.com/Tutorials:Introducing_$(document).ready()

Resources