Ask if save changes
MoinMoin modification to confirm saving changes before leaving the editor page.
Features
- It asks user to save changes before leaving the page editing.
- It there is no change in the text, it does not ask.
Please make it so that only "Cancel" does ask, I hate it if the computer constantly questions my mouse clicks -- i.e. if I click the Save bbutton, I mean it. -- JürgenHermann 2005-10-20 18:57:32
Please make it so "Cancel" does NOT ask The question should be asked only when there is a high chance that you don't mean to drop your changes. If you try to close the window, you probably don't mean to drop your changes, you simply forgot about them. If you done a preview, and clicked on a link in the preview, you probably don't mean to drop your changes. But if you point your mouse above the "Cancel" button, and click it, you do mean to cancel your changes.
Second, even more important - the editor should NOT ask "Close the editor without saving changes?" and accept "OK" or "Cancel" - this is the wrong way, used by Microsoft everywhere, and confusing even expert users.
Or in other words, not this:
Are you really sure you don't want not to save? [[OK]] [[Cancel]]
The editor should suggest some actions, and let you choose with one click:
Do you want to save the changes you have made? [[Save]] [[Cancel]] [[Don't save]]
- When you click the default button "Save" or click Enter or Return, the editor should save the changes, and you should go on to your original destination.
- When you click "Cancel", the operation you started, will be canceled
- When you click "Don't Save" you will continue to the destination, dropping the changes.
-- NirSoffer 2005-10-20 20:16:28
IMHO "Cancel" should be "Resume editing" or shorter "Back". -- JürgenHermann 2005-10-22 18:02:17
I agree that the editor should suggest 3 choices above, but I could not find any javascript code for that. I think that it'd be better to ask 'Continue without saving changes?'. I think that the page editor should not intend "you save the changes!" but "just for your information, I inform you have some changes but you meant to leave this page without saving them". -- SeungikLee 2005-10-21 01:58:49
Internal
uses onbeforeunload event in javascript
Platform Support
- Tested on/with:
Sample
You can test the modified page editor in my moinmoin
- this wiki (currently only with text editor). if we stay happy with it, we add gui editor later.
How to apply
- wikiutil.py
--- wikiutil-1.3.5.py 2005-07-24 19:32:50.000000000 +0900 +++ wikiutil.py 2005-10-22 00:17:22.078125000 +0900 @@ -984,6 +984,7 @@ @keyword html_head: additional <head> code @keyword body_attr: additional <body> attributes @keyword body_onload: additional "onload" JavaScript code + @keyword body_onbeforeunload: additional "onBeforeUnload" JavaScript code """ from MoinMoin.Page import Page _ = request.getText @@ -1136,6 +1137,11 @@ body_onload = keywords.get('body_onload', '') if body_onload: bodyattr.append(''' onload="%s"''' % body_onload) + + body_onbeforeunload = keywords.get('body_onbeforeunload', '') + if body_onbeforeunload: + bodyattr.append(''' onBeforeUnload="%s"''' % body_onbeforeunload) + output.append('\n<body%s>\n' % ''.join(bodyattr)) # Output -----------------------------------------------------------
PageEditor.py
--- PageEditor-1.3.5.py 2005-07-28 00:51:40.000000000 +0900 +++ PageEditor.py 2005-10-22 00:30:33.625000000 +0900 @@ -275,6 +275,7 @@ page=self, pagename=self.page_name, msg=status, body_onload=self.lock.locktype and 'countdown()' or '', # broken / bug in Mozilla 1.5, when using #preview + body_onbeforeunload = 'return confirmleaving();', html_head=self.lock.locktype and ( _countdown_js % { 'lock_timeout': lock_timeout, @@ -316,7 +330,7 @@ self.request.write('</p>') # send form - self.request.write('<form id="editor" method="post" action="%s/%s#preview">' % ( + self.request.write('<form id="editor" method="post" action="%s/%s#preview" onSubmit="flgChange = false;">' % ( self.request.getScriptname(), wikiutil.quoteWikinameURL(self.page_name), )) @@ -352,9 +366,25 @@ # language into meta file. lang = self.language or self.request.cfg.default_lang + # XXXX Seungik Lee + # to prevent moving out the page without saving it + + self.request.write( + u'\r\n<script type="text/javascript">\r\n' + u' var flgChange = false;\r\n' + u' function confirmleaving() { \r\n' + u' if ( flgChange == true )\r\n' + u' return "YOUR CHANGES ARE NOT SAVED!";\r\n' + u' \r\n' + u' }\r\n' + u'</script>\r\n' + ) + + # XXXX + self.request.write( u'<textarea id="editor-textarea" name="savetext" lang="%(lang)s" dir="%(dir)s"' - u' rows="%(rows)d">' % { + u' rows="%(rows)d" onChange="flgChange = true;" onKeyPress="flgChange = true;">' % { 'lang': lang, 'dir': i18n.getDirection(lang), 'rows': text_rows, @@ -366,7 +396,7 @@ self.request.write('</p>') self.request.write("<p>", _("Optional comment about this change"), - '<br><input id="editor-comment" type="text" name="comment" value="%s" maxlength="80"></p>' % ( + '<br><input id="editor-comment" type="text" name="comment" value="%s" maxlength="80" onChange="flgChange = true;" onKeyPress="flgChange = true;"></p>' % ( wikiutil.escape(kw.get('comment', ''), 1), )) # Category selection @@ -381,7 +411,7 @@ # button bar button_spellcheck = (SpellCheck and - '<input type="submit" name="button_spellcheck" value="%s">' + '<input type="submit" name="button_spellcheck" value="%s" onClick="flgChange = false;">' % _('Check Spelling')) or '' save_button_text = _('Save Changes') @@ -400,8 +430,8 @@ self.request.write(''' <p> -<input type="submit" name="button_save" value="%s"> -<input type="submit" name="button_preview" value="%s"> %s +<input type="submit" name="button_save" value="%s" onClick="flgChange = false;"> +<input type="submit" name="button_preview" value="%s" onClick="flgChange = false;"> %s <input type="submit" name="button_cancel" value="%s"> </p> <p>
Here is another patch added to ask saving changes in the preview mode, and uses i18n warning message. If you preview your changes, the page editor should ask saving changes even if he/she has no change after preview. It's simple:
- pageeditor.patch Of course that the appropriate i18n message should be added to make this work properly.
1 --- PageEditor-1.3.5.py 2005-07-28 00:51:40.000000000 +0900 2 +++ PageEditor.py 2005-11-03 10:09:45.780773100 +0900 3 @@ -275,6 +275,7 @@ 4 page=self, 5 pagename=self.page_name, msg=status, 6 body_onload=self.lock.locktype and 'countdown()' or '', # broken / bug in Mozilla 1.5, when using #preview 7 + body_onbeforeunload = 'return confirmleaving();', 8 html_head=self.lock.locktype and ( 9 _countdown_js % { 10 'lock_timeout': lock_timeout, 11 @@ -316,7 +332,7 @@ 12 self.request.write('</p>') 13 14 # send form 15 - self.request.write('<form id="editor" method="post" action="%s/%s#preview">' % ( 16 + self.request.write('<form id="editor" method="post" action="%s/%s#preview" onSubmit="flgChange = false;">' % ( 17 self.request.getScriptname(), 18 wikiutil.quoteWikinameURL(self.page_name), 19 )) 20 @@ -352,9 +368,34 @@ 21 # language into meta file. 22 lang = self.language or self.request.cfg.default_lang 23 24 + # XXXX Seungik Lee 25 + # to prevent moving out the page without saving it 26 + 27 + if preview: 28 + flgchange = 'true' 29 + else: 30 + flgchange = 'false' 31 + 32 + 33 + self.request.write( 34 + u'\r\n<script type="text/javascript">\r\n' 35 + u' var flgChange = %(ischanged)s;\r\n' 36 + u' function confirmleaving() { \r\n' 37 + u' if ( flgChange == true )\r\n' 38 + u' return "%(message)s";\r\n' 39 + u' \r\n' 40 + u' }\r\n' 41 + u'</script>\r\n' % { 42 + 'ischanged': flgchange, 43 + 'message': _('Your changes are not saved!'), 44 + } 45 + ) 46 + 47 + # XXXX 48 + 49 self.request.write( 50 u'<textarea id="editor-textarea" name="savetext" lang="%(lang)s" dir="%(dir)s"' 51 - u' rows="%(rows)d">' % { 52 + u' rows="%(rows)d" onChange="flgChange = true;" onKeyPress="flgChange = true;">' % { 53 'lang': lang, 54 'dir': i18n.getDirection(lang), 55 'rows': text_rows, 56 @@ -366,7 +407,7 @@ 57 self.request.write('</p>') 58 59 self.request.write("<p>", _("Optional comment about this change"), 60 - '<br><input id="editor-comment" type="text" name="comment" value="%s" maxlength="80"></p>' % ( 61 + '<br><input id="editor-comment" type="text" name="comment" value="%s" maxlength="80" onChange="flgChange = true;" onKeyPress="flgChange = true;"></p>' % ( 62 wikiutil.escape(kw.get('comment', ''), 1), )) 63 64 # Category selection 65 @@ -381,7 +422,7 @@ 66 67 # button bar 68 button_spellcheck = (SpellCheck and 69 - '<input type="submit" name="button_spellcheck" value="%s">' 70 + '<input type="submit" name="button_spellcheck" value="%s" onClick="flgChange = false;">' 71 % _('Check Spelling')) or '' 72 73 save_button_text = _('Save Changes') 74 @@ -400,8 +441,8 @@ 75 76 self.request.write(''' 77 <p> 78 -<input type="submit" name="button_save" value="%s"> 79 -<input type="submit" name="button_preview" value="%s"> %s 80 +<input type="submit" name="button_save" value="%s" onClick="flgChange = false;"> 81 +<input type="submit" name="button_preview" value="%s" onClick="flgChange = false;"> %s 82 <input type="submit" name="button_cancel" value="%s"> 83 </p> 84 <p>
-- SeungikLee 2005-11-03 00:56:26
Discussion
Could you please test if it works on Mozilla (or Firefox) and Opera, too? If yes, I think this would be a nice improvement for moin 1.5. -- ThomasWaldmann 2005-10-20 17:00:52
- I found some information for this from google:
OnBeforeUnload() is not part of W3C HTML 4.01 specs.
IE4+/Win, Mozilla 1.7a+, Netscape 7.2+, and Firefox support onbeforeunload. Opera doesn't seem to. I have not tested it in Konqueror, Safari, or IE5/Mac
-- SeungikLee 2005-10-21 07:41:07
I've updated the modification and tested it with IE 6, Firefox 1.5b2, Mozilla 1.7a on windows. And I modified the warning message to 'Your changes are not saved'. Because the browsers already inform that you are leaving the page and press OK to continue, CANCEL to stay. Our warning message is just for your information...
-- SeungikLee 2005-10-21 15:46:56
Does not work with Safari.
FYI, while window.onbeforeunload = function used in this wiki works with IE and Firefox, does not with Mozilla. In my experience, only <body onbeforeunload="return function();"> works with all of them.
-- SeungikLee 2005-10-22 04:47:08
Opera supports the "onunload" attribute for body element. As documented here.