20

I've created a redux-form and i want to add className to each Field to customize them with css. The code for each field is:

<Form onSubmit={handleSubmit(requestAccountsFilter)}>
        <FormGroup row>
          <Field
            id="symbol"
            name="symbol"
            type="text"
            component={inputField}
            placeholder="Enter Product Here"
          />
          <Field id="side" name="side" component={inputField} type="select">
            <option value={null}>Any</option>
            <option value="Buy">Buy</option>
            <option value="Sell">Sell</option>
          </Field>
          <Field id="status" name="status" component={inputField} type="select">
            <option value={null}>Any</option>
            <option value="Working">Working</option>
            <option value="Completed">Completed</option>
          </Field>
          <Button name="submit-btn" className="filter-submit-btn" color="danger" type="submit">
        Submit
      </Button>
    </FormGroup>
  </Form>

I've added a className tag but i see that neither the placeholder i've added is shown nor the className. How can i customize each field?

RamAlx
  • 6,976
  • 23
  • 58
  • 106
  • It all depends on what your `inputField` function looks like. Can you show it to us? – gustavohenke Feb 13 '17 at 11:11
  • All props that you passed to `Field` will be available in your `inputField` component. So in your `inputField` component, you just need to destructure props like ``. In this way all the props that you pass to `Field` will be available in your `inputField` component.` – Hardik Modha Feb 13 '17 at 14:03
  • My inputField component is like this:export default field => (
    {field.children} {field.meta.touched && field.meta.error && {field.meta.error}}
    );
    – RamAlx Feb 13 '17 at 15:43
  • 1
    Rather than pasting your code in the comment. Please edit your question. – Hardik Modha Feb 13 '17 at 16:09

4 Answers4

13
<Field 
    type="text" 
    className="myClass"
    component={InputField} 
    placeholder="Type here..."
/>

and your custom InputField should be something like

(I've taken this example from http://redux-form.com/6.5.0/examples/submitValidation/)

export const InputField = ({ input, type, placeholder, className, meta: { touched, error } }) => (
  <div>
      <input {...input} placeholder={placeholder} type={type} className={className}/>
      {meta.touched && meta.error && <span>{meta.error}</span>}
  </div>
)

or a better approach, if too many props are there, You can use object destructuring

export const InputField = (field) => ( 
    <div> 
        <input {...field.input} {...field} /> 
        {field.meta.touched && field.meta.error && <span className="error">{field.meta.error}</span>} 
    </div>
)

{...field} will extract all props that you have passed in Field.

You can take a look at this official redux-form example: http://redux-form.com/6.5.0/examples/react-widgets/ to get more idea.

Hope it helps :)

Hardik Modha
  • 12,098
  • 3
  • 36
  • 40
  • The last InputField Component shows me an error that cannot read props meta and input – RamAlx Feb 14 '17 at 13:49
  • Did first one work? I'm not much sure about the second because I haven't tried it myself. I'll need to look into it. – Hardik Modha Feb 14 '17 at 14:06
  • Nor the first is working. It's working only if i assign a value directly. to be more specific if i assign etc value="fsfsdfs" it will work but if i assign value={value} and in my component i set value="fsdfsdfsd" it will not work – RamAlx Feb 14 '17 at 14:23
  • I've also made some other changes. Can you please try updated answer? – Hardik Modha Feb 14 '17 at 14:34
  • No, it didnt work. Also the return throws me an error – RamAlx Feb 14 '17 at 14:37
  • I've reverted my answer, I tested the first version and it's working fine. Can you please copy as it is an try now? – Hardik Modha Feb 14 '17 at 14:42
  • It's fine mate thanks a lot! But i want to ask you something else. i want my box to have a default value. Does a box have a value prop so as to assign a value in it? – RamAlx Feb 14 '17 at 14:44
  • So it worked? You might find reading this helpful. http://redux-form.com/6.0.0-alpha.4/examples/initializeFromState/ and http://stackoverflow.com/questions/36958251/unable-set-a-default-value-in-redux-form-w-react – Hardik Modha Feb 14 '17 at 14:46
  • Thanks a lot :) You were really helpful :) – RamAlx Feb 14 '17 at 14:49
  • Did it wok or not? – Hardik Modha Feb 14 '17 at 15:04
  • Glad it worked. If you are satisfied with the answer then you can mark the answer as accepted. It will also help others in the future for reference. :) – Hardik Modha Feb 14 '17 at 15:17
1

You can use object destructuring method to set className.

<Field 
        type="text" 
        input={{className:'red'}}
        component={InputField} 
        placeholder="Type here..."
    />
luis
  • 11
  • 2
  • I really like this approach over the others, and removes the need for adding className on a component, something that can be considered a bad practice. – DBrown Dec 09 '18 at 19:56
1

I realize that you are using a custom renderer by saying component={InputField}, but for others coming here (since I can't find it in the docs): if you are using one of the built-in renderers like component="input" or component="select", you can just add className and the renderer will apply it, e.g.:

<Field name="foo" component="select" className="form-control">
</Field>
Paul A Jungwirth
  • 23,504
  • 14
  • 74
  • 93
0

By definition, whatever you pass to the Field component should be passed to the InputField component as input prop. So, your InputField Component should look something like this:

<div> 
    <InputField  {...field.input} > {field.children} </InputField> 
    {field.meta.touched && field.meta.error && <span className="error"> 
    {field.meta.error}</span>}
</div>