jQuery slider/switcher/tabs - javascript

I had no idea how to title this topic, sorry for that. I am building simple shopping cart splited into few steps. The whole thing is supposed to work similar to sliders or well-known tabs.
Let's see the code to make things easier.
$(document).ready(function(){
$('.stepNumber').click(function(e) {
e.preventDefault();
var stepDesc = $(this).next('.stepDesc');
if(!stepDesc.is(':visible')) {
$('.step').removeClass('stepActive');
$(this).parent().addClass('stepActive');
}
var val = parseInt($('.step.stepActive').children('div.stepNumber').text());
switch(val) {
case 1:
$('.formStepTwo').hide();
$('.formStepOne').show();
break;
case 2:
$('.formStepOne').hide();
$('.formStepTwo').show();
break;
case 3:
alert('blabla');
break;
}
});
});
.formStep {
display: none;
}
step {
float: left;
border: 1px solid #333;
margin-right: 5px;
}
.stepNumber {
background: #333;
color: #fff;
float: left;
padding: 6px 10px;
}
.stepDesc {
text-align: left;
padding: 6px 10px;
width: 150px;
display: none;
}
.stepActive > .stepDesc {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="step stepOne stepActive">
<div class="stepNumber">1</div>
<div class="stepDesc">Cart</div>
</div>
<div class="step stepTwo">
<div class="stepNumber">2</div>
<div class="stepDesc">Client data</div>
</div>
<div class="step stepThree">
<div class="stepNumber">3</div>
<div class="stepDesc">Shipping data</div>
</div>
<div class="formStep formStepOne">
Something - tab content
</div>
<div class="formStep formStepTwo">
Something else
</div>
Sorry for the appearance, some cosmetic css is missing here.
The actual problem:
I want to add button "Next" just under my "tab content". If we're in the step 1 at this moment, clicking that button should take us to step 2 and so on.
In the meantime time our "tab menu" script should be activated - as in the snippet: close description of others step, show current description and add class "stepActive".
Almost the same thing you can find in common sliders: arrows (next, prev) to move between slides and also "dot menu" with correct dot being highlighted.

If I'm not mistaken, it's something like that, what you wanted, isn't it?
$(document).ready(function(){
$('.stepNumber:contains(3)').click(function(){
alert('blabla');
});
$('.nextStep').click(function (e) {
e.preventDefault();
var stepActive = $('.stepActive');
if (stepActive.next('.step').length)
stepActive.next().children('.stepNumber')[0].click();
else
$('.step > .stepNumber')[0].click();
});
$('.stepNumber').click(function(e) {
e.preventDefault();
var obj = $(this);
var parent = obj.parent();
var stepDesc = obj.next('.stepDesc');
if(!stepDesc.is(':visible')) {
$('.step').removeClass('stepActive');
parent.addClass('stepActive');
}
$('[id^=step]').hide();
$('#step' + obj.text()).show();
});
$('.stepNumber')[0].click();
});
.formStep {
display: none;
}
.step {
float: left;
border: 1px solid #333;
margin-right: 5px;
}
.stepNumber, .nextStep {
background: #333;
color: #fff;
float: left;
padding: 6px 10px;
}
.stepDesc {
text-align: left;
padding: 6px 10px;
width: 150px;
display: none;
}
.stepActive > .stepDesc {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="step">
<div class="stepNumber">1</div>
<div class="stepDesc">Cart</div>
</div>
<div class="step">
<div class="stepNumber">2</div>
<div class="stepDesc">Client data</div>
</div>
<div class="step">
<div class="stepNumber">3</div>
<div class="stepDesc">Shipping data</div>
</div>
<div id="step1" class="formStep">
Something - tab content
</div>
<div id="step2" class="formStep">
Something else
</div>
<div id="step3" class="formStep">
The last one
</div>
<div class="nextStep">Next</div>

Related

Hide rows on click with jQuery

I have a small self made filter bar for a small agenda.
When i click on the filter button i want to hide the rows which are not in the category.
When i click Marketing, it will hide all other categories, and it's the same for the siblings. When i press ALL I want to show all rows again.
I bet there has to be a better way, i just can't figure it out
(function ($) {
$('#FilterBar a').click(function () {
if ($('#FilterBar a').is('.all')) {
$('.row').show();
}
else if ($('#FilterBar a').is('.pauses')) {
$('#Agenda .row:not(.pauses)').hide();
}
else if ($('#FilterBar a').is('.marketing')) {
$('#Agenda .row:not(.marketing)').hide();
}
else if ($('#FilterBar a').is('.sales')) {
$('#Agenda .row:not(.sales)').hide();
}
});
})(jQuery);
.wrapper {
padding: 20px;
}
#FilterBar a {
padding: 5px;
}
#Agenda {
padding: 15px 5px 5px;
}
#Agenda div {
padding: 20px;
background: #e7e7e7;
}
#Agenda div:nth-child(even) {
padding: 20px;
background: #f7f7f7;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="FilterBar">
All
Pauses
Marketing
Sales
</div>
<div id="Agenda">
<div class="row pauses"><b>Pause:</b> Break at 10:30</div>
<div class="row marketing"><b>Marketing:</b> This is marketing</div>
<div class="row sales"><b>Sales:</b> Sales is important</div>
</div>
</div>
You could do it like this:
(function ($) {
$('#FilterBar a').click(function () {
$('#Agenda .row').hide();
const className = $(this).attr('class');
$('#Agenda .' + (className === 'all' ? 'row' : className)).show();
});
})(jQuery);
.wrapper {
padding: 20px;
}
#FilterBar a {
padding: 5px;
}
#Agenda {
padding: 15px 5px 5px;
}
#Agenda div {
padding: 20px;
background: #e7e7e7;
}
#Agenda div:nth-child(even) {
padding: 20px;
background: #f7f7f7;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="FilterBar">
All
Pauses
Marketing
Sales
</div>
<div id="Agenda">
<div class="row pauses"><b>Pause:</b> Break at 10:30</div>
<div class="row marketing"><b>Marketing:</b> This is marketing</div>
<div class="row sales"><b>Sales:</b> Sales is important</div>
</div>
</div>

