21

I am using react bootstrap and this framework provides some nice FormControls.

But I would like to make the Input field that is generated within the FormControls to have a prop of readonly="readonly". This way, this field looks the same as my other FormControls, but does not give a keyboard input on IOS.

In my case, the input will be provided by a calendar picker which will be triggered by an popover.

Does anyone know how to give FormControl the parameter readonly="readonly", so that the generated Input field in the browser will have the prop readonly="readonly"?

Many thnx for the answers!

user3611459
  • 3,311
  • 6
  • 16
  • 18
  • [What have you tried so far?](http://whathaveyoutried.com) Please [edit] your question to show a [mcve] of the code that you are having problems with, then we can try to help with the specific problem. You should also read [ask]. – Toby Speight May 16 '16 at 12:13

3 Answers3

45

It doesn't look like a problem with react-bootstrap, but rather with react itself. React is not transferring the 'readonly' prop to the generated (real) DOM element:

React-bootstrap create the following react virtual dom input: enter image description here

Yet, react generated the following real DOM element, omitting the readonly attribute: enter image description here

Maybe using 'disabled' could help in your case:

<FormControl
   disabled
   type="text"
   placeholder="Enter text"
   onChange={this.handleChange}
 />

For differences between readonly & disbabled see here: https://stackoverflow.com/a/7730719/1415921

I have created an issue in React's github repo: #6783


UPDATE

After getting an answer in the above issue. You need to write it with camelcase: readOnly.

So it should be:

<FormControl
   readOnly
   type="text"
   placeholder="Enter text"
   onChange={this.handleChange}
 />
Community
  • 1
  • 1
omerts
  • 8,485
  • 2
  • 32
  • 39
  • it can be readOnly only under certain circumstances, so for when it is not, you need to handle change – omerts Jan 29 '17 at 09:08
  • @omerts but the way you've answered it, it will be readOnly in all circumstances? – joedotnot Feb 08 '19 at 03:45
  • 2
    @joedotnot You can use it with: readOnly={false} || readOnly={true} – omerts Feb 13 '19 at 15:26
  • 1
    @omerts. No. there is no such thing as readOnly= true/false; if it's present, it is assumed to be read only! you can have readOnly="whatevs", readonly="true", readOnly="false" all mean the same thing. – joedotnot Feb 14 '19 at 00:00
  • @joedotnot It works, please look at the way I wrote it precisely,I am using {false}, and not 'false'. See here: https://jsfiddle.net/omerts/b5q8axhn/ – omerts Feb 19 '19 at 13:46
  • 2
    @omerts yes you are 100% correct it works ! And now this will be something I and others will have to remember. that "false" and {false} behave differently - that is totally unexpected (and bad in my opinion that the library allows for that) – joedotnot Feb 19 '19 at 14:17
0

Old problem, new approach: Take advantage of onChange event to control if you'll call handleChange event or not. I defined editForm as a props value controlled by buttons, to see if i'm in view or edit mode.

Example:

<TextField
        name="id"
        label="ID
        value={entityState.entity.Id || ""}
        onChange={(a) => (props.formEdit ? handleChange(a) : "")}
/>
Edu Garcia
  • 11
  • 5
0

On the basis of values this attribut will be readOnly={!!value} to make input field disable to edit

class Input extends React.Component {
  render () {
    const { defaultValue, value, onChange } = this.props
    const nothing = () => {}
    
    return (
      <input
        type='text'
        defaultValue={defaultValue}
        value={value ? value.toUpperCase() : undefined}
        readOnly={!!value}
        onChange={value ? nothing : onChange}
       />
    )
  }
}

class App extends React.Component {
  constructor () {
    super ()
    
    this.state = {
      value: 'arr'
    }
  }
  
  handleChange (e) {
    const { target: { value }} = event
    this.setState({ value })
  }
  
  render () {
    const { value } = this.state
 
    return (
      <div>
        <Input 
          onChange={this.handleChange.bind(this)}
          defaultValue={'patata'}
          />
        <Input 
          value={value}
          />
     </div>
    )
  }  
}

ReactDOM.render(<App />, document.getElementById('arr'))
Sandeep Jain
  • 1,019
  • 9
  • 13