How to add disabled attribute via prop to a button in react? - javascript

I am creating a custom button component in react. I want to pass a prop to that button, based on the value of which button gets enabled or disabled.
My problem is
- The mere presence of the disabled property disables the element, so I cannot set its value as "false". Even the following code is disabling the element
<input type="button" id="myBtn" value="Submit" disabled="" />
I need to either remove the attribute completely or set its property via javascript.
document.getElementById("myBtn").disabled = true;
My custom button component is -
import React from 'react';
const CustomButton = ({ whenClicked, classNames, buttonText, isDisabled }) =>
(
<button
onClick = {whenClicked}
className = {`btn ${classNames}`}
type = "button"
disabled = {isDisabled}
>
{buttonText}
</button>
);
export default CustomButton;
isDisabled is a boolean value.
One more thing, I lost the default submit behavior of button while using custom button. Now I always need to pass a click handler. Is there any way to achieve the same behavior again?

What you currently have should work perfectly fine. Be careful that when you use CustomButton you don't send in the value for disabled as a string. That will make it disabled regardless of what you pass in. Instead, you need to pass in a boolean, that's in JSX syntax.
Here's a sample usage where you would put it inside of a render function of a component that uses the button:
...
render() {
<div>
...
<CustomButton
whenClicked={() => console.log('I just got clicked')}
buttonText="Some Button"
isDisabled={false}
/>
...
</div>
}
...
Basically, instead of false you could pass in something else. You could pass in a boolean value that's stored on the props of the container that holds the CustomButton.
You could say isDisabled={this.props.disableInnerButton} and it would work as you would expect. Changing the value of the boolean will disable or enable the button.
Below you can find a relevant answer I gave recently on a very similar topic:
Statement to add or not an attribute in JSX

At first it looks quite complicated to handle but, if we look at the problem I think we can achive it using css only by adding a class(selector) to the element
.disabled { pointer-events: none;}
or conditionally styling:
<button style={{pointerEvents: notValid ? "none" : "initial"}}> Submit </button>

Related

How remove React visible checkmark after form reset?

I'm working on a React app with a button to reset a form. When the user clicks the "Reset" button, all the states revert to their original values. But a checkmark remains selected even after all the other data clears. It does appear to reset the state, but the checkmark is still visible and confusing to the user. I understand that defaultChecked is read on the initial load, but the checkmark remains even if I remove defaultChecked completely, so I'm not sure where the problem is. I suspect the solution might involve onChange, but I haven't been able to get that to work. Any help appreciated.
const [checked, setChecked] = useState(false);
const clearSearch = () => {
setResults([]);
setQuery("");
setFormat("");
setChecked(false);
}
<label>
<input
type="checkbox"
id="searchAll"
defaultChecked={checked}
onChange={() => setChecked(!checked)}
/>
Search all formats
</label>
<button className="btn btn-danger"
onClick={event => {
event.preventDefault();
clearSearch();
}}>
Reset
</button>
App.js on GitHub https://github.com/irene-rojas/loc/blob/master/src/App.js
Your checkbox is actually an uncontrolled input, which probably isn't what you want (it usually isn't in React). That is because, although you've got the onChange event wired up to a handler which sets state, you're not reading back from that state into the input. Except in the defaultChecked attribute - which doesn't control whether it's actually checked or not.
You need to use the checked attribute, which for a checkbox is essentially equivalent to the value attribute of a text or numeric input:
<input
type="checkbox"
id="searchAll"
checked={checked}
onChange={() => setChecked(!checked)}
/>
(I've removed your defaultChecked attribute, as I don't think you want it - but feel free to put it back in if you do. The important thing is having a checked attribute that reads from the checked state value.)

ReactJS - How does one delete a button component, that was just clicked?

