i've got this function and i need 'click' event to stop after input value reaches 0 and less
function clickPlus(e) {
var parent = e.target.parentNode,
span = parent.querySelector('span'),
input = parent.getElementsByTagName('input')[0],
inner = span.dataset.one,
price = inner * (++parent.querySelector('input').value);
span.innerHTML = price; // price takes an input value
if (price > 10){
return false; // error here
}
countPrice();
}
for(i=0; i<pluses.length; i++) eventsObj.addEvent(pluses[i],'click', clickPlus);
The 'countPrice' function fires regardless of the if statement.
Try the other way round with your if statement or add an else...
if(price>0)
{
countPrice();
}
Just unbind the click event from pluses[i]
You can unbind by calling the jquery unbind / off method.
$(pluses[i]).off('click');
value of pluses[i] is not given , so I am going to call the value as pluses[i] itself.
For more info - SO
jquery off method
Related
I am dynamically creating a table where i am adding onclick function to each column.
for (var x = 0; x < r.length; x++) {
//Setting the columns
if (i === 1) {
var headerCell = document.createElement("TH");
headerCell.innerHTML = r[x];
headerCell.id = x;
headerCell.onclick = function () {
sortTable(this.id, name);
}
row.appendChild(headerCell);
}
}
In a specific situation I want to disable the onclick function. Here is the code and it works.
$('#errorTable TH').prop("onclick", null).off("click");
and in another situation i want to reattach the onclick function. And that doesn't work. I want to enable the original function....
Any ideas ?
The way you created your table and adding/removing events are not easily maintainable. I also have some suggestions:
Review your code and define code click handler separately.
If you use jQuery in your project use it every where, if not, do not use it anywhere.
In your code i is undefined.
Add Remove Event Listener with jQuery
First define your handler function:
var myClickHandler = function(){
// this is your click handler
alert('Yes!!!');
}
Select your element and assign to a variable. <div id="clickable">Click Me!</div> must be in the DOM at the time of below script executed.
var element = $('#clickable');
// assign event listener
element.on('click',myClickHandler);
// remove event listener:
element.off('click',myClickHandler);
note that you must have to inform jQuery which handler should be removed.
See a sample https://codepen.io/softberry/pen/BEpove
An alternative is to build a click handler that checks a "kill switch".
var tableClickable = true;
headerCell.onclick = function () {
if (tableClickable) {
sortTable(this.id, name);
}
}
//In a specific situation I want to disable the onclick function.
something.addEventListener('someEvent', function () {
tableClickable = false;
});
//and in another situation i want to reattach the onclick function.
something.addEventListener('someOtherEvent', function () {
tableClickable = true;
});
I am trying to code a simple quiz app. I am trying to put a hidden screen at the end when one clicks on a button 3 times at the end. This is what I have tried:
for (var i = 0; i > 2; i++) {
onEvent("button26", "click", function() {
setScreen("TrollScreen");
playSound("sound://default.mp3", false);
});
}
I am fairly new to code, and I'm not sure how to do this. Help is appreciated.
You need to keep the count of the clicks outside of the event handler. Then inside it you can check that value and show the screen or increase the counter accordingly.
var count = 0;
onEvent("button26", "click", function(){
if(count > 2){
setScreen("TrollScreen");
playSound("sound://default.mp3", false);
}else{
count++;
}
});
Since all DOM elements are actually objects, you can attach a property to them that will serve as a counter, thus when a button gets clicked, you increment that property by 1 and then check if it reached 3 already.
A more subtle approach is to use a helper function that attaches the event and set up the counter as a closured variable, here is how:
function attachEventWithCounter(elem, func, maxClickCount) {
let count = 0;
elem.addEventListener("click", function(e) {
count++;
if(count >= maxClickCount) {
func.call(this, e);
// and probably reset 'count' to 0
}
});
}
You can then use it like so:
attachEventWithCounter(myButton, myEventListener, 3);
attachEventWithCounter just takes a DOM element, a function that will serve as the event listener and a number that will be the maximum amount of tries. It then attaches a click event listener (you could pass in the type of the event as well if you want) and then whenever that event happens, it increments a locally declared variable count (initially set to 0) and checks if it reached the maximum amount of tries, if so it just calls the function passed as parameter (using Function#call to pass a custom this and the event argument to mimic the actual event listener).
Example:
function attachEventWithCounter(elem, func, maxClickCount) {
let count = 0;
elem.addEventListener("click", function(e) {
count++;
if(count >= maxClickCount) {
func.call(this, e);
count = 0;
}
});
}
let btn = document.getElementById("myButton");
function listener() {
alert("Clicked at last!!!");
}
attachEventWithCounter(btn, listener, 3);
<button id="myButton">Click me 3 times</button>
this will click the button three times every time you press it (at least I think). instead, make a counter variable that starts at 0 and increment it up by 1 each time the button is pressed. the put the action you want to perform inside in an if statement ie
if(counter >= 3){
//do some action
}
hope that helps!
you want to keep a counter variable outside the scope of the event to keep track of how many times it was clicked. Ex.
let counter = 0;
onEvent("button26", "click", function() {
if(counter >= 3) {
setScreen("TrollScreen");
playSound("sound://default.mp3", false);
}
counter ++;
});
//create a variable to check how many times the button has been clicked
var buttonClick = 0;
function CheckCount() {
//Check if the buttonClick variable is three
if (buttonClick == 3) {
//if it is equal to three, display the screen and play the sound
//below commented out for sake of demo
//setScreen("TrollScreen");
//playSound("sound://default.mp3", false);
document.getElementById('buttonclickcount').innerHTML = "You clicked it three times";
} else {
//if it is not so, then increment the buttonClick variable by 1
buttonClick++
//so you can see how many times the button has been clicked
document.getElementById('buttonclickcount').innerHTML = buttonClick;
}
};
<!--I would create an onclick event on the button itself that runs a function when -->
<button onclick="CheckCount()">You Win!</button>
<div id="buttonclickcount"></div>
You should look at using closures. This is where you define a variable before returning a function; your returned function closes around this variable. You could do something like in this fiddle.
const button = document.getElementById('button');
const output = document.getElementById('output');
const click = (function() {
let count = 0;
return function() {
count++;
if(count > 3) {
output.innerHTML = 'Count is greater than 3: ' + count
}
}
})();
button.addEventListener('click', click);
I am having some trouble understanding what is happening in a piece of vanilla JS for the Isotope filter. The original code is here: https://codepen.io/desandro/pen/VWLJEb
var buttonGroups = document.querySelectorAll('.button-group');
for (var i = 0; i < buttonGroups.length; i++) {
var buttonGroup = buttonGroups[i];
var onButtonGroupClick = getOnButtonGroupClick(buttonGroup);
buttonGroup.addEventListener('click', onButtonGroupClick);
}
function getOnButtonGroupClick(buttonGroup) {
return function(event) {
// check for only button clicks
var isButton = event.target.classList.contains('button');
if (!isButton) {
return;
}
var checkedButton = buttonGroup.querySelector('.is-checked');
checkedButton.classList.remove('is-checked')
event.target.classList.add('is-checked');
}
}
What is happening between the getOnButtonGroupClick function and it being assigned to a variable in the for loop preceding it?
getButtonGroupClick returns a closure that saves the value of buttonGroup. When you click on a button in the button group, it uses that closure variable to search for the checked button in the group, uncheck it, and then check the button you clicked on.
This complexity isn't really needed. When an event listener is called, event.currentTarget is set to the element that the listener was attached to, so you could just use that.
var buttonGroups = document.querySelectorAll('.button-group');
for (var i = 0; i < buttonGroups.length; i++) {
var buttonGroup = buttonGroups[i];
buttonGroup.addEventListener('click', onButtonGroupClick);
}
function OnButtonGroupClick(event) {
// check for only button clicks
var isButton = event.target.classList.contains('button');
if (!isButton) {
return;
}
var checkedButton = event.currentTarget.querySelector('.is-checked');
checkedButton.classList.remove('is-checked')
event.target.classList.add('is-checked');
}
The for loop is used to iterate over all of the elements with the class of button-group and and a click event listener to them. getOnButtonGroupClick returns a function to be used as the function to be used as the event listener for the element i.e. the function that is run when the element is clicked on.
var buttonGroups = document.querySelectorAll('.button-group');
//get all elements within the document with a class of button-group
//buttonGroups is a NodeList
for (var i = 0; i < buttonGroups.length; i++) {
//loop through all of the elements with a class of button-group matched by the above query selector
var buttonGroup = buttonGroups[i];
//get the element in the NodeList with the index i
var onButtonGroupClick = getOnButtonGroupClick(buttonGroup);
//get the function to be run when the element is clicked on
buttonGroup.addEventListener('click', onButtonGroupClick);
//add a click event listener to the element
}
function getOnButtonGroupClick(buttonGroup) {
return function(event) {
// check for only button clicks
var isButton = event.target.classList.contains('button');
//check if the element has a class of button
if (!isButton) {
//if the element does not have a class of button, do nothing
return;
}
var checkedButton = buttonGroup.querySelector('.is-checked');
checkedButton.classList.remove('is-checked')
event.target.classList.add('is-checked');
}
}
If I understood your question correctly, It means that a click event is being added to every button in the buttonGroups there is. Although, if you ask me, it would be way better and cleaner to just use a forEach, like so:
const buttonGroups = document.querySelectorAll('.button-group');
buttonGroups.forEach(button => button.addEventListener("click", OnButtonGroupClick)
function OnButtonGroupClick(event) {
// check for only button clicks
let isButton = event.target.classList.contains('button');
if (!isButton) {
return;
}
let checkedButton = event.currentTarget.querySelector('.is-checked');
checkedButton.classList.remove('is-checked')
event.target.classList.add('is-checked');
}
So, you add a click event to ALL the buttons in the buttonGroups that will run the function onButtonGroupClick.
EDIT: And there's no really need to assign the function like that... at all. Just call it on the click event and that's it.
I am working on a kendo Grid, on its databound event, I have called a function to check whether value in each of the row's second block is greater than first block. If true then I change color of texts inside by adding a class.
But, the problem is the added class gets away finally when I see on browser.
If there are two rows with error the first row that I am editing doesn't hold the class but the later ones holds that well.
dataBound: configureGridProperties,
Code for dataBound is
function configureGridProperties(e) {
try {
if (true) {
$('#grid .k-grid-content tr[role=row]').each(function (i) {
var sh = $(this).find('.sh').text();
var sm = $(this).find('.sm').text()
var eh = $(this).find('.eh').text()
var em = $(this).find('.em').text()
var startMin = parseInt(sh) * 60 + parseInt(sm);
var endMin = parseInt(eh) * 60 + parseInt(em);
if (startMin > endMin) {
showOutputExplicitly('Start time cannot be less than end time');
$(this).find('.sh, .sm,.eh,.em').addClass('timeError');
$('div.k-grid-pager').hide();
errorInTime = false;
}
else {
$(this).find('.sh, .sm,.eh,.em').removeClass('timeError');
if (!$('.timeError').length > 0) {
$('div.k-grid-pager').show();
hideErrorMsgSlow();
errorInTime = true;
}
}
});
}
return false;
} catch (e) {
}
pic for the situation . >
The second row that I just edited(start time 23) doesn't hold the colorChange class, but earlier ones hold that. Is there any other event that occurs after dataBound event?
It happens that when dataBound is called, the grid html elements are not rendered yet with the new data. I know that is strange, but I don't know other way than using setTimeout to make this work. So this may work:
dataBound: function(e) {
window.setTimeout(configureGridProperties.bind(this, e), 1);
}
Reference:
dataBound
bind()
I am trying to make a number keypad from 0 to 9 and when certain numbers get pressed in a certain order an event will happen.
So something like this
if ( button1 gets pressed then button2 then button3 )
alert('You did the code!')
}
else {
alert('You did not do the code')
}
No jQuery please
Thanks!
//sequence is 358
//SOLUTION
sequence = {
check : function(e){
sequence.value += this.textContent;
if (sequence.value == sequence.sequence)
{
alert(1);
sequence.value = "";
}
else
{
if (sequence.timer)
{
clearTimeout(sequence.timer);
}
sequence.timer = setTimeout("sequence.value=''", 1000);
}
},
value : "",
sequence : "358"
}
//THIS CODE ATTACHES CLICK HANDLERS TO THE BUTTON, NOT PART OF THE SOLUTION
Array.prototype.map.call(document.querySelectorAll("button"), function(element){
element.addEventListener("click", sequence.check, false);
});
//end
<button>7</button><button>8</button><button>9</button><br/>
<button>4</button><button>5</button><button>6</button><br/>
<button>1</button><button>2</button><button>3</button><br/>
<button>0</button>
How does this work. I don't want to pollute the global scope with values so I used an object to store the variables and the check method in.
The object is called sequence.
It has three properties
check, the method that checks the input when a button is clicked.
value, that holds the sequence value until the correct sequence is found.
sequence, the property that holds the correct value.
Each button on the page is assigned with a click handler. When clicked it fires sequence.check. Via the this keyword (referring to the button) we extract the number (via textContent). We add that number to the value string. Then we check if the value matches the sequence. If so execute some code (in this case an alert) and reset the value.
There is a timer set. If the user doesn't enter a new number within a second the timer will reset the value. setTimeout does this. The 1000 stands for 1000 milliseconds = 1 second.
I would achieve this by monitoring the keydown event, and if the key is a number, add in to an array. At the same time, check the array contents to see if they are in a certain defined order. If they are, fire whatever you need to do, if not, do nothing but add the key to the array. Once your sequence has been completed, clear the array to make way for a new sequence.
You could get complicated with things like, clearing the array after a certain interval of not completing the sequence etc.
Here is a simple system that does part of what you are looking for:
var buttons = document.querySelectorAll('button'),
i;
for (i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function() {
var pressed = document.getElementById('pressed');
pressed.value += this.value + "|";
if (pressed.value === '1|2|3|') {
alert('You unlocked it!');
}
if (pressed.value.length >= 6) {
//Start over
pressed.value = "";
}
}, false);
}
<input id='pressed' type='text' />
<button value='1'>One</button>
<button value='2'>Two</button>
<button value='3'>Three</button>