HTML Replace Select item with something more formatable - javascript

I have on a website a select box to select the language of the website:
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<select class="w3-bar-item w3-select w3-right w3-button" onchange="if (this.value) window.location.href=this.value" style="-webkit-appearance: none;">
<option value="?&lang=lu"<?php if ($_SESSION['lang'] == "lu") echo "selected='selected'";?>>Lëtzebuergesch</option>
<option value="?&lang=en"<?php if ($_SESSION['lang'] == "en") echo "selected='selected'";?>>English</option>
<option value="?&lang=fr"<?php if ($_SESSION['lang'] == "fr") echo "selected='selected'";?>>Français</option>
<option value="?&lang=de"<?php if ($_SESSION['lang'] == "de") echo "selected='selected'";?>>Deutsch</option>
</select>
This works all fine but I cannot format it as i want. I would like to replace it with something like this:
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<div class="w3-dropdown-hover">
<button class="w3-button">Dropdown</button>
<div class="w3-dropdown-content w3-bar-block w3-card-4">
Lëtzebuergesch
English
Français
Deutsch
</div>
</div>
So that when you chose the language it sets the value of &lang and sets the name of the button to the language that is selected.
I hope someone can help me with this.
You can see the select box in action here on the upper right of the site:
(https://elgaucho.lu/beta/)
Thanks for your help
Andy

Scroll a bit to see how to make a custom select. All you need are last HTML and CSS codes. Other codes are just to implement the logic with JS (I know you did that with PHP).
Standard HTML select solution.
HTML:
<select id="select">
<option value="?&lang=lu">Lëtzebuergesch</option>
<option value="?&lang=en">English</option>
<option value="?&lang=fr">Français</option>
<option value="?&lang=de">Deutsch</option>
</select>
JS:
document.addEventListener('DOMContentLoaded', function() {
const select = document.getElementById('select');
select.addEventListener('change', function() {
if (this.value) {
location.href = this.value;
}
});
// loop through select options
// and if page URL contains option value, select it
for (let i = 0; i < select.options.length; i++) {
if (location.href.includes(select.options[i].value)) {
select.value = select.options[i].value;
break;
}
}
});
Custom select solution:
HTML:
<div id="my-select">
<div id="my-select-label">Lëtzebuergesch</div>
<div id="my-select-options">
<div data-value="?&lang=lu">Lëtzebuergesch</div>
<div data-value="?&lang=en">English</div>
<div data-value="?&lang=fr">Français</div>
<div data-value="?&lang=de">Deutsch</div>
</div>
</div>
CSS:
#my-select {
width: 150px;
}
#my-select:hover #my-select-options {
display: block;
}
#my-select-options {
display: none;
}
#my-select-options > div {
padding: 0.5em;
border: 1px solid black;
border-top: none;
}
#my-select-label {
margin-top: 2em;
padding: 1em;
border: 1px solid black;
}
JS:
document.addEventListener('DOMContentLoaded', function() {
const mySelectLabel = document.getElementById('my-select-label');
const mySelectOptions = document.querySelectorAll('#my-select-options > div');
for (let i = 0; i < mySelectOptions.length; i++) {
mySelectOptions[i].addEventListener('click', function() {
location.href = this.getAttribute('data-value');
});
}
for (let i = 0; i < mySelectOptions.length; i++) {
if (location.href.includes(mySelectOptions[i].getAttribute('data-value'))) {
mySelectLabel.textContent = mySelectOptions[i].textContent;
break;
}
mySelectLabel.textContent = mySelectOptions[0].textContent;
}
});
If you have any questions, ask.

Related

Show/ hide elements on page with conditional html selects