My aim is to delete the button, I have just clicked. I understand there may be numerous ways such as creating a deleteButton component, and setting the state appropriately.
However, my return function in the main App component will also render another button (this I can do), but I think this may add to the complexity.
I'm currently struggling to pin-point the ideal solution, so please help.
Okay, so I've managed to solve my question, although I'm sure there's other ways too.
To further clarify...
I had a form which I wished to render, when clicking on a 'Create' Button.
At the same time, I wished to remove the 'Create' button, once clicked.
The end result is to only display the form and nest a new button in the return function.
1) Set the initial state of the form to false:
this.state = {
displayForm: false,
}
2) Then use setState within the displayForm function to allow for the change in state, once the button is clicked:
displayForm(){
this.setState({
displayForm: !this.state.displayForm {/* true */}
})
}
3) set a style object within the render function, such as:
render() {
const btnStyle = {
display: 'block',
} ...
4) Use an IF statement to change the display style of the button if the form has been rendered
if(this.state.displayForm){
btnStyle.display = 'none'
}
5) Now, within the return function, use your JSX tags appropriately and call the function onClick, as well as the style to be applied.
<Button
style={btnStyle}
onClick={() => {
this.displayForm()
}}>Create</button>
{this.state.displayForm && ([
<Form />,
<br />,
<Button>Add Schema</Button>,
])}
NOTE: the < Form /> and < Button /> components have been imported and added here.
So, once the 'Create' button has been clicked, the form displays (true), and thereby the 'Create' button disappears from the Virtual DOM. I've also nested another (new) button as intended, underneath the form.

Check for a value onClick react

In my render method i render some cards that all have button and when i click on the button i want to disabled them.
Those buttons are checking if the value of the array is true and if it is it's disabling the button but this is only working when i refresh the page and i want the button to be disabled directly on click
Here is my try
//this is checking from my database if it include the id of the pokemon that i want to get
const check = pokemon.id
const newPoke = getPokemon.includes(check);
// Here is the button that is getting disabled only if newPoke return true
<Button isDisabled={newPoke}/>
Everything work correctly when i refresh the page the buttons that i clicked previously get disabled but not onClick directly.
I think after i click i have to re-check for newPoke but i'm not sure how to include it in the button
You are using props to pass variable from parent to children(Button).
reactjs documentation states react props are read-only
If you are planing to change the values of newPoke then you should rethink your structure and maybe its best to use states in your example
For example here
<Button isDisabled="newPoke"></Button will only be checked at initialization stage since its a react prop. but if you used state which gets updated with every new action you can have a true one-way binding and your ui would reflect data changes quickly
store the newPoke in state and change it's value when the button is clicked. and use that value in button isDisabled prop. try something like this
state={
isDisabled: false;
}
handleClick=(isDisabled)=>{
this.setState({isDisabled});
}
//this is checking from my database if it include the id of the pokemon that i want to get
const check = pokemon.id
const newPoke = getPokemon.includes(check);
// Here is the button that is getting disabled only if newPoke return true
return(
<Button isDisabled={this.state.isDisabled} onClick={()=>this.handleClick(newPoke )}/>
);
i think if you want get value from database you can use componentDidMount().
and your value you can save while in state. and then in function handleClick you can change this state
for example :
handleClick = () => {
const value = this.state.valueFromDataBase
this setState({valueFromDataBase: false})
}
and in render you declare this value state
render(){
return(
<Button defaultValue={this.state.valueFromDataBase} onCLick={this.handleClick} />
)
}
please correct my answer if I am wrong in responding to your question

React/Next.js how to get other Element event target value on button click

