jenesius-vue-form
Advanced tools
Comparing version 2.0.6 to 2.0.7
@@ -125,2 +125,4 @@ import EventEmitter from "jenesius-event-emitter"; | ||
set save(callback: FunctionHandleData); | ||
/**VALIDATION**/ | ||
validate(): any; | ||
} | ||
@@ -127,0 +129,0 @@ interface FormParams { |
@@ -1,52 +0,23 @@ | ||
import { ValidationRule } from "../types"; | ||
import EventEmitter from "jenesius-event-emitter"; | ||
export declare class Input extends EventEmitter { | ||
static EVENT_NEW_VALUE: string; | ||
static EVENT_CHANGE_DISABLED: string; | ||
value: any; | ||
import Form from "./Form"; | ||
export default class Input extends EventEmitter { | ||
parentForm: Form; | ||
name: string; | ||
disabled: boolean; | ||
hidden: boolean; | ||
validation: InputParams["validation"]; | ||
validation: any[]; | ||
constructor(params: InputParams); | ||
disable(): void; | ||
enable(): void; | ||
private setDisabled; | ||
setValue(v: any): void; | ||
hide(): void; | ||
show(): void; | ||
get value(): import("../types").Values | undefined; | ||
get disabled(): boolean; | ||
change(v: any): void; | ||
/** | ||
* @deprecated | ||
* @description Run all guards from validation. Input is not validated If on | ||
* e of guard don't return true. | ||
* @return Array {} Array of string messages. | ||
* | ||
* */ | ||
setChange(v: any): void; | ||
getValue(): any; | ||
errors: any[]; | ||
validate(): boolean; | ||
validate(): string[]; | ||
} | ||
export declare function Input1(params: InputParams): InputInterface; | ||
export declare function useInputState(input: Input): { | ||
value: any; | ||
disabled: boolean; | ||
}; | ||
export interface InputParams { | ||
interface InputParams { | ||
name: string; | ||
validation?: ValidationRule[]; | ||
validation?: any[]; | ||
} | ||
export interface InputInterface { | ||
name: string; | ||
value: any; | ||
changed: boolean; | ||
setValue: (v: any) => void; | ||
setChange: InputInterface["setValue"]; | ||
getValue: () => any; | ||
validate: () => boolean; | ||
errors: string[]; | ||
disabled: boolean; | ||
disable: () => void; | ||
enable: () => void; | ||
hidden: boolean; | ||
hide: () => void; | ||
show: () => void; | ||
type?: string; | ||
} | ||
export {}; |
@@ -1,11 +0,9 @@ | ||
export default function useInputState(name: string): { | ||
import Input from "../classes/Input"; | ||
export default function useInputState(name: string, validation?: any[]): { | ||
state: { | ||
value: { | ||
[x: string]: any; | ||
} | undefined; | ||
value: any; | ||
disabled: boolean; | ||
errors: string[]; | ||
}; | ||
input: { | ||
change: (v: any) => void; | ||
}; | ||
input: Input; | ||
}; |
@@ -6,1 +6,2 @@ export interface Values { | ||
export declare type FunctionHandleData = () => Promise<any> | any | void; | ||
export declare type ValidationGuard = () => void; |
@@ -1,1 +0,1 @@ | ||
export declare function runPromiseQueue(guards: Array<any>): Promise<void>; | ||
export default function runPromiseQueue(guards: Array<any>): Promise<void>; |
/*! | ||
* jenesius-vue-form v2.0.6 | ||
* jenesius-vue-form v2.0.7 | ||
* (c) 2022 Jenesius | ||
@@ -118,29 +118,2 @@ * @license MIT | ||
/** | ||
* раскладывает составное значение | ||
* */ | ||
function deepenObject(value) { | ||
if (typeof value !== 'object') | ||
return value; | ||
if (value === null || value === undefined) | ||
return value; | ||
return Object.keys(value).reduce((acc, key) => mergeObjects(acc, deepenValue(key, value[key])), {}); | ||
} | ||
/** | ||
* Раскладывает составное имя и значение | ||
* */ | ||
function deepenValue(name, value) { | ||
const output = {}; | ||
let currentLink = output; | ||
// Разбиваем имя на подимена, если состоит из точек | ||
const splitName = name.split('.'); | ||
splitName.forEach((n, index) => { | ||
currentLink[n] = {}; | ||
if (index === splitName.length - 1) | ||
currentLink[n] = deepenObject(value); | ||
currentLink = currentLink[n]; | ||
}); | ||
return output; | ||
} | ||
function runPromiseQueue(guards) { | ||
@@ -165,3 +138,3 @@ return guards.reduce((promiseAccumulator, fn) => promiseAccumulator.then((x) => fn === null || fn === void 0 ? void 0 : fn(x)), Promise.resolve()); | ||
} | ||
function replaceValues(object, value) { | ||
function replaceValues(object, value = true) { | ||
const copyObject = JSON.parse(JSON.stringify(object)); | ||
@@ -185,2 +158,52 @@ return replace(copyObject, value); | ||
function step(array, value, path = []) { | ||
if (checkPrimitiveType(value)) | ||
return; | ||
Object.keys(value) | ||
.forEach(key => { | ||
const parsedKey = key.split('.'); | ||
const p = [...path, ...parsedKey]; // Step path | ||
const v = value[key]; // Step value | ||
if (checkPrimitiveType(v)) { | ||
array.push({ | ||
path: p, | ||
value: v | ||
}); | ||
return; | ||
} | ||
step(array, v, p); | ||
}); | ||
} | ||
/** | ||
* @description Функция проходит по всем полям объекта. | ||
* @return Array of {path: string[], value: any} | ||
*/ | ||
function bypassObject(object) { | ||
const array = []; | ||
step(array, object); | ||
return array; | ||
} | ||
function grandObject(object) { | ||
return bypassObject(object) | ||
.reduce((acc, { path, value }) => { | ||
let link = acc; | ||
let index = 0; | ||
while (index !== path.length) { | ||
const name = path[index]; | ||
// last item | ||
if (index === path.length - 1) | ||
link[name] = value; | ||
else { | ||
link = link[name] || (() => { | ||
link[name] = {}; | ||
return link[name]; | ||
})(); | ||
} | ||
index++; | ||
} | ||
return acc; | ||
}, {}); | ||
} | ||
var _Form_values, _Form_changes, _Form_debug, _Form_disabled, _Form_handleDE, _Form_disabledElements, _Form_readData, _Form_saveData; | ||
@@ -293,3 +316,3 @@ class Form extends EventEmitter__default["default"] { | ||
} | ||
const v = deepenObject(replaceValues(values, true)); | ||
const v = grandObject(replaceValues(values)); | ||
mergeObjects(__classPrivateFieldGet(this, _Form_changes, "f"), v); | ||
@@ -373,3 +396,3 @@ if (this.changed) | ||
if (values) { | ||
const _v = deepenObject(values); | ||
const _v = grandObject(values); | ||
this.mergeValues(_v); | ||
@@ -542,2 +565,11 @@ } | ||
} | ||
/**VALIDATION**/ | ||
validate() { | ||
return this.dependencies.reduce((acc, dep) => { | ||
if (dep.validate) { | ||
acc = acc && dep.validate(); | ||
} | ||
return acc; | ||
}, true); | ||
} | ||
} | ||
@@ -592,9 +624,51 @@ _Form_values = new WeakMap(), _Form_changes = new WeakMap(), _Form_debug = new WeakMap(), _Form_disabled = new WeakMap(), _Form_handleDE = new WeakMap(), _Form_disabledElements = new WeakMap(), _Form_readData = new WeakMap(), _Form_saveData = new WeakMap(); | ||
function useInputState(name) { | ||
const parentForm = vue.inject(Form.PROVIDE_NAME); | ||
class Input extends EventEmitter__default["default"] { | ||
constructor(params) { | ||
super(); | ||
this.validation = []; | ||
this.name = params.name; | ||
this.parentForm = Form.getParentForm(); | ||
if (params.validation) | ||
this.validation = params.validation; | ||
} | ||
get value() { | ||
return this.parentForm.getValueByName(this.name); | ||
} | ||
get disabled() { | ||
return this.parentForm.getDisabledByName(this.name); | ||
} | ||
change(v) { | ||
this.parentForm.input(this.name, v); | ||
} | ||
/** | ||
* @description Run all guards from validation. Input is not validated If on | ||
* e of guard don't return true. | ||
* @return Array {} Array of string messages. | ||
* | ||
* */ | ||
validate() { | ||
return this.validation.reduce((acc, guard) => { | ||
const guardResult = guard(this.value); | ||
if (guardResult !== true) | ||
acc.push(guardResult); | ||
return acc; | ||
}, []); | ||
} | ||
} | ||
function useInputState(name, validation = []) { | ||
const input = new Input({ name, validation }); | ||
const state = useInputController(input); | ||
return { | ||
state, | ||
input | ||
}; | ||
} | ||
function useInputController(input) { | ||
const state = vue.reactive({ | ||
value: parentForm.getValueByName(name), | ||
disabled: parentForm.getDisabledByName(name) | ||
value: input.value, | ||
disabled: input.disabled, | ||
errors: [] | ||
}); | ||
const off = parentForm.dependInput(name, { | ||
const controls = { | ||
change: (v) => { | ||
@@ -611,19 +685,13 @@ state.value = v; | ||
show: () => { }, | ||
validate: () => { }, | ||
validate: () => { | ||
state.errors = input.validate(); | ||
return state.errors.length === 0; | ||
}, | ||
focus: () => { } | ||
}); | ||
}; | ||
const off = input.parentForm.dependInput(input.name, controls); | ||
vue.onUnmounted(() => { | ||
off(); | ||
}); | ||
/** | ||
* Предоставляется фронтенду, презентейшен view. | ||
* */ | ||
return { | ||
state, | ||
input: { | ||
change: (v) => { | ||
parentForm.input(name, v); | ||
}, | ||
} | ||
}; | ||
return state; | ||
} | ||
@@ -712,3 +780,4 @@ | ||
name: { type: String, required: true }, | ||
label: { type: String, required: false } | ||
label: { type: String, required: false }, | ||
validation: { type: Array, required: false, default: () => [] } | ||
}, | ||
@@ -721,13 +790,11 @@ setup(__props) { | ||
const componentItem = vue.computed(() => store[props.type] || store.text); | ||
const { state, input } = useInputState(props.name); | ||
function test(a) { | ||
input.change(a); | ||
} | ||
const { state, input } = useInputState(props.name, props.validation); | ||
return (_ctx, _cache) => { | ||
return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(vue.unref(componentItem)), { | ||
modelValue: vue.unref(state).value, | ||
"onUpdate:modelValue": test, | ||
label: __props.label, | ||
disabled: vue.unref(state).disabled | ||
}, null, 8, ["modelValue", "label", "disabled"]); | ||
"onUpdate:modelValue": _cache[0] || (_cache[0] = (v) => vue.unref(input).change(v)), | ||
label: props.label, | ||
disabled: vue.unref(state).disabled, | ||
errors: vue.unref(state).errors | ||
}, null, 8, ["modelValue", "label", "disabled", "errors"]); | ||
}; | ||
@@ -734,0 +801,0 @@ } |
{ | ||
"name": "jenesius-vue-form", | ||
"version": "2.0.6", | ||
"version": "2.0.7", | ||
"description": "Heavy form system for Vue.js", | ||
@@ -48,2 +48,3 @@ "author": "Jenesius", | ||
"@rollup/plugin-typescript": "^8.3.2", | ||
"@types/jest": "^28.1.1", | ||
"@typescript-eslint/eslint-plugin": "^5.25.0", | ||
@@ -61,3 +62,3 @@ "@typescript-eslint/parser": "^5.25.0", | ||
"eslint-plugin-vue": "^9.0.1", | ||
"jest": "26.6.3", | ||
"jest": "^26.6.3", | ||
"rollup-plugin-postcss": "^4.0.2", | ||
@@ -74,6 +75,3 @@ "rollup-plugin-vue": "^6.0.0", | ||
"not ie 11" | ||
], | ||
"dependencies": { | ||
} | ||
] | ||
} |
@@ -28,3 +28,3 @@ # Jenesius Vue Form | ||
import {useFormState} from "jenesius-vue-modal" | ||
const {state} = useFormState(form) | ||
const {state} = useFormState(form) // disabled changed | ||
``` | ||
@@ -53,3 +53,4 @@ | ||
import {useInputState} from "jenesius-vue-modal" | ||
const {state, input} = useInputState(props.name); | ||
const {state, input} = useInputState(props.name) | ||
// state - {value, disabled} | ||
``` | ||
@@ -59,3 +60,10 @@ - **input** - контроллер для работы с виджетом. Необходим для обработки изменения | ||
## Validation | ||
Для валидации формы испольхуется метод **validate**, который вернёт true в случае | ||
если всё зависимые элементы - валидны: | ||
```js | ||
form.validate(); // true or false | ||
``` | ||
## Основная логика | ||
@@ -82,1 +90,2 @@ 1. Значения хранятся только в **агригатном элементе** | ||
- **label** метка элемента. Используется как заголовок. | ||
- **validation** массив обработчиков валидности поля. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
55164
38
1286
88
24