On click show next tab in formular (div) - javascript

I got multiple divs with the class tab <div class="tab">i am div 1</div><div class="tab">i am div 2 </div>. Inside i have some input field anon the bottom I got a next and back button
<div class="funnel-buttons text-right">
<button type="button" class="icon-btn" id="prevBtn">Back</button>
<button type="button" class="icon-btn" id="nextBtn" onclick="nextTab()">Next</button>
</div>
now after clicking next or back button I want the next or prev div to shown up so I made a JS function when tab[0] is displayed and clicking next I should dissappear.
const tab = document.getElementsByClassName('tab');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
tab[0].style.display = 'block';
tab[1].style.display = 'none';
function nextTab () {
if(tab[0].style.display == 'block') {
tab[1].style.display = 'block';
tab[0].style.display = 'none';
}
}
But when I do so all the tabs disappear and nothing is shown.
Where is the error?

you can solve like this
const tab = document.getElementsByClassName('tab');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
function nextTab() {
const currentTab = document.querySelector('.show');
const tabArray = Array.from(tab);
const currentIndex = tabArray.indexOf(currentTab);
console.log(currentIndex);
currentTab.classList.remove('show');
currentTab.classList.add('hide');
if (tabArray.length > currentIndex + 1) {
tabArray[currentIndex + 1].classList.remove('hide');
tabArray[currentIndex + 1].classList.add('show');
} else {
// to return first tab at the end
tabArray[0].classList.remove('hide');
tabArray[0].classList.add('show');
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.show {
display: block;
}
.hide {
display: none;
}
</style>
</head>
<body>
<div class="tab show">1</div>
<div class="tab hide">2</div>
<div class="tab hide">3</div>
<div class="funnel-buttons text-right">
<button type="button" class="icon-btn" id="prevBtn">Back</button>
<button type="button" class="icon-btn" id="nextBtn"
onclick="nextTab()">Next</button>
</div>
<script src="app.js"></script>
</body>
</html>

You can introduce a variable to capture which is the current tab - in my code currentVisible. Based on that you can manipulate which tab you want to see on the UI. Also you can use .forEach() to iterate through all the <div> elements which has tab class added. Finally you can change the visibility with ternary operator like i === currentVisible ? 'block' : 'none'.
Try as the following:
const tab = document.getElementsByClassName('tab');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
let currentVisible = 0;
const handleTab = n => {
if (currentVisible + n >= 0 && currentVisible + n < tab.length) {
currentVisible += n;
Array.prototype.forEach.call(tab, (e, i) => {
tab[i].style.display = i === currentVisible ? 'block' : 'none';
});
}
}
handleTab(0);
<div class="funnel-buttons text-right">
<button type="button" class="icon-btn" id="prevBtn" onclick="handleTab(-1)">Back</button>
<button type="button" class="icon-btn" id="nextBtn" onclick="handleTab(1)">Next</button>
</div>
<div class="tab">I am div 1</div>
<div class="tab">I am div 2 </div>
<div class="tab">I am div 3</div>
<div class="tab">I am div 4 </div>
I hope this helps!

Related

For each element inside an array I want it to have another for each that will have unique action

I wanted to make each element inside myArray will have it's unique action, but I end up with only one of them working.
I have tried one more way of doing it that worked, but it was a complete boilerplate and I'm looking for a better solution than that.
More details:
For each element (Another array of buttons) inside myArray it will have unique action like scrollIntoView of some element in HTML.
In HTML I have 4 divs that share the same class and it looks like that:
<div class='firstDiv'>
<button class="teamBtn"></button>
<button class="serviceBtn"></button>
etc..
</div>
<div class='secondDiv'>
<button class="teamBtn"></button>
<button class="serviceBtn"></button>
etc..
</div>
let aboutSection = document.querySelector('.about')
let serviceSection = document.querySelector('.services')
let teamSection = document.querySelector('.team')
let homeBtn = document.querySelectorAll('.homeBtn');
let aboutBtn = document.querySelectorAll('.aboutBtn');
let serviceBtn = document.querySelectorAll('.serviceBtn')
let teamBtn = document.querySelectorAll('.teamBtn')
let myArray = [];
myArray[0] = homeBtn;
myArray[1] = aboutBtn;
myArray[2] = serviceBtn;
myArray[3] = teamBtn;
myArray.forEach(el => {
addEventListener('click', () => {
teamBtn.forEach(() => {
teamSection.scrollIntoView();
});
serviceBtn.forEach(() => {
serviceSection.scrollIntoView();
});
})
})
You really want delegation from a container wrapping ALL divs. Then only one event handler is needed for all buttons
document.getElementById("nav").addEventListener("click",function(e) {
const tgt = e.target.closest("button")
if (tgt && (tgt.classList.contains("teamBtn") ||tgt.classList.contains("serviceBtn"))) {
document.getElementById(tgt.dataset.id).scrollIntoView();
}
})
section div {
height: 500px;
background-color: red;
border: 1px solid black;
}
<nav id="nav">
<div class="firstDiv">
<button class="teamBtn" data-id="team1">Team 1</button>
<button class="serviceBtn" data-id="service1">Service 1</button>
</div>
<div class="secondDiv">
<button class="teamBtn" data-id="team2">team 2</button>
<button class="serviceBtn" data-id="service2">Service 2</button>
</div>
</nav>
<section id="content1">
<div id="team1">Team 1</div>
<div id="service1">Service 1</div>
</section>
<section id="content2">
<div id="team2">Team 2</div>
<div id="service2">Service 2</div>
</section>

Arrange todo items using drag and drop

I'm trying to create a todo list then use drag and drop to arrange it as I want. I have a dummy data (list items) which I can arrange as I want. the problem I am having is any new todo I add to the list item can not be dragged or rearrange.
here is my code below
var form = document.getElementById('addForm');
var itemList = document.getElementById('items');
form.addEventListener('submit', addTodo);
itemList.addEventListener('click', removeItem)
function addTodo(e) {
e.preventDefault()
// get input value
var newTodo = document.getElementById('todo');
// create new li element
var li = document.createElement('li')
//add class draggable property
li.className = 'draggable';
li.draggable = true
// add textnode with input value
li.appendChild(document.createTextNode(newTodo.value))
// delete button
var delBtn = document.createElement('button')
delBtn.className = 'btn btn-danger btn-sm float-right del';
delBtn.appendChild(document.createTextNode('X'))
li.appendChild(delBtn)
itemList.appendChild(li)
newTodo.value = ""
}
function removeItem(e) {
if (e.target.classList.contains('del')) {
if (confirm('Are you sure?')) {
var li = e.target.parentElement
itemList.removeChild(li)
}
}
}
const draggables = document.querySelectorAll('.draggable')
draggables.forEach(draggable => {
draggable.addEventListener('dragstart', () => {
draggable.classList.add('dragging')
})
draggable.addEventListener('dragend', () => {
draggable.classList.remove('dragging')
})
})
itemList.addEventListener('dragover', (e) => {
e.preventDefault()
const draggable = document.querySelector('.dragging')
const afterElement = getDragAfterElement(draggable, e.clientY)
console.log(afterElement);
if (afterElement == null) {
itemList.appendChild(draggable)
} else {
itemList.insertBefore(draggable, afterElement)
}
})
function getDragAfterElement(draggables, y) {
const draggableElements = [...document.querySelectorAll('.draggable:not(.dragging)')]
console.log('Dragable', draggableElements);
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect()
const offset = y - box.top - box.height / 2
if (offset < 0 && offset > closest.offset) {
return {
offset: offset,
element: child
}
} else {
return closest
}
}, {
offset: Number.NEGATIVE_INFINITY
}).element
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Todo task</title>
<!-- Font Awesome -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css">
<!-- Google Fonts -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap">
<!-- Bootstrap core CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet">
<!-- Material Design Bootstrap -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/css/mdb.min.css" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container mt-2">
<div class="row justify-content-center">
<div class="col-md-8">
<h1>Todo Task</h1>
<div class="card">
<div class="card-header bg-grey">
<h4>What Todo</h4>
</div>
<div class="card-body">
<form action="" id="addForm">
<div class="form-group mt-2 pl-5">
<label for="">Title of Task</label>
<input type="text" id="todo" placeholder="Enter todo..." class="form-control">
</div>
<button type="submit" id="submit" class="btn btn-primary btn-sm">Submit</button>
</form>
</div>
</div>
<div class="jumb mt-4">
<h2>Todo Lists</h2>
<ul class="list-group" id="items">
<li class="draggable" draggable="true">Item 1 <button class="btn btn-danger btn-sm float-right del">X</button></li>
<li class="draggable" draggable="true">Item 2 <button class="btn btn-danger btn-sm float-right del">X</button></li>
<li class="draggable" draggable="true">Item 3 <button class="btn btn-danger btn-sm float-right del">X</button></li>
</ul>
</div>
</div>
</div>
</div>
<!-- JQuery -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Bootstrap tooltips -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.4/umd/popper.min.js"></script>
<!-- Bootstrap core JavaScript -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js"></script>
<!-- MDB core JavaScript -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/js/mdb.min.js"></script>
<script src="app.js"></script>
</body>
</html>
If I understand it correctly you are attaching some events to every item on the list to allow the drag&drop functionality.
The new elements don't have those events attached to them, though. You need to watch for new elements and initialize the drag&drop functionality for them too.
NOTICE: Heretic Monkey has linked to a more comprehensive answer.
You need to warp this piece of into function
const draggables = document.querySelectorAll('.draggable')
draggables.forEach(draggable => {
draggable.addEventListener('dragstart', () => {
draggable.classList.add('dragging')
})
draggable.addEventListener('dragend', () => {
draggable.classList.remove('dragging')
})
})
To
function enableDragDrop() {
const draggables = document.querySelectorAll('.draggable')
draggables.forEach(draggable => {
draggable.addEventListener('dragstart', () => {
draggable.classList.add('dragging')
})
draggable.addEventListener('dragend', () => {
draggable.classList.remove('dragging')
})
})
}
and call the function in addTodo(e) that is called event binding
function addTodo(e) {
....
enableDragDrop();
}
also, call the function on page load show it should bind the drag events by default
....
var form = document.getElementById('addForm');
var itemList = document.getElementById('items');
form.addEventListener('submit', addTodo);
itemList.addEventListener('click', removeItem)
enableDragDrop();
Complete JS.
var form = document.getElementById('addForm');
var itemList = document.getElementById('items');
form.addEventListener('submit', addTodo);
itemList.addEventListener('click', removeItem)
enableDragDrop();
function addTodo(e) {
e.preventDefault()
// get input value
var newTodo = document.getElementById('todo');
// create new li element
var li = document.createElement('li')
//add class draggable property
li.className = 'draggable';
li.draggable = true
// add textnode with input value
li.appendChild(document.createTextNode(newTodo.value))
// delete button
var delBtn = document.createElement('button')
delBtn.className = 'btn btn-danger btn-sm float-right del';
delBtn.appendChild(document.createTextNode('X'))
li.appendChild(delBtn)
itemList.appendChild(li)
newTodo.value = "";
enableDragDrop();
}
function removeItem(e) {
if (e.target.classList.contains('del')) {
if (confirm('Are you sure?')) {
var li = e.target.parentElement
itemList.removeChild(li)
}
}
}
function enableDragDrop() {
const draggables = document.querySelectorAll('.draggable')
draggables.forEach(draggable => {
draggable.addEventListener('dragstart', () => {
draggable.classList.add('dragging')
})
draggable.addEventListener('dragend', () => {
draggable.classList.remove('dragging')
})
})
}
itemList.addEventListener('dragover', (e) => {
e.preventDefault()
const draggable = document.querySelector('.dragging')
const afterElement = getDragAfterElement(draggable, e.clientY)
console.log(afterElement);
if (afterElement == null) {
itemList.appendChild(draggable)
} else {
itemList.insertBefore(draggable, afterElement)
}
})
function getDragAfterElement(draggables, y) {
const draggableElements = [...document.querySelectorAll('.draggable:not(.dragging)')]
console.log('Dragable', draggableElements);
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect()
const offset = y - box.top - box.height / 2
if (offset < 0 && offset > closest.offset) {
return {offset: offset, element: child}
} else {
return closest
}
}, {offset: Number.NEGATIVE_INFINITY}).element
}

