0.7.178 • Published 1 year ago

@rxdi/forms v0.7.178

Weekly downloads
121
License
MIT
Repository
github
Last release
1 year ago

Reactive forms binding for LitHtml

Install

npm i @rxdi/forms

Using it inside component

Important!

Define <form> element with name <form name"my-form"></form>

Put my-form inside @Form({ name: 'my-form' }) decorator since this will be our form selector

import { html, Component } from '@rxdi/lit-html';
import { FormGroup, Form } from '@rxdi/forms';
import { BaseComponent } from '../shared/base.component';

/**
 * @customElement login-component
 */
@Component({
  selector: 'login-component',
  template(this: LoginComponent) {
    return html`
      <form name="my-form" @submit=${this.onSubmit}>
        <input
          style="margin-bottom: 20px;"
          name="email"
          type="email"
          value=${this.form.value.email}
          placeholder="Email address"
          required
          autofocus
        />
        <input
          type="password"
          value=${this.form.value.password}
          name="password"
          placeholder="Password"
          required=""
        />
        <div>
          <label>
            <input name="rememberMe" type="checkbox" /> Remember me
          </label>
        </div>
        <button type="submit">
          Sign in
        </button>
      </form>
    `;
  }
})
export class LoginComponent extends BaseComponent {
  @Form({
    strategy: 'change',
    name: 'my-form'
  })
  private form = new FormGroup({
    password: '',
    email: '',
    rememberMe: ''
  });

  OnInit() {
    this.form.valueChanges.subscribe(values => {
      values; // password, email, rememberMe
    });
    this.form.getValue('password');
    this.form.setValue('email', 'blabla');
  }

  onSubmit(event: Event) {
    this.form.values;
  }
}

Error handling and validators

import { html, Component } from '@rxdi/lit-html';
import { FormGroup, Form } from '@rxdi/forms';
import { BaseComponent } from '../shared/base.component';

/**
 * @customElement login-component
 */
@Component({
  selector: 'login-component',
  template(this: LoginComponent) {
    return html`
      <form name="my-form" @submit=${this.onSubmit}>
        <input
          style="margin-bottom: 20px;"
          name="email"
          type="email"
          placeholder="Email address"
          required
          autofocus
        />
        ${this.form.hasError('email', 'blabla') ? html`${this.form.getError('email', 'blabla')}` : ''}
        <input
          type="password"
          name="password"
          placeholder="Password"
          required=""
        />
        <div>
          <label>
            <input name="rememberMe" type="checkbox" /> Remember me
          </label>
        </div>
        <button type="submit">
          Sign in
        </button>
      </form>
    `;
  }
})
export class LoginComponent extends BaseComponent {
  @Form({
    strategy: 'change',
    name: 'my-form'
  })
  private form = new FormGroup({
    password: '',
    email: ['', [this.validateEmail]],
    rememberMe: ''
  });

  OnUpdate() {
    this.form.getValue('password');
    this.form.setValue('email', 'blabla');

    this.form.get('password'); // returns HTMLIntputElement
    this.form.hasError('email', 'blabla')
  }

  onSubmit(event: Event) {
    this.form.values;
  }

  validateEmail(element: HTMLInputElement) {
    if (element.value === 'restrictedEmail@gmail.com') {
      return { key: 'blabla', message: 'Please specify different email'};
    }
  }
}

Group multiple inputs with single check intaraction

By default all inputs with same attribute name are binded together,

  @Form({
    strategy: 'change',
    name: 'my-form'
  })
  private form = new FormGroup({
    condition: ''
  });
<label>
  <input
    name="condition"
    type="checkbox"
    value='none'
  />
  None
</label>

<label>
  <input
    name="condition"
    type="checkbox"
    value='checked'
  />
  Checked
</label>

<label>
  <input
    name="condition"
    type="checkbox"
    value='not-checked'
  />
  Not checked
</label>

Group multiple inputs with multi check intaraction

To remove binding we can set multi: false when defining our form

  @Form({
    strategy: 'change',
    name: 'my-form',
    multi: false
  })
  private form = new FormGroup({
    condition: ''
  });

Native browser errors

By default this library uses native error messages provided by HTML5 form validation API

You can create your error template as follow:

import { html } from '@rxdi/lit-html';

export function InputErrorTemplate(input: HTMLInputElement) {
  if (input && !input.checkValidity()) {
    return html`
      <div>${input.validationMessage}</div>
    `;
  }
  return '';
}

Usage

<form>
  <input
    name="email"
    type="email"
    value=${this.form.value.email}
    class="form-control"
    placeholder="Email address"
    required
    autofocus
  />
  ${InputErrorTemplate(this.form.get('email'))}
</form>
Native HTML with JS
import { FormGroup } from '@rxdi/forms';

export function EmailValidator(element: HTMLInputElement) {
  const regex = /^([a-zA-Z0-9_\.\-]+)@([a-zA-Z0-9_\.\-]+)\.([a-zA-Z]{2,5})$/;
  if (!regex.test(element.value)) {
    element.classList.add('is-invalid');
    return {
      key: 'email-validator',
      message: 'Email is not valid'
    };
  }
  element.classList.remove('is-invalid');
}

const form = new FormGroup({
  email: ['', [EmailValidator]],
  password: '',
});

form
  .setParentElement(document.body)
  .setOptions({ name: 'my-form' })
  .prepareValues()
  .setFormElement(form.querySelectForm(document.body))
  .setInputs(form.mapEventToInputs(form.querySelectorAllInputs()));
