Skip to content

Instantly share code, notes, and snippets.

@tabishiqbal
Last active November 13, 2019 03:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tabishiqbal/fa3c69c1dc2f9a0e2f985b6e04dcdf7f to your computer and use it in GitHub Desktop.
Save tabishiqbal/fa3c69c1dc2f9a0e2f985b6e04dcdf7f to your computer and use it in GitHub Desktop.
How to submit a form in Vue via Rails
<template>
<div class="lg:w-4/5 w-full">
<form method="post" v-on:submit.prevent="submitForm">
<div class="bg-white py-5 px-6 mb-6 rounded shadow">
<div class="pb-8">
<div class="text-base font-medium">General Information</div>
</div>
<div class="flex flex-wrap -mx-3 mb-6">
<div class="w-full md:w-1/2 px-3 mb-6 md:mb-0">
<label class="block uppercase tracking-wide text-grey-darker text-xs mb-2" for="tool-model">
Model
</label>
<input
name="post[name]"
v-model="post.name"
class="block w-full form-control"
type="text"
placeholder="Some post info"
v-validate="'required'"
:class="{'border border-red': errors.has('post[name]')}"
>
<span class="text-red" v-show="errors.has('post[name]')">Name is required</span>
</div>
</div>
<div class="flex flex-wrap -mx-3 mb-6">
<div class="w-full md:w-1/2 px-3">
<label class="block uppercase tracking-wide text-grey-darker text-xs mb-2" for="brand">
Options Example
</label>
<div class="relative">
<select name="post[option]" class="form-control select2-selection" v-model="selectedOption" v-validate="'required'" :class="{'border border-red': errors.has('post[option]')}">
<option disabled value="">Select an option</option>
<option v-for="(option, index) in options" :key="index" v-bind:value="option">{{ option.name }}</option>
</select>
<div class="pointer-events-none absolute pin-y pin-r flex items-center px-2 text-grey-darker">
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/></svg>
</div>
</div>
<span class="text-red" v-show="errors.has('post[option]')">Please select an option</span>
</div>
</div>
</div>
<div class="bg-white py-5 px-6 mb-6 rounded shadow">
<div class="pb-8">
<div class="text-base font-medium">Upload Image</div>
</div>
<div class="flex flex-wrap -mx-3 mb-6">
<div class="w-full px-3 mb-6 md:mb-0">
<input
name="post[image]"
id="post_image"
accept="image/*"
type="file"
data-direct-upload-url="/rails/active_storage/direct_uploads"
direct_upload="true"
@change="onImageSelected"
/>
</div>
</div>
</div>
<div class="flex justify-end">
<button @click.prevent="cancel" class="text-black px-8 ml-2 focus:outline-none hover:underline">Cancel</button>
<button v-if="!loading" @click.prevent="submitForm" class="btn-primary-dark text-white px-8 ml-2">Save</button>
<button v-if="loading" class="btn-primary-dark text-white px-8 ml-2">Saving...</button>
</div>
</form>
</div>
</template>
<script>
import axios from 'axios';
import VeeValidate from 'vee-validate';
export default {
props: {
post: Object,
required: true
},
data() {
return {
loading: false,
selectedImage: '',
selectedOption: '',
}
},
methods: {
cancel() {
window.location.href = '/posts';
},
onImageSelected(event) {
this.selectedImage = event.target.files[0];
this.selectedImageValue = 'post.cached_image_data';
},
submitForm() {
this.$validator.validate().then(result => {
this.loading = true;
let formData = new FormData();
formData.append('post[name]', this.post.name)
formData.append('post[option]', this.selectedOption)
// below are examples of passing null values so you don't have empty strings in your table
if (this.selectedImage) {
formData.append('post[image]', this.selectedImage)
}
axios.post('/posts.json', formData)
.then(resp => {
if (resp) {
let id = resp.data.public_uid;
window.location.href = `/posts/${id}`
}
})
.catch((error) => {
let errors = error.response.data;
let that = this;
_.forEach(errors, function(value, key) {
that.errorMsg = _.capitalize(key) + ' ' + value
});
this.loading = false;
});
});
this.loading = false;
}
}
}
</script>
<div class="mx-8 h-64px my-3">
<div class="pb-12">
<div class="text-2xl py-4">Add New Tool</div>
<% if @post.errors.any? %>
<% @post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
<% end %>
<add-post
:current-account="<%= current_user.account.id.to_json %>" # you can pass current account as well if you need it!
:post="<%= @post.to_json %>"
>
</add-post>
</div>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment