final-form / final-form

🏁 Framework agnostic, high performance, subscription-based form state management

Home Page:https://final-form.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Object doesn't support property or method 'values' in IE11

maxdev opened this issue · comments

Hi,

We use final-form and react-final-form in our project. But seems it not works in IE11.
Browser throws this error in console: SCRIPT438 Object doesn't support property or method 'values'

I found, that the issue in this part of final-form code:

Object.values(dirtyFieldsSinceLastSubmit).some(value => value)

Is there any solution how to fix it?

you need the Object.values polyfill, here is all the polyfills needed for IE11 : https://polyfill.io/v3/polyfill.min.js?features=Array.from%2CPromise%2CObject.values

here is my full example working on IE11 :

<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'>
  <meta http-equiv='X-UA-Compatible' content='IE=edge'>
  <title>Final Form - IE11</title>
  <meta name='viewport' content='width=device-width, initial-scale=1'>
  <script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from%2CPromise%2CObject.values"></script>
</head>

<body>

  <style>
    body {
      font-family: sans-serif;
    }

    form {
      max-width: 600px;
      margin: 10px auto;
      border: 1px solid #ccc;
      border-radius: 3px;
      box-shadow: 1 1 2px rgba(0, 0, 0, 0.3);
      padding: 10px;
      display: flex;
      flex-flow: column nowrap;
    }

    h1 {
      text-align: center;
      color: #333;
    }

    p {
      margin: 10px auto;
      line-height: 1.2em;
      max-width: 500px;
    }

    div {
      margin: 10px;
      display: flex;
      flex-flow: row nowrap;
      justify-content: center;
    }

    label {
      width: 120px;
      text-align: right;
      margin-right: 15px;
      padding: 5px;
    }

    input {
      padding: 5px;
      flex: 1;
      border: 1px solid #ccc;
      border-radius: 3px;
    }

    select {
      flex: 1;
      height: 24px;
      border: 1px solid #ccc;
      border-radius: 3px;
    }

    span {
      color: #600;
      font-weight: bold;
      margin: 0 0 0 10px;
      line-height: 26px;
    }

    button {
      width: 80px;
      display: block;
    }

    button + button {
      margin-left: 10px;
    }
  </style>

  <form id="form">
    <h1>
      🏁 Final Form - Vanilla JS Demo
    </h1>
    <p>
      Uses record level validation. Errors don't show up until a field is
      "touched" or a submit is attempted. Errors disappear immediately as the
      user types.
    </p>
    <div>
      <label>First Name</label>
      <input type="text" name="firstName" placeholder="First Name" />
      <span id="firstName_error"></span>
    </div>
    <div>
      <label>Last Name</label>
      <input type="text" name="lastName" placeholder="Last Name" />
      <span id="lastName_error"></span>
    </div>
    <div>
      <label>Favorite Color</label>
      <select name="color">
        <option value="#FF0000">Red</option>
        <option value="#00FF00">Green</option>
        <option value="#0000FF">Blue</option>
      </select>
      <span id="color_error"></span>
    </div>
    <div>
      <label>Employed?</label>
      <input type="checkbox" name="employed" />
      <span id="employed_error"></span>
    </div>
    <div>
      <button type="submit">Submit</button>
      <button type="button" id="reset">Reset</button>
    </div>
  </form>

  <script src="https://cdn.jsdelivr.net/npm/final-form@4.20.1/dist/final-form.umd.js"></script>

  <script>

    function onSubmit(values) {
      window.alert(JSON.stringify(values, undefined, 2))
    }

    function validate(values) {
      console.log('validate')
      const errors = {}
      if (!values.firstName) {
        errors.firstName = 'Required'
      }
      if (!values.lastName) {
        errors.lastName = 'Required'
      }
      if (values.color === '#00FF00') {
        errors.color = 'Gross! Not green! 🤮'
      }
      return errors
    }

    const form = window['final-form'].createForm({
      onSubmit: onSubmit,
      initialValues: {
        color: '#0000FF'
      },
      validate: validate
    })

    document.getElementById('form').addEventListener('submit', function (event) {
      event.preventDefault()
      form.submit()
    })
    document.getElementById('reset').addEventListener('click', function () { form.reset() })

    const registered = {}

    function onChange(fieldState, input) {
      console.log('on change', input, fieldState)
      const name = input.name
      const errorElement = document.getElementById(name + '_error')
      if (!registered[name]) {
        // first time, register event listeners
        input.addEventListener('blur', function () { fieldState.blur() })
        input.addEventListener('input', function (event) {
          fieldState.change(
            input.type === 'checkbox'
              ? event.target.checked
              : event.target.value
          )
        })
        input.addEventListener('focus', function () { fieldState.focus() })
        registered[name] = true
      }

      // update value
      if (input.type === 'checkbox') {
        input.checked = fieldState.value
      } else {
        input.value = fieldState.value === undefined ? '' : fieldState.value
      }

      // show/hide errors
      if (errorElement) {
        if (fieldState.touched && fieldState.error) {
          errorElement.innerHTML = fieldState.error
          errorElement.style.display = 'block'
        } else {
          errorElement.innerHTML = ''
          errorElement.style.display = 'none'
        }
      }
    }

    function registerField(input) {
      console.log('register', input.name)
      form.registerField(
        input.name,
        function (fieldState) { onChange(fieldState, input) },
        {
          value: true,
          error: true,
          touched: true
        }
      )
    }

    Array.from(document.forms[0]).forEach(function (input) {
      if (input.name) {
        registerField(input)
      }
    })
  </script>
</body>

</html>

also duplicate of #316

IE11 is irrelevant in 2023. If you need/want to support it add your own polyfill as suggested in #316