I have an input element and a button in React:
<li><input type="text" placeholder="Enter new ID"></input>
<button onClick={(e)=>this.saveKonfigElementHandler()}>Save</button></li>
Now, when I enter some value into the input field, I want to save the value into some array when I click on the button.
Is it somehow possible to get a reference to that input field (e.g. the target.value of the input field) to save it when clicking the button?
Or would I simply have to do it with an onChange event that saves the current input value into some Variable, and when I click the button, I will simply retrieve that value to save it into some array? Maybe that would be a lot simpler.
E.g:
<input type="text" value={this.state.inputFieldText.join('')} onChange={(event) => this.textHandler(event)}></input>
in the textHandler Method, I will save the target value from the input field into a Class Component state variable in the textHandler() method. And when I click the button, I retrieve that state value and can do some manipulation with it?
A modern way to do it, with function components, hooks and a controlled form element, is:
import { useState } from 'react'
function MyComponent({ initialId, onSave }) {
const [newId, setNewId] = useState(initialId)
return (
<li>
<input
type="text"
placeholder="Enter new ID"
onChange={(e) => setNewId(e.target.value)}
/>
<button onClick={() => onSave(newId)}>Save</button>
</li>
)
}
I'd also note that it is considered better accessibility practice to use a label element for describing the purpose of your field, rather than a placeholder. Placeholders are more appropriate for example input.
Is it somehow possible to get a reference to that input field (e.g. the target.value of the input field) to save it when clicking the button?
Yes.
Or would I simply have to do it with an onChange event that saves the current input value into some Variable, and when I click the button, I will simply retrieve that value to save it into some array? Maybe that would be a lot simpler.
That would be a slightly more React way to do it.
Your DOM-only approach is more "uncontrolled" (see these docs for what controlled/uncontrolled means). You'd do it like this:
Change your onClick to pass e to the handler:
onClick={(e)=>this.saveKonfigElementHandler(e)}
In saveKonfigElementHandler, use e.target.previousElementSibling to access the input:
saveKonfigElementHandler(e) {
const { value } = e.target.previousElementSibling;
// Use `value` ...
}
That's fragile, of course; if you change your structure so another element is between the button and the input, or the input is within a container element, etc., it'll break — which is one argument for the controlled approach. You could store a link to the input in a data attribute on the button:
<li><input id="id-input" type="text" placeholder="Enter new ID"/>
<button data-input="#id-input" onClick={(e)=>this.saveKonfigElementHandler(e)}>Save</button></li>
and then use querySelector to get it:
saveKonfigElementHandler(e) {
const { value } = document.querySelector(e.target.getAttribute("data-input"));
// Use `value` ...
}
but the you're having to keep selectors unique, etc.
Which you choose, controlled or uncontrolled, is ultimately up to you.
I'm not sure about your question. Do you want something like this ?
<button data-input="#id-input" onClick={this.saveKonfigElementHandler(value)}>Save</button></li>
saveKonfigElementHandler = (value) => (event) => {}

Can´t access button value using material-ui

I have to access the value of a button, because it holds the ID which is needed for further progress.
I first used a normal button with some bootstrap styles and everything worked fine.
<button
value={row.vacationRequestID}
className="btn btn-warning"
onClick={myRef.handleDeclineClick.bind(myRef)}>No
</button>
handleDeclineClick(e, value) {
console.log("decline");
console.log(e.target.value) //ID: 120
// this.props.declineClick(e);
//dispatch(requestStatusUpdate(e.target.value, declined, reason))
}
Now after using the material-ui, I can´t access the value anymore.
<IconButton
iconClassName="material-icons"
tooltip="Ablehnen"
value={row.vacationRequestID}
ref={"dd"}
onClick={myRef.handleDeclineClick.bind(myRef)}
>
thumb_down
</IconButton>
I have tried to access it via ref, but not even this is working anymore. Can someone explain me why? The Documentation doesn´t say anything about value.
Use currentTarget instead of target
handleDeclineClick(e, value) {
console.log("decline");
console.log(e.currentTarget.value);
}
Original Answer
MaterialUI doesn't use any value prop. So when you set the value prop to the IconButton, it means essentially nothing.
If you'd want to pass any value to the onClick call back function, bind the value to the function. So when it is called, you'll get it as the first argument.
myRef.handleDeclineClick.bind(myRef, row.vacationRequestID)

Categories