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/
Related
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.
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
I need a some sort of a practical solution for toggle between different divs, when i click on a anchor tag.
I have done a JSfiddle that is kind of the solution i want.
the problem there is when i first click on "show 1" and then "show 2" the two first placeholders content disappear, but nothing new shows up.
I want it this way:
When i click "show 1", Two Placeholders appear(PlaceHolder 1 and 2).
When clicking "show 2" WITHOUT closing Placeholder 1 and 2. The PlaceHolder 1 and 2 should close AND PlaceHolder 3 should appear.
Jsfiddle: http://jsfiddle.net/CY3tj/2/
HTML:
<a id="1" class="show">show 1</a>
<br/ ><br/ >
<a id="2" class="show">show 2</a>
<div class="content-wrapper">
<div id="item-1">
<div>
<h2>Placeholder1</h2>
<p>Placeholder1</p>
</div>
<div>
<h2>PLaceHolder2</h2>
<p>Placeholder2</p>
</div>
</div>
<div id="item-2">
<div>
<h2>Placeholder3</h2>
<p>Placeholder3</p>
</div>
</div>
</div>
JQuery:
$(document).ready(function () {
$(".content-wrapper").hide();
});
$(document.body).on("click", "a.show", function () {
var id = $(this).attr("id");
$(".content-wrapper > div").each(function () {
if ($(this).attr("id") == "item-" + id) {
$(this).show();
} else {
$(this).hide();
}
});
$(".content-wrapper").toggle();
});
You can simplify this to:
$(function(){
var $allItems = $(".content-wrapper > div"); //Cache the collection here.
$(document).on("click", "a.show", function () {
var id = this.id, itemId = "#item-" + id; //get the id and itemId
$allItems.not($(itemId).toggle()).hide(); //Hide all items but not the one which is the target for which you will do a toggle
});
});
Demo
Instead of hiding the wrapper via JS, you can just add a rule to hide its contents.
.content-wrapper >div{
display:none;
}
Your main problem is your using $(.content-wrapper).toggle() You only want to hide the content wrapper initially and then after one click you want it to show up. By toggling your content wrapper you were making it dissapear every other click which was why you had to click twice to see it.
$(document.body).on("click", "a.show", function () {
var id = $(this).attr("id");
$(".content-wrapper > div").each(function () {
if ($(this).attr("id") == "item-" + id) {
$(this).show();
} else {
$(this).hide();
}
});
$(".content-wrapper").show();
});
If you are looking to keep the toggle functionality (to hide a div that is already showing) here is a solution for that.
$(document.body).on("click", "a.show", function () {
var id = $(this).attr("id");
if($(".content-wrapper #item-"+id).is(':visible'))
$(".content-wrapper").hide();
else{
$(".content-wrapper").children("div").hide();
$(".content-wrapper #item-"+id).show();
$(".content-wrapper").show();
}
});
You would gain more flexibility and performance by selecting the ids of the anchor tags. You should also hide the specific divs that you want to be hidden rather than hiding the overall container. That way, you can easily target which div you want to show and which one to hide.
$(document).ready(function () {
$(".content-wrapper > div").hide();
});
$("#1").click(function(){
$("#item-2").hide();
$("#item-1").show();
});
$("#2").click(function(){
$("#item-1").hide();
$("#item-2").show();
});
However, if you're looking to add an unknown number of these items, then you will want to select (for readability) just the element and class, rather than having to go through the document, which is just redundant.
$(document).ready(function () {
$(".content-wrapper > div").hide();
});
$("a.show").click(function(){
$(".content-wrapper > div").hide();
$("#item-" + $(this).attr("id").show();
});
I have HTML
<div id="top" class="shadow">
<ul class="gprc">
<li>Home</li>
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
<li>Text4</li>
</ul>
</div>
and JQUERY
$(function () {
var url = window.location.pathname,
urlRegExp = new RegExp(url.replace(/\/$/, '') + "$");
$('#top a').each(function () {
if (urlRegExp.test(this.href.replace(/\/$/, ''))) {
$(this).addClass('active');
}
});
});
The problem is that when i click on the Home link all tabs are getting active class and don't understand why. I need it for the first link to not get any active class.
I'm also looking for this solution and I have tested your code. On the first approach all links are highlighted and when I click other links it is working properly. The problem was on the home page because all links are highlighted because there is "no event been received" when the page is loaded, the code will work if you send a command or by clicking each links, theoretically. To stop this behavior, I found this code to one of the answers above, add this code and change the ".sibling()" to ".previousSibling()"
$(this).parent().sibling().find('a').removeClass('active');
".sibling()" will highlighted at the end of your links change it to ".previousSibling()" so it will go to first (Li)
$(this).parent().previoussibling().find('a').removeClass('active');
Your code will be like this:
$(function () {
var url = window.location.pathname,
urlRegExp = new RegExp(url.replace(/\/$/, '') + "$");
$('#top a').each(function () {
if (urlRegExp.test(this.href.replace(/\/$/, ''))) {
$(this).addClass('active');
$(this).parent().previoussibling().find('a').removeClass('active');
}
});
});
Check this , this will only activates clicked tab , remove active for all and then add for the one clicked
$("#top a").click(function() {
$('a').removeClass('active');
$(this).addClass("active");
});
Check this
You may try this out. It will help you:
<script type="text/javascript">
$(function () {
$('#sidebar li a').each(function () {
var path = window.location.pathname;
if (path.indexOf('?') > 0) {
var current = path.indexOf('?');
}
else {
var current = path;
}
var url = $(this).attr('href');
var currenturl = url.substring(url.lastIndexOf('.') + 1);
if (currenturl.toLowerCase() == current.toLowerCase()) {
$(this).addClass('active');
var par = $(this).parent();
par.addClass('open');
}
});
});
</script>
You're running a foreach loop on all <a> tags within your #top div. So of course it'll add the class active to all of them.
I think what you're trying to do is this: http://jsfiddle.net/rLddf/4/
I used the click event instead.
edit switched link to Kristof Feys example - more efficient.
try this...
$(function() {
$('#yourMenu a').each(function(){
$current = location.href;
$target= $(this).attr('href');
if ( $target== $current)
{
$(this).addClass('active');
}
});
});
I came across the same issue and I found it easier to just add an additional if statement so that the function would fire on all pages except the home page which met my needs.
$(function(){
var url = window.location.pathname,
urlRegExp = new RegExp(url.replace(/\/$/,'') + "$");
$('#top a').each(function(){
if ( window.location.pathname != '/' ){
if(urlRegExp.test(this.href.replace(/\/$/,''))){
$(this).addClass('active');
}
}
});
});
You could also add in an else statement to show an active link on the homepage by targeting the link directly if required.
I think you need something like this:
$(function () {
$("#top a").click(function(e){
e.preventDefault();
$(this).addClass('active');
$(this).parent().siblings().find('a').removeClass('active');
});
});
Fiddle Demo
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));