@@ -47,6 +47,172 @@ export interface BasicColumn {
47
47
maxInputLength ?: number ;
48
48
}
49
49
50
+ const editableCellsLogic = /*js*/ `
51
+ let updateRequests = {};
52
+
53
+ function requestCellUpdate(cellNode, originalValue, statement, bindings) {
54
+ const randomId = Math.floor(Math.random() * 1000000);
55
+ updateRequests[randomId] = {cellNode, originalValue};
56
+
57
+ vscode.postMessage({
58
+ command: 'update',
59
+ id: randomId,
60
+ update: statement,
61
+ bindings: bindings
62
+ });
63
+ }
64
+
65
+ function handleCellResponse(id, success) {
66
+ const previousRequest = updateRequests[id];
67
+
68
+ if (previousRequest) {
69
+ if (!success) {
70
+ previousRequest.cellNode.innerText = previousRequest.originalValue;
71
+ }
72
+
73
+ delete updateRequests[id];
74
+ }
75
+ }
76
+
77
+ document.getElementById('resultset').onclick = function(e){
78
+ console.log('click')
79
+ if (updateTable === undefined) return;
80
+
81
+ var e = e || window.event;
82
+ var target = e.target || e.srcElement;
83
+
84
+ let chosenValue;
85
+ let trWithColumn;
86
+ let editableNode;
87
+
88
+ if (target.tagName.toLowerCase() == "div") {
89
+ chosenValue = target.innerText;
90
+ editableNode = target;
91
+ trWithColumn = target.parentElement;
92
+ }
93
+ else if (target.tagName.toLowerCase() == "td") {
94
+ // get the inner div
95
+ chosenValue = target.firstChild.innerText;
96
+ editableNode = target;
97
+ trWithColumn = target;
98
+ }
99
+
100
+ if (trWithColumn && trWithColumn.column) {
101
+ const chosenColumn = trWithColumn.column;
102
+ if (chosenColumn === 'RRN') return;
103
+
104
+ const chosenColumnDetail = updateTable.columns.find(col => col.name === chosenColumn);
105
+ if (!chosenColumnDetail) return;
106
+
107
+ const parentRow = trWithColumn.parentElement;
108
+
109
+ const updateKeyColumns = updateTable.columns.filter(col => col.useInWhere);
110
+ if (updateKeyColumns.length === 0) return;
111
+
112
+ let idValues = [];
113
+ for (let i = 0; i < parentRow.cells.length; i++) {
114
+ const cell = parentRow.cells[i];
115
+ if (updateKeyColumns.some(col => col.name === cell.column)) {
116
+ idValues.push(cell.firstChild.innerText);
117
+ }
118
+ }
119
+
120
+ // Already editable, just return
121
+ if (editableNode.contentEditable === 'true') return;
122
+ editableNode.contentEditable = true;
123
+ editableNode.focus();
124
+
125
+ const keydownEvent = (e) => {
126
+ if (e.key === 'Enter') {
127
+ e.preventDefault();
128
+ finishEditing(e.target);
129
+ }
130
+ }
131
+
132
+ const finishEditing = (currentNode) => {
133
+ if (currentNode === undefined) return;
134
+
135
+ // Remove keydown listener
136
+ currentNode.removeEventListener('keydown', keydownEvent);
137
+
138
+ currentNode.contentEditable = false;
139
+ let newValue = currentNode.innerText;
140
+
141
+ if (newValue === chosenValue) return;
142
+ if (chosenColumnDetail.maxInputLength && newValue.length > chosenColumnDetail.maxInputLength) {
143
+ newValue = newValue.substring(0, chosenColumnDetail.maxInputLength);
144
+ currentNode.innerText = newValue;
145
+ }
146
+
147
+ const useRrn = updateKeyColumns.length === 1 && updateKeyColumns.some(col => col.name === 'RRN');
148
+
149
+ let bindings = [];
150
+ let updateStatement = 'UPDATE ' + updateTable.table + ' t SET t.' + chosenColumn + ' = ';
151
+
152
+ if (newValue === 'null') {
153
+ updateStatement += 'NULL';
154
+
155
+ } else {
156
+ switch (chosenColumnDetail.jsType) {
157
+ case 'number':
158
+ if (isNumeric(newValue)) {
159
+ bindings.push(newValue);
160
+ updateStatement += '?';
161
+ } else {
162
+ currentNode.innerHTML = chosenValue;
163
+ return;
164
+ }
165
+ break;
166
+
167
+ case 'asString':
168
+ updateStatement += '?';
169
+ bindings.push(newValue);
170
+ break;
171
+ }
172
+ }
173
+
174
+ updateStatement += ' WHERE ';
175
+
176
+ for (let i = 0; i < updateKeyColumns.length; i++) {
177
+ if (idValues[i] === 'null') continue;
178
+
179
+ if (useRrn && updateKeyColumns[i].name === 'RRN') {
180
+ updateStatement += 'RRN(t) = ?';
181
+ } else {
182
+ updateStatement += updateKeyColumns[i].name + ' = ?';
183
+ }
184
+
185
+ switch (updateKeyColumns[i].jsType) {
186
+ case 'number':
187
+ bindings.push(Number(idValues[i]));
188
+ break;
189
+ case 'asString':
190
+ bindings.push(idValues[i]);
191
+ break;
192
+ }
193
+
194
+ if (i < updateKeyColumns.length - 1) {
195
+ updateStatement += ' AND ';
196
+ }
197
+ }
198
+
199
+ currentNode = undefined;
200
+
201
+ requestCellUpdate(currentNode, chosenValue, updateStatement, bindings);
202
+ }
203
+
204
+ editableNode.addEventListener('blur', (e) => {
205
+ e.stopPropagation();
206
+ console.log('blur');
207
+ // Code to execute when the element loses focus
208
+ finishEditing(e.target);
209
+ }, {once: true});
210
+
211
+ editableNode.addEventListener('keydown', keydownEvent);
212
+ }
213
+ };
214
+ ` ;
215
+
50
216
export function generateScroller ( basicSelect : string , isCL : boolean , withCancel ?: boolean , updatable ?: UpdatableInfo ) : string {
51
217
const withCollapsed = Configuration . get < boolean > ( 'collapsedResultSet' ) ;
52
218
@@ -95,169 +261,7 @@ export function generateScroller(basicSelect: string, isCL: boolean, withCancel?
95
261
}
96
262
}, { threshold: [0] }).observe(document.getElementById(messageSpanId));
97
263
98
- let updateRequests = {};
99
-
100
- function requestCellUpdate(cellNode, originalValue, statement, bindings) {
101
- const randomId = Math.floor(Math.random() * 1000000);
102
- updateRequests[randomId] = {cellNode, originalValue};
103
-
104
- vscode.postMessage({
105
- command: 'update',
106
- id: randomId,
107
- update: statement,
108
- bindings: bindings
109
- });
110
- }
111
-
112
- function handleCellResponse(id, success) {
113
- const previousRequest = updateRequests[id];
114
-
115
- if (previousRequest) {
116
- if (!success) {
117
- previousRequest.cellNode.innerText = previousRequest.originalValue;
118
- }
119
-
120
- delete updateRequests[id];
121
- }
122
- }
123
-
124
- document.getElementById('resultset').onclick = function(e){
125
- console.log('click')
126
- if (updateTable === undefined) return;
127
-
128
- var e = e || window.event;
129
- var target = e.target || e.srcElement;
130
-
131
- let chosenValue;
132
- let trWithColumn;
133
- let editableNode;
134
-
135
- if (target.tagName.toLowerCase() == "div") {
136
- chosenValue = target.innerText;
137
- editableNode = target;
138
- trWithColumn = target.parentElement;
139
- }
140
- else if (target.tagName.toLowerCase() == "td") {
141
- // get the inner div
142
- chosenValue = target.firstChild.innerText;
143
- editableNode = target;
144
- trWithColumn = target;
145
- }
146
-
147
- if (trWithColumn && trWithColumn.column) {
148
- const chosenColumn = trWithColumn.column;
149
- if (chosenColumn === 'RRN') return;
150
-
151
- const chosenColumnDetail = updateTable.columns.find(col => col.name === chosenColumn);
152
- if (!chosenColumnDetail) return;
153
-
154
- const parentRow = trWithColumn.parentElement;
155
-
156
- const updateKeyColumns = updateTable.columns.filter(col => col.useInWhere);
157
- if (updateKeyColumns.length === 0) return;
158
-
159
- let idValues = [];
160
- for (let i = 0; i < parentRow.cells.length; i++) {
161
- const cell = parentRow.cells[i];
162
- if (updateKeyColumns.some(col => col.name === cell.column)) {
163
- idValues.push(cell.firstChild.innerText);
164
- }
165
- }
166
-
167
- // Already editable, just return
168
- if (editableNode.contentEditable === 'true') return;
169
- editableNode.contentEditable = true;
170
- editableNode.focus();
171
-
172
- const keydownEvent = (e) => {
173
- if (e.key === 'Enter') {
174
- e.preventDefault();
175
- finishEditing();
176
- }
177
- }
178
-
179
- const finishEditing = () => {
180
- if (editableNode === undefined) return;
181
-
182
- // Remove keydown listener
183
- editableNode.removeEventListener('keydown', keydownEvent);
184
-
185
- editableNode.contentEditable = false;
186
- let newValue = editableNode.innerText;
187
-
188
- if (newValue === chosenValue) return;
189
- if (chosenColumnDetail.maxInputLength && newValue.length > chosenColumnDetail.maxInputLength) {
190
- newValue = newValue.substring(0, chosenColumnDetail.maxInputLength);
191
- editableNode.innerText = newValue;
192
- }
193
-
194
- const useRrn = updateKeyColumns.length === 1 && updateKeyColumns.some(col => col.name === 'RRN');
195
-
196
- let bindings = [];
197
- let updateStatement = 'UPDATE ' + updateTable.table + ' t SET t.' + chosenColumn + ' = ';
198
-
199
- if (newValue === 'null') {
200
- updateStatement += 'NULL';
201
-
202
- } else {
203
- switch (chosenColumnDetail.jsType) {
204
- case 'number':
205
- if (isNumeric(newValue)) {
206
- bindings.push(newValue);
207
- updateStatement += '?';
208
- } else {
209
- editableNode.innerHTML = chosenValue;
210
- return;
211
- }
212
- break;
213
-
214
- case 'asString':
215
- updateStatement += '?';
216
- bindings.push(newValue);
217
- break;
218
- }
219
- }
220
-
221
- updateStatement += ' WHERE ';
222
-
223
- for (let i = 0; i < updateKeyColumns.length; i++) {
224
- if (idValues[i] === 'null') continue;
225
-
226
- if (useRrn && updateKeyColumns[i].name === 'RRN') {
227
- updateStatement += 'RRN(t) = ?';
228
- } else {
229
- updateStatement += updateKeyColumns[i].name + ' = ?';
230
- }
231
-
232
- switch (updateKeyColumns[i].jsType) {
233
- case 'number':
234
- bindings.push(Number(idValues[i]));
235
- break;
236
- case 'asString':
237
- bindings.push(idValues[i]);
238
- break;
239
- }
240
-
241
- if (i < updateKeyColumns.length - 1) {
242
- updateStatement += ' AND ';
243
- }
244
- }
245
-
246
- editableNode = undefined;
247
-
248
- requestCellUpdate(target, chosenValue, updateStatement, bindings);
249
- }
250
-
251
- editableNode.addEventListener('blur', (e) => {
252
- e.stopPropagation();
253
- console.log('blur');
254
- // Code to execute when the element loses focus
255
- finishEditing();
256
- }, {once: true});
257
-
258
- editableNode.addEventListener('keydown', keydownEvent);
259
- }
260
- };
264
+ ${ editableCellsLogic }
261
265
262
266
window.addEventListener('message', event => {
263
267
const data = event.data;
0 commit comments