Toggle "addClass" at 3 divs successively

This is my html:
<div class="button"></div>
<div class="wrapper>
<div class="something">Hello</div>
<div class="box one">Box 1</div>
<div class="box two">Box 2</div>
<div class="box three">Box 3</div>
</div>
By clicking the div "button", I want to add the class "active" to the first div with class name "box". If I clicking the button again, I want to remove the class "active" from box 1 and add it to box 2. Aso.
Later, if box 3 has the added class name "active" and I press the div "button" again, it should start from the beginning.
I try something like this, but it fails:
$(".button").click(function() {
$(this).find(".wrapper").add(".box").toggleClass("active");
});
You'll need to use css :eq() selector or .eq() on jquery
$(document).ready(function(){
var index = 0; // define index for the first box
$('.button').on('click',function(){
$('.wrapper .box').removeClass('active'); // remove class active from all box divs
$('.wrapper .box:eq('+index+')').addClass('active'); // add class active to the box index we need
index = (index < $('.wrapper .box').length - 1) ? index +1 : 0; // if index = the number of box divs add + 1 if not return it back to 0
}).click(); // if you need to run it onload add .click()
});
.active{
background : red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button">Click</div>
<div class="wrapper">
<div class="something">Hello</div>
<div class="box one">Box 1</div>
<div class="box two">Box 2</div>
<div class="box three">Box 3</div>
</div>
You can try something like this:
jQuery(".button").click(function(){
var active = jQuery(".wrapper").children(".active").first();
if (!active.length)
jQuery(".wrapper").children(":first").addClass("active");
else{
active.removeClass("active");
if (active[0] != jQuery(".wrapper").children(":last")[0])
active.next().addClass("active");
else
jQuery(".wrapper").children(":first").addClass("active");
}
});
.button {
width: 150px;
height: 50px;
cursor: pointer;
background-color: blue;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
border-style: solid;
border-width: 0.5px;
border-radius: 9px;
position: relative;
left: 30%;
}
.wrapper {
margin-top: 20px;
margin-left: 30px;
background-color: white;
width: 450px;
height: 550;
text-align: center;
border-style: dashed;
}
.active {
background-color: grey;
}
.something {
margin-bottom: 8px;
margin-top: 8px;
}
.box {
margin-bottom: 8px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button">
<p>Press Me</p>
</div>
<div class="wrapper">
<div class="something">Hello</div>
<div class="box one">Box 1</div>
<div class="box two">Box 2</div>
<div class="box three">Box 3</div>
</div>
Some fun with generator functions :)
let box = 0;
$('.button').on('click', function() {
const boxes = document.querySelectorAll('.box'); // get all boxes
let iter = activateBox(box, boxes); // create itarator to go over boxes
$('.box').removeClass('active'); // remove any active class from all boxes
iter.next(box++).value.classList.add('active'); // add active class to the next box in line
if (box === boxes.length) box = 0; // reset counter if last box reached
});
function* activateBox(i, boxes) {
yield boxes[i];
}
body {
font-family: 'Arial', sans-serif;
}
.button {
display: inline-block;
padding: 8px;
border: 2px solid lightblue;
border-radius: 4px;
color: #444;
cursor: pointer;
transition: background .15s ease-out;
}
.button:hover {
background: lightblue;
color: #FFF;
}
.box {
display: flex;
justify-content: center;
align-items: center;
width: 300px;
height: 100px;
background: #FFF;
margin: 8px 0;
border: 2px solid lightblue;
border-radius: 4px;
}
.box.active {
background: lightblue;
color: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button">Apply Active</div>
<div class="wrapper">
<div class="box one">Box 1</div>
<div class="box two">Box 2</div>
<div class="box three">Box 3</div>
</div>

How to make slideToggle dynamic in JQuery

I have a page where multiple div and within each div there is a option to click and toggle the information, I am able to create by defining different IDs of DIV but I think that can be done somehow dynamically, here is what I have created in JSFiddle
CSS
.boxwrap {
float: left;
width: 200px;
height: 250px;
border: 1px solid #ccc;
margin: 0 5px 0 0;
text-align: center;
box-sizing: border-box;
padding: 10px;
}
.boxwrap_inner {
float: left;
width: 100%;
background: #ddd;
padding: 5px 0;
text-align: center;
}
.noDisplay {
display: none;
}
HTML
<div class="boxwrap">
Go
<div class="boxwrap_inner noDisplay" id="content1">
Content goes here
</div>
</div>
<div class="boxwrap">
Go
<div class="boxwrap_inner noDisplay" id="content2">
Content goes here
</div>
</div>
JQuery
$('#button1').click(function () {
$("#content1").slideToggle(200);
});
$('#button2').click(function () {
$("#content2").slideToggle(200);
});
Check this:
$('.boxwrap > a').click(function () {
$(this).next().slideToggle(200);
});
.boxwrap {
float: left;
width: 200px;
height: 250px;
border: 1px solid #ccc;
margin: 0 5px 0 0;
text-align: center;
box-sizing: border-box;
padding: 10px;
}
.boxwrap_inner {
float: left;
width: 100%;
background: #ddd;
padding: 5px 0;
text-align: center;
}
.noDisplay {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="boxwrap">
Go
<div class="boxwrap_inner noDisplay" id="content1">
Content goes here
</div>
</div>
<div class="boxwrap">
Go
<div class="boxwrap_inner noDisplay" id="content2">
Content goes here
</div>
</div>
The previous answers rely on the fact that the DOM is going to remain the same and the next() element after the button will always be the content div.
For a more robust solution, I would add a class to the buttons in the boxwrap(i.e. .boxbtn) and a class to the content divs (i.e. boxcontent) and then I would do something like the following:
$('.boxbtn').click(function () {
$(this).closest('.boxwrap')..find('.boxcontent').slideToggle(200);
});
Try this way,
It's better to specify the element with it's parent on which you're calling a click event.
$('.boxwrap > a').click(function(){
$(this).next('div').slideToggle(200);
});
Here with 2 options
using relative attribute value
using finding relative don element
/*$('.toggle_link').click(function () {
$($(this).data('toggle')).slideToggle(200);
});
OR
*/
$('.toggle_link').click(function () {
$(this).parent().find('.noDisplay').slideToggle(200);
});
.boxwrap{float:left; width:200px; height:250px; border:1px solid #ccc; margin:0 5px 0 0; text-align:center; box-sizing:border-box; padding:10px;}
.boxwrap_inner{float:left; width:100%; background:#ddd; padding:5px 0; text-align:center;}
.noDisplay{display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="boxwrap">
Go
<div class="boxwrap_inner noDisplay" id="content1">
Content goes here
</div>
</div>
<div class="boxwrap">
Go
<div class="boxwrap_inner noDisplay" id="content2">
Content goes here
</div>
</div>

Swapping an image when a toggle has been clicked on

I have the following code where I added a plus symbol to one of my service titles. I was informed by someone that when that service is clicked on I should have a minus sign take its place to show that it can be minimized. I am unsure of how to swap out the plus sign when the description has been expanded. Does anyone have any ideas of how I could do that?
Here is a snippet. Click on one of the service names to see the description expand.
$('.service_wrapper').click(function() {
var thisDescription = $('.service_description', $(this));
// Hide all other descriptions
$('.service_description').not(thisDescription).hide();
// Toggle (show or hide) this description
thisDescription.slideToggle(500);
});
.service_wrapper {
border: 1px solid black;
margin: 15px;
width: 20%;
}
.service_list {
margin-left: 20%;
}
.service_title {
padding: 15px 12px;
margin: 0;
font-weight: bold;
font-size: 1em;
}
.service_title:hover {
background-color: gray;
color: blue;
cursor: pointer;
}
.service_description {
display: none;
padding: 8px 14px;
width: 100%;
margin-top: 10px;
font-size: .9em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="service_list">
<div class="service_wrapper">
<div class="service_title">
<img src="http://realtorcatch.com/icons/plusSymbol.png" alt="Service" style="width:10px;height:10px;">Floors</div>
<div class="service_description">The best floors!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Roofs</div>
<div class="service_description">Your roof will be perfect!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Siding</div>
<div class="service_description">mmmm siding.</div>
</div>
<div class="service_wrapper">
<div class="service_title">Paint</div>
<div class="service_description">Fabulous paint!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Kitchen Remodels</div>
<div class="service_description">Pretty kitchen.</div>
</div>
</div>
Here is the working example, i change a little de html and Js
$('.service_wrapper').click(function() {
var thisDescription = $('.service_description', $(this));
var t = $(this);
if(t.hasClass('open'))
{
t.removeClass('open');
t.find('.status').html("+");
}else {
t.addClass('open');
t.find('.status').html("-");
}
// Hide all other descriptions
$('.service_description').not(thisDescription).hide();
// Toggle (show or hide) this description
thisDescription.slideToggle(500);
});
the working example
I'd suggest simply toggling a class to achieve this.
You can add the icon as a background image of a pseudo element inserted into the .service_title element. Then you can simply toggle a class in order to change the icon. Update the background image URLs accordingly. See the updated example for the modified jQuery; it's still only 5 lines.
The relevant CSS:
.service_title:before {
content: '';
background: url('http://i.stack.imgur.com/GC7i2.png') 0 0 / 10px 10px no-repeat;
width: 10px;
height: 10px;
display: inline-block;
vertical-align: middle;
}
.closed .service_title:before {
background-image: url('http://i.stack.imgur.com/ma4L4.png');
}
Updated Example:
$('.service_wrapper').click(function() {
var thisDescription = $('.service_description', $(this));
$('.service_description').not(thisDescription).hide().parent().removeClass('closed');
thisDescription.slideToggle(500).parent().toggleClass('closed');
});
.service_wrapper {
border: 1px solid black;
margin: 15px;
width: 20%;
}
.service_list {
margin-left: 20%;
}
.service_title {
padding: 15px 12px;
margin: 0;
font-weight: bold;
font-size: 1em;
}
.service_title:before {
content: '';
background: url('http://i.stack.imgur.com/GC7i2.png') 0 0 / 10px 10px no-repeat;
width: 10px;
height: 10px;
display: inline-block;
vertical-align: middle;
}
.closed .service_title:before {
background-image: url('http://i.stack.imgur.com/ma4L4.png');
}
.service_title:hover {
background-color: gray;
color: blue;
cursor: pointer;
}
.service_description {
display: none;
padding: 8px 14px;
width: 100%;
margin-top: 10px;
font-size: .9em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="service_list">
<div class="service_wrapper">
<div class="service_title">Floors</div>
<div class="service_description">The best floors!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Roofs</div>
<div class="service_description">Your roof will be perfect!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Siding</div>
<div class="service_description">mmmm siding.</div>
</div>
<div class="service_wrapper">
<div class="service_title">Paint</div>
<div class="service_description">Fabulous paint!</div>
</div>
<div class="service_wrapper">
<div class="service_title">Kitchen Remodels</div>
<div class="service_description">Pretty kitchen.</div>
</div>
</div>
You could just change it within your click binding...
Let's say your using images, just add a data-attribute you can query when you need to, like this...
HTML
<div class="service_wrapper">
<img data-state="plus" class="state" src="plus.png" alt="More"/>
<div class="service_title">Paint</div>
<div class="service_description">Fabulous paint!</div>
</div>
JS
$('.service_wrapper').click(function() {
var state = $(this).find('.state');
if(state.data('state') == 'plus')
state.attr({ 'src': 'minus.png', 'alt': 'Less' }).data('state', 'minus');
else
state.attr({ 'src': 'plus.png', 'alt': 'More' }).data('state', 'plus');
});

How to wrap more than one div around a div

I have a div (Slideshow) and I want to wrap around it small divs (Items). The Slideshow div will be static and the Items will be rendered automatically using a Repeater Control.
I made this image to better illustrate what I need to achieve.
I saw this Question and I thought I could use the same logic, let the Repeater items get rendered normally and then change the markup using JavaScript and use some sort of a CSS Grid layout to style the first 4 items for example on the left and the right and the rest will be beneath them but I'm not sure how to do it plus if there's a more simple solution I thought it could be cleaner than using the concept I saw in the question I referred.
Update1: Changed the picture to show the exact desired output
You could generate a Masonary layout. This plug in may be helpful, https://github.com/desandro/masonry
You could do this with bootstrap columns as well. For the first row, with the slideshow, you have 3 columns. The outer left and right columns will have 2 nested rows. http://getbootstrap.com/examples/grid/. This is what Im most familiar with so I'll show you how I would implement a solution for the first row and how to implement a second row with 4 columns.
<div class="row">
<!-- Outer Left Column -->
<div class="col-xs-4">
<div class="row">
<div class="col-xs-12">
Item
</div>
</div>
<div class="row">
<div class="col-xs-12">
Item
</div>
</div>
</div>
<div class="col-xs-12">
Slide Show
</div>
<!-- Outer Right Column -->
<div class="col-xs-4">
<div class="row">
<div class="col-xs-12">
Item
</div>
</div>
<div class="row">
<div class="col-xs-12">
Item
</div>
</div>
</div>
</div>
<!-- Row With Four Items -->
<div class="row">
<div class="col-xs-3">
Item
</div>
<div class="col-xs-3">
Item
</div>
<div class="col-xs-3">
Item
</div>
<div class="col-xs-3">
Item
</div>
</div>
Checkout the angular material layout system as well. This will be harder to implement though because it requires Angular. https://material.angularjs.org/latest/#/layout/grid
Check this solution out and see if you can adopt it to your project: http://jsfiddle.net/1b0hoked/.
HTML:
<div id = "wrapper">
<div id = "slideshow"></div>
</div>
CSS:
*, :before, :after {
margin: 0;
padding: 0;
border: 0;
box-sizing: border-box;
}
body {
padding: 10px;
}
#wrapper {
counter-reset: item-counter;
text-align: right;
margin: 0 auto;
display: table;
outline: 1px solid gray;
position: relative;
}
#slideshow {
width: 210px;
height: 210px;
line-height: 210px;
text-align: center;
border: 2px solid red;
position: absolute;
top: 5px;
left: 50%;
margin-left: -105px;
}
#slideshow:before {
content: "Slide Show";
vertical-align: middle;
font: bold 16px/1 Sans-Serif;
color: red;
}
.item {
height: 100px;
width: 100px;
text-align: center;
line-height: 96px;
border: 2px solid #aaa;
}
.item:before {
counter-increment: item-counter;
content: "item " counter(item-counter);
vertical-align: middle;
font: bold 12px/1 Sans-Serif;
color: #aaa;
}
.item {
float: left;
margin: 5px;
}
.item:nth-of-type(4n + 1) {
clear: left;
}
.item:nth-of-type(3) {
float: right;
margin-top: -105px;
}
.item:nth-of-type(4) {
float: right;
clear: right;
margin-left: -105px;
}
.item:nth-of-type(2) {
clear: left;
}
JS/jQuery:
$(function() {
var numToAdd = 50;
while(--numToAdd >= 0) {
$("</p>").addClass("item").appendTo("#wrapper");
}
});

Categories