Remove parent div in product grid - javascript

Firstly I want to apologize for my English. I have a html template for shop and it has interesting structure of product grid in category page:
HTML:
<div class="product-line">
<div class="product">
<div class="product-small"></div>
<div class="product-big"></div>
</div>
<div class="product">
<div class="product-small"></div>
<div class="product-big"></div>
</div>
<div class="product">
<div class="product-small"></div>
<div class="product-big"></div>
</div>
</div>
<div class="product-line">
<div class="product">
<div class="product-small"></div>
<div class="product-big"></div>
</div>
<div class="product">
<div class="product-small"></div>
<div class="product-big"></div>
</div>
<div class="product">
<div class="product-small"></div>
<div class="product-big"></div>
</div>
</div>
CSS:
.content-center .product-line {
position: relative;
height: 238px;
margin-bottom: 30px;
}
.content-center .product-line .product {
position: absolute;
color: #534741;
}
.content-center .product:nth-child(1) {
top: 0;
left: 0;
}
.content-center .product:nth-child(2) {
top: 0;
left: 330px;
}
.content-center .product:nth-child(3) {
top: 0;
left: 660px;
}
.content-center .product-small {
box-sizing: border-box;
width: 300px;
height: 238px;
background: #fcfcfc;
border: 1px solid #dbdbdb;
box-shadow: inset 0 0 10px #dbdbdb;
padding: 20px;
position: relative;
}
.content-center .product-big {
box-sizing: border-box;
width: 630px;
min-height: 506px;
background: #fcfcfc;
border: 1px solid #dbdbdb;
box-shadow: inset 0 0 10px #dbdbdb;
padding: 20px;
position: relative;
display: none;
}
JS:
$('.detail').on('click', function() {
var _this = $(this);
var parentProduct = _this.closest('.product');
var parentLine = _this.closest('.product-line');
var index = parentProduct.index();
var eq1 = parentLine.find('.product').eq(0);
var eq2 = parentLine.find('.product').eq(1);
var eq3 = parentLine.find('.product').eq(2);
$('.product-small').show();
$('.product-big').hide();
$('.product-line').css('height', '237px');
$('.product').removeAttr('style');
switch (index)
{
case 0:
eq1.css({'left' : 0, 'top' : 0});
eq2.css({'left' : '660px', 'top' : 0});
eq3.css({'left' : '660px', 'top' : '268px'});
break;
case 1:
eq1.css({'left' : 0, 'top' : 0});
eq2.css({'left' : '330px', 'top' : 0});
eq3.css({'left' : 0, 'top' : '268px'});
break;
case 2:
eq1.css({'left' : 0, 'top' : 0});
eq2.css({'left' : 0, 'top' : '268px'});
eq3.css({'left' : '330px', 'top' : 0});
break;
}
parentProduct.find('.product-big').show();
parentProduct.find('.product-small').hide();
parentLine.css('height', parentProduct.find('.product-big').innerHeight());
});
Is it possible to make same functional but use only one block where products stored.
Now I have a lot of blocks where stored 3 products(x lines per 3 products), and I need to make only one block and unlimited products. For example make something like that:
<div class="product-line">
<div class="product">
<div class="product-small"></div>
<div class="product-big"></div>
</div>
<div class="product">
<div class="product-small"></div>
<div class="product-big"></div>
</div>
<div class="product">
<div class="product-small"></div>
<div class="product-big"></div>
</div>
<div class="product">
<div class="product-small"></div>
<div class="product-big"></div>
</div>
<div class="product">
<div class="product-small"></div>
<div class="product-big"></div>
</div>
</div>
I'm tried to use float:left method, but when i click "detail" button the grid is braking.
Site with current functional: link

Generally, use float, but float:right every 2nd and 3rd items
selected product should have a class 'selected';
don't use style attribute (always important to separate style and content)
.product { float: left; }
.product.selected:nth-child(3n),
.product.selected:nth-child(3n+2) { float: right; }
.product.product-small { display: block; }
.product.selected .product-small { display: none; }
.product.product-big{ display: none; }
.product.selected .product-big{ display: block; }
you'll probably have problems that now #content-main is considered empty, but I believe you'll be able to manage that (try clear:both).

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>

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>

How can i filter a list of divs when 2 checkboxes are checked using jquery or javascript?

