How can I do actions when multiple divs are clicked ? (Javascript) - javascript

I'll try to explain : I have a lot of divs that I am using as buttons (they're switching to red when you click on it).
It's a ranking system (for a videogame). Each rank has three step (1-2-3).
The goal of this is that you can select your rank first, then select the desire rank.
After choosing this, the price is displayed. Im trying to do this function.
For example, you select the lowest rank possible, then your landing (1-2-3).
Then, you choose what is the rank that you want, so in total, there is 4 divs clicked.
Finally, the goal of it all is to show the price.
But im having troubles. If you guys have some ideas.
I know that this is not the good way to do it. The code below is an example (Silver 1 to Silver 2).
I'm sure that I can condense this but I don't know how (Because there is a lot of ranks and doing 50 functions is not a good idea I think).
I hope to have been clear and precise, thanks for your help.
//First part
var fer1 = 0;
var bronze1 = 0;
var argent1 = 0;
var or1 = 0;
var platine1 = 0;
var diamant1 = 0;
var immortel1 = 0;
var un1 = 0;
var deux1 = 0;
var trois1 = 0;
//Second part
var fer2 = 0;
var bronze2 = 0;
var argent2 = 0;
var or2 = 0;
var platine2 = 0;
var diamant2 = 0;
var immortel2 = 0;
var un2 = 0;
var deux2 = 0;
var trois2 = 0;
function P1() {
fer1 = 1;
bronze1 = 0;
argent1 = 0;
or1 = 0;
platine1 = 0;
diamant1 = 0;
immortel1 = 0;
if ((fer1 == 1 && fer2 == 1 && un1 == 1 && deux2 == 1)) {
document.getElementById('total').innerHTML = "100€"
} else {
document.getElementById('total').innerHTML = "0€"
}
}
function P8() {
un1 = 1;
deux1 = 0;
trois1 = 0;
if ((fer1 == 1 && fer2 == 1 && un1 == 1 && deux2 == 1)) {
document.getElementById('total').innerHTML = "100€"
} else {
document.getElementById('total').innerHTML = "0€"
}
}
function P11() {
fer2 = 1;
bronze2 = 0;
argent2 = 0;
or2 = 0;
platine2 = 0;
diamant2 = 0;
immortel2 = 0;
if ((fer1 == 1 && fer2 == 1 && un1 == 1 && deux2 == 1)) {
document.getElementById('total').innerHTML = "100€"
} else {
document.getElementById('total').innerHTML = "0€"
}
}
function P99() {
un2 = 0;
deux2 = 1;
trois2 = 0;
if ((fer1 == 1 && fer2 == 1 && un1 == 1 && deux2 == 1)) {
document.getElementById('total').innerHTML = "100€"
} else {
document.getElementById('total').innerHTML = "0€"
}
}
HTML :
<div class="selection2">
<h1 class="unselectable policeOA policeRS" style="background-color:black; color:white;"> VOTRE RANG SOUHAITÉ</h1>
<div class="SousSelection1">
<div class="contenu-grille">
<div class="foc">
<div class="PetitCarre customClass" id="pc11">
<img class="rankss unselectable" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\Rank\Silver.png"/>
<img id="s1" class="unselectable slash1" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\All\Slashwhite.png"/>
</div>
</div>
<div class="foc">
<div class="PetitCarre" id="pc22">
<img class="rankss unselectable" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\Rank\Bronze.png"/>
<img id="s2" class="unselectable slash2" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\All\Slashwhite.png"/>
</div>
</div>
<div class="foc">
<div class="PetitCarre" id="pc33">
<img class="rankss unselectable" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\Rank\Argent.png"/>
<img id="s3" class="unselectable slash3" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\All\Slashwhite.png"/>
</div>

