How to get back value present in button on mouseclick event - javascript

Currently I am getting a huge object when I'm logging x.
How to get the value from the event?
function IncrementOnClick() {
function increment(x) {
console.log(x);
}
return (
<div>
<button onClick={increment}>1</button>
</div>
);
}

It would seem you are using reactJs rather then pure JavaScript.
By calling onClick={increment} the parameter you pass to increment is an event. To get the target that you clicked on use x.target, and if you want the targets value x.target.value. for example:
const increment = ({ target }) => console.log(target.value);
return (
<div>
<button value="submit" onClick={increment}>
Manikanta
</button>
</div>
);
EDIT
Since you wish the get the inner text Manikanta rather then the actual value, use target.innerText. So in this case would be:
const increment = ({ target }) => console.log(target.innerText);
return (
<div>
<button onClick={increment}>Manikanta</button>
</div>
);

I didn't quite understand what you wanted to return but if I understood correctly this is the right code
function increment(x) {
console.log(x);
return x;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<div>
<button onClick="increment(20);">Manikanta</button>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>

I believe you are using React seeing your return statement and the curly braces JS blocks in the JSX. You can do something like the following:
import React, {useState} from "react";
function IncrementOnClick() {
// Setup the state to store the clicks
const [clicks, setClicks] = useState(0);
// You can learn more about hooks here:
// https://reactjs.org/docs/hooks-intro.html
function increment(e) {
// The argument `e` that you get to the function is the click
// event, which can be used to get a lot of information about
// the click like the coordinates of the click, button's information
// and a lot more other information.
// every time the button is clicked, you add 1 to the clicks.
setClicks((prevClicks) => prevClicks + 1);
}
return (
<div>
<button onClick={increment}>Clicks = {clicks}</button>
</div>
);
}

Related

How to run <script> when props of a component change?

Is it possible to execute a <Script/> every time the props of a react/nextjs component change?
I am converting markdown files to html using marked and, before rendering the html, I would like to have a [copy] button on each <pre> block (those are the code blocks). I have a <script/> that iterates through the <pre> blocks of the DOM document.querySelectorAll("pre") and injects the button needed. If the html changes though at a later stage, then I have found no way to re-run the script to add the copy buttons again.
I have the impression that this is not a very react/nextjs way of doing this, so any hints would be appreciated.
The Script to add the copy buttons. I have added this as the last tag of my <body>:
<Script id="copy-button">
{`
let blocks = document.querySelectorAll("pre");
blocks.forEach((block) => {
if (navigator.clipboard) {
let button = document.createElement("img");
button.src = "/images/ic_copy.svg"
button.title = "Copy"
button.id = "copy"
button.addEventListener("click", copyCode);
block.appendChild(button);
}
});
async function copyCode(event) {
const button = event.srcElement;
const pre = button.parentElement;
let code = pre.querySelector("code");
let text = code.innerText;
await navigator.clipboard.writeText(text);
button.src = "/images/ic_done.svg"
setTimeout(()=> {
button.src = "/images/ic_copy.svg"
},1000)
}
`}
</Script>
the React component. Not much to say here. The content is coming from the backend. Not sure what would be the 'React' way to do this without the script.
export default function Contents({ content }) {
return (
<div className='pl-2 pr-2 m-auto w-full lg:w-2/3 mb-40 overflow-auto break-words'>
<div className="contents" dangerouslySetInnerHTML={{ __html: content }} />
</div>
)
}
You should absolutely not do this and instead incorporate this logic into your react app, but if you must you can leverage custom window events to make logic from your html script tags happen from react.
Here is an example script:
<script>
function addEvent() {
function runLogic() {
console.log("Stuff done from react");
}
window.addEventListener("runscript", runLogic);
}
addEvent();
</script>
And calling it form react like this:
export default function App() {
const handleClick = () => {
window.dispatchEvent(new Event("runscript"));
};
return (
<div className="App" onClick={handleClick}>
<h1>Hello</h1>
</div>
);
}

Can't understand how reactivity and stores work

I'm trying to understand how reactivity should work, but I cannot figure out why some things work how they work.
Svelte REPL with the code: https://svelte.dev/repl/aa0821cd95c54708b2d12a05bf74577e?version=3.49.0
I created a simple app:
App.svelte:
<script>
import { numbers } from './store.js'
function copy() {
$numbers.copied = $numbers.selected
}
function select(i) {
console.log("Selected: " + i)
$numbers.selected = i
}
</script>
<button on:click={select(1)}>
1
</button>
<button on:click={select(2)}>
2
</button>
<button on:click={select(3)}>
3
</button>
<button on:click={copy()}>
Copy
</button>
<h1>
Selected: {$numbers.selected}
</h1>
<h1>
Copied: {$numbers.copied}
</h1>
store.js:
import { writable } from 'svelte/store'
export let numbers = writable({
selected: null,
copied: null
})
From this, I was expecting:
On launch, store values stay as null
On every button click, $store.selected changes to proper value
$store.copied updates its value only when Copy button is clicked
Instead:
On launch, select function is called 3 times, once for every button with its argument
$store.selected and $store.copied both have value 3 which cannot be changed by clicking buttons
When clicking buttons, select function is not called
Your event handlers are just wrong. You are calling the functions instead of passing them.
You need something like on:click={() => select(1)}. For copy you could also pass it as is because it has no arguments: on:click={copy}.

onSubmit handler function not working as expected, shows error for split second and disappears, in React.js

I am a beginner in React.js and I'm trying to implement a delete functionality for an app. On clicking the button, the form gets submitted and the function runs, however it shows an error in the console which is there for a split second so I couldn't read it. I have tried setTimeout to atleast see the error but it has no effect. The error just appears for a fraction of a second in the console and then disappears. The code is:
const Note = ({object}) => {
const {title, desc} = object;
const handleDel = (e, object)=>{
e.preventDefault();
console.log(object)
}
return (
<>
<div className="single-note">
<div>
<h1>{title}</h1>
<p>{desc}</p>
</div>
<form onSubmit={()=>handleDel(object)}>
<button type="submit" className="submit">
<FaRegTrashAlt/>
</button>
</form>
</div>
</>
)
}
export default Note
I guess you missed to pass the event and it is trying to invoke preventDefault on the object param that is passed. Try the below code:
onSubmt={(e) => handleDel(e,object)}

How to pass a parameter to a filter method & calling the function in React onClick event with different params?

I have created a filter() method that returns an new array if certain condition is met.
Function to filter array:
filterTableData = () => {
const userPackages: any = this.props.lenders.packages;
const userPackageFiltered = userPackages.filter((userPackage) => {
return userPackage.businessStatus.toLowerCase() === this.state.btnValue;
});
console.log(userPackageFiltered);
}
Then, I'm using onClick React event handler to trigger the function
like so:
<button
value={this.state.btnValue}
onClick={this.filterTableData}
>
Invited
</button>
It works perfectly!
Now, I want to reuse this logic & attach it to different buttons. So, I am trying to pass parameters to my filterTableData() function like so:
filterTableData = (parameters) => {
const userPackages = this.props.lenders.packages;
const userPackageFiltered = userPackages.filter((parameters) => {
return parameters.toLowerCase() === this.state.btnValue;
});
console.log(userPackageFiltered);
}
Then, I tried to call it like so:
<button
value={this.state.btnValue}
onClick={this.filterTableData(userPackage.businessStatus)}
>
Invited
</button>
<button
value={this.state.btnValue2}
onClick={this.filterTableData(userPackage.type)}
>
Draft
</button>
Obviously, this isn't working.
Here it is a sample code. I want to pass the filter value into a parameter to reuse this code in other buttons & filter the array with different criteria.
The behavior is similar to this code sample, make sure to check the "View Column" icon & the behavior of the checkboxes.
If the aim is to filter based on the truthiness of a particular field in your data, whose name is held in the component as this.state.buttonValue, then you can achieve the desired effect by writing your filter method like this:
filterTableData(param) {
const filteredData = this.state.data.filter(user => user[param]);
// code to use filterdData, presumably using this.setState somewhere
}
And then define your onClick attribute as follows:
onClick={() => this.filterTableData(this.state.buttonValue)}
It's likely though that you don't just want to use the truthiness/falsiness of the values (they will likely only be falsy if they're not actually provided) - you might want an "age" filter to only select users aged over 18, for example. It's not clear what your exact needs are - but the above code should serve as a good outline, the only change will be in filterTableData where you may have to use a switch on the param argument and define a custom filter function for each, which you then pass in to this.state.data.filter. Hopefully you can work out from this what exactly you need to do for your situation.
If I am understanding this correctly, you want to supply a custom parameter along with the onClick event. To do this, you will need to use an anonymous function.
You can either use the anonymous function inline, within the onClick prop (FirstTest), or you can use it on the handler (SecondTest).
Please see the following example, and let me know if this is what you're looking for.
const mybuttons = [{
name: "Invited",
value: "__some__INVITED__value__"
}, {
name: "Draft",
value: "__some__DRAFT__value__"
}]
function FormTest() {
const handleClick = parameter => event => {
switch(parameter.name){
case "Invited": {
alert("You clicked: INVITED! Value of: " + parameter.value);
break;
}
case "Draft": {
alert("You clicked: DRAFT! Value of: " + parameter.value);
break;
}
default:
break;
}
}
return(
<div>
{mybuttons.map(button => {
return <button onClick={handleClick(button)}>{button.name}</button>
})}
</div>
);
}
/**
* FIRST TEST
*/
function FirstTest() {
const handleClick = parameter => {
alert(parameter);
}
return(
<div>
<button onClick={() => handleClick("[FirstTest] My Custom Parameter 1!")}>
First Test
</button>
</div>
);
}
/**
* SECOND TEST
*/
function SecondTest() {
const handleClick = parameter => clickevent => {
alert(parameter);
}
return(
<div>
<button onClick={handleClick("[SecondTest] My Custom Parameter 2!")}>
Second Test
</button>
</div>
);
}
function App(){
return(
<div>
<FormTest />
<hr />
<br />
<p>Original Answer:</p>
<FirstTest />
<SecondTest />
</div>
);
}
ReactDOM.render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>

Why doesnt my code for my calculator work?

I have some uncompleted code that's suposed to return a number for what ever button I click but instead it does nothing and the console doesnt throw an error so that i cant see what i did.
Ive done some spell checking and my code comes mainly form a youtube video.
const minus = document.querySelector('[data-delete]');
const current = document.querySelector('[data-input]');
const allClear = document.querySelector('[data-all-clear]');
const numberButtons = document.querySelectorAll('[data-number]')
const operation = document.querySelectorAll('[data-operation]')
const equals =document.querySelector('[data-equals]')
class Calc {
constructor(inputText){
this.inputText = current
this.clear()
}
clear(){
this.input=''
this.operation=undefined
}
delete(){
}
writeNumber(num){
this.input = num
}
operation(sign){
}
compute(){
}
updateDisplay(){
this.input.innerText = this.operation
}
}
const calculator = new Calc(current);
numberButtons.forEach(number=>{
equals.onClick('click',()=>{
calculator.appendNumber(equals.innerText)
calculator.updateDisplay()
})
})
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Calculator</title>
<link href="calc.css" rel="stylesheet">
<script src="calc.js"></script>
</head>
<body>
<div class="container-grid">
<div data-input class="input">3</div>
<button data-all-clear class="span-two">AC</button>
<button data-delete>DEL</button>
<button data-operation>/</button>
<button data-number>1</button>
<button data-number>2</button>
<button data-number>3</button>
<button data-operation>*</button>
<button data-number>4</button>
<button data-number>5</button>
<button data-number>6</button>
<button data-operation>+</button>
<button data-number>7</button>
<button data-number>8</button>
<button data-number>9</button>
<button data-operation>-</button>
<button data-number>.</button>
<button data-number>0</button>
<button data-equals class = "span-two">=</button>
</div>
<script src="calc.js"></script>
</body>
</html>
I just want the buttons to display numbers
I am able to run your code after doing the below change,
wrap everything inside one method,
you are having an issue with the below click event,
Incorrect one,
equals.onClick('click',()=>{
calculator.appendNumber(equals.innerText)
calculator.updateDisplay()
})
If you dont want jQuery use javascript click event bind()
equals.addEventListener("click",()=>{
calculator.writeNumber(equals.innerText)
calculator.updateDisplay()
})
Refer the below updated your function
function Calci() {
let minus = document.querySelector('[data-delete]');
let current = document.querySelector('[data-input]');
let allClear = document.querySelector('[data-all-clear]');
let numberButtons = document.querySelectorAll('[data-number]')
let operation = document.querySelectorAll('[data-operation]')
let equals =document.querySelector('[data-equals]')
class Calc {
letructor(inputText){
this.inputText = current
this.clear()
}
clear(){
this.input=''
this.operation=undefined
}
delete(){ }
writeNumber(num){
this.input = num
}
operation(sign){
}
compute(){ }
updateDisplay(){
this.input.innerText = this.operation
}
}
let calculator = new Calc(current);
numberButtons.forEach(number=>{
equals.addEventListener("click",()=>{
calculator.writeNumber(equals.innerText)
calculator.updateDisplay()
})
})
}
Calci(); //call the method
JS Fiddle Answer : https://jsfiddle.net/xa14fbc0/
So I'm not quite sure what you're trying to achieve here but I'll point out a few things that might help.
Are you trying to make your element with data-equals show the number button you click on?
your function
numberButtons.forEach(number=>{
equals.onClick('click',()=>{
calculator.appendNumber(equals.innerHTML)
})
})
needs some work, you wouldn't use use onClick('click'... instead you would use addEventListener('click'... to attach a handler (using .click to attach an on click handler is jQuery and you do not have jQuery setup in your code - might be something to look at). Furthermore, you are attaching the on click to the equals element each time over and over again, not to your buttons. For that you would do number.addEventListener('click'... to attach a click handler to each of your buttons so an action takes place each time you click. You also are calling a method calculator.appendNumber but your calculator class doesn't have an appendNumber method in it.
What you are looking for is something along the lines of :
numberButtons.forEach(number=>{
number.addEventListener('click',()=>{
calculator.appendNumber(number.innerText)
calculator.updateDisplay()
})
})
you also want to add an appendNumber method to your Calc class or call a method that is available in your Calc class
You are also instantiating calculator with current which is a dom element, but your Calc class constructor is looking for inputText so what you want there is something like :
const calculator = new Calc(current.value)
in order to pass in the value of your input - keep in mind that constructors get instantiated with the value at the time of instantiation and will not change as you change your input value - you'd need to attach an on change handler to your input in order for your class instance to make a change when that input value changes
I've made a JS fiddle that changes the input to a number you click to get you started, based on your code : https://jsfiddle.net/xa14fbc0/

Categories