laravel-form-validation
Version:
Yet another form validation helper for Laravel
512 lines (482 loc) • 15.6 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("axios"), require("object-to-formdata"), require("vue"));
else if(typeof define === 'function' && define.amd)
define("LaravelForm", ["axios", "object-to-formdata", "vue"], factory);
else if(typeof exports === 'object')
exports["LaravelForm"] = factory(require("axios"), require("object-to-formdata"), require("vue"));
else
root["LaravelForm"] = factory(root["axios"], root["object-to-formdata"], root["Vue"]);
})(this, (__WEBPACK_EXTERNAL_MODULE__300__, __WEBPACK_EXTERNAL_MODULE__614__, __WEBPACK_EXTERNAL_MODULE__976__) => {
return /******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ 300:
/***/ ((module) => {
module.exports = __WEBPACK_EXTERNAL_MODULE__300__;
/***/ }),
/***/ 614:
/***/ ((module) => {
module.exports = __WEBPACK_EXTERNAL_MODULE__614__;
/***/ }),
/***/ 976:
/***/ ((module) => {
module.exports = __WEBPACK_EXTERNAL_MODULE__976__;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
"Errors": () => (/* reexport */ src_Errors),
"FieldErrorComponent": () => (/* reexport */ FieldErrorComponent),
"Form": () => (/* reexport */ src_Form),
"IsInvalidDirective": () => (/* reexport */ IsInvalidDirective),
"VueFormPlugin": () => (/* binding */ VueFormPlugin),
"default": () => (/* reexport */ src_Form)
});
// EXTERNAL MODULE: external "axios"
var external_axios_ = __webpack_require__(300);
var external_axios_default = /*#__PURE__*/__webpack_require__.n(external_axios_);
;// CONCATENATED MODULE: ./src/Errors.ts
var Errors = /** @class */ (function () {
/**
* Create a new Errors instance.
*
* @param {Object} errors
*/
function Errors(errors) {
if (errors === void 0) { errors = {}; }
this.errors = errors;
}
/**
* Get all of the messages in the bag.
*
* @return {object}
*/
Errors.prototype.all = function () {
return this.errors;
};
/**
* Determine if messages exist for the given key.
*
* @param {String} field
* @return {Boolean}
*/
Errors.prototype.has = function (field) {
var hasError = this.errors.hasOwnProperty(field);
if (!hasError) {
hasError = Object.keys(this.errors).some(function (f) { return f.startsWith("".concat(field, ".")) || f.startsWith("".concat(field, "[")); });
}
return hasError;
};
/**
* Get the first message from the bag for a given key.
*
* @param {String} field
* @returns {String|null}
*/
Errors.prototype.first = function (field) {
return this.get(field)[0];
};
/**
* Get the first error from matching key
*
* @param fieldPattern
*/
Errors.prototype.firstWhere = function (fieldPattern) {
var foundKey = Object.keys(this.all()).find(function (f) { return f.startsWith("".concat(fieldPattern, ".")) || f.startsWith("".concat(fieldPattern, "[")); });
if (foundKey) {
return this.first(foundKey);
}
return null;
};
/**
* Get all of the messages from the bag for a given key.
*
* @param {String} field
* @returns {Array}
*/
Errors.prototype.get = function (field) {
return this.errors[field] || [];
};
/**
* Determine if we have any errors.
*
* @return {Boolean}
*/
Errors.prototype.any = function () {
return Object.keys(this.errors).length > 0;
};
/**
* Get all the errors in a flat array.
*
* @return {Array}
*/
Errors.prototype.flatten = function () {
return Object.values(this.errors).reduce(function (a, b) { return a.concat(b); }, []);
};
/**
* Record the new errors.
*
* @param {Object} errors
*/
Errors.prototype.record = function (errors) {
this.errors = errors;
};
/**
* Clear a specific field, object or all error fields.
*
* @param {String?} field
*/
Errors.prototype.clear = function (field) {
var errors = {};
if (field) {
// Prevent reactivity issues
errors = Object.assign({}, this.errors);
Object.keys(errors)
.filter(function (f) { return f === field || f.startsWith("".concat(field, ".")) || f.startsWith("".concat(field, "[")); })
.map(function (f) { return delete errors[f]; });
}
this.record(errors);
};
return Errors;
}());
/* harmony default export */ const src_Errors = (Errors);
;// CONCATENATED MODULE: ./src/Util.ts
/**
* Check if the given data contains any instance of File.
*
* @param {Object} data
* @return {Boolean}
*/
var hasFile = function (data) {
for (var property in data) {
if (hasFileDeep(data[property])) {
return true;
}
}
return false;
};
/**
* Determines if object is file.
*
* @param {Object} item
* @returns {boolean}
*/
var isFile = function (item) {
return item instanceof Blob || item instanceof FileList;
};
/**
* Check if the given item is (or contains) a File.
*
* @param {Object|Array} item
* @return {Boolean}
*/
var hasFileDeep = function (item) {
if (isFile(item)) {
return true;
}
if (typeof item === 'object') {
for (var key in item) {
if (item.hasOwnProperty(key) && hasFileDeep(item[key])) {
return true;
}
}
}
if (Array.isArray(item)) {
return item.some(function (element) { return hasFileDeep(element); });
}
return false;
};
// EXTERNAL MODULE: external "object-to-formdata"
var external_object_to_formdata_ = __webpack_require__(614);
;// CONCATENATED MODULE: ./src/Form.ts
var __assign = (undefined && undefined.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var Form = /** @class */ (function () {
/**
* Create a new Form instance.
* @return {Form}
*/
function Form() {
this.$progress = 0;
this.$pending = false;
this.$errors = new src_Errors();
}
/**
* Make a get request.
*
* @param {String} url
* @param {Object} params
* @returns {Promise}
*/
Form.prototype.get = function (url, params) {
if (params === void 0) { params = {}; }
return this.submit('get', url, {}, { params: params });
};
/**
* Make a post request.
*
* @param {String} url
* @param {Object} data
* @returns {Promise}
*/
Form.prototype.post = function (url, data) {
if (data === void 0) { data = {}; }
return this.submit('post', url, data);
};
/**
* Make a patch request.
*
* @param {String} url
* @param {Object} data
* @returns {Promise}
*/
Form.prototype.patch = function (url, data) {
if (data === void 0) { data = {}; }
return this.submit('patch', url, data);
};
/**
* Make a put request.
*
* @param {String} url
* @param {Object} data
* @returns {Promise}
*/
Form.prototype.put = function (url, data) {
if (data === void 0) { data = {}; }
return this.submit('put', url, data);
};
/**
* Make a delete request.
*
* @param {String} url
* @param {Object} data
* @returns {Promise}
*/
Form.prototype.delete = function (url, data) {
if (data === void 0) { data = {}; }
return this.submit('delete', url, data);
};
/**
* Submit the form to the given URL using the method specified.
*
* @param {String} method
* @param {String} url
* @param {Object} data
* @param {Object} config
* @return {Promise}
*/
Form.prototype.submit = function (method, url, data, config) {
var _this = this;
if (data === void 0) { data = {}; }
if (config === void 0) { config = {}; }
var formData = data;
method = method.toLowerCase();
this.$progress = 0;
this.$errors.clear();
this.$pending = true;
if (hasFile(formData)) {
formData = (0,external_object_to_formdata_.serialize)(formData, {
indices: true,
booleansAsIntegers: true
});
// Form Method Spoofing is needed to send files using PUT/PATCH/DELETE.
// https://laravel.com/docs/routing#form-method-spoofing
// https://github.com/laravel/framework/issues/13457
if (method !== 'post') {
formData.append('_method', method);
method = 'post';
}
}
return new Promise(function (resolve, reject) {
Form.$defaults.axios.request(__assign(__assign({ url: url, method: method, data: formData }, _this.axiosConfig()), config))
.then(function (response) {
resolve(response.data);
})
.catch(function (error) {
_this.onFail(error);
reject(error);
})
.then(function () { return _this.$pending = false; });
});
};
/**
* Returns the axios configuration object.
*
* @source https://github.com/axios/axios#request-config
* @return {Object}
*/
Form.prototype.axiosConfig = function () {
var _this = this;
return {
onUploadProgress: function (event) {
_this.$progress = Math.round((event.loaded * 100) / event.total);
}
};
};
/**
* Handle a error response.
*
* @param {AxiosError} error
*/
Form.prototype.onFail = function (error) {
var _a;
/* istanbul ignore else */
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 422) {
var json = error.response.data;
this.$errors.record(json.errors);
}
};
return Form;
}());
/*
* Expose default values in order to let users customize behavior.
*/
Form.$defaults = { axios: (external_axios_default()) };
/* harmony default export */ const src_Form = (Form);
// EXTERNAL MODULE: external {"commonjs":"vue","commonjs2":"vue","amd":"vue","root":"Vue"}
var external_commonjs_vue_commonjs2_vue_amd_vue_root_Vue_ = __webpack_require__(976);
var external_commonjs_vue_commonjs2_vue_amd_vue_root_Vue_default = /*#__PURE__*/__webpack_require__.n(external_commonjs_vue_commonjs2_vue_amd_vue_root_Vue_);
;// CONCATENATED MODULE: ./src/Vue/FieldErrorComponent.ts
/* harmony default export */ const FieldErrorComponent = (external_commonjs_vue_commonjs2_vue_amd_vue_root_Vue_default().extend({
name: 'FieldError',
render: function (el) {
return this.hasError ? el('div', {
class: this.className,
domProps: {
innerText: this.message
},
}) : null;
},
props: {
bag: {
type: Object,
required: true,
},
field: {
type: String,
required: true
},
className: {
type: String,
default: 'invalid-feedback'
}
},
computed: {
hasError: function () {
return this.bag.has(this.field);
},
message: function () {
return this.bag.first(this.field);
}
}
}));
;// CONCATENATED MODULE: ./src/Vue/IsInvalidDirective.ts
/* harmony default export */ const IsInvalidDirective = (function ($el, binding) {
/**
* @var Errors $errors
*/
var $errors = binding.value;
if (!$el.attributes.name) {
throw new Error('v-invalid directive requires `name` attribute on input.');
}
if ($errors.has($el.attributes.name.value)) {
$el.classList.add('is-invalid');
}
else {
$el.classList.remove('is-invalid');
}
});
;// CONCATENATED MODULE: ./src/index.ts
var VueFormPlugin = {
install: function (Vue) {
Vue.directive('invalid', IsInvalidDirective);
Vue.component('field-error', FieldErrorComponent);
}
};
})();
/******/ return __webpack_exports__;
/******/ })()
;
});