jQuery tabs add more selectors to same function - javascript

I managed to reduce my jquery tabs to this current state where I define tabs ID in variables.
Question: How to modify this code to have more IDs?
For example:
var tabsId = '#tabs1', '#tabs2', ... ;
var containerId = '#tabs-container1', '#tabs-container2', ...
JS:
var containerId = '#tabs-container';
var tabsId = '#tabs';
$(document).ready(function() {
// Preload tab on page load
if ($(tabsId + ' li.current a').length > 0) {
loadTab($(tabsId + ' li.current a'));
}
$(tabsId + ' a').click(function() {
if ($(this).parent().hasClass('current')) {
return false;
}
$(tabsId + ' li.current').removeClass('current');
$(this).parent().addClass('current');
loadTab($(this));
return false;
});
});
function loadTab(tabObj) {
if (!tabObj || !tabObj.length) {
return;
}
$(containerId).addClass('loading');
$(containerId).fadeOut('fast');
$(containerId).load(tabObj.attr('href'), function() {
$(containerId).removeClass('loading');
$(containerId).fadeIn('fast');
});
}
HTML:
<ul class="mytabs" id="tabs">
<li class="current">Tab 1</li>
<li>Tab 2</li>
<li>Tab 3</li>
</ul>
<div class="mytabs-container" id="tabs-container">
Loading. Please Wait...
</div>

Actually, I don't se a single place in your code where you need your tabIds. It works exactly the same if you just remove it.
Unique instances of the .click() event will be added to each a element either way, and you don't have to specify them by ID´s. Here is an example with tabIds removed.
http://jsfiddle.net/c7RHs/
var containerId = '#tabs-container';
$(document).ready(function () {
if ($('li.current a').length > 0) {
loadTab($('li.current a'));
}
$('li a').click(function () {
if ($(this).parent().hasClass('current')) {
return false;
}
$('li.current').removeClass('current');
$(this).parent().addClass('current');
loadTab($(this));
return false;
});
});
function loadTab(tabObj) {
if (!tabObj || !tabObj.length) {
return;
}
$(containerId).addClass('loading');
$(containerId).fadeOut('fast');
$(containerId).load(tabObj.attr('href'), function () {
$(containerId).removeClass('loading');
$(containerId).fadeIn('fast');
});
}
Otherwise, you could make an array of ID´s as suggested in another answer, but I don't think you need it.
Hope it helps!

You could use array's like
var tabIds = {'tab1','tab2'};
Then you can loop over the array elements. An alternative is to use the variables like you mentioned (comma separated) and split them. Then you can loop through them again.
see this thread for an example: Split string with JavaScript

Related

Show a specific element with specific button

