Skip to content

Instantly share code, notes, and snippets.

@yoshuawuyts
Created September 1, 2016 15:47
Show Gist options
  • Save yoshuawuyts/ab5beca3dcee9e28546f34b215e11e77 to your computer and use it in GitHub Desktop.
Save yoshuawuyts/ab5beca3dcee9e28546f34b215e11e77 to your computer and use it in GitHub Desktop.
const Validate = require('form-element/validate')
const State = require('form-element/state')
const Form = require('form-element')
const html = require('bel')
const fields = [
['credentials', [
['username', 'text', (str) => str.length < 20],
['password', 'password', (str) => str.length > 8 && str.length < 99]
]],
['address', [
['city', 'text'],
['street', 'text']
]]
]
// to validate async, check that all fields are not pristine and no errors,
// then send the formState off to the server and set corresponding errors
const validate = Validate(fields)
const state = State(fields)
// => {
// username: { pristine: true, error: null, data: '' },
// password: { pristine: true, error: null, data: '' },
// city: { pristine: true, error: null, data: '' },
// street: { pristine: true, error: null, data: '' }
// }
const model = {
namespace: 'form',
state: state,
reducers: { validate: validate }
}
formView.model = model
module.exports = formView
function formView (state, prev, send) {
const form = createForm(send)
return html`<section>${form(state.form)}</section>`
}
function createForm (formState, send) {
return Form(fields, formState, (newFormState) => {
send('form:validate', newFormState)
})
}
@yoshuawuyts
Copy link
Author

const Validate = require('form-element/validate')
const State = require('form-element/state')
const Form = require('form-element')
const html = require('bel')

const fields = [
  ['credentials', [
    ['username', 'text', (str) => str.length < 20],
    ['password', 'password', (str) => str.length > 8 && str.length < 99]
  ]],
  ['address', [
    ['city', 'text'],
    ['street', 'text']
  ]]
]

const model = {
  namespace: 'form',
  state: State(fields),
  reducers: { validate: Validate(fields) }
}

formView.model = model
module.exports = formView

function formView (state, prev, send) {
  const form = Form(fields, state.form, (newFormState) => {
    send('form:validate', newFormState)
  })

  return html`<section>${form}</section>`
}

@yoshuawuyts
Copy link
Author

need to be able to have named fields for things like placeholder and validator and stuff; we can build a model / stuff off that (:

@yoshuawuyts
Copy link
Author

The above wasn't flexible enough, and too slow. This should work better:

with comments

const Form = require('form-element')
const html = require('choo/html')

module.exports = formView

function formView (state, prev, send) {
  // here we create a new form based off our fields, local state and pass it a
  // callback that contains the form data. Form data has the format of:
  // => {
  //   username: { pristine: true, error: null, data: '' },
  //   password: { pristine: true, error: null, data: '' },
  //   city: { pristine: true, error: null, data: '' },
  //   street: { pristine: true, error: null, data: '' }
  // }
  // Each field gets its regex set on the form element itself. If an error is
  // triggered on the form el it fires an event. Internally it should probably
  // debounce to prevent event from flooding the handlers (e.g. every error
  // triggers both input and error by design), but that's an optimization.
  //
  // the Form constructor can take an optional third arg for options
  const form = Form(formFields, state.form, (formState) => {
    send('form:validate', formState)
  })

  return html`<section>${form}</section>`
}

// function that returns all fields as an array; which is needed so hyperx
// doesn't complain. The `form` argument allows us to create fancy constructor
// thingies; quite similar to how react-form works
// obj -> [obj]
function formFields (form) {
  return [
    html`
      <fieldset>
        ${form.text('username')}
        ${form.password('password')}
      </fieldset>
    `,
    html`
      <fieldset>
        ${form.text('city')}
        ${form.text('address')}
      </fieldset>
      ${form.submit('Send!')}
    `
  ]
}

without comments

const Form = require('form-element')
const html = require('choo/html')

module.exports = formView

function formView (state, prev, send) {
  const form = Form(formFields, state.form, (formState) => {
    send('form:validate', formState)
  })

  return html`<section>${form}</section>`
}

function formFields (form) {
  return [
    html`
      <fieldset>
        ${form.text('username')}
        ${form.password('password')}
      </fieldset>
    `,
    html`
      <fieldset>
        ${form.text('city')}
        ${form.text('address')}
      </fieldset>
      ${form.submit('Send!')}
    `
  ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment