Javascript in Moodle 2

Javascript in Moodle 2

by Andrew Lyons -
Number of replies: 7
Picture of Core developers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Testers
Ruslan and I have been working on some interesting (at least to us) javascript updates to Moodle 2 and I wanted to share some of what we've been doing.

So far we've rewritten and removed the old section_ajax.js file along with several other related files. We've rewritten everything as a set of moodle YUI3 modules and have improved (hopefully) the performance of the drag and drop code. We've also massively simplified the javascript and hopefully made it more maintainable in the future.

Ruslan is now working to rewrite the drag and drop for blocks - a feature which has been missing since Moodle 2 came out. We'll also be looking at adding the other block controls (show/hide, group modes, etc) using AJAX calls again.

I've put together a quick screen cast to demonstrate the drag and drop and one of the other changes:


We've also submitted the code in MDL-31052, and MDL-31215.

We'd love to have feedback (and peer review) on these changes so far.

Thanks,

Andrew and Ruslan
LUNS Limited
Average of ratings: -
In reply to Andrew Lyons

Re: Javascript in Moodle 2

by Mary Cooch -
Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Testers Picture of Translators

Nice screencastsmile

I like two things

  1. the fact that from your screencast dragging and dropping items/sections seems to work much better - because  I agree, previously you could try to drag something and end up in the back of beyond; certainly not where you wanted to move to
  2. I LOVE the ability to do a quick spelling change without having to go into the editing. That is one of those small changes that makes such a big difference to usability. I want that NOW.
In reply to Andrew Lyons

Re: Javascript in Moodle 2

by Itamar Tzadok -

While I can appreciate some of the suggested improvements I think it should be a good time to stop pushing javascript enhancement into core and focus on making such enhancements plugable. Moodle is already stuffed with tightly integrated enhancements, some of which are indisputably badly or half implemented. I should be able to simply remove any js enhancement either to ease things up or to replace them with my own without hacking the core code. A standard set of enhancements may be distributed with standard moodle, but they should be replacable just like replacing icons in themes. smile

In reply to Itamar Tzadok

Re: Javascript in Moodle 2

by Andrew Lyons -
Picture of Core developers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Testers
Hi Itamar,

Actually, the way that this is implemented should make life slightly easier for you if anything. The existing YUI2 code is very difficult to work with and disable as it's written as a set of functions.

The YUI3 replacement is written as a set of YUI modules - I believe it should be possible to extend and/or override as appropriate. I think we've ended up with 4 YUI modules in total for:
* general resource and section javascript
* section drag/drop
* resource drag/drop
* drag/drop core (not actually initialized directly)

I'm not sure how you'd entirely *remove* a core YUI module though - it's not something I've tried to do yet! Ruslan may be able to comment further on this,

Andrew
In reply to Andrew Lyons

Re: Javascript in Moodle 2

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

I've not yet looked at the code (and the demo does look very nice!), so apologies if you've covered either of these already, but I've got a suggestion and a request to do with this new Javascript code:

First, a suggestion: at the moment, if you edit a page using AJAX, click on a link and then return to the course page using the browser 'back' button, you are presented with the state before you edited anything (until you refresh the page). Things can get very confused if you try to edit the page in this state. It would be great if you could implement some way of 'phoning home' when the course javascript initialises and then force a page refresh (of some kind) if the page has been edited since the page was generated.

Second, a request: please could you make sure there is some way for other scripts to hook into your code to initialise any later additions to the page. I currently use this to allow my drag and drop upload block to work: I create new resource elements on the page dynamically, when files are dropped onto the page, then call the AJAX course edit script to add the correct editing elements (see the last few lines here https://github.com/davosmith/moodle-block_dndupload/blob/master/dndupload.js for the code I use - I also check for the existence of an object called 'main' to detect that AJAX course editing is enabled, some hook to allow such detection would be great as well). Whilst my block is currently a 3rd part plugin, I hope that some code I am writing, based on it, may someday make it into core.

I also hope that someday the course editing is updated to allow new activities to be added using AJAX directly on the course page (maybe with some popup dialog boxes to gather basic details) - in this case, a hook to add controls directly to these new activities would also be useful.

Anyway, keep up the good work - it looks a lot more stable than the current drag & drop.

In reply to Davo Smith

Re: Javascript in Moodle 2

by Andrew Lyons -
Picture of Core developers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Testers
Re: forcing a refresh:
Good thought -- I'm not sure how we'd determine whether the course had been changed without checking each module in turn so it's something to look into.
It's certainly something we should look to do.


Re your request:
Unlike the existing code which removes all items in the command span and re-adds the ones it wants; the new and updated code basically works by:
* remove the href
* add an on click handler

As a result, there's no longer a function to add all of the editing icons in one go which I think is the one you're using and we'd therefore need to rewrite one for code such as yours.
I think though that we should look at doing this in a far more elegant way - for example having a pluggable system so that a YUI plugin can register an oncreate type function when it instantiates to set up anything it requires. This would allow anyone using JS to add additional buttons to plug in and have them there too. I've not written this or thought about it much more yet as I wasn't aware of any code which did this at present - perhaps you have some thoughts on how this could be implemented more elegantly than the current solution..?

WRT to the ajax course editing, I'm sure we can add something if you can't already use what's there. At present we're not respecting the 'Advanced AJAX features' option in a users profile and are solely relying on whether javascript is enabled in the browser - we've discussed it at length internally and feel that with the functionality written with a progressive enhancement stance it *shouldn't* be necessary.

Andrew
In reply to Andrew Lyons

Re: Javascript in Moodle 2

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

The main problem is editing the page via AJAX, navigating away then back again. Storing a 'last modified' timestamp for each course (updated when it receives an AJAX update request), embedding that value within the javascript initialisation parameters then firing off a quick 'is this the right timestamp?' request on initialisation should give a fairly big clue. It won't cover modification of an individual activity (e.g. a name change / groups change via the activity settings page), but those are more likely to result in a redirect to an updated course page anyway (if you are pressing the 'back' button you are much more likely to have viewed an activity, then gone back to the course page).

As for updating the icons - I assume your new code must work on some HTML generated by the course format output and then transform it. My drag and drop plugin (which I know is a fairly specialised example), uses the old function call on the back-end to generate the snippet for the action buttons, passes this back via the dndupload AJAX call, adds it to the page and then lets the course editing AJAX transform it to what it wants. Which, without having looked through your code yet, would still be very similar to what would happen with your new code.