HTML:
<nav id="sales-countries">
<ul>
<li>...1...</li>
<li>...2...</li>
<li>...3...</li>
<li>...4...</li>
<li>...5...</li>
<li>...6...</li>
<li>...7...</li>
</ul>
</nav>
<nav class="sales-location">...1...</nav>
<nav class="sales-location">...2...</nav>
<nav class="sales-location">...3...</nav>
<nav class="sales-location">...4...</nav>
<nav class="sales-location">...5...</nav>
<nav class="sales-location">...6...</nav>
<nav class="sales-location">...7...</nav>
Javascript:
$("nav.sales-location").hide();
$("#sales-countries a:eq(0)").click(function() {
$("nav.sales-location").hide();
$("nav.sales-location:eq(0)").show();
});
$("#sales-countries a:eq(1)").click(function() {
$("nav.sales-location").hide();
$("nav.sales-location:eq(1)").show();
});
$("#sales-countries a:eq(2)").click(function() {
$("nav.sales-location").hide();
$("nav.sales-location:eq(2)").show();
});
$("#sales-countries a:eq(3)").click(function() {
$("nav.sales-location").hide();
$("nav.sales-location:eq(3)").show();
});
$("#sales-countries a:eq(4)").click(function() {
$("nav.sales-location").hide();
$("nav.sales-location:eq(4)").show();
});
$("#sales-countries a:eq(5)").click(function() {
$("nav.sales-location").hide();
$("nav.sales-location:eq(5)").show();
});
$("#sales-countries a:eq(6)").click(function() {
$("nav.sales-location").hide();
$("nav.sales-location:eq(6)").show();
});
I need, that element of specific number - button, show an element of specific number.
JavaScript code above have this property and work well, but it is too long.
How I make this property for (for example) one hundred buttons and elements for showing so that JavaScript code was very short?
Between code paragraphs is different in the two numbers only!
You can do it by a common function for every li click and you can show corresponding div by jquery index()
try this:
$("nav.sales-location").hide();
$("#sales-countries ul li").click(function() {
ind = $(this).index();//get the li index
$("nav.sales-location").hide();// hide all divs
$("nav.sales-location:eq("+ind+")").show(); //show corresponding index div
});
live demo
Reduce it to just:
$("nav.sales-location").hide();
$("#sales-countries a").click(function() {
$("nav.sales-location").hide();
$("nav.sales-location:eq("+$(this).index('#sales-countries a')+")").show();
});
jsFiddle example
You can pass a selector to .index() to specify what collection it's relative to.
since you're just showing the same text as the a that's clicked you can grab the value using .text() and pass it to an empty div called .sales-location
$("#sales-countries a").click(function() {
var results = $(this).text();
$(".sales-location").html(results);
});
JSFIDDLE
Try this:
var $locations = $("nav.sales-location").hide();
$("#sales-countries a").click(function () {
$locations.hide().filter(":eq(" + $(this).parent().index() + ")").show();
});
Demo: http://jsfiddle.net/bZLqR/1/
I did something like this kind of recently. This will do it even with Jquery.
var array = [ 1,2,3,4,5 ]
var list = document.getElementById('some-id');
function links(){ // generate links
for (var i in array){
var val = array[i];
var li = document.createELement('li');
li.innerHTML = "<a href='#'>" + val + "</a>"
li.onclick = show;
li.index = i; // save the array index for later
list.appendChild(li);
}
}
function show(e){
var index = e.target.index || -1 ;
var toShow = document.getElementsByClassName('class-name');
// hide all
for (var i in toShow){
toShow[i].style.visibility = 'hidden';
}
// show the one I want.
if (toShow.length < index && index >= 0){
toShow[index].style.visibility = 'visible';
}
}
links(); // build the links.

JQuery get link and add variable depending on nth number

I have a list set up containing links. Before this list is another link, this is the html:
<div class="catItemBody">
<div class="catItemImage">
Link
</div>
<ul class="sigProBetton">
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</div>
<div class="catItemBody">
<div class="catItemImage">
Link
</div>
<ul class="sigProBetton">
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</div>
There are multiple .catItemBody on the page, each containing a unique link.
I also have some jquery which takes the first link (.catItemImage a) and applies it to each of the links in the list. What I am trying to do is modify this link depending on the list items nth number. I have been experimenting with the first link item using the following jQuery:
$(document).ready(function() {
$('.catItemBody').each(function(){
var linkitem = $('.catItemImage a', this).attr('href');
if ($('ul.sigProBetton li').is(':nth-child(1)')){
$('ul.sigProBetton li a', this).attr('href' , linkitem+'?image=1');
} else {
$('ul.sigProBetton li a', this).attr('href' , linkitem);
}
});
});
Eventually I want to build on this so that the link in the first item has the URL variable of ?image=1, then the second will have ?image=2 etc... I need the 'count' to reset so that the list in the next .catItemBody will start again at ?image=1.
At the moment, each link has the variable ?image=1 which is not ideal. I have set up a jsFiddle at http://jsfiddle.net/Dyfe6/.
EDIT
All of your answers seem to work but the problem is that I have more than one .catItemBody on the page, an updated jsfiddle can be found at http://jsfiddle.net/Dyfe6/9/
No need to use nth-child.
I didn't understand if you wanted to reset or not the image count, so here it is not resetted :
$(document).ready(function () {
var count = 0;
$('.catItemBody').each(function () {
var linkitem = $(this).find('.catItemImage a').attr('href');
$(this).find('ul.sigProBetton li').each(function () {
count++;
$(this).find('a').attr('href', linkitem + '?image=' + count);
});
});
});
jsFiddle : http://jsfiddle.net/Dyfe6/11/
And here it is resetted :
$(document).ready(function () {
$('.catItemBody').each(function () {
var linkitem = $(this).find('.catItemImage a').attr('href');
$(this).find('ul.sigProBetton li').each(function (index) {
$(this).find('a').attr('href', linkitem + '?image=' + (index + 1));
});
});
});
http://jsfiddle.net/Dyfe6/12/
This may not be the best way, but I've done it like this:
var pre = $('.catItemImage').children('a').attr('href');
var links = $('.sigProBetton li a'),count=1;
$(links).each(function() {
$(this).attr('href',pre+'?image='+count);
count += 1;
});
use :first-child instead of :nth-child(1)
updated
$(document).ready(function () {
$('.catItemBody').each(function () {
var linkitem = $('.catItemImage a', this).attr('href');
var $this=$(this);
$this.find('ul.sigProBetton li').each(function (index) {
$this.find('a').attr('href', linkitem + '?image=' + (index + 1));
});
});
});
fiddle here
You can leverage the jQuery's index() method. http://api.jquery.com/index/
Here's the update jsFiddle: http://jsfiddle.net/ArtBIT/Dyfe6/4/