I have a list of 4 divs and i use 2 checkboxes to filter the list by the existence of specific divs. The filtering works perfect until i check both 2 checkboxes.
As you can see in my code below if you try to check both "Card" & "Paypal" checkboxes the list is disappeared. Instead i need to display all of 4 divs. How can i make it work this way?
Here's the code:
$("#by-card").change(function() {
$('.store-block .store-payment-options').each(function() {
if ($(this).find('.card-available').length === 0) {
$(this).parent(".store-block").toggleClass('hide-me');
}
});
});
$("#by-paypal").change(function() {
$('.store-block .store-payment-options').each(function() {
if ($(this).find('.paypal-available').length === 0) {
$(this).parent(".store-block").toggleClass('hide-me');
}
});
});
.search-area {
margin-bottom: 10px;
}
.storesList {
margin-top: 20px;
}
#count {
display: inline-block;
}
.store-block {
width: 80%;
margin-bottom: 10px;
padding: 5px;
background: #e5e5e5;
position: relative;
overflow: hidden;
}
.rating {
position: absolute;
right: 70px;
top: 3px;
}
.minorder {
position: absolute;
right: 180px;
top: 3px;
}
.paypal-available,
.card-available {
position: absolute;
right: 10px;
top: 5px;
font-size: 11px;
font-weight: bold;
color: blue;
}
.right {
float: right;
}
.left {
float: left;
}
.hide-me {
display: none;
}
.checkbox-lab {
font-size: 12px;
font-weight: bold;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="checkboxes-area">
<div class=" inputRadioGroup">
<input type="checkbox" id="by-card">
<label for="by-card">Card</label>
</div>
<div class=" inputRadioGroup">
<input type="checkbox" id="by-paypal">
<label for="by-paypal">Paypal</label>
</div>
</div>
<div class="storesList">
<div class="store-block">
<div class="store-name">Apple Store</div>
<div class="rating">&bigstar; 4.5</div>
<div class="minorder">100 €</div>
<div class="store-payment-options">
<div class="card-available">CARD</div>
</div>
</div>
<div class="store-block">
<div class="store-name">Nokia Store</div>
<div class="rating">&bigstar; 3.8</div>
<div class="minorder">250 €</div>
<div class="store-payment-options">
<div class="paypal-available">PAYPAL</div>
</div>
</div>
<div class="store-block">
<div class="store-name">Samsung Store</div>
<div class="rating">&bigstar; 4.0</div>
<div class="minorder">25 €</div>
<div class="store-payment-options">
<div class="card-available">CARD</div>
</div>
</div>
<div class="store-block">
<div class="store-name">Linux</div>
<div class="rating">&bigstar; 4.9</div>
<div class="minorder">50 €</div>
<div class="store-payment-options">
<div class="paypal-available">PAYPAL</div>
</div>
</div>
</div>
To get that behaviour you need to change the code which you have:
You need to have a single change function for the checkboxes of paypal and card
Then whenever any of the checkbox is checked/unchecked, you can loop both the checkboxes to know if any of them is checked. If you get the checkbox checked then show the elements with class store-block where I have also added one more class same as the id value of the checkbox that is clicked.
Using this class value it will be easy to determine the set of divs that belong to the particular checkbox.
You also need to manage the scenario when all the checkbox are unchecked after they were checked so, for that I have used a variable oneChecked.
$(".inputRadioGroup input[type='checkbox']").change(function() {
var oneChecked = false;
$(".inputRadioGroup input[type='checkbox']").each(function(){
var checked = this.checked;
var checkedId = $(this).attr('id');
if(checked){
oneChecked = true;
$('.'+checkedId).show();
} else {
$('.'+checkedId).hide();
}
});
if(!oneChecked){
$('.store-block').show();
}
});
.search-area {
margin-bottom: 10px;
}
.storesList {
margin-top: 20px;
}
#count {
display: inline-block;
}
.store-block {
width: 80%;
margin-bottom: 10px;
padding: 5px;
background: #e5e5e5;
position: relative;
overflow: hidden;
}
.rating {
position: absolute;
right: 70px;
top: 3px;
}
.minorder {
position: absolute;
right: 180px;
top: 3px;
}
.paypal-available,
.card-available {
position: absolute;
right: 10px;
top: 5px;
font-size: 11px;
font-weight: bold;
color: blue;
}
.right {
float: right;
}
.left {
float: left;
}
.hide-me {
display: none;
}
.checkbox-lab {
font-size: 12px;
font-weight: bold;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="checkboxes-area">
<div class="inputRadioGroup">
<input type="checkbox" id="by-card">
<label for="by-card">Card</label>
</div>
<div class="inputRadioGroup">
<input type="checkbox" id="by-paypal">
<label for="by-paypal">Paypal</label>
</div>
</div>
<div class="storesList">
<div class="store-block by-card">
<div class="store-name">Apple Store</div>
<div class="rating">&bigstar; 4.5</div>
<div class="minorder">100 €</div>
<div class="store-payment-options">
<div class="card-available">CARD</div>
</div>
</div>
<div class="store-block by-paypal">
<div class="store-name">Nokia Store</div>
<div class="rating">&bigstar; 3.8</div>
<div class="minorder">250 €</div>
<div class="store-payment-options">
<div class="paypal-available">PAYPAL</div>
</div>
</div>
<div class="store-block by-card">
<div class="store-name">Samsung Store</div>
<div class="rating">&bigstar; 4.0</div>
<div class="minorder">25 €</div>
<div class="store-payment-options">
<div class="card-available">CARD</div>
</div>
</div>
<div class="store-block by-paypal">
<div class="store-name">Linux</div>
<div class="rating">&bigstar; 4.9</div>
<div class="minorder">50 €</div>
<div class="store-payment-options">
<div class="paypal-available">PAYPAL</div>
</div>
</div>
</div>
I'm not good at jQuery, but here's how I'd solve that using good old plain vanilla Javascript. The key change to your approach is to listen for the change event on a parent element of both checkboxes (instead of on each checkbox with a seperate handler), then check if either, or both, or no checkboxes are checked, and create the appropriate DOM state accordingly:
var checkboxArea = document.querySelector('.checkboxes-area')
var storeBlocks = Array.from(document.querySelectorAll('.store-block'))
var byCard = document.getElementById('by-card')
var byPaypal = document.getElementById('by-paypal')
var cardBlocks = storeBlocks.filter(function(block) {
return block.querySelector('.card-available')
})
var payPalBlocks = storeBlocks.filter(function(block) {
return block.querySelector('.paypal-available')
})
checkboxArea.addEventListener('change', function(e) {
switch (true) {
case byCard.checked && byPaypal.checked:
storeBlocks.forEach(function(block) { block.classList.remove('hide-me') })
break
case byCard.checked:
cardBlocks.forEach(function(block) { block.classList.remove('hide-me') })
payPalBlocks.forEach(function(block) { block.classList.add('hide-me') })
break
case byPaypal.checked:
cardBlocks.forEach(function(block) { block.classList.add('hide-me') })
payPalBlocks.forEach(function(block) { block.classList.remove('hide-me') })
break
default:
payPalBlocks.concat(cardBlocks).forEach(function(block) { block.classList.remove('hide-me') })
}
})
.search-area {
margin-bottom: 10px;
}
.storesList {
margin-top: 20px;
}
#count {
display: inline-block;
}
.store-block {
width: 80%;
margin-bottom: 10px;
padding: 5px;
background: #e5e5e5;
position: relative;
overflow: hidden;
}
.rating {
position: absolute;
right: 70px;
top: 3px;
}
.minorder {
position: absolute;
right: 180px;
top: 3px;
}
.paypal-available,
.card-available {
position: absolute;
right: 10px;
top: 5px;
font-size: 11px;
font-weight: bold;
color: blue;
}
.right {
float: right;
}
.left {
float: left;
}
.hide-me {
display: none;
}
.checkbox-lab {
font-size: 12px;
font-weight: bold;
cursor: pointer;
}
<div class="checkboxes-area">
<div class="inputRadioGroup">
<input type="checkbox" id="by-card">
<label for="by-card">Card</label>
</div>
<div class="inputRadioGroup">
<input type="checkbox" id="by-paypal">
<label for="by-paypal">Paypal</label>
</div>
</div>
<div class="storesList">
<div class="store-block">
<div class="store-name">Apple Store</div>
<div class="rating">&bigstar; 4.5</div>
<div class="minorder">100 €</div>
<div class="store-payment-options">
<div class="card-available">CARD</div>
</div>
</div>
<div class="store-block">
<div class="store-name">Nokia Store</div>
<div class="rating">&bigstar; 3.8</div>
<div class="minorder">250 €</div>
<div class="store-payment-options">
<div class="paypal-available">PAYPAL</div>
</div>
</div>
<div class="store-block">
<div class="store-name">Samsung Store</div>
<div class="rating">&bigstar; 4.0</div>
<div class="minorder">25 €</div>
<div class="store-payment-options">
<div class="card-available">CARD</div>
</div>
</div>
<div class="store-block">
<div class="store-name">Linux</div>
<div class="rating">&bigstar; 4.9</div>
<div class="minorder">50 €</div>
<div class="store-payment-options">
<div class="paypal-available">PAYPAL</div>
</div>
</div>
</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>

