I have a div with children that I need to crawl looking for specific links. The HTML looks like so:
<div id="ctl00_LeftNav">
<h3>
Menu 1</h3>
<div>
<p>
<span>
<div style="padding-left: 0px; font-weight: bold;">
Opt 1</div>
<div style="padding-left: 10px;">
Opt 1a</div>
<div style="padding-left: 0px; font-weight: bold;">
Opt 2</div>
</span>
</p>
</div>
<h3>
Menu 2</h3>
<div>
<p>
<span>
<div style="padding-left: 0px; font-weight: bold;">
Opt 1</div>
<div style="padding-left: 0px; font-weight: bold;">
Opt 2</div>
<div style="padding-left: 10px;">
Opt 2a</div>
</span>
</p>
</div>
<h3>
Menu 3</h3>
<div>
<p>
<span>
<div style="padding-left: 0px; font-weight: bold;">
Opt 1</div>
<div style="padding-left: 0px; font-weight: bold;">
Opt 2</div>
</span>
</p>
</div>
</div>
The Javascript that I have works fine in IE / Firefox, but fails in Chrome:
function OnPageLoadCategorySelect(Category) {
var Root = $j('#ctl00_LeftNav').children();
var Tab = 0;
for (var i = 1; i < Root.length; i += 2) {
var Menu = Root[i].firstChild.firstChild.childNodes;
var MenuLength = Menu.length;
for (var j = 0; j < Menu.length; j++) {
var Link = Menu[j].innerHTML;
var Start = Link.indexOf('(');
var End = Link.indexOf(')');
var Res = Link.slice(Start + 1, End);
if (Res == Category) {
SelectedTabIndex = Tab;
OnLeftMenuSelection(Category);
$j('#ShopTabs').show();
$j('#ctl00_LeftNav').accordion('activate', Tab);
return;
}
}
Tab++;
}
}
In Chrome the 2nd for loop never executes because Menu.length is zero. What would be the best way to get these internal divs?
Solution
function OnPageLoadCategorySelect(Category) {
$j("#ctl00_LeftNav > div").each(function(Tab, el) {
$j('a', this).each(function() {
var id = $j(this).attr('href').replace('javascript:OnLeftMenuSelection(', '').replace(');', '');
if (id == Category) {
SelectedTabIndex = Tab;
OnLeftMenuSelection(Category);
$j('#ShopTabs').show();
$j('#ctl00_LeftNav').accordion('activate', Tab);
return false; // exit the loop
}
})
});
}
If I understand your code correctly, replace your whole function with this:
function OnPageLoadCategorySelect(Category) {
$j("#ctl00_LeftNav > div").each(function(Tab, el){
$j('a', this).each(function(){
var id = $j(this).attr('href').replace('javascript:OnLeftMenuSelection(','').replace(')','');
if( id == Category ) {
SelectedTabIndex = Tab;
OnLeftMenuSelection(Category);
$j('#ShopTabs').show();
$j('#ctl00_LeftNav').accordion('activate', Tab);
return false; // exit the loop
}
})
});
}
The first parameter of the each function is the zero based index. By supplying Tab, it counts it up for you.
You should consider using jQuery.
$('#ctl00_LeftNav').children("div").each(function(index) {
alert(index + ': ' + $(this).text()); // displays inner text of div
});
or this gets all children divs of the selector as pointed out by patrick
$('#ctl00_LeftNav > div').each(function(index) {
alert(index + ': ' + $(this).text()); // displays inner text of div
});
Source: here for loops
Related
I'm using a script that counts how many times the user clicks each link and sort their order based on that number...
It works fine as is, however it doesn't work if the <a> tags is nested inside a div. It's ignoring the divs and the content/image/icon inside, while showing only the links..
How to change it so that it will show and reorder the entire div instead of just the link?
Please see what I have so far:
function updateClicks(ele) {
const storage = window.localStorage.getItem(ele.innerHTML + " clicks");
if (storage === null) {
window.localStorage.setItem(ele.innerHTML + " clicks", "1");
} else {
var clicks = parseInt(window.localStorage.getItem(ele.innerHTML + " clicks")) + 1;
localStorage.removeItem(ele.innerHTML + " clicks");
window.localStorage.setItem(ele.innerHTML + " clicks", clicks);
}
}
function orderItems() {
var order = [];
var href = [];
var links = document.getElementById("links-list");
var link = links.getElementsByTagName("a");
for (i = 0; i < link.length; i++) {
href.push(link[i].href);
}
links = links.innerHTML.split("</a>");
document.getElementById("links-list").innerHTML = "";
for (i = 0; i < links.length - 1; i++) {
var lastChar = links[i].charAt(links[i].length - 1);
var clicks = parseInt(window.localStorage.getItem(lastChar + " clicks"));
if (isNaN(clicks)) {
clicks = 0;
}
order.push([lastChar, clicks, href[i]]);
}
order.sort(function(a, b) {
return a[1] - b[1]
});
order.reverse();
console.log(order)
for (i = 0; i < order.length; i++) {
document.getElementById("links-list").innerHTML += "<a href='" + order[i][2] + "' onclick='updateClicks(this)'>" + order[i][0] + "</a>";
}
}
.link-container {
display: inline-block;
}
.link-container a {
padding: 10px;
background-color: #c0c0c0;
}
.link-img {
width: 16px;
height: 16px;
}
<body onload="orderItems();">
<div id="links-list">
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/6ZpMxiG.png" />
A
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/sFUFOyO.png" />
B
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/M5a2gh8.png" />
C
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/mbrEuvR.png" />
D
</div>
</div>
</body>
I'm still trying to learn JS and I need this feature for a project I'm building.. Thank you in advance for any help.
Here is one way of keeping track of the click counts and sorting the divs accordingly:
// The cnt values in the divs array could be initialised from local storage:
const
list=document.getElementById("links-list"),
divs=[...list.querySelectorAll(".card")];
divs.forEach(e=>e.cnt=0)
list.onclick=ev=>{
if (ev.target.tagName!=="A") return;
ev.target.closest(".card").cnt++;
divs.sort((a,b)=>a.cnt-b.cnt)
.forEach(el=>list.append(el))
console.log(divs.map(e=>e.textContent.trim()+e.cnt).join(","))
}
.link-container {
display: inline-block;
border:1px solid grey;
}
.link-img {
width: 16px;
height: 16px;
}
<body">
<div id="links-list">
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/6ZpMxiG.png" />
A
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/sFUFOyO.png" />
B
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/M5a2gh8.png" />
C
</div>
<div class="card link-container">
<img class="link-img" src="https://i.imgur.com/mbrEuvR.png" />
D
</div>
</div>
</body>
I have an html code from an online product recommendation platform which allows me to add JS to html.
The HTML code below works fine, but i want to apply JS to it based on the logic that, if ${discountvalue} shows any value, then both ${discountvalue} and ${regularvalue} values are visible with cross line on regularvalue.
If ${regularvalue} does not have any value or is empty/null, then only ${regularvalue} will be visible.
HTML CODE:
<div class="slider-wrapper">
${#Recommendations} // This loads the the more then one values of product recommendation
${discountvalue}
${regularvalue}
<div class="slider-wrapper">
<div class="pricebox">
<p class="dynamic-price">${discountvalue}</p>
<p class="regular-price">
<span class="rec_price_num">${regularvalue}</span>
</p>
</div>
</div>
${/#Recommendations}
</div>
And this is the JS code:
var itemPrices = document.querySelectorAll('.slider-wrapper .pricebox');
for(var i=0; i<itemPrices.length; i++){
var discount_price = itemPrices[i].getElementsByClassName("dynamic-price")[0].innerHTML;
var price = getElementsByClassName("rec_price_num")[0].innerHTML;
if(discount_price){
var discount_price = itemPrices[i].getElementsByClassName("dynamic-price")[0].innerHTML;
var price = getElementsByClassName("rec_price_num")[0].innerHTML;
}
else {
var price = getElementsByClassName("rec_price_num")[0].innerHTML;
}
}
parseFloat(discount_price.innerHTML) will return a truthy value if the discount price can be parsed to a floating point number different from 0.
You can use the CSS rule text-decoration: line-through; to have a cross line on the value.
var itemPrices = document.querySelectorAll('.slider-wrapper .pricebox');
for(var i=0; i<itemPrices.length; i++){
var discount_price = itemPrices[i].getElementsByClassName("dynamic-price")[0];
var price = itemPrices[i].getElementsByClassName("regular-price")[0];
if(parseFloat(discount_price.innerHTML)){
price.style.textDecoration = "line-through";
} else {
discount_price.style.display = "none";
}
}
<div class="slider-wrapper">
<div class="pricebox">
<p class="dynamic-price">0</p>
<p class="regular-price">5</p>
</div>
<hr>
<div class="pricebox">
<p class="dynamic-price">4</p>
<p class="regular-price">5</p>
</div>
</div>
Don't need javascript. can be solved by css3
.pricebox p {
font-weight: bold;
font-size: 1.5rem;
color: red;
margin: 0 0 1rem;
}
.pricebox .dynamic-price {
margin-bottom: 0;
}
.pricebox .dynamic-price:empty {
display: none
}
.pricebox .dynamic-price:not(:empty) + .regular-price {
font-size: .875rem;
color: gray;
text-decoration: line-through;
}
<div class="slider-wrapper">
<div class="slider-wrapper">
<div class="pricebox">
<p class="dynamic-price"></p>
<p class="regular-price">
<span class="rec_price_num">200.00</span>
</p>
</div>
<div class="pricebox">
<p class="dynamic-price">100.00</p>
<p class="regular-price">
<span class="rec_price_num">150.00</span>
</p>
</div>
</div>
</div>
I'm trying to setup multiple-step form in which the first step is visible by default and rest of the steps are hidden with class "hide". I'd like to switch the class with Next and Back button so only one step is visible at a time. Could you please help with this (Already spent an hour on this)
<div class="steps">
<div class="step1">step1</div>
<div class="step2 hide">step2</div>
<div class="step3 hide">step3</div>
<div class="step4 hide">step4</div>
</div>
<div class="back">Back</div>
<div class="next">Next</div>
$('.next').click(function(){
$('div:not(.hide)').next().removeClass('hide');
$('.hide').prev().removeClass('hide')
})
Try combining the 2 actions into one, like so:
$('.next').click(function(){
$('.steps div:not(.hide)').addClass('hide').next().removeClass('hide');
})
That way, you add the .hide class on your current div and then remove it on the next one.
You can use something similar for the Back button, by replacing .next() with .previous()
$('.next').click(function() {
// find the div that is not hidden
var $current = $('.steps div:not(.hide)');
// only perform logic if there is a proceeding div
if ($current.next().length) {
// show the next div
$current.next().removeClass('hide');
// hide the old current div
$current.addClass('hide')
}
});
$('.back').click(function() {
// find the div that is not hidden
var $current = $('.steps div:not(.hide)');
// only perform logic if there is a preceeding div
if ($current.prev().length) {
// show the previous div
$current.prev().removeClass('hide');
// hide the old current div
$current.addClass('hide')
}
});
.hide { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="steps">
<div class="step1">step1</div>
<div class="step2 hide">step2</div>
<div class="step3 hide">step3</div>
<div class="step4 hide">step4</div>
</div>
<div class="back">Back</div>
<div class="next">Next</div>
You can add a current step variable to track the currently displayed step and two css for styling and showing your content.
jQuery(function($) {
let currentstep = 1;
let maxsteps = 4;
function showstep(step) {
let step_c = '.step' + step;
for (i = 1; i <= maxsteps; i++) {
var step_selector = '.step' + i;
$(step_selector).removeClass('show');
$(step_selector).addClass('hide');
}
$(step_c).removeClass('hide');
$(step_c).addClass('show');
};
$('.next').click(function() {
currentstep = currentstep + 1;
currentstep = (currentstep % (maxsteps + 1));
if (currentstep == 0) currentstep = 1;
showstep(currentstep);
});
$('.back').click(function() {
currentstep = currentstep - 1;
currentstep = (currentstep % (maxsteps + 1));
if (currentstep == 0) currentstep = 4;
showstep(currentstep);
});
});
.hide {
display: none;
}
.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="steps">
<div class="step1 show">step1</div>
<div class="step2 hide">step2</div>
<div class="step3 hide">step3</div>
<div class="step4 hide">step4</div>
</div>
<div class="back">Back</div>
<div class="next">Next</div>
I converted Taplar's answer to a jQuery plugin.
You are essentially navigating left or right by one, using the previous and next functions. These functions navigate through the sibling elements.
(function() {
$.fn.moveRight = function(className) {
var $curr = this.find('div:not(.' + className + ')');
if ($curr.next().length) $curr.next().removeClass(className);
else this.find('div:first-child').removeClass(className);
$curr.addClass(className);
return this;
};
$.fn.moveLeft = function(className) {
var $curr = this.find('div:not(.' + className + ')');
if ($curr.prev().length) $curr.prev().removeClass(className);
else this.find('div:last-child').removeClass(className);
$curr.addClass(className);
return this;
};
})(jQuery);
$('.next').on('click', (e) => $('.steps').moveRight('hide'));
$('.back').on('click', (e) => $('.steps').moveLeft('hide'));
.hide {
display: none;
}
.nav {
width: 260px;
text-align: center;
}
.nav .nav-btn::selection { background: transparent; }
.nav .nav-btn::-moz-selection { background: transparent; }
.nav .nav-btn {
display: inline-block;
cursor: pointer;
}
.steps {
width: 260px;
height: 165px;
border: thin solid black;
text-align: center;
line-height: 165px;
font-size: 3em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="steps">
<div class="step1">step1</div>
<div class="step2 hide">step2</div>
<div class="step3 hide">step3</div>
<div class="step4 hide">step4</div>
</div>
<div class="nav">
<div class="nav-btn back">[ << Back ]</div>
<div class="nav-btn next">[ Next >> ]</div>
</div>
I'm trying to filter multiple items at once. For example fruits and animals or even 3+. So far it only does it by selecting one item at a time.How can I select more than one? I have also tried https://wch.io/static/tagsort/demo-stacks/index.html but it was bugged keept showing the text but this how it should be but in javascript?
filterSelection("all")
function filterSelection(c) {
var x, i;
x = document.getElementsByClassName("filterDiv");
if (c == "all") c = "";
for (i = 0; i < x.length; i++) {
w3RemoveClass(x[i], "show");
if (x[i].className.indexOf(c) > -1) w3AddClass(x[i], "show");
}
}
function w3AddClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {element.className += " " + arr2[i];}
}
}
function w3RemoveClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
}
.filterDiv {
float: left;
background-color: #2196F3;
color: #ffffff;
width: 100px;
line-height: 100px;
text-align: center;
margin: 2px;
display: none;
}
.show {
display: block;
}
.container {
margin-top: 20px;
overflow: hidden;
}
<h2>Filter DIV Elements</h2>
<input type="radio" onclick="filterSelection('all')" name="category" checked> Show all<br>
<input type="radio" onclick="filterSelection('cars')" name="category"> Cars<br>
<input type="radio" onclick="filterSelection('animals')" name="category"> Animals<br>
<input type="radio" onclick="filterSelection('fruits')" name="category"> Fruits<br>
<input type="radio" onclick="filterSelection('colors')" name="category"> Colors<br>
<div class="container">
<div class="filterDiv cars">BMW</div>
<div class="filterDiv colors fruits">Orange</div>
<div class="filterDiv cars">Volvo</div>
<div class="filterDiv colors">Red</div>
<div class="filterDiv cars animals">Mustang</div>
<div class="filterDiv colors">Blue</div>
<div class="filterDiv animals">Cat</div>
<div class="filterDiv animals">Dog</div>
<div class="filterDiv fruits">Melon</div>
<div class="filterDiv fruits animals">Kiwi</div>
<div class="filterDiv fruits">Banana</div>
<div class="filterDiv fruits">Lemon</div>
<div class="filterDiv animals">Cow</div>
</div>
// If we save our current state somewhere, we can easily filter the divs.
var checkedCategories = ["cars", "animals", "fruits", "colors"];
// We need a function that detects the click on a checkbox and adds/removes that category.
var changeCategory = function changeCategory(event) {
// The event object will tell us exactly what was clicked.
var checkbox = event.target;
// The category we want toa dd or remove is the attribute
var category = checkbox.getAttribute("data-category");
// To check if we already have the category in the array, we just check the index.
var savedCategoryIndex = checkedCategories.indexOf(category);
// If the checkbox is checked, that category has to already exist in the array or get added.
if (checkbox.checked && savedCategoryIndex === -1) {
checkedCategories.push(category);
}
// if it is not checked and is present in the array, it needs to be removed.
else if (!checkbox.checked && savedCategoryIndex !== -1) {
checkedCategories.splice(savedCategoryIndex, 1);
}
renderCategories();
};
// We want a reusable function that will show/hide any categories we want to see.
var renderCategories = function renderCategories() {
// We need a list of all the divs. So we just select all the divs that have the data-category attribute and slice them into an array.
// Could be replaced by Array.from() if your browser supports it.
var categoryDivs = Array.prototype.slice.call(document.querySelectorAll("div[data-category]"));
// Now we need to loop over all the divs and check if they need to get hidden or not.
categoryDivs.forEach(function(div) {
// Get all the tags the div has
var tags = div.getAttribute("data-category").split(" ");
// If at least one tag of the div is inside our categories array, we know it'll need to get shown.
var divShouldBeShown = tags.some(function(tag) {
return checkedCategories.indexOf(tag) !== -1;
});
// The decide if we need to hide the div or not.
// Can be replaced by a classList.toggle() if your browser supports it.
if (divShouldBeShown && div.className.indexOf("hidden") !== -1) {
div.className = div.className.replace("hidden", "");
} else if (!divShouldBeShown && div.className.indexOf("hidden") === -1) {
div.className = div.className + " hidden";
}
});
};
// Finally we have to add an event to the checkboxes.
document.querySelector("#categoryBoxes").addEventListener('click', changeCategory);
.hidden {
display: none;
}
<!-- I've made some changed to the structure of your program to shorten the code alot -->
<h2>Filter DIV Elements</h2>
<!--
We need checkboxes instead of radio buttons if we want to be able to select multiples.
By wrapping them inside a div, we can use one event handler instead of one onclick event for each element.
This makes adding more checkboxes later easier.
-->
<div id="categoryBoxes">
<input type="checkbox" data-category="cars" name="category" checked>Cars<br>
<input type="checkbox" data-category="animals" name="category" checked>Animals<br>
<input type="checkbox" data-category="fruits" name="category" checked>Fruits<br>
<input type="checkbox" data-category="colors" name="category" checked>Colors<br>
</div>
<div class="container">
<!--
By using data-attributes instead of a classname, we make it easier to change the classname, no need to split/rejoin etc
This seperates the javascript from the css, so you can keep the css for styling only and the data-attribute for JS
-->
<div data-category="cars" class="filterDiv">BMW</div>
<div data-category="colors fruits" class="filterDiv">Orange</div>
<div data-category="cars" class="filterDiv">Volvo</div>
<div data-category="colors" class="filterDiv">Red</div>
<div data-category="cars animal" class="filterDiv">Mustang</div>
<div data-category="colors" class="filterDiv">Blue</div>
<div data-category="animals" class="filterDiv">Cat</div>
<div data-category="animals" class="filterDiv">Dog</div>
<div data-category="fruits" class="filterDiv">Melon</div>
<div data-category="fruits animals" class="filterDiv">Kiwi</div>
<div data-category="fruits" class="filterDiv">Banana</div>
<div data-category="fruits" class="filterDiv">Lemon</div>
<div data-category="animals" class="filterDiv">Cow</div>
</div>
The attribute ID is missing on your inputs.
the attribute name groups the radio and allows only one to be checked at once but it will not help on its own to treat the inputs via a submit or javascript.
You can use CSS :checked to select siblings coming next if its only about visual(nothing submit or to treat via js) but it will still require an id in order to work as expected.
example with checkbox :
#all:checked ~ .container .filterDiv{
display: block;
}
.filterDiv, :not(#all):checked ~ .container .filterDiv{
float: left;
background-color: #2196F3;
color: #ffffff;
width: 100px;
line-height: 100px;
text-align: center;
margin: 2px;
display: none;
}
#cars:checked ~ .container .cars,
#animals:checked ~ .container .animals,
#fruits:checked ~ .container .fruits,
#color:checked ~ .container .colors{
display: block;
}
.container {
margin-top: 20px;
overflow: hidden;
}
<h2>Filter DIV Elements</h2>
<input type="checkbox" id="all" checked> Show all<br>
<input type="checkbox" id="cars"> Cars<br>
<input type="checkbox" id="animals"> Animals<br>
<input type="checkbox" id="fruits" > Fruits<br>
<input type="checkbox" id="color" > Colors<br>
<div class="container">
<div class="filterDiv cars">BMW</div>
<div class="filterDiv colors fruits">Orange</div>
<div class="filterDiv cars">Volvo</div>
<div class="filterDiv colors">Red</div>
<div class="filterDiv cars animals">Mustang</div>
<div class="filterDiv colors">Blue</div>
<div class="filterDiv animals">Cat</div>
<div class="filterDiv animals">Dog</div>
<div class="filterDiv fruits">Melon</div>
<div class="filterDiv fruits animals">Kiwi</div>
<div class="filterDiv fruits">Banana</div>
<div class="filterDiv fruits">Lemon</div>
<div class="filterDiv animals">Cow</div>
</div>
Here is an old pen of mine sorting gallerie via radio input and labels inside a form , so selection can be submited and treated on server side or via javascript. You can inspire yourself from the linked codepen where form and radio are used.
var inputs = document.getElementsByTagName("input");
var cbs = []; //will contain all checkboxes
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type == "checkbox") {
cbs.push(inputs[i]);
}
}
filterSelection();
function filterSelection() {
var checkedVal = [],showAll = false;
for (var i = 0; i < cbs.length; i++) {
if (cbs[i].checked && cbs[i].value == "all") {
var showAll = true;
break;
} else if (cbs[i].checked) {
checkedVal.push(cbs[i].value);
}
}
var x, i;
x = document.getElementsByClassName("filterDiv");
//if (c == "all") c = "";
for (i = 0; i < x.length; i++) {
w3RemoveClass(x[i], "show");
if (!showAll) {
for (var j = 0; j < checkedVal.length; j++) {
if (x[i].className.indexOf(checkedVal[j]) > -1) {
w3AddClass(x[i], "show");
}
}
}
else {
w3AddClass(x[i], "show");
}
}
}
function w3AddClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {
element.className += " " + arr2[i];
}
}
}
function w3RemoveClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
}
.filterDiv {
float: left;
background-color: #2196F3;
color: #ffffff;
width: 100px;
line-height: 100px;
text-align: center;
margin: 2px;
display: none;
}
.show {
display: block;
}
.container {
margin-top: 20px;
overflow: hidden;
}
<h2>Filter DIV Elements</h2>
<div><input type="checkbox" onclick="filterSelection()" name="category" value="all" checked> Show all</div>
<input type="checkbox" onclick="filterSelection();" name="category" value="cars"> Cars<br>
<input type="checkbox" onchange="filterSelection();" name="category" value="animals"> Animals<br>
<input type="checkbox" onchange="filterSelection();" name="category" value="fruits"> Fruits<br>
<input type="checkbox" onchange="filterSelection()" name="category" value="colors"> Colors<br>
<div class="container">
<div class="filterDiv cars show">BMW</div>
<div class="filterDiv colors fruits">Orange</div>
<div class="filterDiv cars">Volvo</div>
<div class="filterDiv colors">Red</div>
<div class="filterDiv cars animals">Mustang</div>
<div class="filterDiv colors">Blue</div>
<div class="filterDiv animals">Cat</div>
<div class="filterDiv animals">Dog</div>
<div class="filterDiv fruits">Melon</div>
<div class="filterDiv fruits animals">Kiwi</div>
<div class="filterDiv fruits">Banana</div>
<div class="filterDiv fruits">Lemon</div>
<div class="filterDiv animals">Cow</div>
</div>
You can use check boxes instead of radio buttons to do so. Have one button called Apply which will trigger the filtering logic.
Else, if you don't want to use Apply button then you can use the technique used in https://wch.io/static/tagsort/demo-stacks/index.html
Here, user is toggling classes based on the click on the span and depending on the clicked divs(having active class), you can build your filtering logic.
Hope this helps.
I want to create a pair game that if the same textnode is matched it will set the background in white to reveal the matched textnode if not it will set a timeout and get back in original state.
The Problem of this is if I use the childNodes.nodeValue in match it saids that ChildNodes.nodeValue is not a function. And I try another code. I declare a variable that calls the element tag name of div which is I append a textNode in div. I want to compare two consecutive childNodes of div and if it is the same node, I change the color of the background to white. and I use the setTimout method, if not the color of background will go back again in original state which is black, I am pretty confused about this.
can you scan my code and help me to figure out what is the problem of this code?
here is the code.
<html>
<head>
<style>
div.row {
clear : left;
margin: auto;
width: 520px;
}
div.col {width:100px;
height:100px;
border: 3px solid black;
float : left;
margin: 10px;
font-size: 75px;
text-align: center;
background-color: black;
}
</style>
</head>
<body>
<div class="row">
<div id="00" class="col"></div>
<div id="01"class="col"></div>
<div id="02"class="col"></div>
<div id="03"class="col"></div>
</div>
<div class="row">
<div id="10" class="col"></div>
<div id="11"class="col"></div>
<div id="12"class="col"></div>
<div id="13"class="col"></div>
</div>
<div class="row">
<div id="20" class="col"></div>
<div id="21"class="col"></div>
<div id="22"class="col"></div>
<div id="23"class="col"></div>
</div>
<div class="row">
<div id="30" class="col"></div>
<div id="31"class="col"></div>
<div id="32"class="col"></div>
<div id="33"class="col"></div>
</div>
<script>
var size = 4;
var player = 0;
var board = new Array(size);
for (var i = 0; i < size; i++) {
board[i] = new Array(size);
for (var j = 0; j < size; j++) {
board[i][j] = 0;
}
}
var div_elements = document.getElementsByClassName("col");
for (var i = 0; i < div_elements.length;i++) {
div_elements[i].addEventListener("click", function() {mclick(this);});
}
var count=0;
function mclick(obj) {
if(match(div_elements.childNodes[0].nodeValue) == match(div_elements.childNodes[1].nodeValue)
{
obj.style.backgroundColor="white";
}
else{
setTimeout(function(){ obj.style.backgroundColor="white" }, 1000);
}
}
function shuffle() {
var value;
var text;
var text_node;
for (var i = 0; i < (size * size) ; i++) {
value = Math.ceil(Math.random() * 8);
board[Math.floor(i/4)][i %4] = value;
}
for (var i = 0; i < div_elements.length; i++)
{
text = board[Math.floor(i/4)][i%4];
text_node = document.createTextNode( text);
div_elements[i].appendChild(text_node);
}
}
shuffle();
</script>
</body>
</html>
You must be more specific. What kind of problem are you having? What are the error messages? What do you do that triggers the problem?
At least, put the code in a pastebin.com or something similar so that others don't need to setup a project for testing your whole stuff.