Compare commits

...

8 Commits

Author SHA1 Message Date
xiaozhe.ma
6fff3ec006 条件設定関連No511,512障害修正 2024-07-18 17:40:17 +09:00
Yukina Mori
64e72a66d5 Merged PR 52: fix: 値挿入のコンポーネント BUG523 [値挿入]日時に挿入できない BUG517 [値挿入]対象イベント編集成功後に挿入されない の修正
fix: 値挿入のコンポーネント BUG523 [値挿入]日時に挿入できない BUG517 [値挿入]対象イベント編集成功後に挿入されない の修正

BUG523 「2024-07-05T01:32:25.552Z」(ミリ秒を含めた)日時形式と「2024-07-28T17:00:00Z」(ミリ秒を含めない)日時形式も日時フィールドに値挿入できるよう、修正いたしました。

BUG517 保存成功時イベントに値が挿入されないため、保存成功時イベントはasync/await による非同期処理でフィールドに値を挿入、レコードを更新するよう修正いたしました。

Related work items: #517, #523
2024-07-18 06:21:19 +00:00
Moriyukina2
af5f27c8c5 fix: 値挿入のコンポーネント BUG523 [値挿入]日時に挿入できない BUG517 [値挿入]対象イベント編集成功後に挿入されない の修正 2024-07-18 14:53:04 +09:00
Yu Wang
5823c989c2 Merged PR 51: Bug510保存成功後イベントで文字結合複数設定の非同期処理修正
Bug510保存成功後イベントで、文字結合の複数設定の非同期処理修正。
feat239文字結合。

Related work items: #239, #510
2024-07-17 13:28:35 +00:00
王玉
ee362a6a93 Bug510保存成功後イベントで文字結合複数設定できるように非同期処理修正 2024-07-17 21:34:47 +09:00
Kanaru Tsuda
6ba1e0d958 Merged PR 49: Bug 518,519 feat 236,284 全半角チェックのバグ修正の為のコード再構築
Bug 518,519 feat 236,284
全半角チェックのバグ修正の為のコード再構築
エラーメッセージの正常時に表示されていたバグの解消

Related work items: #236, #284, #518, #519
2024-07-17 05:11:03 +00:00
kanarutsuda
fde66aa480 全半角チェックのバグ修正の為のコード再構築 2024-07-17 14:00:18 +09:00
Shohtetsu Ma
79a8598468 Merged PR 48: レコード作成および更新アクション
以下の内容を更新しました。
1.指定アプリのレコード作成および更新アクション
2.関連の共通部分のUIの修正

Related work items: #252, #253
2024-07-12 13:17:35 +00:00
12 changed files with 261 additions and 154 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
#開発環境
KAB_BACKEND_URL="https://kab-backend.azurewebsites.net/"
#KAB_BACKEND_URL="https://kab-backend.azurewebsites.net/"
#単体テスト環境
#KAB_BACKEND_URL="https://kab-backend-unittest.azurewebsites.net/"
#ローカル開発環境
#KAB_BACKEND_URL="http://127.0.0.1:8000/"
KAB_BACKEND_URL="http://127.0.0.1:8000/"

View File

