how to identify which button clicked in react? - javascript

I have two buttons that execute the same function, and that function needs to evaluate go backward or go forward as I show in the following image
and in the following code I want to evaluate what function next() or prev() to execute depending on which button was touched, this is built in react
const onFinish = (values) => {
if (values.users) {
const Operator = values.users.map((item) => ({
ruleAttributeName: item.ruleAttributeName,
isoAttributeId: item.isoAttributeId,
ruleOperationId: item.ruleOperationId,
mandatoryValue: item.mandatoryValue,
}));
setAttributes(Operator);
}
if (values.users) {
const attributesSave = values.users.map((item) => ({
ruleAttributeName: item.ruleAttributeName,
isoAttributeEntity: {
isoAttributeId: item.isoAttributeId,
},
ruleOperationEntity: {
ruleOperationId: item.ruleOperationId,
},
mandatoryValue: item.mandatoryValue,
}));
console.log('mandatory';
setAttributesSave(attributesSave);
setMandatoryValue();
next();
prev();
};
and in this form I pass by parameter the function
<Form
name='dynamic_form_nest_item'
onFinish={onFinish}
autoComplete='off'
>

You can identify them by assigning unique Id to both button like this
<button onClick={onFinish} Id={'1'}>Next</button>
<button onClick={onFinish} Id={'2'}>Next</button>
And in you listener check id which button clicked.
const onFinish = (event) => {
Let id = event.target.id;
if(id=== "1") {
// Do for one
} else {
// For second
}
}

I don't know the parameters that you got on that custom buttons and how is it triggering onClick event. But here is the solution for HTML buttons.
You can set a value to the button like this.
<button onClick={onFinish} value="next">Next</button>
const onFinish = (ev) => {
ev.preventDefault() // this is to prevent the refresh
const { value } = ev.target // equals with const value = ev.target.value
if(value === "next") {
next()
} else {
prev()
}
}

Related

State updating for onkeyup, but not for onclick in React

I am working on an app that uses both onkeyup and onclick events. onkeyup is working as expected, however, onclick is not working as expected. See the code below...
//the state
const [currentGuess, setCurrentGuess] = useState("");
//the callback function
const handleKeyup = (e) => {
let pressedKey = "";
if (typeof e == "string") {
pressedKey = e;
}
const checkPressedKey = pressedKey ? pressedKey : e.key;
setCurrentGuess((prev) => prev + checkPressedKey);
console.log(currentGuess.length);
}
//triggering callback when user types on keyboard
useEffect(() => {
window.addEventListener("keyup", handleKeyup);
return () => window.removeEventListener("keyup", handleKeyup);
}, [handleKeyup]);
//trigger the callback when user types in the fake keyboard
useEffect(() => {
setKeyOnClick();
}, []);
function setKeyOnClick() {
const allkey = document.querySelectorAll(".key");
allkey.forEach((btnKey) => {
btnKey.addEventListener("click", function () {
handleKeyup(btnKey.dataset.key);
});
});
}
***for onKeyup**
output: 0, 1, 2, 3, 4 ....
***for onclick**
output: 0 (it doesn't increase);
-HTML-
<button className="key" data-key="Q">Q</button>
<button className="key" data-key="W">W</button>
<button className="key" data-key="E">E</button>
<button className="key" data-key="R">R</button>
<button className="key" data-key="T">T</button>
<button className="key" data-key="Y">Y</button>
As you can see above i have to pass the dataset-key in the handlekeyup function for onclick event.
Your buttons have className="key", so if you want to get elements by class name you have to use a dot in querySelectorAll, try this:
const allkey = document.querySelectorAll(".key");

Enter key for Route another page

I have a input for searchbox. I must make like; Write my words fors search then after i press enter it must need go another page with input value. So i can access that value with query string. So how can i route another page with value of input after i press enter ? Thank you for help! I Just add That codes for catch enter press.
useEffect(() => {
const listener = (event) => {
if (event.code === "Enter" || event.code === "NumpadEnter") {
alert("Enter key was pressed. Run your function.");
event.preventDefault();
}
};
document.addEventListener("keydown", listener);
return () => {
document.removeEventListener("keydown", listener);
};
}, []);
You don't necessarily have to set an event listener, using onKeyDown event handler will also do. Enter key has a code of 13, so we just have to detect that.
Keep your value in a state (here, myValue), detect that you've pressed Enter key (here, using keyPressHandler method), and finally, pass the parameter to your route.
import {useHistory} from "react-router-dom"
function App() {
let history = useHistory();
const [myValue, setMyValue] = useState("");
const handleChange = ({ target: { value } }) => {
setMyValue(value);
};
const keyPressHandler = (e) => {
if (e.which === 13) {
// alert("You pressed enter!");
history.push("/process/" + myValue);
}
};
return (
<div className="App">
<input value={myValue} onKeyDown={keyPressHandler} onChange={handleChange} />
</div>
);
}
UPDATE:
According to MDN Web Docs, e.which is non-standard [Source] and e.keyCode is deprecated [Source], so you should be using e.key instead like:
const keyPressHandler = (e) => {
if (e.key=== 'Enter') {
// alert("You pressed enter!");
history.push("/process/" + myValue);
}
};
Working CodeSandbox Link

JavaScript function cannot recognise input.checked elment correctly

I have a problem with my "CheckCheck" function. The following part of the code should generate a to-do task. The input tag dynamically created in JS provides an option to set the priority to the given task. There is an option to set the task to "normal" or "priotity". However, the code sets the fisk task to "on" and after continues with the imposed "priority" and "normal" but inversely. How to prevent this from happening?
The code:
let tasklist = [];
function Apply() {
const Tasktask = document.querySelector(".task-form");
const Taskdate = document.querySelector(".date");
const Taskpriority = document.querySelector(".check-box");
function Prevent() {
if (Tasktask.value.length === 0 || Taskdate.value === "") {
alert("Fields cannot be empty!");
} else {
Pushed();
render();
clear();
}
}
Prevent();
function Pushed() {
let newTasks = new Tasks(Tasktask.value, Taskdate.value, Taskpriority.value);
tasklist.push(newTasks);
updateLocalStorage();
}
function render() {
CheckCheck();
insertTd();
}
function CheckCheck() {
if (Taskpriority.checked === true) {
Taskpriority.value = "priority"
} else {
Taskpriority.value = "normal"
}
}
function clear() {
Tasktask.value = "";
Taskdate.value = "";
Taskpriority.checked = false;
}
function insertTd() {
checkLocalStorage();
const parent2 = document.querySelector(".table-body");
parent2.innerHTML = "";
tasklist.forEach((item) => {
const table = `<tr>
<td>${item.task}</td>
<td>${item.date}</td>
<td>${item.priority}</td>
<td><a class="delete">delete</a></td>
</tr>`;
parent2.insertAdjacentHTML("afterbegin", table);
});
}
function deleteItem() {
const Table = document.querySelector("table").addEventListener("click", (e) => {
const currentTarget = e.target.parentNode.parentNode.childNodes[1];
if (e.target.innerHTML == "delete") {
if (confirm(`Are you sure you want to delete ${currentTarget.innerText}?`))
deleteTask(findTask(tasklist, currentTarget.innerText));
}
if (e.target.classList.contains("status-button")) {
findTask(tasklist, currentTarget.innerText);
}
updateLocalStorage();
insertTd();
});
}
deleteItem();
function deleteTask(currentTask) {
tasklist.splice(currentTask, currentTask + 1);
}
function findTask(taskArray, task) {
if (taskArray.length === 0 || taskArray === null) {
return;
}
for (let item of taskArray)
if (item.task === task) {
return taskArray.indexOf(item);
}
}
}
The other thing which is not working as intended is the confirm prompt. The more tasks I add, the more confirm prompts I get. I.e. for 1 task it is only one confirm window, for 3 tasks - 3 windows etc. Why is that?
I also attach below a JSFiddle link how better understanding.
Link
Thanks in advance for answers.
You don't get the state of a checkbox by reading its value but its checked property. Try document.querySelector('.check-box').checked
You keep reusing the same buttons and add an event listener to them each time. Either clone them every time, or add the listener once right after creating them.
Simple illustration of the problems here
document.querySelector('#readstates').addEventListener('click', e => {
e.preventDefault();
const disp = `Checked\n 1: ${chk1.checked}, 2: ${chk2.checked} \n`
+ `Value\n 1: ${chk1.value}, 2: ${chk2.value}`;
alert(disp);
});
const spawnBut = document.createElement('button');
spawnBut.id = 'spawned';
spawnBut.textContent = 'Spawned';
document.querySelector('#spawnDirty').addEventListener('click', e => {
const previous = document.querySelector('form #spawned');
if (previous) previous.remove();
document.querySelector('#spawnHere').append(spawnBut);
spawnBut.addEventListener('click', e => {
e.preventDefault();
alert('click!');
});
});
document.querySelector('#spawnClone').addEventListener('click', e => {
const previous = document.querySelector('form #spawned');
if (previous) previous.remove();
const nSpawnBut = spawnBut.cloneNode(true);
document.querySelector('#spawnHere').append(nSpawnBut);
nSpawnBut.addEventListener('click', e => {
e.preventDefault();
alert('click!');
});
});
<form>
<p class="inputs">
<label for="chk1">chk1:</label> <input type="checkbox" id="chk1" />
<label for="chk2">chk2:</label> <input type="checkbox" id="chk2" value="mycheckedvalue" />
<button id="readstates">Read chks</button>
</p>
<p class="button-spawners">
Try spamming those then click below:
<button type="button" id="spawnDirty"
title="Each time you click this one, the button below is respawned and a new handler is attached">
Spawn button
</button>
<button type="button" id="spawnClone"
title="This one will spawn a clone each time, so the click handler is attached only once">
Spawn button clone
</button>
</p>
<p id="spawnHere">
New button will spawn here
</p>
</form>

How to return the value of outer function when button inside inner function is clicked?

I have two buttons with the text ok and cancel.
<div class="buttons-div">
<button class='cancel'>Cancel</button>
<button class='ok'>Ok</button>
</div>
My functions are the following:
function outerFunc() {
function innerFunc() {
const btns = document.querySelectorAll('.buttons-div')
btns.forEach(btn => {
btn.onclick = (e) => {
if(e.target.classList.contains('cancel')) {
return false;
} else {
return true;
}
}
}
)
}
return innerFunc()
}
const myBoolean = outerFunc()
I want to return a true or false value in outerFunc() when one of the two buttons is clicked.
I am guessing here that you want to perform some action once either button is clicked, according to whether or not the OK/Cancel button was clicked. Would something like the following help you?
https://jsfiddle.net/8sy2mh4z/
function buttonClick(okClicked) {
console.log(okClicked);
// TODO - implement logic based on button click
}
function initButtons() {
document.querySelectorAll('.buttons-div').forEach(btn => {
btn.onclick = (e) => {
if(e.target.classList.contains('cancel')) {
buttonClick(false);
} else {
buttonClick(true);
}
}
});
}
initButtons();
In your outerfunc, add an event listener that monitors for the button's click.

Prevent text and value from changing when clicked twice

I am trying to prevent the text and value changing when clicked multiple times. i have looked at similar questions and tried out their answers but nothing has worked.
Here is my code:
const updateSuccess = (event) => {
if (playerXTurn === true) {
$('#cell0').val('X')
$('#cell0').text('X')
} else {
playerXTurn === false
$('#cell0').val('O')
$('#cell0').text('O')
}
playerXTurn = !playerXTurn
getGames.game.cells[0] = $('#cell0').val()
event.stopPropagation(updateSuccess)
}
I also have this code before it
const onUpdateGame = function (event) {
event.preventDefault()
const data = getGames
api.updateGame(data)
.then(gameUi.updateSuccess)
.catch(ui.fail)
}

Categories