Skip to content

Commit

Permalink
Update README.
Browse files Browse the repository at this point in the history
  • Loading branch information
nathan-osman committed Aug 15, 2018
1 parent 294eab6 commit 5455ebe
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 67 deletions.
109 changes: 42 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,100 +10,75 @@ This package provides an extremely simple method for parsing forms.

### Usage

Begin by creating a type to represent the inputs in your form:
Begin by importing the following packages:

```go
import (
"github.com/nathan-osman/ezforms"
"github.com/nathan-osman/ezforms/fields"
"github.com/nathan-osman/ezforms/validators"
)
```

#### Creating a Form

Now create a type to represent the inputs in your form:

```go
type RegistrationForm struct {
Name string
NumTickets int64
PayLater bool
Name *fields.String
Age *fields.Integer
AcceptLicense *fields.Boolean
}
```

Next, create validation methods for each field you wish to validate.
To simplify creation, add a function that initializes each field:

```go
func (r RegistrationForm) ValidateName(v string) error {
return ezform.IsNonZero(v)
func NewRegistrationForm() *RegistrationForm {
return &RegistrationForm{
Name: fields.NewString(&validators.NonEmpty{}),
Age: fields.NewInteger(),
AcceptLicense: fields.NewBoolean(&validators.Required{}),
}
}
```

Each validation method must conform to four requirements:
In the example above, the `NonEmpty` validator ensures that a non-empty string is provided for `Name` and the `Required` validator ensures that `AcceptLicense` is set to `true`.

- the name of the method must be `Validate[field]`
- the method must use a value receiver
- the method must accept a single parameter of the field's type
- the method return type must be an `error`
#### Writing HTML

The example validation method above ensures that `Name` has a non-zero value.

The HTML for this form might resemble the following:
The HTML for the form above would resemble the following:

```html
<form method="post">
<input type="text" placeholder="Name" name="Name"><br>
<input type="number" placeholder="# Tickets" name="NumTickets"><br>
<input type="checkbox" name="PayLater"> Pay Later
<input type="number" placeholder="Age" name="Age"><br>
<input type="checkbox" name="AcceptLicense"> Pay Later
<button type="submit">Submit</button>
</form>
```

To parse and validate the form, use the following code in the handler:

```go
f := &RegistrationForm{}
fieldErrs, err := ezform.Parse(r, f, nil)
```

The first return value is a map of field names to errors that were encountered during validation. This map will be empty if no errors were encountered. The second return value will indicate any internal errors that were encountered during parsing.

### Validators
#### Validating a Request

The example above introduced the `IsNonZero` validator, but there are others:

#### Contains

The `Contains` validator checks to see if the provided value is found within a slice or the keys of a map.
To validate a POST request against the form, use the `ezform.Validate()` function:

```go
validCountries := []string{
"Australia",
"Canada",
"Spain",
}

func (r RegistrationForm) ValidateCountry(v string) error {
return ezform.Contains(validCountries, v)
}
```

#### IsURL

The `IsURL` validator determines if the provided value is a valid URL:

```go
func (r RegistrationForm) ValidateWebsite(v string) error {
return ezform.IsURL(v)
func registrationPage(w http.ResponseWriter, r *http.Request) {
f := NewRegistrationForm()
if err := ezform.Validate(r, f); err {
if err == ezform.ErrInvalid {
// form contains invalid data
} else {
// internal error
}
}
//...
}
```

### Passing Parameters

Sometimes a validation method will need to access data from the scope invoking `Parse`. The third parameter to the function is used for this purpose:
After successful validation, each field will be set to the appropriate value from the request using the field's native type, which can be retrieved with the `Value()` method. For example, to retrieve the `Age` field from the example above:

```go
ezform.Parse(r, f, dbConn)
age := f.Age.Value()
```

The validation methods may include an optional second parameter in their signature. This parameter will be set to the value passed in `Parse`:

```go
func (r RegistrationForm) ValidateName(v string, dbConn *db.Conn) error {
if !dbConn.isNameUnique(v) {
return errors.New("username is already in use")
}
return nil
}
```

If more than one parameter must be passed, a `struct` should be used.
1 change: 1 addition & 0 deletions validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var (
)

// Validate parses request data and validates it against the provided form.
// The return value is set to ErrInvalid if the form fails validation.
func Validate(r *http.Request, v interface{}) error {
s := reflectr.Struct(v)
if !s.IsPtr() {
Expand Down

0 comments on commit 5455ebe

Please sign in to comment.