How to capture the inner dataset attribute value through javascript click? - javascript

I want to capture data-name and data-price when I click, and throw the captured data into the fields in the show block respectively.
But now because the price_item is clicked, it seems that only the data-name can be captured, and the internal data-price data cannot be obtained!
I want to ask how to rewrite the data to capture the data-name and data-price data at the same time?
I need everyone for the help, thank you all.
let coin_total = document.querySelector('.coin_total');
let item = document.querySelectorAll('.price_item');
let price = document.querySelector('.real-price');
function showplan(e) {
const target = e.currentTarget;
const selectedPlan = target.dataset.plan;
const selectedPrice = target.dataset.price;
item.forEach(el => el.classList.remove('active'))
coin_total.textContent = selectedPlan;
price.textContent = selectedPrice;
console.log(price);
}
item.forEach(el => el.addEventListener('click', showplan));
.price-content {
display: flex;
}
.price-content .price_item {
padding: 30px;
border: 1px solid #222;
border-radius: 4px;
margin: 10px;
}
<ul class="price-content">
<li class="price_item" data-plan="BASE">
<div class="price_item_plan">
<h2 class="name">BASE</h2>
<p class="coin">3,000 point</p>
</div>
<div class="price_item_cost">
<h3 class="price" data-price="3000"><span class="symbol">$</span>3,000</h3>
</div>
</li>
<li class="price_item" data-plan="Luxury">
<div class="price_item_plan">
<h2 class="name">luxury</h2>
<p class="coin">9,000 point</p>
</div>
<div class="price_item_cost">
<h3 class="price" data-price="9000"><span class="symbol">$</span>9,000</h3>
</div>
</li>
</ul>
<div class="show">
<p class="coin_total">60,000點(豪華版)</p>
<p class="real-price">$9,000</p>
</div>

The 'data-price' attribute is in the h3 tags, which are not being read in the event listener.
Put the 'data-price' attribute in every li with class 'price_item', the same way it is already done with 'data-plan'.

You have data-plan on the <li>, but data-price is on the <h3>.
You would have to get data-price from the <h3> directly, you can't access that from the dataset on the <li>.

I don't see the data-name in the code, but infer from your code it should refer to the data-plan, simply use getAttribute to get the attribute
const item = document.querySelectorAll('.price_item');
function showPlan(){
const show =
document.querySelectorAll('.show p');
show[0].textContent =
this.getAttribute('data-plan');
show[1].textContent =
this.querySelector('.price').getAttribute('data-price');
}
item.forEach(e => e.addEventListener('click', showPlan));
.price-content {
display: flex;
}
.price-content .price_item {
padding: 30px;
border: 1px solid #222;
border-radius: 4px;
margin: 10px;
}
<ul class="price-content">
<li class="price_item" data-plan="BASE">
<div class="price_item_plan">
<h2 class="name">BASE</h2>
<p class="coin">3,000 point</p>
</div>
<div class="price_item_cost">
<h3 class="price" data-price="3000"><span class="symbol">$</span>3,000</h3>
</div>
</li>
<li class="price_item" data-plan="Luxury">
<div class="price_item_plan">
<h2 class="name">luxury</h2>
<p class="coin">9,000 point</p>
</div>
<div class="price_item_cost">
<h3 class="price" data-price="9000"><span class="symbol">$</span>9,000</h3>
</div>
</li>
</ul>
<div class="show">
<p class="coin_total">60,000點(豪華版)</p>
<p class="real-price">$9,000</p>
</div>
You can also tweak how your dataset is designed, you can set both data-plan and data-price in the li tag.
For example, replace
<li class="price_item" data-plan="BASE">
with
<li class="price_item" data-plan="BASE" data-price="3000">
const item = document.querySelectorAll('.price_item');
function showPlan() {
const show =
document.querySelectorAll('.show p');
show[0].textContent =
this.getAttribute('data-plan');
show[1].textContent =
this.getAttribute('data-price');
}
item.forEach(e => e.addEventListener('click', showPlan));
.price-content {
display: flex;
}
.price-content .price_item {
padding: 30px;
border: 1px solid #222;
border-radius: 4px;
margin: 10px;
}
<ul class="price-content">
<li class="price_item" data-plan="BASE" data-price="3000">
<div class="price_item_plan">
<h2 class="name">BASE</h2>
<p class="coin">3,000 point</p>
</div>
<div class="price_item_cost">
<h3 class="price"><span class="symbol">$</span>3,000</h3>
</div>
</li>
<li class="price_item" data-plan="Luxury" data-price="9000">
<div class="price_item_plan">
<h2 class="name">luxury</h2>
<p class="coin">9,000 point</p>
</div>
<div class="price_item_cost">
<h3 class="price"><span class="symbol">$</span>9,000</h3>
</div>
</li>
</ul>
<div class="show">
<p class="coin_total">60,000點(豪華版)</p>
<p class="real-price">$9,000</p>
</div>
Or directly destructuring assignment the value from the dataset.
const {plan, price} = this.dataset;
const item = document.querySelectorAll('.price_item');
function showPlan() {
const {plan, price} = this.dataset;
const show = document.querySelectorAll('.show p');
show[0].textContent = plan;
show[1].textContent = price;
}
item.forEach(e => e.addEventListener('click', showPlan));
.price-content {
display: flex;
}
.price-content .price_item {
padding: 30px;
border: 1px solid #222;
border-radius: 4px;
margin: 10px;
}
<ul class="price-content">
<li class="price_item" data-plan="BASE" data-price="3000">
<div class="price_item_plan">
<h2 class="name">BASE</h2>
<p class="coin">3,000 point</p>
</div>
<div class="price_item_cost">
<h3 class="price"><span class="symbol">$</span>3,000</h3>
</div>
</li>
<li class="price_item" data-plan="Luxury" data-price="9000">
<div class="price_item_plan">
<h2 class="name">luxury</h2>
<p class="coin">9,000 point</p>
</div>
<div class="price_item_cost">
<h3 class="price"><span class="symbol">$</span>9,000</h3>
</div>
</li>
</ul>
<div class="show">
<p class="coin_total">60,000點(豪華版)</p>
<p class="real-price">$9,000</p>
</div>
Or put the data-plan into the tag (using the name class attribute), just like designing the data-price.
<li class="price_item">
<div class="price_item_plan">
<h2 class="name" data-plan="BASE">BASE</h2>
<p class="coin">3,000 point</p>
</div>
<div class="price_item_cost">
<h3 class="price" data-price="3000"><span class="symbol">$</span>3,000</h3>
</div>
</li>
const item = document.querySelectorAll('.price_item');
function showPlan(){
const getVal = (selector, name) =>
this
.querySelector(selector)
.getAttribute(name);
const show =
document.querySelectorAll('.show p');
show[0].textContent =
getVal('.price_item_plan .name', 'data-plan');
show[1].textContent =
getVal('.price_item_cost .price', 'data-price');
}
item.forEach(e => e.addEventListener('click', showPlan));
.price-content {
display: flex;
}
.price-content .price_item {
padding: 30px;
border: 1px solid #222;
border-radius: 4px;
margin: 10px;
}
<ul class="price-content">
<li class="price_item">
<div class="price_item_plan">
<h2 class="name" data-plan="BASE">BASE</h2>
<p class="coin">3,000 point</p>
</div>
<div class="price_item_cost">
<h3 class="price" data-price="3000"><span class="symbol">$</span>3,000</h3>
</div>
</li>
<li class="price_item">
<div class="price_item_plan">
<h2 class="name" data-plan="Luxury">luxury</h2>
<p class="coin">9,000 point</p>
</div>
<div class="price_item_cost">
<h3 class="price" data-price="9000"><span class="symbol">$</span>9,000</h3>
</div>
</li>
</ul>
<div class="show">
<p class="coin_total">60,000點(豪華版)</p>
<p class="real-price">$9,000</p>
</div>
Either way can be used as long as you know how and where to get the dataset value.

