Giter Club home page Giter Club logo

composeeasyforms's Introduction

build-status Maven Central

Compose EasyForms

Focus on building your form UI while the library do the heavy work for you.

Features

Built in support for most of the Form widgets in Compose

Examples

Initializing

EasyForms handles process death out of the box ๐Ÿ˜Ž.

@Composable
fun BuildMyAwesomeForm(
  onClick: (EasyForms) -> Unit,
) {
  Scaffold(
    ....
  ) {
    // BuildEasyForms fun provided by EasyForms
    BuildEasyForms { easyForm ->
      Column {
        // your Composables
        LoginButton(easyForms) { onClick(easyForms) }
      }
    }
  }
}
TextField

EasyForms provide some of the commom used textfields validation:

  • Email validation
@Composable
fun EmailTextField(easyForms: EasyForms) {
  val textFieldState = easyForms.getTextFieldState(
    key = MyFormKeys.EMAIL,
    easyFormsValidationType = EmailValidationType,
    defaultValue = "",
  )
  val state = textFieldState.state
  TextField(
    value = state.value,
    onValueChange = textFieldState.onValueChangedCallback,
    isError = textFieldState.errorState.value == EasyFormsErrorState.INVALID,
  )
}
  • Password validation
@Composable
fun PasswordTextField(easyForms: EasyForms) {
  val textFieldState = easyForms.getTextFieldState(
    key = MyFormKeys.PASSWORD,
    easyFormsValidationType = PasswordValidationType,
    defaultValue = "",
  )
  val state = textFieldState.state
  TextField(
    value = state.value,
    onValueChange = textFieldState.onValueChangedCallback,
    isError = textFieldState.errorState.value == EasyFormsErrorState.INVALID,
  )
}
  • Phone validation
@Composable
fun PhoneTextField(easyForms: EasyForms) {
  val textFieldState = easyForms.getTextFieldState(
    key = MyFormKeys.PHONE,
    easyFormsValidationType = PhoneValidationType,
    defaultValue = "",
  )
  val state = textFieldState.state
  TextField(
    value = state.value,
    onValueChange = textFieldState.onValueChangedCallback,
    isError = textFieldState.errorState.value == EasyFormsErrorState.INVALID,
  )
}
  • URL validation
@Composable
fun UrlTextField(easyForms: EasyForms) {
  val textFieldState = easyForms.getTextFieldState(
    key = MyFormKeys.URL,
    easyFormsValidationType = UrlValidationType,
    defaultValue = "",
  )
  val state = textFieldState.state
  TextField(
    value = state.value,
    onValueChange = textFieldState.onValueChangedCallback,
    isError = textFieldState.errorState.value == EasyFormsErrorState.INVALID,
  )
}
  • Name validation
@Composable
fun NameTextField(easyForms: EasyForms) {
  val textFieldState = easyForms.getTextFieldState(
    key = MyFormKeys.NAME,
    easyFormsValidationType = NameValidationType,
    defaultValue = "",
  )
  val state = textFieldState.state
  TextField(
    value = state.value,
    onValueChange = textFieldState.onValueChangedCallback,
    isError = textFieldState.errorState.value == EasyFormsErrorState.INVALID,
  )
}
  • Cards validation
@Composable
fun CardTextField(easyForms: EasyForms) {
  val textFieldState = easyForms.getTextFieldState(
    key = MyFormKeys.CARD,
    easyFormsValidationType = CardValidationType,
    defaultValue = "",
  )
  val state = textFieldState.state
  TextField(
    value = state.value,
    onValueChange = textFieldState.onValueChangedCallback,
    isError = textFieldState.errorState.value == EasyFormsErrorState.INVALID,
  )
}

Custom Validation:

  • You can provide your own validator for EasyForms to use, for example you could provide a custom regex only, a min and/or max length only or combine them all together and EasyForms will ensure the validity based on your configuration.
object MyCustomValidationType : EasyFormsValidationType(
  regex = "MyAwesomeRegex",
  minLength = 10,
  maxLength = 30,
)

object MyCustomRegexValidationType : EasyFormsValidationType(
  regex = "MyAwesomeRegex"
)

object MyCustomLengthValidationType : EasyFormsValidationType(
  minLength = 20,
  maxLength = 50,
)

To use your custom validation:

