How reset the one() function on an object? - javascript

I had 6 circles. I'm trying to prevent my users to click NOT in order from 1-6, from left-right.
Ex : Users should not allow clicking on the 2nd or 3rd one if they not yet clicked on the first one.
I have access to the index of all those circles.
if(steps.indexOf(selector) != 0){
alert("Please start by selecting your device.");
return false;
}
Since my circles click bind using a one() so it only listening to an event one time only, after they click on a wrong order, my alert pop up, BUT when I click on the same circle again, nothing will happen anymore since the circle bind using one() function.
Is there a way to reset the one() on a $(this) object so that way it will listen to an event again?
$('.' + selector).on("click", function() {
...
});
How reset the one() function on an object - jQuery ?

Don't add a one time listener, instead add an all time listener, and solve your problem using business logic. For example like this example:
const $first = document.getElementById('first'),
$second = document.getElementById('second'),
$third = document.getElementById('third');
function makeOrderedClick() {
let currentStep = 0;
return index => {
if (index !== currentStep) {
alert("Please click step" + currentStep);
return;
}
currentStep++;
};
}
const orderedClick = makeOrderedClick();
$first.addEventListener('click', e => {
orderedClick(0);
})
$second.addEventListener('click', e => {
orderedClick(1);
})
$third.addEventListener('click', e => {
orderedClick(2);
})
<div id="app">
<button id="first">
First
</button>
<button id="second">
Second
</button>
<button id="third">
Third
</button>
</div>

// index of the button that is supposed to be clicked
var curIdx = 0;
// get all the buttons present in the page
const $buttons = document.getElementsByTagName('button');
// iterate all the buttons
for (let idx = 0; idx < $buttons.length; idx++)
{
// add Event Listener to each button
$buttons[idx].addEventListener('click', e => {
// is the index of the button the same as the control var?
if (idx === curIdx) {
curIdx++;
console.log('correct index');
}
else
{
alert('not the correct index');
}
});
}
<div id="app">
<button id="first">
First
</button>
<button id="second">
Second
</button>
<button id="third">
Third
</button>
</div>

Related

change listener on 2nd click

I have a javascript code where I store an element in an array upon clicking on a button, and change the button from "+" to "-". Upon clicking the button again, I want to remove that element from the array.
I have this code. It does the first part well, but it also removes the element without clicking on the button the second time.
let favorites = []
let buttonList = document.querySelectorAll("button")
let click = 0
buttonList.forEach((button, index) => {
button.addEventListener('click', function saveFavourites() {
click++
favorites.push(products[index])
button.textContent = "-"
console.log(favorites)
if (click === 1) {
this.removeEventListener('click', saveFavourites)
}
})
button.addEventListener('click', function removeFavourites() {
click ++
let i = favorites.indexOf(products[index])
favorites.splice(i, 1)
button.textContent = "+"
console.log(favorites)
if (click === 2) {
this.removeEventListener('click', removeFavourites)
}
})
})
You're adding two separate event listeners to the same button element. Use a single event listener and toggle a boolean flag variable to keep track of whether the element should be added or removed.
let favorites = []
let buttonList = document.querySelectorAll("button")
buttonList.forEach((button, index) => {
let isAdded = false; // flag variable to track whether the element is added or removed
button.addEventListener('click', function toggleFavourites() {
if (isAdded) {
let i = favorites.indexOf(products[index])
favorites.splice(i, 1)
button.textContent = "+"
isAdded = false;
} else {
favorites.push(products[index])
button.textContent = "-"
isAdded = true;
}
console.log(favorites)
})
})
When the button is clicked, the code checks the value of isAdded and either adds the element to the favorites array or removes it.
Here is the Demo:- Codesandbox

How to get the values of buttons with eventListener?