This is most likely a duplicate, but I couldn't find snippets that help me out
I have a page with multiple images and two select fields. I want to show depending on the selection of the user different images. For the individual selects this is easy, but how can I achieve a dependency between both selects the easy way?
Example:
Items on Page: "A B", "A", "B"
User selection:
First select: A
Second select: B
Result: "A B"
User selection:
First select: A
Second select: empty
Result: "A"
I think you get the point.
The few snippets I've found are made with jQuery and I would really like to avoid jQuery and only use vanilla JS.
My current approach:
let redShown;
let blueShown;
let greenShown;
let oneShown;
let twoShown;
let threeShown;
// ColorFilter
function colorFilter(select) {
if (select.value == "red") {
redShown = true;
blueShown = false;
greenShown = false;
// Show Red
for (let i = 0; i < document.querySelectorAll(".box.red").length; i++) {
document.querySelectorAll(".box.red")[i].style.display = "inherit";
}
// Hide everything else than red
for (let i = 0; i < document.querySelectorAll(".box:not(.red)").length; i++) {
document.querySelectorAll(".box:not(.red)")[i].style.display = "none";
}
} else if (select.value == "blue") {
blueShown = true;
redShown = false;
greenShown = false;
// Show Blue
for (let i = 0; i < document.querySelectorAll(".box.blue").length; i++) {
document.querySelectorAll(".box.blue")[i].style.display = "inherit";
}
// Hide everything else than blue
for (let i = 0; i < document.querySelectorAll(".box:not(.blue)").length; i++) {
document.querySelectorAll(".box:not(.blue)")[i].style.display = "none";
}
} else if (select.value == "green") {
greenShown = true;
redShown = false;
blueShown = false;
// Show Green
for (let i = 0; i < document.querySelectorAll(".box.green").length; i++) {
document.querySelectorAll(".box.green")[i].style.display = "inherit";
}
// Hide everything else than green
for (let i = 0; i < document.querySelectorAll(".box:not(.green)").length; i++) {
document.querySelectorAll(".box:not(.green)")[i].style.display = "none";
}
}
}
// Numberfilter
function numberFilter(select) {
if (select.value == "one") {
oneShown = true;
twoShown = false;
threeShown = false;
// Show 1
for (let i = 0; i < document.querySelectorAll(".box.one").length; i++) {
document.querySelectorAll(".box.one")[i].style.display = "inherit";
}
// Hide everything else than 1
for (let i = 0; i < document.querySelectorAll(".box:not(.one)").length; i++) {
document.querySelectorAll(".box:not(.one)")[i].style.display = "none";
}
} else if (select.value == "two") {
oneShown = false;
twoShown = true;
threeShown = false;
// Show 2
for (let i = 0; i < document.querySelectorAll(".box.two").length; i++) {
document.querySelectorAll(".box.two")[i].style.display = "inherit";
}
// Hide everything else than 2
for (let i = 0; i < document.querySelectorAll(".box:not(.two)").length; i++) {
document.querySelectorAll(".box:not(.two)")[i].style.display = "none";
}
} else if (select.value == "three") {
oneShown = false;
twoShown = false;
threeShown = true;
// Show 3
for (let i = 0; i < document.querySelectorAll(".box.three").length; i++) {
document.querySelectorAll(".box.three")[i].style.display = "inherit";
}
// Hide everything else than 3
for (let i = 0; i < document.querySelectorAll(".box:not(.three)").length; i++) {
document.querySelectorAll(".box:not(.three)")[i].style.display = "none";
}
}
}
.flex-wrapper {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.box {
width: 100px;
height: 100px;
margin: 10px;
display: flex;
justify-content: center;
align-items: center;
font-size: 2rem;
}
.box.red {
background: red;
}
.box.green {
background: green;
}
.box.blue {
background: blue;
}
<select id="colorSelect" onchange="colorFilter(this)">
<option disabled selected value="">Color</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
</select>
<select id="numberSelect" onchange="numberFilter(this)">
<option disabled selected value="">Number</option>
<option value="one">1</option>
<option value="two">2</option>
<option value="three">3</option>
</select>
<div class="flex-wrapper">
<div class="box red one">1</div>
<div class="box red two">2</div>
<div class="box red three">3</div>
<div class="box blue one">1</div>
<div class="box blue two">2</div>
<div class="box blue three">3</div>
<div class="box green one">1</div>
<div class="box green two">2</div>
<div class="box green three">3</div>
</div>
Right now the selects overwrite each other, so they don't work together.
Also my code is super complex because I write out every possible combination by hand. There has to be a shorter version for this.
You can attach the same event listener to both selects and set display properties of each box depending on the changed values of the number select and color select. PS: I tweaked HTML a little bit so it is easier to access box' variables (added data-color attribute for the color value and data-number attribute for the number value). In addition, I've changed numberSelect values from "one", "two" and "three" to "1", "2" and "3". Also, the code is 100% free of jQuery :-)
See the implementation below:
let colorSelect = document.getElementById('colorSelect');
let numberSelect = document.getElementById('numberSelect');
let boxWrapper = document.getElementById('boxWrapper');
function handleChange() {
// Get new values for changed color
// and changed number which user selected
let changedColor = colorSelect.value;
let changedNumber = numberSelect.value;
// Get the list of all boxes inside our box wrapper div
let boxes = boxWrapper.querySelectorAll('.box');
// For each box check whether its display property
// should be 'block' or 'none' based on changed values
// in colorSelect and numberSelect
boxes.forEach(box => {
// Get color and number values from the current box
let color = box.getAttribute('data-color');
let number = box.getAttribute('data-number');
// Check whether current box color and number values
// comply to user changed values in selects
let isColorValid = !changedColor || changedColor === color;
let isNumberValid = !changedNumber || changedNumber === number;
// If both color and number values comply - display the box
// otherwise hide the box using display: none
if (isColorValid && isNumberValid) {
box.style.display = 'block';
} else {
box.style.display = 'none';
}
})
}
// Attach listeners to both colorSelect and numberSelect
colorSelect.addEventListener('change', () => handleChange());
numberSelect.addEventListener('change', () => handleChange());
.flex-wrapper {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.box {
width: 100px;
height: 100px;
margin: 10px;
display: flex;
justify-content: center;
align-items: center;
font-size: 2rem;
}
.box.red {
background: red;
}
.box.green {
background: green;
}
.box.blue {
background: blue;
}
<select id="colorSelect">
<option disabled selected value="">Color</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
</select>
<select id="numberSelect">
<option disabled selected value="">Number</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<div class="flex-wrapper" id="boxWrapper">
<div class="box red" data-color="red" data-number="1">1</div>
<div class="box red" data-color="red" data-number="2">2</div>
<div class="box red" data-color="red" data-number="3">3</div>
<div class="box blue" data-color="blue" data-number="1">1</div>
<div class="box blue" data-color="blue" data-number="2">2</div>
<div class="box blue" data-color="blue" data-number="3">3</div>
<div class="box green" data-color="green" data-number="1">1</div>
<div class="box green" data-color="green" data-number="2">2</div>
<div class="box green" data-color="green" data-number="3">3</div>
</div>

Why is my text output from next() and prev() toggle incorrect?

When clicking the arrows to change the displayed option, the incorrect options is shown.
The user should be able click on the option menu to toggle it open/cosed and be able to click on a option to select it. Alternatively, the arrows could be used to toggle through the options instead.
This is the problematic code:
<script>
$("#arrow_left_physics").click(function() {
var $selected = $(".left_menu_option_selected").removeClass("left_menu_option_selected");
var divs = $("#left_menu__variant_physics").children();
divs.eq((divs.index($selected) - 1) % divs.length).addClass("left_menu_option_selected");
$("#left_menu_open .button-text").text($($selected).text());
});
$("#arrow_right_physics").click(function() {
var $selected = $(".left_menu_option_selected").removeClass("left_menu_option_selected");
var divs = $selected.parent().children();
divs.eq((divs.index($selected) + 1) % divs.length).addClass("left_menu_option_selected");
$("#left_menu_open .button-text").text($($selected).text());
});
</script>
$("#menu_open").click(function() {
$("#menu").toggle();
});
$(".menu_option").click(function() {
if ($(this).hasClass(".menu_option_selected")) {} else {
$(".menu_option").removeClass("menu_option_selected");
$(this).addClass("menu_option_selected");
$("#menu_open .button_text").text($(this).text());
}
});
$("#arrow_left").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) - 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($($selected).text());
});
$("#arrow_right").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) + 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($($selected).text());
});
.menu_open {
Cursor: pointer;
}
.menu {
display: none;
position: absolute;
border: 1px solid;
}
.menu_option {
Cursor: pointer;
Padding: 5px;
}
.menu_option:hover {
Background-Color: black;
Color: white;
}
.menu_option_selected {
color: green;
Background-color: #00ff0a4d;
}
.menu_option_selected:hover {
color: green;
}
.arrow {
Cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input class="arrow" type="button" id="arrow_left" value="❮" />
<input class="arrow" type="button" id="arrow_right" value="❯" />
</div>
<div>
<button class="menu_open" id="menu_open">
<span class="button_text">option1</span>
</button>
</div>
<div class="menu" id=menu>
<div class="menu_option menu_option_selected">option1</div>
<div class="menu_option">option2</div>
<div class="menu_option">option3</div>
<div class="menu_option">option4</div>
<div class="menu_option">option5</div>
<div class="menu_option">option6</div>
</div>
-It seems that the first click of the arrows isn't working and that the index function is incorrect somewhere.
The problem is this line:
$("#menu_open .button_text").text($($selected).text());
$($selected) is the option that was previously selected, so you're showing the text of the previous option, not the current option. (BTW, there's no need to wrap $selected in $(), since it's already a jQuery object.)
You should use $(".menu_option_selected").text() instead of $($selected).text() to get the current option.
You should also make the initial text of the button option1, so it matches the selected option.
$("#menu_open").click(function() {
$("#menu").toggle();
});
$(".menu_option").click(function() {
if ($(this).hasClass(".menu_option_selected")) {} else {
$(".menu_option").removeClass("menu_option_selected");
$(this).addClass("menu_option_selected");
$("#menu_open .button_text").text($(this).text());
}
});
$("#arrow_left").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) - 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($(".menu_option_selected").text());
});
$("#arrow_right").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) + 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($(".menu_option_selected").text());
});
.menu_open {
Cursor: pointer;
}
.menu {
display: none;
position: absolute;
border: 1px solid;
}
.menu_option {
Cursor: pointer;
Padding: 5px;
}
.menu_option:hover {
Background-Color: black;
Color: white;
}
.menu_option_selected {
color: green;
Background-color: #00ff0a4d;
}
.menu_option_selected:hover {
color: green;
}
.arrow {
Cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input class="arrow" type="button" id="arrow_left" value="❮" />
<input class="arrow" type="button" id="arrow_right" value="❯" />
</div>
<div>
<button class="menu_open" id="menu_open">
<span class="button_text">option1</span>
</button>
</div>
<div class="menu" id=menu>
<div class="menu_option menu_option_selected">option1</div>
<div class="menu_option">option2</div>
<div class="menu_option">option3</div>
<div class="menu_option">option4</div>
<div class="menu_option">option5</div>
<div class="menu_option">option6</div>
</div>
Just another version, refactoring your javascript code with some Arrow functions.
const setButtonText = () => {
$("#menu_open .button_text").text(
$(".menu_option_selected").text()
);
}
const moveSelection = direction => {
var selected = $(".menu_option_selected")
var options = $("#menu").children()
var newIndex;
if (direction == 'right') {
newIndex = (options.index(selected) + 1) % options.length
} else {
newIndex = (options.index(selected) - 1) % options.length
}
selected.removeClass("menu_option_selected")
options.eq(newIndex).addClass("menu_option_selected")
setButtonText()
}
// inizilize menu button_text
setButtonText()
$("#arrow_left").click(() => moveSelection('left'));
$("#arrow_right").click( () => moveSelection('right'));
$("#menu_open").click( () => $("#menu").toggle());
$(".menu_option").click( function() {
$(".menu_option_selected").removeClass("menu_option_selected")
$(this).addClass("menu_option_selected")
setButtonText()
});

How to include a input in a label in a querySelector() in javascript?

I am trying to construct a personality quiz for my school project. Everything was working fine until I decided that I want the inputs for the radio buttons to be just pictures. The problem is that I am not sure how to save the selected choice and its value, in order to calculate the result.
This is my HTML code:
<div id="simplequiz">
<h3>What's your favourite colour palette?</h3>
<p>
<input type="radio" name="colour" class="a" value="-1" />
<label for="p">
<img src="images/2.jpg" alt="Gothic colour palette" style="width: 200px">
</label>
</p>
<button type="submit" value="submit" onClick="submitSimpleQuiz()">Submit</button>
</div>
This is my CSS:
.input_hidden {
position: absolute;
left: -9999px;
}
.selected {
background-color: #ccc;
}
#simplequiz label {
display: inline-block;
cursor: pointer;
}
#simplequiz label:hover {
background-color: #efefef;
}
#simplequiz label img {
padding: 3px;
}
And this is my Javascript:
function submitSimpleQuiz() {
"use strict";
var colour = praseInt(document.querySelector('input[name = "colour"]:checked').value);
var total = colour;
if (total < 0) {
document.getElementById("answer").innerHTML = "Goth";
document.getElementById("simplequiz").style.display = "none";
} else {
document.getElementById("answer").innerHTML = "Minimalistic";
document.getElementById("simplequiz").style.display = "none";
}
}
$('#simplequiz input:radio').addClass('input_hidden');
$('#simplequiz label').click(function () {
$(this).addClass('selected').siblings().removeClass('selected');
});
This is just one question and answer but essentially all the answers should add up to an outcome which will display a personality description. I don't know why the button for submitting doesn't work anymore.
I would greatly appreciate the help.
I am only new to coding, but I tried including the label into the javascript and also changing the layout of the HTML so that the input is included in the label tag.
As I am sure you won't stop with only 1 question, here is a working snippet in which you can add more questions easily:
function submitSimpleQuiz() {
"use strict";
var total = 0;
var answer = ""; // Added, just because… (see below)
// Easy selection, now! That counts only "selected" inputs!
var inputs = document.querySelectorAll("#simplequiz .selected input");
for (var i = 0; i < inputs.length; i++) {
total += parseInt(inputs[i].value);
}
if (total < 0) {
answer = "Goth";
} else {
answer = "Minimalistic";
}
// Moved outside of the if to only have these instructions one time
document.getElementById("simplequiz").style.display = "none";
document.getElementById("answer").innerHTML = answer;
}
// Your other code, I haven't touched it. Promise.
$('#simplequiz input:radio').addClass('input_hidden');
$('#simplequiz label').click(function() {
$(this).addClass('selected').siblings().removeClass('selected');
});
.input_hidden {
position: absolute;
left: -9999px;
}
.selected {
background-color: #ccc;
}
#simplequiz label {
display: inline-block;
cursor: pointer;
}
#simplequiz label:hover {
background-color: #efefef;
}
#simplequiz label img {
padding: 3px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="simplequiz">
<h3>What's your favourite colour palette?</h3>
<p>
<!-- Modified order -->
<label for="p">
<input type="radio" name="colour" class="a" value="-1" />
<img src="images/2.jpg" alt="Gothic colour palette" style="width: 200px">
</label>
<!-- Added another one below -->
<label for="p">
<input type="radio" name="colour" class="a" value="1" />
<img src="images/2.jpg" alt="Minimal colour palette" style="width: 200px">
</label>
</p>
<button type="submit" value="submit" onClick="submitSimpleQuiz()">Submit</button>
</div>
<!-- Added "answer" -->
<div id="answer"></div>
Anyway, I've got a few remarks, here:
⋅ Your function submitSimpleQuiz is in JavaScript only, whereas your other code is in jQuery. You should choose what you want to use!
⋅ I moved the inputs in your labels to make it easier to select them.
⋅ Why are you using inputs if you're hiding them, and can't/don't check them?!…
Hope it helps.
You need to remove line :
$('#simplequiz input:radio').addClass('input_hidden');
Or you need to modify the line:
var colour = parseInt(document.querySelector('input[name = "colour"]:checked').value);
Because if you uncheck radiobutton you can't get the value. And You have to use parseInt not praseInt. it's an error.
First off all you need to import Jquery for using Jquery function $.
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
Second it is parseInt not praseInt.
Third:
use this piece of code instead of yours:
var colour = parseInt(document.querySelector("div#simplequiz input[name = 'colour']").value);
Fourth:
for your script to work correctly your javasScript should be -
<script type="text/javascript">
function submitSimpleQuiz(){
"use strict";
var colour = parseInt(document.querySelector("div#simplequiz input[name = 'colour']").value);
if (document.querySelector("div#simplequiz input[name = 'colour']").checked) {
colour = 0;
}
var total = colour;
if (total < 0) {
document.getElementById("answer").innerHTML = "Goth";
document.getElementById("simplequiz").style.display = "none";
}
else
{
document.getElementById("answer").innerHTML = "Minimalistic";
document.getElementById("simplequiz").style.display = "none";
}
}
$('#simplequiz input:radio').addClass('input_hidden');
$('#simplequiz label').click(function() {
$(this).addClass('selected').siblings().removeClass('selected');
});
</script>

