-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathwoz-content-manager.html
More file actions
265 lines (215 loc) · 7.35 KB
/
woz-content-manager.html
File metadata and controls
265 lines (215 loc) · 7.35 KB
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
<!DOCTYPE html>
<html>
<head>
<!--
Author: Erkan Basar - erkan.basar@ru.nl
Description: This simple web page is designed to display a table of contents
where each cell can be clicked to copy its content to the clipboard of your
operating system. The content of the cells can be updated dynamically via
input fields that are shown on the left side of the page.
Version: 0.1
-->
<title>Click-to-copy Content Table for Wizard-of-Oz studies</title>
<style>
body {
margin: 0;
font-family: Arial, sans-serif;
display: flex;
}
#sidebar {
width: 200px;
height: 100vh;
position: fixed;
background-color: #f1f1f1;
overflow-y: scroll;
padding: 20px;
}
#sidebar label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
#sidebar input {
width: 100%;
padding: 8px;
margin-bottom: 10px;
box-sizing: border-box;
}
#table-container {
flex-grow: 1;
overflow: auto;
padding: 20px;
margin-left: 250px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #dddddd;
padding: 8px;
text-align: left;
}
td {
cursor: pointer;
}
td.clicked {
background-color: lightgreen;
}
</style>
</head>
<body>
<!-- INPUTS FORMS -->
<!--
How to add a new input field:
1. Copy a label-input pair below.
2. Paste it just below or above the other label-input pairs.
The order of the tags here matches to the order shown
on the webpage.
3. You have to change the value of the "id" in the input tag.
4. The new "id" value has to have the same value with the tag id
you are using in the table. For example, the new tag is called
"{{ sense-number }}", then the "id" of the input should also say
"sense-number". This is case-sensitive.
5. Finally give the same value to the "for" of the label.
6. Update the text within the label (e.g. "Name:"), for your convenience.
-->
<div id="sidebar">
<label for="name">Name: </label>
<input type="text" id="name">
<label for="age">Age: </label>
<input type="text" id="age">
</div>
<!-- TABLE -->
<!--
How to add a new table cell:
1. Copy a table cell that starts with <tr> and ends with </tr>,
including the <tr> and </tr>.
2. Paste it to just below or above any other <tr> tags.
Never paste them below </table> or above <table ...>.
The order of the content here matches to the order shown
on the webpage.
3. Notice that within some <tr> tags, there is <th> and some has <td>.
4. If you want to have a heading within your table, use a <th> tag,
and write your title between a <th> and </th>.
These are only for headings and are NOT click-to-copy.
5. For the content that you would like to be able to copy by clicking,
use the <td> tags, and write your content between a <td> and </td>.
How to add dynamic content:
You can add a variable within your content by using the following
format with curly brackets: "{{ xyz }}". Here the entire tag
will be replaced with a corresponding value that you assign via the
input fields (explained above).
There are a few rules to use this format:
1. Give a self-explanatory but short id (e.g. "xyz") to your tag,
and write it between the curly brackets.
2. Never use empty space in your tag id. If you need to used
a two word identification, use a hyphen (e,g, " {{ xyz-abc }}").
3. Always leave a single space between the tag id and the brackets.
DO NOT write {{xyz}}, but always write "{{ xyz }}".
Glossary reminder:
<tr> = stands for Table Row
<td> = stands for Table Data
<th> = stands for Table Heading
-->
<div id="table-container">
<table id="content-table">
<tr>
<th>Introduction</th>
</tr>
<tr>
<td>Hello, {{ name }}. How are you today?</td>
</tr>
<tr>
<td>Nice to meet you!</td>
</tr>
<tr>
<th>Age question</th>
</tr>
<tr>
<td>How old are you?</td>
</tr>
<tr>
<td>{{ age }} is a good age, {{ name }}!</td>
</tr>
<tr>
<th>Easter egg</th>
</tr>
<tr>
<td>I'm sorry Dave, I am afraid I can't do that.</td>
</tr>
</table>
</div>
<script>
/////////////// CONSTANT DEFINITIONS ///////////////
// This Map object is used to store the original contents of the table cells.
// This allows us to update the content of the table cells multiple times.
const originalContentMap = new Map();
// Get the table element. Currently the script only works for a single
// table with the specific id "content-table".
const table = document.getElementById("content-table");
// Get all the table cells with "td" tag within the table.
const tdElements = table.querySelectorAll("td");
// Get all input elements on the webpage.
const inputElements = document.querySelectorAll("input");
/////////////// TABLE CELL COPY FUNCTION HADNLING ///////////////
const copyTableCell = (cell) => {
if (cell) {
// Get the content of the cell to be copied.
const cellContent = cell.innerText || cell.textContent;
// Copy the content of the cell to the clipboard.
navigator.clipboard.writeText(cellContent)
.then(() => {
console.log("Copied:", cellContent);
})
.catch((err) => {
console.error("Unable to copy cell content to clipboard", err);
});
}
};
// The function to be executed when a table element is clicked.
const handleTableCellClick = (event) => {
const target = event.target;
// Check if the clicked element is a table cell (td).
if (target.tagName === "TD") {
// Call the copyTableCell function with the clicked cell.
copyTableCell(target);
target.classList.toggle('clicked');
}
};
// Attache the event listener to the table element.
table.addEventListener("click", handleTableCellClick);
/////////////// TABLE CONTENT UPDATE HANDLING ///////////////
const updateTableSlots = (event) => {
// Loop over each table cell to update their content.
tdElements.forEach((tdElem) => {
if (tdElem) {
// Store the original content to memory, if not already stored.
if (!originalContentMap.has(tdElem)) {
originalContentMap.set(tdElem, tdElem.textContent);
}
// Get the corresponding original content from the memory.
let tdContent = originalContentMap.get(tdElem);
// Loop over each input element to update the cell's content.
inputElements.forEach((input) => {
const inputId = input.id;
const updatedValue = input.value;
// If an updated value is empty, skip it.
if (updatedValue === '') return;
// If the table element does not contain the tag, skip it.
if (!tdContent.includes(`{{ ${inputId} }}`)) return;
// Replace the tags in the content via the input id and updated value.
tdContent = tdContent.replace(`{{ ${inputId} }}`, updatedValue);
});
// Assign the updated value back to the table cell.
tdElem.textContent = tdContent;
}
});
}
// Attach the event listener to each input element.
inputElements.forEach((input) => {
input.addEventListener("blur", updateTableSlots);
});
</script>
</body>
</html>