/* This file is part of myTinyTodo. (C) Copyright 2009-2010 Max Pozdeev Licensed under the GNU GPL v2 license. See file COPYRIGHT for details. */ (function(){ var taskList = new Array(), taskOrder = new Array(); var filter = { compl:0, search:'', due:'' }; var sortOrder; //save task order before dragging var searchTimer; var objPrio = {}; var selTask = 0; var flag = { needAuth:false, isLogged:false, tagsChanged:true, readOnly:false, editFormChanged:false }; var taskCnt = { total:0, past: 0, today:0, soon:0 }; var tabLists = { _lists: {}, _length: 0, _order: [], _alltasks: {}, clear: function(){ this._lists = {}; this._length = 0; this._order = []; this._alltasks = { id:-1, showCompl:0, sort:3 }; }, length: function(){ return this._length; }, exists: function(id){ if(this._lists[id] || id==-1) return true; else return false; }, add: function(list){ this._lists[list.id] = list; this._length++; this._order.push(list.id); }, replace: function(list){ this._lists[list.id] = list; }, get: function(id){ if(id==-1) return this._alltasks; else return this._lists[id]; }, getAll: function(){ var r = []; for(var i in this._order) { r.push(this._lists[this._order[i]]); }; return r; }, reorder: function(order){ this._order = order; } }; var curList = 0; var tagsList = []; var mytinytodo = window.mytinytodo = _mtt = { theme: { newTaskFlashColor: '#ffffaa', editTaskFlashColor: '#bbffaa', msgFlashColor: '#ffffff' }, actions: {}, menus: {}, mttUrl: '', templateUrl: '', options: { openList: 0, singletab: false, autotag: false, tagPreview: true, tagPreviewDelay: 700, //milliseconds saveShowNotes: false, firstdayofweek: 1, touchDevice: false }, timers: { previewtag: 0 }, lang: { __lang: null, daysMin: [], daysLong: [], monthsShort: [], monthsLong: [], get: function(v) { if(this.__lang[v]) return this.__lang[v]; else return v; }, init: function(lang) { this.__lang = lang; this.daysMin = this.__lang.daysMin; this.daysLong = this.__lang.daysLong; this.monthsShort = this.__lang.monthsMin; this.monthsLong = this.__lang.monthsLong; } }, pages: { current: { page:'tasks', pageClass:'' }, prev: [] }, // procs init: function(options) { jQuery.extend(this.options, options); flag.needAuth = options.needAuth ? true : false; flag.isLogged = options.isLogged ? true : false; if(this.options.showdate) $('#page_tasks').addClass('show-inline-date'); if(this.options.singletab) $('#lists .mtt-tabs').addClass('mtt-tabs-only-one'); this.parseAnchor(); // handlers $('.mtt-tabs-add-button').click(function(){ addList(); }); $('.mtt-tabs-select-button').click(function(event){ if(event.metaKey || event.ctrlKey) { // toggle singetab interface _mtt.applySingletab(!_mtt.options.singletab); return false; } if(!_mtt.menus.selectlist) _mtt.menus.selectlist = new mttMenu('slmenucontainer', {onclick:slmenuSelect}); _mtt.menus.selectlist.show(this); }); $('#newtask_form').submit(function(){ submitNewTask(this); return false; }); $('#newtask_submit').click(function(){ $('#newtask_form').submit(); }); $('#newtask_adv').click(function(){ showEditForm(1); return false; }); $('#task').keydown(function(event){ if(event.keyCode == 27) { $(this).val(''); } }).focusin(function(){ $('#task_placeholder').removeClass('placeholding'); $('#toolbar').addClass('mtt-intask'); }).focusout(function(){ if('' == $(this).val()) $('#task_placeholder').addClass('placeholding'); $('#toolbar').removeClass('mtt-intask'); }); $('#search_form').submit(function(){ searchTasks(1); return false; }); $('#search_close').click(function(){ liveSearchToggle(0); return false; }); $('#search').keyup(function(event){ if(event.keyCode == 27) return; if($(this).val() == '') $('#search_close').hide(); //actual value is only on keyup else $('#search_close').show(); clearTimeout(searchTimer); searchTimer = setTimeout(function(){searchTasks()}, 400); }) .keydown(function(event){ if(event.keyCode == 27) { // cancel on Esc (NB: no esc event on keypress in Chrome and on keyup in Opera) if($(this).val() != '') { $(this).val(''); $('#search_close').hide(); searchTasks(); } else { liveSearchToggle(0); } return false; //need to return false in firefox (for AJAX?) } }).focusin(function(){ $('#toolbar').addClass('mtt-insearch'); $(this).focus(); }).focusout(function(){ $('#toolbar').removeClass('mtt-insearch'); }); $('#taskview').click(function(){ if(!_mtt.menus.taskview) _mtt.menus.taskview = new mttMenu('taskviewcontainer'); _mtt.menus.taskview.show(this); }); $('#mtt_filters .tag-filter .mtt-filter-close').live('click', function(){ cancelTagFilter($(this).attr('tagid')); }); $('#tagcloudbtn').click(function(){ if(!_mtt.menus.tagcloud) _mtt.menus.tagcloud = new mttMenu('tagcloud', { beforeShow: function(){ if(flag.tagsChanged) { $('#tagcloudcontent').html(''); $('#tagcloudload').show(); loadTags(curList.id, function(){$('#tagcloudload').hide();}); } }, adjustWidth:true }); _mtt.menus.tagcloud.show(this); }); $('#tagcloudcancel').click(function(){ if(_mtt.menus.tagcloud) _mtt.menus.tagcloud.close(); }); $('#tagcloudcontent .tag').live('click', function(){ addFilterTag($(this).attr('tag'), $(this).attr('tagid')); if(_mtt.menus.tagcloud) _mtt.menus.tagcloud.close(); return false; }); $('#mtt-notes-show').click(function(){ toggleAllNotes(1); this.blur(); return false; }); $('#mtt-notes-hide').click(function(){ toggleAllNotes(0); this.blur(); return false; }); $('#taskviewcontainer li').click(function(){ if(this.id == 'view_tasks') setTaskview(0); else if(this.id == 'view_past') setTaskview('past'); else if(this.id == 'view_today') setTaskview('today'); else if(this.id == 'view_soon') setTaskview('soon'); }); // Tabs $('#lists li.mtt-tab').live('click', function(event){ if(event.metaKey || event.ctrlKey) { // hide the tab hideTab(this); return false; } tabSelect(this); return false; }); $('#list_all').click(function(event){ if(event.metaKey || event.ctrlKey) { // hide the tab hideTab(-1); return false; } tabSelect(-1); return false; }); $('#lists li.mtt-tab .list-action').live('click', function(){ listMenu(this); return false; //stop bubble to tab click }); $('#list_all .list-action').click(function(event){ listMenu(this); return false; //stop bubble to tab click }); //Priority popup $('#priopopup .prio-neg-1').click(function(){ prioClick(-1,this); }); $('#priopopup .prio-zero').click(function(){ prioClick(0,this); }); $('#priopopup .prio-pos-1').click(function(){ prioClick(1,this); }); $('#priopopup .prio-pos-2').click(function(){ prioClick(2,this); }); $('#priopopup').mouseleave(function(){ $(this).hide()} ); // edit form handlers $('#alltags_show').click(function(){ toggleEditAllTags(1); return false; }); $('#alltags_hide').click(function(){ toggleEditAllTags(0); return false; }); $('#taskedit_form').submit(function(){ return saveTask(this); }); $('#alltags .tag').live('click', function(){ addEditTag($(this).attr('tag')); return false; }); $("#duedate").datepicker({ dateFormat: _mtt.duedatepickerformat(), firstDay: _mtt.options.firstdayofweek, showOn: 'button', buttonImage: _mtt.templateUrl + 'images/calendar.png', buttonImageOnly: true, constrainInput: false, duration:'', dayNamesMin:_mtt.lang.daysMin, dayNames:_mtt.lang.daysLong, monthNamesShort:_mtt.lang.monthsLong }); $("#edittags").autocomplete('ajax.php?suggestTags', {scroll: false, multiple: true, selectFirst:false, max:8, extraParams:{list:function(){ var taskId = document.getElementById('taskedit_form').id.value; return taskList[taskId].listId; }}}); $('#taskedit_form').find('select,input,textarea').bind('change keypress', function(){ flag.editFormChanged = true; }); // tasklist handlers $("#tasklist").bind("click", tasklistClick); $('#tasklist li').live('dblclick', function(){ //clear selection if(document.selection && document.selection.empty && document.selection.createRange().text) document.selection.empty(); else if(window.getSelection) window.getSelection().removeAllRanges(); var li = findParentNode(this, 'LI'); if(li && li.id) { var id = li.id.split('_',2)[1]; if(id) editTask(parseInt(id)); } }); $('#tasklist .taskactionbtn').live('click', function(){ var id = parseInt(getLiTaskId(this)); if(id) taskContextMenu(this, id); return false; }); $('#tasklist input[type=checkbox]').live('click', function(){ var id = parseInt(getLiTaskId(this)); if(id) completeTask(id, this); //return false; }); $('#tasklist .task-toggle').live('click', function(){ var id = getLiTaskId(this); if(id) $('#taskrow_'+id).toggleClass('task-expanded'); return false; }); $('#tasklist .tag').live('click', function(event){ clearTimeout(_mtt.timers.previewtag); $('#tasklist li').removeClass('not-in-tagpreview'); addFilterTag($(this).attr('tag'), $(this).attr('tagid'), (event.metaKey || event.ctrlKey ? true : false) ); return false; }); if(!this.options.touchDevice) { $('#tasklist .task-prio').live('mouseover mouseout', function(event){ var id = parseInt(getLiTaskId(this)); if(!id) return; if(event.type == 'mouseover') prioPopup(1, this, id); else prioPopup(0, this); }); } $('#tasklist .mtt-action-note-cancel').live('click', function(){ var id = parseInt(getLiTaskId(this)); if(id) cancelTaskNote(id); return false; }); $('#tasklist .mtt-action-note-save').live('click', function(){ var id = parseInt(getLiTaskId(this)); if(id) saveTaskNote(id); return false; }); if(this.options.tagPreview) { $('#tasklist .tag').live('mouseover mouseout', function(event){ var cl = 'tag-id-' + $(this).attr('tagid'); var sel = (event.metaKey || event.ctrlKey) ? 'li.'+cl : 'li:not(.'+cl+')'; if(event.type == 'mouseover') { _mtt.timers.previewtag = setTimeout( function(){$('#tasklist '+sel).addClass('not-in-tagpreview');}, _mtt.options.tagPreviewDelay); } else { clearTimeout(_mtt.timers.previewtag); $('#tasklist li').removeClass('not-in-tagpreview'); } }); } $("#tasklist").sortable({ items:'> :not(.task-completed)', cancel:'span,input,a,textarea', delay:150, start:sortStart, update:orderChanged, placeholder:'mtt-task-placeholder' }); $("#lists ul").sortable({delay:150, update:listOrderChanged}); this.applySingletab(); // AJAX Errors $('#msg').ajaxSend(function(r,s){ $("#msg").hide().removeClass('mtt-error mtt-info').find('.msg-details').hide(); $("#loading").show(); }); $('#msg').ajaxStop(function(r,s){ $("#loading").fadeOut(); }); $('#msg').ajaxError(function(event, request, settings){ var errtxt; if(request.status == 0) errtxt = 'Bad connection'; else if(request.status != 200) errtxt = 'HTTP: '+request.status+'/'+request.statusText; else errtxt = request.responseText; flashError(_mtt.lang.get('error'), errtxt); }); // Error Message details $("#msg>.msg-text").click(function(){ $("#msg>.msg-details").toggle(); }); // Authorization $('#bar_login').click(function(){ showAuth(this); return false; }); $('#bar_logout').click(function(){ logout(); return false; }); $('#login_form').submit(function(){ doAuth(this); return false; }); // Settings $("#settings").click(showSettings); $("#settings_form").live('submit', function() { saveSettings(this); return false; }); $(".mtt-back-button").live('click', function(){ _mtt.pageBack(); this.blur(); return false; } ); $(window).bind('beforeunload', function() { if(_mtt.pages.current.page == 'taskedit' && flag.editFormChanged) { return _mtt.lang.get('confirmLeave'); } }); // tab menu this.addAction('listSelected', tabmenuOnListSelected); // task context menu this.addAction('listsLoaded', cmenuOnListsLoaded); this.addAction('listRenamed', cmenuOnListRenamed); this.addAction('listAdded', cmenuOnListAdded); this.addAction('listSelected', cmenuOnListSelected); this.addAction('listOrderChanged', cmenuOnListOrderChanged); this.addAction('listHidden', cmenuOnListHidden); // select list menu this.addAction('listsLoaded', slmenuOnListsLoaded); this.addAction('listRenamed', slmenuOnListRenamed); this.addAction('listAdded', slmenuOnListAdded); this.addAction('listSelected', slmenuOnListSelected); this.addAction('listHidden', slmenuOnListHidden); return this; }, log: function(v) { console.log.apply(this, arguments); }, addAction: function(action, proc) { if(!this.actions[action]) this.actions[action] = new Array(); this.actions[action].push(proc); }, doAction: function(action, opts) { if(!this.actions[action]) return; for(var i in this.actions[action]) { this.actions[action][i](opts); } }, setOptions: function(opts) { jQuery.extend(this.options, opts); }, loadLists: function(onInit) { if(filter.search != '') { filter.search = ''; $('#searchbarkeyword').text(''); $('#searchbar').hide(); } $('#page_tasks').hide(); $('#tasklist').html(''); tabLists.clear(); this.db.loadLists(null, function(res) { var ti = ''; var openListId = 0; if(res && res.total) { // open required or first non-hidden list for(var i=0; i