I think you should give the divs the same class name the select them using querySelectorAll then create forEach loop on them add click event listener for them inside the event check for the current rank and div rank then return the required price also insted of using fer1 fer2 use [fer1,fer2] it would be much better. if you could provide the html maybe I could help more
UPDATE
you can modify this as it fit your project
// ranks variable will hold all the ranks
// currentRank will hold the user current rank if user have current rank
const ranks = document.querySelectorAll(".foc");
const currentRank = document.getElementById("");
const total = document.getElementById("total");
let upgradePrice = 0;
// this will loop over every rank div you have
ranks.forEach(rank=>{
// then we will add event listener for mouse clicks
rank.addEventListener("click",event=>{
// here you will write the upgrade logic like checking the clicked div id
// so you can know which rank is this and if you need to do any
// validation you can do it here then after you finish you can
// add the upgrade cost to upgradePrice variable so you show it to user
// and be able to use it in another part in your code if needed
// also if you want to get id or class of any element in the rank div
// or the parent element of the div you can use `event`
// you can search for the propertys you can use with `event.target` in google
// you can get the id of the div or the id of any element inside it use event argument
// const rankId = event.target.id <- this the div id
upgradePrice+=100
// after you finish you can change the div style to using `event.target.style`
// event.target.style.background = "red"; <- to mark the div as selected
total.innerHTML = `${upgradePrice}€`
})
})

Related

Add "No results found" message on div search

I'm making an audio player, and I have a list of divs acting as my playlist... I'm using JS to make the list, and I'm using this script to search through them:
/*Search Songs*/
function searchSongs(){
let input = _('#songSearch').value.toLowerCase();
let items = _all('.item');
let dividers = _all(".divider");
for (let i = 0; i < items.length; i++) {
if (!items[i].innerHTML.toLowerCase().includes(input)) {
items[i].style.display = "none";
}
else {
items[i].style.display = "";
}
}
// add noresults message at end if all list divs are hidden
if (!items.innerHTML.toLowerCase().includes(input)) {
_('.noResults').innerHTML = `<p>No results found for "${input}"`
}
}
I have a paragraph element at the end of my list (with nothing in it) and I want to show the message (<p>No results found for "${input}") is there some js I can use to accomplish this? The script above is working for the searching, but not working for the message.
Finished result:
/*Search Songs*/
function searchSongs(){
let input = _('#songSearch').value.toLowerCase();
let items = _all('.item');
let dividers = _all(".divider");
let counter = 0;
for (let i = 0; i < items.length; i++) {
if (!items[i].innerHTML.toLowerCase().includes(input)) {
items[i].style.display = "none";
counter++;
}
else {
items[i].style.display = "";
}
}
// keeping the result 22 letters long (for asthetic purposes)
let maxLen = 22;
if (input.length > maxLen) {
input = input.substring(0, maxLen - 3) + "...";
}
if (counter >= items.length) {
_('#noResults').innerHTML = `No results found for "${input}"` //add no results message if all items are hidden...
} else {
_('#noResults').innerHTML = `` //else hide the message by removing text.
}
}
Thanks, #Asif !!
I've made a little modification in your function. I hope this will solve your issue.
/*Search Songs*/
function searchSongs(){
let input = _('#songSearch').value.toLowerCase();
let items = _all('.item');
let dividers = _all(".divider");
let counter = 0;
for (let i = 0; i < items.length; i++) {
if (!items[i].innerHTML.toLowerCase().includes(input)) {
items[i].style.display = "none";
}
else {
items[i].style.display = "";
counter++;
}
}
// add noresults message at end if all list divs are hidden
if (counter > 0) {
_('.noResults').innerHTML = `<p>No results found for "${input}"`
}
}

How to select an element from NodeList in JavaScript?

I wanted to make a food order app, and try to make the quantity buttons like this with my own code: https://css-tricks.com/examples/InputNumberIncrementer/
I struggled with the results. There is an input which will set the quantity once incButtons or decButtons is clicked.
But when I click a button, all the inputs change. How do I fix it, if I want the input to change only on the clicked button, not set to all inputs?
this is my source code :
let incButton = document.querySelectorAll('.inc');
let decButton = document.querySelectorAll('.dec');
// Increment Button
for (let i = 0; i < incButton.length; i++){
incButton[i].addEventListener('click', function() {
// show the decButton when quantity > 1
decButton[i].style.display = 'inline';
// increment the quantity when incButton clicked
for (let i = 0; i < incButton.length; i++){
let inputField = document.querySelectorAll('.quantityNumber');
if(incButton) {
let newVal = parseInt(inputField[i].value) + 1;
inputField[i].value = newVal;
console.log('Quantity +1 added');
}
}
});
};
// Decrement Button
for (let i = 0; i < decButton.length; i++) {
decButton[i].addEventListener('click', function () {
let inputField = document.querySelectorAll('.quantityNumber');
for (let i = 0; i < inputField.length; i++) {
// if decButton is clicked and quantitiy >= 2 decrement it
if (decButton[i] && inputField[i].value >= 2) {
let newVal = parseInt(inputField[i].value) - 1;
inputField[i].value = newVal;
console.log('Quantity -1 reduced');
}
// hide the decButton when quantity is 1
if (inputField[i].value == 1) {
decButton[i].style.display = 'none';
}
}
});
};
<div class="quantity">
<button class="dec">-</button>
<input type="text" class="quantityNumber" value="1">
<button class="inc">+</button>
</div>
<br>
<div class="quantity">
<button class="dec">-</button>
<input type="text" class="quantityNumber" value="1">
<button class="inc">+</button>
</div>
Please help me to solve this, and thank you before for the questions :)

