Stepper with pure javascript - previous function not working - javascript

How to make it return to false once exceeded max step (which is the last step), previous function not working once exceeded max step, I tried to set current step as -1 but still doesn't work.
I get this error msg (TypeError: bullets[current] is undefined) on my console when it exceeded max step.
Can somebody help me with this? Thanks in advance.
const bullets=[...document.querySelectorAll('.bullet')];
const max=4;
let current=-1;
function next(){
current+=1;
if(!bullets[current]){
return false;
}
bullets[current].classList.add('hovered');
}
function previous(){
bullets[current].classList.remove('hovered');
current-=1;
if(!bullets[current]){
return false;
}
bullets[current].classList.add('hovered');
}
.progressbar{
display:flex;
justify-content:space-between;
align-items:flex-end;
width:90%;
margin:0 auto;
margin-bottom:40px;
}
.item{
text-align:center;
width:20%;
position:relative;
}
.text{
height:50px;
margin:10px 0px;
color:#3CB371;
}
.bullet{
border:1px solid #3CB371;
height:20px;
width:20px;
color:#3CB371;
display:inline-block;
transition:background-color 500ms;
line-height:20px;
}
.bullet.hovered{
color:#fff;
background-color:#3CB371;
bottom:10px;
}
.bullet.completed:after{
content:'';
position:absolute;
bottom:80px;
height:1px;
width:calc(133% - 21px);
background-color:#3CB371;
margin-left:7px;
}
<div class="progressbar">
<div class="item">
<div class="bullet completed">1</div>
<div class="text">Hello Hello Hello</div>
</div>
<div class="item">
<div class="bullet completed">2</div>
<div class="text">Hello</div>
</div>
<div class="item">
<div class="bullet completed">3</div>
<div class="text">Hello</div>
</div>
<div class="item completed">
<div class="bullet">4</div>
<div class="text">Hello</div>
</div>
</div>
<div onclick="previous();">Previous</div>
<div onclick="next();">Next</div>

You're unconditionally incrementing/decrementing current at the moment. Even if you don't try changing the classList on this call of next or previous, the next time either button is clicked, the current index may not exist. So, in previous, when you do bullets[current].classList.remove('hovered'); at the beginning of the function, that will throw if the last current went beyond the possible indicies for the bullets collection.
Consider using Math.max / Math.min to ensure that current is constrained to the possible indicies (or -1, in the case that nothing should be highlighted):
const bullets = [...document.querySelectorAll('.bullet')];
let current = -1;
function next() {
current = Math.min(current + 1, bullets.length - 1);
bullets[current].classList.add('hovered');
}
function previous() {
if (bullets[current]) {
bullets[current].classList.remove('hovered');
}
current = Math.max(current - 1, -1);
}
.progressbar {
display: flex;
justify-content: space-between;
align-items: flex-end;
width: 90%;
margin: 0 auto;
margin-bottom: 40px;
}
.item {
text-align: center;
width: 20%;
position: relative;
}
.text {
height: 50px;
margin: 10px 0px;
color: #3CB371;
}
.bullet {
border: 1px solid #3CB371;
height: 20px;
width: 20px;
color: #3CB371;
display: inline-block;
transition: background-color 500ms;
line-height: 20px;
}
.bullet.hovered {
color: #fff;
background-color: #3CB371;
bottom: 10px;
}
.bullet.completed:after {
content: '';
position: absolute;
bottom: 80px;
height: 1px;
width: calc(133% - 21px);
background-color: #3CB371;
margin-left: 7px;
}
<div class="progressbar">
<div class="item">
<div class="bullet completed">1</div>
<div class="text">Hello Hello Hello</div>
</div>
<div class="item">
<div class="bullet completed">2</div>
<div class="text">Hello</div>
</div>
<div class="item">
<div class="bullet completed">3</div>
<div class="text">Hello</div>
</div>
<div class="item completed">
<div class="bullet">4</div>
<div class="text">Hello</div>
</div>
</div>
<div onclick="previous();">Previous</div>
<div onclick="next();">Next</div>