filtering elements with two select elements with plain javascript

im struggling with two select elements to sort my squares and circles.
each select element work separately, but it doesn't work together.
can anyone tell me how can i make it work right?
please help!
function colorType(){
var colorBox = document.querySelector('#selectColor');
var boxValue = colorBox.options[colorBox.selectedIndex].value;
var blue = document.querySelectorAll('.card.blue');
var red = document.querySelectorAll('.card.red');
if(boxValue == 'blue'){
for (var i = 0; i < red.length; i++){
red[i].classList.add('hidden');
}
for (var i = 0; i < blue.length; i++){
blue[i].classList.remove('hidden');
}
}
if(boxValue == 'red'){
for (var i = 0; i < blue.length; i++){
blue[i].classList.add('hidden');
}
for (var i = 0; i < red.length; i++){
red[i].classList.remove('hidden');
}
}
}
function shapeType(){
var shapeBox = document.querySelector('#selectShape');
var boxValue = shapeBox.options[shapeBox.selectedIndex].value;
var round = document.querySelectorAll('.card.round');
var square = document.querySelectorAll('.card.square');
if(boxValue == 'round'){
for (var i = 0; i < square.length; i++){
square[i].classList.add('hidden');
}
for (var i = 0; i < round.length; i++){
round[i].classList.remove('hidden');
}
}
if(boxValue == 'square'){
for (var i = 0; i < round.length; i++){
round[i].classList.add('hidden');
}
for (var i = 0; i < square.length; i++){
square[i].classList.remove('hidden');
}
}
}
.card{
width:100px;
height: 100px;
float: left;
margin: 20px;
}
.blue{
background: blue;
}
.red{
background: red;
}
.round{
border-radius: 50%;
}
.hidden{
display: none;
}
<label>Choose the color
<select id="selectColor" onchange="colorType();">
<option value=""></option>
<option value="blue">Blue</option>
<option value="red">Red</option>
</select>
</label>
<label>Choose the shape
<select id="selectShape" onchange="shapeType();">
<option value=""></option>
<option value="round">Round</option>
<option value="square">Square</option>
</select>
</label>
<div class="card-holder">
<div class="card blue round"></div>
<div class="card blue square"></div>
<div class="card blue round"></div>
<div class="card red round"></div>
<div class="card red square"></div>
<div class="card blue square"></div>
<div class="card red round"></div>
<div class="card red square"></div>
</div>
You can do the following, selecting cards, turn the HTMLCollection to Array and use filter.
The display function is quite useless but I let it so I didn't have to change the HTML.
EDIT : Detailed explanation
You need to get all the cards.
To do so, it's better to use getElementdByClassName since it returns an HTMLCollection.
querySelectorAll on the other hand returns a NodeList. HTMLCollection are live collections while that's not always the case for NodeList.
An HTMLCollection in the HTML DOM is live; it is automatically updated
when the underlying document is changed.
So once you get the card in your variable, if you add or remove cards, you don't need to update your variable value, it will be done automatically.
Trigger your function when the inputs are selected
You already did it, that's just the onchange event.
Get shape and color value
Just retrieve your selects items with document.getElementById (faster thant querySelector), then the value attribute give you the value of the selected option inside your select tag.
Display all your cards and hide the right ones
Since cards is an HTMLCollection, you can't use Array methods on it, so you need to turn it into an array with Array.from.
Then you can use forEach and remove the 'hidden' class.
To add, remove or check the existence of classes, we use the ClassList property.
To filter the Array.from(cards), use the filter method, and then you can add the 'hidden' class to the desired cards.
var cards = document.getElementsByClassName('card');
var colorSelect = document.getElementById('selectColor');
var shapeSelect = document.getElementById('selectShape');
function colorType() {
display(colorSelect.value, shapeSelect.value);
}
function shapeType() {
display(colorSelect.value, shapeSelect.value);
}
function display(color, shape) {
Array.from(cards).forEach(card => card.classList.remove('hidden'));
if (color) {
Array.from(cards)
.filter(card => !card.classList.contains(color))
.forEach(card => card.classList.add('hidden'))
}
if (shape) {
Array.from(cards)
.filter(card => !card.classList.contains(shape))
.forEach(card => card.classList.add('hidden'))
}
}
.card{
width:100px;
height: 100px;
float: left;
margin: 20px;
}
.blue{
background: blue;
}
.red{
background: red;
}
.round{
border-radius: 50%;
}
.hidden{
display: none;
}
<label>Choose the color
<select id="selectColor" onchange="colorType();">
<option value=""></option>
<option value="blue">Blue</option>
<option value="red">Red</option>
</select>
</label>
<label>Choose the shape
<select id="selectShape" onchange="shapeType();">
<option value=""></option>
<option value="round">Round</option>
<option value="square">Square</option>
</select>
</label>
<div class="card-holder">
<div class="card blue round"></div>
<div class="card blue square"></div>
<div class="card blue round"></div>
<div class="card red round"></div>
<div class="card red square"></div>
<div class="card blue square"></div>
<div class="card red round"></div>
<div class="card red square"></div>
</div>
Hope it helps,
Best regards