@@ -1,5 +1,4 @@
<template>
<div class="q-pa-sm">
<q-field labelColor="primary" class="condition-object" dense outlined :label="label" :disable="disabled"
:clearable="isSelected">
<template v-slot:control>
@@ -26,19 +25,20 @@
<condition-objects ref="appDg" name="フィールド" type="single" :filter="filter" :appId="store.appInfo?.appId" :vars="vars"></condition-objects>
-->
<DynamicItemInput v-model:selectedObject="selectedObject" :canInput="config.canInput"
:buttonsConfig="config.buttonsConfig" :appId="store.appInfo?.appId" />
:buttonsConfig="config.buttonsConfig" :appId="store.appInfo?.appId" :options="options" ref="inputRef" />
</show-dialog>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, watchEffect, computed } from 'vue';
import { defineComponent, reactive, ref, watchEffect, computed ,PropType} from 'vue';
import ShowDialog from '../ShowDialog.vue';
// import ConditionObjects from '../ConditionObjects.vue';
import DynamicItemInput from '../DynamicItemInput/DynamicItemInput.vue';
import { useFlowEditorStore } from '../../stores/flowEditor';
import { IActionFlow, IActionNode, IActionVariable } from '../../types/ActionTypes';
import { IDynamicInputConfig } from 'src/types/ComponentTypes';
export default defineComponent({
name: 'ConditionObject',
@@ -57,7 +57,7 @@ export default defineComponent({
default: undefined
},
config: {
type: Object,
type: Object as PropType<IDynamicInputConfig>,
default: () => {
return {
canInput: false,
@@ -68,6 +68,12 @@ export default defineComponent({
};
}
},
options:
{
type:Array as PropType< string[]>,
default:()=>[]
},
modelValue: {
type: Object,
default: null
@@ -75,6 +81,7 @@ export default defineComponent({
},
setup(props, { emit }) {
// const appDg = ref();
const inputRef=ref();
const show = ref(false);
const selectedObject = ref(props.modelValue);
const store = useFlowEditorStore();
@@ -97,6 +104,7 @@ export default defineComponent({
const closeDg = (val: string) => {
if (val == 'OK') {
// selectedObject.value = appDg.value.selected[0];
selectedObject.value = inputRef.value.selectedObjectRef
}
};
@@ -105,6 +113,7 @@ export default defineComponent({
});
return {
inputRef,
store,
// appDg,
show,

View File

@@ -69,17 +69,19 @@
<div class="row no-wrap items-center q-my-xs">
<ConditionObject v-bind="prop.node" v-model="prop.node.object" :config="leftDynamicItemConfig" class="col-4"/>
<q-select v-model="prop.node.operator" :options="operators" class="operator" :outlined="true" :dense="true"></q-select>
<ConditionObject v-bind="prop.node" v-model="prop.node.value" :config="rightDynamicItemConfig" class="col-4"/>
<ConditionObject v-bind="prop.node" v-model="prop.node.value" :config="rightDynamicItemConfig" class="col-4"
:options="objectValueOptions(prop.node?.object?.options)"
/>
<!-- <ConditionObject v-bind="prop.node" v-model="prop.node.object" class="col-4"/> -->
<!-- <q-input v-if="!prop.node.object || !('options' in prop.node.object)"
v-model="prop.node.value"
class="condition-value" :outlined="true" :dense="true" ></q-input> -->
<q-select v-if="prop.node.object && ('options' in prop.node.object)"
<!-- <q-select v-if="prop.node.object && ('options' in prop.node.object)"
v-model="prop.node.value"
:options="objectValueOptions(prop.node.object.options)"
clearable
value-key="index"
class="condition-value" :outlined="true" :dense="true" ></q-select>
class="condition-value" :outlined="true" :dense="true" ></q-select> -->
<q-btn flat round dense icon="more_horiz" size="sm" >
<q-menu auto-close anchor="top right">
<q-list>
@@ -118,6 +120,7 @@ import { finished } from 'stream';
import { defineComponent,ref,reactive, computed, inject } from 'vue';
import { INode,ConditionTree,GroupNode,ConditionNode, LogicalOperator,Operator,NodeType } from '../../types/Conditions';
import ConditionObject from './ConditionObject.vue';
import { IDynamicInputConfig } from 'src/types/ComponentTypes';
export default defineComponent( {
name: 'NodeCondition',
components: {
@@ -145,17 +148,18 @@ export default defineComponent( {
return opts;
});
const operator = inject('Operator')
const operators =computed(()=>{
return operator ? operator : Object.values(Operator);
});
const operatorSet = inject<Array<any>>('Operator')
const operators = ref(operatorSet ? operatorSet : Object.values(Operator));
const tree = reactive(props.conditionTree);
const conditionString = computed(()=>{
return tree.buildConditionString(tree.root);
});
const objectValueOptions=(options:any):any[]=>{
const objectValueOptions=(options:any):any[]|null=>{
if(!options){
return null;
}
const opts:any[] =[];
Object.keys(options).forEach((key) =>
{
@@ -222,13 +226,14 @@ export default defineComponent( {
ticked.value=[];
}
const expanded=computed(()=>tree.getGroups(tree.root));
// addCondition(tree.root);
const leftDynamicItemConfig = inject<IDynamicInputConfig>('leftDynamicItemConfig');
const rightDynamicItemConfig = inject<IDynamicInputConfig>('rightDynamicItemConfig');
return {
leftDynamicItemConfig :inject('leftDynamicItemConfig'),
rightDynamicItemConfig:inject('rightDynamicItemConfig'),
leftDynamicItemConfig,
rightDynamicItemConfig,
showingCondition,
conditionString,
tree,
@@ -260,10 +265,11 @@ export default defineComponent( {
max-height: 40px;
margin: 0 2px;
}
.operator{
min-width: 150px;
max-height: 40px;
margin-left: 12px;
margin: 0 2px;
text-align: center;
font-size: 12pt;

View File

@@ -2,13 +2,30 @@
<div class="q-mx-md" style="max-width: 600px;">
<!-- <q-card> -->
<div class="q-mb-md">
<q-input ref="inputRef" outlined dense debounce="200" @update:model-value="updateSharedText"
v-model="sharedText" :readonly="!canInput" autogrow>
<q-input ref="inputRef" v-if="!optionsRef|| optionsRef.length===0"
outlined dense debounce="200" @update:model-value="updateSharedText"
v-model="sharedText" :readonly="!canInputFlag" autogrow>
<template v-slot:append>
<q-btn flat round padding="none" icon="cancel" @click="clearSharedText" color="grey-6" />
</template>
</q-input>
<q-select v-if="optionsRef && optionsRef.length>0"
:model-value="sharedText"
:options="optionsRef"
clearable
value-key="index"
outlined
dense
use-input
hide-selected
input-debounce="10"
fill-input
@input-value="setValue"
@clear="sharedText=null"
hide-dropdown-icon
:readonly="!canInputFlag"
>
</q-select>
</div>
<div class="row q-gutter-sm">
@@ -34,18 +51,12 @@
</template>
<script lang="ts">
import { ref, inject, watchEffect, defineComponent } from 'vue';
import { ref, inject, watchEffect, defineComponent,PropType } from 'vue';
import FieldAdd from './FieldAdd.vue';
import VariableAdd from './VariableAdd.vue';
// import FunctionAdd from './FunctionAdd.vue';
import ShowDialog from '../ShowDialog.vue';
type ButtonConfig = {
label: string;
color: string;
type: string;
editable: boolean;
};
import { IButtonConfig } from 'src/types/ComponentTypes';
export default defineComponent({
name: 'DynamicItemInput',
@@ -56,18 +67,21 @@ export default defineComponent({
ShowDialog
},
props: {
// canInput: {
// type: Boolean,
// default: false
// },
canInput: {
type: Boolean,
default: false
},
appId: {
type: String,
},
selectedObject: {
default: {}
},
options:{
type:Array as PropType< string[]>
},
buttonsConfig: {
type: Array as () => ButtonConfig[],
type: Array as PropType<IButtonConfig[]>,
default: () => [
{ label: 'フィールド', color: 'primary', type: 'FieldAdd' }
]
@@ -77,17 +91,18 @@ export default defineComponent({
const filter = ref('');
const dialogVisible = ref(false);
const currentDialogName = ref('');
const selectedObjectRef = ref(props.selectedObject);
const currentComponent = ref('FieldAdd');
const sharedText = ref(props.selectedObject?.sharedText ?? '');
const inputRef = ref();
const canInput = ref(true);
const canInputFlag = ref(props.canInput);
const editable = ref(false);
const openDialog = (button: ButtonConfig) => {
const openDialog = (button: IButtonConfig) => {
currentDialogName.value = button.label;
currentComponent.value = button.type;
dialogVisible.value = true;
editable.value = button.editable ?? true;
editable.value = canInputFlag.value;
};
const closeDialog = () => {
@@ -95,46 +110,51 @@ export default defineComponent({
};
const handleSelect = (value:any) => {
// 获取当前光标位置
// const cursorPosition = inputRef.value.getNativeElement().selectionStart;
// if (cursorPosition === undefined || cursorPosition === 0) {
sharedText.value = `${value._t}`;
// } else {
// const textBefore = sharedText.value.substring(0, cursorPosition);
// const textAfter = sharedText.value.substring(cursorPosition);
// sharedText.value = `${textBefore}${value._t}${textAfter}`;
// }
if (value && value._t && (value._t as string).length > 0) {
canInput.value = editable.value;
canInputFlag.value = editable.value;
}
emit('update:selectedObject', { sharedText: sharedText.value, ...value });
selectedObjectRef.value={ sharedText: value._t, ...value };
sharedText.value = `${value._t}`;
// emit('update:selectedObject', { sharedText: sharedText.value, ...value });
dialogVisible.value = false;
};
const clearSharedText = () => {
sharedText.value = '';
canInput.value = true;
emit('update:selectedObject', {});
selectedObjectRef.value={};
canInputFlag.value = true;
// emit('update:selectedObject', {});
}
const updateSharedText = (value:string) => {
sharedText.value = value;
emit('update:selectedObject', { ...props.selectedObject, sharedText: value,objectType:'text' });
selectedObjectRef.value= { sharedText: value,objectType:'text' }
// emit('update:selectedObject', { ...props.selectedObject, sharedText: value,objectType:'text' });
}
const setValue=(value:string)=>{
sharedText.value = value;
if(selectedObjectRef.value.sharedText!==value){
selectedObjectRef.value= { sharedText: value,objectType:'text' }
}
}
const optionsRef=ref(props.options);
return {
filter,
dialogVisible,
currentDialogName,
currentComponent,
canInput,
canInputFlag,
openDialog,
closeDialog,
handleSelect,
clearSharedText,
updateSharedText,
setValue,
sharedText,
inputRef
inputRef,
optionsRef,
selectedObjectRef
};
}
});

View File

@@ -18,38 +18,13 @@
</div>
</template>
<script lang="ts">
import { ConditionNode, ConditionTree, Operator, OperatorListItem } from 'app/src/types/Conditions';
import { computed, defineComponent, provide, reactive, ref, watchEffect } from 'vue';
import ConditionEditor from '../ConditionEditor/ConditionEditor.vue';
import { IActionProperty } from 'src/types/ActionTypes';
import { } from 'src/types/';
type Props = {
props?: {
name: string;
modelValue?: {
app: {
id: string;
name: string;
},
fields: {
type: string;
label: string;
code: string;
}[]
}
}
};
type InputConfg = {
canInput: boolean;
buttonsConfig: {
label: string;
color: string;
type: string;
}[]
};
export default defineComponent({
@@ -60,7 +35,7 @@ export default defineComponent({
},
props: {
context: {
type: Array<Props>,
type: Array<IActionProperty>,
default: '',
},
displayName: {
@@ -115,7 +90,7 @@ export default defineComponent({
},
setup(props, { emit }) {
const source = props.context.find(element => element?.props?.name === 'sources')
const source = props.context.find(element => element.props.name === 'sources')
if (source) {
if (props.sourceType === 'field') {

View File

@@ -15,8 +15,15 @@
<q-icon name="search" class="cursor-pointer" color="primary" @click="showDg" />
</template>
</q-field>
<show-dialog v-model:visible="show" name="フィールド一覧" @close="closeDg" widht="400px">
<field-select ref="appDg" name="フィールド" :type="selectType" :appId="store.appInfo?.appId" :fieldTypes="fieldTypes"></field-select>
<show-dialog v-model:visible="show" name="フィールド一覧" @close="closeDg" min-width="400px">
<template v-slot:toolbar>
<q-input dense debounce="300" v-model="filter" placeholder="検索" clearable>
<template v-slot:before>
<q-icon name="search" />
</template>
</q-input>
</template>
<field-select ref="appDg" name="フィールド" :type="selectType" :appId="store.appInfo?.appId" :fieldTypes="fieldTypes" :filter="filter"></field-select>
</show-dialog>
</div>
</template>
@@ -99,7 +106,8 @@ export default defineComponent({
showDg,
closeDg,
selectedField,
isSelected
isSelected,
filter:ref(''),
};
}
});

View File

@@ -0,0 +1,50 @@
export interface IApp {
id: string,
name: string
}
export interface IField {
label?:string;
code:string;
type?:string;
required?:boolean;
options?:string;
}
/**
* 選択されたフィールド
*/
export interface ISelectedField extends IField{
objectType:'Field'|'RefField';
}
export interface IAppFields {
app?: IApp,
name?:string;
fields: IField[]
}
/**
* 条件式の入力ボタンの属性定義
*/
export interface IButtonConfig{
label: string;
color: string;
type: 'FieldAdd' | 'VariableAdd' | 'FunctionAdd';
};
/**
* 条件入力項目の属性
*/
export interface IDynamicInputConfig{
canInput: boolean;
buttonsConfig: IButtonConfig[];
}
/**
* 条件式入力項目の属性
*/
export interface ICoditionConfig{
left:IDynamicInputConfig,
right:IDynamicInputConfig
}

View File

@@ -88,7 +88,8 @@ export class InsertValueAction implements IAction{
let singleDigitMonthDay = inputValue.match(/(\d{4})-(\d{1})-(\d{1})$/);//4桁の数字-1桁の数字-2桁の数字
let singleDigitMonth = inputValue.match(/(\d{4})-(\d{1})-(\d{2})$/);//4桁の数字-1桁の数字-2桁の数字
let singleDigitDay = inputValue.match(/(\d{4})-(\d{2})-(\d{1})$/);//4桁の数字-2桁の数字-1桁の数字
let dateTime = inputValue.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).000Z/);//時刻入りのUTCの日付形式
let dateTimeMilliSecond = inputValue.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).(\d{2,3})Z$/);//時刻入りのUTCの日付形式(ミリ秒)
let dateTime = inputValue.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/);//時刻入りのUTCの日付形式
let date;
//date型に変換
date = new Date(inputValue);
@@ -96,7 +97,7 @@ export class InsertValueAction implements IAction{
//date型変換できたか確認
if(date !== undefined && !isNaN(date.getDate())){
//正規表現チェック確認
if(twoDigitMonthDay === null && singleDigitMonth === null && singleDigitDay === null && singleDigitMonthDay === null && dateTime === null){
if(twoDigitMonthDay === null && singleDigitMonth === null && singleDigitDay === null && singleDigitMonthDay === null && dateTime === null && dateTimeMilliSecond === null){
event.record[fieldCode]['error'] = "「"+fieldCode+"」"+"フィールドに入れようとした値は、無効な日付形式です。"; //レコードにエラーを表示
throw new Error("「"+fieldCode+"」"+"フィールドに入れようとした値は、無効な日付形式です。「値を挿入する」コンポーネントの処理を中断しました。");
}
@@ -440,6 +441,9 @@ export class InsertValueAction implements IAction{
}
}
//保存成功イベントの場合、kintone async/await による非同期処理でフィールドに値を挿入する
if(!event.type.includes('success')){
//条件式の結果がtrueかつ挿入する値が変換できた場合、フィールドラジオボタン・ドロップダウン・チェックボックス・複数選択・文字列一行・文字列複数行・リッチエディタ・数値・日付・日時・時刻にセット
if(conditionResult && (correctFormattedValue || correctValues)){
//条件式の結果がtureかつ、値を正しい形式に変換できた場合、フィールドに値をセットする
@@ -451,6 +455,38 @@ export class InsertValueAction implements IAction{
}
}
}else{
//kintone async/await による非同期処理(保存成功時イベントREST API処理時)
async function updateRecord(fieldCode:string,event:any,insertValue:any) {
return new Promise((resolve, reject) => {
var updatedRecord = {
app: event.appId,
id: event.recordId,
record: {[fieldCode]:{"value":insertValue}}
};
kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', updatedRecord, (resp) => {
resolve(resp);
}, (error) => {
reject(error);
});
});
}
//条件式の結果がtrueかつ挿入する値が変換できた場合、フィールドラジオボタン・ドロップダウン・チェックボックス・複数選択・文字列一行・文字列複数行・リッチエディタ・数値・日付・日時・時刻にセット
if(conditionResult && (correctFormattedValue || correctValues)){
//条件式の結果がtureかつ、値を正しい形式に変換できた場合、フィールドに値をセットする
if(correctFormattedValue){
event.record[fieldCode].value = correctFormattedValue;
//条件式の結果がtureかつ、値を正しい形式配列に変換できた場合、フィールドに値配列をセットする
}else if(correctValues.length > 0){
event.record[fieldCode].value = correctValues;
}
}
//kintone async/await による非同期処理(レコード更新)
await updateRecord(fieldCode,event,correctFormattedValue);
};
result= {
canNext:true,
result:true

View File

@@ -159,32 +159,32 @@ export class StringJoinAction implements IAction{
if (!event.type.includes('success')){
//保存先フィールドに値セット:
record[this.props.saveField.code].value=saveValue;
window.alert("文字結合行いました。"+this.props.joinField1.name+":"+joinValue1+","+this.props.joinField2.name+":"+joinValue2+"。");
//window.alert("文字結合行いました。"+this.props.joinField1.name+":"+joinValue1+","+this.props.joinField2.name+":"+joinValue2+"。");
}else{
const params={
"app":event.appId,
"id":event.recordId,
"record":{[this.props.saveField.code]:{"value":saveValue}}
//kintone async/await による非同期処理(成功イベントREST API処理時)
async function updateRecord(fieldCode:string,event:any) {
return new Promise((resolve, reject) => {
var updatedRecord = {
app: event.appId,
id: event.recordId,
record: {[fieldCode]:{"value":saveValue}}
};
return await kintone.api(kintone.api.url('/k/v1/record',true),'PUT',params).then((resp) => {
kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', updatedRecord, (resp) => {
resolve(resp);
}, (error) => {
reject(error);
});
});
}
//kintone保存先フィールド存在確認
record[this.props.saveField.code].value=saveValue;
//kintone async/await による非同期処理:
await updateRecord(this.props.saveField.code,event);
//一覧画面更新成功後手動リロードください:
if (event.type.includes('index')){
window.alert("文字結合行いました。"+this.props.joinField1.name+":"+joinValue1+","+this.props.joinField2.name+":"+joinValue2+"。一覧画面更新成功後自動リロードしません。必要に応じて手動リロードください。");
}else{
window.alert("文字結合行いました。"+this.props.joinField1.name+":"+joinValue1+","+this.props.joinField2.name+":"+joinValue2+"。");
//window.alert("文字結合行いました。"+this.props.joinField1.name+":"+joinValue1+","+this.props.joinField2.name+":"+joinValue2+"。一覧画面更新成功後自動リロードしません。必要に応じて手動リロードください。");
window.alert("文字結合には、一覧画面更新成功後自動リロードしません。必要に応じて手動リロードください。");
}
//一覧画面更新成功後リロード:
// if (event.type.includes('index')){
// event.url = location.href.endsWith('/') || location.href.endsWith('&') ?
// location.href.slice(0, -1) :
// location.href + (location.href.includes('?') ? '&' : '/');
// }
}).catch((error) => {
event.error = 'エラーが発生しました。結合しません。システム管理者へお問合せください';
window.alert(event.error+"error message"+error);
return event;
});
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
result= {

View File

@@ -1,12 +1,10 @@
import { actionAddins } from ".";
import { IAction,IActionResult, IActionNode, IActionProperty, IField, IContext } from "../types/ActionTypes";
//クラス名を設計書に揃える
/**
* アクションの属性定義
*/
interface FullWidthProps{
//checkOption:Array<string>,
field:IField
}
/**
@@ -20,7 +18,6 @@ export class FullWidthAction implements IAction{
this.name="全角チェック"; /* pgadminのnameと同様 */
this.actionProps=[];
this.props={
//checkOption:[],
field:{code:''}
}
//アクションを登録する
@@ -50,15 +47,17 @@ export class FullWidthAction implements IAction{
//条件分岐
//未入力時は何も処理をせず終了
if(value===undefined || value===''){
return result;
record[this.props.field.code].error=null;
}
//半角が含まれていた場合resultがfalse
if(!this.containsFullWidthChars(value)){
if(!this.containsFullWidthChars(value) && !(value === undefined || value ==='')){
//エラー時に出力される文字設定
record[this.props.field.code].error="半角が含まれています";
//次の処理を中止する値設定
result.canNext=false;
return result;
}
else{
record[this.props.field.code].error=null;
}
//resultプロパティ指定
result= {
@@ -79,6 +78,7 @@ export class FullWidthAction implements IAction{
containsFullWidthChars(text: string): boolean {
// 半角英数字カナ記号を除外
//全角かどうか
const checkRegex="^[^\x01-\x7E\uFF61-\uFF9F]+$";
//正規表現オブジェクト生成

View File

@@ -47,7 +47,7 @@ export class HalfWidthAction implements IAction{
//条件分岐
//未入力時は何も処理をせず終了
if(value===undefined || value===''){
return result;
record[this.props.field.code].error=null;
}
//全角が含まれていた場合保存処理中止(エラー処理)
if(!this.containsHalfWidthChars(value)){
@@ -55,7 +55,9 @@ export class HalfWidthAction implements IAction{
record[this.props.field.code].error="全角が含まれています";
//次の処理を中止する値設定
result.canNext=false;
return result;
}
else{
record[this.props.field.code].error=null;
}
//半角の場合問題なく実行
//resultプロパティ指定