Skip to content

Latest commit

 

History

History
582 lines (521 loc) · 14.8 KB

Field.md

File metadata and controls

582 lines (521 loc) · 14.8 KB

<Field />

import { Field } from 'vue-controlled-form-fields';

Field is a reactive and subscription-based, injector and also provider. Field can be used in 3 different ways.

Usage

1. Native components

<c-form :submit="onSubmit">
    <div>
      <label>Simple Default Input</label>
      <field
        :validate="required"
        name="user.name"
        component="input"
        type="text"
        placeholder="username"
      />
    </div>
    <div>
      <label>Boolean Checkbox</label>
      <field name="vegetarian" component="checkbox" />
    </div>
    <div>
      <label
        >Multi Checkboxes (The value will be array of selected
        checkboxes)</label
      >
      <field
        name="foods"
        component="input"
        type="checkbox"
        value="chicken 🐥"
      />
      <field
        name="foods"
        component="input"
        type="checkbox"
        value="Fesenjoon 🥜"
      />
      <field
        name="foods"
        component="input"
        type="checkbox"
        value="Ghormesabzi 😍"
      />
      <field name="foods" component="input" type="checkbox" value="Gheyme 🐄" />
    </div>
    <div>
      <label>Radio</label>
      <field name="gender" component="input" type="radio" value="male 👨‍💼" />
      <field name="gender" component="input" type="radio" value="female 👩‍🔧" />
    </div>
    <div>
      <label>Select</label>
      <field component="select" name="country">
        <option>select</option>
        <option value="australia">Australia</option>
        <option value="canada">Canada</option>
        <option value="usa">USA</option>
      </field>
    </div>
    <div>
      <label>Multiple select</label>
      <field component="select" name="nationality" multiple>
        <option>select</option>
        <option value="australia">Australia</option>
        <option value="canada">Canada</option>
        <option value="usa">USA</option>
      </field>
    </div>
    <div>
      <label>Textarea</label>
      <field component="story" name="subject" placeholder="Write something.." />
    </div>
</c-form>

For showing validation errors you can use form's state using slot-scope, like this:

<c-form>
	<div slot-scope="{ errors, visitedFields }">
	   <div>
          <label>Simple Default Input</label>
          <field
          	:validate="required"
            name="user.name"
            component="input"
            type="text"
            placeholder="username"
          />
          <span v-if="errors.user.name && visitedFields['user.name']">
          	{{ errors.user.name }}
          </span>
      </div>
    </div>
</c-form>

2. Custom Native components

You can create your own native components. You can access to field state using slot-scope="fieldState".

 <c-form>
    <div slot-scope="{ errors, visitedFields }">
      <div>
        <label>Simple Default Input</label>
        <field
          :validate="required"
          name="user.name"
          component="input"
          type="text"
          placeholder="username"
        />
        <span v-if="errors.user.name && visitedFields['user.name']">
          {{ errors.user.name }}
        </span>
      </div>
    </div>
</c-form>

2. Custom and reusable components

You can create reusable components in separate file, for accessing to field state in another component you need to use FieldStateMixin. By using this mixin you can access to field state inside your component context or in template. (this.field)

//**** InputText.vue *******
<template>
  <div>
    <label>
      {{ label }}
      <input
        :disabled="disabled"
        :type="type"
        :placeholder="placeholder"
        :value="field.value"
        v-on="field.events"
      />
      <span v-if="field.touched && field.error">{{ field.error }}</span>
    </label>
  </div>
</template>

<script>
import { FieldStateMixin } from 'vue-controlled-form-fields';

export default {
  mixins: [FieldStateMixin],
  props: {
    type: {
      type: String,
      default: 'text'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    label: {
      type: String,
      default: ''
    },
    placeholder: {
      type: String,
      default: ''
    }
  }
};
</script>

And then you can use it every where like this:

// In you form
<template>
  <c-form :submit="onSubmit">
    <field name="user.email" :validate="[required, email]">
      <input-text type="email" placeholder="email" />
    </field>
  </c-form>
</template>

<script>
import InputText from './InputText';

export default {
  components: {
    InputText
  }
};
</script>

You can also use third party libraries here. like antd or material design. You can find more examples here.

Field :props

Properties Type Default Example
name string required Link
name of the field. for having nested values you should use object notation. name="user.username"
validate Function or Array of Functions required Link
You can validate the field by passing function or array of functions. You can access to value of field in first argument and values of form in second argument. Based on your conditions if you return string the field will be invalid and the string will set to error property.
subscription { [string]: boolean } undefined Link
The field will only re-render when these properties in field state changes. Field state will only includes these properties. Could be useful for performance, If you pass nothing then everything will be subscribed.
allowNull boolean false Link
When you pass it true, If the value of field be empty string or undefined, null will be set to state.
component string undefined Link
Will create native inputs. You can also create them by your self but these are ready to use. Enum ['input', 'select', 'textarea']
type (only for native input) string undefined Link
When you want to use native inputs, You should pass type of the input. Enum ['checkbox', 'text', 'email', 'password', 'radio']
placeholder (only for native input) string undefined Link
placeholder of native input
value (only for native input) string, number, boolean, undefined undefined Link
Value of field, For radio, checkbox, select.
checkbox: If you have several checkboxes with different values, the value will be array of values which has been checked by user otherwise the values will be boolean (checked)
multiple (only for native select) boolean false Link
Will enable the multiple feature for native select. value of field will be array of selected options
disabled (only for native select) boolean false Link
Will disable the native input

Field {}State (field.meta)

Properties Type Example
name string Link
name of the field
value any Link
Current value of field. accessible from field.value or field.meta.value
meta.active boolean Link
Will be true when field has been focus (while user is interacting with field), Will be false when blur function triggered.
meta.dirty boolean Link
Will be true when the value of the field is not equal to the initial value.
meta.error string Link
When the validations has been ran the result will be set to this property. (error message)
meta.invalid boolean Link
Will be true when the error property has a value.
meta.valid boolean Link
Will be true when the error property has not a value.
meta.modified boolean Link
Will be true if this field's value has ever been changed. false otherwise.
meta.pristine boolean Link
true if the current value is equal to the same property in initial values, otherwise false.
meta.touched boolean Link
Will be true if the focus and blur events has been called before in field.
meta.visited boolean Link
Will be true if the focus event has been called before in field.

Field Methods() (field.events)

Properties Parameters Example
events.change or change value: any Link
For changing the value of field. accessible from field.events or field.change. You can pass native event or pass any type of value to it. You can find more in examples.
events.focus undefined Link
Will change some properties in field state. like visited or touched.
events.blur undefined Link
Same with focus(), Will change some properties in field state. like visited or touched.

Accessibility to state and methods

It depends how do you want to use the field.

1. Custom native components

{
	meta: fieldState,
    events: {
      change,
      focus,
      blur
    },
    input: {
        type,
        name,
        multiple, // only for select
        placeholder,
        checked, // only for select checkbox,
        value, // this value is for
    },
    name,
}

2. Custom reusable components

This means you want to create a component in different location and file and use it everywhere. You will need to import FieldStateMixin then we'll have this structure.

{
  meta: fieldState,
    events: {
      change,
      focus,
      blur
    },
    value,
    change, // no difference in events.change and this,
    name,
}

This structure will be useful because we can use v-bind and v-on. checkout the above examples or click on links.