Moodle

Automatically and periodically save WYSIWYG editor content as a draft/concept

Details

  • Type: New Feature New Feature
  • Status: Open Open
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: 1.9.3
  • Fix Version/s: DEV backlog
  • Component/s: Forms Library, HTML Editor
  • Labels:
    None
  • Difficulty:
    Moderate
  • Affected Branches:
    MOODLE_19_STABLE

Description

This emerged during the discussion at MDL-13370. Shortly: use AJAX to automatically and periodically (eg. every minute) save the content of a WYSIWYG editor to the concepts (drafts) space. See GMail for the working example.

It seems to me that we could use table mdl_post for this therefore not DB changes should be required. There will be a flag for a rich text field definitions that enables this feature. Every WYSIWYG will have to have some uniq identifier. Concepts are accessible to their owners only (and admins?) - maybe via a card in their profiles? Their lifetime is a subject of configuration - couple of hours by default.

  1. MDL-18014-autosave-alpha1.diff.txt
    05/Feb/09 11:12 PM
    19 kB
    David Mudrak
  1. autosave-1.png
    28 kB
    25/Jan/09 9:46 AM
  2. autosave-2.png
    29 kB
    25/Jan/09 9:47 AM
  3. autosave-3.png
    7 kB
    03/Feb/09 1:39 AM
  4. autosave-4.png
    9 kB
    03/Feb/09 1:39 AM

Issue Links

Activity

Hide
David Mudrak added a comment -

By Olli Savolainen at http://moodle.org/mod/forum/discuss.php?d=74710 :

"A similar thing could be done, yes, for forum posting, too, or for that matter any other form field. Since Moodle uses YUI instead of prototype, it should be done with that, and probably we should try to make it more general than just something that works for quiz or for forum; i.e. this kind of functionality should be integrated in the editor itself and a general backend to receive the autosaves would need to be created."

Show
David Mudrak added a comment - By Olli Savolainen at http://moodle.org/mod/forum/discuss.php?d=74710 : "A similar thing could be done, yes, for forum posting, too, or for that matter any other form field. Since Moodle uses YUI instead of prototype, it should be done with that, and probably we should try to make it more general than just something that works for quiz or for forum; i.e. this kind of functionality should be integrated in the editor itself and a general backend to receive the autosaves would need to be created."
Hide
David Mudrak added a comment -

I've got first working prototype of autosaving. At the moment it can support all form fields rendered by print_textarea(). There are several important aspects to be discussed:

1. at the moment, I save the content of the field into the table 'post' where module is 'autosave'. Is it ok?
2. how shall we implement a recovery procedure? i mean - what the user has to do to get the autosaved contents? I can see two possible approaches:
2.1. add another tab into the user profile where she can find all her recent autosaved fields. This is easy to implement and might be enough given that autosave feature is just a backup&rescue tool
2.2. after the page with a supported field is loaded, try to check if we have a previously autosaved content and offer it to user. This is more difficult to implement. How to make sure we are at the same page again? URL may have changed since the field was autosaved...

Show
David Mudrak added a comment - I've got first working prototype of autosaving. At the moment it can support all form fields rendered by print_textarea(). There are several important aspects to be discussed: 1. at the moment, I save the content of the field into the table 'post' where module is 'autosave'. Is it ok? 2. how shall we implement a recovery procedure? i mean - what the user has to do to get the autosaved contents? I can see two possible approaches: 2.1. add another tab into the user profile where she can find all her recent autosaved fields. This is easy to implement and might be enough given that autosave feature is just a backup&rescue tool 2.2. after the page with a supported field is loaded, try to check if we have a previously autosaved content and offer it to user. This is more difficult to implement. How to make sure we are at the same page again? URL may have changed since the field was autosaved...
Hide
Tim Hunt added a comment -

This is a valuable feature, but ...

1. I don't think that the post table is the right place for this. Make a new table specifically for this purpose.

2. Recovery should be as transparent as possible.

3. If this is worth doing, surely it is worth doing for all form fields.

