Reactive?
Since 4.0, Moodle now employs a reactive user interface (UI) (moodledev.io/docs/5.1/guides/javascript/reactive) for editing content. With JavaScript being my weakest skill, I’ve been meaning for ages to learn more about it. The incentive really arrived when in a post about the Adaptable theme (moodle.org/mod/forum/discuss.php?d=468708#p1881901) where the activity navigation requires updating when the next activity is made available because of a completion state change, that I looked further into understanding it and how I could potentially solve the problem.
In this post I’m taking the focus of the journey rather than being overly technical.
Disclaimers
Names / logos can be trademarks of their respective owners. Please review their website for details. I am independent from the organisations mentioned and am in no way writing for or endorsed by them. The information presented in this article is written according to my own understanding, there could be inaccuracies, so please do undertake your own research. The featured image is my copyright, please don’t use without my permission.
Understanding
I’ve written some reactive UI code before, but that was only to adapt what had already been written for a course format. Now I needed to create something from scratch and even though it would not add to the user interface in terms of functionality, I still needed to understand how it all works, so set about reading the Moodle guide, several times.
What is a ‘Reactive UI’? In essence it is where you perform an action on the user interface and then that action is sent to the server as a ‘state change’ request (the state of the user interface), which understands the bigger picture in a multi-user environment, it validates the action and changes the ‘state’ accordingly. Then tells you what the changes are to the state. Your view then ‘reacts’ and updates, including the action you instigated. Thus other elements that are on the page that are ‘watching’ a given change in ‘state’ then change if they deem they need to do so. To illustrate this using a learning tool I’ve created, more on this later, there is a ‘Click’ button followed by a number. This number is stored on the server, and when the button is clicked the ‘change request’ happens to increment it. Thus, click, wait, update:
Because you have in essence to wait for ‘approval’ by the server of your action, then to me this seems slow and could be frustrating for the user. I argued this in ‘Understanding the reactive UI’ on the Moodle developer’s forum. But the thing is in our world that we want things to happen now, to not be so patient but have the result there and if it’s not then we ‘click’ again. This then brings thoughts about how changes in a multi-user environment are orchestrated.
When in the physical world we are working on a task with a group of people, we know what each of us is working on purely because of adjacent physical presence. We co-ordinate and at any one given time only one person can be physically interacting with a given element of the world. In effect ‘locking’ it’s use from somebody else. In the virtual world ‘locks’ (en.wikipedia.org/wiki/Lock_(computer_science)) are employed, but that would mean that the UI would have to lock / unlock elements for the user before they potentially changed them. More overhead and with the chance that a ‘lock’ would not be released and therefore prevent any user from changing an element without some sort of ‘reset’ intervention.
This then leads to the question: Should the UI make the change for the user based on the data state it’s sending to the server, it then validates and then informs the client (user) that the change was successful by returning the change. If the returned change matches what the user did, then nothing happens. Otherwise it changes to what the server said it should? Therefore the user gets a faster response with other elements updating as they need to. After all, our focus is on what we are working on, not so much what is around us. We’re not so bothered about that but we are about what we are doing. Besides as humans we co-ordinate ourselves such that we work on elements separately, thus reducing the risk of the same element being changed at the same time. Therefore do we need to have the requirement that the server tells us that the change can happen? Perhaps there needs to be a block on a course that shows whom is editing the course? Then we’d be aware of unexpected changes on that course and not get frustrated.
For the time being though, the reactive ‘pattern’ is in place and understanding how its works and why allows us to cope with its behaviour.
A learning tool
In order to understand what events I needed to react (in code) to in order to solve my problem appreciate what is involved with having my own UI changes, I decided that I needed to observe what events where happening on the UI when they happened. Moodle already has a debugging functionality in the footer when the system setting ‘debug’ is set to ‘Developer’:

But this only shows for the administrator. What if you wanted to know what’s happening with an editing teacher? Enter the world of ‘local’ plugins (moodledev.io/docs/apis/plugintypes/local), they are a generic plugin type that allows you to have functionality that is not tied to any particular Moodle concept. Rather that they allow you to implement functionality that integrates with Moodle to whatever specific thing you need it to do.
Thus I created ‘Local Observer’, a plugin that would:
- Report all events to the browser console with their data. Unlike the core debugging functionality which only shows you the state and not the data associated with each event.
- Have its own UI element that you’d interact with and change its state, observing what is happening and understanding how to implement it.
The outcome of this development is (in this case, an editing teacher is shown):

Where you can see the ‘Click’ button again, followed by a number. The number being the number of clicks recorded for that course by all users that can access that course. Underneath in the browser console you can see all of the events that have ‘fired’ as a result of the page loading and the button being pressed (screen shot shows as many as I can fit!).
Local Observer even implements its own ‘Reactive Instance’ rather than relying on the core ‘Course Editor’:

Again so I could understand as much as possible of the reactive ‘pattern’.
Value
Local Observer by it’s very nature as a Moodle plugin written partly in PHP and integrating with it at an API level has to be GPLv3 licensed (www.gnu.org/licenses/gpl-faq.html#GPLAndPlugins and www.gnu.org/licenses/gpl-faq.html#GPLPlugins), and with the licence itself www.gnu.org/licenses/gpl-3.0.en.html. But that does not mean that I have to make the plugin available if I don’t want to. It only means that if I decide to give you a copy that you can re-propagate if you wish as long as it retains the same license. That there is no copyright infringement because I’m in effect copyrighting it to make it ‘open source’ and affix the GPLv3 license to it. Though I’m a software engineer, not a lawyer so this is just my interpretation.
Moodle itself and all the other plugins written for it will (or should) be GPLv3 in full / part or a compatible license. Therefore what value do they have to you? Is Local Observer something that would benefit you or simply a tool specific to my learning of the reactive user interface? Purely something for me to use when I need to at a later date or is it more than that?
Conclusion
I have now solved the problem I wanted to solve with the code github.com/gjbarnard/moodle-theme_adaptable/blob/V500.1.2/amd/src/activity_navigation.js and it has been quite a journey to accomplish that. As is often the case in software engineering.
I hope by creating this post that you’ve learnt something new about the Moodle UI as it is now. What more can you ‘observe’ by interacting with the interface?
- Reactive? – 16th September 2025
- Gathering dust – 16th August 2025
- Humanity – 16th July 2025