feat: jqValidateForm에 Values Type 지정

This commit is contained in:
2021-08-26 21:10:02 +09:00
parent 7bebc7da8d
commit 946fbc0933
11 changed files with 122 additions and 199 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
import { activeFlip, mb_strwidth, isBrightColor, getIconPath, errUnknown, errUnknownToast, quickReject, initTooltip } from "./common_legacy";
import { activeFlip, isBrightColor, getIconPath, errUnknown, errUnknownToast, quickReject, initTooltip } from "./common_legacy";
import { mb_strwidth } from "./util/mb_strwidth";
import { TemplateEngine } from "./util/TemplateEngine";
import { escapeHtml } from "./legacy/escapeHtml";
import { nl2br } from "./util/nl2br";
-60
View File
@@ -8,66 +8,6 @@ import 'bootstrap';
import axios from "axios";
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
//TODO: X-Requested-With 믿지 말자.
//https://gist.github.com/demouth/3217440
/**
* mb_strwidth
* @see http://php.net/manual/function.mb-strwidth.php
*/
export function mb_strwidth(str: string): number {
const l = str.length;
let length = 0;
for (let i = 0; i < l; i++) {
const c = str.charCodeAt(i);
if (0x0000 <= c && c <= 0x0019) {
length += 0;
} else if (0x0020 <= c && c <= 0x1FFF) {
length += 1;
} else if (0x2000 <= c && c <= 0xFF60) {
length += 2;
} else if (0xFF61 <= c && c <= 0xFF9F) {
length += 1;
} else if (0xFFA0 <= c) {
length += 2;
}
}
return length;
}
/**
* mb_strimwidth
* @param String
* @param int
* @param int
* @param String
* @return String
* @see http://www.php.net/manual/function.mb-strimwidth.php
*/
export function mb_strimwidth(str: string, start: number, width: number, trimmarker = ''): string {
const trimmakerWidth = mb_strwidth(trimmarker);
const l = str.length;
let trimmedLength = 0;
const trimmedStr: string[] = [];
for (let i = start; i < l; i++) {
const c = str.charAt(i);
const charWidth = mb_strwidth(c);
const next = str.charAt(i + 1);
const nextWidth = mb_strwidth(next);
trimmedLength += charWidth;
trimmedStr.push(c);
if (trimmedLength + trimmakerWidth + nextWidth > width) {
trimmedStr.push(trimmarker);
break;
}
}
return trimmedStr.join('');
}
/**
* object의 array를 id를 key로 삼는 object로 재 변환
*/
+17 -3
View File
@@ -5,8 +5,7 @@ import 'bootstrap';
import { setAxiosXMLHttpRequest } from "./util/setAxiosXMLHttpRequest";
import axios from "axios";
import { InvalidResponse } from "./defs";
import { Rules } from "async-validator";
import { JQValidateForm } from "./util/jqValidateForm";
import { JQValidateForm, NamedRules } from "./util/jqValidateForm";
import { convertFormData } from "./util/convertFormData";
type ResponseScenarioItem = {
@@ -130,7 +129,22 @@ function scenarioPreview() {
});
}
const descriptor: Rules = {
type InstallFormType = {
turnterm: number,
sync: 1|0,
scenario: number,
fiction: number,
extend: number,
npcmode: number,
show_img_level: number,
tournament_trig: number,
join_mode: number,
autorun_user: string[],
autorun_user_minutes: number,
reserve_open?: string,
pre_reserve_open?: string,
}
const descriptor: NamedRules<InstallFormType> = {
turnterm: {
required: true,
type: "enum",
+10 -3
View File
@@ -1,8 +1,7 @@
import axios from 'axios';
import jQuery from 'jquery';
import { Rules } from 'async-validator';
import { JQValidateForm } from './util/jqValidateForm';
import { JQValidateForm, NamedRules } from './util/jqValidateForm';
import { convertFormData } from './util/convertFormData';
import { InvalidResponse } from './defs';
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
@@ -10,7 +9,15 @@ import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
jQuery(async function ($) {
setAxiosXMLHttpRequest();
const descriptor: Rules = {
type FormValue = {
full_reset: string,
db_host: string,
db_port: number,
db_id: string,
db_pw: string,
db_name: string,
}
const descriptor: NamedRules<FormValue> = {
full_reset: {
required: true,
},
+4 -4
View File
@@ -3,7 +3,7 @@ import { isArray, isString, isNumber, isBoolean } from "lodash";
export function convertFormData(values: Record<string, null|number[]|string[]|boolean[]|number|string|boolean>): FormData{
const formData = new FormData();
const simpleConv = (v: unknown):string=>{
const simpleConv = (v: unknown, key: string):string=>{
if(isString(v)){
return v;
}
@@ -16,19 +16,19 @@ export function convertFormData(values: Record<string, null|number[]|string[]|bo
if(v===null){
return '';
}
throw new TypeError('지원하지 않는 formData Type');
throw new TypeError(`지원하지 않는 formData Type: ${key}`);
}
for(const [key, value] of Object.entries(values)){
if(isArray(value)){
const arrKey = `${key}[]`;
for(const subValue of value){
formData.append(arrKey, simpleConv(subValue));
formData.append(arrKey, simpleConv(subValue, key));
}
continue;
}
formData.append(key, simpleConv(value));
formData.append(key, simpleConv(value, key));
}
return formData;
+12 -5
View File
@@ -1,4 +1,4 @@
import Schema, { Rules, Values } from "async-validator";
import Schema, { Rule, Values } from "async-validator";
import { isArray } from "lodash";
import { mergeKVArray } from "./mergeKVArray";
import $ from 'jquery';
@@ -8,10 +8,17 @@ type Option = {
postParse?: (values:Record<string, string | string[]>, $target?: JQuery<HTMLElement>)=>[Record<string, string | string[]>, Map<string, string>]
}
export class JQValidateForm {
type DefaultFormDataType = Record<string, null|number[]|string[]|boolean[]|number|string|boolean>;
export type NamedRules<T extends Record<string, unknown>> = {
[v in keyof T]: Rule
}
export class JQValidateForm<TypedValue extends Values = DefaultFormDataType> {
public readonly validator: Schema;
public readonly inputs: JQuery<HTMLElement>;
constructor(public readonly target: JQuery<HTMLElement>, public readonly rule: Rules, public readonly option?:Option) {
constructor(public readonly target: JQuery<HTMLElement>, public readonly rule: NamedRules<TypedValue>, public readonly option?:Option) {
this.validator = new Schema(rule);
this.inputs = target.find(':input');
}
@@ -29,7 +36,7 @@ export class JQValidateForm {
return this;
}
public async validate(): Promise<undefined | Values> {
public async validate(): Promise<undefined | TypedValue> {
if(this.option?.preParse !== undefined){
this.option.preParse(this.target);
}
@@ -106,6 +113,6 @@ export class JQValidateForm {
}
this.clearErrMsg();
this.inputs.addClass('is-valid');
return validateResult;
return validateResult as TypedValue;
}
}
+31
View File
@@ -0,0 +1,31 @@
import { mb_strwidth } from "./mb_strwidth";
/**
* mb_strimwidth
* @param String
* @param int
* @param int
* @param String
* @return String
* @see http://www.php.net/manual/function.mb-strimwidth.php
*/
export function mb_strimwidth(str: string, start: number, width: number, trimmarker = ''): string {
const trimmakerWidth = mb_strwidth(trimmarker);
const l = str.length;
let trimmedLength = 0;
const trimmedStr: string[] = [];
for (let i = start; i < l; i++) {
const c = str.charAt(i);
const charWidth = mb_strwidth(c);
const next = str.charAt(i + 1);
const nextWidth = mb_strwidth(next);
trimmedLength += charWidth;
trimmedStr.push(c);
if (trimmedLength + trimmakerWidth + nextWidth > width) {
trimmedStr.push(trimmarker);
break;
}
}
return trimmedStr.join('');
}
+25
View File
@@ -0,0 +1,25 @@
//TODO: X-Requested-With 믿지 말자.
//https://gist.github.com/demouth/3217440
/**
* mb_strwidth
* @see http://php.net/manual/function.mb-strwidth.php
*/
export function mb_strwidth(str: string): number {
const l = str.length;
let length = 0;
for (let i = 0; i < l; i++) {
const c = str.charCodeAt(i);
if (0x0000 <= c && c <= 0x0019) {
length += 0;
} else if (0x0020 <= c && c <= 0x1FFF) {
length += 1;
} else if (0x2000 <= c && c <= 0xFF60) {
length += 2;
} else if (0xFF61 <= c && c <= 0xFF9F) {
length += 1;
} else if (0xFFA0 <= c) {
length += 2;
}
}
return length;
}