ホテル管理システム
ogi
yesterday 1a1c8e71fcd14858f595029f089b2d4a00202b32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
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を<input>の属性にセットする
*2.OnAfterRenderAsyncのfirstRenderでInputCoreのinit(Guid)を呼出し
*3.InputCoreのinit(Guid)に、JViewModelを生成し、<input>の属性より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();