I created buttons with different values in my HTML. I am trying to output these values when clicked on. I am making use of querySelectorAll and eventListeners but it keeps outputing undefined.
let buttons = document.querySelectorAll('button');
function showNumber() {
if (buttons.value != 5) {
document.getElementById('screen').innerHTML = buttons.value;
} else {
document.getElementById('screen').innerHTML = 5;
}
}
buttons.forEach(buttons => {
buttons.addEventListener("click", () => {
showNumber()
});
});
You can do it like this:
const
buttons = document.getElementsByTagName("button"),
screen = document.getElementById('screen');
Array.from(buttons).forEach(button =>
button.addEventListener("click", showNumber));
function showNumber(event) { // Listener can access its triggering event
const button = event.target; // event's `target` property is useful
if (button.value != 5) { screen.innerHTML = button.value; }
else { screen.innerHTML = 5; }
}
<button value="5">Button 1</button>
<button value="42">Button 2</button>
<p id="screen"></p>
But you might consider employing event delegation:
const
container = document.getElementById('container'),
screen = document.getElementById('screen');
container.addEventListener("click", showNumber); // events bubble up to ancestors
function showNumber(event) {
const clickedThing = event.target;
if(clickedThing.tagName == 'BUTTON'){ // makes sure this click interests us
screen.innerHTML = clickedThing.value;
}
}
<div id="container">
<button value="5">Button 1</button>
<button value="42">Button 2</button>
</div>
<p id="screen"></p>
in your foreach loop you need to pass back the button to your function
let buttons = document.querySelectorAll('button');
function showNumber(button) {
if (button.value != 6) {
document.getElementById('screen').innerHTML = button.value;
} else {
document.getElementById('screen').innerHTML = 5;
}
}
buttons.forEach(button => {
button.addEventListener("click", () => {
showNumber(button)
});
});
<button value=10>10</button>
<button value=8>8</button>
<button value=6>6</button>
<button value=4>4</button>
<button value=2>2</button>
<div id='screen'></div>
The issue is that buttons is the whole array of buttons, not just the clicked button.
To access the button that was clicked, the simplest way is to use this. Inside an event handler, this points to the element that triggered the event (i.e. the button that was clicked), as long as we bind the function showNumber directly to the event handler (and not calling showNumber() from an anonymous function like in your initial code), i.e.:
button.addEventListener("click", showNumber);
So, binding showNumber directly to the event handler and using this, this is what we can do:
let buttons = document.querySelectorAll('button');
function showNumber() {
if (buttons.value != 5) {
document.getElementById('screen').innerHTML = this.value;
} else {
document.getElementById('screen').innerHTML = 5;
}
}
buttons.forEach(button => {
button.addEventListener("click", showNumber);
});
<p id="screen"></p>
<button value="1">1</button>
<button value="10">10</button>

Removing Only Selected list item from local storage - Pure JS

