2

In my React component, I have a form with multiple input fields. In the CSS classes that I'm working with, there's an "invalid" pseudo-class that should highlight the field if its value is invalid. Currently, the input fields do not have any classes defined in my component. They're using the default styling that comes from the CSS file.

class MyForm extends Component {

   render() {

      return(

         // There's more code here. Not showing to keep things simple

         <input type="text" name="someProperty" value={myObject.someProperty} onChange={e => this.someFunction(e)} />

      );
   }

}

How do I actually use this -- meaning, how do I set the input field to invalid? I tried simply adding "invalid" to its CSS class but it didn't work.

This is what I tried with no results:

<input type="text" name="someProperty" className={showInvalid} value={myObject.someProperty} onChange={e => this.someFunction(e)} />

UPDATE:

Doing a bit more research on pseudo-classes, they do NOT go into the class. So in HTML, the input field would simply appear as below:

<input name"someProperty" invalid />
Sam
  • 26,817
  • 58
  • 206
  • 383
  • className should be a string. I think it probably thinks className is undefined since showInvalid is undefined. –  Dec 21 '16 at 21:19
  • See my update. Looks like it should not go into the className. – Sam Dec 21 '16 at 21:22
  • Ah some reason I brain farted... Didn't see the psuedo. My bad –  Dec 21 '16 at 21:23
  • It looks like you can't use pseudo classes in inline style. Which is basically what you are doing. http://stackoverflow.com/questions/28269669/css-pseudo-elements-in-react. Never had that come up –  Dec 21 '16 at 21:25
  • Unfortunately, I'm coming to that conclusion as well! Bummer! – Sam Dec 21 '16 at 21:28
  • look at http://stackoverflow.com/questions/30187781/react-js-disable-button-when-input-is-empty – Robert Dec 21 '16 at 21:43

2 Answers2

0

If I understand correctly, that is what you're looking for

className={`${this.state.showInvalid} ? 'invalidCssClassName' : 'nonInvalidCssClassName'`}

That means you should store somewhere (state or props) the value which will be responsible for evaluating the class name. In that case when showInvalid is evaluated to true, CSS class will be invalidCssClassName otherwise nonInvalidCssClassName

jmac
  • 688
  • 3
  • 15
  • See my update. Research shows me that pseudo-classes are not used in class names. – Sam Dec 21 '16 at 21:22
0

You could just use the pattern attribute on the input elements.

When an element is invalid

The element matches the :invalid CSS pseudo-class; this will let you apply a specific style to invalid elements. Similarly, valid elements match the :valid pseudo-class....

...All <input> elements can be validated using the pattern attribute. This attribute expects a case sensitive Regular Expression as its value...

var NumberInput = React.createClass({
  render: function() {
    return <input type="number" pattern="[0-9]+([\,|\.][0-9]+)?" step="0.01" title="This should be a number with up to 2 decimal places." placeholder="Price" />;
  }
});

ReactDOM.render(
  <NumberInput />,
  document.getElementById('container')
);
input:invalid {
  background-color: #ff3333;
}

input:valid {
  background-color: transparent;
}
<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="container"></div>
Community
  • 1
  • 1
DavidDomain
  • 14,976
  • 4
  • 42
  • 50
  • This is an interesting idea! I'll give it a try and let you know. Thanks! – Sam Dec 21 '16 at 21:48
  • Sure, no problem. – DavidDomain Dec 21 '16 at 21:49
  • I couldn't get it to work but it should. We simply put a regex into pattern, right? For example if I want to make sure it's a number with two decimal points, I should be able to use pattern="/^[0-9]+(\.[0-9][0-9]?)?$/", correct? – Sam Dec 21 '16 at 21:59
  • I've made an update to the fiddle using an `input` with `type` set to `number`, allowing up to two decimal places. – DavidDomain Dec 21 '16 at 22:03
  • Sorry, my first pattern was wrong, this should work `[0-9]+([\,|\.][0-9]+)?`. Check out the code snippet. – DavidDomain Dec 21 '16 at 22:08
  • This is working nicely. My CSS file was cached so the invalid pseudo-class that I had added wasn't coming through. I think this is a nice and clean approach because it's all CSS based. – Sam Dec 21 '16 at 23:14