Related

How do I know when 2 absolute html element stack on top of each other

A little background on my current project:
I'm building the calendar scheduler.
I have a structure as below:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.label {
display: flex;
flex-direction: row;
}
.title {
border: 1px #333 solid;
padding: 10px 20px;
text-align: center;
width: 100px;
}
.task {
margin-top: 6px;
position: relative;
}
.eachTask {
position: absolute;
border: 1px #333 solid;
padding: 10px 20px;
width: 100px;
}
.task1 {
left: 100px;
}
.task2 {
left: 300px;
}
.task3 {
left: 500px;
}
.task4 {
left: 500px;
top: 40px;
}
<div>
<div class="label">
<div class="title">Monday</div>
<div class="title">Tuesday</div>
<div class="title">Wednesday</div>
<div class="title">Thursday</div>
<div class="title">Friday</div>
<div class="title">Saturday</div>
<div class="title">Sunday</div>
</div>
<div class="task">
<div class="eachTask task1">Task1</div>
<div class="eachTask task2">Task2</div>
<div class="eachTask task3">Task3</div>
<div class="eachTask task4">Task4</div>
</div>
</div>
I put the top position for the Task4 to appear below Task 3. Otherwise, it will stack on top of eachother.
Is there any way to know if the element is overlapping or stacking so that I can align it below.
I have a list of tasks, every task will be displayed on the same line, is there any way to know that each of them has the same position or stacking on top of each other so that I can set the top position to put it below. (Note: I have control the width of each task and the left position).
I have an idea about looping all the task, For each task I will compare the left and the width value with all the other one. If one of them is stacking I will insert the top position. but as far as I concern It will be a nested loop.
Thank you
http://codesandbox.io/s/crazy-cerf-jeipz?file=/index.html:0-1525
Edit: I put one more case here to get my idea
Please consider it like a Gant Chart
https://codesandbox.io/s/vigorous-star-rvcpe?file=/index.html
Are you able to add a class to each task representing the day of the week? If so you can kind of hack to together with js sort of by adding an increasing margin-top to each progressive task. Take a look at what I did here:
var marginsat=-40;
$(".saturday").each(function(){
$(this).css("margin-top",marginsat+=40)
})
var margintues=-40;
$(".tuesday").each(function(){
$(this).css("margin-top",margintues+=40)
})
var marginth=-40;
$(".thursday").each(function(){
$(this).css("margin-top",marginth+=40)
})
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.label {
display: flex;
flex-direction: row;
}
.title {
border: 1px #333 solid;
padding: 10px 20px;
text-align: center;
width: 100px;
}
.task {
margin-top: 6px;
position: relative;
}
.eachTask {
position: absolute;
border: 1px #333 solid;
padding: 10px 20px;
width: 100px;
}
.task1 {
left: 100px;
}
.task2 {
left: 300px;
}
.task3 {
left: 500px;
}
.task4 {
left: 500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="label">
<div class="title">Monday</div>
<div class="title">Tuesday</div>
<div class="title">Wednesday</div>
<div class="title">Thursday</div>
<div class="title">Friday</div>
<div class="title">Saturday</div>
<div class="title">Sunday</div>
</div>
<div class="task">
<div class="eachTask task1 tuesday">Task1</div>
<div class="eachTask task2 thursday">Task2</div>
<div class="eachTask task3 saturday">Task3</div>
<div class="eachTask task4 saturday">Task4</div>
<div class="eachTask task4 saturday">Task5</div>
<div class="eachTask task4 saturday">Task6</div>
<div class="eachTask task1 tuesday">Task7</div>
<div class="eachTask task2 thursday">Task8</div>
<div class="eachTask task1 tuesday">Task9</div>
<div class="eachTask task2 thursday">Task10</div>
</div>
</div>

Rotate an item on a background image with transform and js

I have a background image and another image element as needle. So you will see 3 tabs above the snippet page. My goal is to change the position of the needle when you click to the buttons. But there are some problems like if you click 2nd or 3th tab first, the needle moves wrong direction.
And if you move between 3th and 1st tabs the bottom of needle is moving out of the black little circle.
How can I achieve my purpose without any visual errors? Maybe some other way to achieve this?
function asama3() {
document.getElementById("ibre").style.transform = "rotate(-68deg)";
document.getElementById("ibre").style.left = "210px";
document.getElementById("ibre").style.top = "178px";
}
function asama2() {
document.getElementById("ibre").style.transform = "rotate(-107deg)";
document.getElementById("ibre").style.left = "157px";
document.getElementById("ibre").style.top = "180px";
}
function asama1() {
document.getElementById("ibre").style.transform = "rotate(-145deg)";
document.getElementById("ibre").style.left = "113px";
document.getElementById("ibre").style.top = "211px";
}
#ibre {
width:150px;
position: absolute;
left: 100px;
top: 258px;
transition: all 1s;
}
<div style="cursor: pointer; float:left; background-color:red; color:#fff; width:200px;"><h1 onclick="asama1()">1. aşama</h1></div>
<div style="cursor: pointer; float:left; background-color:red; color:#fff; width:200px;"><h1 onclick="asama2()">2. aşama</h1></div>
<div style="cursor: pointer; float:left; background-color:red; color:#fff; width:200px;"><h1 onclick="asama3()">3. aşama</h1></div>
<div style="clear:both;"></div>
<div style=" background-image: url('https://i.hizliresim.com/WNguZF.png'); background-repeat:no-repeat; height:281px; width:500px;">
<div style=""><img id="ibre" style="" src="https://i.hizliresim.com/Hmuavw.png"></div>
</div>
As it rotates at the center, you can create a hidden div and wrap them both in an outer div and makes sure the center lines up with the black dot:
function asama3() {
document.getElementById("outer").style.transform = "rotate(68deg)";
}
function asama2() {
document.getElementById("outer").style.transform = "rotate(107deg)";
}
function asama1() {
document.getElementById("outer").style.transform = "rotate(145deg)";
}
#outer {
display: flex;
width: 300px;
height: 5px;
position: absolute;
left: 108px;
top: 278px;
transition: all 1s;
}
#ibre {
width: 150px;
height: 5px;
border-radius: 5px;
background-color: #070707;
}
#hidden {
width: 150px;
height: 5px;
border-radius: 5px;
background-color: transparent;
}
<div style="cursor: pointer; float:left; background-color:red; color:#fff; width:200px;">
<h1 onclick="asama1()">1. aşama</h1>
</div>
<div style="cursor: pointer; float:left; background-color:red; color:#fff; width:200px;">
<h1 onclick="asama2()">2. aşama</h1>
</div>
<div style="cursor: pointer; float:left; background-color:red; color:#fff; width:200px;">
<h1 onclick="asama3()">3. aşama</h1>
</div>
<div style="clear:both;"></div>
<div style=" background-image: url('https://i.hizliresim.com/WNguZF.png'); background-repeat:no-repeat; height:281px; width:500px;">
<div id="outer">
<div id="ibre"></div>
<div id="hidden"></div>
</div>
</div>
This way it pivots on that dot to wherever you need it pointing.
Something like this, i think
function asama3() {
document.getElementById("ibre").style.transform = "rotate(140deg)";
document.getElementById("ibre").style.left = "250px";
document.getElementById("ibre").style.top = "220px";
}
function asama2() {
document.getElementById("ibre").style.transform = "rotate(80deg)";
document.getElementById("ibre").style.left = "165px";
document.getElementById("ibre").style.top = "190px";
}
function asama1() {
document.getElementById("ibre").style.transform = "rotate(40deg)";
document.getElementById("ibre").style.top = "220px";
document.getElementById("ibre").style.left = "120px";
}
#ibre {
width:150px;
position: absolute;
left: 100px;
top: 270px;
transition: all 1s;
}
<div style="cursor: pointer; float:left; background-color:red; color:#fff; width:200px;"><h1 onclick="asama1()">1. aşama</h1></div>
<div style="cursor: pointer; float:left; background-color:red; color:#fff; width:200px;"><h1 onclick="asama2()">2. aşama</h1></div>
<div style="cursor: pointer; float:left; background-color:red; color:#fff; width:200px;"><h1 onclick="asama3()">3. aşama</h1></div>
<div style="clear:both;"></div>
<div style=" background-image: url('https://i.hizliresim.com/WNguZF.png'); background-repeat:no-repeat; height:281px; width:500px;">
<div style=""><img id="ibre" style="" src="https://i.hizliresim.com/Hmuavw.png"></div>
</div>