I am facing a bit of trouble here. I am trying to create a to-do list with local storage but the only things I got to work are adding list item it to the local storage and deleting all items from the local storage but I can't delete a single SELECTED item out from the list. Can someone help me figure:
1) Removing a selected single item from the list.
2) Putting Checkbox before the List Text.
3) On clicking checkbox, toggle class list "strike" and remembering it on load/page refresh.
Here is my code:
<body>
<div>
<h1>To-do's list</h1>
<div>
<input type="text" id="textBox">
<button id="enterBtn" type="button">Enter</button>
<div>
<uL id="ul">
<li class="li"><input type="checkbox" class="checkBox" name=""> Buy food for Siboo <button class="deleteBtn">Delete</button></li>
<li class="li"><input type="checkbox" class="checkBox" name=""> Get a new controller <button class="deleteBtn">Delete</button></li>
</uL><br>
<button id="deleteAllBtn"><i class="fa fa-trash"></i> Delete All Items</button>
</div>
<script type="text/javascript" src="script.js"></script>
</div>
</body>
Here is CSS:
.strike {
text-decoration: line-through;
}
Here is my JS:
var textBox = document.getElementById("textBox");
var enterBtn = document.getElementById("enterBtn");
var ul = document.querySelector("ul");
var li = document.getElementsByClassName("li");
var checkBox = document.getElementsByClassName("checkBox");
var deleteBtn = document.getElementsByClassName("deleteBtn");
var deleteAllBtn = document.getElementById("deleteAllBtn");
var itemsArray = localStorage.getItem('items') ? JSON.parse(localStorage.getItem('items')) : [];
localStorage.setItem('items', JSON.stringify(itemsArray));
var data = JSON.parse(localStorage.getItem('items'));
// Functions *********************
// Adding New Items to List - adding list element with checkbox and delete button *********************
function addNewItemToList(text)
{
itemsArray.push(textBox.value);
localStorage.setItem('items', JSON.stringify(itemsArray));
liMaker(textBox.value);
}
function liMaker(text) {
var newLi = document.createElement("li");
newLi.textContent = text;
newLi.className = "li";
ul.appendChild(newLi);
var createCheckBox = document.createElement("input");
createCheckBox.type = "checkbox";
createCheckBox.className = "checkBox";
newLi.appendChild(createCheckBox);
var createDeleteButton = document.createElement("button");
var nameButtonDelete = document.createTextNode("Delete");
createDeleteButton.appendChild(nameButtonDelete);
createDeleteButton.className = "deleteBtn";
newLi.appendChild(createDeleteButton);
}
data.forEach(item => {
liMaker(item);
});
// CheckBox ELEMENT - click on checkBox to strike the list item off list*********************
function checkBoxFunction() {
for (var i = 0; i < checkBox.length; i++) {
checkBox[i].onclick = function () {
this.parentNode.classList.toggle("strike");
}}
}
// // DELETE BUTTON - click the delete button to delete the list item *********************
function deleteBtnFunction() {
for (var i = 0; i < deleteBtn.length; i++) {
deleteBtn[i].onclick = function () {
this.parentNode.parentNode.removeChild(this.parentNode);
}}
}
// DELETE ALL BUTTON - click the Delete ALl Items button to remove all items from the list *********************
function deleteAllBtnFunction()
{
localStorage.clear();
while (ul.firstChild) {
ul.removeChild(ul.firstChild);
}
itemsArray = [];
}
// TEXTBOX - press enter key to add an item to list *********************
function textBoxFunction()
{
if (event.keyCode === 13 && textBox.value.length > 0)
{
addNewItemToList();
textBox.value = "";
}
else if (event.keyCode === 13)
{
alert("Please enter an item to-do!");
}
}
// ENTER BUTTON - click the enter button to add item to list *********************
function enterBtnFunction()
{
if (textBox.value.length > 0)
{
addNewItemToList();
textBox.value = "";
}
else
{
alert("Please enter an item to-do!");
}
}
listItemFunction();
deleteBtnFunction();
// Event Listeners *********************
textBox.addEventListener("keypress", textBoxFunction);
enterBtn.addEventListener("click", enterBtnFunction);
deleteAllBtn.addEventListener("click", deleteAllBtnFunction);
// End of Event Listeners *********************
localStorage.removeItem(/*key*/);
You can use this function to remove a specific item and save the items to localstorage again:
function removeItem(text) {
var items = JSON.parse(localStorage.getItem("items"));
items = items.filter(function(e) {return e !== text; });
localStorage.setItem("items", JSON.stringify(items));
}
removeItem("itemname");
I am not a professional but recently I created a todo app like this. I figured out after adding a new item, action listeners do not count them. So I inserted the event listeners inside the new element creation function after adding the element to the DOM.
Here is my suggestion
First, you have to link jQuery-3.2.1.slim.min.js to your project
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
Put this code to the end of your liMaker function.
$('input[type="checkbox"]').click(function() {
if ($(this).is(':checked')) {
//Call your function
console.log(this.id)
}
});
When creating the list element give each of them a unique id (add it to your checkbox). Maybe you can give them the array index.
createCheckBox.id ={unique id}
After doing that when you click the checkbox to invoke the above function. In that function this.id is the unique value you gave to the checkbox.
Then you can use it to remove that index from your array.
Second Method (Pure JS)
Give a common class name to all checkboxes and a unique id also.
const checkBoxes = document.querySelectorAll(".{common_class_name}")
for(const cb of checkBoxes){
button.addEventListener('click',function(){
let id = this.id
/*this id is the value you gave to the checkbox.
Call your deleting methods here*/
})
}
Place this method at the end of your element creation method. This must run every time you add an element.
I copied your code and my method is working fine. I am a beginner there may be better ways to do that. but my method works.
Good Luck

first click, result not like I'm expect

