Check for unsaved changes when switching selection

This commit is contained in:
Thomas Bruederli 2014-04-02 16:58:14 +02:00
parent 684964282a
commit 9f6de7de6d
2 changed files with 166 additions and 28 deletions

View file

@ -16,12 +16,18 @@ $labels['createlist'] = 'New Notebook';
$labels['editlist'] = 'Edit Notebook'; $labels['editlist'] = 'Edit Notebook';
$labels['listname'] = 'Name'; $labels['listname'] = 'Name';
$labels['tabsharing'] = 'Sharing'; $labels['tabsharing'] = 'Sharing';
$labels['discard'] = 'Discard';
$labels['abort'] = 'Abort';
$labels['unsavedchanges'] = 'Unsaved Changes!';
$labels['savingdata'] = 'Saving data...'; $labels['savingdata'] = 'Saving data...';
$labels['recordnotfound'] = 'Record not found'; $labels['recordnotfound'] = 'Record not found';
$labels['nochanges'] = 'No changes to be saved';
$labels['entertitle'] = 'Please enter a title for this note!'; $labels['entertitle'] = 'Please enter a title for this note!';
$labels['deletenotesconfirm'] = 'Do you really want to delete the selected notes?'; $labels['deletenotesconfirm'] = 'Do you really want to delete the selected notes?';
$labels['deletenotebookconfirm'] = 'Do you really want to delete this notebook with all its notes? This action cannot be undone.'; $labels['deletenotebookconfirm'] = 'Do you really want to delete this notebook with all its notes? This action cannot be undone.';
$labels['discardunsavedchanges'] = 'The current note has not yet been saved. Discard the changes?';
$labels['invalidlistproperties'] = 'Invalid notebook properties! Please set a valid name.'; $labels['invalidlistproperties'] = 'Invalid notebook properties! Please set a valid name.';
$labels['entertitle'] = 'Please enter a title for this note.';
$labels['aclnorights'] = 'You do not have administrator rights for this notebook.'; $labels['aclnorights'] = 'You do not have administrator rights for this notebook.';

View file