Dynamically assign properties and values to a javascript object

I am trying to create a week meal planner. At the moment the scenario is the following:
You click on a time of day (breakfast/lunch/dinner) + day of the week;
A list of recipes fades in;
By selecting (clicking) on a recipe you assign this recipe to the day of th week + time of day previously selected.
I want to store all this data into a JS object, ideally I would like to dynamically create the day object with breakfast/lunch/dinner as keys and recipe as the value but I'm a little stuck here. I've created a jsfiddle as a little demo of what I'm trying achieve. The problem is that when I select for e.g. recipe-1 for Monday breakfast it does correctly get stored but then, if I select recipe-2 for lunch - breakfast gets reassinged a value of 0. Can someone help me understand why is this happening and guide me to a better approach? Any suggestion/ help is very much appreciated! Thank you very much!
// find elements
var data_day = '',
time_of_day = '',
recipe = $('.recipes .recipe'),
weekly_recipes = {
'week_day': {}
};
// show list of recipes
$("[data-time]").on("click", function(){
$('.recipes').fadeIn();
time_of_day = $(this).attr('data-time');
data_day = $(this).parents('.column').attr('data-day');
});
recipe.on('click', function(){
var recipe_name = $(this).attr('data-recipe');
weekly_recipes.week_day[data_day] = {
'breakfast': 0,
'lunch': 0,
'dinner': 0
};
$('.recipes').fadeOut();
weekly_recipes.week_day[data_day][time_of_day] = recipe_name;
$('.meal-plan').text(JSON.stringify(weekly_recipes));
console.log(weekly_recipes);
});
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
.column{
width: 25%;
float: left;
padding: 10px;
}
.column strong{
display: block;
margin-bottom: 20px;
}
.column .wrp{
background: white;
}
.column [data-time]{
cursor: pointer;
margin-bottom: 10px;
}
.recipes{
width: 100%;
display: none;
clear: both;
margin-top: 40px;
background: white;
}
.recipes span{
display: block;
cursor: pointer;
margin-top: 10px;
}
.meal-plan{
margin-top: 20px;
background: white;
clear: both;
margin-top: 40px;
background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="column" data-day="monday">
<div class="wrp">
<strong>Monday</strong>
<div data-time="breakfast">Breakfast</div>
<div data-time="lunch">Lunch</div>
<div data-time="dinner">Dinner</div>
</div>
</div>
<div class="column" data-day="tuesday">
<div class="wrp">
<strong>Tuesday</strong>
<div data-time="breakfast">Breakfast</div>
<div data-time="lunch">Lunch</div>
<div data-time="dinner">Dinner</div>
</div>
</div>
<div class="column" data-day="wednesday">
<div class="wrp">
<strong>Wednesday</strong>
<div data-time="breakfast">Breakfast</div>
<div data-time="lunch">Lunch</div>
<div data-time="dinner">Dinner</div>
</div>
</div>
<div class="recipes">
<div class="recipe" data-recipe="recipe-1">
<span data-recipe="recipe-1">recipe 1</span>
</div>
<div class="recipe" data-recipe="recipe-2">
<span data-recipe="recipe-2">recipe 2</span>
</div>
</div>
<div class="meal-plan">
</div>
</div>
You were almost there but the whole issue was that you were resetting the object to default 0 value everytime the user clicks on the recepie.
Instead you need to put some check that if it is already initialized then dont reset it to default.
I have added the below code:
if(!weekly_recipes.week_day.hasOwnProperty(data_day) || Object.keys(weekly_recipes.week_day[data_day]).length === 0){
weekly_recipes.week_day[data_day] = {
'breakfast': 0,
'lunch': 0,
'dinner': 0
};
}
See the working code below:
// find elements
var data_day = '',
time_of_day = '',
recipe = $('.recipes .recipe'),
weekly_recipes = {
'week_day': {}
};
// show list of recipes
$("[data-time]").on("click", function() {
$('.recipes').fadeIn();
time_of_day = $(this).attr('data-time');
data_day = $(this).parents('.column').attr('data-day');
});
recipe.on('click', function() {
var recipe_name = $(this).attr('data-recipe');
console.log(weekly_recipes.week_day[data_day]);
if (!weekly_recipes.week_day.hasOwnProperty(data_day) || Object.keys(weekly_recipes.week_day[data_day]).length === 0) {
weekly_recipes.week_day[data_day] = {
'breakfast': 0,
'lunch': 0,
'dinner': 0
};
}
$('.recipes').fadeOut();
weekly_recipes.week_day[data_day][time_of_day] = recipe_name;
$('.meal-plan').text(JSON.stringify(weekly_recipes));
console.log(weekly_recipes);
});
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
.column {
width: 25%;
float: left;
padding: 10px;
}
.column strong {
display: block;
margin-bottom: 20px;
}
.column .wrp {
background: white;
}
.column [data-time] {
cursor: pointer;
margin-bottom: 10px;
}
.recipes {
width: 100%;
display: none;
clear: both;
margin-top: 40px;
background: white;
}
.recipes span {
display: block;
cursor: pointer;
margin-top: 10px;
}
.meal-plan {
margin-top: 20px;
background: white;
clear: both;
margin-top: 40px;
background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="column" data-day="monday">
<div class="wrp">
<strong>Monday</strong>
<div data-time="breakfast">Breakfast</div>
<div data-time="lunch">Lunch</div>
<div data-time="dinner">Dinner</div>
</div>
</div>
<div class="column" data-day="tuesday">
<div class="wrp">
<strong>Tuesday</strong>
<div data-time="breakfast">Breakfast</div>
<div data-time="lunch">Lunch</div>
<div data-time="dinner">Dinner</div>
</div>
</div>
<div class="column" data-day="wednesday">
<div class="wrp">
<strong>Wednesday</strong>
<div data-time="breakfast">Breakfast</div>
<div data-time="lunch">Lunch</div>
<div data-time="dinner">Dinner</div>
</div>
</div>
<div class="recipes">
<div class="recipe" data-recipe="recipe-1">
<span data-recipe="recipe-1">recipe 1</span>
</div>
<div class="recipe" data-recipe="recipe-2">
<span data-recipe="recipe-2">recipe 2</span>
</div>
</div>
<div class="meal-plan">
</div>
</div>
Your code is very near to work, you only need to take care when the object of some day already exists to not create it again.
See below code, you just create a new day when it doesn't exist, if it already exists, then just add the recipe to the time_of_day of that day
var data_day = '',
time_of_day = '',
recipe = $('.recipes .recipe'),
weekly_recipes = {
'week_day': {}
};
$("[data-time]").on("click", function(){
$('.recipes').fadeIn();
time_of_day = $(this).attr('data-time');
data_day = $(this).parents('.column').attr('data-day');
});
recipe.on('click', function(){
var recipe_name = $(this).attr('data-recipe');
//CHECK FOR DAY EXISTANCE
if (weekly_recipes.week_day[data_day] == null || !weekly_recipes.week_day.hasOwnProperty(data_day)){
weekly_recipes.week_day[data_day] = {
'breakfast': 0,
'lunch': 0,
'dinner': 0
};
}
weekly_recipes.week_day[data_day][time_of_day] = recipe_name;
$('.recipes').fadeOut();
$('.meal-plan').text(JSON.stringify(weekly_recipes));
console.clear()
console.log(weekly_recipes);
});
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
.column{
width: 25%;
float: left;
padding: 10px;
}
.column strong{
display: block;
margin-bottom: 20px;
}
.column .wrp{
background: white;
}
.column [data-time]{
cursor: pointer;
margin-bottom: 10px;
}
.recipes{
width: 100%;
display: none;
clear: both;
margin-top: 40px;
background: white;
}
.recipes span{
display: block;
cursor: pointer;
margin-top: 10px;
}
.meal-plan{
margin-top: 20px;
background: white;
clear: both;
margin-top: 40px;
background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="column" data-day="monday">
<div class="wrp">
<strong>Monday</strong>
<div data-time="breakfast">Breakfast</div>
<div data-time="lunch">Lunch</div>
<div data-time="dinner">Dinner</div>
</div>
</div>
<div class="column" data-day="tuesday">
<div class="wrp">
<strong>Tuesday</strong>
<div data-time="breakfast">Breakfast</div>
<div data-time="lunch">Lunch</div>
<div data-time="dinner">Dinner</div>
</div>
</div>
<div class="column" data-day="wednesday">
<div class="wrp">
<strong>Wednesday</strong>
<div data-time="breakfast">Breakfast</div>
<div data-time="lunch">Lunch</div>
<div data-time="dinner">Dinner</div>
</div>
</div>
<div class="recipes">
<div class="recipe" data-recipe="recipe-1">
<span data-recipe="recipe-1">recipe 1</span>
</div>
<div class="recipe" data-recipe="recipe-2">
<span data-recipe="recipe-2">recipe 2</span>
</div>
</div>
<div class="meal-plan"></div>

Add image below a certain class of element using css

What I want to do:
I want to add a "walkingMan" image under an element when its class is changed to activeCell. I know how to do it when the image is added to the front or back of the element using pseudo class, but as far as I know, there isn't something like :below that I can use to achieve the same effect. Is there a way in css I can use to micmic this?
What I have done:
I have added image below every upper cell and make it visible when the class is changed to activeCell. But I hope to find a more simple solution.
What it looks like:
Code: Simplified Code Example
You can use a single pseudo element on the .cell element and place a background image on it when it's active.
let activeIndex = 0;
const cells = [...document.querySelectorAll('.cell')];
setInterval(() => {
cells.forEach(cell => {
cell.classList.remove('activeCell')
});
cells[activeIndex].classList.add('activeCell');
activeIndex = activeIndex === cells.length - 1 ? 0 : (activeIndex + 1);
}, 300)
.cell {
display: inline-block;
border: 1px solid black;
margin-bottom: 1.2em;
}
.activeCell {
background-color: lightgrey;
position: relative;
}
.activeCell::after {
content: "";
position: absolute;
width: 1em;
height: 1em;
top: 1.3em;
left: calc(50% - .5em); /* Center the stickman. Position it half of its width before the parent center*/
background-image: url('https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png');
background-size:cover; /* Scale the stickman to completely cover the background area. */
}
<div>
<div class='top'>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
<div class='bottom'>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
</div>
What about this: https://jsfiddle.net/147prwy5/3/
HTML
<div class="cell active">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
<div class="cell">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
<div class="cell">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
<div class="cell active">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
CSS
.cell {
display: inline-block;
}
.cell a {
border: 1px solid black;
}
.cell.active a {
background-color: lightgrey;
}
.cell img {
width: 20px;
height: 20px;
display: none;
}
.cell.active img {
margin-top: 5px;
width: 20px;
height: 20px;
display: block;
}
I've never been a fan of the ::before and ::after pseudo classes mainly because I've personally noticed some oddities when trying to position things in Chrome vs IE (damn it IE!). Since most people here are going to give a solution using these pseudo classes (because that's somewhat what you asked) I thought I'd give a different solution using flexbox and more divs.
Not the most optimal for download size but I do like that it's not absolute positioning elements and if the squares get bigger or smaller it's pretty easy to handle that as a scss variable at the top of the file. This all uses only two values, your padding between boxes and the size of the boxes so it should be easy to update and maintain.
Anyway, have fun! Awesome question by the way :-)
.blocks {
display: flex;
}
.block {
flex: 0 0 20px;
margin: 0px 5px;
display: flex;
flex-direction:column;
}
.block > .square {
flex: 0 0 20px;
margin: 5px 0px;
background: grey;
}
.block > .space {
flex: 0 0 20px;
margin: 5px 0px;
}
.block.activeCell > .space {
background: green;
}
<div class="blocks">
<div class="block activeCell"><div class="square"></div><div class="space"></div></div>
<div class="block"><div class="square"></div><div class="space"></div></div>
<div class="block"><div class="square"></div><div class="space"></div></div>
<div class="block"><div class="square"></div><div class="space"></div></div>
</div>
<div class="blocks">
<div class="block"><div class="square"></div></div>
<div class="block"><div class="square"></div></div>
<div class="block"><div class="square"></div></div>
<div class="block"><div class="square"></div></div>
</div>
Using jQuery you can toggle the class upon clicking with this:
$('.cell').click(function() { //catch clicks on .cell
$('.cell').removeClass('activeCell'); //remove class "activeCell" from all
$(this).addClass('activeCell'); //add class "activeCell" to .cell clicked
});
Apply position: relative; to .top and .bottom:
.top,
.bottom {
position: relative;
}
And use the psuedoclass :before to create a image under the .activeCell
.activeCell:before {
content: "";
position: absolute;
bottom: -20px;
height: 20px;
width: 20px;
background-image: url("https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png");
background-size: 20px 20px;
}
And remove this:
.walkingMan {
width: 20px;
height: 20px;
display: inline-block
}
And this:
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" class='walkingMan'/>
And to add space between the divs .top and .bottom put a <br> between them.
$('.cell').click(function() {
$('.cell').removeClass('activeCell');
$(this).addClass('activeCell');
});
.cell {
display: inline-block;
border: 1px solid black;
cursor: pointer;
}
.top,
.bottom {
position: relative;
}
.activeCell {
background-color: lightgrey;
}
.activeCell:before {
content: "";
position: absolute;
bottom: -20px;
height: 20px;
width: 20px;
background-image: url("https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png");
background-size: 20px 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div>
<div class='top'>
<a class='cell activeCell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
<br>
<div class='bottom'>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
</div>
add .RunManActive Class for Active element
//clicking add active Class
$(".RunMan").click(function() {
$(".RunMan").removeClass('RunManActive');
$(this).toggleClass('RunManActive');
});
//timing add active Class
var i=0;
var $elm=$(".Animate");
setInterval(function(){
$elm.removeClass('RunManActive');
$elm.eq(i).toggleClass('RunManActive');
i=$elm.length<=i?0:i+1;
}, 1000);
.RunMan{
width:35px;
height:35px;
background-color:lightgray;
border:3px solid #fff;
float:left;
position: relative;
}
.RunManActive{
background-color:#eee;
border:3px solid lightgray;
}
.RunManActive > div{
width:35px;
height:35px;
position: absolute;
background-image:url(http://www.iconsfind.com/wp-content/uploads/2013/11/Objects-Running-man-icon.png);
background-size:cover;
top:100%;
margin-top:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="RunMan"><div></div></div>
<div class="RunMan RunManActive"><div></div></div>
<div class="RunMan"><div></div></div>
<div class="RunMan"><div></div></div>
<div class="RunMan"><div></div></div>
<br><br><br><br><br><br>
<div style=" width:100%">
<div class="Animate RunMan"><div></div></div>
<div class="Animate RunMan "><div></div></div>
<div class="Animate RunMan"><div></div></div>
<div class="Animate RunMan"><div></div></div>
<div class="Animate RunMan"><div></div></div>
You can do something like this, using CSS only. With :target selector you can apply a style to the element you need to hide / show.
.container {
display: inline-block;
width: 100px;
height: 200px;
}
.link {
display: block;
width: 100px;
height: 100px;
background: #ccc;
}
.walking-man {
display: none;
width: 100px;
height: 100px;
background: red;
}
#p1:target {
display: block;
}
#p2:target {
display: block;
}
#p3:target {
display: block;
}
#p4:target {
display: block;
}
height: 90px;
float: left;
}
.walking-man img {
width: 100%;
}
.walkin-man:target {
display: block;
}
<div class="container">
<div id="p1" class="walking-man"></div>
</div>
<div class="container">
<div id="p2" class="walking-man"></div>
</div>
<div class="container">
<div id="p3" class="walking-man"></div>
</div>
<div class="container">
<div id="p4" class="walking-man"></div>
</div>

Set div's left value based on grandparent element

I have an absolute div nested inside a relative div. I want the absolute div's left value to be relative to the grandparent's position, but still allow it's height to be relative to it's parent element. Here is where the page is: http://pixeloft.com/clients/supportcenter/facilitators/
I want the left value of the bio element to always have the left value of the first "Frank Abdale" on click.
Is this possible by setting the div's left value through js?
Here is my code: http://jsfiddle.net/6RQ3u/
HTML:
<div class="person">
<div class="person-info"> <a class="showBio" target="1">
<h4>Name 1</h4></a>
<div class="arrow" id="arrow-1">^</div>
</div>
<div class="bio-wrapper">
<div class="bio" id="bio-box-1"><a class="hideBio" target="1">X</a>Bio</div>
</div>
</div>
<div class="person">
<div class="person-info"> <a class="showBio" target="2">
<h4>Name 2</h4></a>
<div class="arrow" id="arrow-2">^</div>
</div>
<div class="bio-wrapper">
<div class="bio" id="bio-box-2"><a class="hideBio" target="2">X</a>Bio</div>
</div>
</div>
<div class="person">
<div class="person-info"> <a class="showBio" target="3">
<h4>Name 3</h4></a>
<div class="arrow" id="arrow-3">^</div>
</div>
<div class="bio-wrapper">
<div class="bio" id="bio-box-3"><a class="hideBio" target="3">X</a>Bio</div>
</div>
</div>
CSS:
.person a h4 {
color: #000;
font-weight: normal;
font-size: 18px;
line-height: 21px;
width: 100px;
}
.bio {
border-top: 18px solid #387496;
position:absolute;
width:618px!important;
float:left;
background-color:#d8edf4;
padding:15px 170px;
top:284px;
left:-19px;
display:none;
z-index:200;
clear: both;
}
.person {
width:164px;
margin-right:20px;
float:left;
display:inline;
margin-bottom:30px;
position: relative;
}
.person-info {
float:left;
}
.showBio {
float:left;
}
.hideBio {
float:right;
color:#fff!important;
font-size:11px;
position: absolute;
right: 10px;
top: -14px;
}
.arrow {
display:none;
background: url('images/bio-arrow.jpg') no-repeat -2px -6px #fff;
float: left;
display: block;
clear: both;
width: 30px;
height: 15px;
text-indent: -3000px;
}
a{cursor:pointer;}
JQuery:
jQuery(function () {
jQuery('.bio').hide();
jQuery('.arrow').hide();
jQuery('.showBio').click(function () {
jQuery('.bio').hide();
jQuery('.arrow').hide();
jQuery('#bio-box-' + $(this).attr('target')).slideToggle('fast');
jQuery('#arrow-' + $(this).attr('target')).slideToggle('fast');
});
jQuery('.hideBio').click(function () {
jQuery('#bio-box-' + $(this).attr('target')).slideToggle('slow');
jQuery('#arrow-' + $(this).attr('target')).slideUp();
});
});
Thanks for all your help!

Categories

Resources