I am trying to create a slideshow but the addEventListener is not working !!
i am beginner in js world and want to get better by projects but this simple project has stumped me.
const nextBtn = document.querySelector(".next-btn");
const prevBtn = document.querySelector(".prev-btn");
const slides = document.querySelectorAll(".slide");
const slider = document.querySelector(".slider");
const slideIcons = document.querySelectorAll(".slide-icon");
// selecting total number of slides
const numberOfSlides = slides.length;
// whatever
const slideNumber = 0;
// manual functionality
// next-btn
nextBtn.addEventListener("click" ,() => {
slides.forEach(slide =>{
slide.classList.remove("actve");
});
slideIcons.forEach((slideIcon) => {
slideIcon.classList.remove("active");
});
})
I don't got the whole situation but as I see your need to add event Listener to your slider so am gonna give you ex about range slider event handler
// this stores the value at startup (which is why you're always getting 1)
var rangeInput = document.getElementById("rangeinput").value;
You should be reading the value in the handler instead:
function testtest(e) {
// read the value from the slider:
var value = document.getElementById("rangeinput").value;
// now compare:
if (value > 0 && value < 5) {
alert("First");
} else {
alert("Second");
}
}
now Updating rangevalue
It also looks like you want to update the output element with the value of the range. What you're currently doing is referring to the element by id:
onchange="rangevalue.value=value"
However, as far as I know, this isn't standard behavior; you can't refer to elements by their id alone; you have to retrieve the element and then set the value via the DOM.
Might I suggest that you add a change listener via javascript:
rangeInput.addEventListener("change", function() {
document.getElementById("rangevalue").textContent = rangeInput.value;
}, false);
Of course, you'll have to update the code to use addEventListener or attachEvent depending on the browsers that you want to support; this is where JQuery really becomes helpful.
Use the mouseup event for that.
var rangeInput = document.getElementById("rangeinput");
rangeInput.addEventListener('mouseup', function() {
if (this.value > 0 && this.value < 5) {
alert("First");
} else{
alert("Second");
}
});
You can also use the FORMs oninput method:
<form oninput="result.value=parseInt(a.value)+parseInt(b.value)">
<input type="range" name="b" value="50" />100 +
<input type="number" name="a" value="10" /> =
<output name="result"></output>
</form>
This has an advantage over onclick/onmouseup because it handles the case where the slider is moved using the keyboard (tab to the input and use the arrow keys)
Try giving your html elements an id and then use getElementById instead of querySelector
Related
The Problem:
I can't seem to be able to get a list of buttons to change the value of their corresponding inputs.
I'm trying to code a cart system for my website, pretty standard. It involves a list of item, each of which have a section that includes two buttons for adding or subtracting the quantity of its corresponding item. These buttons surround the input that displays the current quantity (disabled so that the user must use the buttons to control it).
Everything is working, but I can't seem to figure out how to target the corresponding input of a button that is clicked so that it will change the value of that specific input.
What I've Tried:
I've figured out that if I add a [0] at the end of the "quantityInputs" variable then it will target the first input in the list, makes sense. But I don't want it to only target the first input, I want it to target the input that the button is associated with. Even then, when I test the plus button it only updates the input one time to 2 and then stops, which I only know because I'm printing the value to the console - it doesn't actually change the display on the webpage.
I've considered using a for loop to get the position of the input, but I'm not sure how to incorporate that into the code in order for it to work with the for loop that gets the position of the plus or minus buttons, or if that will even work.
Can anyone please help me out? I'd really appreciate it.
My Code:
HTML:
if (document.readyState == 'loading') {
document.addEventListener('DOMContentLoaded', ready)
} else {
changeQuantity()
}
function changeQuantity() {
var buttonUps = document.getElementsByClassName('item-quantity-up')
console.log('There are ' + buttonUps.length + ' plus buttons total.') // Tells you how many plus buttons there are.
for (var i = 0; i < buttonUps.length; i++) { // Get the positions of each plus button.
var button = buttonUps[i]
button.addEventListener('click', addQuantity) // When a plus button is clicked, run the addQuantity function.
}
var buttonDowns = document.getElementsByClassName('item-quantity-down')
console.log('There are ' + buttonDowns.length + ' minus buttons total.') // Tells you how many minus buttons there are.
for (var i = 0; i < buttonDowns.length; i++) { // Get the positions of each minus button.
var button = buttonDowns[i]
button.addEventListener('click', subQuantity) // When a minus button is clicked, run the subQuantity function.
}
}
function addQuantity(event) {
var quantityInputs = document.getElementsByClassName('cart-item-quantity') // Needs an index such as [0] in order to return a real number.
var inputValue = parseInt(quantityInputs.value) // Turns the value into an integer.
var max = quantityInputs.max // Retrieves the max value for the input.
if (inputValue >= max) {
inputValue = inputValue // If the quantity is greater than or equal to the max, then don't change the quantity.
} else {
inputValue = inputValue + 1 // If the quantity is less than the max, then add 1 to the quantity.
console.log(inputValue)
}
}
function subQuantity(event) {
var quantityInputs = document.getElementsByClassName('cart-item-quantity') // Needs an index such as [0] in order to return a real number.
var inputValue = parseInt(quantityInputs.value) // Turns the value into an integer.
var min = quantityInputs.min // Retrieves the min value for the input.
if (inputValue <= min) {
inputValue = inputValue // If the quantity is less than or equal to the min, then don't change the quantity.
} else {
inputValue = inputValue - 1 // If the quantity is greater than the min, then subtract one from the quantity.
console.log(inputValue)
}
}
<div class="cart-quantity-field">
<button class="item-quantity-down">-</button>
<input class="cart-item-quantity" type="number" min="1" max="20" value="1" disabled>
<button class="item-quantity-up">+</button>
</div>
You can manipulate the correct input field by doing the following:
On quantity-button click:
locate the clicked button's parent element
inside that parent, look for input with the correct class name
decide whether the button clicked should add or subtract one
add +1 or -1 respectively to the current value of the input
const allQuantityBtns = document.getElementsByClassName("quantity-btn");
Array.from(allQuantityBtns).forEach(btn => {
btn.addEventListener("click", e => {
const inputToChange = e.target.parentElement.querySelector(".cart-item-quantity");
const plusOrMinusOne = e.target.classList.contains("item-quantity-up") ? 1 : -1;
const newValue = parseInt(inputToChange.value) + plusOrMinusOne;
// validate newValue here. Eg: is it allowed to be smaller than zero?
inputToChange.value = newValue;
});
});
<div class="cart-quantity-field">
<button class="item-quantity-down quantity-btn">-</button>
<input class="cart-item-quantity" type="number" min="1" max="20" value="1" disabled>
<button class="item-quantity-up quantity-btn">+</button>
</div>
Note: you may wish to implement some validation:
stop the quantity from being too large or small before modifying the input's value
so I was trying to make a simple search option whereas the user types in the name, the name shows up. However, with my code, the name shows up only when the user completely types the name right. Basically, I want it to show all available names relevant to user's search (If user
const li = document.querySelectorAll("li");
const input = document.querySelector("#search");
const form = document.querySelector("form");
const searchBtn = document.querySelector("button");
const loopThrough = () => {
for (var i = 0; i < li.length; i++) {
if (input.value.toLowerCase() === li[i].innerText.toLowerCase()) {
li[i].style.display = "block";
}
if (li[i].style.display = "block" && input.value.toLowerCase().length == 0) {
li[i].style.display = "none";
}
}
}
input.addEventListener("keyup", loopThrough);
<form>
<input type="search" id="search" placeholder="Search here...">
<button type="button">Search</button>
</form>
<ul>
<li>Pierre</li>
<li>Peter</li>
<li>Philip</li>
<li>Mazen</li>
<li>Zeina</li>
<li>Anna</li>
<li>Wael</li>
<li>Fadi</li>
<li>Faris</li>
<li>Walid</li>
</ul>
types "p", I want all names that start with "p" to show up.)
and initially, in CSS, all li display property is set to none
This is a trivial thing to do with JavaScript and a document like you have. Some pointers:
Forget "keyup", and in fact all explicit keyboard events. You are doing yourself and your users disservice. Not all devices have keyboards, and smart people behind Web standards have long ago foreseen this and there are "input" and "change" events available to fire on every text input control.
You can initiate a search on every "input" or "change" event, but if your search queries take any time at all, you would be wise to reset a search timeout on every "input" event at least instead -- some people type very fast, and there is no good need on application's part to run a search query for every letter typed -- that would be well over 10 searches a second in many cases for fast typers. Waste of resources -- reset a timeout so that a search is queued after half a second or so. The number should typically be user's preference, but it's a minute preference that most people won't bother with, so just use some good enough average.
Don't use inline styles in this case. They very seldom are a fitting part of a solution. Use CSS classes, so that behavior and style of the elements that match your search, can be specified in the stylesheet. Or you can use the hidden attribute, it may be suitable, depending.
Here is some off-the-top-of-my-head code that solves your problem, adapted from your snippet:
var timeout;
document.getElementById("form").elements.search.addEventListener("input", function(ev) {
if(timeout) clearTimeout(timeout);
timeout = setTimeout(function(input) {
for(const li of document.querySelectorAll("li")) {
li.classList.toggle("match", li.textContent.startsWith(input.value));
}
}, 500, ev.target);
});
Use startsWith function
With your code:
const li = document.querySelectorAll("li");
const input = document.querySelector("#search");
const form = document.querySelector("form");
const searchBtn = document.querySelector("button");
const loopThrough = () => {
for (var i = 0; i < li.length; i++) {
if (input.value.toLowerCase().startsWith(li[i].innerText.toLowerCase())) {
li[i].style.display = "block";
}
if (li[i].style.display = "block" && input.value.toLowerCase().length == 0) {
li[i].style.display = "none";
}
}
}
input.addEventListener("keyup", loopThrough);
There is a page and I am trying to attach an onclick event to the button ("SEARCH CRUISES") on the page but the onclick event is not firing correctly. Here is my code:
<script>
debugger;
var x = document.getElementsByClassName("cdc-filters-search-cta")
for (i=0; i< x.length; i++){
if(x[i].text.trim().indexOf("SEARCH") >= 0 && x[i].text.trim().indexOf("CRUISES") >= 0){
x[i].onclick = function(){
console.log("Search button clicked");
};
break;
}
}
Here is the complete html: https://jsfiddle.net/g0tkqrx6/
I have tried attaching the onclick event to the object in many different ways but I am not able to get the click event to fire. I would appreciate if anybody can provide some insight as to what I could be doing wrong here.
Thanks in advance
Seeing your html would be helpful. Make sure you are interacting with the correct names for your js events.
You must use textContent for element text and make it uppercase.
Here is an example:
var x = document.getElementsByClassName("cdc-filters-search-cta")
for (var i=0; i< x.length; i++){
var element = x[i] ;
if((element.textContent ).toUpperCase().indexOf("SEARCH") >= 0 && element.textContent.toUpperCase().indexOf("CARS") >= 0){
element.onclick = function(){
console.log("Search button clicked");
};
break;
}
}
<button class="cdc-filters-search-cta"> SEARCH</button>
<button class="cdc-filters-search-cta"> CARS</button>
<button class="cdc-filters-search-cta">SEARCH CARS</button>
Well to start with I think you should really take a look at this article on why you shouldn't add inline functions or css.
https://www.tomdalling.com/blog/coding-styleconventions/why-inline-comments-are-generally-a-bad-idea/
Secondly I think your issue is that you are trying to add a click event to an angular front end which is controlled by the ngModel and also the site is probably compiled AOT. However you can try this,
let x = document.querySelectorAll('.cdc-filters-search-cta');
let term = /[(SEARCH)(CRUISES)]/
x = Array.from(x);
x.forEach(span => {
if (term.test(span.textContent)) {
return span.addEventListener('click', (e) => {
console.log('span clicked')
});
}
})
I changed your code to querySelectorAll which returns an array and I used a forEach loop to add an eventListener. Not sure how well that will go down with your angular, but maybe.
I have a JavaScript variable:
var setClickTime = "2000";
I would like to give the user a choice of 2000 or 4000 based on their preference by clicking a button.
What is the best way to allow the user to change this variable? I have considered having two buttons one of which will have the class active when clicked. That would require me to set up an if / else statement to change the variable based on which button is active. But I am new to this and I do not know the best approach.
Just give your buttons IDs and bind listeners.
Say, you have two buttons id="setTime2000" and id="setTime4000", then you just need:
HTML Code:
<div>
<button id="setTime2000">Set time as 2000</button>
<button id="setTime4000">Set time as 4000</button>
</div>
JS Code:
$(document).ready() {
var mTime = 2000; // set the default value of time
$("#setTime2000").click(function () {
mTime = 2000;
}
$("#setTime4000").click(function () {
mTime = 4000;
}
// ... do something with the variable set
}
Do you just want a button event listener to change it:
<button id="changeBtn">4000</button>
JS
var setClickTime = "2000";
$("#changeBtn").click(function() {
setClickTime = "4000";
})
First, you have a JavaScript variable, it has nothing to do with jQuery.
Then, if you want something easy, without dependencies. Here a simple example:
var myValue = 2000;
updateOutput();
a.addEventListener('click', function() {
myValue = 2000;
updateOutput()
});
b.addEventListener('click', function() {
myValue = 4000;
updateOutput()
});
function updateOutput() {
output.value = myValue;
}
<button id="a">2000</button>
<button id="b">4000</button>
<input readonly id="output">
A generic answer in pure javascript.
<button class='setTime'>
2000
</button>
<button class='setTime'>
4000
</button>
Pure Javascript:
var setClickTime = "";
var buttons = document.getElementsByClassName('setTime')
for (i = 0; i < buttons.length; i++) {
this.onclick = function setTime(event) {
setClickTime = event.target.innerHTML;
alert(setClickTime);
}
}
fiddle: https://jsfiddle.net/b1vy8ahp/
You can define multiple radio buttons for more options ( with same name attribute to group them ) and then just delegate or bind a change event on that group of radios buttons to get the selected value.
<input type="radio" name="test" value="2000">2000
<input type="radio" name="test" value="4000">4000
<script>
var setClickTime;
$('input:radio[name=test]').on('change',function()
{
setClickTime = this.value;
});
</script>
Example : https://jsfiddle.net/DinoMyte/71hgeqnb/1/
I have the following code
$(document).ready(function () {
$('#big_1').change(function () {
var bigAmt = document.getElementById("big_1").value
+ document.getElementById("big_2").value
+ document.getElementById("big_3").value
+ document.getElementById("big_4").value
+ document.getElementById("big_5").value
+ document.getElementById("big_6").value
+ document.getElementById("big_7").value
+ document.getElementById("big_8").value
+ document.getElementById("big_9").value
+ document.getElementById("big_10").value;
var elem = document.getElementById("totalBig");
elem.value = bigAmt;
});
});
I actually wanted to add the value of big_1 to big_10 on input text value change of "big_1 to big_10" either 1 of the textfield change its value, this should be invoke.
as of now i only run on big_1 change event.
I get an javascript error by adding this way, I think the way I add them up is quite messy.
What should I do to change my code so I can sum up
big_1 to big_10 textfield value, and on change of big_1 to big_10(any of them), it will invoke this and change span id="totalBig" to the value of their sum (big_1 add until big_10)
Below is my edited extra code:
<input type="number" data-bv-digits-message="true" data-bv-threshold="1" min="0" class="form-control" name="big_1" id="big_1" size="6">
<input type="number" data-bv-digits-message="true" data-bv-threshold="1" min="0" class="form-control" name="big_2" id="big_2" size="6">
all the way until big_10
I wanna on change value of any of this big_Identifier(1-10), it will sum it up and change my
<div class="well">
Total Big: <span id="totalbig">0</span> </span>
</div>
I tried the
<script type="text/javascript">
$(document).ready(function() {
$('#html5Form').bootstrapValidator();
$('.big').change(function() {
var bigAmt = "";
$('.big').each(function () {
bigAmt += $(this).val();
})
var elem = document.getElementById("totalBig");
alert(bigAmt);
elem.value = bigAmt;
});
});
</script>
It doesn't run any alert when any of the big_ value was changed.
It would be much better if you added a big class to every single <input id="big_NUMBER">. Then you could do this:
$(document).ready(function() {
$('.big').change(function() {
var bigAmt = 0;
$('.big').each(function () {
bigAmt += Number($(this).val());
})
$("#totalBig").val(bigAmt);
});
});
That's much cleaner and easier to understand than what you had.
In order for this to work, you'll need to add a class to all your inputs:
<input type="number" data-bv-digits-message="true" data-bv-threshold="1" min="0" class="form-control big" name="big_2" id="big_2" size="6"><!-- Notice the big class-->
This is the best way to group all your inputs. They are all related, so they should share a classes. You should not be calling multiple ids for functionality that's so similar.
If you are using jquery, use it properly, it'll make your life a lot easier.
This will work for you in your case exactly
$(document).ready(function() {
$('[id^="big"').change(function(){
var total = (+$('#totalBig').val());
var currentVal = (+$(this).val());
total += currentVal;
$('#totalBig').val(total)
})
});
DEMO
Add class="bigs" to all inputs and then try this:
$(document).ready(function () {
var intTotalBig;
$('.bigs').change(function () {
intTotalBig = 0;
$('.bigs').each(function(){
$thisVal = $(this).val();
if ($.isNumeric($thisVal)){
intTotalBig += parseInt($thisVal, 10);
}
});
$("#totalBig").val(intTotalBig);
});
});
This code check all inputs on every change and sum all of them that has a number value and ignore empty or no number values.
Check JSFiddle Demo
You monitor the change event on all the input type text as follows:
$('input:text').change(
function () {
alert('text changed of any text box.');
//You can doo your code here.
});
Or...
If you want add the monitor to any selected text boxes then you will have to add any css class to those selected text boxes and then monitor those text boxes through class as follows:
$('.yourclass').change(
function () {
alert('text changed of any text box.');
//You can doo your code here.
});
this change event will fire when you lose focus from the text box after changing the text....
but if you want with loosing the focus (means if you want to update the count while typing) then you should use keyup event as stated in this answer.
$(document).ready(function() {
$('#big_1').change(function() {
var divArray = ["big_1","big_2","big_3","big_4","big_5","big_6","big_7","big_8","big_9","big_9","big_10"];
var bigAmt = 0;
for(var i = 0, n = divArray.length;i<n;i++)
{
bigAmt += parseInt($("#" + divArray[i]).val(),10);
}
$("#totalBig").val(bigAmt);
});
});
Try the above, it should do what you're looking for. You'll probably want to use parseInt as well incase the input isn't of "number" type.
*edit, forgot the # for the id.
*edit, removed comment about considering using jquery functions because people are really sensitive.