@ -36,8 +36,8 @@ function rcube_kolab_notes_ui(settings)
var me = this; var me = this;
/* public members */ /* public members */
this.selected_list = settings.selected_list; this.selected_list;
this.selected_note = settings.selected_id; this.selected_note;
this.notebooks = rcmail.env.kolab_notebooks || {}; this.notebooks = rcmail.env.kolab_notebooks || {};
/** /**
@ -46,7 +46,9 @@ function rcube_kolab_notes_ui(settings)
function init() function init()
{ {
// register button commands // register button commands
rcmail.register_command('createnote', function(){ edit_note(null, 'new'); }, false); rcmail.register_command('createnote', function(){
warn_unsaved_changes(function(){ edit_note(null, 'new'); })
}, false);
rcmail.register_command('list-create', function(){ list_edit_dialog(null); }, true); rcmail.register_command('list-create', function(){ list_edit_dialog(null); }, true);
rcmail.register_command('list-edit', function(){ list_edit_dialog(me.selected_list); }, false); rcmail.register_command('list-edit', function(){ list_edit_dialog(me.selected_list); }, false);
rcmail.register_command('list-remove', function(){ list_remove(me.selected_list); }, false); rcmail.register_command('list-remove', function(){ list_remove(me.selected_list); }, false);
@ -73,8 +75,8 @@ function rcube_kolab_notes_ui(settings)
// initialize folder selectors // initialize folder selectors
var li, id; var li, id;
for (id in me.notebooks) { for (id in me.notebooks) {
if (me.notebooks[id].editable && (!me.selected_list || (me.notebooks[id].active && !me.notebooks[me.selected_list].active))) { if (me.notebooks[id].editable && (!settings.selected_list || (me.notebooks[id].active && !me.notebooks[me.selected_list].active))) {
me.selected_list = id; settings.selected_list = id;
} }
} }
@ -88,9 +90,15 @@ function rcube_kolab_notes_ui(settings)
}); });
notebookslist.addEventListener('select', function(node) { notebookslist.addEventListener('select', function(node) {
var id = node.id; var id = node.id;
if (me.notebooks[id]) { if (me.notebooks[id] && id != me.selected_list) {
rcmail.enable_command('createnote', 'list-edit', 'list-remove', me.notebooks[id].editable); warn_unsaved_changes(function(){
fetch_notes(id); // sets me.notebooks[id] rcmail.enable_command('createnote', 'list-edit', 'list-remove', me.notebooks[id].editable);
fetch_notes(id); // sets me.selected_list
},
function(){
// restore previous selection
notebookslist.select(me.selected_list);
});
} }
}); });
@ -99,14 +107,20 @@ function rcube_kolab_notes_ui(settings)
noteslist = new rcube_list_widget(rcmail.gui_objects.noteslist, noteslist = new rcube_list_widget(rcmail.gui_objects.noteslist,
{ multiselect:true, draggable:true, keyboard:false }); { multiselect:true, draggable:true, keyboard:false });
noteslist.addEventListener('select', function(list) { noteslist.addEventListener('select', function(list) {
var note; var selection_changed = list.selection.length != 1 || !me.selected_note || list.selection[0] != me.selected_note.id;
if (list.selection.length == 1 && (note = notesdata[list.selection[0]])) { selection_changed && warn_unsaved_changes(function(){
// TODO: check for unsaved changes and warn var note;
edit_note(note.uid, 'edit'); if (noteslist.selection.length == 1 && (note = notesdata[noteslist.selection[0]])) {
} edit_note(note.uid, 'edit');
else { }
reset_view(); else {
} reset_view();
}
},
function(){
// TODO: previous restore selection
list.select(me.selected_note.id);
});
rcmail.enable_command('delete', me.notebooks[me.selected_list] && me.notebooks[me.selected_list].editable && list.selection.length > 0); rcmail.enable_command('delete', me.notebooks[me.selected_list] && me.notebooks[me.selected_list].editable && list.selection.length > 0);
}) })
@ -216,8 +230,8 @@ function rcube_kolab_notes_ui(settings)
tinyMCE.init(editor_conf); tinyMCE.init(editor_conf);
if (me.selected_list) { if (settings.selected_list) {
notebookslist.select(me.selected_list) notebookslist.select(settings.selected_list)
} }
} }
this.init = init; this.init = init;
@ -497,7 +511,14 @@ function rcube_kolab_notes_ui(settings)
} }
if (me.selected_note && me.selected_note.uid == note.uid && !match) { if (me.selected_note && me.selected_note.uid == note.uid && !match) {
noteslist.clear_selection(); warn_unsaved_changes(function(){
me.selected_note = null;
noteslist.clear_selection();
}, function(){
tagsfilter = [];
filter_notes();
update_tagcloud();
});
} }
} }
} }
@ -533,6 +554,10 @@ function rcube_kolab_notes_ui(settings)
if (data.data.length == 1) { if (data.data.length == 1) {
noteslist.select(data.data[0].id); noteslist.select(data.data[0].id);
} }
else if (settings.selected_id) {
noteslist.select(settings.selected_id);
delete settings.selected_id;
}
else if (me.selected_note && notesdata[me.selected_note.id]) { else if (me.selected_note && notesdata[me.selected_note.id]) {
noteslist.select(me.selected_note.id); noteslist.select(me.selected_note.id);
} }
@ -609,6 +634,9 @@ function rcube_kolab_notes_ui(settings)
node = editor.getContentAreaContainer().childNodes[0]; node = editor.getContentAreaContainer().childNodes[0];
if (node) node.tabIndex = content.get(0).tabIndex; if (node) node.tabIndex = content.get(0).tabIndex;
editor.getBody().focus(); editor.getBody().focus();
// read possibly re-formatted content back from editor for later comparison
me.selected_note.description = editor.getContent({ format:'html' })
} }
else { else {
$(rcmail.gui_objects.noteseditform).hide(); $(rcmail.gui_objects.noteseditform).hide();
@ -715,6 +743,9 @@ function rcube_kolab_notes_ui(settings)
if (tagsfilter && tagsfilter.length && $.inArray(tag, tagsfilter)) { if (tagsfilter && tagsfilter.length && $.inArray(tag, tagsfilter)) {
elem.addClass('selected'); elem.addClass('selected');
} }
else {
elem.removeClass('selected');
}
}); });
} }
@ -727,7 +758,11 @@ function rcube_kolab_notes_ui(settings)
var row, is_new = notesdata[data.id] == undefined var row, is_new = notesdata[data.id] == undefined
notesdata[data.id] = data; notesdata[data.id] = data;
render_note(data);
if (is_new || me.selected_note && data.id == me.selected_note.id) {
render_note(data);
render_tagslist(data.categories || []);
}
// add list item on top // add list item on top
if (is_new) { if (is_new) {
@ -747,8 +782,6 @@ function rcube_kolab_notes_ui(settings)
$('.date', row.obj).html(Q(data.changed || '')); $('.date', row.obj).html(Q(data.changed || ''));
// TODO: move to top // TODO: move to top
} }
render_tagslist(data.categories || []);
} }
/** /**
@ -773,6 +806,30 @@ function rcube_kolab_notes_ui(settings)
return false; return false;
} }
var savedata = get_save_data();
// do some input validation
if (savedata.title == '') {
alert(rcmail.gettext('entertitle', 'kolab_notes'));
$('.notetitle', rcmail.gui_objects.noteviewtitle).focus();
return false;
}
if (check_change_state(savedata)) {
rcmail.lock_form(rcmail.gui_objects.noteseditform, true);
saving_lock = rcmail.set_busy(true, 'kolab_notes.savingdata');
rcmail.http_post('action', { _data: savedata, _do: savedata.uid?'edit':'new' }, true);
}
else {
rcmail.display_message(rcmail.get_label('nochanges', 'kolab_notes'), 'info');
}
}
/**
* Collect updated note properties from edit form for saving
*/
function get_save_data()
{
var editor = tinyMCE.get('notecontent'); var editor = tinyMCE.get('notecontent');
var savedata = { var savedata = {
title: trim($('.notetitle', rcmail.gui_objects.noteviewtitle).val()), title: trim($('.notetitle', rcmail.gui_objects.noteviewtitle).val()),
@ -793,15 +850,90 @@ function rcube_kolab_notes_ui(settings)
savedata.categories.push(newtag); savedata.categories.push(newtag);
} }
// do some input validation return savedata;
if (savedata.title == '') { }
alert(rcmail.gettext('entertitle', 'kolab_notes'))
/**
* Check if the currently edited note record was changed
*/
function check_change_state(data)
{
if (!me.selected_note || me.selected_note.readonly || !me.notebooks[me.selected_note.list || me.selected_list].editable) {
return false; return false;
} }
rcmail.lock_form(rcmail.gui_objects.noteseditform, true); var savedata = data || get_save_data();
saving_lock = rcmail.set_busy(true, 'kolab_notes.savingdata');
rcmail.http_post('action', { _data: savedata, _do: savedata.uid?'edit':'new' }, true); return savedata.title != me.selected_note.title
|| savedata.description != me.selected_note.description
|| savedata.categories.join(',') != (me.selected_note.categories || []).join(',');
}
/**
* Check for unsaved changes and warn the user
*/
function warn_unsaved_changes(ok, nok)
{
if (typeof ok != 'function')
ok = function(){ };
if (typeof nok != 'function')
nok = function(){ };
if (check_change_state()) {
var dialog, buttons = [];
buttons.push({
text: rcmail.gettext('discard', 'kolab_notes'),
click: function() {
dialog.dialog('close');
ok();
}
});
buttons.push({
text: rcmail.gettext('save'),
click: function() {
save_note();
dialog.dialog('close');
ok();
}
});
buttons.push({
text: rcmail.gettext('abort', 'kolab_notes'),
click: function() {
dialog.dialog('close');
nok();
}
});
var options = {
width: 460,
resizable: false,
closeOnEscape: false,
dialogClass: 'warning',
open: function(event, ui) {
$(this).parent().find('.ui-dialog-titlebar-close').hide();
$(this).parent().find('.ui-button').first().addClass('mainaction').focus();
}
};
// open jquery UI dialog
dialog = rcmail.show_popup_dialog(
rcmail.gettext('discardunsavedchanges', 'kolab_notes'),
rcmail.gettext('unsavedchanges', 'kolab_notes'),
buttons,
options
);
return false;
}
if (typeof ok == 'function') {
ok();
}
return true;
} }
/** /**