Browse Source

Lifted the state to Form component

Snow 8 years ago
parent
commit
818263b0bf
2 changed files with 79 additions and 57 deletions
  1. 24 15
      src/__test__/Form.test.js
  2. 55 42
      src/components/Form/index.js

+ 24 - 15
src/__test__/Form.test.js

@@ -1,35 +1,34 @@
 import React from 'react';
-import Form, { InputWithPlaceHolder } from '../components/Form';
+import Form from '../components/Form';
 import { mount, shallow } from 'enzyme';
 
 describe('Place holder', () => {
   const colorTest = (inputWindow, color) => {
-    expect(inputWindow.find('input').prop('style')).toHaveProperty(
-      'color',
-      color
-    );
+    expect(inputWindow.find('input').at(0).prop('style'))
+      .toHaveProperty('color', color);
   };
 
   it('Placeholder shows on loading and color is grey', () => {
-    const inputWindow = shallow(<InputWithPlaceHolder placeHolder="test" />);
-    expect(inputWindow.find('input').prop('value')).toBe('test');
+    const inputWindow = shallow(<Form />);
+    expect(inputWindow.find('input').at(0).prop('value')).toBeTruthy();
     colorTest(inputWindow, 'grey');
   });
 
   it('Clicking on the input field hides the placeholder', () => {
-    const inputWindow = shallow(<InputWithPlaceHolder placeHolder="test" />);
-    const inputField = inputWindow.find('input');
+    const inputWindow = mount(<Form />);
+    const inputField = inputWindow.find('input').at(0);
     inputField.simulate('focus');
-    expect(inputWindow.find('input').prop('value')).toBe('');
+    expect(inputField.prop('value')).toBe('');
   });
 
   it('Typing in the input area shows the text with color black, \
   	deleting the text shows placeholder again on blur', () => {
-    const inputWindow = mount(<InputWithPlaceHolder placeHolder="test" />);
-    const inputField = inputWindow.find('input');
-    inputField.simulate('focus');
-    const newValue = 'Entered new value';
-    inputField.simulate('change', { target: { value: newValue } });
+    const inputWindow = mount(<Form />);
+    const inputField = inputWindow.find('input').at(0);
+      inputField.simulate('focus');
+      const newValue = 'Entered new value'
+    inputField.node.value = newValue;
+    inputField.simulate('change', inputField);
     expect(inputField.prop('value')).toBe(newValue);
     colorTest(inputWindow, 'black');
     inputField.simulate('change', { target: { value: '' } });
@@ -38,3 +37,13 @@ describe('Place holder', () => {
     colorTest(inputWindow, 'grey');
   });
 });
+
+describe('Validation', () => {
+  it('Exceeding the max length shows show a warning', () => {
+    const inputWindow = mount(<InputWithPlaceHolder maxLength={8}/>)
+    const inputField = inputWindow.find('input')
+    const newValue = 'test   test'
+    inputField.simulate('change', { target: { value: newValue } });
+    expect(inputWindow.find('.warning').text()).toTruthy()
+  })
+})

+ 55 - 42
src/components/Form/index.js

@@ -1,90 +1,103 @@
 import React from 'react';
+import PropTypes from 'prop-types'
 
-export class InputWithPlaceHolder extends React.Component {
+export default class Form extends React.Component {
+  static placeHolder = {
+    name: 'Enter your name',
+    password: '12345678',
+    password2: '12345678',
+    comment: 'Enter your comment'
+  }
+  
   state = {
-    value: this.props.placeHolder,
-    fontColor: 'grey'
-  };
+    ...this.constructor.placeHolder
+  }
 
-  handleFocus = () => {
-    if (this.state.fontColor === 'grey') {
+  handleFocus = (event) => {
+    const target = event.target
+    const color = target.style.color;
+    const name = target.name;
+    if (target.value === this.constructor.placeHolder[name] && color === 'grey') {
       this.setState({
-        value: '',
-        fontColor: 'black'
-      });
+        [name]:'',
+      })
     }
   };
    
-  handleChange = event => {
-    this.setState({
-      value: event.target.value
-    });
-  };
-
-  handleBlur = () => {
-    if (this.state.value.length === 0) {
+  handleBlur = (event) => {
+    const target = event.target
+    const name = target.name
+    if (target.value.length === 0) {
       this.setState({
-        value: this.props.placeHolder,
-        fontColor: 'grey'
+        [name]: this.constructor.placeHolder[name],
       });
     }
   };
+  
+  handleChange = event => {
+    const target = event.target;
+    const value = target.type === 'checkbox' ? target.checked : target.value;
+    const name = target.name;
+    this.setState({[name]:value})
+  };
 
-  render() {
-    if (this.props.type === 'textarea') {
+
+  renderInput = (type,name) => {
+    const color = (this.state[name].length === 0) ? 'black' : 'grey'
+    
+    if (type === 'textarea') {
       return (
         <textarea
-          type={this.props.type}
-          value={this.state.value}
+           type={type}
+           name={name}
+          value={this.state[name]}
           onFocus={this.handleFocus}
           onChange={this.handleChange}
-          style={{ color: this.state.fontColor }}
+          style={{ color: color }}
           onBlur={this.handleBlur}
-          className="input"
+          className={"input " + name}
         />
       );
     }
 
     return (
       <input
-        type={this.props.type}
-        value={this.state.value}
-        onFocus={this.handleFocus}
-        onChange={this.handleChange}
-        style={{ color: this.state.fontColor }}
-        onBlur={this.handleBlur}
-        className="input"
+           type={type}
+           name={name}
+          value={this.state[name]}
+          onFocus={this.handleFocus}
+          onChange={this.handleChange}
+          style={{ color: color }}
+          onBlur={this.handleBlur}
+           className={"input " + name}
       />
     );
   }
-}
-
-export default class Form extends React.Component {
+  
   render() {
     return (
       <form>
         <label>
           Name:
-          <InputWithPlaceHolder type="text" placeHolder="Enter your name" />
+          {this.renderInput('text','name')}
         </label>
         <br />
         <label>
           Password:
-          <InputWithPlaceHolder type="password" placeHolder="12345678" />
+          {this.renderInput('password','password')}
         </label>
         <br />
         <label>
           Password:
-          <InputWithPlaceHolder type="password" placeHolder="12345678" />
+{this.renderInput('password','password2')}
         </label>
         <br />
         <label>
           Comments: <br />
-          <InputWithPlaceHolder
-            type="textarea"
-            placeHolder="Enter your comments."
-          />
+          {this.renderInput('textarea','comment')}
         </label>
+        <br />
+        <input type="submit" value="Submit" />
       </form>
     );
   }