How to add an up arrow to select element along with down arrow and to traverse options only using these arrows?

I have a select element on which i was able to style it with a up and down arrow. But here I seek your help to traverse the option dropdown only using these arrows. Infact I need that dropdown list to get hide.
Here is the Markup
<div class="select_wrap">
<div class="select_arow_wrap">
<span id="select-up" class="select-up"></span>
<span id="select-down" class="select-down"></span>
</div>
<div class="select_bg">
<select id="select">
<option value="Newzealand">Newzealand</option>
<option value="India">India</option>
<option value="United States">United States</option>
<option value="United Kingdom">United Kingdom</option>
</select>
</div>
</div>
The CSS
.select_bg {
background-image:url(../images/select-bg.png);
background-repeat:repeat-x;
border:1px solid #dddedf;
background-position:left center;
background-color:transparent;
width:100%;
border-radius:5px;
padding:5px;
height:33px;
}
.select_wrap {
position:relative;
float:left;
width:100%;
overflow:hidden;
margin:5px;
}
.form_wrap form select {
background-color:transparent;
width:105%;
padding:3px;
top:0;
position:absolute;
-moz-appearance:none;
-webkit-appearance: none;
appearance: none;
margin:0;
height:30px;
}
.form_wrap form select option {
display:none;
}
.form_wrap form select::-ms-expand {
display: none;
}
.select_arow_wrap {
border-left:1px solid #dddedf;
float:left;
position:absolute;
width:16px;
height:30px;
right:5px;
top:2px;
padding:2px;
z-index:999;
}
.select-up,
.select-down{
background-repeat:no-repeat;
float:left;
width:14px;
height:13px;
cursor:pointer;
}
.select-up {
background-image:url(../images/select_up_arw.png);
right:-10px;
top:6px;
}
.select_wrap .select-down {
background-image:url(../images/select_dnw_arw.png);
right:-9px;
bottom:8px;
}
And it looks something like
http://awesomescreenshot.com/0ed3syg0c6
What I need is the jquery to traverse the options on clicking those arrows.
Thanks in Advance
you can try this:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<style>
img{
width : 20px;
height : 20px;
}
</style>
<script>
$(document).ready(function(){
var nextListitem;
var noOfListItems = $("#select > option").length-1;
var curListItem = $("#select")[0].selectedIndex;
$("#upArrow").on("click", function(){
//alert(noOfListItems);
// Decrement the selection by one, unless that will be less than zero, then go to the last option
nextListitem = (curListItem-1 < 0) ? noOfListItems : curListItem-1;
// alert(nextListitem);
curListItem = nextListitem;
$("#select")[0].selectedIndex = nextListitem;
});
$("#downArrow").on("click", function(){
// alert(noOfListItems);
// Increment the selection by one, unless that will be more than the number of options, then go to the first option
nextListitem = (curListItem+1 > noOfListItems) ? 0 : curListItem+1;
// alert(nextListitem);
curListItem = nextListitem;
$("#select")[0].selectedIndex = nextListitem;
});
});
</script>
<body>
<div class="select_wrap">
<div class="select_arow_wrap">
<span id="select-up" class="select-up"></span>
<span id="select-down" class="select-down"></span>
</div>
<div class="select_bg">
<select id="select">
<option value="Newzealand">Newzealand</option>
<option value="India">India</option>
<option value="United States">United States</option>
<option value="United Kingdom">United Kingdom</option>
</select>
<img id="upArrow" src="http://www.clker.com/cliparts/8/7/Y/H/W/e/up-arrow-circle-hi.png" style="float : top" />
<img id="downArrow" src="http://www.clker.com/cliparts/y/m/X/o/s/R/down-arrow-circle-hi.png" style="float : bottom" />
</div>
</div>
</body>
</html>
see demo here:Fiddle
Simply create a custom element that will work as a select element with the features you want. You'll be using the jQuery click event to change the content of your custom select element. Try this way : (It's a demo work. You can style it as you want.)
HTML :
<div id="customSelectElement">
<div id="selectBox">
<input type="text" id="selector" readonly />
</div>
<div id="navigator">
<img id="upArrow" src="http://www.clker.com/cliparts/8/7/Y/H/W/e/up-arrow-circle-hi.png" style="float : top" />
<img id="downArrow" src="http://www.clker.com/cliparts/y/m/X/o/s/R/down-arrow-circle-hi.png" style="float : bottom" />
</div>
</div>
jQuery :
var data = ["Dubai", "Qatar", "Thiland"];
var counter = 0;
var currentElement = data[counter];
$("#selector").val(currentElement);
$("#upArrow").on("click", function(){
if(counter > 0){
counter--;
}
setData(counter);
});
$("#downArrow").on("click", function(){
if(counter < data.length - 1){
counter++;
}
setData(counter);
});
function setData(counter){
currentElement = data[counter];
$("#selector").val(currentElement);
}
jsFiddle
Use this code for selectbox
var data = new Array();
$("#select option").each(function(){
data.push($(this).val());
});
var counter = 0;
var currentElement = data[counter];
$("#select-up").on("click", function(){
if(counter > 0){
counter--;
}
selectData(counter);
});
$("#select-down").on("click", function(){
if(counter < data.length - 1){
counter++;
}
selectData(counter);
});
function selectData(counter){
currentElement = data[counter];
console.log(currentElement);
//$('#selector option[value="'+currentElement+'"]').attr("selected",true);
$('#select').val(currentElement)
}

Categories