# Form

The create and edit pages will allow creation of new resource item or modification of existing method, by using respectively create and update data provider methods. In general this pages will share same form although it is not required. With Vuetify Admin, development of form can be done with minimal code thanks to many available input components that have knowledge of current form context.

form

# Layouts

Both create and edit layouts share similar layout as show page with specific contextualized actions. There is nothing more to say about them as the VaForm will do the real work.

# Create layout

VaCreateLayout

Page layout for resource creation.

MIXINS

Resource

PROPS

Props Type Description
title string Optional H1 title of the page shown on the left of top header

SLOTS

Name Description
actions Additional custom action buttons placeholder.
default Page content placeholder.

CLONE

Note that the create page support copy of values from other existing resource, i.e. cloning, as soon as a specific source query string with a valid existing id is present. This is automatically done via VaCloneButton present by default on VaDataTable. This is why a item prop is available on Create vue component that allows you to inject it into VaForm.



 







 



<template>
  <va-create-layout>
    <va-form :item="item">
      <!-- VA inputs component -->
    </va-form>
  </va-create-layout>
</template>

<script>
export default {
  props: ["item"],
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13

# Edit layout

VaEditLayout

Page layout for resource edition. Contain specific related action as deleting, cloning, showing as well as translation action.

MIXINS

Resource

PROPS

Props Type Description
title string Optional H1 title of the page shown on the left of top header

SLOTS

Name Description
actions Additional custom action buttons placeholder.
default Page content placeholder.

USE ID

Compared to to create page, you gain a new id prop that correspond to the resource to edit and patch on the API side. Don't forget to put it on form via the same prop in order to use update data provider method under the hood.



 







 



<template>
  <va-edit-layout>
    <va-form :id="id" :item="item">
      <!-- VA inputs component -->
    </va-form>
  </va-edit-layout>
</template>

<script>
export default {
  props: ["id", "item"],
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13

# Tabbed layout

As the same way for the show view, you have total freedom for page templating. Example with a tabbed style form :

tabs-form

Here a code sample :

<template>
  <va-edit-layout>
    <va-form :id="id" :item="item">
      <v-row justify="center">
        <v-col lg="8">
          <base-material-tabs-card
            :tabs="[
              { id: 'attributes', icon: 'mdi-eye' },
              { id: 'summary', icon: 'mdi-text' },
            ]"
          >
            <template v-slot:attributes>
              <!-- 1st tab content -->
            </template>
            <template v-slot:summary>
              <!-- 2st tab content -->
            </template>
          </base-material-tabs-card>
        </v-col>
      </v-row>
    </va-form>
  </va-edit-layout>
</template>

<script>
export default {
  props: ["title", "id", "item"],
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# Injector

VaForm

Form component which handle resource saving by calling create or update data provider methods. It's the better place for made heavy usage of any VA inputs. Use injection which allowing unique global v-model for all inputs.

MIXINS

Resource

PROPS

Props Type Description
v-model object Current form model being edited. Represent the final data that will be send through your API.
id string|number Id of resource to be edit. If null, then create a new one.
item object Explicit item resource object where all properties must be injected into form model.
redirect string Default route resource action to redirect after saving.
disableRedirect boolean Disable default redirect behavior

SLOTS

Name Description
default All content form with all inner inputs. Model will be injected for each inputs.

EVENTS

Name Description
input Send model update, called after each single input change.
saved Sent after success saving.

Here a quick sample usage within the VaForm inside a VaEditLayout component :

<template>
  <va-form :id="id" :item="item">
    <v-row justify="center">
      <v-col lg="6">
        <base-material-card>
          <template v-slot:heading>
            <div class="display-2">
              {{ title }}
            </div>
          </template>
          <v-card-text>
            <va-autocomplete-input
              source="book"
              reference="books"
              model="book_id"
            ></va-autocomplete-input>
            <va-radio-group-input source="status" row></va-radio-group-input>
            <va-rating-input source="rating"></va-rating-input>
            <va-text-input source="body" multiline></va-text-input>
            <va-text-input source="author"></va-text-input>
            <va-date-input source="publication_date"></va-date-input>
          </v-card-text>
          <va-save-button></va-save-button>
        </base-material-card>
      </v-col>
    </v-row>
  </va-form>
</template>

<script>
export default {
  props: ["id", "title", "item"],
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

This form page will use special VA input components that are aware of current route context and are able to catch and edit the value of resource property indicated on the source prop.

Note that the main internal form model will be auto generated from all inputs that will be present on this form. If you inject an existing item into VaForm, the main form model will takes his actual values that will be reflected for each input.

ALL INPUT COMPONENTS

Go to separated inputs guide reference to get all supported components for edit data. You can still create your own input component if none suit your needs.

# Saving and redirect

Use the VaSaveButton as default submit button. It will automatically synchronize with parent form in order to active the spinner while saving to the API.


 

 









<template>
  <va-form :id="id" :item="item" redirect="show">
    <!-- VA inputs component -->
    <va-save-button></va-save-button>
  </va-form>
</template>

<script>
export default {
  props: ["id", "title", "item"],
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12

By default a successful saving will redirect to resource list page unless you set explicit redirect on VaForm prop as above. Note as this prop have only effect for a submit button. Moreover, you can set redirect on VaSaveButton. It will disable the default submit behavior and the user must click or key press on it for saving. Particularly useful when you need multiple redirect actions as shown next :




 
 
 
 
 
 









<template>
  <va-form :id="id" :item="item">
    <!-- VA inputs component -->
    <va-save-button></va-save-button>
    <va-save-button
      text
      redirect="create"
      color="secondary"
    ></va-save-button>
  </va-form>
</template>

<script>
export default {
  props: ["id", "title", "item"],
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

It will render 2 different buttons, the default one that will submit on enter and redirect to list, and an additional save and add button :

saving

NO DEFAULT REDIRECT

Use disable-redirect prop on VaForm in order to prevent default submit redirect. No effect on save buttons with redirect.

# Form model

As you can see on above code sample, there is no need of any v-model in order to make it work. Indeed, all child inputs will receive the parent form state via provide/inject (opens new window) Vue feature, which reduces considerably code form boilerplate. All inputs will update the internal parent model accordingly on first input initialization and on every input change.

But what if we need access to internal form model for specific case, as show/hide some fields based on current model state ? For that you just have to expose the internal form model via v-model.

Here is a full example with show/hide some fields based on active property model :


 


 
















 
 
 





<template>
  <va-form :id="id" :item="item" v-model="model">
    <va-text-input source="description" multiline></va-text-input>
    <va-boolean-input source="active"></va-boolean-input>
    <v-row v-if="model.active">
      <v-col sm="6">
        <va-text-input source="url"></va-text-input>
      </v-col>
      <v-col sm="6">
        <va-text-input source="email"></va-text-input>
      </v-col>
    </v-row>
    <va-save-button></va-save-button>
  </va-form>
</template>

<script>
export default {
  props: ["id", "title", "item"],
  data() {
    return {
      model: {
        active: true,
      },
    };
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

DEFAULT VALUE

Note that you're not forced to put all properties inside exposed model. If not present, they will still auto created by all present VA inputs component.

If you explicitly set a property, the related input will take this value as default in case of no item is injected into VaForm. Ideal for pre filling a create item.

If you don't need a v-model, simply set the value prop to any compatible value. This value will be take as default on create form.

You can even use the v-model on VA input instead of full form :




 
 
















 





<template>
  <va-form :id="id" :item="item">
    <va-text-input source="description" multiline></va-text-input>
    <va-boolean-input source="active" v-model="active"></va-boolean-input>
    <v-row v-if="active">
      <v-col sm="6">
        <va-text-input source="url"></va-text-input>
      </v-col>
      <v-col sm="6">
        <va-text-input source="email"></va-text-input>
      </v-col>
    </v-row>
    <va-save-button></va-save-button>
  </va-form>
</template>

<script>
export default {
  props: ["id", "title", "item"],
  data() {
    return {
      active: true,
    };
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# Client-side validation

VaForm use a vuetify v-form under the hood. Check the official docs (opens new window) for further detail. Use the rules property for each VA inputs for setting custom rules. For required, you can use the required shorthand prop.

# Server-side validation

ERRORS HANDLING

See separated section before continue.

Server-side validation is supported as soon as your API provides all constraint violations inside response body, which usually wears a 422 status code. VaForm will search for a errors property on the error object returned by your data provider and will dispatch them to all input fields.

This errors property is a key-value object where each property have the list of associated errors. The name of each property must correspond to the source defined on each input in order to push errors on it via his errorMessages prop.

Here an example of compatible object error :

{
    "message": "The given data was invalid.",
    "status": 422,
    "errors": {
        "book_id": ["The book id field is required."],
        "status": ["The status field is required."],
        "author": ["The author field is required."],
        "publication_date": ["The publication date field is required."]
    }
}
1
2
3
4
5
6
7
8
9
10

It will render as next :

form-validation