Responsive collapsible tables one at a time: - javascript

First time on stackoverflow, so please don't beat me up too much.
I'm working with an existing code from codepen and trying to figure out how to make the tables expand one at a time.
Currently if we click on more than one "+" icon, they remain open, wondering how we can make it so that previous items expanded will close when clicking on the "+" sign.
I tried adjusting the layout here to no avail:
$('.js-tdToggle').on('click', function(){
if(window.innerWidth < 681){
$(this).toggleClass("fa-plus-square fa-minus-square");
var trParent = $(this).parent().parent();
trParent.toggleClass("collapse");
} else {
$(this).toggleClass("fa-plus-square fa-minus-square");
var tdParent = $(this).parent();
tdParent.next("td").toggleClass("collapse");
}
});
Original Source Codepen

You have to add code where you do the opposite action on every other toggle. JQuery's .not() function is very useful for this. With my changes the JavaScript looks like this:
$('.js-tdToggle').on('click', function() {
var $otherToggles = $(".js-tdToggle.fa-minus-square");
if (window.innerWidth < 681) {
$(this).toggleClass("fa-plus-square fa-minus-square");
$otherToggles.not(this).toggleClass("fa-minus-square fa-plus-square");
var trParent = $(this).parent().parent();
trParent.toggleClass("collapse expand");
var $otherParents = $otherToggles.parent().parent();
$otherParents.removeClass("expand").addClass(" collapse");
} else {
$(this).toggleClass("fa-plus-square fa-minus-square");
$otherToggles.not(this).toggleClass("fa-minus-square fa-plus-square");
var tdParent = $(this).parent();
tdParent.next("td").toggleClass("collapse expand");
var $otherParents = $($otherToggles).not(this).parent();
$otherParents.next("td").toggleClass("expand collapse");
}
});
You can refer to my forked pen to see it in action: codepen.io

Related

Adding Next & Previous Buttons to modal with JavaScript

I have made a clean modal to use on a website to open images, everything works fine and is pretty nice.
Now I want to make a next image and previous image button for a better user experience.
I have a plan, so I find the index of the current image that is in the modal and I increment it by one on the next button, and decrement it by one on the previous button, HM ok seems easy enough. So how do I go about doing this?
this is my Modal code
window.onload = function() {
var imgArr = document.getElementsByClassName("myImg");
var modalWindow = document.getElementById("myModal");
var modalImg = document.getElementById("img01");
var caption = document.getElementById("caption");
var span = document.getElementById("close");
var modalBlock = document.getElementById("modalBlock");
for (i = 0; i < imgArr.length; i++) {
var picture = imgArr[i];
var list = Array.from(imgArr);
picture.onclick = function() {
openImg(this);
var index = list.indexOf(this);
console.log(index);
};
}
function openImg(pic) {
modalWindow.style.display = "block";
modalBlock.style.transform = "translateY(0%)";
modalImg.src = pic.src;
modalImg.alt = pic.alt;
caption.innerHTML = modalImg.alt;
imgIndex = picture[i];
bodyScrollLock.disableBodyScroll(myModal);
}
};
Now I have the open image that I've clicked on and its index, and I'm stuck on what to do next. I've found the w3 lightbox tutorial, but it's so different from my code I need to swap everything. Does anyone have an idea how I can do this with my own code?
A jsFiddle how it looks at the moment
https://jsfiddle.net/superVoja/eoyda1vh/15/
If you insist on building this from scratch then you will need to start thinking about what you should control with HTML and CSS and leave the rest to do with JavaScript.
I would use Modal window set with Html and hide it with CSS, then when image link and trigger fires I would bring modal to front. Using fadein fadeout, opacity and z-index to make sure that is on the front. Set background to black in order to get the Modal effect.
The faster way is to use library like Lightbox js
Then overwrite using CSS and maybe some js if need to in order to adjust to your liking.
Well, here is the answer I got myself if anyone reads this give yourself some time, you'll find the answer yourself!
I followed my code and did exactly the thing I was trying to do, I found the index of the image that is clicked, and then I just incremented it by one like this.
var next = this.document.getElementById("next");
var slideIndex = "";
for (i = 0; i < imgArr.length; i++) {
var picture = imgArr[i];
var list = Array.from(imgArr);
picture.onclick = function() {
var index = list.indexOf(this);
slideIndex = index;
openImg(imgArr[index]);
console.log(index);
};
}
next.addEventListener("click", function(event) {
openImg(imgArr[(slideIndex += 1)]);
});
It may not look pretty, but it's mine and I am proud of it!
And here is a link How it looks!

