Semantic TextArea not editable with initial text - reactjs

React Semantic - TextArea
I have initial value
which is showing in the textArea but its not editable anymore.
Any solution?
codepen example:
[1]: https://codepen.io/as3script/pen/VRepqv?editors=1010

You can use state for this purpose
const {
TextArea,
} = semanticUIReact
class App extends React.Component {
constructor(props){
super(props);
this.state={
value: "initial text which I would like to edit" // set initial state
}
}
onChange(e){
this.setState({ value: e.target.value })
}
render() {
const { value } = this.state;
return (
<div>
<TextArea
rows={4}
style={{'width': '550'}}
onChange={(e) => this.onChange(e)}
value={value} //render changed state
/>
</div>
)
}
}
// ----------------------------------------
// Render to DOM
// ----------------------------------------
const mountNode = document.createElement('div')
document.body.appendChild(mountNode)
ReactDOM.render(<App />, mountNode)

Related

Passing input value to sibling through parent

I'm trying to pass input value from one child to another child using setState. It renders the first element, but not the second element in the first child...
class App extends Component {
constructor(props) {
super(props);
this.state = {};
};
showTekst = () => {
const inpValue = document.querySelector('.inpValue').value;
this.setState({
name: 'Bruce Wayne',
namefromvalue: inpValue.value
});
}
render() {
return (
<div className="app">
<Button showTekst={this.showTekst.bind(this)} />
<Text name={this.state.name} namefromvalue={this.state.namefromvalue}/>
<Inputvalue />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
class Inputvalue extends Component {
render() {
return (
<input className="inpValue"></input>
);
}
}
class Text extends Component {
render() {
return (
<div>
<h1>This is text..</h1>
<h2>{this.props.namefromvalue}</h2>
<p>{this.props.name}</p>
</div>
);
}
}
If you want to show the text from the Inputvalue component in the Text component only when the Button component is clicked you can store the input value in the App instance and update the App state when the Button is clicked.
To do so, we define an onChange prop in the Inputvalue component so that every time the text in the input changes, the prop is called with the new value. With that prop we update the value in the App instance. This value will always be in sync with the input value.
Last, when the button is clicked we update the App state with the input value so that the Text component renders its value.
class App extends Component {
constructor(props) {
super(props);
this.state = {};
// This variable will hold the input value.
this.inputValue = "";
}
showTekst = () => {
// Update with the current input value.
this.setState({
name: "Bruce Wayne",
namefromvalue: this.inputValue
});
};
onInputChange = value => {
// Update the input value.
this.inputValue = value;
};
render() {
return (
<div className="app">
<Button showTekst={this.showTekst.bind(this)} />
<Text name={this.state.name} namefromvalue={this.state.namefromvalue} />
<Inputvalue onChange={this.onInputChange} />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
class Button extends Component {
render() {
return <button onClick={this.props.showTekst}>Show text</button>;
}
}
class Inputvalue extends Component {
render() {
return (
<input
className="inpValue"
onChange={ev => this.props.onChange(ev.target.value)}
/>
);
}
}
class Text extends Component {
render() {
return (
<div>
<h1>This is text..</h1>
<h2>{this.props.namefromvalue}</h2>
<p>{this.props.name}</p>
</div>
);
}
}

Material Ui - Unable to enter input textfield/ set values on a controlled component

I tried to create a custom input component with inputRef (material ui Input component). Looks like the component reference is working but I'm unable to enter any value in the text field after i set the value attribute. I think it's because of the way i implemented the onchange event. I'm not sure what am i missing. Please help.
Here is the codesandbox url
https://codesandbox.io/s/pjlwqvwrvm
Actually you don't need a onChange prop to for get the changed value..
Just get the value from onchange and set the value in state value.
Another mistake is you are not created the constructor, and gave this.props.value to the value prop. That's it not get updated..
Now I created the constructor and give the this.state.value to the value props.
Now you get your onchanged value in custominput component and your submit function also..
import React from "react";
import { render } from "react-dom";
import { Input } from "material-ui-next";
import trimStart from "lodash/trimStart";
import PropTypes from "prop-types";
const defaultProps = {
state: "",
onChange: () => {} // no need
};
const propTypes = {
state: PropTypes.string,
onChange: PropTypes.func
};
class App extends React.Component {
constructor() {
super();
this.state = {
value:''
}
}
handleSubmit(event) {
event.preventDefault();
console.log("state: " + this.state.value); //shows onChanged value in console
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit.bind(this)}>
<CustomInput
labelText="State"
id="state"
value={this.state.value}
onChange={e=> {
this.setState({value:e.target.value})
}}
/>
</form>
</div>
);
}
}
App.propTypes = propTypes;
App.defaultProps = defaultProps;
class CustomInput extends React.Component {
render() {
const {
classes,
formControlProps,
value,
onChange,
labelText,
id,
labelProps,
inputRef,
inputProps
} = this.props;
return (
<div {...formControlProps}>
{labelText !== undefined ? (
<div htmlFor={id} {...labelProps}>
{labelText}
</div>
) : null}
<Input
classes={{
root: labelText !== undefined ? "" : classes.marginTop
}}
id={id}
value={value} ///////// Fixed ////////
onChange={onChange}
inputRef={inputRef}
{...inputProps}
/>
</div>
);
}
}
render(<App />, document.getElementById("root"));
Here is code in sandbox check it..
https://codesandbox.io/s/84rjk4m8l8
You can either go on inputRef - then your value and onChange event are extra - it is called uncontrolled Component. You can see more about it here: https://reactjs.org/docs/uncontrolled-components.html
Or you can do it with value & onChange event - and work with controlled components, you can find more about controlled components here: https://reactjs.org/docs/forms.html#controlled-components
How to solve it (uncontrollable) with inputRef:
class App extends React.Component {
handleSubmit = (event) => {
event.preventDefault();
console.log("input value: ", this.input.value); // will now show you correct input value
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<CustomInput
labelText="State"
id="state"
inputRef={input => {
this.input = input;
}}
/>
<Button onClick={this.handleSubmit} color='primary'>Submit</Button>
</form>
</div>
);
}
}
Instead of "this.state = input", bind input to something else, because this.state is reserved for local state of React Component, and it won't work with it, not like that.
How to solve it (controllable) with state, value & onChange event:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: props.state || ''
}
}
handleSubmit = (event) =>{
event.preventDefault();
console.log("state: ", this.state.value); // will now show you correct input value
}
handleChange = (event) => {
this.setState({value: event.target.value});
}
render() {
const {value} = this.state;
return (
<div>
<form onSubmit={this.handleSubmit}>
<CustomInput
labelText="State"
id="state"
onChange={this.handleChange}
value={value}
/>
<Button onClick={this.handleSubmit} color='primary'>Submit</Button>
</form>
</div>
);
}
}
Note that I added the constructor and defined the local state for component, and I'm changing value inside of state with this.setState (because state is immutable, and that's the right way to update it).
In both examples, you are able to get input value inside of handleSubmit method, will you work with controllable or uncontrollable components, it's up to you :)
Use value={this.state} or value={this.value}
Here is Your sandbox code Updated
https://codesandbox.io/s/qqk2qoxmlj
In my case, I was mistakenly using state from parent component in child component, since I had declared child component inside parent itself. Moving whole state to child component solved the problem.

