|
30 | 30 | */ |
31 | 31 | async function initSemanticGraph(container) { |
32 | 32 | // Show loading state |
33 | | - container.innerHTML = '<div class="graph-loading">Loading semantic graph...</div>'; |
| 33 | + while (container.firstChild) { container.removeChild(container.firstChild); } |
| 34 | + const loadingDiv = document.createElement('div'); |
| 35 | + loadingDiv.className = 'graph-loading'; |
| 36 | + loadingDiv.textContent = 'Loading semantic graph...'; |
| 37 | + container.appendChild(loadingDiv); |
34 | 38 |
|
35 | 39 | // Fetch semantic graph data from WordPress REST API |
36 | 40 | const response = await fetch(sinople.rest_url + 'sinople/v1/semantic-graph', { |
|
162 | 166 | // Add controls |
163 | 167 | const controls = document.createElement('div'); |
164 | 168 | controls.className = 'graph-controls'; |
165 | | - controls.innerHTML = ` |
166 | | - <label for="graph-filter">Filter constructs:</label> |
167 | | - <input type="search" id="graph-filter" placeholder="Search..." aria-label="Filter constructs"> |
168 | | - <span role="status" aria-live="polite" id="graph-status"> |
169 | | - Showing ${data.nodes.length} constructs |
170 | | - </span> |
171 | | - `; |
172 | | - |
173 | | - container.innerHTML = ''; |
| 169 | + |
| 170 | + const label = document.createElement('label'); |
| 171 | + label.setAttribute('for', 'graph-filter'); |
| 172 | + label.textContent = 'Filter constructs:'; |
| 173 | + controls.appendChild(label); |
| 174 | + |
| 175 | + const input = document.createElement('input'); |
| 176 | + input.type = 'search'; |
| 177 | + input.id = 'graph-filter'; |
| 178 | + input.placeholder = 'Search...'; |
| 179 | + input.setAttribute('aria-label', 'Filter constructs'); |
| 180 | + controls.appendChild(input); |
| 181 | + |
| 182 | + const statusSpan = document.createElement('span'); |
| 183 | + statusSpan.setAttribute('role', 'status'); |
| 184 | + statusSpan.setAttribute('aria-live', 'polite'); |
| 185 | + statusSpan.id = 'graph-status'; |
| 186 | + statusSpan.textContent = `Showing ${data.nodes.length} constructs`; |
| 187 | + controls.appendChild(statusSpan); |
| 188 | + |
| 189 | + while (container.firstChild) { container.removeChild(container.firstChild); } |
174 | 190 | container.appendChild(controls); |
175 | 191 | container.appendChild(svg); |
176 | 192 |
|
|
222 | 238 | * Show Error Message |
223 | 239 | */ |
224 | 240 | function showError(container, message) { |
225 | | - container.innerHTML = ` |
226 | | - <div class="graph-error" role="alert"> |
227 | | - <p><strong>Error:</strong> ${message}</p> |
228 | | - <p>Please try refreshing the page or contact the administrator if the problem persists.</p> |
229 | | - </div> |
230 | | - `; |
| 241 | + while (container.firstChild) { container.removeChild(container.firstChild); } |
| 242 | + |
| 243 | + const errorDiv = document.createElement('div'); |
| 244 | + errorDiv.className = 'graph-error'; |
| 245 | + errorDiv.setAttribute('role', 'alert'); |
| 246 | + |
| 247 | + const errorP = document.createElement('p'); |
| 248 | + const strong = document.createElement('strong'); |
| 249 | + strong.textContent = 'Error:'; |
| 250 | + errorP.appendChild(strong); |
| 251 | + errorP.appendChild(document.createTextNode(' ' + message)); |
| 252 | + errorDiv.appendChild(errorP); |
| 253 | + |
| 254 | + const helpP = document.createElement('p'); |
| 255 | + helpP.textContent = 'Please try refreshing the page or contact the administrator if the problem persists.'; |
| 256 | + errorDiv.appendChild(helpP); |
| 257 | + |
| 258 | + container.appendChild(errorDiv); |
231 | 259 | } |
232 | 260 |
|
233 | 261 | })(); |
0 commit comments