jQuery addClass on user control list

I have a list on a user control and a jquery script that works when an li is clicked. This works fine. I want to change the class on the selected li but having trouble making this work. I tried this in a fiddle and no problem - but in my actual page - no good.
the fiddle is at https://jsfiddle.net/u6sykb8d/7/
the actual jquery script is
$(document).ready(function () {
$('.listButtons li').on("click", function () {
$('.selected').removeClass("selected");
$(this).addClass("selected");
var tabid = $(this).attr('id');
var cont = $(this).closest($(".container"));
var tabs = ["tabAddress", "tabPeople0", "tabPeople1", "tabPeople2", "tabPeople3", "tabPeople4"];
var divs = ["divAddress0", "divPeople_0", "divPeople_1", "divPeople_2", "divPeople_3", "divPeople_4"];
var indx = tabs.indexOf(tabid);
for (var i = 0; i < divs.length; i++) {
if (i == indx) {
cont.find($("div[id$='" + divs[i] + "']")).show();
}
else {
cont.find($("div[id$='" + divs[i] + "']")).hide();
}
}
});
});
the rest of the script works, the lines removing and adding the class don't seem to work.
Any ideas?
embarrassed to say but after digging through the code the problem turned out to be an extra space in the css file 'li .selected' instead of 'li.selected' . Thanks for the help

Jquery, show and layer divs when their checkboxs are selected

I am making a page in which you select sandwich toppings with checkboxes, and after you click submit those sandwich option divs containing images will show. By default they are all hidden. I want the first div that is shows to be fixed while the rest of the toppings layer on top of the first one. I'll eventually set it up so that while you scroll down, the toppings appear to move up and over the previous topping. So, if you select bagel-bottom and bacon, you scroll down to see a bagel bottom and keep scrolling for the bacon to move up on top of the bagel bottom.
The first topping div in the HTML order is bagel-bottom, but even though I select "bacon" the only div that shows is bagel-bottom.
I have the jsfiddle here: http://jsfiddle.net/3kgnkh4w/
$(document).ready(function() {
$('#sandwich-option-submit').click(function() {
var checkedTopping = $('.sandwich-option').val();
var divCheckedTopping = $('#'+ checkedTopping);
var optionsContainer = $('#sandwich-selection-container');
if($('.sandwich-option').is(':checked')) {
$(divCheckedTopping).show().addClass('display');
$(divCheckedTopping).eq(0).addClass('first-checked-topping');
} else {
$(divCheckedTopping).hide();
};
});
});
The jQuery class selector returns an array of all objects within that class, so you need to check all of them. Here is the fixed jQuery:
$(document).ready(function() {
$('#sandwich-option-submit').on("click", function() {
var checkedToppings = $('.sandwich-option');
for(var i = 0; i < checkedToppings.length; i++){
var checkedTopping = $(checkedToppings[i]);
var checkedToppingVal = $(checkedTopping).val();
var divCheckedTopping = $('#' + checkedToppingVal);
var optionsContainer = $('#sandwich-selection-container');
if($(checkedTopping).is(':checked')) {
$(divCheckedTopping).show().addClass('display');
$(divCheckedTopping).eq(0).addClass('first-checked-topping');
} else {
$(divCheckedTopping).hide();
}
}
});
});
Alternatively, you can have each topping shown on check, using the toggle() jQuery function which toggles between the hide() and show() method. Here is the code for that:
$(document).ready(function() {
$('.sandwich-option').on("click", function() {
var checkedToppingVal = $(this).val();
var divCheckedTopping = $('#' + checkedToppingVal);
$(divCheckedTopping).toggle();
});
});
You can then remove the submit buttton.