4. What does this do to server load. For example it is not much good auto-saving data during a quiz attempt, if the result is to overload the server and crash it when otherwise everything would be fine.

5. What are the security implications. For example, if an malicious person can insert arbitrary content into the admin's autosaved fields area, then when the admin goes to look at that content, he is vulnerable to XSS vulnerabilities. Of course, the more validation you try to do, the more the performance implications.

6. Whatever happens, we need an on/off switch in the admin settings, so admins can control this.

7. What are we actually trying to achieve here anyway? Are we saving people from browser crashes, session problems, server crashes, what?

Show
Tim Hunt added a comment - This is a valuable feature, but ... 1. I don't think that the post table is the right place for this. Make a new table specifically for this purpose. 2. Recovery should be as transparent as possible. 3. If this is worth doing, surely it is worth doing for all form fields. 4. What does this do to server load. For example it is not much good auto-saving data during a quiz attempt, if the result is to overload the server and crash it when otherwise everything would be fine. 5. What are the security implications. For example, if an malicious person can insert arbitrary content into the admin's autosaved fields area, then when the admin goes to look at that content, he is vulnerable to XSS vulnerabilities. Of course, the more validation you try to do, the more the performance implications. 6. Whatever happens, we need an on/off switch in the admin settings, so admins can control this. 7. What are we actually trying to achieve here anyway? Are we saving people from browser crashes, session problems, server crashes, what?
Hide
David Mudrak added a comment -

Thanks for your "buts", Tim.

re 1. I have chosen the current post table because they are simply there and ready, which makes the development and testing much much easier (no need to upgrade, bump versions etc.). I will keep in mind that the physical storage can be change in the future. However, all I/O operation are wrapped so it won't be hard task to rewrite this part.

re 2. well, it matters. I understand this feature as a rescue tool for users whose browsers do not cache the content of our HTML editor. Moreover, because TinyMCE does not update the content of the textarea it is linked to automatically but at the moment of saving the form (using tinyMCE.triggerSave(} call), the browser has nothing to cache. So, I do not think we really need a transparent recovery. Ask somebody who spent half an hour writing a forum post, then lost the focus of the editor (by a popup for example), returned back (after closing the popup) and pressed the backspace because of a typo. He is redirected to the previous page and after returning back, the HTML editor is empty. Such user will be more than happy if he is able to find a minute old draft of his post anywhere in the Moodle, without the need to get the content automatically. Of course, I would like to see a transparent and silent recovery more, but it makes the whole mechanism more complicated. I like things simply stupid.

re 3. sure it is. Let us start with the support of HTML editor. Usually standard form fields are pretty well cached by the browser itself and the input is not so long.

re 4 + 6. totally agree. Admins will have to enable this feature and set the frequency of the autosaving (influnce the server load) and the draft lifetime

5. a priority issue, of course. That is why I wanted to put automatically saved drafts into a user space, ie. his profile. No automatic pre-filling of forms from drafts. If I loose something, I will find it in a rescue box at my profile page. Should standard sesskey() validation be enough in this case?

7. see the users' stories in the linked issues. Basically this should protect from browser crashes, accidental redirections, window/tab close, connectivity problems, server crash etc. Actually I can't see the point of this question.

