How to allow user formatting in React app? - reactjs

I have a React app where a user can type something into textbox, click 'submit' and then the text appears somewhere.
I want to add functionality which will allow the user to format the text. Just like you can do here on SE when asking questions. For example I want the below input to be shown as bold.
<b>bold</b>
How can I achieve this? Or where to look for this kind of thing?

If you want to enable the same functionality you get in stack overflow, then I think the one way to achieve this would be allowing the user to input markdown and converting that to HTML. This is a library that could help with that: marked
Freecodecamp has a markdown previewer as one of their projects, so if you want to check out some examples, you could probably find hundreds of different implementations: https://www.freecodecamp.org/forum/t/build-a-markdown-previewer/198715

Yes, this can be done using state, as well as a checkbox toggle to determine whether or not the text should be bold or not.
handleChange will update the input. handleFormatChange will update whether or not you should use bold text or not. In the render, a conditional can be implemented to determine when to render what format.
class Formatter extends React.Component {
state = {
format: false,
input: ""
}
handleChange = () => {
this.setState({
input: event.target.value
})
}
handleFormatChange = () => {
this.setState({
format: !this.state.format
})
}
render() {
var input = this.state.format
? <b> {this.state.input} </b>
: <p> {this.state.input} </p>
return (
<div>
Bold <input type="checkbox"
onChange = {
this.handleFormatChange
}
/>
<br />
<input value={this.state.input}
onChange = {this.handleChange}
/>
<br/>
{input}
</div>
);
}
}
ReactDOM.render( <
Formatter / > ,
document.getElementById('root')
);
p {
margin-top: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root">
<!-- This element's contents will be replaced with your component. -->
</div>

Related

Auto focus first time on loading page

There is a input text in center in which I want to focus when the page loads, so I have used componentDidMount() and set the focus.
componentDidMount() {
this.inputBar.focus();
}
.
.
<input type="text" ref={(element) => { this.inputBar = element; }}>
but it isn't working as a sidebar pops in as the page loads and shifts the focus from the center input.
I tried to use componentDidUpdate() but then it triggers the focus again and again when I close the sideBar. I only want to focus only at first time when I load the page.
I am new at coding, please suggest something that can be done here.
Thanks in advance.
you have to create ref , then in your lifecycle method use that ref, you have forgotten to use current when you are using ref in lifecycle method, your code will be like this:
class GroupDetail extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
componentDidMount(){
this.ref.current.focus()
}
render(){
return(
<input type="text" ref={this.inputRef}/>
)
}
}
If you want to focus a single Input then you can simply do
<input type="text" autofocus>
If you just want to focus an element when it mounts (initially renders) a simple use of the autoFocus attribute will do.
<input type="text" autoFocus />
Or if you want to do it with componentDidMount and to control focus dynamically you can go with the below snippet
class App extends React.Component{
componentDidMount(){
this.nameInput.focus();
}
render() {
return(
<div>
<input defaultValue="Won't focus"/>
<input ref={(element) => { this.nameInput = element; }} defaultValue="will focus"/>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

Component design hierearchy in React

I have recently started learning React. I want to create two components - Input and Display. Input has a textfield and a button. When I type something and submit the button, the value of the textfield should be passed as a prop to Display and the Display should output the value.
How to approach the design? What is the component hierarchy?
You will need to 'lift up' the value from the text input to the display prop via it's shared ancestor component.
Here is an example of 'lifting up' state with useState in the functional style:
const Input = ({ setValue }) => {
return <input onChange={(event) => setValue(event.target.value)} />
}
const Display = ({ value }) => {
return <div>{value}</div>
}
const Parent = () => {
const [value, setValue] = React.useState('')
return <div>
<Input setValue={setValue} />
<Display value={value} />
</div>
}
ReactDOM.render(<Parent />, document.getElementById('app'))
<script crossorigin src="https://unpkg.com/react#16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.production.min.js"></script>
<div id="app" />
If you provide what you have at the moment, then it'll be easier to answer; otherwise I'll just be writing the whole code instead of letting you learn.
One way is to implement a callback function that sets the state in Display with text field's value when Input button is clicked. Display should be the one passing this function as a prop to Input. Input calls this function when button is clicked with the text field's value.
Then whatever is rending Display's state will output the value appropriately.

How to link a text field with a radio button

Before Clicking anything text field should be disable . when after the radio button selected my text field must be enable.
This is the working solution of your question.
class App extends React.Component {
state = {
isRadioSelected: true
};
changeHandler = () => {
this.setState({ isRadioSelected: false });
};
render() {
return (
<div className="App">
<h3>Input text is {this.state.isRadioSelected ? 'Disabled': 'Enabled'}</h3>
<input type="text" disabled={this.state.isRadioSelected} />
<br />
<label>Select Radio Button</label>
<input type="radio" onChange={this.changeHandler} />
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root' />
Your description is pretty vague and you don't have any code samples, but here's likely what you want to do:
Make the radio button a controlled component, so that you can access it's value within React's state.
Tie the input's disabled attribute to the value of that state field.
It also seems like you want a checkbox, and not a radio button, since a radio button cannot be untoggled if there is only a single radio button.
This code will likely not work as-is (I haven't run it), but should provide a starting idea:
function Tester() {
const [radioValue, setRadioValue] = useState(false)
return (
<div>
<input type="radio" onClick={(e) => setRadioValue(e.target.value)} value={radioValue} />
<input type="text" placeholder="your input box" disabled={!radioValue} />
</div>
)
}

Click to Enable TextField React

I am displaying tabular data and each cell displays data using a TextField of Material UI (like input field). I want to show all of these TextFields as disabled at first, and enable any of them if they are clicked on. So user would click on the TextField and field would become available to alter. How can I do that?
Setting the state for field
state = {
button: false,
}
I have the TextField like below:
<TextField
disabled={this.state.button}
onClick={this.fieldActivate}
name="abc"
Activating field
fieldActivate(event) {
this.setState({
button: true
})
}
onClick and disabled
They don"t work together since disabled elements are not clickable. However, you could use something like onMouseOver.
Callback and Scope
If you want to define a function for an Event which uses this keyword, you need to either bind this or call the function from an anonymous function.
Finding the target
Since you only want one field to be enabled, you need to identify it somehow. Give them keys/ids.
Example
class MyComponent extends React.Component {
state = {
enabled: -1
}
handleMouseOver(id) {
this.setState({
enabled: id
});
}
render() {
let inputs = [];
for (let i=0; i<=20; i++) {
inputs.push({ id: i, placeholder: 'Input ' + i });
}
return (
<div>
{inputs.map((input) => {
return(
<input
disabled={this.state.enabled !== input.id}
type='text'
placeholder={input.placeholder}
onMouseOver={(e) => {
this.handleMouseOver(input.id);
}}
/>
);
})}
</div>
);
}
}
ReactDOM.render(
<MyComponent />,
document.getElementById('app')
);
input:disabled{
background: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='app'></div>
state = { currentFocusElement: '' }
...
<TextField
disabled={this.state.currentFocusElement !== 'name'}
onFocus={() => this.setState({ currentFocusElement: 'name' })}
The idea is force a re-render when onfocus, and change the disabled value

React form input won't let me change value

I have a component in a React class in my Laravel project which is a simple form with one input field. It houses a phone number which I have retrieved from the database and passed back through the reducer and into the component as a prop. Using this, I have passed it through to the module as a prop which then populates the field with the currently saved value:
<OutOfOfficeContactNumberForm
show={props.showOutOfOffice}
value={props.outOfOfficeNumber}
handleChange={console.log("changed")}
/>
I have a handleChange on here which is supposed to fire a console log, but it only ever displays on page load. Here is my form module class:
class OutOfOfficeContactNumberForm extends React.Component {
render() {
const { show, value, handleChange } = this.props;
if(!show) return null;
return (
<div>
<p>
Please supply an Out of Office contact number to continue.
</p>
<InputGroup layout="inline">
<Label layout="inline" required={true}>Out of Office Contact Number</Label>
<Input onChange={handleChange} value={value} layout="inline" id="out-of-office-number" name="out_of_office_contact_number" />
</InputGroup>
</div>
);
}
}
export default (CSSModules(OutOfOfficeContactNumberForm, style));
The form is embedded in my parent component, as follows:
return (
<SectionCategoriesSettingsForm
isSubmitting={this.state.isSubmitting}
page={this.props.page}
show={this.props.show}
categories={this.props.categories}
submitSectionCategoriesSettings={this._submit.bind(this, 'add')}
updateSelectedCategories={this._updateSelectedCategories.bind(this)}
selectedCategoryIds={this.state.selectedCategoryIds}
storedUserCategories={this.props.selectedCategories}
outOfOfficeNumber={this.state.outOfOfficeNumber}
onUpdateContactNumber={this._updateContactNumber.bind(this)}
/>
);
In my componentWillReceiveProps() function, I set the state as follows:
if (nextProps.selectedCategories && nextProps.selectedCategories.length > 0) {
this.setState({
outOfOfficeNumber: nextProps.outOfOfficeNumber,
selectedCategoryIds: nextProps.selectedCategories.map(c => c.id)
});
}
I'm pretty sure the reason it's not changing is because it's pre-loaded from the state which doesn't change - but if I cannot edit the field how can I get it to register a change?
EDIT: Just to clarify there are also checkboxes in this form for the user to change their preferences, and the data retrieved for them is set the same way but I am able to check and uncheck those no problem
Changes:
1- onChange expect a function and you are assigning a value that's why, put the console statement inside a function and pass that function toOutOfOfficeContactNumberForm component , like this:
handleChange={() => console.log("changed")}
2- You are using controlled component (using the value property), so you need to update the value inside onChange function otherwise it will not allow you to change means input values will not be not reflect in ui.
Check example:
class App extends React.Component {
state = {
input1: '',
input2: '',
}
onChange = (e) => this.setState({ input2: e.target.value })
render() {
return(
<div>
Without updating value inside onChange
<input value={this.state.input1} onChange={console.log('value')} />
<br />
Updating value in onChange
<input value={this.state.input2} onChange={this.onChange} />
</div>
)
}
}
ReactDOM.render(<App />, 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' />
I think the best way is when you get data from database put it to state and pass the state to input and remember if you want to see input changes in typing, use a function to handle the change and that function should change state value.
class payloadcontainer extends Component {
constructor(props) {
super(props)
this.state = {
number:1
}
}
render() {
return (
<div>
<input value={this.state.number} onChange={(e)=>this.setState({number:e.target.value})}></input>
<button onClick={()=>this.props.buyCake(this.state.number)}><h3>buy {this.state.number} cake </h3></button>
</div>
)
}
}

Resources