Remove class if id's the correct ID

Looking to remove a class if a certain button is clicked.
<div class="slide-container">
<section class="about" id="slide-0">
<div class="menu-total">
<nav class="nav">
<button class="nav_link home" onclick="slideTo('slide-2')">HOME</button>
<button class="nav_link about" onclick="slideTo('slide-0')">ABOUT</button>
<button class="nav_link fun-stuff" onclick="slideTo('slide-1')">FUN STUFF</button>
<button class="nav_link professional" onclick="slideTo('slide-3')">PROFESSIONAL</button>
<button class="nav_link contact" onclick="slideTo('slide-4')">CONTACT</button>
</nav>
<div class="hamburger">
<span class="hamburger__patty"></span>
<span class="hamburger__patty"></span>
<span class="hamburger__patty"></span>
</div>
</div>
The one I want to remove the class on is the HOME button. So "slideTo('slide-2)". If it's clicked on the others then the class is kept. I believe someone is either wrong with my loop or not getting the ID correctly of the items/
function slideTo(slideId) {
const slide = document.getElementById(slideId);
slide.scrollIntoView({
behavior: 'smooth'
})
// above this line works fine
let nonHome = document.querySelectorAll('.slide-container section');
let nonHomeID = document.getElementById('slide-2');
var i;
setTimeout(function(){
for (i=0; i < nonHome.length; i++ ){
// i believe it's somewhere here it is wrong
if (nonHome[i].id != nonHomeID){
nonHome[i].classList.add("nav-visibility");
} else{
nonHomeID.classList.remove("nav-visibility");
}
}
}, 1000)
}
If you can use jquery library, you can write in the HTML:
<button class="nav_link" data-value="home">HOME</button>
...
and then in the JS code:
$(".nav_link").on("click", function() {
var valueClicked = $(this).data("value"); // Get the data-value clicked
$(".nav_link").each(function() { // Loop through all elements of the class 'nav-link'
var v = $(this).data("value");
if (v == valueClicked) {
$(this).removeClass("nav-visibility");
} else {
$(this).addClass("nav-visibility");
}
)
}
Not much simpler, but the HTML is cleaner.
Simpler version if it is not required to browse through all buttons at each button click:
$(".nav_link").on("click", function() {
var valueClicked = $(this).data("value"); // The value of the button clicked by the user
if (valueClicked == "home") {
$(this).removeClass("nav-visibility");
console.log('remove')
} else { $(this).addClass("nav-visibility");
console.log('add')
}
});

How to create a proper start button on typing game using vanilla javascript

I'm trying to create a start button for my Javascript game that starts the and when the game is over resets the game. As of right now, the button I have starts the game but when it's "Game Over" the timer doesn't reset or start. The words change but not the timer or score. I tried using the reload.location and it didn't do anything.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/css/bootstrap.min.css"> -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css">
<title>One Piece WordBeater</title>
</head>
<body>
<body class="bg-dark text-white">
<header class="bg-secondary text-center p-3 mb-5">
<h1>One Piece Word Beater</h1>
</header>
<div class="container text-center">
<!--Word & Input-->
<div class="row">
<div class="col-md-3 mx-auto">
<p class="lead">Current Level: <span class="text-info" id="levels"></span></p>
</div>
<div class="col-md-6 mx-auto">
<p class="lead">Type the Given Word Within <span class="text-success" id="seconds">5</span> Seconds. </p>
<h2 class="display-2 mb-5" id="current-word">luffy</h2>
<input type="text" class="form-control form-control-lg" placeholder="Start Typing..." id="word-input" autofocus>
<h4 class="mt-3" id="message"></h4>
<br>
<div class="btn-group">
<button type="button" class="btn btn-warning mr-5" id="start"><b>Let's Play!</b></button>
<button type="button" class="btn btn-danger" id="reset"><b>Reset Game</b></button>
</div>
</div>
<div class="col-md-3 mx-auto">
<p class="lead">High Score: <span class="text-info" id="highsocre"></span></p>
</div>
</div>
<!--Time and Columns-->
<div class="row mt-5">
<div class="col md-6">
<h3>Time left: <span id="time">0</span></h3>
</div>
<div class="col md-6">
<h3>Score: <span id="score"> 0 </span></h3>
</div>
</div>
<!--Instructions-->
<div class="row mt-5">
<div class="col md-12">
<div class="card card-body bg-secondary text-white">
<h5>Instructions</h5>
<p>Type each word in the given amount of seconds to score. To play again, just type the current word. Your score
will reset</p>
</div>
</div>
</div>
<!--Level Selector-->
<div class = "row mt-5">
<div class="col md-12">
<div class="card card-body bg-secondary text-white">
<h5>Select the Difficulty</h5>
<div class="row mt-5">
<div class="col md-12">
<div class="btn-group">
<button type="button" class="btn btn-success mr-2" id="easy">Easy</button>
<button type="button" class="btn btn-primary mr-2" id="medium">Medium</button>
<button type="button" class="btn btn-danger" id="hard">Hard</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="index.js"></script>
</body>
</html>
JavaScript:
window.addEventListener('load', init,);
//Avaible levels
const levels = {
easy: 5,
medium: 3,
hard: 2,
}
//to cchange level
const currentLevel = levels.easy;
let time = currentLevel;
let score = 0;
let isPLaying;//initalzies game...true if game is on false if game is off
/*function resetGame(){
const resetBtn = document.getElementById('reset')
resetBtn.onclick = function() {
let time = currentLevel;
let score = 0;
let isPLaying; //Show number of seconds
}
}*/
//DOM Elements
const wordInput = document.querySelector('#word-input');
const currentWord = document.querySelector('#current-word');
const scoreDisplay = document.querySelector('#score');
const timeDisplay = document.querySelector('#time');
const message = document.querySelector('#message');
const seconds = document.querySelector('#seconds');
const levelDisplay = document.querySelector('#levels');
const words = [
'luffy',
'zoro',
'shanks',
'nami',
'brook',
'chooper',
'sanji',
'franky',
'jinbe',
'carrot',
'pekoms',
'ace',
'sabo',
'robin',
'bellamy',
'crocodile',
'merry',
'yonko',
'camie',
'nefertari',
'raizo',
'momo',
'law',
'dracule',
'boa',
'buggy',
'golroger',
'bigmom',
'smoker',
'kaido'
];
//initialize Game
/*function init() {
// //Show number of seconds
seconds.innerHTML = currentLevel;
// //load a word from array
showWord(words);
// //Start Matching on word input
wordInput.addEventListener('input', startMatch);
// //Call countdown every second
setInterval(countdown, 1000);
// //Check status
setInterval(checkStatus, 50)
} */
function init() {
//start button
const startBtn = document.getElementById('start')
startBtn.onclick = function() {
//Show number of seconds
seconds.innerHTML = currentLevel;
//load a word from array
showWord(words);
//Start Matching on word input
wordInput.addEventListener('input', startMatch);
//Call countdown every second
setInterval(countdown, 1000);
//Check status
setInterval(checkStatus, 50)
}
}
//level Buttons
//Easy Mode
// document.getElementById('easy').addEventListener('click', easyMode);
// function easyMode(levels) {
// }
//Start Match
//converts words to lowercase
function startMatch() {
if(matchWords()){
isPLaying = true;
time = currentLevel + 1;
showWord(words);
wordInput.value='';
score++;
}
//if score negative -1 display 0
if(score === -1){
scoreDisplay.innerHTML = 0;
}else{
scoreDisplay.innerHTML = score;
}
}
//Match Current Word to word imput
function matchWords(){
if(wordInput.value.toLowerCase() === currentWord.innerHTML) {
message.innerHTML = 'Correct!!!';
return true;
} else {
message.innerHTML = '';
return false;
}
}
//Pick & Show random word
function showWord(words) {
//Generate random array index
const randIndex = Math.floor(Math.random() * words.length);
//Output random word
currentWord.innerHTML = words[randIndex];
}
//Countdown Timer
function countdown() {
//Make sure time is not run out
if(time > 0) {
//Decrease time
time--;
}else if(time === 0) {
//Game Over
isPLaying = false;
}
//Show time
timeDisplay.innerHTML = time;
}
//Check game Status
function checkStatus() {
if(!isPLaying && time === 0){
message.innerHTML = 'Game Over!!';
score = -1;
}
}
Your timer doesn't reset because you didn't stop it with the clearInterval function. The score doesn't reset because you didn't change it in HTML.
First Of all to understang what is wrong with your timer add this code inside your checkStatus() function and open the developer console of your navigator. You will see that your timer continue even if the game is over.
console.log("The game is over but the timer continue...");
OK now, to fix you issue: add this to your code to keep a reference and use it later:
let countDownInterval;
let checkStatusCountDown;
modify your init() function with:
countDownInterval = setInterval(countdown, 1000);
checkStatusCountDown = setInterval(checkStatus, 50);
Now when the game is over we will clear the time interval and reset the score:
function checkStatus() {
if(!isPLaying && time === 0){
message.innerHTML = 'Game Over!!';
score = -1;
scoreDisplay.innerHTML = 0; // reset score in html
clearInterval(checkStatusCountDown); // clear interval
clearInterval(countDownInterval); // clear interval
}
}

How do I make JS code not affect other DIV?

Hi I am try to make a list of item, I have "add" and "minus" button for each item. The problem is that the JS code I had control two items together. ex. if I click "add" for item1, then the item2 gets added as well.
Looks like that my JS functions works for all button elements. So when I click a "button" element, all buttons get triggered.
How can I do add them individually?
PS: I guess I need to do something like a specific ID for JS to trigger. My thought is add a unique ITEM ID for each one and trigger the button under that specific ID so other buttons under other ITEM ID don't get triggered.
Here is my HTML code:
<div class="row bb">
<div class="col-xs-12 food-container">
<img src="img/1.png" class="min-w img-responsive" />
<div class="food-detail">
<div class="food-name">test</div>
<div class="food-sales">test:233333</div>
<div class="food-price">
¥50
<div class="food-edit">
<button class="btn btn-info" value="50.55" id="minus">-</button>
<span class="num-sales"></span>
<button class="btn btn-info" value="50.55" id="add">+</button>
</div>
</div>
</div>
</div>
</div>
<div class="row bb">
<div class="col-xs-12 food-container">
<img src="img/1.png" class="min-w img-responsive" />
<div class="food-detail">
<div class="food-name">test</div>
<div class="food-sales">test:233333</div>
<div class="food-price">
¥50
<div class="food-edit">
<button class="btn btn-info" value="50.55" id="minus">-</button>
<span class="num-sales"></span>
<button class="btn btn-info" value="50.55" id="add">+</button>
</div>
</div>
</div>
</div>
</div>
Here is my JS:
var theTotal = 0;
var theSales = 0;
var minusButton = document.getElementById('minus');
if (theSales == 0) {
$(minusButton).hide();
}
$('button').click(function () {
var ID = this.id;
if (ID == "add") {
$(minusButton).show();
theTotal = Number(theTotal) + Number($(this).val());
theSales++;
var num = theTotal.toFixed(2);
$('.total').text("¥" + num);
$('.total-num-of-sales').text(theSales + "份");
$('.num-sales').text(theSales);
};
if (ID == "minus") {
theTotal = Number(theTotal) - Number($(this).val());
theSales--;
var num = theTotal.toFixed(2);
if ( theSales == 0 ) {
$('.total').text("");
$('.total-num-of-sales').text("");
$('.num-sales').text("");
$(minusButton).hide();
}
else if ( theSales > 0 ) {
$('.total').text("¥"+num);
$('.total-num-of-sales').text(theSales + "份");
$('.num-sales').text(theSales);
}
};
});
Don't use multiple id on same page
http://jsfiddle.net/bjc1c9tr/4/
Check this will help you
var theTotal = 0;
var theSales = 0;
var minusButton = $('.minus');
if (theSales == 0) {
$(minusButton).hide();
}
$('button').click(function(){
var ID = $(this).attr('data');
if (ID == "add") {
$(this).parent().find('.minus').show();
theTotal = Number($(this).parent().find('.num-sales').text()) + Number($(this).val());
theSales = Number($(this).parent().find('.num-sales').text()) + Number(1);
var num=theTotal.toFixed(2);
$(this).parent().find('.total').text("¥"+num);
$(this).parent().find('.total-num-of-sales').text(theSales+"份");
$(this).parent().find('.num-sales').text(theSales);
};
if (ID == "minus") {
theTotal = Number($(this).parent().find('.num-sales').text()) - Number($(this).val());
theSales= Number($(this).parent().find('.num-sales').text()) - Number(1);
var num=theTotal.toFixed(2);
if ( theSales == 0) {
$('.total').text("");
$(this).parent().find('.total-num-of-sales').text("");
$(this).parent().find('.num-sales').text("");
$(this).parent().find('.minus').hide();
}
else if ( theSales > 0) {
$(this).parent().find('.total').text("¥"+num);
$(this).parent().find('.total-num-of-sales').text(theSales + "份")
$(this).parent().find('.num-sales').text(theSales);
}
};
});
html (added new classes)
<div class="row bb">
<div class="col-xs-12 food-container">
<img src="img/1.png" class="min-w img-responsive" />
<div class="food-detail">
<div class="food-name">test</div>
<div class="food-sales">test:233333</div>
<div class="food-price">¥50
<div class="food-edit">
<button class="btn btn-info minus" value="50.55" data="minus">-</button>
<span class="num-sales"></span>
<button class="btn btn-info add" value="50.55" data="add">+</button>
</div>
</div>
</div>
</div>
</div>
<div class="row bb">
<div class="col-xs-12 food-container">
<img src="img/1.png" class="min-w img-responsive" />
<div class="food-detail">
<div class="food-name">test</div>
<div class="food-sales">test:233333</div>
<div class="food-price">¥50
<div class="food-edit">
<button class="btn btn-info minus" value="50.55" data="minus">-</button>
<span class="num-sales"></span>
<button class="btn btn-info add" value="50.55" data="add">+</button>
</div>
</div>
</div>
</div>
</div>
$('button').click(function(){
var ID = this.id;
if (ID == "add") {
$(minusButton).show();
theTotal = Number(theTotal) + Number($(this).val());
theSales = Number($(this).parent().find('.num-sales').text())+1;
var num=theTotal.toFixed(2);
$('.total').text("¥"+num);
$('.total-num-of-sales').text(theSales+"份");
$(this).parent().find('.num-sales').text(theSales);
};
if (ID == "minus") {
theTotal = Number(theTotal) - Number($(this).val());
theSales = Number($(this).parent().find('.num-sales').text())-1;
var num=theTotal.toFixed(2);
if ( theSales == 0) {
$('.total').text("");
$('.total-num-of-sales').text("");
$(this).parent().find('.num-sales').text("");
//$('.num-sales').text("");
$(minusButton).hide();
}
else if ( theSales > 0) {
$('.total').text("¥"+num);
$('.total-num-of-sales').text(theSales + "份");
$(this).parent().find('.num-sales').text(theSales);
//$('.num-sales').text(theSales);
}
};
$(this).parent().find('.num-sales').text(theSales);
By this way you can get the parent of clicked button and change the value of .num-sales of the selected parent
https://jsfiddle.net/s2u9eb36/ refer this one
You are mixing the elements because of your id and class selectors.
When you select elements through jQuery by class (like $('.num-sales')), jQuery gives you a collection of all elements that match the selector. In your case, that would be both class="num-sales" elements.
Whenever you then call a function (like .html(theSales)), it will apply that function to each element in the collection, that's why your code is affecting more than one element.
You will need to find a way to distinguish one element of the other. There's quite a few options here, but I like doing it by limiting the scope of my selectors. With this I mean I would first find the food-detail div that contains the clicked element, and then find .num-sales etc... only within that element.
Then you can do the following in your button clicks:
$('button').click(function(){
var ID = this.id;
var element = $(this) //make a jQuery object of the clicked button
// finds the first parent element with class food-detail
var container = element.closest('.food-detail');
// find .num-sales within container
var numSales = container.find('.num-sales')
// continue...
});
in short:
when a button is clicked, find the food-detail div the button is in
.find in only that container instead of using selectors on the entire document
Edit: you should really change the id="Add" and id="minus" on your buttons, ids should be unique on the entire document. You can simply add add or minus as a class instead and check for it with element.hasClass('add').

Categories