Issue 260 Dashboard Widget Cog Did Nothing - edmozley/freeitsm GitHub Wiki
Reported: #260, November 2026 ยท Module: Tickets โ Dashboard ยท Fixed in: the release after 4.10.0 (changelog #2740)
On Tickets โ Dashboard, clicking the cog on any widget did nothing: no edit window, no message. The browser console showed:
Uncaught ReferenceError: esc is not defined
at onPropertyChange (widget-editor.js:229)
at Object.populateForm (widget-editor.js:340)
at openWidgetEditModal (dashboard/:3348)
The same fault was behind two buttons nobody had reported. In the Widget Library, New widget and Edit went through the same code and failed in the same way. So from 2.5.0 to 4.10.0, nobody could create a widget or change one from the screen. Adding, removing, reordering, duplicating and deleting widgets all still worked.
The edit form is shared by the dashboard and the library through one script, assets/js/widget-editor.js (see the Developer Guide). Its escape helper is called escapeHtml().
In 2.5.0, the change that translated the last screens (#1895-#1903) rewrote two lines in onPropertyChange() - the part that rebuilds the Series dropdown - to translate the option text, and escaped it with esc(). Most FreeITSM scripts have an esc(). This one did not.
onPropertyChange() is not only run when you change What to count. Every way of opening the form calls it, so the dropdowns suit the widget:
- the cog โ
populateForm()โonPropertyChange() - library Edit โ
populateForm()โonPropertyChange() - library New widget โ
resetForm()โonPropertyChange()
The error stopped each of them before the form was shown. The dashboard shows its modal on the line after populateForm(), so the click looked as if it did nothing.
There is no server error and nothing in a log. The page loads perfectly, and the charts draw. The failure only appears on a click, and only in the browser console. The existing escape-helper test checked that every helper escapes quotes. It did not check that the helper a script calls is one it has.
// assets/js/widget-editor.js, onPropertyChange()
seriesSelect.innerHTML = '<option value="">' +
escapeHtml(we('form.series_none', 'None (single series)')) + '</option>';
...
seriesSelect.innerHTML += '<option value="' + s + '">' + escapeHtml(label) + '</option>';The script's version number was bumped to ?v=3 on both pages, so browsers fetch the fixed copy.
No database change, nothing to run after upgrading. Widgets were never damaged - they just could not be opened.
| File | Change |
|---|---|
๐ต assets/js/widget-editor.js
|
esc() โ escapeHtml(), twice |
๐ต tickets/dashboard/index.php
|
widget-editor.js?v=3 |
๐ต tickets/dashboard/library.php
|
widget-editor.js?v=3 |
๐งช tests/escape-helpers-quotes.php
|
new check: no script in assets/js/ calls esc() without defining it or importing it (esc = P.esc, { esc } = window.Dom) |
-
In a real browser. Headless Chrome opened the dashboard as an admin and clicked the first cog. With the fix, the edit window opened, filled with Tickets by status, and there were no errors. Control: the same click with the old file in place threw
esc is not defined, and the window stayed shut. -
php tests/escape-helpers-quotes.php- 6 passed. Control: against the oldwidget-editor.jsit fails, naming that file. Its own two controls prove that it flags an undefinedesc()and does not flag one imported from a shared module. -
The sweep, first time round, listed 15 scripts. 14 import
escfrom a shared module (the Projects, Domains, Starters and Files screens), so the check now recognises that. Onlywidget-editor.jswas really broken.
Not proven live: the library's New widget and Edit were not clicked in the browser. They fail and recover through the same function, which the cog run does exercise.
- After upgrading, the cog opens the edit window again, and New widget and Edit work in the Widget Library.
- Editing a widget changes it for everyone who has it on their dashboard - the library is shared. To change one just for yourself, Duplicate it in the library and add the copy.