class JValidField {
constructor(el) {
this.Guid = el.dataset.guid;
this.Index = parseInt(el.dataset.validIndex);
this.Name = el.dataset.validName;
this.OrgText = el.dataset.validOrgText;
this.Text = el.dataset.validText;
this.InputChar = parseInt(el.dataset.validInputChar);
this.ShowStyle = parseInt(el.dataset.validShowStyle);
this.ThousandFormat = el.dataset.validThousandFormat;
}
};
/*
*画面(部品)単位のViewModel管理
*想定シナリオ
*1.C# Blazor側でViewModelにViewModel生成、GuidやValidFieldをの属性にセットする
*2.OnAfterRenderAsyncのfirstRenderでInputCoreのinit(Guid)を呼出し
*3.InputCoreのinit(Guid)に、JViewModelを生成し、の属性よりValidFieldを生成し、入力制御を行う
*4.C# Blazor側Page OR 部品 Dispose時に、InputCoreのdispose(Guid)を呼出し、廃棄する
*/
class JViewModel {
constructor(guid) {
this.Guid = guid
this.Fields = [];
this.FieldMap = new Map();
}
add(field) {
this.Fields.push(field);
this.FieldMap.set(field.Name, field);
}
static create(guid) {
return new JViewModel(guid);
}
};
/*
* IMEモードなし状態:
* 通常文字入力:keydown⇒keypress⇒input⇒keyup
* Enter:keydown⇒keypress⇒change(※文字変更あった場合)⇒keyup
* Tab:keydown⇒blur⇒focus(次)⇒keyup
* ※その場合、入力文字毎制限はinputに行う
* IMEモード状態:ひらがな
* 通常文字入力:compositionstart⇒複数回keydown⇒input⇒keyup⇒compositionend
* ※その場合、入力文字毎制限はcompositionendに行う
* 全部入力内容のチェックタイミングはblurで行う
* Up、End、Enterの判断はKeyUpの信頼度は一番高い、又Enterのみはkeypressでも可能です。
*
* フォーカス移動、全部チェックのため、viewFieldsの配列が必要です。
*/
class InputCore {
constructor() {
this.viewModelMap = new Map();
}
static filter(e) {
let index = parseInt(e.target.dataset.validIndex);
let field = window.inputCore.viewModelMap.get(e.target.dataset.guid).Fields[index];
if (field.InputChar == 1) { return; }
let v = e.target.value;
// 全角数字変換
if ((field.InputChar & 0x02) == 0x02) {
v = v.replace(/[0-9]/g, function (x) { return String.fromCharCode(x.charCodeAt(0) - 0xFEE0) });
}
let limitChar = '[^';
if ((field.InputChar & 0x02) == 0x02) { limitChar += '0-9'; } //数字
if ((field.InputChar & 0x04) == 0x04) { limitChar += 'a-z'; } //小アルファベット
if ((field.InputChar & 0x08) == 0x08) { limitChar += 'A-Z'; } //大アルファベット
if ((field.InputChar & 0x10) == 0x10) { limitChar += 'ヲ-゚'; } //カナ
if ((field.InputChar & 0x200) == 0x200) { limitChar += ' '; } // [space]
if ((field.InputChar & 0x400) == 0x400) { limitChar += ':'; } // :
if ((field.InputChar & 0x800) == 0x800) { limitChar += '-'; } // -
if ((field.InputChar & 0x2000) == 0x2000) { limitChar += '.'; } // .
if ((field.InputChar & 0x4000) == 0x4000) { limitChar += '/'; } // /
if ((field.InputChar & 0x8000) == 0x8000) { limitChar += ','; } // ,
limitChar += ']';
var re = new RegExp(limitChar,'g');
v = v.replace(re, '');
//let v = e.target.value
// .replace(/[0-9]/g, function (x) { return String.fromCharCode(x.charCodeAt(0) - 0xFEE0) })
// .replace(/[^0-9,.-]/g, '');
//.replace(/[0-9a-zA-Z]/g, function(x){ return String.fromCharCode(x.charCodeAt(0) - 0xFEE0) })
//.replace(/[^0-9a-zA-Z]/g, '');
//.replace(/[^0-9]/g, '')
e.target.value = v;
}
dispose(guid) {
try {
viewModelMap.delete(guid);
} catch(err) {
console.log(err);
}
}
init(guid) {
let viewModel = new JViewModel(guid);
let key = `[data-guid="${guid}"]`;
var list = document.querySelectorAll(key);
list.forEach(item => {
let field = new JValidField(item);
viewModel.add(field);
});
this.viewModelMap.set(guid, viewModel);
viewModel.Fields.forEach(item => {
let id = `${guid}-${item.Index}`;
var obj = document.getElementById(id);
obj.addEventListener('focus', function (e) {
console.log('focus', e.target.value, e.target.dataset.validName);
let index = parseInt(e.target.dataset.validIndex);
let field = window.inputCore.viewModelMap.get(e.target.dataset.guid).Fields[index];
field.OrgText = e.target.value;
if (((field.ShowStyle & 0x04) == 0x04) && e.target.value.length > 0) {
e.target.value = e.target.value.replace(",", "");
}
DotNet.invokeMethodAsync('HotelPms.Client.Blazor', 'InputCoreEvent', { ID: e.target.dataset.guid, Index: index, Name: e.target.dataset.validName, EventName: "focus", Key: "", OrgText: field.OrgText, Text: e.target.value })
.then(data => {
console.log(JSON.stringify(data));
});
});
obj.addEventListener('blur', function (e) {
console.log('blur', e.target.value, e.target.dataset.validName);
let index = parseInt(e.target.dataset.validIndex);
var field = window.inputCore.viewModelMap.get(e.target.dataset.guid).Fields[index];
DotNet.invokeMethodAsync('HotelPms.Client.Blazor', 'InputCoreEvent', { ID: e.target.dataset.guid, Index: index, Name: e.target.dataset.validName, EventName: "blur", Key: "", OrgText: field.OrgText, Text: e.target.value })
.then(data => {
console.log(JSON.stringify(data));
e.target.value = data.text;
});
});
obj.addEventListener('keyup', function (e) {
console.log('keyup', e.target.value, e.key, e.target.dataset.validName);
if (e.key === "Enter" || e.key === "ArrowUp" || e.key === "End") {
e.preventDefault();
e.stopPropagation();
let index = parseInt(e.target.dataset.validIndex);
var field = window.inputCore.viewModelMap.get(e.target.dataset.guid).Fields[index];
DotNet.invokeMethodAsync('HotelPms.Client.Blazor', 'InputCoreEvent', { ID: e.target.dataset.guid, Index: index, Name: e.target.dataset.validName, EventName: "keyup", Key: e.key, OrgText: field.OrgText, Text: e.target.value })
.then(data => {
console.log(JSON.stringify(data));
field.OrgText = data.orgText;
e.target.value = data.text;
if (data.nextFocus.length > 0) {
let nextInput = document.getElementById(data.nextFocus);
nextInput.focus();
nextInput.select();
}
});
}
});
obj.addEventListener('keypress', function (e) {
console.log('keypress', e.target.value, e.key, e.target.dataset.validName);
});
obj.addEventListener('keydown', function (e) {
console.log('keydown', e.target.value, e.key, e.target.dataset.validName);
});
obj.addEventListener('change', function (e) {
console.log('change', e.target.value, e.key, e.target.dataset.validName);
});
obj.addEventListener('input', function (e) {
console.log('input', e.target.value, e.key, e.target.dataset.validName, e.isComposing);
if (!e.isComposing) { InputCore.filter(e); }
});
obj.addEventListener('compositionstart', function (e) {
console.log('compositionstart', e.target.value, e.target.dataset.validName);
});
obj.addEventListener('compositionend', function (e) {
console.log('compositionend', e.target.value, e.target.dataset.validName);
InputCore.filter(e);
});
});
}
};
window.inputCore = new InputCore();