.addClass to element adds a styling then removes, how do I fix

I have a code
var prev;
function addClass( classname, element ) {
prev = cn;
var cn = document.getElementById(element);
$(cn).addClass("selected");
}
The element in the dom look like this:
<div class="arrowgreen">
<ul>
<li>Manager</li>
<li>Planner</li>
<li>Administrator</li>
</ul>
</div>
For 'arrowgreen' I have a styling which changes the li styling on rollover and click.
When an element is clicked on, I want to apply the 'selected' classname to the element.
It does this for a split second and then reverts back.
The css looks like
.arrowgreen li a.selected{
color: #26370A;
background-position: 100% -64px;
}
Working jsFiddle Demo
In usage of $ in your code, I see that you are using jQuery.
There is no need to set onclick internally.
Let's jQuery handle it for you:
// wait for dom ready
$(function () {
// when user clicks on elements
$('.arrowgreen li a').on('click', function (e) {
// prevent default the behaviour of link
e.preventDefault();
// remove old `selected` classes from elements
$('.arrowgreen li a').removeClass('selected');
// add class `selected` to current element
$(this).addClass('selected');
});
});
Working JSFiddle
There was an error in your HTML, a " that opened a new string after onclick.
var prev;
function addClass(classname, element) {
var cn = document.getElementById(element);
prev = cn; //does nothing useful really
$(cn).addClass("selected");
}
<div class="arrowgreen">
<ul>
<li>Manager
</li>
<li>Planner
</li>
<li>Administrator
</li>
</ul>
</div>
Remember to include jQuery in your page!
There is a way to do this without jQuery anyway:
function addClass(classname, element) {
var cn = document.getElementById(element);
prev = cn; //does nothing useful really
cn.className += " " + classname;
}
Similar way to do it:
(function ($) {
$('.arrowgreen > ul > li > a').on('click', function (e) {
e.preventDefault();
$(this).addClass('selected').siblings().removeClass('selected');
});
}(jQuery));

how can I fix the error: this.parentNode is null?