jQuery Flip: Why is only my text turning and not .card?

I'm using the jQuery Flip Plugin. I'm trying to have a couple of cards on top of each other and when the user clicks on a card, it should turn and show the backside. But now only the text is flipping and not the card behind the text. I managed to have it wokring before, but I had to make classes for front and back.
$(function() {
$(".card").flip({
axis: "y",
reverse: "false",
trigger: "click",
speed: 700,
});
});
.card {
position: absolute;
width: 400px;
height: 248px;
margin: 2px;
background-color: #F3ECE2;
border: 5px blue solid;
padding: 10px;
border-radius: 25px;
}
#card-1 {
left: 0px;
top: 0px;
z-index: 1;
}
#card-2 {
left: 10px;
top: -238px;
z-index: 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/nnattawat/flip/v1.0.16/dist/jquery.flip.min.js"></script>
<div class="card" id="card-1">
<div>
Front1
</div>
<div>
Back1
</div>
</div>
<div class="card" id="card-2">
<div>
Front2
</div>
<div>
Back2"
</div>
</div>
From my understanding of the website, you need to add front and back classes to the corresponding div's, as shown:
$(function() {
$(".card").flip({
axis: "y",
reverse: "false",
trigger: "click",
speed: 700,
});
});
.card{
width:200px;
height:100px;
position:relative;
}
.front,
.back {
background-color: #F3ECE2;
border: 5px blue solid;
padding: 10px;
border-radius: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/nnattawat/flip/v1.0.16/dist/jquery.flip.min.js"></script>
<div class="card" id="card-1">
<div class="front">
Front1
</div>
<div class="back">
Back1
</div>
</div>
<div class="card" id="card-2">
<div class="front">
Front2
</div>
<div class="back">
Back2
</div>
</div>

Categories

Resources