@Composable
fun MyTextField(easyForms: EasyForms) {
  val textFieldState = easyForms.getTextFieldState(MyFormKeys.MY_KEY, MyCustomValidationType)
  val state = textFieldState.state
  TextField(
    value = state.value,
    onValueChange = textFieldState.onValueChangedCallback,
    isError = textFieldState.errorState.value == EasyFormsErrorState.INVALID,
  )
}
Checkbox
@Composable
fun CheckboxLayout(easyForms: EasyForms) {
  val checkboxState = easyForms.getCheckboxState(
    MyFormKeys.CHECKBOX,
    defaultValue = false,
    isRequired = true,
  )
  val checkedState = checkboxState.state
  Checkbox(
    checked = checkedState.value,
    onCheckedChange = checkboxState.onValueChangedCallback,
  )
}
TriStateCheckbox
@Composable
fun TriCheckboxLayout(easyForms: EasyForms) {
  val checkboxState = easyForms.getTriCheckboxState(
    MyFormKeys.TRI_CHECKBOX,
    defaultValue = ToggleableState.Indeterminate,
    isRequired = true,
  )
  val checkedState = checkboxState.state
  TriStateCheckbox(
    state = checkedState.value,
    onClick = checkboxState.onClick,
  )
}
RadioButton
@Composable
fun RadioButtonLayout(easyForms: EasyForms) {
  val radioButtonState = easyForms.getRadioButtonState(
    MyFormKeys.RADIO_BUTTON,
    defaultValue = false,
    isRequired = true,
  )
  val checkedState = radioButtonState.state
  RadioButton(
    state = checkedState.value,
    onClick = radioButtonState.onClick,
  )
}
Switch
@Composable
fun SwitchLayout(easyForms: EasyForms) {
  val switchState = easyForms.getSwitchState(
    MyFormKeys.SWITCH,
    defaultValue = false,
    isRequired = true,
  )
  val checkedState = switchState.state
  Checkbox(
    checked = checkedState.value,
    onCheckedChange = switchState.onValueChangedCallback,
  )
}
Slider
@Composable
fun SliderLayout(easyForms: EasyForms) {
  val state = easyForms.getSliderState(
    key = MyFormKeys.SLIDER,
    defaultValue = 0F,
    isRequired = true,
  )
  val sliderPosition = state.state
  Slider(
    value = sliderPosition.value,
    onValueChange = state.onValueChangedCallback,
    onValueChangeFinished = state.onValueChangeFinished,
  )
}
RangeSlider
@Composable
fun RangeSliderLayout(easyForms: EasyForms) {
  val state = easyForms.getRangeSliderState(
    key = MyFormKeys.RANGE_SLIDER,
    defaultValue = 0F..0F,
    isRequired = true
  )
  val sliderPosition = state.state
  RangeSlider(
    value = sliderPosition.value,
    onValueChange = state.onValueChangedCallback,
    onValueChangeFinished = state.onValueChangeFinished,
  )
}
CustomState

You can use one of the already defined EasyFormsState for most cases, however when you need something that EasyFormsState doesn't provide then you could simply create your own. Please follow this link for more details.

ObserveState
@Composable
fun LoginButton(
  easyForms: EasyForms,
  onClick: () -> Unit,
) {
  val errorStates = easyForms.observeFormStates()
  Button(
    onClick = onClick,
    modifier = Modifier.fillMaxWidth(),
    enabled = errorStates.value.all {
      it.value == EasyFormsErrorState.VALID
    }
  ) {
    Text("Submit")
  }
}

For more example please refer to the example app.

VideoEditor_20210921_094725.mp4

Download Maven Central

repositories {
  mavenCentral()
}

dependencies {
  implementation("com.github.k0shk0sh:compose-easyforms:<version>")
}

Contributions

Please contribute! We will gladly review any pull requests. Make sure to read the Contributing page first though.

composeeasyforms's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

mhmonicox paul75

composeeasyforms's Issues

Display error only when use unfocus textfield

Discussed in #9

Originally posted by nachtien September 21, 2021
Are there any plans to handle onFocusChange at all? It's weird to have an error state when someone is typing text into the field.

Add ability to look at form level if my form is invalid

Is your feature request related to a problem? Please describe.
Say you have a button on your form that you wish to have disabled until the associated form is considered valid by EasyForms, right now you have to check, every field's validation state. Which form a form as simple as a login form that's fine but for more complexed forms it can get a bit ugly ๐Ÿ™ˆ

Describe the solution you'd like
It could be as simple as a method form.isValid() or a computed property form.isValid. It would look across a form and all of its field's errorState objects to ensure they are all valid.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.