Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - restrict to numeric/alphanumeric/hexadecimal symbols in text field with max length

Tags:

reactjs

input

I'm working on React.js project. I wanna create 3 Text Fields where:

1st Text Field - I want to insert only hexadecimal values. It should accept the numbers from 0-9 & letters from A-F & colon. It should accept only 23 chars(numbers, letters from A-F & colon).

2nd Text Field- It should only Hexadecimal values.

3rd Text Field- It should accept only Alpha Numeric values (only Numbers &
letters).

4th Text Field- Only Letters.

Note: Special Characters should not be accepted.

Please help me out to solve this.

Sample Code:

constructor(props) {
  super(props);this.state = {showModal: true};
  this.modalFooter = this.modalFooter.bind(this);
  this.modalBody = this.modalBody.bind(this); this.updateState = this.updateState.bind(this);     
};

modalFooter() {
  return (
    <div>
      <BButton name="Cancel" onClickHandler={() => { this.setState({ showModal: false }) }} />
    </div>);
}

modalBody() {
  return (
    <div>
      <br className="Class">
        <br> Hex Value: <input type="text" className="Class" formnovalidate="return isNumber(event)"
          maxLength="23" placeholder="" /></br>
        <br> Addr:  <input type="text" className="Class" maxLength="6" name=""
          placeholder="" /></br><br> Name: <input type="text" className="Class" id="Number"
            maxLength="64"
            name="" placeholder="" /></br>
      </br>
    </div>
  );
}

updateState(e) {
  this.setState({data: e.target.value});
}

render() {
  let body = this.modalBody();
  let footer = this.modalFooter();
  let modal = <BModal header="Add Message"
    body={body}
    footer={footer} />
  return (
    <div className="page-title">
      <center>
        <h3> Sample Program </h3>
      </center>
      <hr className="horizontal-line"></hr>

      <div>  <font color="grey"><input type="text" value={this.state.data}
        onClick={() => { this.setState({ showModal: true }) }} /></font>
        {this.state.showModal ? modal : ""}
      </div>
    </div>);

}
like image 361
Sai Avatar asked Mar 30 '16 09:03

Sai


2 Answers

I suggest you to use React onKeyPress event with regexp verifications (see example below and the jsbin link)

var Form = React.createClass({

  firstMethod(e) {
    const re = /[0-9A-F:]+/g;
    if (!re.test(e.key)) {
      e.preventDefault();
    }
  },

  secondMethod(e) {
    const re = /[0-9A-F]+/g;
    if (!re.test(e.key)) {
      e.preventDefault();
    }
  },

  thirdMethod(e) {
    const re = /[0-9a-fA-F]+/g;
    if (!re.test(e.key)) {
      e.preventDefault();
    }
  },

  fourthMethod(e) {
    const re = /[a-fA-F]+/g;
    if (!re.test(e.key)) {
      e.preventDefault();
    }
  },

  render() {
    return (
      <form>
        <input ref="first" onKeyPress={(e) => this.firstMethod(e)} />
        <input ref="second" onKeyPress={(e) => this.secondMethod(e)} />
        <input ref="third" onKeyPress={(e) => this.thirdMethod(e)} />
        <input ref="fourth" onKeyPress={(e) => this.fourthMethod(e)} />
      </form>
    );
  }
});

ReactDOM.render(
  <Form />,
  document.getElementById('example')
);

http://jsbin.com/juyakaqawe/edit?html,js,output

like image 75
Anastasia Abakumova Avatar answered Oct 12 '22 23:10

Anastasia Abakumova


Actually, it's not complicated at all. You only need to take care of extracting allowed characters from text input, limit its length, ... To be honest, this is not related to React in any way - it's pure Javascript.

Let's begin with simple function which extracts substring from string by pattern

const extract = (str, pattern) => (str.match(pattern) || []).pop() || '';
// Usage
extract("01az", "[0-9a-fA-F]+") // "01a"

Then, wrap this function into functions which solve pattern problems for 1, 2, 3 and 4

const extractHexadecimalWithColon = (str) => extract(str, "[0-9a-fA-F:]+");

const extractHexadecimal = (str) => extract(str, "[0-9a-fA-F]+");

const extractAlphanum = (str) => extract(str, "[0-9a-zA-Z]+");

const extractAlpha = (str) => extract(str, "[a-zA-Z]+");

It super easy to limit length of string

const limitLength = (str, length) => str.substring(0, length);

Then, create your text inputs components, listen for changes and update state as required.

var App = React.createClass({
  getInitialState() {
    return {};
  },

  setA(e) {
    this.setState({
      a: limitLength(extractHexadecimalWithColon(e.target.value), 23),
    });
  },

  setB(e) {
    this.setState({
      b: extractHexadecimal(e.target.value),
    });
  },

  setC(e) {
    this.setState({
      c: extractAlphanum(e.target.value),
    });
  },

  setD(e) {
    this.setState({
      d: extractAlpha(e.target.value),
    });
  },

  render() {
    return (
      <div>
        <div>
          Hexadecimal, max 23 chars, colon allowed<br/>
          <textarea value={this.state.a} onChange={this.setA} />
        </div>

        <div>
          Hexadecimal only, no length restriction<br/>
          <textarea value={this.state.b} onChange={this.setB} />
        </div>

        <div>
          Alphanumeric<br/>
          <textarea value={this.state.c} onChange={this.setC} />
        </div>

        <div>
          Letters only<br/>
          <textarea value={this.state.d} onChange={this.setD} />
        </div>
      </div>
    )
  }
});

Full working fiddle here https://jsfiddle.net/69z2wepo/36536/

Original solution split into separate components https://jsfiddle.net/69z2wepo/36654/

like image 44
Andreyco Avatar answered Oct 12 '22 22:10

Andreyco