I am trying to disable the "decrease" when the counter goes below 0 and re-enable it, when the counter goes up.
But when I press the "increase" button the "decrease" button stays disable.
Here is what I have so far:
let countEl = document.getElementById('count')
let decreaseEl = document.getElementById('decrease')
let resetEl = document.getElementById('reset')
let increaseEl = document.getElementById('increase')
let saveEl = document.getElementById("save")
let savedEl = document.getElementById('savedCount')
let message = "Invalid Value";
let invalid = false
let countNo = 0;
decreaseEl.addEventListener('click', function(){
countNo--;
if(countNo < 0){
countEl.textContent = message;
invalid = true
decreaseEl.disabled = true;
}else{
countEl.textContent = countNo;
invalid = false
if(invalid = false){
decreaseEl.disabled = false;
}
}
})
resetEl.addEventListener('click', function(){
countEl.textContent = 0;
countNo = 0;
savedEl.textContent = "Counts:";
})
increaseEl.addEventListener('click',function(){
countNo++;
countEl.textContent = countNo;
invalid = false
})
saveEl.addEventListener('click',function(){
if(invalid == true){
savedEl.textContent += "";
}else{
savedEl.textContent += " " + countNo + "-";
countNo = 0;
countEl.textContent = 0;
}
})
Cause you are added event listener on the button, you are disabling and undisabling the button inside the event listener.
You should do something like this:
increaseEl.addEventListener('click', function() {
countNo++;
countEl.textContent = countNo;
invalid = false;
if (countNo > 0) {
decreaseEl.disabled = false;
}
});
I would expect something like this:
let countEl = document.getElementById('count')
let decreaseEl = document.getElementById('decrease')
let resetEl = document.getElementById('reset')
let increaseEl = document.getElementById('increase')
let saveEl = document.getElementById("save")
let savedEl = document.getElementById('savedCount')
let message = "Invalid Value";
let invalid = false
let countNo = 0;
decreaseEl.addEventListener('click', function() {
countNo--;
const neg = countNo < 0;
countEl.textContent = neg ? message : countNo;
decreaseEl.disabled = neg;
if (neg) setTimeout(function() {
countNo = 0;
countEl.textContent = countNo
}, 2000); // optional
})
resetEl.addEventListener('click', function() {
countEl.textContent = 0;
countNo = 0;
savedEl.textContent = "Counts:";
})
increaseEl.addEventListener('click', function() {
countNo++;
countEl.textContent = countNo;
decreaseEl.disabled = countNo <= 0;
invalid = false
})
<span id="count">0</span>
<button id="increase">Increase</button>
<button id="decrease">Decrease</button>
<button id="reset">Reset</button>
<button id="save">Save</button>
<span id="savedCount">0</span>
Inside increaseEl.addEventListener add if(countNo=>0) decreaseEl.disabled = false;
let countEl = document.getElementById('count')
let decreaseEl = document.getElementById('decrease')
let resetEl = document.getElementById('reset')
let increaseEl = document.getElementById('increase')
let message = "Invalid Value";
let invalid = false
let countNo = 0;
decreaseEl.addEventListener('click', function(){
countNo--;
if(countNo <0){
countEl.textContent = message;
invalid = true
decreaseEl.disabled = true;
}else{
countEl.textContent = countNo;
invalid = false
if(invalid = false){
decreaseEl.disabled = false;
}
}
})
increaseEl.addEventListener('click',function(){
countNo++;
if(countNo=>0) decreaseEl.disabled = false;
countEl.textContent = countNo;
invalid = false
})
<button id="count">0</button>
<button id="increase">Increase</button>
<button id="decrease">Decrease</button>
As you have your answer as to why your doesn't work you may find this example useful/interesting. It's based from code I wrote as an answer to a similar question a couple of days ago.
All of the information about how it works is in that link, but basically it provides you with a way to handle the buttons from one listener (on the container), and there's no need for a global count variable.
// Cache the elements
const counterElement = document.querySelector('#counterValue');
const container = document.querySelector('#container');
const decrease = document.querySelector('button[data-type="decrease"]');
// Add a listener to the container
container.addEventListener('click', handleClick(), false);
// Initialise the count variable
function handleClick(count = 0) {
// Return a new function (the closure)
// as the function that will be called when
// the buttons are clicked
return function(e) {
// Get the button type from the clicked button
const { type } = e.target.dataset;
if (type === 'decrease') --count;
if (type === 'increase') {
// If the decrease button is disabled
// re-enable it
if (decrease.disabled) {
decrease.disabled = false;
}
++count;
}
// Disable the decrease button if it's zero
if (count === 0) decrease.disabled = true;
counterElement.textContent = count;
}
}
.counter-value {font-size: 36px; font-weight: 900; }
.button {color: #ffffff; background-color: #0967d2; font-size: 14px; border-width: 0; border-radius: 4px; padding: 10px;}
button { cursor: pointer; }
button:disabled { opacity: 30%; cursor: default;}
<p id="counterValue" class="counter-value">0</p>
<div id="container">
<button data-type="decrease" class="button" disabled>DECREASE</button>
<button data-type="increase" class="button">INCREASE</button>
</div>
The issue that you are having curretly is, you are settting the disabled status of your #decrease button onli inside the click event of #decrease button. This works in setting the disabled status of button to true.
You are setting the disabled status of the button to false inside the else statement of countNo < 0 inside the click event of #decrease button. Does this have any impact on your functionality? NO!!!. Why? Because when the number is negative, the button will be disabled and the click event wont trigger and the disable status wont be reset to false.
The enabling of the button should be handled in the #increase button click event instead. You can directly rest the disabled status to false if the button is disabled. Because the count wont go negative inside this function.
Working Fiddle
let countEl = document.getElementById('count')
let decreaseEl = document.getElementById('decrease')
let resetEl = document.getElementById('reset')
let increaseEl = document.getElementById('increase')
let saveEl = document.getElementById("save")
let savedEl = document.getElementById('savedCount')
let message = "Invalid Value";
let invalid = false
let countNo = 0;
decreaseEl.addEventListener('click', function () {
countNo--;
if (countNo < 0) {
countEl.textContent = message;
invalid = true
decreaseEl.disabled = true;
} else {
countEl.textContent = countNo;
invalid = false
// This doesnot have any impact
// if (invalid = false) {
// decreaseEl.disabled = false;
// }
}
})
resetEl.addEventListener('click', function () {
countEl.textContent = 0;
countNo = 0;
savedEl.textContent = "Counts:";
})
increaseEl.addEventListener('click', function () {
countNo++;
countEl.textContent = countNo;
invalid = false
if (decreaseEl.disabled) {
decreaseEl.disabled = !decreaseEl.disabled;
}
})
saveEl.addEventListener('click', function () {
if (invalid == true) {
savedEl.textContent += "";
} else {
savedEl.textContent += " " + countNo + "-";
countNo = 0;
countEl.textContent = 0;
}
})
<button id="count">0</button>
<button id="increase">Increase</button>
<button id="decrease">Decrease</button>
<button id="reset">Reset</button>
<button id="save">Save</button>
<p id="savedCount"></p>
Related
My pagination System currently looks like this:
What my pagination system currently looks like
However, I only want 10 page links to appear at a time. Instead of all of the links.
I have this code:
const nav = document.getElementById('nav');
const content = document.getElementById('content');
let pageIndex = 0;
let itemsPerPage = 3;
let finalPage = Math.ceil(items.length / itemsPerPage) - 1;
console.log(finalPage)
loadItems();
function loadItems() {
content.innerHTML = "";
for (let i = pageIndex * itemsPerPage; i < (pageIndex * itemsPerPage) + itemsPerPage; i++) {
if (!items[i]) break;
const item = document.createElement('div');
item.innerHTML = `
<div>
<img src="${items[i].src}"/>
</div>
<div>
<button>${items[i].desc}</button>
</div>
`;
content.append(item);
}
firstPage();
minusPage();
loadPageNav();
plusPage();
lastPage();
}
function loadPageNav() {
for (let i = 0; i < items.length / itemsPerPage; i++) {
const button = document.createElement('button');
button.classList.add('btn');
button.innerHTML = i + 1;
button.addEventListener('click', (e) => {
pageIndex = e.target.innerHTML - 1;
loadItems();
});
nav.append(button);
}
}
function plusPage() {
const button = document.createElement('button');
button.classList.add('btn');
button.innerHTML = "›";
button.addEventListener('click', () => {
pageIndex = pageIndex + 1;
loadItems();
});
nav.append(button);
if (pageIndex === finalPage) {
button.disabled = true;
}
}
function minusPage() {
const button = document.createElement('button');
button.classList.add('btn');
button.innerHTML = "‹";
button.addEventListener('click', () => {
pageIndex = pageIndex - 1;
loadItems();
});
nav.append(button);
if (pageIndex === 0) {
button.disabled = true;
}
}
function firstPage() {
nav.innerHTML = "";
const button = document.createElement('button');
button.classList.add('btn');
button.innerHTML = "«";
button.addEventListener('click', () => {
pageIndex = 0;
loadItems();
});
nav.append(button);
if (pageIndex === 0) {
button.disabled = true;
}
}
function lastPage() {
const button = document.createElement('button');
button.classList.add('btn');
button.innerHTML = "»";
button.addEventListener('click', () => {
pageIndex = finalPage;
loadItems();
});
nav.append(button);
if (pageIndex === finalPage) {
button.disabled = true;
}
}
This code produces the output shown above. However, I want to produce this output:
What my pagination system should look like
From my understanding, the loadPageNav function is the one that draws your page numbers. Pay attention to the maximum value your for loop goes too.
For example if you have 100 items (items.length = 100) and want to display only 5 items per page then
items.length / itemsPerPage is 100 / 5 = 20.
You have 20 pages and in your loop you create and add a button for each of those. If you want to limit the number of buttons drawn, then you need to limit the maximum value you assign to i.
i have i little project, that take the input of Name/Value; name and value stores in array as a string and looks lile this. arr = ['Name=Value', 'Name2=Value2'...]. the '=' is a spliter but the name=value is a solid string. So i need to sort my array and show it by name Asceding and then with other button sort it by value. i tried sort() method and it helped but i cant figure out how to sort it by value
let input = document.getElementById('input');
let values = document.getElementById('values');
let addButton = document.getElementById('addButton');
let SortByNameButton = document.getElementById('SortByNameButton');
let SortByValueButton = document.getElementById('SortByValueButton');
let DeleteButton = document.getElementById('DeleteButton');
let ShowXmlButton = document.getElementById('ShowXmlButton');
let warning = document.getElementById('warning');
/* valuesList Записывает значения попавшие в поле после валидации для их дальнейшего пользования */
let valuesList = [];
/*The validateEnterText Func checks the value of the input field using regex "validChars", and for the presence of at least one '=' character*/
function validateEnterText() {
const validChars = /^[а-яА-ЯёЁa-zA-Z0-9 =]*$/;
const spliter = '=';
if (validChars.test(input.value) === true) {
let inputTextValue = input.value.split('');
for (let i = 0; i < inputTextValue.length; i++) {
if (inputTextValue[i] === spliter && i != 0 && i < inputTextValue.length - 1) {
values.innerHTML += `<p>${input.value}</p>`;
valuesList.push(input.value)
warning.style.display = 'none';
break;
} else {
warning.style.display = 'block';
}
}
} else {
warning.style.display = 'block';
}
input.value = '';
}
/*Вынес функцию валидации текста ввода в отдельную функцию что бы добавить подтверждение ввода с помошью Enter*/
addButton.addEventListener('click', validateEnterText);
input.addEventListener('keyup', (e) => {
if (e.key === 'Enter') {
validateEnterText();
}
})
SortByNameButton.addEventListener('click', () => {
valuesList.sort();
values.innerHTML = '';
for (const value of valuesList) {
values.innerHTML += `<p>${value}</p>`;
}
})
I'm a newbie to js.And I'm making a simple calculator. Everything's working fine except delete button.I want the delete button to remove last character in the string. So I used both slice and substring method. But both aren't working. Is there something wrong in my code
let num = document.querySelector("#num");
let answer = document.querySelector("#answer");
let p = document.querySelector("#demo");
let numKeys = document.querySelectorAll(".numKeys");
let operator = document.querySelectorAll(".operator");
let removeNum = document.querySelector(".delete");
let clear = document.querySelector(".clear")
let btnValue = 0;
let numValue = "";
let called;
function numValues() {
let numKeyValue = Number(this.innerHTML);
if (num.value === "") {
numValue += numKeyValue;
} else if (called === true) {
num.value = "";
called = false;
numValue += numKeyValue;
} else {
numValue += numKeyValue;
}
num.value += numKeyValue;
console.log(numValue);
}
function operators(){
let add = this.value;
numValue += add;
called = true;
}
function result() {
num.value = eval(numValue);
}
function remove() {
numValue.substring(0, numValue.length -1);
console.log(numValue);
}
function clearAll() {
numValue = "";
num.value = "";
}
for (let i=0; i<numKeys.length; i++){
numKeys[i].addEventListener("click", numValues)
}
for (let i=0; i<operator.length; i++) {
operator[i].addEventListener("click", operators);
}
answer.addEventListener("click", result);
removeNum.addEventListener("click", remove);
clear.addEventListener("click", clearAll);
numValue = numValue.substring(0, numValue.length -1);
I would love some help with this project. I am creating a small project with Javascript, I am still new with HTML,CSS, and JavaScript. What I would like to do with my program, is that the counter will stop after 1 minute has passed and a pop up window appears that no more clicks are accepted. Below is my code, any help will be appreciated!!
var count = 0;
var countblack = 0;
var countred = 0;
var countButton = document.getElementById("black");
var countButtonC = document.getElementById("red");
var displayCount = document.getElementById("displayCount");
black.onclick = function() {
count++;
countblack++;
displayCount.innerHTML = count;
displayCountblack.innerHTML = countblack;
}
red.onclick = function() {
count++;
countred++;
displayCount.innerHTML = count;
displayCountred.innerHTML = countred;
}
http://jsfiddle.net/wr1ua0db/544/
You can use setTimeout to count 60seconds and then disable the buttons. Below is the solution
var allowClick = true;
var count = 0;
var countblack = 0;
var countred = 0;
var black = document.getElementById("black");
var red = document.getElementById("red");
var displayCount = document.getElementById("displayCount");
var displayBlackCount = document.getElementById("displayBlackCount");
var displayRedCount = document.getElementById("displayRedCount");
black.onclick = function() {
if (!allowClick) return;
count++;
countblack++;
displayCount.innerHTML = count;
displayBlackCount.innerHTML = countblack;
}
red.onclick = function() {
if (!allowClick) return;
count++;
countred++;
displayCount.innerHTML = count;
displayRedCount.innerHTML = countred;
}
startTime(60); // time in seconds
function startTime(time) {
var timer = setTimeout(function() {
black.setAttribute('disabled', 'disabled');
red.setAttribute('disabled', 'disabled');
allowClick = false;
clearTimeout(timer)
}, 1000 * time)
}
<button id="black">Count Black</button>
<button id="red">Count Red</button>
<div>Display Count: <span id="displayCount">0</span></div>
<div>Black Count: <span id="displayBlackCount">0</span></div>
<div>Red Count: <span id="displayRedCount">0</span></div>
I used the below code to upload multiple files. Its working absolutely fine but as i need to check that the file which i am uploading is duplicate or not, i am facing one problem in that. I created one function called checkDuplicate for that and calling it inside the function. But the problem is that the for loop is looping double the size of the array. I don't know why it is so. Please kindly help me if anyone has any idea.
Here is the Javascript
<script type="text/javascript">
function MultiSelector(list_target, max) {
this.list_target = list_target;
this.count = 0;
this.id = 0;
if (max) {
this.max = max;
} else {
this.max = -1;
};
this.addElement = function(element) {
if (element.tagName == 'INPUT' && element.type == 'file') {
element.name = 'file_' + this.id++;
element.multi_selector = this;
element.onchange = function() {
var new_element = document.createElement('input');
new_element.type = 'file';
this.parentNode.insertBefore(new_element, this);
this.multi_selector.addElement(new_element);
this.multi_selector.addListRow(this);
this.style.position = 'absolute';
this.style.left = '-1000px';
};
if (this.max != -1 && this.count >= this.max) {
element.disabled = true;
}
;
this.count++;
this.current_element = element;
}
else {
alert('Error: not a file input element');
}
;
};
this.addListRow = function(element) {
var new_row = document.createElement('div');
var new_row_button = document.createElement('img');
new_row_button.setAttribute("src","<%=request.getContextPath()%>/images/deletei.gif");
new_row_button.onclick = function() {
this.parentNode.element.parentNode.removeChild(this.parentNode.element);
this.parentNode.parentNode.removeChild(this.parentNode);
this.parentNode.element.multi_selector.count--;
this.parentNode.element.multi_selector.current_element.disabled = false;
return false;
};
if(checkDuplicate(element)) {
new_row.element = element;
new_row.innerHTML = element.value + " ";
new_row.appendChild(new_row_button);
this.list_target.appendChild(new_row);
}
};
};
function checkDuplicate(element) {
var arr = new Array();
var i = 0,dup=0;
//alert(new_row.element = element.value);
if(dup==0) {
arr[i++] = element.value;
dup=1;
}
alert("Length ==> "+ arr.length);
for ( var j = 0; j < arr.length; j++) {
alert("Name ==> " + arr[j]);
if(arr[j] == element.value && j>=1) {
alert("Duplicate");
} else {
alert("Not Duplicate");
arr[i++] = element.value;
}
}
}
</script>
Here is the HTML
<body>
<!-- This is the form -->
<form enctype="multipart/form-data" action=""method="post">
<input id="my_file_element" type="file" name="file_1">
<input type="submit">
<br/>
<br/>
Files:
<!-- This is where the output will appear -->
<div id="files_list"></div>
</form>
<script>
var multi_selector = new MultiSelector(document
.getElementById('files_list'), 15);
multi_selector.addElement(document.getElementById('my_file_element'));
</script>
</body>
</html>
because you have the arr[i++] = element.value; in the last line, and j < arr.length in the for, so every time the array.lenght gets bigger and bigger.
change the for line to these two lines:
var len = arr.length;
for ( var j = 0; j < len; j++) {