Swiftpack.co - samuraime/ReactiveForm as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by samuraime.
samuraime/ReactiveForm v0.1.0
A reactive form that works with SwiftUI.
⭐️ 3
🕓 2 weeks ago
iOS macOS tvOS
.package(url: "https://github.com/samuraime/ReactiveForm.git", from: "v0.1.0")

ReactiveForm

Main workflow codecov

A reactive form that works with SwiftUI and takes advantage of Combine. Just grabbed great ideas from Reactive forms of Angular.

Install

Add the following to Package.swift:

.package(url: "https://github.com/samuraime/ReactiveForm", from: "0.1.0")

Or add the package in Xcode.

Usage

Creating a form model

You can build a form using ObservableForm and FormControl.

import ReactiveForm

class ProfileForm: ObservableForm {
  var name = FormControl("", validators: [.required])
  var email = FormControl("", validators: [.required, .email])
}

Working with SwiftUI

import SwiftUI

struct ContentView: View {
  @StateObject var form = ProfileForm()

  var body: some View {
    Form {
      TextField("Name", text: $form.name.value)
      if form.name.isDirty && form.name.errors[.required] {
        Text("Please fill a name.")
          .foregroundColor(.red)
      }
      TextField("Email", text: $form.email.value)
      if form.email.isDirty && form.email.errors[.email] {
        Text("Please fill a valid email.")
          .foregroundColor(.red)
      }
      Button(action: submit) {
        Text("Submit")
      }
      .disabled(form.isInvalid)
    }
  }

  func submit() {
    print(form)
  }
}

Validating manually

You might think that performing validation every time the value changes is a bit too frequent. You can also perform validation manually at different times, such as blur of a text field or submit of a form.

Here is an example for validating on submit.

It binds pendingValue of a form control to TextField instead of value and performs updateValueAndValidity on submit.

import SwiftUI

struct ContentView: View {
  @StateObject var form = ProfileForm()

  var body: some View {
    Form {
      TextField("Name", text: $form.name.pendingValue)
      if form.name.errors[.required] {
        Text("Please fill a name.")
          .foregroundColor(.red)
      }
      TextField("Email", text: $form.email.pendingValue)
      if form.email.errors[.email] {
        Text("Please fill a valid email.")
          .foregroundColor(.red)
      }
      Button(action: submit) {
        Text("Submit")
      }
    }
  }

  func submit() {
    form.updateValueAndValidity()
    if form.isValid {
      print(form)
    }
  }
}

@FormField

Additionally, there is @FormField for the fans of property wrapper. Its projectedValue is just FormControl. The code in View is a little bit different from the example above. Please note the position of $.

import SwiftUI
import ReactiveForm

class ProfileForm: ObservableForm {
  @FormField(validators: [.required])
  var name = ""
  
  @FormField(validators: [.required, .email])
  var email = ""
}

struct ContentView: View {
  @StateObject var form = ProfileForm()

  var body: some View {
    Form {
      TextField("Name", text: $form.firstName)
      if form.$name.errors[.required] {
        Text("Please fill a name.")
          .foregroundColor(.red)
      }
      TextField("Email", text: $form.email)
      if form.$email.errors[.email] {
        Text("Please fill a valid email")
          .foregroundColor(.red)
      }
    }
  }
}

Documentation

Netlify Status

The APIs are written by DocC, you can build it in your Xcode or see the online version.

License

MIT

GitHub

link
Stars: 3
Last commit: 2 weeks ago
jonrohan Something's broken? Yell at me @ptrpavlik. Praise and feedback (and money) is also welcome.

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics