Form component to create and edit using Vue 3 with Oruga UI

- Andrés Cruz

En español
Form component to create and edit using Vue 3 with Oruga UI

In oruga UI we have a large number of components, among them the form components cannot be missing; for traditional text fields, there are so-called o-inputs of type text and textarea.

We can map them with the o-field component which allows us to indicate other characteristics such as the label and messages (which will be used to show validation errors):

<template>
  <o-field label="Título">
    <o-input value=""></o-input>
  </o-field>
  <o-field label="Descripción">
    <o-input type="textarea" value=""></o-input>
  </o-field>
  <o-field label="Contenido">
    <o-input type="textarea" value=""></o-input>
  </o-field>
  <o-field label="Categoría">
    <o-select placeholder="Seleccione una categoría">
      <option value="">Cate 1</option>
    </o-select>
  </o-field>
  <o-field label="Posted">
    <o-select placeholder="Seleccione un estado">
      <option value="yes">Si</option>
      <option value="nost">No</option>
    </o-select>
  </o-field>
  <o-button variant="primary">Enviar</o-button>
</template>

From the routes component, for navigation, which was installed previously and we see it in another post; the route will be like the following:

resources/js/vue/router.js

   {
        name:'save',
        path:'/vue/save/:slug?',
        component: Save
    },

In this case, an optional argument is used since this same component is used for both creating records and editing; therefore, if it is passed the identifier, it means that it wants to be edited.

In this case, the slug is passed as the identifier, but it can be any other such as the PK; It all depends on what the Rest Api that is used in this tutorial (a rest api created in Laravel of CRUD type) needs to obtain the detail.

Now, from the Save.vue component, we define a new property:

  data() {
    return {
      ***
      post:""
    };
  },

Which will be used to map the structure of the post or the entity you are editing.

It will only be defined if you are editing, if you are in the process of creating then it will be empty.

In which we register the post that we want to edit; when we mount the mentioned component, we ask if the slug is defined or not:

resources/js/vue/componets/Save.vue

async mounted() {
    if(this.$route.params.slug){
      await this.getPost();
      this.initPost();
    }
    this.getCategory();
  },

In the getPost() function, we get the detail of the post through the slug connecting to the Rest Api in Laravel:

async getPost() {
      this.post = await this.$axios.get("/api/post/slug/"+this.$route.params.slug);
      this.post = this.post.data
},

In the initPost() function we initialize the form, in other words, the v-model of each of our properties:

  initPost(){
      this.form.title = this.post.title
      this.form.description = this.post.description
      this.form.content = this.post.content
      this.form.category_id = this.post.category_id
      this.form.posted = this.post.posted
    }

Of course, if and only if we are editing the registry.

And in the submit process, you can ask for any of the manageable ways in this component to know if we are in the edit or create phase to know which rest resource we are going to call:

submit(){
    this.cleanErrorsForm()
  if(this.post == "")
    return this.$axios.post("/api/post",
      this.form
    ).then(res => {
      console.log(res)
    }).catch(error =>{
      console.log(error.response.data)
      if(error.response.data.title)
        this.errors.title = error.response.data.title[0]
    
      if(error.response.data.description)
        this.errors.description = error.response.data.description[0]
      if(error.response.data.category_id)
        this.errors.category_id = error.response.data.category_id[0]
      if(error.response.data.posted)
        this.errors.posted = error.response.data.posted[0]
      if(error.response.data.content)
        this.errors.content = error.response.data.content[0]
    })
    // actualizar
    this.$axios.patch("/api/post/"+this.post.id,
      this.form
    ).then(res => {
      console.log(res)
    }).catch(error =>{
      console.log(error.response.data)
      if(error.response.data.title)
        this.errors.title = error.response.data.title[0]
    
      if(error.response.data.description)
        this.errors.description = error.response.data.description[0]
      if(error.response.data.category_id)
        this.errors.category_id = error.response.data.category_id[0]
      if(error.response.data.posted)
        this.errors.posted = error.response.data.posted[0]
      if(error.response.data.content)
        this.errors.content = error.response.data.content[0]
    })
  },

Rest APIs in Laravel

You'll have to remove the required from the slug validation process, since we're not passing it the same (or create a slug field on the form for the slug); of:

"slug" => "required|min:5|max:500|unique:posts,slug,".$this->route("post")->id,

To:

"slug" => "required|min:5|max:500|unique:posts,slug,".$this->route("post")->id,

For the rest, the registry is perfectly created, and if server errors occur, the corresponding errors are mapped and displayed using the o-field of Oruga UI, which as mentioned above, this component allows to display messages that in this case, is for validation errors.

Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.