I'm developing an app where you can display all monuments and places to be in Ghent (Belgium). There's a fullscreen map on the homepage (programmed in jQuery with Google Maps API v3) and on the lefthand side, there's a list of the items that you can display. Users can choose whether they want the category to be displayed alone, or to be added to the categories that they clicked before.
This is what happens: I load the page, I click a category. Everything works fine. But only if I click spans in the same category. Whenever I click something in another category, firebug throws the error: parent is null (or this.parentNode is null)
I initially tried to do it in jQuery with $(this).parent().html()..., but it gives me a similar error: 'TypeError: parent.html(...) is undefined'.
Here's my code...
HTML
<section class="category transport">
<h1>Transport</h1>
<ul class="clearfix">
<li><span class="category_li">Parkings</span></li>
<li><span class="category_li">Stations</span></li>
</ul>
</section>
JQUERY (HOVER EFFECT)
this is where I add the 'add_on_map' span to the list-items
$('.category ul li').hover(
//mouse-enter
function()
{
if($(this).children('.add_on_map').length == 0)
{
$(this).append(add_marker_sign);
$('.add_on_map').click(showCategory);
}
else
{
$(this).children('.add_on_map').show();
}
},
//mouse-leave
function()
{
$(this).children('.add_on_map').hide();
}
);
JQUERY (CLICK EVENT)
function showCategory(e)
{
var parent = null;
parent = this.parentNode;
var add_marker_sign = '<span class="add_on_map plus"> +</span>';
var remove_marker_sign = '<span class="add_on_map minus"> -</span>';
var element;
var to_removed_marker_sign = parent.innerHTML.replace(add_marker_sign, remove_marker_sign);
var to_add_marker_sign = parent.innerHTML.replace(remove_marker_sign, add_marker_sign);
//User clicks span -> If you click on the word:
// All markers are deleted and the clicked category is added
//So when the clicked item doesn't have the 'add_on_map' class:
if(!$(this).hasClass('add_on_map')){
console.log('remove all markers and add new');
removeAllMarkers();
element = $(this).text().toLowerCase();
$(this).parent().html(to_removed_marker_sign);
$('.category ul li').removeClass('active_subcategory');
addMarkers(element);
$('.category ul li span').click(showCategory);
}
//When clicked item DOES have 'add_on_map' class:
else
{
element = $(this).parent().children('.category_li').text().toLowerCase();
//Check if markers should be ADDED or DELETED
if($(this).hasClass('plus')) {
console.log('add markers');
$(this).parent().html(to_removed_marker_sign);
addMarkers(element);
$('.category ul li span').click(showCategory);
}
if($(this).hasClass('minus')) {
console.log('remove markers');
$(this).parent().html(to_add_marker_sign);
removeMarkers(element);
$('.category ul li span').click(showCategory);
}
}
}
I made a small live demo on jsfiddle!
If anyone can help me with this, I'd be greatful!
Thanks in advance.
Helena S.
I've based on your JSFiddle and come to that solution: http://jsfiddle.net/98gmn/6/ (only the jQuery part has changed)
jQuery
var add_marker_sign = '<span class="add_on_map plus"> +</span>';
var remove_marker_sign = '<span class="add_on_map minus"> -</span>';
$('.category ul li').click(showCategory);
$('.category ul li').hover(
//mouse-enter
function () {
if ($(this).children('.add_on_map').length == 0) {
$(this).append(add_marker_sign);
} else {
$(this).children('.add_on_map').show();
}
},
//mouse-leave
function () {
$(this).children('.add_on_map').hide();
});
function showCategory() {
var element;
var $this = $(this);
var $marker = $this.find('span.add_on_map');
element = $(this).text().toLowerCase();
$this.toggleClass('show_on_map');
$marker.toggleClass('plus').toggleClass('minus');
if($marker.hasClass('plus'))
{
$marker.html(' +');
}
else
{
$marker.html(' -');
}
}
It simplifies the DOM and event manipulation, sets the class "show_on_map" on list elements which are to be show on map.

grabbing title with jquery

Im trying to grab the "title" on the <li> when it is clicked. It keeps returning undefined.
html
<div id="sidebar">
<div class="navigation">
<ul>
<li title="../../000_Movies/_assets/playlist.html">فیلم ها</li>
</ul>
</div>
</div>
js
$('.navigation li').click(function () {
$('.slider').animate({
marginLeft: 0
}, 500,function() {
var test = $(this).attr('title');
alert(test);
location.href = '';
});
});
This doesn't work?
$('li').click(function(){
alert($(this).attr('title'));
});
"this" maybe is not the li. Or the browser have a bug (IE?). Your code seems correct to me.
You should create a closure on the clicked li element. You're getting this inside another function in the click handler function, so the definition of this will be different than the original function.
$('.navigation li').click(function () {
// cache the element here
var that = $(this);
$('.slider').animate({
marginLeft: 0
}, 500, function() {
// then access that instead here
// (we're creating a closure on the that variable)
var test = that.attr('title');
alert(test);
location.href = '';
});
});
If you have two nested functions, their this variables will be different:
function foo () {
// this here ...
function bar () {
// ... is different from this here
}
}
So building on that...
$('li').click(function () {
// $(this) here ...
$('something').slider({},100, function () {
// ... is different from $(this) here
});
});
$("li").on('click',function () {alert($(this).attr('title');)});
How are you attaching the click handler on the li element? Are you sure this inside the handler is poiting to li element.
I would try to log this and find out what it points to.
If this points to li then $(this).attr('title') should work perfectly fine.
I'm guessing it would be:
$("li.clickMe").click(function () {
$("this").attr("title").whateverYouNeedToDo("");
});

Categories