I have a react project, a recipe box, which includes the ability to open a recipe and add/delete ingredients. Here is a fiddle. You can click the recipe name to open the recipe. There is an edit button which reveals the delete button and gives the option to change the name of the ingredients. When the 'delete ingredient' button is pressed, the last ingredient appears to always be deleted, regardless of which ingredient is selected, but when the 'done' button is clicked and the editable input boxes change back to text, the correct change is shown, the proper ingredient deleted and the last ingredient remains. Though this works functionally, it's obviously not very UI friendly, and I wondered why this was happening. Any help would be great.
jsFiddle
class Input extends React.Component {
render() {
const array = this.props.update;
let booleanButton = null;
if (this.props.ingr) {
////////////////////////////
// here is the button's JSX
booleanButton = <button onClick=
{this.props.handleDeleteIngredient.bind(this, array)}>delete
ingredient</button>;
///////////////////////////
}
return (<div><form><input type="text" defaultValue={this.props.text}
onChange={this.props.onChange.bind(this, array)} /></form>{booleanButton}
</div>)
}
}
And the handler:
handleDeleteIngredient(data, e ) {
var key = data[2];
var ingrs = this.state.ingrs;
ingrs.splice(key, 1);
this.setState({ingrs:ingrs});
}
Your description is quiet confusing, and according the your fiddle code I think your problem is caused by not setting a good key for your list Item.
from what it looks in this line, you don't have a key={ingrs[i]} props, try set it to id see it will work, but making ingrediant name as key is probably not a good idea, try to give an actual id.
ingrList.push(<Input key={ingrs[i]} handleDeleteIngredient={this.handleDeleteIngredient.bind(this)} id={id} update={[this.props.objectIndex, "ingrs", i]} onChange={this.onInputChangeIng.bind(this)} text={ingrs[i]} />);
Related
I need help about changing the button style in Discord.JS. interaction.component.setStyle("DANGER") works, but for multi-buttons inside an Action Row doesn't work. I tried <row>.components, it shows an array of MessageButton. I can also <row>.components[0].setStyle("DANGER") but it can't do the clicked one. Can you please help? Thank you!
Using interaction.message.components[0] would return the first MessageActionRow.
Take a look at the image that I've linked below to see the numbers that I've been talking about.
In order to edit button 5, you would have to get the 2nd button of the 2nd row.
This would be interaction.components[1].components[1]. You can then edit stuff like the style, label, etc. by running the usual .setLabel("Something") function.
Don't forget to reply to the interaction.
In your case you would have to update the original interaction-message.
A possible way to insert this would be:
const { Client } = require("discord.js")
const client = new Client(/*Your intents*/)
//Your code to create the buttons, etc.
client.on("interactionCreate", interaction=>{
if(interaction.isButton()){
if(interaction.customId=="your custom button id"){
//Remember to start counting with 0. 0 in the code equals 1 in real life...
interaction.message.components[1].interaction[1].setStyle("DANGER")
interaction.update({
components: interaction.components
})
}
}
})
client.login("your token")
Buttons with the numbers I talked about.
Can't solve a problem. Could someone help me?
I'm building a form and have an autocomplete box. The problem is that if I click somewhere on a page (except for the suggestion item) it doesn't hide. Where should I add setIsAutoCompelte(false) so that it hides?
State
// if true then show the box
const [isAutoComplete, setIsAutoCompelte] = useState(false);
onHandleChangeInput (if input.length > 3)
// show the box
setIsAutoCompelte(true);
onSuggestionClick (if I click on item in autocoplete box)
// hide the box
setIsAutoCompelte(false);
I do not provide full code because it's too big and I'm sure nobody would take a look at it.
You could have an onClick on App that changes the state if the clicked target didn't have the className of the input. You'd need to apply a className such as "autoCompleteBox" to every element/component where you want isAutoComplete to be true.
const clickAnyWhereBut = (e, className) => {
if (!e.current.target.classList.contains(className)) {
setIsAutoCompelte(false); /* you have a typo for "complete/compelte" */
}
}
<div className="App" onClick={() => clickAnyWhereBut("autoCompleteBox")}></div>
This is a lot easier if you're using redux because you wouldn't need to pass down the setIsAutoCompelte[sic] state.
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.
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
Please take a look at my code for Dropdown,
I'm using the semantic ui react dropdown on an EditProfile component. I have pasted a sample code here, https://codesandbox.io/s/m4288nx4z8, but I could not get it to work because I'm not very familiar with functional components in React, I've always used Class component. But you can check the full code for the whole component below in the github gist.
https://gist.github.com/mayordwells/b0cbb7b63af85269091f1f98296fd9bb
Please, I need help on inserting values from multiple select options of a Dropdown into the Database and also a way to display that back upon viewing the profile edit page again.
I'm using semantic-ui-react in react + rails app.
Also when I insert a value using a normal drop down without multiple select, the value gets persisted into the database.
<Dropdown
placeholder='Select Country'
fluid
search
selection
options={countryOptions}
name='country'
defaultValue={this.state.extraInfo.country}
onChange={(e) => this.handleExtraInfoChange('country', e)}
/>
This code handles change for the dropdown elements.
handleExtraInfoChange = (name, event) => {
let value;
if (event.target.value !== undefined) {
value = event.target.value;
} else {
value = event.target.textContent;
}
let newExtraInfo = Object.assign(this.state.extraInfo, { [name]: value })
this.setState({ extraInfo: newExtraInfo});
}
But when I visit the page again, I get a white blank in the input box. Here's a screen pic for that. When I comment out the defaultValue or value property(i have tried with defaultValue and value), the white blank disappears, but the value picked by a user is also not seen.
Please advice what is a possible solution to this misbehavior? And what is the best way to insert multiple values into the Database?
Thanks in advance for your time.
A functional component does not have state, it's used for composition; you want to store state, so you either have to create a Component class or you need an external state container like redux.