Result not like I'm expect
var clicks = 0;
$("*").click(function(event){
if(clicks == 0){ // first click
a=parseFloat(event.pageY-pageYOffset);
++clicks;
}else{ // second clik
b=parseFloat(event.pageY-pageYOffset);
$("#lable7").text(b-a); //heppen in first click, why?
clicks=0;
}
} );
I want to count distance between first and second click, and do it many times on page.
I tried some tips but
$('*').one('click',function(){
}).click(function(){
alert("heppen in first click");
});
What I'm doing wrong?
The event is bubbling, so the handler is being executed for all the nested elements on the page. You need to disable propagation.
var clicks = 0;
var pageYOffset = 500;
$("*").click(function(event) {
if (clicks == 0) { // first click
a = parseFloat(event.pageY - pageYOffset);
++clicks;
} else { // second clik
b = parseFloat(event.pageY - pageYOffset);
$("#lable7").text(b - a); //heppen in first click, why?
clicks = 0;
}
event.stopPropagation();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Text
<div>More text</div>
</div>
<div id="lable7"></div>

Function activate after two onclicks

Hey I'm using javascript+html only.
Is there any way to activate a function after the button has been clicked two (or more) times? I want the button to do NOTHING at the first click.
For a "doubleclick", when the user quickly presses the mouse button twice (such as opening a program on the desktop), you can use the event listener dblclick in place of the click event.
https://developer.mozilla.org/en-US/docs/Web/Reference/Events/dblclick
For a quick example, have a look at the below code. http://jsfiddle.net/jzQa9/
This code just creates an event listener for the HTMLElement of "item", which is found by using getElementById.
<div id="item" style="width:15px;height:15px;background-color:black;"></div>
<script>
var item = document.getElementById('item');
item.addEventListener('dblclick',function(e) {
var target = e.target || e.srcElement;
target.style.backgroundColor = 'red';
},false);
</script>
As for wanting the user to click an element X times for it to finally perform an action, you can do the following. http://jsfiddle.net/5xbPG/
This below code works by adding a click tracker to the HTMLElement and incrementing the click count every time it's clicked. I opted to save the clicks to the HTMLElement instead of a variable, but either way is fine.
<div id="item" style="width:15px;height:15px;background-color:black;"></div>
<script>
var item = document.getElementById('item');
item.addEventListener('click',function(e) {
var target = e.target || e.srcElement;
var clicks = 0;
if(target.clicks)
clicks = target.clicks;
else
target.clicks = 0;
if(clicks >= 4) {
target.style.backgroundColor = 'red';
}
target.clicks += 1;
},false);
</script>
== UPDATE ==
Since you recently posted a comment that you want two different buttons to be clicked for an action to happen, you would want to do something like this... http://jsfiddle.net/9GJez/
The way this code works is by setting two variables (or more) to track if an element has been clicked. We change these variables when that item has been clicked. For each event listener at the end of changing the boolean values of the click state, we run the function checkClick which will make sure all buttons were clicked. If they were clicked, we then run our code. This code could be cleaned up and made to be more portable and expandable, but this should hopefully get you started.
<input type="button" id="button1">
<input type="button" id="button2">
<div id="result" style="width:15px;height:15px;background-color:black;"></div>
<script>
var result = document.getElementById('result');
var button1 = document.getElementById('button1');
var button2 = document.getElementById('button2');
var button1Clicked = false;
var button2Clicked = false;
button1.addEventListener('click',function(e) {
button1Clicked = true;
checkClick();
},false);
button2.addEventListener('click',function(e) {
button2Clicked = true;
checkClick();
},false);
function checkClick() {
if(button1Clicked && button2Clicked) {
result.style.backgroundColor = 'red';
}
}
</script>
Two ways you can do this, one would be to have a data attribute within the html button that identifies whether the click has been done.
<button id="btn">Click Me!</button>
<script>
var clickedAlready = false;
document.getElementById('btn').onclick = function() {
if (clickedAlready) {
//do something...
}
else
clickedAlready = true;
}
</script>
While global variables aren't the best way to handle it, this gives you an idea. Another option would be to store the value in a hidden input, and modify that value to identify if it's the first click or not.
Maybe something like this?
var numberTimesClicked = 0;
function clickHandler() {
if (numberTimesClicked > 0) {
// do something...
}
numberTimesClicked++;
}
document.getElementById("myBtn").addEventListener("click", clickHandler);

Categories

Resources