+ can add lists and rename, view tasks and tagcloud according to the curently selected list

(but not to add tasks, search, etc)
This commit is contained in:
Max Pozdeev 2009-09-19 18:41:48 +04:00
parent f59a53fa4d
commit 41bb96e2a4
6 changed files with 230 additions and 45 deletions

View file

@ -23,6 +23,8 @@ var img = {
var taskCnt = { total:0, past: 0, today:0, soon:0 };
var tmp = {};
var oBtnMenu = {};
var tabLists;
var curList = 0;
function loadTasks()
{
@ -31,7 +33,7 @@ function loadTasks()
if(filter.search) search = '&s='+encodeURIComponent(filter.search); else search = '';
if(filter.tag) tag = '&t='+encodeURIComponent(filter.tag); else tag = '';
nocache = '&rnd='+Math.random();
$.getJSON('ajax.php?loadTasks&compl='+filter.compl+'&sort='+sortBy+search+tag+'&tz='+tz+nocache, function(json){
$.getJSON('ajax.php?loadTasks&list='+curList.id+'&compl='+filter.compl+'&sort='+sortBy+search+tag+'&tz='+tz+nocache, function(json){
resetAjaxErrorTrigger();
$('#total').html(json.total);
taskList = new Array();
@ -426,14 +428,14 @@ function updateAccessStatus(onInit)
{
if(flag.needAuth && !flag.isLogged) $("#tasklist").sortable('disable').addClass('readonly');
else if(sortBy == 0) $("#tasklist").sortable('enable').removeClass('readonly');
else $("#tasklist").removeClass('readonly');
if(!flag.canAllRead && !flag.isLogged) {
$('#page_tasks > h3,#taskcontainer').hide();
$('#tabs').hide();
$('#page_tasks').hide();
$('#lists').hide();
}
else {
$('#page_tasks > h3,#taskcontainer').show();
$('#tabs').show();
$('#page_tasks').show();
}
if(flag.needAuth) {
$('#bar_auth').show();
@ -449,9 +451,6 @@ function updateAccessStatus(onInit)
if(onInit == null || !onInit)
{
if(flag.isLogged) $("#tabs").tabs('enable',0).tabs('enable',1).tabs('select',0);
else if(flag.canAllRead) $("#tabs").tabs('enable',1).tabs('select', 1).tabs('disable',0);
else $("#tabs").tabs('disable',0).tabs('disable',1);
}
}
@ -471,7 +470,8 @@ function doAuth(form)
$('#searchbar').hide();
}
updateAccessStatus();
loadTasks();
// loadTasks();
loadLists();
}
else {
flashError(lang.invalidpass);
@ -523,11 +523,11 @@ function getRecursParent(el, needle, level)
return getRecursParent(el.parentNode, needle, level);
}
function cancelTagFilter()
function cancelTagFilter(dontLoadTasks)
{
$('#tagcloudbtn>.btnstr').text($('#tagcloudbtn').attr('title'));
filter.tag = '';
loadTasks();
if(dontLoadTasks==null || !dontLoadTasks) loadTasks();
}
function addFilterTag(tag)
@ -693,7 +693,7 @@ function showTagCloud(el)
setAjaxErrorTrigger();
nocache = '&rnd='+Math.random();
$.getJSON('ajax.php?tagCloud'+nocache, function(json){
$.getJSON('ajax.php?tagCloud&list='+curList.id+nocache, function(json){
resetAjaxErrorTrigger();
$('#tagcloudload').hide();
if(!parseInt(json.total)) return;
@ -781,7 +781,7 @@ function taskviewClose(e)
$('#taskview').hide();
}
function setTaskview(v)
function setTaskview(v, dontLoadTasks)
{
if(v == 0)
{
@ -795,7 +795,7 @@ function setTaskview(v)
if(filter.compl != 0) {
filter.compl = 0;
$('#total').text('...');
loadTasks();
if(dontLoadTasks==null || !dontLoadTasks) loadTasks();
}
}
else if(v == 1)
@ -843,9 +843,18 @@ function editFormResize(startstop, event)
function mttTabSelected(el, indx)
{
$(el.parentNode.parentNode).children('.mtt-tabs-selected').removeClass('mtt-tabs-selected');
$(el.parentNode).addClass('mtt-tabs-selected');
if(!tabLists[indx]) return;
if(indx != curList.i) {
$('#tasklist').html('');
}
curList = tabLists[indx];
flag.tagsChanged = true;
cancelTagFilter(1);
setTaskview(0, 1);
loadTasks();
}
function btnMenu(el)
@ -915,3 +924,63 @@ function toggleAllNotes(showhide)
}
}
function loadLists(onInit)
{
if(flag.needAuth && !flag.isLogged) return false;
setAjaxErrorTrigger();
nocache = '&rnd='+Math.random();
$.getJSON('ajax.php?loadLists'+nocache, function(json){
resetAjaxErrorTrigger();
if(!parseInt(json.total)) {
$('#page_tasks').hide();
return;
}
tabLists = new Array();
var ti = '';
$.each(json.list, function(i,item){
item.i = i;
tabLists[i] = item;
ti += '<li class="'+(i==0?'mtt-tabs-selected':'')+'"><a href="#list'+item.id+'" onClick="mttTabSelected(this,'+i+');return false;">'+item.name+'</a></li>';
});
$('#lists>ul').html(ti);
$('#lists').show();
curList = tabLists[0];
loadTasks();
});
}
function addList()
{
var r = prompt(lang.addList, lang.addListDefault);
if(r == null) return;
setAjaxErrorTrigger()
nocache = '&rnd='+Math.random();
$.post('ajax.php?'+nocache, { addList:1, name:r }, function(json){
resetAjaxErrorTrigger();
if(!parseInt(json.total)) return;
var item = json.list[0];
var i = tabLists.length;
item.i = i;
tabLists[i] = item;
$('#lists>ul').append('<li><a href="#list'+item.id+'" onClick="mttTabSelected(this,'+i+');return false;">'+item.name+'</a></li>');
}, 'json');
}
function renameCurList()
{
if(!curList) return;
var r = prompt(lang.renameList, dehtml(curList.name));
if(r == null) return;
setAjaxErrorTrigger()
nocache = '&rnd='+Math.random();
$.post('ajax.php?'+nocache, { renameList:1, id:curList.id, name:r }, function(json){
resetAjaxErrorTrigger();
if(!parseInt(json.total)) return;
var item = json.list[0];
item.i = curList.i;
tabLists[curList.i] = item;
curList = item;
$('#lists>ul>.mtt-tabs-selected>a').html(item.name);
}, 'json');
}

View file

@ -8,12 +8,27 @@ require_once('./lang/class.default.php');
require_once('./lang/'.$config['lang'].'.php');
$lang = new Lang();
if(isset($_GET['loadTasks']))
if(isset($_GET['loadLists']))
{
check_read_access();
$t = array();
$t['total'] = 0;
$q = $db->dq("SELECT * FROM lists ORDER BY id ASC");
while($r = $q->fetch_assoc($q))
{
$t['total']++;
$t['list'][] = array('id'=>$r['id'], 'name'=>htmlarray($r['name']));
}
echo json_encode($t);
exit;
}
elseif(isset($_GET['loadTasks']))
{
check_read_access();
stop_gpc($_GET);
if(_get('compl')) $sqlWhere = '';
else $sqlWhere = ' AND compl=0';
$listId = (int)_get('list');
$sqlWhere = ' AND list_id='. $listId;
if(_get('compl') == 0) $sqlWhere .= ' AND compl=0';
$inner = '';
$tag = trim(_get('t'));
if($tag != '') {
@ -272,8 +287,9 @@ elseif(isset($_GET['setPrio']))
}
elseif(isset($_GET['tagCloud']))
{
$listId = (int)_get('list');
$a = array();
$q = $db->dq("SELECT name,tags_count FROM tags WHERE tags_count>0 ORDER BY tags_count ASC");
$q = $db->dq("SELECT name,tags_count FROM tags WHERE list_id=$listId AND tags_count>0 ORDER BY tags_count ASC");
while($r = $q->fetch_row()) {
$a[$r[0]] = $r[1];
}
@ -296,8 +312,40 @@ elseif(isset($_GET['tagCloud']))
echo json_encode($t);
exit;
}
elseif(isset($_POST['addList']))
{
check_write_access();
stop_gpc($_POST);
$t = array();
$t['total'] = 0;
$name = str_replace(array('"',"'",'<','>','&'),array('','','','',''),trim(_post('name')));
$db->dq("INSERT INTO lists (name) VALUES (?)", array($name));
$id = $db->last_insert_id();
$t['total'] = 1;
$r = $db->sqa("SELECT * FROM lists WHERE id=$id");
$t['list'][] = array('id'=>$r['id'], 'name'=>htmlarray($r['name']));
echo json_encode($t);
exit;
}
elseif(isset($_POST['renameList']))
{
check_write_access();
stop_gpc($_POST);
$t = array();
$t['total'] = 0;
$id = (int)_post('id');
$name = str_replace(array('"',"'",'<','>','&'),array('','','','',''),trim(_post('name')));
$db->dq("UPDATE lists SET name=? WHERE id=$id", array($name));
$t['total'] = $db->affected();
$r = $db->sqa("SELECT * FROM lists WHERE id=$id");
$t['list'][] = array('id'=>$r['id'], 'name'=>htmlarray($r['name']));
echo json_encode($t);
exit;
}
###################################################################################################
function prepareTaskRow($r, $tz=null)
{
$dueA = prepare_duedate($r['duedate'], $tz);

View file

@ -56,7 +56,6 @@ function __($s)
<script type="text/javascript">
$().ready(function(){
// $("#tabs").tabs({ select: tabSelected <?php echo $tabDisabled; ?>});
$("#tasklist").sortable({cancel:'span,input,a,textarea', delay: 150, update:orderChanged, start:sortStart, items:'> :not(.task-completed)'});
$("#tasklist").bind("click", tasklistClick);
$("#edittags").autocomplete('ajax.php?suggestTags', {scroll: false, multiple: true, selectFirst:false, max:8});
@ -68,11 +67,9 @@ $().ready(function(){
echo "\tflag.needAuth = true;\n";
if(!canAllRead()) echo "\tflag.canAllRead = false;\n";
if(is_logged()) echo "\tflag.isLogged = true;\n";
if(is_logged() || canAllRead()) echo "\tloadTasks();\n";
echo "\tupdateAccessStatus(1);\n";
} else {
echo "\tloadTasks();\n";
}
echo "\tloadLists(1)\n";
?>
preloadImg();
$("#duedate").datepicker({dateFormat: '<?php echo $duedateformat; ?>', firstDay: <?php echo $config['firstdayofweek']; ?>,
@ -114,10 +111,7 @@ $().ajaxStop( function(r,s) {$("#loading").fadeOut();} );
<div id="page_tasks">
<div id="lists" class="mtt-tabs">
<ul class="">
<li class="mtt-tabs-selected"><a href="#list1" onClick="mttTabSelected(this,0)">ToDo</a></li>
<li><a href="#list2" onClick="mttTabSelected(this,1)">Todo #2</a></li>
</ul>
<ul class=""></ul>
<div class="mtt-htabs">
<span id="htab_newtask">
@ -203,8 +197,8 @@ $().ajaxStop( function(r,s) {$("#loading").fadeOut();} );
</div>
<div id="mylistscontainer" class="mtt-btnmenu-container" style="display:none">
<div class="li" onClick="prompt('New list', 'To-Do')">New list</div>
<div class="li" onClick="prompt('Rename list', 'list name')">Rename</div>
<div class="li" onClick="addList()">New list</div>
<div class="li" onClick="renameCurList()">Rename</div>
<div class="li" onClick="confirm('This will delete current list with all tasks in it.\nAre you sure?')">Delete</div>
</div>

View file

@ -20,6 +20,9 @@ class DefaultLang
'invalidpass' => "Wrong password",
'readonly' => "read-only",
'tagfilter' => "Tag:",
'addList' => "Create new list",
'addListDefault' => "Todo",
'renameList' => "Rename list",
);
private $default_inc = array

View file

@ -16,6 +16,8 @@ class Lang extends DefaultLang
'invalidpass' => "Wrong password",
'readonly' => "read-only",
'tagfilter' => "Tag:",
'addList' => "Create new list",
'renameList' => "Rename list",
);
var $inc = array

View file

@ -14,15 +14,10 @@ if($needAuth && !is_logged())
$dbclass = strtolower(get_class($db));
$dbtype = ($dbclass == 'database_mysql') ? 'mysql' : 'sqlite';
$lastVer = '1.2';
$lastVer = '1.3';
echo '<html><head><meta name="robots" content="noindex,nofollow"></head><body>';
echo "<b>myTinyTodo v$lastVer Setup</b><br><br>";
# exclude sqlite2
if($dbclass == 'database_sqlite') {
exitMessage("Install/update is not available for sqlite2. Use sqlite v3.");
}
# determine current installed version
$ver = get_ver($db, $dbtype);
@ -41,6 +36,7 @@ if(!$ver)
"CREATE TABLE todolist (
`id` INT UNSIGNED NOT NULL auto_increment,
`d` DATETIME NOT NULL,
`list_id` INT UNSIGNED NOT NULL default 0,
`compl` TINYINT UNSIGNED NOT NULL default 0,
`title` VARCHAR(250) NOT NULL,
`note` TEXT,
@ -48,7 +44,8 @@ if(!$ver)
`ow` INT NOT NULL default 0, /* order weight */
`tags` VARCHAR(250) NOT NULL default '', /* denormalization - for fast access to task tags */
`duedate` DATE default NULL,
PRIMARY KEY(`id`)
PRIMARY KEY(`id`),
KEY(`list_id`)
) CHARSET=utf8 ");
$db->ex(
@ -56,8 +53,10 @@ if(!$ver)
`id` INT UNSIGNED NOT NULL auto_increment,
`name` VARCHAR(50) NOT NULL,
`tags_count` INT default 0,
`list_id` INT UNSIGNED NOT NULL default 0,
PRIMARY KEY(`id`),
UNIQUE KEY(`name`)
UNIQUE KEY(`name`),
KEY(`list_id`)
) CHARSET=utf8 ");
$db->ex(
@ -68,6 +67,13 @@ if(!$ver)
KEY(`task_id`)
) CHARSET=utf8 ");
$db->ex(
"CREATE TABLE lists (
`id` INT UNSIGNED NOT NULL auto_increment,
`name` VARCHAR(50) NOT NULL default '',
PRIMARY KEY(`id`)
) CHARSET=utf8 ");
} catch (Exception $e) {
exitMessage("<b>Error:</b> ". htmlarray($e->getMessage()));
}
@ -80,6 +86,7 @@ if(!$ver)
"CREATE TABLE todolist (
id INTEGER PRIMARY KEY,
d DATETIME NOT NULL default '0000-00-00',
list_id INTEGER UNSIGNED NOT NULL default 0,
compl TINYINT UNSIGNED NOT NULL default 0,
title VARCHAR(250) NOT NULL,
note TEXT,
@ -88,27 +95,37 @@ if(!$ver)
tags VARCHAR(250) NOT NULL default '',
duedate DATE default NULL
) ");
$db->ex("CREATE INDEX list_id ON todolist (list_id)");
$db->ex(
"CREATE TABLE tags (
id INTEGER PRIMARY KEY,
name VARCHAR(50) NOT NULL COLLATE NOCASE UNIQUE,
tags_count INT default 0
tags_count INT default 0,
list_id INTEGER UNSIGNED NOT NULL default 0
) ");
$db->ex("CREATE INDEX tags_list_id ON tags (list_id)");
$db->ex(
"CREATE TABLE tag2task (
tag_id INTEGER NOT NULL,
task_id INTEGER NOT NULL
) ");
$db->ex("CREATE INDEX tag_id ON tag2task (tag_id)");
$db->ex("CREATE INDEX task_id ON tag2task (task_id)");
$db->ex(
"CREATE TABLE lists (
id INTEGER PRIMARY KEY,
name VARCHAR(50) NOT NULL
) ");
} catch (Exception $e) {
exitMessage("<b>Error:</b> ". htmlarray($e->getMessage()));
}
}
createDefaultList($db);
}
elseif($ver == $lastVer)
{
@ -116,17 +133,22 @@ elseif($ver == $lastVer)
}
else
{
if(!in_array($ver, array('1.1'))) {
exitMessage("Can not update database. Unsupported version ($ver).");
if(!in_array($ver, array('1.1','1.2'))) {
exitMessage("Can not update database. Unsupported version (v$ver).");
}
if(!isset($_POST['update'])) {
exitMessage("Update database from v$ver to v1.2 <form method=post><input type=hidden name=update value=1><input type=submit value=' Update '></form>");
exitMessage("Update database v$ver <form method=post><input type=hidden name=update value=1><input type=submit value=' Update '></form>");
}
# update process
if($ver == '1.1')
if($ver == '1.2')
{
update_12_13($db, $dbtype);
}
elseif($ver == '1.1')
{
update_11_12($db, $dbtype);
update_12_13($db, $dbtype);
}
}
echo "Done<br><br> <b>Attention!</b> Delete this file for security reasons.";
@ -145,6 +167,8 @@ function get_ver($db, $dbtype)
if(!has_field_sqlite($db, 'todolist', 'duedate')) return $v;
}
$v = '1.2';
if(!$db->table_exists('lists')) return $v;
$v = '1.3';
return $v;
}
@ -182,11 +206,10 @@ function has_field_mysql($db, $table, $field)
### 1.1-1.2 ##########
function update_11_12($db, $dbtype)
{
echo "Changing database structure...<br>";
if($dbtype == 'mysql') $db->ex("ALTER TABLE todolist ADD `duedate` DATE default NULL");
else $db->ex("ALTER TABLE todolist ADD duedate DATE default NULL");
echo "Fixing broken tags...<br>";
# Fixing broken tags
$db->ex("BEGIN");
$db->ex("DELETE FROM tags");
$db->ex("DELETE FROM tag2task");
@ -242,4 +265,50 @@ function update_task_tags($id, $tag_ids)
### end 1.1-1.2 #####
### 1.2-1.3 ##########
function update_12_13($db, $dbtype)
{
$db->ex("BEGIN");
if($dbtype=='mysql')
{
$db->ex(
"CREATE TABLE lists (
`id` INT UNSIGNED NOT NULL auto_increment,
`name` VARCHAR(50) NOT NULL default '',
PRIMARY KEY(`id`)
) CHARSET=utf8 ");
$db->ex("ALTER TABLE todolist ADD `list_id` INT UNSIGNED NOT NULL default 0");
$db->ex("ALTER TABLE tags ADD `list_id` INT UNSIGNED NOT NULL default 0");
$db->ex("ALTER TABLE todolist ADD KEY(`list_id`)");
$db->ex("ALTER TABLE tags ADD KEY(`list_id`)");
}
else
{
$db->ex(
"CREATE TABLE lists (
id INTEGER PRIMARY KEY,
name VARCHAR(50) NOT NULL
) ");
$db->ex("ALTER TABLE todolist ADD list_id INTEGER UNSIGNED NOT NULL default 0");
$db->ex("ALTER TABLE tags ADD list_id INT UNSIGNED NOT NULL default 0");
$db->ex("CREATE INDEX list_id ON todolist (list_id)");
$db->ex("CREATE INDEX tags_list_id ON tags (list_id)");
}
$db->ex("COMMIT");
createDefaultList($db);
}
function createDefaultList($db)
{
$db->ex("INSERT INTO lists (name) VALUES (?)", array('TODO'));
$db->ex("UPDATE todolist SET list_id=1");
$db->ex("UPDATE tags SET list_id=1");
}
### end 1.2-1.3 #####
?>