Related

jQuery onClick create number of div blocks based on available list items (Eg: Image src, heading text etc...)

Having the dynamic list items which has checkbox, label, text, image etc...
Based on number of items (<li>'s), I want to create input fields with index numbers (Item 1, Item 2, etc...) dynamically.
jsFiddle
Currently it is working as expected for Checkboxes and lablels by using below code.
let $checkboxContent = $('.checkboxes-content');
$(document).on('click', '#getCheckboxesContent', function() {
let html = $('.checkboxes :checkbox').map((i, el) => `<div class="item">Item ${i + 1}: <input type="text" value="${el.nextElementSibling.textContent}" /></div>`).get();
$checkboxContent.append(html);
});
Thanks to #Rory McCrossan for the above code.
But I also want to get the Image url and .text html.
How can I get the Image path & text for each list item.
Tried below tags without luck :(
${el.querySelectAll('li .text').textContent}
<img src="${el.querySelectAll('li img').attr('src')}" />
let $checkboxContent = $('.checkboxes-content');
$(document).on('click', '#getCheckboxesContent', function() {
let html = $('.checkboxes :checkbox').map((i, el) => `
<div class="item">
<h3 class="text">${el.querySelectAll('li .text').textContent}</h3>
Item ${i + 1}: <input type="text" value="${el.nextElementSibling.textContent}" />
<img src="${el.querySelectAll('li img').attr('src')}" />
</div>
`).get();
$checkboxContent.append(html);
});
body{font-family:verdana;font-size:14px;}
.checkboxes{padding:20px;}
ul{margin:0;padding:0;list-style:none;}
li{margin-top:10px;padding:5px;background:#efefef;}
label .lbl{margin-left:5px;}
.item{margin-top:10px;background:#efefef;padding:10px;}
h2{font-weight:bold;margin:0;padding:0;font-size:16px;}
.checkboxes-content{margin:15px;}
#getCheckboxesContent{margin-left:15px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="checkboxes">
<h2>Heading</h2>
<ul>
<li>
<h3 class="text">Hello World</h3>
<label><input type="checkbox" class="checkbox-sm" name="checkbox"><span class="lbl">Checkbox 1</span></label>
<img src="https://via.placeholder.com/100x20.png" alt="">
</li>
<li>
<h3 class="text">Lorem ipsum</h3>
<label><input type="checkbox" class="checkbox-sm" name="checkbox"><span class="lbl">Checkbox 2</span></label>
<img src="https://via.placeholder.com/50x15.png" alt="">
</li>
<li>
<h3 class="text">dolar sit amet</h3>
<label><input type="checkbox" class="checkbox-sm" name="checkbox"><span class="lbl">Checkbox 3</span></label>
<img src="https://via.placeholder.com/150x20.png" alt="">
</li>
</ul>
</div>
Get content
<div class="checkboxes-content">
</div>
You can use .closest() and .find() to get required elements texts and src.
Demo Code :
let $checkboxContent = $('.checkboxes-content');
$(document).on('click', '#getCheckboxesContent', function() {
let html = $('.checkboxes :checkbox').map((i, el) => `
<div class="item">
<h3 class="text">${$(el).closest("li").find('.text').text()}</h3>
Item ${i + 1}: <input type="text" value="${$(el).closest("li").find('.lbl').text()}" />
<img src="${$(el).closest("li").find('img').attr('src')}" />
</div>
`).get();
$checkboxContent.append(html);
});
body {
font-family: verdana;
font-size: 14px;
}
.checkboxes {
padding: 20px;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
li {
margin-top: 10px;
padding: 5px;
background: #efefef;
}
label .lbl {
margin-left: 5px;
}
.item {
margin-top: 10px;
background: #efefef;
padding: 10px;
}
h2 {
font-weight: bold;
margin: 0;
padding: 0;
font-size: 16px;
}
.checkboxes-content {
margin: 15px;
}
#getCheckboxesContent {
margin-left: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="checkboxes">
<h2>Heading</h2>
<ul>
<li>
<h3 class="text">Hello World</h3>
<label><input type="checkbox" class="checkbox-sm" name="checkbox"><span class="lbl">Checkbox 1</span></label>
<img src="https://via.placeholder.com/100x20.png" alt="">
</li>
<li>
<h3 class="text">Lorem ipsum</h3>
<label><input type="checkbox" class="checkbox-sm" name="checkbox"><span class="lbl">Checkbox 2</span></label>
<img src="https://via.placeholder.com/50x15.png" alt="">
</li>
<li>
<h3 class="text">dolar sit amet</h3>
<label><input type="checkbox" class="checkbox-sm" name="checkbox"><span class="lbl">Checkbox 3</span></label>
<img src="https://via.placeholder.com/150x20.png" alt="">
</li>
</ul>
</div>
Get content
<div class="checkboxes-content">
</div>

How can I apply Javascript properly?

Basically, there are four containers, each containing an image, I added a script that provides the ability to view the full image. But this function only works for the first container.
const img = document.querySelector("img");
const icons = document.querySelector(".icons");
img.onclick = function(){
this.classList.toggle("active");
icons.classList.toggle("active");
}
Html:
<div class="container">
<div class="wrapper">
<a href="#">
<img src="https://www.flaticon.com/premium-icon/icons/svg/3007/3007960.svg" alt="">
</a>
<div class="title">
Jeffrey
</div>
<div class="place">
Age | City, Country</div>
</div>
<div class="content">
<p>
User Interface Designer and <br>front-end developer</p>
<div class="buttons">
<div class="btn">
<button>Message</button>
</div>
<div class="btn">
<button>Following</button>
</div>
</div>
</p>
</div>
</div>
<div class="icons">
<li><span class="fab fa-facebook-f"></span></li>
<li><span class="fab fa-twitter"></span></li>
<li><span class="fab fa-instagram"></span></li>
</div>
</div>
Updated HTML (1), some details; I changed the names for each container and wrapper, created different CSS files for each new one and it did not work, here is a part of the new updated html:
<div class="container3">
<div class="wrapper3">
<a href="#">
<img src="https://www.flaticon.com/premium-icon/icons/svg/3007/3007960.svg" alt="">
</a>
<div class="title">
Name</div>
<div class="place">
Age | City, Country</div>
</div>
<div class="content">
<p>
User Interface Designer and <br>front-end developer</p>
<div class="buttons">
<div class="btn">
<button>Message</button>
</div>
<div class="btn">
<button>Following</button>
</div>
</div>
</div>
<div class="icons">
<li><span class="fab fa-facebook-f"></span></li>
<li><span class="fab fa-twitter"></span></li>
<li><span class="fab fa-instagram"></span></li>
</div>
</div>
<script>
const images = [...document.querySelectorAll(".wrapper img, .wrapper1 img, .wrapper2 img, .wrapper3 img")];
images.forEach(img => {
img.addEventListener("click", function() {
images
.filter(img => img !== this)
.forEach(img => img.classList.remove("active"));
this.classList.toggle("active");
</script>
Modify this to your liking. Have fun...
const images = [...document.querySelectorAll(".images-2 img, .images img")];
images.forEach(img => {
img.addEventListener("click", function() {
images
.filter(img => img !== this)
.forEach(img => img.classList.remove("active"));
this.classList.toggle("active");
});
});
.images,
.images-2 {
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
}
.images-2 img,
.images img {
box-sizing: border-box;
width: 200px;
height: 100px;
object-fit: cover;
object-position: center;
margin-bottom: 1rem;
transition: all 250ms linear;
cursor: pointer;
}
.images-2 img.active,
.images img.active {
transform: scale(1.2);
box-shadow: 0px 10px 25px -10px #333;
}
<div class="images">
<img src="https://placeimg.com/640/480/nature?1" />
<img src="https://placeimg.com/640/480/nature?2" />
<img src="https://placeimg.com/640/480/nature?3" />
</div>
<div class="images-2">
<img src="https://placeimg.com/640/480/nature?4" />
<img src="https://placeimg.com/640/480/nature?5" />
<img src="https://placeimg.com/640/480/nature?6" />
</div>
You need querySelectorAll and a for loop.
Try:
const img = document.querySelectorAll("img");
for (var i = 0; i < img.length; i++) {
img[i].addEventListener("click", function(e){
console.log(e);
});
}

As it is necessary to simplify the code

I have code for mega dropdown menu on click. It works fine but code is Substandard, wrong. Is it possible to simplify it as anything? Here i writed the same action code for others
Look at the code:
$('.main-nav .first').click(function () {
$('.drop-down-container').toggleClass('visible');
});
$('.main-nav .sec').click(function () {
$('.drop-down-container-sec').toggleClass('visible')
});
$('.main-nav .rd').click(function () {
$('.drop-down-container-rd').toggleClass('visible');
});
$('.main-nav .fth').click(function () {
$('.drop-down-container-fth').toggleClass('visible');
});
$('.main-nav .fvth').click(function () {
$('.drop-down-container-fvth').toggleClass('visible');
});
HTML:
<li class="nav-item sec ">JAMOA VA O`QITUVCHILARGA<i class="fa fa-angle-down"></i>
<div class="drop-down-container-sec d-n" style="margin-left: -13em;">
<div class="row">
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-12 left " style="height: 510px;">
<h4 style="color: white">Tezkor menyu</h4>
<ul class="list-menu">
<li>Dars ishlanmalari</li>
<li>Ilg`or texnologiyalar</li>
<li>Tajriba sinovlari</li>
<li>Kasaba uyushmamiz</li>
<li>Moddiy-texnika bazamiz</li>
<li>Davlat dasturlari ijrosi</li>
<li>Me`yoriy hujjatlar</li>
<li>Maktab konsepsiyasi</li>
<li>Ustozlarimiz</li>
<li>Maktab rahbariyati</li>
<li>Kadrlar salohiyati</li>
<li>Hisobot o`rnida</li>
<li>Doimiy komissiyalar</li>
<li>Homiylarimiz</li>
<li>Hamkorlik</li>
<li>Ijodkor o`qituvchilar</li>
<li>Yilning eng yaxshi fan o`qituvchisi</li>
<li>Attestasiya materiallari</li>
<li>O`quv rejalari</li>
</ul>
<p class="all">
Umumiy yig'inda
</p>
</div>
<div class="col-md-8 col-sm-8 col-xs-12 right">
<li class="nav-item rd ">MAKTAB VA TA`LIM<i class="fa fa-angle-down"></i>
<div class="drop-down-container-rd d-n" style="margin-left: -28em">
<div class="row">
<div class="col-lg-4 col-md-3 col-sm-6 col-xs-12 left">
<h4 style="color: white">Elektron kutubxona</h4>
<ul class="list-menu">
<li>Bitiruvchilar vinetkalari</li>
<li>Maktab Nizomi</li>
<li>Maktabimiz pasporti</li>
<li>Ichki tartib-qoidalar</li>
<li>Ona-vatan madhi</li>
<li>Alifbe bayramlari</li>
<li>To`garaklarimiz</li>
<li>"Bilimlar bellashuvi" akademiya klublari</li>
<li>Fotoalbom</li>
<li>Videolavhalar</li>
<li>Tibbiy xizmat</li>
<li>Ogohlik va xavfsizlik</li>
</ul>
<p class="all">
Barcha darsliklar
</p>
</div>
<div class="col-md-8 col-sm-8 col-xs-12 right">
<div class="row">
<div class="col-md-4 col-sm-6">
<h5>Imtihonlar jadvali</h5>
<p style="color: white; font-size: 12px">Diqqat, diqqat, diqqat! Imtihon-2017. Sinovga puxta tayyorlaning!</p>
<p class="button_red_small">Batafsil</p>
</div>
<div class="col-md-4 col-sm-6">
<h5><a href="#">
Imtihonlar jadvali
</a></h5>
<p style="color: white; font-size: 12px">Diqqat, diqqat, diqqat! Imtihon-2017. Sinovga puxta tayyorlaning!</p>
<p class="button_red_small">Batafsil</p>
</div>
<div class="col-md-4 col-sm-6">
<h5>Imtihonlar jadvali</h5>
<p style="color: white; font-size: 12px">Diqqat, diqqat, diqqat! Imtihon-2017. Sinovga puxta tayyorlaning!</p>
<p class="button_red_small">Batafsil</p>
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-6">
<h5><a href="#">
Imtihonlar jadvali
</a></h5>
<p style="color: white; font-size: 12px">Diqqat, diqqat, diqqat! Imtihon-2017. Sinovga puxta tayyorlaning!</p>
<p class="button_red_small">Batafsil</p>
</div>
<div class="col-md-4 col-sm-6">
<h5>Imtihonlar jadvali</h5>
<p style="color: white; font-size: 12px">Diqqat, diqqat, diqqat! Imtihon-2017. Sinovga puxta tayyorlaning!</p>
<p class="button_red_small">Batafsil</p>
</div>
<div class="col-md-4 col-sm-6">
<h5>Imtihonlar jadvali</h5>
<p style="color: white; font-size: 12px">Diqqat, diqqat, diqqat! Imtihon-2017. Sinovga puxta tayyorlaning!</p>
<p class="button_red_small">Batafsil</p>
</div>
</div>
</div>
</div>
</div>
</li>
So dropdown menu is huge
Guys if it possible to Simplify and fix this code please help me! I just hate that kind of code.
Well, your HTML code does not contain any element with the class main-nav. But you can short your code down to something like the following.
$('.main-nav .first, .main-nav .sec, .main-nav .rd, .main-nav .fth, .main-nav .fvth').click(function() {
var s = $(this).attr("class") == "first" ? "" : "-" + $(this).attr("class")
console.log('.drop-down-container' + s)
$('.drop-down-container' + s).toggleClass('visible');
});
$('.main-nav .first, .main-nav .sec, .main-nav .rd, .main-nav .fth, .main-nav .fvth').click(function() {
var s = $(this).attr("class") == "first" ? "" : "-" + $(this).attr("class")
console.log('.drop-down-container' + s)
$('.drop-down-container' + s).toggleClass('visible');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-nav">
<div class="first">first
</div>
<div class="sec">sec
</div>
<div class="rd">rd
</div>
<div class="fth">fth
</div>
<div class="fvth">fvth
</div>
</div>
Let me simplify your code. Instead of handling each and every block separately with individual class names, change them to have common class names. Now you can easily do the toggling with any number of elements.
$('.nav-item .dropdown-toggle').click(function(){
$(this).closest('.nav-item').find('.drop-down-container').toggle('slow');
$('.navigation-tabs .dropdown-toggle').not(this).closest('.nav-item').find('.drop-down-container').hide('slow');
});
.drop-down-container {display: none;}
.navigation-tabs {padding: 0;}
.nav-item {display: block; border: 1px solid #ccc; padding: 5px; margin: 5px;}
.nav-item a {display: block; text-decoration: none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="navigation-tabs">
<li class="nav-item">
<a class="dropdown-toggle" href="#">
JAMOA VA O`QITUVCHILARGA<i class="fa fa-angle-down"></i>
</a>
<div class="drop-down-container">First container</div>
</li>
<li class="nav-item">
<a class="dropdown-toggle" href="#">
MAKTAB VA TA`LIM<i class="fa fa-angle-down"></i>
</a>
<div class="drop-down-container">Second container</div>
</li>
</ul>
You can use a code like the following.
const array = ['first', 'sec', 'rd', 'fth', 'fvth'];
array.forEach(x => {
$(`.main-nav .${x}`).click(() => $(`.drop-down-container${x === 'first' ? '' : '-'+x}`).toggleClass('visible') );
});
it will iterate the array and add the click function for .main-val .YourClass that will toggle the class for .drop-down-container-YourClass

jQuery filter to show/hide and append and remove

I am trying to create a simple filter to filter elements of the DOM by color, one part of the filter works just fine, where I click the item in the list, but what I am also trying to do is to create a tag of the selected filer with small cross, which is when clicked will reset the filter back to the previous state.
Filter HTML
<div class="accordion-content">
<ul id="color-filter">
<li class="form-checkmark is-selected" data-filter="black" data-filter-type="color"><span class="label"><span class="checkbox black checkmark"></span><span class="radio-text">Black</span></span></li>
<li class="form-checkmark" data-filter="blue" data-filter-type="color"><span class="label"><span class="checkbox blue"></span><span class="radio-text">Blue</span></span></li>
<li class="form-checkmark" data-filter="brown" data-filter-type="color"><span class="label"><span class="checkbox brown"></span><span class="radio-text">Brown</span></span></li>
<li class="form-checkmark" data-filter="green" data-filter-type="color"><span class="label"><span class="checkbox green"></span><span class="radio-text">Green</span></span></li>
</ul>
</div>
HTML Elements
<div class="grid-23 material-tiles">
<div class="selected-filters">
<div class="filter-label">YOUR ACTIVE FILTERS</div>
<div class="filter-item"><span>Black</span><span class="filter-close"></span></div>
<div class="filter-item"><span>Blue</span><span class="filter-close"></span></div>
</div>
<div class="grid-3 samples" data-color="black">
<span class="sample-name">Black</span>
</div>
<div class="grid-3 samples" data-color="black">
<span class="sample-name">Black</span>
</div>
<div class="grid-3 samples" data-color="blue">
<span class="sample-name">Blue</span>
</div>
<div class="grid-3 samples" data-color="blue">
<span class="sample-name">Blue</span>
</div>
<div class="grid-3 samples" data-color="brown">
<span class="sample-name">Brown</span>
</div>
<div class="grid-3 samples" data-color="brown">
<span class="sample-name">Brown</span>
</div>
</div>
The first part .selected-filters should show the filters that were selected
The rest are just <div> with sample colors that should be displayed or hidden, depending on the selection.
So what I am trying to archive is when filter tag is closed to show back hidden color samples and remove class .checkmark and .is-selected and at the same time close the tag <div class="filter-item"><span>Black</span><span class="filter-close"></span></div>
Or if filter is clicked again then do the same as above.
So far my attempts failed as I do not know much about js and jQuery.
jQuery
function onGridChangeRequest() {
var selected = [];
$('#color-filter').find('.is-selected').each(function(i, el) {
selected.push($(this).attr('data-filter'));
})
$('.material-tiles').find('.samples').each(function(i, el) {
if(selected.length) {
if (selected.indexOf($(el).attr('data-color')) !== -1) {
$(el).show();
return;
}
$(el).hide();
return;
}
$(el).show();
})
}
$('#color-filter > li').on('click', function(e) {
var checkBox = $('.checkbox');
var filteBlock = '<div class="filter-item"><span>'+ $(this).text() +'</span><span class="filter-close"></span></div>';
$(this).toggleClass('is-selected');
$(this).find(checkBox).toggleClass('checkmark');
$('.selected-filters').css('display','block').append(filteBlock);
$('.filter-close').on('click', function () {
$(this).parent().remove();
$('#color-filter > li').find(checkBox).removeClass('checkmark');
$('#color-filter > li').removeClass('is-selected');
$('.material-tiles').find('.samples').css('display','block');
});
onGridChangeRequest();
});
Here is Fiddle
$('#color-filter > li').on('click', function (e) {
var checkBox = $('.checkbox');
$(this).toggleClass('is-selected');
$(this).find(checkBox).toggleClass('checkmark');
var color = $.trim($(this).text());
if ($(this).find(checkBox).hasClass('checkmark')) {
var filteBlock = '<div class="filter-item"><span>' + $(this).text() + '</span><span class="filter-close">X</span></div>';
$('.selected-filters').show().append(filteBlock);
} else {
$(".filter-item span:contains('" + color + "')").parent().remove();
}
if($(".selected-filters .filter-item").length<=0){
$(".selected-filters").hide();
}
onGridChangeRequest();
});
$('body').on('click', '.filter-close', function () {
$(this).parent().remove();
var color = $.trim($(this).siblings('span').text());
$('#color-filter > li .radio-text:contains("' + color + '")').trigger('click');
onGridChangeRequest();
});
function onGridChangeRequest() {
var selected = [];
$('#color-filter').find('.is-selected').each(function(i, el) {
selected.push($(this).attr('data-filter'));
})
$('.material-tiles').find('.samples').each(function(i, el) {
if(selected.length) {
if (selected.indexOf($(el).attr('data-color')) !== -1) {
$(el).show();
return;
}
$(el).hide();
return;
}
$(el).show();
})
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="grid-13 filter">
<div class="filters-body">
<div class="accordion is-open">
<h3 class="accordion-header">COLOUR<span class="accordion-indicator"></span></h3>
<div class="accordion-content">
<ul id="color-filter">
<li class="form-checkmark" data-filter="black">
<span class="label">
<span class="checkbox black"></span>
<span class="radio-text">Black</span>
</span>
</li>
<li class="form-checkmark" data-filter="blue">
<span class="label">
<span class="checkbox blue"></span>
<span class="radio-text">Blue</span>
</span>
</li>
<li class="form-checkmark" data-filter="brown">
<span class="label">
<span class="checkbox brown"></span>
<span class="radio-text">Brown</span>
</span>
</li>
<li class="form-checkmark" data-filter="green">
<span class="label">
<span class="checkbox green"></span>
<span class="radio-text">Green</span>
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="grid-23 material-tiles">
<div class="selected-filters" style="display:none">
<div class="filter-label">YOUR ACTIVE FILTERS</div>
</div>
<div class="grid-3 samples" data-color="black">
<span class="sample-name" style="width: 100px; height:100px; display:block; margin-top:5px; background: #000;">Black</span>
</div>
<div class="grid-3 samples" data-color="black">
<span class="sample-name" style="width: 100px; height:100px; display:block; margin-top:5px; background: #000;">Black</span>
</div>
<div class="grid-3 samples" data-color="blue">
<span class="sample-name" style="width: 100px; height:100px; display:block; margin-top:5px; background: blue;">Blue</span>
</div>
<div class="grid-3 samples" data-color="blue">
<span class="sample-name" style="width: 100px; height:100px; display:block; margin-top:5px; background: blue;">Blue</span>
</div>
<div class="grid-3 samples" data-color="brown">
<span class="sample-name" style="width: 100px; height:100px; display:block; margin-top:5px; background: brown;">Brown</span>
</div>
<div class="grid-3 samples" data-color="brown">
<span class="sample-name" style="width: 100px; height:100px; display:block; margin-top:5px; background: brown;">Brown</span>
</div>
<div class="grid-3 samples" data-color="green">
<span class="sample-name" style="width: 100px; height:100px; display:block; margin-top:5px; background: green;">Green</span>
</div>
<div class="grid-3 samples" data-color="green">
<span class="sample-name" style="width: 100px; height:100px; display:block; margin-top:5px; background: green;">Green</span>
</div>
</div>
I have updated your fiddle now its working please have a look.
Basically there was two problems:
One is that you are not checked for condition if checkbox is not checked.
I have just checked for checkmark class i.e. $(this).find(checkBox).hasClass('checkmark') if this is true then we'll just append the filter nothing else. if it is not true then we ll remove that filter and then called your onGridChangeRequest() method which'll filter among samples.
Another one was, you need to do same logic if you removed filter directly. One thing is you are adding filter dynamically so click() event directly will not work for close filter because click() binding you're using is called a "direct" binding which will only attach the handler to elements that already exist. It won't get bound to elements created in the future. To do that, you'll have to create a "delegated" binding by using on() so used $('body').on('click', '.filter-close', function () {}. Main thing from filter we will get the color name & will trigger manually click event of li which has that color, so automatically our radio button click logic will call & you acheive same result.
One of the main selector used here is contains attribute.

HTML, CSS and JS not linking properly

I am trying to build a quiz using the code from this codepen (code posted in snippet below).
$(document).ready(function() {
//get total of questions
var $questionNumber = $('h2').length;
console.log($questionNumber);
//caching final score
var $totalScore = 0;
$('li').click(function() {
//caching variables
var $parent = $(this).parent();
var $span = $(this).find('.fa');
//deactivate options on click
$parent.find('li').off("click");
//check for .correct class
//if yes
if ($(this).hasClass('correct')) {
//add .correctAnswer class
$(this).addClass('correctAnswer');
//find next span and change icon
$span.removeClass('fa fa-square-o').addClass('fa fa-check-square-o');
//reduce opacity of siblings
$(this).siblings().addClass('fade');
//show answer
var $answerReveal = $parent.next('.answerReveal').show();
var $toShowCorrect = $answerReveal.find('.quizzAnswerC');
var $toShowFalse = $answerReveal.find('.quizzAnswerF');
$toShowCorrect.show();
$toShowFalse.remove();
//add 1 to total score
$totalScore += 1;
//console.log($totalScore);
} else {
//add .wrongAnswer class
$(this).addClass('wrongAnswer').addClass('fade');
//change icon
$span.removeClass('fa fa-square-o').addClass('fa fa-check-square-o');
//reduce opacity of its siblings
$(this).siblings().addClass('fade');
//show wrong Message
var $answerReveal = $parent.next('.answerReveal').show();
var $toShowCorrect = $answerReveal.find('.quizzAnswerC');
var $toShowFalse = $answerReveal.find('.quizzAnswerF');
$toShowCorrect.remove();
$toShowFalse.show();
//locate correct answer and highlight
$parent.find('.correct').addClass('correctAnswer');
};
}); //end click function
//print Results
function printResult() {
var resultText = '<p>';
if ($totalScore === $questionNumber) {
resultText += 'You got ' + $totalScore + ' out of ' + $questionNumber + '! </p>';
$('.resultContainer').append(resultText);
$('#halfText').append('<p>This is awesome!</p>');
$('#halfImage').append('<img src="http://placehold.it/350x150" width="100%"><img>');
} else if ($totalScore >= 3 && $totalScore < $questionNumber) {
resultText += 'You got ' + $totalScore + ' out of ' + $questionNumber + '! </p>';
$('.resultContainer').append(resultText);
$('#halfText').append('<p>So and so...better luck next time</p>');
$('#halfImage').append('<img src="http://placehold.it/350x150" width="100%"><img>');
} else if ($totalScore < 3) {
resultText += 'You got ' + $totalScore + ' out of ' + $questionNumber + ' </p>';
$('.resultContainer').append(resultText);
$('#halfText').append('<p>No..no...no...you have to try harder</p>');
$('#halfImage').append('<img src="http://placehold.it/350x150" width="100%"><img>');
}
}; //end function
//final score
$('ul').last().click(function() {
//prevent further clicks on this
$(this).off('click');
//show result after last li is clicked
var $height = $('.finalResult').height();
printResult();
$('.finalResult').show();
$('html, body').animate({
scrollTop: $(document).height() - $height
},
1400);
});
}); //end dom ready
#import url("//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css");
body {
background: #fff;
font-family: 'Open Sans', sans-serif;
font-size: 1em;
}
.container {
width: 100%;
}
.inner {
width: 60%;
margin: 0 auto;
}
ul {
list-style-type: none;
margin-left: -40px;
}
h2 {
margin-top: 50px;
}
/*********************** LIST ***********************/
.simpleListAnswer:hover {
/*background:#fff195;*/
cursor: pointer;
}
.simpleListAnswer,
.quizzAnswer {
width: 100%;
background: #f2f2f2;
padding: 9px;
margin-top: 12px;
border: 1px solid #d8d8d8;
}
.simpleListText {
margin-left: 8px;
font-size: 19px;
color: #3d3d3d;
}
/***************************ANSWER REVEAL******************/
.quizzAnswerC,
.quizzAnswerF,
.finalResult {
background: #fefefe;
border: 1px solid #ddd;
}
.answerReveal {
display: none;
width: 100%;
}
.answerHeader div {
color: #84f272;
margin-top: 10px;
}
#bravo,
#sorry {
width: 100%;
margin-left: 20px;
margin-top: 30px;
}
.answerHeader {
margin-left: 20px;
width: 100%;
}
h3.correctMessage {
color: #88f078;
font-size: 30px;
}
h3.wrongMessage {
color: #ff1f1f;
font-size: 30px;
}
.fa.fa-check-circle,
.fa.fa-times-circle {
padding-right: 10px;
}
.correctAnswer {
background: #88f078;
}
.wrongAnswer {
background: #ff1f1f;
}
.fade {
opacity: .6;
cursor: default;
}
/*************************FINAL RESULT******************************/
.finalResult {
width: 100%;
height: 300px;
padding: 0 10px;
margin-top: 30px;
display: none;
}
.finalResult h4 {
color: #797979;
}
.resultContainer p {
font-size: 25px;
}
#halfText,
#halfImage {
width: 50%;
float: left;
}
#halfImage {
margin-top: -40px;
}
#halfImage img {
width: 100%;
}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="font-awesome-4.3.0/css/font-awesome.min.css">
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<script src="jquery-1.11.2.js"></script>
<script src="app.js"></script>
</head>
<body>
<div class="container">
<div class="inner">
<h1>How much do you think you know about stuff?</h1>
<h2>Who discovered America?</h2>
<ul class="simpleList">
<li class="simpleListAnswer correct">
<span class="fa fa-square-o"></span>
<span class="simpleListText">Christopher Columbus</span>
</li>
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">My grandma</span>
</li>
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">Yes,please</span>
</li>
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">Who's this on the phone again?</span>
</li>
</ul>
<!--end simpleList-->
<div class="answerReveal">
<div class="quizzAnswerC">
<div class="answerHeader">
<h3 class="correctMessage"><i class="fa fa-check-circle "></i>Correct! </h3>
</div>
<!--end answer header-->
<div class="answerText">
<p id="bravo">Your answer is correct on so many levels! Well done!</p>
</div>
<!--end asnwerText-->
</div>
<!--end quizzAnswerC-->
<div class="quizzAnswerF">
<div class="answerHeader">
<h3 class="wrongMessage"><i class="fa fa-times-circle"></i>Sorry</h3>
</div>
<!--end answer header-->
<div class="answerText">
<p id="sorry">This is not the answer we were looking for...</p>
</div>
<!--end asnwerText-->
</div>
<!--end quizzAnswerF-->
</div>
<!--end answerReveal-->
<h2>What is 2 x 4?</h2>
<ul class="simpleList">
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">Pasta</span>
</li>
<li class="simpleListAnswer correct">
<span class="fa fa-square-o"></span>
<span class="simpleListText">8</span>
</li>
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">232.456</span>
</li>
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">1</span>
</li>
</ul>
<!--end simpleList-->
<div class="answerReveal">
<div class="quizzAnswerC">
<div class="answerHeader">
<h3 class="correctMessage"><i class="fa fa-check-circle "></i>Correct! </h3>
</div>
<!--end answer header-->
<div class="answerText">
<p id="bravo">Your answer is correct on so many levels! Well done!</p>
</div>
<!--end asnwerText-->
</div>
<!--end quizzAnswerC-->
<div class="quizzAnswerF">
<div class="answerHeader">
<h3 class="wrongMessage"><i class="fa fa-times-circle "></i>Sorry</h3>
</div>
<!--end answer header-->
<div class="answerText">
<p id="sorry">This is not the answer we were looking for...</p>
</div>
<!--end asnwerText-->
</div>
<!--end quizzAnswerF-->
</div>
<!--end answerReveal-->
<h2>How many tires do you have to buy if you have 2 cars in the family?</h2>
<ul class="simpleList">
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">10</span>
</li>
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">We don't have a car</span>
</li>
<li class="simpleListAnswer correct">
<span class="fa fa-square-o"></span>
<span class="simpleListText">8</span>
</li>
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">12</span>
</li>
</ul>
<!--end simpleList-->
<div class="answerReveal">
<div class="quizzAnswerC">
<div class="answerHeader">
<h3 class="correctMessage"><i class="fa fa-check-circle "></i>Correct! </h3>
</div>
<!--end answer header-->
<div class="answerText">
<p id="bravo">Your answer is correct on so many levels! Well done!</p>
</div>
<!--end asnwerText-->
</div>
<!--end quizzAnswerC-->
<div class="quizzAnswerF">
<div class="answerHeader">
<h3 class="wrongMessage"><i class="fa fa-times-circle "></i>Sorry</h3>
</div>
<!--end answer header-->
<div class="answerText">
<p id="sorry">This is not the answer we were looking for...</p>
</div>
<!--end asnwerText-->
</div>
<!--end quizzAnswerF-->
</div>
<!--end answerReveal-->
<h2>If a jar of marmelade costs $3 how much do 12 jars of marmelade cost?</h2>
<ul class="simpleList">
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">Batman</span>
</li>
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">$30</span>
</li>
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">Can I have Nutella instead?</span>
</li>
<li class="simpleListAnswer correct">
<span class="fa fa-square-o"></span>
<span class="simpleListText">$36</span>
</li>
</ul>
<!--end simpleList-->
<div class="answerReveal">
<div class="quizzAnswerC">
<div class="answerHeader">
<h3 class="correctMessage"><i class="fa fa-check-circle "></i>Correct! </h3>
</div>
<!--end answer header-->
<div class="answerText">
<p id="bravo">Your answer is correct on so many levels! Well done!</p>
</div>
<!--end asnwerText-->
</div>
<!--end quizzAnswerC-->
<div class="quizzAnswerF">
<div class="answerHeader">
<h3 class="wrongMessage"><i class="fa fa-times-circle "></i>Sorry</h3>
</div>
<!--end answer header-->
<div class="answerText">
<p id="sorry">This is not the answer we were looking for...</p>
</div>
<!--end asnwerText-->
</div>
<!--end quizzAnswerF-->
</div>
<!--end answerReveal-->
<h2>Which planet is nearest the sun?</h2>
<ul class="simpleList">
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">Venus</span>
</li>
<li class="simpleListAnswer correct">
<span class="fa fa-square-o"></span>
<span class="simpleListText">Mercury</span>
</li>
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">The Moon</span>
</li>
<li class="simpleListAnswer">
<span class="fa fa-square-o"></span>
<span class="simpleListText">Earth</span>
</li>
</ul>
<!--end simpleList-->
<div class="answerReveal">
<div class="quizzAnswerC">
<div class="answerHeader">
<h3 class="correctMessage"><i class="fa fa-check-circle "></i>Correct! </h3>
</div>
<!--end answer header-->
<div class="answerText">
<p id="bravo">Your answer is correct on so many levels! Well done!</p>
</div>
<!--end asnwerText-->
</div>
<!--end quizzAnswerC-->
<div class="quizzAnswerF">
<div class="answerHeader">
<h3 class="wrongMessage"><i class="fa fa-times-circle "></i>Sorry</h3>
</div>
<!--end answer header-->
<div class="answerText">
<p id="sorry">This is not the answer we were looking for...</p>
</div>
<!--end asnwerText-->
</div>
<!--end quizzAnswerF-->
</div>
<!--end answerReveal-->
<div class="finalResult">
<h4>How much do you think you know about stuff?</h4>
<div class="resultContainer"></div>
<div id="halfText"></div>
<div id="halfImage"></div>
</div>
<!--end finalResult-->
</div>
<!--end inner-->
</div>
<!--end container-->
</body>
And I have put it into a separate HTML, CSS and JavaScript file and linked them all however when I upload it to my server, none of the buttons actually let me click on them, and it doesn't show the right or wrong answers.
Is there any obvious reason I'm missing here?
Codepen automatically sources jQuery for you, however if you are copying the code directly you will be missing the jQuery reference.
All you need to do is modify the HTML where it reads:
<script src="jquery-1.11.2.js"></script>
and change the entire element to:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

Categories

Resources