From 813c54e9d801abdfabaed4836457e3be992fc11d Mon Sep 17 00:00:00 2001 From: Peter Murphy Date: Thu, 7 Jun 2018 08:40:23 -0700 Subject: [PATCH 01/15] Updating readme files --- .../website/src/examples/form/form_docs.md | 191 +++++++++++++----- .../website/src/guides/getting_started.md | 2 +- 2 files changed, 137 insertions(+), 56 deletions(-) diff --git a/packages/website/src/examples/form/form_docs.md b/packages/website/src/examples/form/form_docs.md index e3623dc..f4a12d7 100644 --- a/packages/website/src/examples/form/form_docs.md +++ b/packages/website/src/examples/form/form_docs.md @@ -1,83 +1,164 @@ ### Forms example -The forms library is designed to help you build a complete form. In this example -we create a simple contacts form. There are other examples too of forms which change -their structure as the user interacts with tham, as well as demostrating the use -of lists within the forms. But here we keep it relatively simple. +The forms library is designed to help you build a complete form, rather than use the individual controls by themselves. In this example we create a simple contacts form. -**What do we want from our form?** +See other examples for forms which change their structure as the user interacts with them, as well as demonstrating the use of lists within the forms. But here we keep it relatively simple. -Essentially we want to provide perhaps some initial data, our form `"value"`, -defaults in the case of a new form, or maybe our current -database state in the case of editing an existing entity. +#### Form requirements + +Let's first look at what we need for our form. + +To begin with we want to provide some initial data, our form `"value"` which may be defaults in the case of a new form, or our current database state in the case of editing an existing entity. As the user edits the data, we'll want to track that. We may choose to save it on submit (if it's a new form, that's likely), or save it as the user edits it -(perhaps if they are using inline editing we might -want to save the data when any fields are changed). Either way, the forms library -allows you to provide a callback function, which will be called whenever the values -in the form change. How you want to respond to that is up to you, but this example -demostrates one possible approach. +(perhaps if they are using inline editing we might want to save the data when any fields are changed). This depends on your requirements. Either way, the forms library allows you to provide a callback function, which will be called whenever the values in the form change. How you want to respond to that is up to you, but this example demonstrates one possible approach. In addition to knowing that the form values have changed, we also need to know if the form has any errors or missing fields. We do this via callbacks as well, where -each callback will tell you the number of missing or empty fields that exist within -the form. You can use that to control if the user can submit the form or not, as -we do in this example. +each callback will tell you the number of missing or empty fields that exist within the form. You can use that to control if the user can submit the form or not, as we do in this example. -Okay, so we have initial values and we have some callbacks. +Okay, so we have initial values and we have some callbacks. Now to build a form. -**How do we get a form up and running to use those?** +#### Building the form -Forms have two concerns. Each form has a schema which we use to provide the meta -data for fields within the form. This includes UI elements like the label for each -fields, the placeholder text, etc, but also rules around the field itself. For -example a field (called an Field in this library), +Forms have two concerns. Each form has a `Schema` which we use to provide the meta +data for fields within the form. This includes UI elements like the `label` for each fields, the `placeholder` text, etc, but also validation rules around the field itself. -The form elements are defined by a **schema**. Schemas can be defined with JSX or manually. Here's the schema used in this page: +Schemas can be defined with JSX or manually. Here's the schema used in this page: - const schema = ( - - - - - +```js +const schema = ( + + + + + - - ); + +); +``` -As you can see the schema is used to associate the Field name (`"first_name"` for example) with some properties which define how it looks and what is a valid value for that Field. Here we define a label (`"First name"`), a placeholder text, and some validation properties. Required can be set true to have the form track that this Field field needs to be filled out before the form is submitted. More on errors and missing value counts below. In addition to being required or not, the Field can have a validation prop set which will be passed to Revalidator for field validation while the user interacts with the form. It is most common to use it to specify the type (`"string", "integer", or "number"`), but you can also specify a format, such as in the example above where the email Field is checked to make sure it is a valid email address. Maximum string lengths, or ranges of numeric values can also be specified. For full details see the [Revalidator website](https://github.com/flatiron/revalidator). +As you can see the schema is used to associate the `Field` `name` (`"first_name"` for example) with some properties which define how it looks and what is a valid value for that Field. -Rendering is not automatic. Instead the form itself is a React component that you define. We define the form itself like this: +Here, for each field, we define: + * a `label` text + * a `placeholder` text + * a `validation` properties + * a `required` flag + + Some quick notes on these: firstly, `required` can be set `true` to have the form track that this field needs to be filled out before the form is submitted (More on errors and missing value counts below.) Secondly, in addition to being required or not, the `Field` can have a `validation` prop set which will be passed to the Revalidator library for field validation while the user interacts with the form. It is most common to use it to specify the type ("string", "integer", or "number"), but you can also specify a format, such as in the example above where the `email` field is checked to make sure it is a valid email address. Maximum string lengths, or ranges of numeric values can also be specified. For full details see the [Revalidator website](https://github.com/flatiron/revalidator). - class ContactForm extends React.Component { +Now that we have a schema we should have a form. Not so much. This library separates the presentation of the form from the schema. This fits in with React as you can use regular React `render()` code to render the form but with the addition that when you render a control you refer to the field name in the schema. - } +So, the form itself is a regular React component that you define. We define the form itself like this: -And then implement the form layout like this: - - renderForm() { - const disableSubmit = this.hasErrors(); - return ( -
- - - - -
- - - ); +```js + class ContactForm extends React.Component { + render() { + return ( + ... + ) + } } +``` + +And then implement the form `render()` like this: + +```js +render() { + const disableSubmit = this.hasErrors(); + return ( + return ( +
this.handleChange(formName, value)} + onMissingCountChange={(fieldName, missing) => + this.setState({ hasMissing: missing > 0 })} + onErrorCountChange={(fieldName, errors) => + this.setState({ hasErrors: errors > 0 })} + > + + + + { + return ( + + {value} + + ); + }} + /> + + + + this.setState({ tagList })} + width={400} + /> +