<form name="my-form">
  <input
    name="email"
    type="email"
    placeholder="Email address"
    required
    autofocus
  />
  <input
    name="password"
    type="password"
    required
  />
</form>
<script src="./main.ts"></script>
0.7.176

1 year ago

0.7.175

1 year ago

0.7.178

1 year ago

0.7.177

1 year ago

0.7.174

2 years ago

0.7.173

2 years ago

0.7.170

2 years ago

0.7.172

2 years ago

0.7.171

2 years ago

0.7.169

2 years ago

0.7.167

2 years ago

0.7.168

2 years ago

0.7.163

2 years ago

0.7.162

2 years ago

0.7.165

2 years ago

0.7.164

2 years ago

0.7.166

2 years ago

0.7.161

2 years ago

0.7.160

2 years ago

0.7.159

3 years ago

0.7.158

3 years ago

0.7.157

3 years ago

0.7.152

3 years ago

0.7.154

3 years ago

0.7.153

3 years ago

0.7.156

3 years ago

0.7.155

3 years ago

0.7.151

3 years ago

0.7.150

3 years ago

0.7.149

3 years ago

0.7.148

3 years ago

0.7.147

3 years ago

0.7.141

3 years ago

0.7.140

3 years ago

0.7.143

3 years ago

0.7.142

3 years ago

0.7.145

3 years ago

0.7.144

3 years ago

0.7.146

3 years ago

0.7.138

3 years ago

0.7.137

3 years ago

0.7.139

3 years ago

0.7.136

4 years ago

0.7.135

4 years ago

0.7.121

4 years ago

0.7.120

4 years ago

0.7.123

4 years ago

0.7.122

4 years ago

0.7.125

4 years ago

0.7.124

4 years ago

0.7.130

4 years ago

0.7.132

4 years ago

0.7.131

4 years ago

0.7.134

4 years ago

0.7.133

4 years ago

0.7.127

4 years ago

0.7.126

4 years ago

0.7.129

4 years ago

0.7.128

4 years ago

0.7.118

4 years ago

0.7.119

4 years ago

0.7.116

4 years ago

0.7.117

4 years ago

0.7.115

4 years ago

0.7.114

4 years ago

0.7.113

4 years ago

0.7.112

4 years ago

0.7.111

4 years ago

0.7.110

4 years ago

0.7.109

4 years ago

0.7.108

4 years ago

0.7.107

4 years ago

0.7.101

4 years ago

0.7.103

4 years ago

0.7.102

4 years ago

0.7.105

4 years ago

0.7.104

4 years ago

0.7.106

4 years ago

0.7.100

4 years ago

0.7.99

4 years ago

0.7.98

4 years ago

0.7.97

4 years ago

0.7.95

4 years ago

0.7.94

4 years ago

0.7.96

4 years ago

0.7.93

5 years ago

0.7.91

5 years ago

0.7.92

5 years ago

0.7.90

5 years ago

0.7.88

5 years ago

0.7.89

5 years ago

0.7.87

5 years ago

0.7.86

5 years ago

0.7.85

5 years ago

0.7.84

5 years ago

0.7.83

5 years ago

0.7.82

5 years ago

0.7.81

5 years ago

0.7.80

5 years ago

0.7.79

5 years ago

0.7.78

5 years ago

0.7.77

5 years ago

0.7.76

5 years ago

0.7.75

5 years ago

0.7.73

5 years ago

0.7.72

5 years ago

0.7.74

5 years ago

0.7.71

5 years ago

0.7.70

5 years ago

0.7.69

5 years ago

0.7.68

5 years ago

0.7.67

5 years ago

0.7.66

5 years ago

0.7.63

5 years ago

0.7.62

5 years ago

0.7.61

5 years ago

0.7.60

5 years ago

0.7.57

5 years ago

0.7.56

5 years ago

0.7.59

5 years ago

0.7.58

5 years ago

0.7.53

5 years ago

0.7.52

5 years ago

0.7.51

5 years ago

0.7.50

5 years ago

0.7.48

5 years ago

0.7.49

5 years ago

0.7.46

5 years ago

0.7.47

5 years ago

0.7.38

6 years ago

0.7.37

6 years ago

0.7.36

6 years ago

0.7.35

6 years ago

0.7.34

6 years ago

0.7.33

6 years ago

0.7.32

6 years ago

0.7.31

6 years ago

0.7.30

6 years ago

0.7.29

6 years ago

0.7.28

6 years ago

0.7.27

6 years ago

0.7.26

6 years ago

0.7.25

6 years ago

0.7.24

6 years ago

0.7.23

6 years ago

0.7.22

6 years ago

0.7.21

6 years ago

0.7.20

6 years ago

0.7.19

6 years ago

0.7.18

6 years ago

0.7.17

6 years ago

0.7.16

6 years ago

0.7.15

6 years ago

0.7.14

6 years ago

0.7.13

6 years ago

0.7.12

6 years ago

0.7.11

6 years ago

0.7.10

6 years ago

0.7.9

6 years ago

0.7.8

6 years ago

0.7.7

6 years ago

0.7.6

6 years ago

0.7.5

6 years ago

0.7.4

6 years ago

0.7.3

6 years ago

0.7.2

6 years ago

0.7.1

6 years ago

0.6.13

6 years ago

0.6.12

6 years ago

0.6.11

6 years ago

0.6.10

6 years ago

0.7.0

6 years ago

0.6.9

6 years ago

0.6.8

6 years ago

0.6.7

6 years ago

0.6.6

6 years ago

0.6.5

6 years ago