Unformed thoughts

Less boilerplate and more awesomeness with the new InertiaJS form helper

In this video we’ll take a look over Inertia’s new form helper – a game changer as it solves some of the old pains we had with forms, while removing a lot of boilerplate as well.

<template>
  <app-layout>
    <div class="sticky top-0 flex items-center justify-between p-4 bg-white border-b border-gray-200">
      <h2 class="text-xl font-semibold leading-tight text-gray-800">
        Edit profile
      </h2>

      <div class="flex items-center space-x-2">
        <secondary-button @click="form.reset()">
          Reset
        </secondary-button>

        <primary-button form="profile-form" :loading="form.processing">
          Save profile {{ form.progress ? `${form.progress.percentage}%` : ''}}
        </primary-button>
      </div>
    </div>

    <form id="profile-form" class="p-5" @submit.prevent="submit">
      <div v-if="form.wasSuccessful" class="p-3 mb-3 bg-green-100 rounded border border-green-300">
        Profile was updated successfully.
      </div>

      <div class="mb-3">
        <avatar-input class="h-24 w-24 rounded-full" v-model="form.avatar" :default-src="user.profile_photo_url"></avatar-input>
        <p class="text-sm text-red-600" v-if="form.errors.avatar">{{ form.errors.avatar }}</p>
      </div>

      <div class="mb-3">
        <label for="name" class="block font-medium text-sm text-gray-700">Name:</label>
        <input v-model="form.name" id="name" class="form-input rounded-md shadow-sm w-full">
        <p class="text-sm text-red-600" v-if="form.errors.name">{{ form.errors.name }}</p>
      </div>

      <div class="mb-3">
        <label for="username" class="block font-medium text-sm text-gray-700">Username:</label>
        <input v-model="form.username" id="username" class="form-input rounded-md shadow-sm w-full">
        <p class="text-sm text-red-600" v-if="form.errors.username">{{ form.errors.username }}</p>
      </div>

      <div class="mb-3">
        <label for="email" class="block font-medium text-sm text-gray-700">Email:</label>
        <input v-model="form.email" id="email" class="form-input rounded-md shadow-sm w-full">
        <p class="text-sm text-red-600" v-if="form.errors.email">{{ form.errors.email }}</p>
      </div>

      <div class="mb-3">
        <label for="description" class="block font-medium text-sm text-gray-700">Description:</label>
        <textarea v-model="form.description" id="description" class="form-input rounded-md shadow-sm w-full" rows="3"></textarea>
        <p class="text-sm text-red-600" v-if="form.errors.description">{{ form.errors.description }}</p>
      </div>
    </form>
  </app-layout>
</template>

<script>
import AppLayout from './../../Layouts/AppLayout';
import AvatarInput from "../../Components/AvatarInput";

export default {
  props: {
    user: Object
  },
  data() {
    return {
      form: this.$inertia.form({
        avatar: null,
        name: this.user.name,
        username: this.user.username,
        email: this.user.email,
        description: this.user.description,
        _method: 'PUT'
      })
    }
  },
  methods: {
    submit() {
      this.form.post(`/settings/profile`, {
        onSuccess: () => this.form.reset();
      });
    }
  },
  components: {
    AppLayout,
    AvatarInput
  },
}
</script>
« »