UNPKG

vue-mfk

Version:

A Vue.js Plugin for MFK input.

805 lines (713 loc) 22.9 kB
/*! * vue-mfk-vuetify v0.2.0 * (c) 2018 Valerij Petrulevich * Released under the MIT License. */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("_"), require("Vuetify")); else if(typeof define === 'function' && define.amd) define(["_", "Vuetify"], factory); else if(typeof exports === 'object') exports["VueMfkVuetify"] = factory(require("_"), require("Vuetify")); else root["VueMfkVuetify"] = factory(root["_"], root["Vuetify"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_5__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 8); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ValidateMfk; function httpGetAsync(theUrl, callback) { //https://apps.its.uiowa.edu/mfk/external-developer.html var xmlHttp = new XMLHttpRequest(); xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState == 4 && xmlHttp.status == 200) callback(xmlHttp.responseText);else if (xmlHttp.readyState == 4) callback("0\nUnable to reach MFK validation service"); //simulate bad response }; xmlHttp.open("GET", theUrl, true); // true for asynchronous xmlHttp.send(null); } var mfkDefinition = [{ name: "Fund", length: 3 }, { name: "Org", length: 2 }, { name: "Dept", length: 4 }, { name: "SubDept", length: 5 }, { name: "Grant/Prg", length: 8 }, { name: "IAcct", length: 4 }, { name: "OAcct", length: 3 }, { name: "DAcct", length: 5 }, { name: "Fn", length: 2 }, { name: "Cctr", length: 4 }]; function ValidateMfk(mfk) { var mfkParts = (mfk || '').split('-'); if (mfkParts.length > mfkDefinition.length) return Promise.reject('MFK has too many parts.'); for (var index = 0; index < mfkDefinition.length; index++) { if ((mfkParts[index] || '').length != mfkDefinition[index].length) return Promise.reject(mfkDefinition[index].name + " must be " + mfkDefinition[index].length + " digits long."); } var mfkWithoutDashes = mfk.replace(/-/g, ""); var url = "https://apps.its.uiowa.edu/mfk/api-singleDesc.jsp?mfk=10%20%20%20" + mfkWithoutDashes; return new Promise(function (resolve, reject) { httpGetAsync(url, function (result) { var parts = result.split(/\n/); //split by new line if (parts[0] == 1) resolve();else reject(parts[1]); }); }); } /***/ }), /* 1 */ /***/ (function(module, exports) { /* globals __VUE_SSR_CONTEXT__ */ // this module is a runtime utility for cleaner component module output and will // be included in the final webpack user bundle module.exports = function normalizeComponent ( rawScriptExports, compiledTemplate, injectStyles, scopeId, moduleIdentifier /* server only */ ) { var esModule var scriptExports = rawScriptExports = rawScriptExports || {} // ES6 modules interop var type = typeof rawScriptExports.default if (type === 'object' || type === 'function') { esModule = rawScriptExports scriptExports = rawScriptExports.default } // Vue.extend constructor export interop var options = typeof scriptExports === 'function' ? scriptExports.options : scriptExports // render functions if (compiledTemplate) { options.render = compiledTemplate.render options.staticRenderFns = compiledTemplate.staticRenderFns } // scopedId if (scopeId) { options._scopeId = scopeId } var hook if (moduleIdentifier) { // server build hook = function (context) { // 2.3 injection context = context || // cached call (this.$vnode && this.$vnode.ssrContext) || // stateful (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional // 2.2 with runInNewContext: true if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { context = __VUE_SSR_CONTEXT__ } // inject component styles if (injectStyles) { injectStyles.call(this, context) } // register component module identifier for async chunk inferrence if (context && context._registeredComponents) { context._registeredComponents.add(moduleIdentifier) } } // used by ssr in case component is cached and beforeCreate // never gets called options._ssrRegister = hook } else if (injectStyles) { hook = injectStyles } if (hook) { var functional = options.functional var existing = functional ? options.render : options.beforeCreate if (!functional) { // inject component registration as beforeCreate hook options.beforeCreate = existing ? [].concat(existing, hook) : [hook] } else { // register for functioal component in vue file options.render = function renderWithStyleInjection (h, context) { hook.call(context) return existing(h, context) } } } return { esModule: esModule, exports: scriptExports, options: options } } /***/ }), /* 2 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_2__; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { var disposed = false function injectStyle (ssrContext) { if (disposed) return __webpack_require__(10) } var Component = __webpack_require__(1)( /* script */ __webpack_require__(6), /* template */ __webpack_require__(12), /* styles */ injectStyle, /* scopeId */ "data-v-24dbf928", /* moduleIdentifier (server only) */ null ) Component.options.__file = "C:\\Projects\\vue-mfk2\\src\\mfk-favorite.vue" if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")} if (Component.options.functional) {console.error("[vue-loader] mfk-favorite.vue: functional components are not supported with templates, they should use render functions.")} /* hot reload */ if (false) {(function () { var hotAPI = require("vue-hot-reload-api") hotAPI.install(require("vue"), false) if (!hotAPI.compatible) return module.hot.accept() if (!module.hot.data) { hotAPI.createRecord("data-v-24dbf928", Component.options) } else { hotAPI.reload("data-v-24dbf928", Component.options) } module.hot.dispose(function (data) { disposed = true }) })()} module.exports = Component.exports /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { var disposed = false function injectStyle (ssrContext) { if (disposed) return __webpack_require__(9) } var Component = __webpack_require__(1)( /* script */ __webpack_require__(7), /* template */ __webpack_require__(11), /* styles */ injectStyle, /* scopeId */ "data-v-21e42b2a", /* moduleIdentifier (server only) */ null ) Component.options.__file = "C:\\Projects\\vue-mfk2\\src\\mfk-input.vue" if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")} if (Component.options.functional) {console.error("[vue-loader] mfk-input.vue: functional components are not supported with templates, they should use render functions.")} /* hot reload */ if (false) {(function () { var hotAPI = require("vue-hot-reload-api") hotAPI.install(require("vue"), false) if (!hotAPI.compatible) return module.hot.accept() if (!module.hot.data) { hotAPI.createRecord("data-v-21e42b2a", Component.options) } else { hotAPI.reload("data-v-21e42b2a", Component.options) } module.hot.dispose(function (data) { disposed = true }) })()} module.exports = Component.exports /***/ }), /* 5 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_5__; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _lodash = __webpack_require__(2); var _lodash2 = _interopRequireDefault(_lodash); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { props: { value: { // mfk input type: String, required: true }, favorites: { type: Array, required: true }, disabled: { type: Boolean, default: false } }, computed: { optionsForFavoriteMfks: function optionsForFavoriteMfks() { if (this.favorites.length > 0) return _lodash2.default.sortBy(this.favorites, [function (item) { return item.alias.toLowerCase(); }]);else return [{ header: 'You have no favorite MFKs' }]; }, selectedFavoriteMfk: { get: function get() { var _this = this; return _lodash2.default.find(this.favorites, function (item) { return item.mfk === _this.value; }); } }, isFavoriteMfk: function isFavoriteMfk() { return this.selectedFavoriteMfk; }, buttonTitle: function buttonTitle() { return this.isFavoriteMfk ? 'Remove MFK from Favorites' : 'Add MFK to Favorites'; } }, methods: { onChange: function onChange($event) { if ($event.mfk) { this.$emit('input', $event.mfk); //tell parent that new MFK was selected } }, toggleFavoriteMfk: function toggleFavoriteMfk() { if (this.isFavoriteMfk) this.removeMfkFromFavorites();else this.addMfkToFavorites(); }, addMfkToFavorites: function addMfkToFavorites() { var newAlias = prompt("Please specify alias name for new favorite MFK."); if (!newAlias) return; this.$emit('add', { mfk: this.value, alias: newAlias }); }, removeMfkFromFavorites: function removeMfkFromFavorites() { if (confirm('Remove favorite MFK \'' + this.selectedFavoriteMfk.alias + '\' ?')) { this.$emit('remove', this.selectedFavoriteMfk); } } } }; // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _validateMfk = __webpack_require__(0); var _validateMfk2 = _interopRequireDefault(_validateMfk); var _lodash = __webpack_require__(2); var _lodash2 = _interopRequireDefault(_lodash); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // // // // // // // // // // // // // // // // // // // // // // // // // exports.default = { props: { value: String, //mfk input validate: { //validate mfk yes/no type: Boolean, default: true }, disabled: { type: Boolean, default: false }, disabledFields: { type: Array, default: function _default() { return []; } }, errorMessage: { type: String, default: null } }, data: function data() { return { mfkError: '', mfkDefinition: [{ index: 0, name: "Fund", maxLength: 3, minWidth: 36, value: "" }, { index: 1, name: "Org", maxLength: 2, minWidth: 26, value: "" }, { index: 2, name: "Dept", maxLength: 4, minWidth: 42, value: "" }, { index: 3, name: "SubDept", maxLength: 5, minWidth: 54, value: "" }, { index: 4, name: "Grant/Prg", maxLength: 8, minWidth: 78, value: "" }, { index: 5, name: "IAcct", maxLength: 4, minWidth: 42, value: "" }, { index: 6, name: "OAcct", maxLength: 3, minWidth: 38, value: "" }, { index: 7, name: "DAcct", maxLength: 5, minWidth: 50, value: "" }, { index: 8, name: "Fn", maxLength: 2, minWidth: 26, value: "" }, { index: 9, name: "Cctr", maxLength: 4, minWidth: 38, value: "" }] }; }, computed: { anyErrors: function anyErrors() { return this.errorToDisplay ? true : false; }, mfkString: function mfkString() { return this.mfkElements.map(function (a) { return a.value; }).join('-'); }, errorToDisplay: function errorToDisplay() { if (this.errorMessage != null) //if external errorMessage is set (i.e. not null) //it always takes priority over mfk validation error return this.errorMessage;else return this.mfkError; }, mfkElements: function mfkElements() { var _this = this; var mfkParts = (this.value || '').split('-'); this.mfkDefinition.forEach(function (el) { el.value = mfkParts[el.index] || ''; el.disabled = _this.disabled || _this.disabledFields.includes(el.index); }); return this.mfkDefinition; }, //proper way to handle debounce //https://forum.vuejs.org/t/issues-with-vuejs-component-and-debounce/7224/8 validateMfk: function validateMfk() { return _lodash2.default.debounce(function () { var _this2 = this; (0, _validateMfk2.default)(this.mfkString).then(function () { return _this2.mfkError = null; }).catch(function (error) { return _this2.mfkError = error; }).finally(function () { return _this2.$emit('update:errorMessage', _this2.mfkError); }); }, 1000); } }, methods: { onInput: function onInput() { this.emitEvent(); }, emitEvent: function emitEvent() { this.$emit('input', this.mfkString); }, goToNextInput: function goToNextInput(el, $event) { if (['Tab', 'Shift', 'ArrowLeft', 'ArrowRight'].includes($event.key)) return; //these keys used for form navigation, so leave them alone if (el.value.length == el.maxLength) this.FocusOnNextField(el.index); }, FocusOnNextField: function FocusOnNextField(currentImputIndex) { var nextField = "mfk_field_" + (currentImputIndex + 1); if (nextField in this.$refs) { if (this.$refs[nextField][0].disabled) //skip field if it is disabled { this.FocusOnNextField(currentImputIndex + 1); } //try focusing on next field else { this.$refs[nextField][0].focus(); } } }, fillWithZeros: function fillWithZeros(el, $event) { if (!($event.key == "Tab" && $event.shiftKey == false)) return; //only fill zeros on forward tab if (el.value.length != el.maxLength) { el.value = el.value === undefined ? '' : el.value.padEnd(el.maxLength, "0"); this.emitEvent(); } }, pasteMfk: function pasteMfk(el, $event) { //if pasting to any but first field, use default behaviour if (el.index != 0) return; var pastedValue = $event.clipboardData.getData('text/plain'); var mfkParts = this.parseMfk(pastedValue); this.mfkDefinition.forEach(function (el) { if (!el.disabled) { el.value = mfkParts[el.index] || el.value; } }); $event.preventDefault(); this.emitEvent(); }, parseMfk: function parseMfk(mfkString) { var mfkWithoutDashes = mfkString.replace(/-/g, ""); var startPosition = 0; var result = []; this.mfkDefinition.forEach(function (el) { result.push(mfkWithoutDashes.substring(startPosition, startPosition + el.maxLength)); startPosition = startPosition + el.maxLength; }); return result; } }, watch: { value: function value(oldValue, newValue) { if (this.validate) { this.validateMfk(); } } } }; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.version = exports.ValidateMfk = exports.MfkFavotire = exports.MfkInput = undefined; var _vuetify = __webpack_require__(5); var _vuetify2 = _interopRequireDefault(_vuetify); var _mfkInput = __webpack_require__(4); var _mfkInput2 = _interopRequireDefault(_mfkInput); var _mfkFavorite = __webpack_require__(3); var _mfkFavorite2 = _interopRequireDefault(_mfkFavorite); var _validateMfk = __webpack_require__(0); var _validateMfk2 = _interopRequireDefault(_validateMfk); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function plugin(Vue, options) { //Use folling components from vuetify Vue.use(_vuetify2.default); Vue.component('mfk-input', _mfkInput2.default); Vue.component('mfk-favorite', _mfkFavorite2.default); } // Install by default if using the script tag if (typeof window !== 'undefined' && window.Vue) { window.Vue.use(plugin); } exports.default = plugin; var version = '__VERSION__'; // Export all components too exports.MfkInput = _mfkInput2.default; exports.MfkFavotire = _mfkFavorite2.default; exports.ValidateMfk = _validateMfk2.default; exports.version = version; /***/ }), /* 9 */ /***/ (function(module, exports) { // removed by extract-text-webpack-plugin /***/ }), /* 10 */ /***/ (function(module, exports) { // removed by extract-text-webpack-plugin /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h; return _c('v-flex', { staticClass: "mfk-input-wrapper", attrs: { "d-inline-flex": "" } }, _vm._l((_vm.mfkElements), function(el, index) { return _c('v-text-field', { key: el.index, ref: 'mfk_field_' + el.index, refInFor: true, class: ['mfk-input', index == _vm.mfkElements.length - 1 ? 'mfk-input-last' : ''], style: ({ minWidth: el.minWidth + 'px', width: el.minWidth + 'px' }), attrs: { "name": el.name, "label": el.name, "maxlength": el.maxLength, "placeholder": '0'.repeat(el.maxLength), "mask": '#'.repeat(el.maxLength), "error": _vm.anyErrors, "error-messages": el.index == 0 && _vm.anyErrors ? [_vm.errorToDisplay] : [], "disabled": el.disabled }, on: { "input": _vm.onInput, "keyup": function($event) { _vm.goToNextInput(el, $event) }, "paste": function($event) { _vm.pasteMfk(el, $event) } }, nativeOn: { "keydown": function($event) { _vm.fillWithZeros(el, $event) } }, model: { value: (el.value), callback: function($$v) { _vm.$set(el, "value", $$v) }, expression: "el.value" } }) })) },staticRenderFns: []} module.exports.render._withStripped = true if (false) { module.hot.accept() if (module.hot.data) { require("vue-hot-reload-api").rerender("data-v-21e42b2a", module.exports) } } /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h; return _c('v-flex', { staticClass: "favorite-mfk-wrapper", attrs: { "d-inline-flex": "" } }, [_c('v-btn', { staticClass: "favorite-mfk-btn", attrs: { "flat": "", "icon": "", "small": "", "top": "", "depressed": "", "color": "indigo", "title": _vm.buttonTitle, "disabled": _vm.disabled }, on: { "click": _vm.toggleFavoriteMfk } }, [_c('v-icon', [_vm._v(_vm._s(_vm.isFavoriteMfk ? 'star' : 'star_border'))])], 1), _vm._v(" "), _c('v-select', { ref: "favoriteMfkSelector", staticClass: "favoriteMfks", attrs: { "items": _vm.optionsForFavoriteMfks, "value": _vm.selectedFavoriteMfk, "label": "Favorite MFKs", "placeholder": "Select", "dense": "", "disabled": _vm.disabled }, on: { "change": _vm.onChange }, scopedSlots: _vm._u([{ key: "selection", fn: function(data) { return [_vm._v("\n " + _vm._s(data.item.alias) + "\n ")] } }, { key: "item", fn: function(data) { return [_vm._v("\n " + _vm._s(data.item.alias) + " \n ")] } }]) })], 1) },staticRenderFns: []} module.exports.render._withStripped = true if (false) { module.hot.accept() if (module.hot.data) { require("vue-hot-reload-api").rerender("data-v-24dbf928", module.exports) } } /***/ }) /******/ ]); });