how to manage a counter on different blades in laravel?

Hello i am working on a project i need to send item in session and add limit only 4 item will be add on session. it's working on one blade but when i move to another blade it will show nothing on the button like how many items in the session and when am trying to add another item it will add.
this is my script
var increment = 0;
$(document).ready(function(){
$(".compare").click(function(){
increment++;
document.getElementById('compare').innerHTML = "";
document.getElementById('compare').innerHTML = "Compare (" +increment+")";
if(increment == 4)
{
var array = document.getElementsByClassName('compare');
for (var i = 0 ; i < array.length ; i++)
{
array[i].setAttribute('disabled','');
}
}
i am wanted to add only 4 items in the session from every where.
please send any solution .
Try this :
var increment = 1;
$(document).ready(function(){
if(localStorage.getItem("compare") > 0){
increment = localStorage.getItem("compare");
document.getElementById('compare').innerHTML = "Compare (" +increment+")";
} else {
document.getElementById('compare').innerHTML = "";
}
$(".compare").click(function(){
if(increment == 4)
{
var array = document.getElementsByClassName('compare');
for (var i = 0 ; i < array.length ; i++)
{
array[i].setAttribute('disabled','');
}
} else {
increment++;
localStorage.setItem("compare", increment);
document.getElementById('compare').innerHTML = "Compare (" +increment+")";
}
}
}

Show a hidden div when no results were found in a Search input

I'm using the w3schools.com w3.js search engine
It works fine, but I need it to display a <div> for when the search engine cannot match any search.
Here's my code:
<input type="text" id="myInput" oninput="w3.filterHTML('#myTable', 'p', this.value)" placeholder="Search for names..">
<div id="myTable">
<div>
<p>Adele</p>
</div>
<div>
<p>Agnes</p>
</div>
<div>
<p>Billy</p>
</div>
<div>
<p>Bob</p>
</div>
</div>
<div id="no-data-div" style="display:none">
<p>No Results Found :(</p>
</div>
and the Script:
<script>
var w3 = {};
w3.getElements = function (id) {
if (typeof id == "object") {
return [id];
} else {
return document.querySelectorAll(id);
}
};
w3.filterHTML = function(id, sel, filter) {
var a, b, c, i, ii, iii, hit;
a = w3.getElements(id);
for (i = 0; i < a.length; i++) {
b = w3.getElements(sel);
for (ii = 0; ii < b.length; ii++) {
hit = 0;
if (b[ii].innerHTML.toUpperCase().indexOf(filter.toUpperCase()) > -1) {
hit = 1;
}
c = b[ii].getElementsByTagName("*");
for (iii = 0; iii < c.length; iii++) {
if (c[iii].innerHTML.toUpperCase().indexOf(filter.toUpperCase()) > -1) {
hit = 1;
}
}
if (hit == 1) {
b[ii].parentElement.style.display = "";
} else {
b[ii].parentElement.style.display = "none";
}
}
}
};
</script>
I want "#no-data-div" to be visible when all the others divs are hidden. How can I achieve this?
I spent some time adjusting your code. I believe this should work for you. I commented your code so you know which each part is doing (as far as I can tell), and adjust as needed... The main addition is just the counter (totalHits++) which runs through the script so it can be analyzed at the end to decide if the no results div should be shown or not.
w3.filterHTML = function(id, sel, filter) {
// w3 search filter function, adjusted by Nerdi.org (username on StackOverflow/my website)
// https://stackoverflow.com/questions/49742504/show-a-hidden-div-when-no-results-were-found-in-a-search-input
var a, b, c, i, ii, iii, hit;
a = w3.getElements(id);
// a.length will tell you # of tables (should be = to 1, as in 1 table being searched)
var totalHits = 0; // let's get a total count.
for (i = 0; i < a.length; i++) {
b = w3.getElements(sel);
// b.length will tell you # of valid selections (by tag, in this case you are searching the <p> tags)
for (ii = 0; ii < b.length; ii++) {
hit = 0;
if (b[ii].innerHTML.toUpperCase().indexOf(filter.toUpperCase()) > -1) {
hit = 1;
totalHits++;
}
c = b[ii].getElementsByTagName("*");
// c.length will tell us how many children this elem has so we can cycle through any child elements within the first selection (in this case, <p>)
var cLength = c.length;
for (iii = 0; iii < cLength; iii++) {
if (c[iii].innerHTML.toUpperCase().indexOf(filter.toUpperCase()) > -1) {
hit = 1;
totalHits++;
}
}
if (hit == 1) {
b[ii].parentElement.style.display = "";
} else {
b[ii].parentElement.style.display = "none";
}
}
}
// now that we've looped through all results, let's see if we found anything using our totalHits var that we set earlier :)
if(totalHits == 0){
document.getElementById('no-data-div').style.display = 'block'; // show the no results found
} else {
document.getElementById('no-data-div').style.display = 'none'; // hide the no results found
}
};

Getting the index of the current element and change his styles

I have a function whose destination is to work onClick event.
So, we have for example 4 Span elements and 4 Div elements.
The Spans are Tabs-buttons which I would like to "open" those Divs.
The 1st Span onClick would (open) change the style.display of the 1st Div in "block", from "none", and so on for the next Spans.
This piece of code works very well, but it changes only the design of elements.
function activateSup(s) {
var workTable = s.parentNode.parentNode.parentNode.parentNode.parentNode;
var spans = workTable.getElementsByTagName("span");
var supDivs = workTable.getElementsByClassName("supDiv");
for (var i = 0; i < spans.length; i++) {
spans[i].style.backgroundColor = "";
spans[i].style.border = "";
}
s.style.backgroundColor = "#5eac58";
s.style.border = "2px solid #336633";
}
I've tried to add the code below into my function to achieve what I want, but It does not work.
var getIndex = function(s) {
for (var index = 0; s != s.parentNode.childNodes[index]; index++);
return index;
}
for (var d = 0; d < supDivs.length; d++) {
if (getIndex == d) {
supDivs[d].style.display = "block";
}
else {
supDivs[d].style.display = "none";
}
}
I'm not exactly sure what you're trying to do, but one thing I noticed is this:
var getIndex = function(s) { /* .... */ }
for (var d = 0; d < supDivs.length; d++) {
if (getIndex == d) {
supDivs[d].style.display = "block";
}
else { /* ... */ }
}
This code is comparing getIndex to d, which means it's comparing an integer (d) to the function getIndex, instead of the result of the function call getIndex(spans[d]) (which is an integer, like d).
But what I think you're really trying to do, is getting the index of the clicked <span> so you can show the <div> with the matching index (and hide the rest). To achieve this, the code could be changed like so:
function activateSup(s) {
var workTable = s.parentNode.parentNode.parentNode.parentNode.parentNode;
var spans = workTable.getElementsByTagName("span");
var supDivs = workTable.getElementsByClassName("supDiv");
var index;
for (var i = 0; i < spans.length; i++) {
spans[i].style.backgroundColor = "";
spans[i].style.border = "";
if (s == spans[i])
index = i;
}
s.style.backgroundColor = "#5eac58";
s.style.border = "2px solid #336633";
for (var d = 0; d < supDivs.length; d++) {
if (index == d) {
supDivs[d].style.display = "block";
} else {
supDivs[d].style.display = "none";
}
}
}
Instead of the function getIndex, this just saves the correct index inside the first for loop.
There are many more improvements that could be made to this code, like rewriting it so you don't need that ugly s.parentNode.parentNode.parentNode.parentNode.parentNode and working with CSS classes instead of manually setting the style. But I'll leave that to the reader.

Categories