Feedback Laraform is now in maintenance mode. Read more on our GitHub.

Buttons

#Creating Buttons

Let's create a form with multiple buttons:

<?php

namespace App\Forms;

class ButtonsForms extends \Laraform
{
  public function schema() {
    return [
      'name' => [
        'type' => 'text',
        'label' => 'Name',
        'rules' => 'required'
      ]
    ];
  }

  public function buttons() {
    return [
      [
        'label' => 'Submit'
      ],
      [
        'label' => 'Reset',
        'prevent' => true
      ],
    ];
  }
}

The first button will act like a Submit button and second should Reset the form.

By default each button will submit the form, unless it has a prevent option set to true. However we have this at the Reset button that itself will not reset the form. Let's see how we can add reset functionality.

#Extending On Frontend

To add frontend features to a button (like reset), let's attach a frontend component to our form:

<?php

namespace App\Forms;

class ButtonsForms extends \Laraform
{
  public $component = 'buttons-form';

  // ...
}

Now let's create the frontend form:

<script>
  export default {
    mixins: [Laraform],
    data() {
      return {
        buttons: [
          {
            // Submit button
            disabled() {
              return this.form$.invalid
            }
          },
          {
            // Reset button
            onClick() {
              this.form$.reset()
            }
          },
        ]
      }
    }
  }
</script>

As you can see we are extending our two buttons on the frontend. The first, Submit button will be disabled if the form has any invalid fields, while the second, Reset will reset() the form on click.

#Button Hooks

You can define Vue Lifecycle Hooks for each button via it's schema:

buttons: [
  {
    label: 'Submit',
    class: 'btn-primary',
    created() {
      // do something
    }
  }
]

#Custom Buttons

Chances are you want to add some extra features to the buttons in general, so let's see how you can replace the default FormButton component with a custom one.

First, let's create a component at resources/js/components/FormButton.vue:

<template>
  <button
    :class="this.class"
    :disabled="disabled"
    @click="handleClick"
  >{{ label }}</button>  
</template>

<script>
  import FormButton from '@laraform/laraform/src/components/FormButton'

  export default {
    mixins: [FormButton]
  }
</script>

This component now equals to Laraform's version, so once we register it you'll be free to extend it as you wish.

Replace FormButton Component

To replace the FormButton component, we need to import the theme we are using and update its component. In this example we are going to update bs4 theme assuming our project uses Bootstrap 4:

import Vue from 'vue'
import Laraform from '@laraform/laraform'
import bs4 from '@laraform/laraform/src/themes/bs4'
import FormButton from './components/FormButton'

bs4.components.FormButton = FormButton

Laraform.theme('bs4', bs4)

Vue.use(Laraform)

const app = new Vue({
  el: '#app'
})

#Add Loading State

Now that we have our custom FormButton component we're free to add any features. As an example let's see how we can add a loading class to the button when the form is loading:

// resources/js/components/FormButton.vue

<template>
  <button
    :class="[this.class, loading: isLoading]"
    :disabled="disabled"
    @click="handleClick"
  >{{ label }}</button>  
</template>

<script>
  import FormButton from '@laraform/laraform/src/components/FormButton'

  export default {
    mixins: [FormButton],
    computed: {
      isLoading() {
        return this.form$.busy
      }
    }
  }
</script>

Pretty simple, we just added loading to the buttons class list explicitly when the isLoading property returns true. The isLoading property relies on the form's busy property to determine if the form is currently in pending state.

If you want to learn more about the button's default methods and properties check out it's reference or check out the default FormButton component at @laraform/laraform/src/components/FormButton.vue.