clear the material UI text field Value in react

How to clear the materialUI textfield value in react?
Check the below code -
<TextField
hintText=""
ref={(node) => this._toField = node}
onChange={this.changeToText}
floatingLabelText="To*"
floatingLabelFixed={true}
fullWidth={true}
/>
I'm using the raisedButton while pressing it validate the above field. If the field has error then displaying the error message. If not, then we need to clear the input. But how can we clear the input text?
if you are using a stateless functional component then you can use react hooks.
Also make sure you are using inputRef
import React, { useState, useRef } from "react";
let MyFunctional = props => {
let textInput = useRef(null);
return (
<div>
<Button
onClick={() => {
setTimeout(() => {
textInput.current.value = "";
}, 100);
}}
>
Focus TextField
</Button>
<TextField
fullWidth
required
inputRef={textInput}
name="firstName"
type="text"
placeholder="Enter Your First Name"
label="First Name"
/>
</div>
);
};
There is a value property that you have to pass to the TextField component.
check example below:
class SomeComponent extends Component {
state = {value: ''}
resetValue = () => {
this.setState({value: ''});
}
render() {
return (
<div>
<TextField
...
value={this.state.value}
/>
<button onClick={this.resetValue}>Reset</button>
</div>
)
}
}
try this
import { Button, Container, InputBase } from '#material-ui/core'
import React, { useState } from 'react'
const ClearText = ()=> {
const [text , setText] = useState("")
const clearTextField = () => setText("")
return (
<Container>
<InputBase
value={text ? text : ""}
onChange={(e)=>setText(e.target.value)}
/>
<Button onClick={clearTextField} > Clear </Button>
</Container>
)
};
export default ClearText;
You need to, somehow, store the input's value. State seems to be an initial approach in this case. Whenever the text changes, you have to update the state. Same applies when you click the button and click the input's value afterwards:
class App extends React.Component {
constructor() {
super()
this.state = {
value: ''
}
this.handleChange = this.handleChange.bind(this)
this.handleClick = this.handleClick.bind(this)
}
handleChange(event) {
this.setState({ value: event.target.value })
}
handleClick() {
// validation...
this.setState({ value: '' })
}
render() {
return (
<div>
<input type="text" value={this.state.value} onChange={this.handleChange}/>
<button onClick={this.handleClick}>Click-me</button>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Reactjs add onChange to props.children dynamically

I'm using React v16 (latest) and I'm trying to create a general form component, that uses props.children.
export class MyForm extends React.Component {
render() {
return (
<div>
<div className="form">
<h3>{this.props.formName}</h3>
<div>
{React.Children.map(this.props.children, t => {return <span>{t}<br></br></span>;})}
</div>
<input type="button" value={this.props.formName} onClick={this.handleClick}/>
</div>
</div>
)
}
}
I want to create small form that just are able to create a meaningful json object and send it in POST
This is an example of such usage:
<MyForm>
<input type="text" name="a1"></input>
<input type="text" name="a2"></input>
</MyForm>
And I want to have many such small forms. Problem is I want each child (props.children) to have an onChange event -
onChange(event) // name is "a1" or "a2", like in the example aboce
{
var obj = {};
obj[name]=event.target.value;
this.setState(obj);
}
-so that I don't need to manually add onChange for each such child
-I guess another solution is to create a component, but I want the form to be flexible for each kind of sub-element (input text, text area, radio buttons,...) and I just want them all to have similar onChange that will set the name of the component and its value to the state...
I tried adding an onChange property in consturctor and in different hooks, but got:
cannot define property 'onChange', object is not extensible
So when are where (if at all) can I add an onChange dynamically to props.children
This is a great use case for a Higher Order Component. You can use a HOC to wrap and add the onChange prop to any component:
const WithOnChange = WrappedComponent => {
return class extends Component {
onChange = e => {
const obj = {};
obj[name]=e.target.value;
this.setState(obj);
}
render() {
return <WrappedComponent {...this.props} onChange={this.onChange} />
}
}
}
...
import Input from './Input';
class MyForm extends Component {
render() {
return (
<form>
...
<Input type="text" name="a1" />
...
</form>
)
}
}
export default MyForm;
....
import WithOnChange from './WithOnChange';
const Input = (props) => (
<input {...props} />
);
export default WithOnChange(Input);
EDIT:
Another option is to move your children map into a higher order component and then create a custom <Form /> component:
const Form = () => {
return <form>{this.props.children}</form>
};
export default WithOnChange(Form);
const WithOnChange = WrappedComponent => {
return class extends Component {
onChange = e => {
const obj = {};
obj[name] = e.target.value;
this.setState(obj);
}
render () {
const children = React.Children.map(this.props.children, child => {
return React.cloneElement(child, { onChange: this.onChange });
});
return <WrappedComponent {...this.props}>{children}</WrappedComponent>
}
}
}
#user967710, can you please test the following code:
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
}
onChange(event) {
debugger;
var obj = {};
obj.name = event.target.value;
this.setState(obj);
}
<MyForm formName="myForm">
<input type="text" name="a1" onChange={this.onChange}></input>
<input type="text" name="a2" onChange={this.onChange}></input>
</MyForm>

React Component Not Updating After Changing A Value

In ReactJS, I'm writing a stateless component;
Since I've read avoiding unnecessary states is best practice.
The component represents an input field which executed a function when the input box contains a value.
export const InputField = (props) => {
const InputFieldContentsChanged = (event) => {
props.onChange(event.target.value);
};
return (
<div data-component="input-field"
className={(props.value !== "" ? "value": "")}>
<input type={props.type} value={props.value} onChange={InputFieldContentsChanged} />
<span className="bar"></span>
<label>{props.label}</label>
</div>
);
};
InputField.PropTypes = {
type: PropTypes.oneOf([ "text", "password" ]).isRequired,
label: PropTypes.string.isRequired,
value: PropTypes.string,
onChange: PropTypes.func.isRequired
}
Now,
I've created another component which just is a sample to test the component above.
This looks like the following:
export const SampleComponent = (props) => {
let componentUsername = "";
const onUsernameChanged = (username) => {
componentUsername = username;
};
return (
<InputField type="text" label="Username" value={componentUsername} onChange={onUsernameChanged} />
);
};
So, I'm binding the value to a custom variable in the component which is changed when the contents of the input field does change.
How does it come that the input field component does not update itself with the new username?
Kind regards,
I'm writing a stateless React component since it's best practice to avoid state when not needed.
In your code you are trying to use your own kind of "state" though, and it's just a variable (componentUsername). But since it's not React state, the component does not re-render upon the change of the variable. React simply doesn't know about the change.
So, either use the usual setState instead of re-assigning the your own "state" variable, or put the logic in the parent component and pass the componentUsername to the SampleComponent via props:
const SampleComponent = props => (
<input type="text" onChange={props.onChange} value={props.value} />
);
class ParentComponent extends React.Component {
constructor() {
super();
this.state = { value: '' };
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(e) {
console.log(e.target.value);
this.setState({ value: e.target.value });
}
render() {
return (
<SampleComponent
value={this.state.value}
onChange={this.handleInputChange}
/>
);
}
}
ReactDOM.render(<ParentComponent />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
The idea of functional components is to not perform any changes to the state or props.
Since there is no trigger to re-render you component you won't see any change.
Change this React.Function to a React.Component.
const InputField = (props) => {
const InputFieldContentsChanged = (event) => {
console.log(event.target.value);
props.onChange(event.target.value);
};
return (
<div data-component="input-field"
className={(props.value !== "" ? "value": "")}>
<input type={props.type} value={props.value} onChange={InputFieldContentsChanged} />
<span className="bar"></span>
<label>{props.label}</label>
</div>
);
};
class SampleComponent extends React.Component {
constructor() {
super();
this.state = { componentUsername : ""};
}
onUsernameChanged = (username) => {
console.log(username);
this.setState({componentUsername: username});
}
render() {
return (
<InputField type="text" label="Username" value={this.state.componentUsername} onChange={this.onUsernameChanged} />
);
}
};
ReactDOM.render(<SampleComponent/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Resources