123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- import Vue from 'vue'
- import Errors from './FormErrors'
- class Form {
- /**
- * Create a new form instance.
- *
- * @param {Object} data
- */
- constructor (data = {}) {
- this.isBusy = false
- this.isDisabled = false
- // this.successful = false
- this.errors = new Errors()
- this.originalData = this.deepCopy(data)
- Object.assign(this, data)
- }
- /**
- * Fill form data.
- *
- * @param {Object} data
- */
- fill (data) {
- this.keys().forEach(key => {
- this[key] = data[key]
- })
- }
- /**
- * Update original form data.
- */
- setOriginal () {
- Object.keys(this)
- .filter(key => !Form.ignore.includes(key))
- .forEach(key => {
- this.originalData[key] = this.deepCopy(this[key])
- })
- }
- /**
- * Fill form data.
- *
- * @param {Object} data
- */
- fillWithKeyValueObject (data) {
- this.keys().forEach(key => {
- const keyValueObject = data.find(s => s.key === key.toString())
- if(keyValueObject != undefined) {
- this[key] = keyValueObject.value
- }
- })
- }
- /**
- * Get the form data.
- *
- * @return {Object}
- */
- data () {
- return this.keys().reduce((data, key) => (
- { ...data, [key]: this[key] }
- ), {})
- }
- /**
- * Get the form data keys.
- *
- * @return {Array}
- */
- keys () {
- return Object.keys(this)
- .filter(key => !Form.ignore.includes(key))
- }
- /**
- * Start processing the form.
- */
- startProcessing () {
- this.errors.clear()
- this.isBusy = true
- // this.successful = false
- }
- /**
- * Finish processing the form.
- */
- finishProcessing () {
- this.isBusy = false
- // this.successful = true
- }
- /**
- * Clear the form errors.
- */
- clear () {
- this.errors.clear()
- // this.successful = false
- }
- /**
- * Reset the form fields.
- */
- reset () {
- Object.keys(this)
- .filter(key => !Form.ignore.includes(key))
- .forEach(key => {
- this[key] = this.deepCopy(this.originalData[key])
- })
- }
- /**
- * Submit the form via a GET request.
- *
- * @param {String} url
- * @param {Object} config (axios config)
- * @return {Promise}
- */
- get (url, config = {}) {
- return this.submit('get', url, config)
- }
- /**
- * Submit the form via a POST request.
- *
- * @param {String} url
- * @param {Object} config (axios config)
- * @return {Promise}
- */
- post (url, config = {}) {
- return this.submit('post', url, config)
- }
- /**
- * Submit the form via a PATCH request.
- *
- * @param {String} url
- * @param {Object} config (axios config)
- * @return {Promise}
- */
- patch (url, config = {}) {
- return this.submit('patch', url, config)
- }
- /**
- * Submit the form via a PUT request.
- *
- * @param {String} url
- * @param {Object} config (axios config)
- * @return {Promise}
- */
- put (url, config = {}) {
- return this.submit('put', url, config)
- }
- /**
- * Submit the form via a DELETE request.
- *
- * @param {String} url
- * @param {Object} config (axios config)
- * @return {Promise}
- */
- delete (url, config = {}) {
- return this.submit('delete', url, config)
- }
- /**
- * Submit the form data via an HTTP request.
- *
- * @param {String} method (get, post, patch, put)
- * @param {String} url
- * @param {Object} config (axios config)
- * @return {Promise}
- */
- submit (method, url, config = {}) {
- this.startProcessing()
- const data = method === 'get'
- ? { params: this.data() }
- : this.data()
- return new Promise((resolve, reject) => {
- // (Form.axios || axios).request({ url: this.route(url), method, data, ...config })
- Vue.axios.request({ url: this.route(url), method, data, ...config })
- .then(response => {
- this.finishProcessing()
- resolve(response)
- })
- .catch(error => {
- this.isBusy = false
- if (error.response) {
- this.errors.set(this.extractErrors(error.response))
- }
- reject(error)
- })
- })
- }
- /**
- * Submit the form data via an HTTP request.
- *
- * @param {String} method (get, post, patch, put)
- * @param {String} url
- * @param {Object} config (axios config)
- * @return {Promise}
- */
- upload (url, formData, config = {}) {
- this.startProcessing()
- return new Promise((resolve, reject) => {
- // (Form.axios || axios).request({ url: this.route(url), method, data, ...config })
- Vue.axios.request({ url: this.route(url), method: 'post', data: formData, header: {'Content-Type' : 'multipart/form-data'}, ...config })
- .then(response => {
- this.finishProcessing()
- resolve(response)
- })
- .catch(error => {
- this.isBusy = false
- if (error.response) {
- this.errors.set(this.extractErrors(error.response))
- }
- reject(error)
- })
- })
- }
- /**
- * Extract the errors from the response object.
- *
- * @param {Object} response
- * @return {Object}
- */
- extractErrors (response) {
- if (!response.data || typeof response.data !== 'object') {
- return { error: Form.errorMessage }
- }
- if (response.data.errors) {
- return { ...response.data.errors }
- }
- if (response.data.message) {
- return { error: response.data.message }
- }
- return { ...response.data }
- }
- /**
- * Get a named route.
- *
- * @param {String} name
- * @return {Object} parameters
- * @return {String}
- */
- route (name, parameters = {}) {
- let url = name
- if (Form.routes.hasOwnProperty(name)) {
- url = decodeURI(Form.routes[name])
- }
- if (typeof parameters !== 'object') {
- parameters = { id: parameters }
- }
- Object.keys(parameters).forEach(key => {
- url = url.replace(`{${key}}`, parameters[key])
- })
- return url
- }
- /**
- * Clear errors on keydown.
- *
- * @param {KeyboardEvent} event
- */
- onKeydown (event) {
- if (event.target.name) {
- this.errors.clear(event.target.name)
- }
- }
- /**
- * Deep copy the given object.
- *
- * @param {Object} obj
- * @return {Object}
- */
- deepCopy (obj) {
- if (obj === null || typeof obj !== 'object') {
- return obj
- }
-
- const copy = Array.isArray(obj) ? [] : {}
-
- Object.keys(obj).forEach(key => {
- copy[key] = this.deepCopy(obj[key])
- })
-
- return copy
- }
- }
- Form.routes = {}
- Form.errorMessage = 'Something went wrong. Please try again.'
- Form.ignore = ['isBusy', 'isDisabled', 'errors', 'originalData']
- export default Form
|