Jquery, show and layer divs when their checkboxs are selected - javascript

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.

Related

How to work with a bunch of buttons (Show/Hide) in JavaScript

I'd like to learn how work with a group of buttons without specifying Ids for the following task:
Hide and Show Div body, Div header stay show.
I was able to make one with this code:
function hide(){
document.getElementById('here').classList.toggle('hide')
}
but Hiding/Showing each individually was prove to be more difficult.
The sample here: Show/Hide Div Body
I know there is something like:
Let btns = document.querySelectorAll('buttons);
Let tables = document.getElementsByClassName('here');
function HideShow(){
//What do I put here??????? :)
}
Note: I can't use ids, because I want to add so many divs to make it dynamic.
UPDATE:::::: UPDATE:::::: UPDATE::::::
I had to do it the old fashion way, with ids!! and IF/ELSE, not cool! :(
let tables = document.getElementsByClassName('here');
var theParent = document.querySelector('#theDude');
theParent.addEventListener('click', doSomeThing, false);
function doSomeThing(e){
if( e.target!==e.currentTarget){
var clickedItem = e.target.id;
if(clickedItem=='one'){
tables[0].classList.toggle('hide')
}else if(clickedItem=='two'){
tables[1].classList.toggle('hide')
}else if(clickedItem=='three'){
tables[2].classList.toggle('hide')
}else if(clickedItem=='four'){
tables[3].classList.toggle('hide')
}
e.stopPropagation();
}
}
Pass your node lists into your Hide and show, and then iterate over them
Let btns = document.querySelectorAll('buttons);
Let tables = document.getElementsByClassName('here');
function HideShow(elemArray){ // note: I've added an elemArray parameter here
//What do I put here??????? :)
elemArray.forEach(elemArray, function(elem) {
//with each element, toggle hide or show
//elem.classList...
}
}
HTML: <button onclick="hideThisButton(this);">Button</button>
JS: let btns = document.querySelectorAll('buttons);
let tables = document.getElementsByClassName('here');
// use this to hide all the buttons
function HideShow(){
for(let i=0;i<btns.length;i++){
// you can access the index i over here
// change the logic to hide or show specific buttons
btns[i].classList.toggle('hide');
}
}
// use this method for hiding a specific button on click
function hideThisButton(event)
{
var btn = event.target;
btn.classList.toggle('hide');
}

Responsive collapsible tables one at a time:

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

Display one div at a time with multiple buttons

Using Foundation 6 as my framework, I wanted to implement a fading effect between two divs when a button is pressed.
The effect I'm trying to do is when button1 is clicked, div2 will hide and fade out (if visible) and div1 will show and fade in, and vice versa.
Here is my Javascript code:
var $button1 = $('#button1');
var $button2 = $('#button2');
var $div1 = $('#div1');
var $div2 = $('#div2');
$button1.click(function() {
if ($div2.is(':visible')) {
MotionUI.animateOut($div2, 'fadeOut');
MotionUI.animateIn($div1, 'fadeIn');
}
else {
$div1.show();
}
});
$button2.click(function() {
if ($div1.is(':visible')) {
MotionUI.animateOut($div1, 'fadeOut');
MotionUI.animateIn($div2, 'fadeIn');
}
else {
$div2.show();
}
});
I have gotten div1 and div2 to fade in/out between the two with one button, but I can't seem to get it to work when using multiple buttons.
Here's a really simple way to toggle display:none using jQuery's toggle() methods. I used fadeToggle since you mentioned wanting a fade, but you could use toggle and set a css3 transition instead.
Keeping the code super simple - to match what you have - this is how you would do it:
Fiddle: https://jsfiddle.net/f1dshffs/2/
var $button1 = $('#button1');
var $button2 = $('#button2');
var $div1 = $('#div1');
var $div2 = $('#div2');
var toggleDivs = function(){
$div1.fadeToggle();
$div2.fadeToggle();
};
$button1.click(toggleDivs);
$button2.click(toggleDivs);
Now there's some things you could do to optimize your code a little bit by selecting by a class instead of an id, and then adding only 1 event to the array of objects.
It reduces the code down to: Fiddle: https://jsfiddle.net/f1dshffs/3/
var buttons = $('.button');
var divs = $('.div');
var toggleDivs = function(){
divs.fadeToggle();
};
buttons.click(toggleDivs);

on click addClass selected overrule addClass on scroll

I'm finding myself in a problem which I think has a easy solution but I cannot see... I have two functions to add a class called selected which highlights the buttons.
One function removes the class selected if present and adds the class to the button clicked:
var sidebarLinks = $('.js-sidebar a');
// About section: Remove and add class on click
sidebarLinks.on('click', function() {
sidebarLinks.removeClass('selected');
$(this).addClass('selected');
});
The other function adds the class selected if the user decides to scroll instead of clicking on the buttons. These buttons would highlight in a determined offset of the page:
var buttonOne = $('.buttonOne');
var buttonTwo = $('.buttonTwo');
var buttonThree = $('.buttonThree');
// Select nav buttons if scrolling and not clicking the button
$(window).scroll(function () {
// About nav sidebar links
var buttonOne = $('.js-polspotten-sidebar');
var buttonTwo = $('.js-product-sidebar');
var buttonThree = $('.js-designers-sidebar');
// About sections top scroll position
var currentTopPosition = $(this).scrollTop();
var productsTopPosition = $('#products').offset().top;
var designersTopPosition = $('#designers').offset().top;
// polspotten selected depending on scroll position
if (currentTopPosition >= currentTopPosition && currentTopPosition < productsTopPosition) {
buttonOne.addClass('selected');
}
else{
buttonOne.removeClass('selected');
}
// products selected depending on scroll position
if (currentTopPosition >= productsTopPosition &&
currentTopPosition < designersTopPosition) {
buttonTwo.addClass('selected');
}
else{
buttonTwo.removeClass('selected');
}
// designers selected depending on scroll position
if (currentTopPosition >= designersTopPosition) {
buttonThree.addClass('selected');
}
else{
buttonThree.removeClass('selected');
}
});
The problem is that both interact at the same time as the click event creates scroll.
What I want is that if somebody clicks on the button the scroll function will not work. It will only work if the user scrolls himself.
Is this possible?

Moving multiple JQueryUI sliders in the DOM while keeping functionality & values

I have a page with a large number of JQueryUI sliders, in div .origin. Each slider has an associated checkbox. If the checkbox is checked, the slider should be moved- with all values intact- to div .favourites. If the checkbox is unchecked, the slider should be moved back to .origin.
Here's a JSFiddle of my attempts so far.
Here's my function to detect the value of the checkbox and make DOM adjustments accordingly:
$('[type="checkbox"]').click(function () {
var check = $(this),
checked = $(check).prop("checked"),
num = $(check).attr("id").split("-")[1],
parent = $("#food-" + num),
parentContent = $(parent).clone(),
slider = "#" + $(parent).find('.slider').attr("id"),
favelist = $(".favourites .content");
alert(checked)
//remove the original
$(parent).remove();
if (checked === true) {
//add to favourites
$(favelist).append(parentContent);
} else {
//add to origin
$(favelist).append(parentContent);
}
//reinitialise slider
loadSlider(slider)
});
A number of things aren't working:
1) First and most significantly, after the slider and it's parent elements have been moved into the .origin div, clicks on the checkbox no longer register. The alert(checked) doesn't fire, and the else statement doesn't run. Why would a checkbox no longer register a click event after being moved in the DOM?
2) Secondly, the moved sliders have the correct value displayed on the highlight div, but the dragger-handles go back to the starting position. How can I re-initialise the slider with the dragger handle in the correct position?
--
UPDATE- JSFIDDLE
OK, first issue is resolved, thanks to the hint provided by Chad, below. I've rewritten the click event into two functions, so that the click event can be re-instantiated after the elements are re-created in the DOM:
//Listen for checkbox to be checked
function checkboxChecked() {
$('[type="checkbox"]').click(function () {
var checkbox = $(this);
moveItem(checkbox);
});
}
//Create/Destroy items when clicked
function moveItem(checkbox) {
var check = $(checkbox),
checked = $(check).prop("checked"),
num = $(check).attr("id").split("-")[1],
parent = $("#food-" + num),
parentContent = $(parent).clone(),
slider = "#" + $(parent).find('.slider').attr("id"),
favelist = $(".favourites .content"),
origin = $(".all .content");
$(parent).remove();
if (checked === true) {
$(favelist).append(parentContent);
} else {
$(origin).append(parentContent);
}
loadSlider(slider);
checkboxChecked();
}
//initialise checkbox move function
checkboxChecked();
Am still trying to solve the mystery of the handle positions being re-set to 0 despite the slider retaining it's value, as shown on the highlighter track.

Categories