Why isn't my div swap working?

So, I need a div to slide up when another slides down.
Example:
When Home button is clicked a div, we'll call it box_Home, slides down. When Games button is clicked, box_Home should slide up and then box_Games should slide down. What's happening is that they are overlapping instead of swapping out.
http://jsfiddle.net/M8UgQ/15/
var open = $('.open'),
a = $('ul').find('a');
console.log(a.hasClass('active'));
open.click(function(e) {
e.preventDefault();
var $this = $(this),
speed = 500;
var link_id = $this.attr('id');
var box_id = '#box_' + link_id;
console.log(box_id);
if($this.hasClass('active') === true) {
$this.removeClass('active');
$(box_id).slideUp(speed);
} else if(a.hasClass('active') === false) {
$this.addClass('active');
$(box_id).slideDown(speed);
} else {
a.removeClass('active')
$(box_id).slideUp(speed);
$this.addClass('active');
$(box_id).delay(speed).slideDown(speed);
}
});
take a look at this
http://jsfiddle.net/rWrJ9/1/
the main idea is...
if the element clicked is active, remove it, otherwise: 1. find (if any) already active elements (using $('.active')) and use jQuery.map() to make them inactive and slide them up, and 2. make the element clicked active.
I also removed the unneeded variable a
IMPORTANT: the this inside the map() function is different from the this (or rather, $this as you called it) outside the map() function
I think you're saying you have two buttons id="Home" class="open" and id="Game" class="open", and two divs id="box_Home" and id="box_Game". If so, you add class="box" to box_Home and box_Game and do something like this:
$('.open').click(function(e) {
e.preventDefault();
var $this = $(this);
var link_id = $this.attr('id');
var box_id = '#box_' + link_id;
$('.box').slideUp();
$(box_id).slideDown();
});
Hi check this fiddle i hope you need thing to implement
jsfiddle
in the if else statement you are doing a mistake
else if(a.hasClass('active') === false) {
replace it with
else if($this.hasClass('active') === false) {

jquery swap images on click and hide then

I'm trying to build a menu. OVer a canvas I load different images and position them using CSS. Currently I operate with SHOW / HIDE with a lots of code duplication. My questions are:
- instead of just hidding an image, how can I change it on click with another one? and then again hide it, if I should click another button?
- is it possible to write all this code somehow simpler?
Thanks a lot...
$("#ten").click(sizeTen);
function sizeTen(){
cb_ctx.lineWidth = 10;
clickSound();
$(this).hide();
$("#twenty").show();
$("#forty").show();
$("#sixty").show();
}
$("#twenty").click(sizeTwenty);
function sizeTwenty(){
cb_ctx.lineWidth = 20;
clickSound();
$(this).hide();
$("#tenClick").show();
$("#ten").show();
$("#forty").show();
$("#sixty").show();
}
$("#forty").click(sizeForty);
function sizeForty(){
cb_ctx.lineWidth = 40;
clickSound();
$(this).hide();
$("#ten").show();
$("#twenty").show();
$("#sixty").show();
}
$("#sixty").click(sizeSixty);
function sizeSixty(){
cb_ctx.lineWidth = 60;
clickSound();
$(this).hide();
$("#ten").show();
$("#twenty").show();
$("#forty").show();
}
May be You Could shrink your coding by the following piece of code,
$("#ten,#twenty,#sixty").show();
I'd put all numeric values along with the corresponding IDs in a map and create a single handler for all buttons:
var boo = function () {
var values = { 'ten': 10, 'twenty': 20, 'forty': 40, 'sixty': 60 };
var id = $(this).attr('id');
$(this).hide();
// cb_ctx.lineWidth = values[id];
// clickSound();
$.each(values, function(key, value) {
if (id != key) {
$('#' + key).show();
}
});
};
$('#ten, #twenty, #forty, #sixty').click(boo);
Check out a jsfiddle at: http://jsfiddle.net/LNFza/4/
Cheers.

Categories