Show
David Mudrak added a comment - Thanks for your "buts", Tim. re 1. I have chosen the current post table because they are simply there and ready, which makes the development and testing much much easier (no need to upgrade, bump versions etc.). I will keep in mind that the physical storage can be change in the future. However, all I/O operation are wrapped so it won't be hard task to rewrite this part. re 2. well, it matters. I understand this feature as a rescue tool for users whose browsers do not cache the content of our HTML editor. Moreover, because TinyMCE does not update the content of the textarea it is linked to automatically but at the moment of saving the form (using tinyMCE.triggerSave(} call), the browser has nothing to cache. So, I do not think we really need a transparent recovery. Ask somebody who spent half an hour writing a forum post, then lost the focus of the editor (by a popup for example), returned back (after closing the popup) and pressed the backspace because of a typo. He is redirected to the previous page and after returning back, the HTML editor is empty. Such user will be more than happy if he is able to find a minute old draft of his post anywhere in the Moodle, without the need to get the content automatically. Of course, I would like to see a transparent and silent recovery more, but it makes the whole mechanism more complicated. I like things simply stupid. re 3. sure it is. Let us start with the support of HTML editor. Usually standard form fields are pretty well cached by the browser itself and the input is not so long. re 4 + 6. totally agree. Admins will have to enable this feature and set the frequency of the autosaving (influnce the server load) and the draft lifetime 5. a priority issue, of course. That is why I wanted to put automatically saved drafts into a user space, ie. his profile. No automatic pre-filling of forms from drafts. If I loose something, I will find it in a rescue box at my profile page. Should standard sesskey() validation be enough in this case? 7. see the users' stories in the linked issues. Basically this should protect from browser crashes, accidental redirections, window/tab close, connectivity problems, server crash etc. Actually I can't see the point of this question.
Hide
David Mudrak added a comment -

Well. After submitting the previous post I repeated some tests to be sure and realized that maybe my arguments are useless. TinyMCE in HEAD is cached in my FF3 when navigating to the previous page and back again :-/ It does not work with the current editor (HTMLArea is it?) in 1.9 stable but does in HEAD. Hmm... much ado about nothing? I will test IE and Opera yet. Can some Apple fan try Safari please?

Show
David Mudrak added a comment - Well. After submitting the previous post I repeated some tests to be sure and realized that maybe my arguments are useless. TinyMCE in HEAD is cached in my FF3 when navigating to the previous page and back again :-/ It does not work with the current editor (HTMLArea is it?) in 1.9 stable but does in HEAD. Hmm... much ado about nothing? I will test IE and Opera yet. Can some Apple fan try Safari please?
Hide
Matt Gibson added a comment -

Regarding point 7, there is also simply forgetting about a tab you've been working on and shutting the browser. I've done this three times in the last two weeks whilst writing long schemes of work into a wiki and it's driving me nuts.

It occurred to me that it may not be obvious to people that they have a saved draft at all (new feature may not be widely publicised by admins), which would be a real waste of a great feature, so it might be handy if there was some visual indicator e.g. an 'unsaved work' icon next to the item on the main course page and also within the activity itself.

Show
Matt Gibson added a comment - Regarding point 7, there is also simply forgetting about a tab you've been working on and shutting the browser. I've done this three times in the last two weeks whilst writing long schemes of work into a wiki and it's driving me nuts. It occurred to me that it may not be obvious to people that they have a saved draft at all (new feature may not be widely publicised by admins), which would be a real waste of a great feature, so it might be handy if there was some visual indicator e.g. an 'unsaved work' icon next to the item on the main course page and also within the activity itself.
Hide
Mark Nielsen added a comment -

