Search code examples
javascriptreduxreact-redux-form

Set initial values fields on React Redux Form


I have rendered a redux form of dynamic fields, which accept either string input from the user, or a boolean which is a select field which has a drop-down menu where the user can select yes or no. Redux form values initialize boolean fields to false. The following code takes takes an object dynamically renders the redux fields by passing an array of these objects:

String input fields: {name: "stateCode", length: 100, title: "State", type: "string", required: true}

Boolean input fields: {name: "amended", length: 5, title: "Amended", type: "boolean", required: true}

An array of these objects gets grabbed from the database by the backend code and gets sends them to the front end. The array of objects is different depending on which one of the 250 different forms the user is filling out, each has a subset of 80 possible fields that are requirements for that form. The following code is how I create the form fields and validate the user input:

const booleanMenuItems = [
      <MenuItem key = {0} value={ false } primaryText={"No"}></MenuItem>,
      <MenuItem key={1} value={true} primaryText={"Yes"}></MenuItem>
    ];


    const additionalEdiFields = this.props.ediAdditionalFields == null ? null : this.props.ediAdditionalFields.map(field =>
        {
            if(field.type == "string"){
                return <Field
                    key = {field.name}
                    name = {field.name}
                    component={ TextField }
                    floatingLabelText= {field.title}
                    floatingLabelStyle={ styles.floatingLabelStyle }
                    style={styles.extraFields}
                >
                </Field>
            }
            if(field.type == "boolean"){
                return <Field
                    key = {field.name}
                    name = {field.name}
                    component = {SelectField}
                    floatingLabelText= {field.title}
                    floatingLabelStyle={ styles.floatingLabelStyle }
                    style={styles.extraFields}
                >
                    {booleanMenuItems}
                </Field>
            }
        }
    );


const validate = (values, state) => {

  const errors = {};

  let additionalEdiFields = state.ediAdditionalFields == null? [] : state.ediAdditionalFields.map((extraField) => {
      return extraField;
  });
  const requiredFields = [
    {name: "legalEntityId", length: 32, title: "Legal Entity Id", type: "string", required: true},
    {name: "stateCode", length: 100, title: "State", type: "string", required: true},
    {name: "filingFormName", length: 100, title: "Return", type: "string", required: true},
    {name: "filingFrequencyId", length: 100, title: "Filing Frequency", type: "string", required: true},
    {name: "dueDayOfFilingPeriod", length: 100, title: "Due Date", type: "string", required: true},
    {name: "defaultAssignedTo", length: 100, title: "Assigned To", type: "string", required: true},
    {name: "filingType", length: 100, title: "Filing Type", type: "string", required: true},
    {name: "paymentType", length: 100, title: "Prepayments", type: "string", required: true},
    {name: "effectiveDateMonth", length: 2, title: "Effective Month", type: "string", required: true},
    {name: "effectiveDateYear", length: 4, title: "Effective Year", type: "string", required: true},
    {name: "hasNoExpirationDate", length: 20, title: "Has No Expiration Date", type: "string", required: true}
  ];

  let allFields = additionalEdiFields.concat(requiredFields);

    allFields.forEach((field) => {
        if(field != undefined) {
            if (!values[field.name]) {
                if (field.required == true) {
                    if (field.name === 'hasNoExpirationDate' && !values.expirationDateMonth) {
                        errors.expirationDateMonth = 'Required';
                    }
                    if (field.name === 'hasNoExpirationDate' && !values.expirationDateYear) {
                        errors.expirationDateYear = 'Required';
                    }
                    if (field.name !== 'hasNoExpirationDate' && field.type != "boolean") {
                        errors[field.name] = 'Required';
                    }
                }
            }
            if (values[field.name]) {
                if (values[field.name].length > field.length) {
                    errors[field.name] = 'Too Long';
                }
            }
        }
    });
    
    return errors
    };

When the form loads I want all the boolean fields to show 'No' in the select field by default, unless the user changes it to 'Yes'. As it currently stands, when the form is rendered, all the fields are blank. If the user doesn't put any input in at all for the boolean fields, they are still allowed to click save, which sends the value false for that field to the backend. enter image description here

As you can see, the 'Amended' field is set to 'No' which I manually entered. I want the form to load with that 'No' showing in the select field instead of a blank by default. My real aim, is to not allow this form from being saved unless the user has entered yes or no to one of those boolean fields. One work around is (and this is how my code was prior), I didn't have the boolean check on the last 'if' statement for the required fields: field.type != "boolean"

When I omit this part of the code, the user cant save the form without selecting yes or no, otherwise that field would get highlighted in red with the word required under it (look at the field Transmission Batch ID which I left blank and tried to save). However, when this is the case, selecting 'No' does not work. The system gives me the required error, even though the input 'No' is selected. Hence why I added the if statement. But now, they can omit an input into that field all together. Although it would still successfully pass 'No' or false to the backend, I cant have that functionality from a product standpoint.

I need one of two solutions:

  1. Load the page showing 'No' on those fields (even if its just text or a visual thing with css. The value can still be blank which will pass false anyway, which is why I want it to show 'No'). Side note: if I save the field field with no input. Then enter the edit panel for that form, 'No' is showing as the previous user input when the page loads. This is because it is reading the state of the previous user input. Maybe there is a way to populate that state on the initial creation of the form, but the fields are dynamic. Maybe resorting to a hard coded list of all the possible boolean fields of the 80 possible fields is the only way to go, but I would like to avoid this approach.

or

  1. Remove the if statement, make the field required, but allow 'No' to be passed instead of having the form read that as no input. (I believe since booleans are initialized to false by default to the redux values, it is reading the 'No' as no value and saying its required, but not 100% sure on this). I am also open to other solutions that aren't one of these two, as long as my aim above is met.

Solution

  • can you add a variable to the state with the value : false and on render pass it to field and add in the field component value ={this.state.chosenvarname} onChange(e) = > {setstate({chosenvarName = e.value)} something like that