@@ -76,25 +76,35 @@ function handleCellResponse(id, success) {
76
76
77
77
const validKeyPresses = ['Enter', 'Backspace', 'Delete', 'ArrowLeft', 'ArrowRight'];
78
78
79
+ const updateMessageContent = (show, initialMessage) => {
80
+ const updateMessage = document.getElementById(updateMessageId);
81
+ if (updateMessage) {
82
+ if (initialMessage) {
83
+ updateMessage.innerHTML = initialMessage;
84
+ }
85
+ updateMessage.style.display = show ? '' : 'none';
86
+ }
87
+ }
88
+
79
89
document.getElementById('resultset').onclick = function(e){
80
90
console.log('click')
81
91
if (updateTable === undefined) return;
82
92
83
93
var e = e || window.event;
84
94
var target = e.target || e.srcElement;
85
95
86
- let chosenValue ;
96
+ let originalValue ;
87
97
let trWithColumn;
88
98
let editableNode;
89
99
90
100
if (target.tagName.toLowerCase() == "div") {
91
- chosenValue = target.innerText;
101
+ originalValue = target.innerText;
92
102
editableNode = target;
93
103
trWithColumn = target.parentElement;
94
104
}
95
105
else if (target.tagName.toLowerCase() == "td") {
96
106
// get the inner div
97
- chosenValue = target.firstChild.innerText;
107
+ originalValue = target.firstChild.innerText;
98
108
editableNode = target;
99
109
trWithColumn = target;
100
110
}
@@ -119,45 +129,8 @@ document.getElementById('resultset').onclick = function(e){
119
129
}
120
130
}
121
131
122
- // Already editable, just return
123
- if (editableNode.contentEditable === 'true') return;
124
- editableNode.contentEditable = true;
125
- editableNode.focus();
126
-
127
- const keydownEvent = (e) => {
128
- if (chosenColumnDetail.maxInputLength && editableNode.innerText.length >= chosenColumnDetail.maxInputLength) {
129
- if (!validKeyPresses.includes(e.key)) {
130
- e.preventDefault();
131
- }
132
- }
133
-
134
- switch (e.key) {
135
- case 'Enter':
136
- e.preventDefault();
137
- finishEditing();
138
- break;
139
- case 'Escape':
140
- editableNode.innerHTML = chosenValue;
141
- finishEditing();
142
- break;
143
- }
144
- }
145
-
146
- const finishEditing = () => {
147
- if (editableNode === undefined) return;
148
-
149
- // Remove keydown listener
150
- editableNode.removeEventListener('keydown', keydownEvent);
151
-
152
- editableNode.contentEditable = false;
153
- let newValue = editableNode.innerText;
154
-
155
- if (newValue === chosenValue) return;
156
- if (chosenColumnDetail.maxInputLength && newValue.length > chosenColumnDetail.maxInputLength) {
157
- newValue = newValue.substring(0, chosenColumnDetail.maxInputLength);
158
- editableNode.innerText = newValue;
159
- }
160
-
132
+ // Can return undefined or {updateStatement, bindings, saneStatement?}
133
+ const getSqlStatement = (newValue, withSane = false) => {
161
134
const useRrn = updateKeyColumns.length === 1 && updateKeyColumns.some(col => col.name === 'RRN');
162
135
163
136
let bindings = [];
@@ -173,7 +146,6 @@ document.getElementById('resultset').onclick = function(e){
173
146
bindings.push(newValue);
174
147
updateStatement += '?';
175
148
} else {
176
- editableNode.innerHTML = chosenValue;
177
149
return;
178
150
}
179
151
break;
@@ -210,7 +182,90 @@ document.getElementById('resultset').onclick = function(e){
210
182
}
211
183
}
212
184
213
- requestCellUpdate(editableNode, chosenValue, updateStatement, bindings);
185
+ let statementParts = updateStatement.split('?');
186
+ let saneStatement = '';
187
+
188
+ if (withSane) {
189
+ for (let i = 0; i < statementParts.length; i++) {
190
+ saneStatement += statementParts[i];
191
+ if (bindings[i]) {
192
+ if (typeof bindings[i] === 'string') {
193
+ saneStatement += "'" + bindings[i] + "'";
194
+ } else {
195
+ saneStatement += bindings[i];
196
+ }
197
+ }
198
+ }
199
+ }
200
+
201
+ return {
202
+ updateStatement,
203
+ bindings,
204
+ saneStatement
205
+ }
206
+ };
207
+
208
+ const updateMessageWithSql = (newValue) => {
209
+ const sql = getSqlStatement(newValue, true);
210
+ updateMessageContent(true, '<pre style="margin: 0;">' + sql.saneStatement + '</pre>');
211
+ }
212
+
213
+ // Already editable, just return
214
+ if (editableNode.contentEditable === 'true') return;
215
+ editableNode.contentEditable = true;
216
+ editableNode.focus();
217
+ updateMessageWithSql(originalValue);
218
+
219
+ const keydownEvent = (e) => {
220
+ const newValue = editableNode.innerText;
221
+ if (chosenColumnDetail.maxInputLength && newValue.length >= chosenColumnDetail.maxInputLength) {
222
+ if (!validKeyPresses.includes(e.key)) {
223
+ e.preventDefault();
224
+ }
225
+ }
226
+
227
+ switch (e.key) {
228
+ case 'Enter':
229
+ e.preventDefault();
230
+ editableNode.blur();
231
+ break;
232
+ case 'Escape':
233
+ editableNode.innerHTML = originalValue;
234
+ editableNode.blur();
235
+ break;
236
+ }
237
+ }
238
+
239
+ const keyupEvent = (e) => {
240
+ const newValue = editableNode.innerText;
241
+ updateMessageWithSql(newValue);
242
+ }
243
+
244
+ const finishEditing = () => {
245
+ updateMessageContent(false);
246
+ if (editableNode === undefined) return;
247
+
248
+ // Remove keydown listener
249
+ editableNode.removeEventListener('keydown', keydownEvent);
250
+ editableNode.removeEventListener('keyup', keyupEvent);
251
+
252
+ editableNode.contentEditable = false;
253
+ let newValue = editableNode.innerText;
254
+
255
+ if (newValue === originalValue) return;
256
+ if (chosenColumnDetail.maxInputLength && newValue.length > chosenColumnDetail.maxInputLength) {
257
+ newValue = newValue.substring(0, chosenColumnDetail.maxInputLength);
258
+ editableNode.innerText = newValue;
259
+ }
260
+
261
+ const sql = getSqlStatement(newValue);
262
+
263
+ if (!sql) {
264
+ editableNode.innerHTML = originalValue;
265
+ return;
266
+ }
267
+
268
+ requestCellUpdate(editableNode, originalValue, sql.updateStatement, sql.bindings);
214
269
215
270
editableNode = undefined;
216
271
}
@@ -223,6 +278,7 @@ document.getElementById('resultset').onclick = function(e){
223
278
}, {once: true});
224
279
225
280
editableNode.addEventListener('keydown', keydownEvent);
281
+ editableNode.addEventListener('keyup', keyupEvent);
226
282
}
227
283
};
228
284
` ;
@@ -245,6 +301,7 @@ export function generateScroller(basicSelect: string, isCL: boolean, withCancel?
245
301
const statusId = 'status';
246
302
const jobId = 'jobId';
247
303
const messageSpanId = 'messageSpan';
304
+ const updateMessageId = 'updateMessage';
248
305
249
306
// Updatable information
250
307
@@ -363,6 +420,16 @@ export function generateScroller(basicSelect: string, isCL: boolean, withCancel?
363
420
// Initialize the footer
364
421
var footer = document.getElementById(htmlTableId).getElementsByTagName('tfoot')[0];
365
422
footer.innerHTML = '';
423
+
424
+ // Foot specificaly for updating tables.
425
+ if (updateTable) {
426
+ const newRow = footer.insertRow();
427
+ const updateCell = newRow.insertCell();
428
+ updateCell.colSpan = columnMetaData.length;
429
+ updateCell.id = updateMessageId;
430
+ updateCell.appendChild(document.createTextNode(' '));
431
+ }
432
+
366
433
const newRow = footer.insertRow();
367
434
368
435
const statusCell = newRow.insertCell();
@@ -435,7 +502,7 @@ export function generateScroller(basicSelect: string, isCL: boolean, withCancel?
435
502
<table id="resultset">
436
503
<thead></thead>
437
504
<tbody></tbody>
438
- <tfoot></tfoot>
505
+ <tfoot id="resultfooter" ></tfoot>
439
506
</table>
440
507
<p id="messageSpan"></p>
441
508
<div id="spinnerContent" class="center-screen">
0 commit comments