What about implementing this through the Moodle form API? The form could have a unique ID (perhaps just use the form's class name?), which is saved with its data into the database. If the form is loaded and there is info for that user in the db, then automatically load the form with the data or ask the user if s/he would like to load it with the data. On submit, the data in the database gets cleared. This route would be transparent for users and turn the form API into an even more powerful tool for developers.

I would also suggest using the YUI since it is part of Moodle's codebase and it is relatively simple to have it submit a form's data to a URL. Also, it has a nice event listener API that's very helpful for this sort of work.

A note on performance, one way to help reduce the number of saves is not just by doing it periodically, but also not saving while the user is typing because as soon as you save, it is out of date anyways. You can accomplish this with timeouts by setting one when you detect a change in the form, and then if you detect another change before the timeout has come to pass, then clear/cancel the old timeout and set a new one.

Show
Mark Nielsen added a comment - What about implementing this through the Moodle form API? The form could have a unique ID (perhaps just use the form's class name?), which is saved with its data into the database. If the form is loaded and there is info for that user in the db, then automatically load the form with the data or ask the user if s/he would like to load it with the data. On submit, the data in the database gets cleared. This route would be transparent for users and turn the form API into an even more powerful tool for developers. I would also suggest using the YUI since it is part of Moodle's codebase and it is relatively simple to have it submit a form's data to a URL. Also, it has a nice event listener API that's very helpful for this sort of work. A note on performance, one way to help reduce the number of saves is not just by doing it periodically, but also not saving while the user is typing because as soon as you save, it is out of date anyways. You can accomplish this with timeouts by setting one when you detect a change in the form, and then if you detect another change before the timeout has come to pass, then clear/cancel the old timeout and set a new one.
Hide
David Mudrak added a comment -

IMHO the form's class is not enough here - the autosave ID should combine the field id and the URL. But in theory the URL may change while still pointing to the same page where the draft was saved.

Yes, the current implementation is based on YUI.

Hmm, I don't think it is good to wait for the user stop typing. It means that the work of "quick-typers" is never autosaved. Instead, there is no need to send an update call to server in case of no change. We could do some statistics based on moodle.org logs: how long does it take to write an average forum post? Ie. the time from displaying the form to the submitting.

Show
David Mudrak added a comment - IMHO the form's class is not enough here - the autosave ID should combine the field id and the URL. But in theory the URL may change while still pointing to the same page where the draft was saved. Yes, the current implementation is based on YUI. Hmm, I don't think it is good to wait for the user stop typing. It means that the work of "quick-typers" is never autosaved. Instead, there is no need to send an update call to server in case of no change. We could do some statistics based on moodle.org logs: how long does it take to write an average forum post? Ie. the time from displaying the form to the submitting.
Hide
Mark Nielsen added a comment -

"IMHO the form's class is not enough here - the autosave ID should combine the field id and the URL. But in theory the URL may change while still pointing to the same page where the draft was saved."

What about using $CFG->pagepath? On the other hand, I wasn't necessarily thinking that we would just enable autosave automatically for every form in Moodle, might be better to have devs implement in the necessary areas. In which case, the dev could assign an appropriate ID. Just another though.

Show
Mark Nielsen added a comment - "IMHO the form's class is not enough here - the autosave ID should combine the field id and the URL. But in theory the URL may change while still pointing to the same page where the draft was saved." What about using $CFG->pagepath? On the other hand, I wasn't necessarily thinking that we would just enable autosave automatically for every form in Moodle, might be better to have devs implement in the necessary areas. In which case, the dev could assign an appropriate ID. Just another though.
Hide
David Mudrak added a comment -

Yes, that might be a solution. Of course that fields that should be autosaved will be manually flaged by a developer. I was thinking of forum post bodies only at this moment and there should be no problem identifying such fields.

Show
David Mudrak added a comment - Yes, that might be a solution. Of course that fields that should be autosaved will be manually flaged by a developer. I was thinking of forum post bodies only at this moment and there should be no problem identifying such fields.
Hide
Sam Marshall added a comment -

Re screenshot:

1 'Saving' should prob. be 'Saving draft' or even 'Autosaving draft'. Don't want to scare users into thinking it's already been submitted.

2 The saving text should be much smaller

Show
Sam Marshall added a comment - Re screenshot: 1 'Saving' should prob. be 'Saving draft' or even 'Autosaving draft'. Don't want to scare users into thinking it's already been submitted. 2 The saving text should be much smaller
Hide
David Mudrak added a comment -

I like sam's idea (from the jabber chatroom):

(15:29:09) sam: can it store the page id (mod-forum-editpost or whatever) and then when you go to that page again (any forum post), display a little '1 recent autosaved draft is available' thing that you can click on to see it and/or get it back somehow?

Show
David Mudrak added a comment - I like sam's idea (from the jabber chatroom): (15:29:09) sam: can it store the page id (mod-forum-editpost or whatever) and then when you go to that page again (any forum post), display a little '1 recent autosaved draft is available' thing that you can click on to see it and/or get it back somehow?
Hide
David Mudrak added a comment -

More screenshots to demonstrate the current implementation:

1. after the page is loaded, an AJAX based check is performed to get know if there is some previously autosaved draft
2. if no saved draft is found, the autosaving feature is enabled and the field content is saved every xxx seconds
3. if there is a draft found, an information appears (with a "yellow fade efect" to draw user's attention) and the draft can be restored with a single click

Show
David Mudrak added a comment - More screenshots to demonstrate the current implementation: 1. after the page is loaded, an AJAX based check is performed to get know if there is some previously autosaved draft 2. if no saved draft is found, the autosaving feature is enabled and the field content is saved every xxx seconds 3. if there is a draft found, an information appears (with a "yellow fade efect" to draw user's attention) and the draft can be restored with a single click
Hide
David Mudrak added a comment -

The actual state of my patch has been attached as autosave-alpha1.diff.txt. Any comments/review/suggestions etc. warmly welcome

Show
David Mudrak added a comment - The actual state of my patch has been attached as autosave-alpha1.diff.txt. Any comments/review/suggestions etc. warmly welcome
Hide
David Mudrak added a comment -

Stopping progress on this for a while. Petr informed me there are some planned changes in the HEAD leading to introduce a new form element. The element will integrate wysiwyg editor, image uploader and attachment uploader. It looks reasonable for me to wait for this component to be included and than support autosave of it.

Show
David Mudrak added a comment - Stopping progress on this for a while. Petr informed me there are some planned changes in the HEAD leading to introduce a new form element. The element will integrate wysiwyg editor, image uploader and attachment uploader. It looks reasonable for me to wait for this component to be included and than support autosave of it.
Hide
Mauno Korpelainen added a comment -

David - can you check http://moodle.org/mod/forum/discuss.php?d=130005&parent=569051#p569547 and http://code.google.com/p/tinyautosave/

TinyAutoSave plug-in works very well in moodle 2.0 (for textareas of tinymce) as an additional / optional autosave feature (should be possible to enable/disable from administration of course)

Show
Mauno Korpelainen added a comment - David - can you check http://moodle.org/mod/forum/discuss.php?d=130005&parent=569051#p569547 and http://code.google.com/p/tinyautosave/ TinyAutoSave plug-in works very well in moodle 2.0 (for textareas of tinymce) as an additional / optional autosave feature (should be possible to enable/disable from administration of course)
Hide
Martin Dougiamas added a comment -

I would still very like to see this in 2.0 if it's not going to be very hard to do.

Show
Martin Dougiamas added a comment - I would still very like to see this in 2.0 if it's not going to be very hard to do.
Hide
David Mudrak added a comment -

The purpose of TinyAutoSave is just to prevent from accidental navigating away from the page (by clicking a link or pressing Backspace button). The disadvantage is that it does not store the draft on the server so it is not the same concept as discussed above. But the advantage is that it does not store the draft on the server so there are no performance/bandwidth issues.

This issue requires some decisions on the required functionality so that we decide about the target version.

1. Should the embedded media and attached files be autosaved, too? I am not sure our File API can support this at the moment. What file area would we used? What would be the context of the files? And itemids?
2. Should the draft be saved on server side or client side?

Show
David Mudrak added a comment - The purpose of TinyAutoSave is just to prevent from accidental navigating away from the page (by clicking a link or pressing Backspace button). The disadvantage is that it does not store the draft on the server so it is not the same concept as discussed above. But the advantage is that it does not store the draft on the server so there are no performance/bandwidth issues. This issue requires some decisions on the required functionality so that we decide about the target version. 1. Should the embedded media and attached files be autosaved, too? I am not sure our File API can support this at the moment. What file area would we used? What would be the context of the files? And itemids? 2. Should the draft be saved on server side or client side?
Hide
Minh-Tam Nguyen added a comment -

I think that saving the draft on the server is a better solution, as this will protect the draft from getting lost if the user's computer crashes.

A case that is occasionally reported to us here is that students start typing their post, but then for whatever reason their computer crashes.
This means that they have to log on again, potentially on a different computer, and in our particular case on a computer that has been deep-frozen. As such, any cached drafts will be lost.

I think that if the draft was saved on the server, the user could then pick up where they left no matter if they switched computer or not.

Show
Minh-Tam Nguyen added a comment - I think that saving the draft on the server is a better solution, as this will protect the draft from getting lost if the user's computer crashes. A case that is occasionally reported to us here is that students start typing their post, but then for whatever reason their computer crashes. This means that they have to log on again, potentially on a different computer, and in our particular case on a computer that has been deep-frozen. As such, any cached drafts will be lost. I think that if the draft was saved on the server, the user could then pick up where they left no matter if they switched computer or not.
Hide
Koen Roggemans added a comment -

It is a difficult question. A network connection failure at saving time will probably cause the text and the draft to be lost.
I guess saving it simultaneously local and server side is not an option ?

Show
Koen Roggemans added a comment - It is a difficult question. A network connection failure at saving time will probably cause the text and the draft to be lost. I guess saving it simultaneously local and server side is not an option ?
Hide
Mauno Korpelainen added a comment -

Server side and/or client side solutions could be used at the same time - current core autosave plugin of tinymce has supported local storage methods since January (no more need to download separate TinyAutoSave plugin anymore) - moodle 2.0 should just be upgraded to use the latest version of tinymce (3.3.6) and moodle sites can add/enable client side autosave feature in init code for those textareas that use tinymce with possible functionality settings http://code.google.com/p/tinyautosave/wiki/Functionality . Autosave plugin supports all the browsers that tinymce supports.

The primary solution for temporary autosaving user input data might still be a server side solution as far as it can be used and we might need a setting to administration to be able to enable/disable either one or both of these options. In my opinion it does not need to be too complex (at first), the most common failure is that users accidentally press some link or button that moves them away from editor screen or they press some button that closes window/moodle. HTMLArea has failed to keep input data in such cases, tinymce with autosave plugin can in most cases restore the last data.

Keeping track of user processes might be usefull for other purposes as well - for example Version control here in tracker offers a nice way to track back last changes in files and in Wiki it is useful to find the last changes saved by different users. The main difficulty in autosaving data is in my opinion the choice of deleting unnecessary data - particularly duplicate files - as soon as possible

So if we need to autosave also attachments (clone attachments) clones should be deleted immediatelly after the actual data & attachments have been saved (or small hosted sites run easily out of hard disc space

Show
Mauno Korpelainen added a comment - Server side and/or client side solutions could be used at the same time - current core autosave plugin of tinymce has supported local storage methods since January (no more need to download separate TinyAutoSave plugin anymore) - moodle 2.0 should just be upgraded to use the latest version of tinymce (3.3.6) and moodle sites can add/enable client side autosave feature in init code for those textareas that use tinymce with possible functionality settings http://code.google.com/p/tinyautosave/wiki/Functionality . Autosave plugin supports all the browsers that tinymce supports. The primary solution for temporary autosaving user input data might still be a server side solution as far as it can be used and we might need a setting to administration to be able to enable/disable either one or both of these options. In my opinion it does not need to be too complex (at first), the most common failure is that users accidentally press some link or button that moves them away from editor screen or they press some button that closes window/moodle. HTMLArea has failed to keep input data in such cases, tinymce with autosave plugin can in most cases restore the last data. Keeping track of user processes might be usefull for other purposes as well - for example Version control here in tracker offers a nice way to track back last changes in files and in Wiki it is useful to find the last changes saved by different users. The main difficulty in autosaving data is in my opinion the choice of deleting unnecessary data - particularly duplicate files - as soon as possible So if we need to autosave also attachments (clone attachments) clones should be deleted immediatelly after the actual data & attachments have been saved (or small hosted sites run easily out of hard disc space
Hide
David Mudrak added a comment -

Re-triage: this must be re-considered for some future version, not in stable.

Show
David Mudrak added a comment - Re-triage: this must be re-considered for some future version, not in stable.

Dates

  • Created:
    Updated: