From: Andreas Gohr Date: Thu, 19 Jan 2006 14:22:17 +0000 (+0100) Subject: interactive note adding X-Git-Tag: 0.7.1~102 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=d99857a7f7a4fb3408c815675f0cc20cc6d024f2;p=contagged interactive note adding darcs-hash:20060119142217-6e07b-7bfe670c42d386f46b81b95b1d761111f89cfcca.gz --- diff --git a/js/date-formatting.js b/js/date-formatting.js new file mode 100644 index 0000000..b2848a1 --- /dev/null +++ b/js/date-formatting.js @@ -0,0 +1,253 @@ +/* + * A Javascript date chooser. + * Copyright (C) 2004 Baron Schwartz + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +Date.formatFunctions = {count:0}; + +Date.prototype.dateFormat = function(format) { + if (Date.formatFunctions[format] == null) { + Date.createNewFormat(format); + } + var func = Date.formatFunctions[format]; + return eval("this." + func + "();"); +} + +Date.createNewFormat = function(format) { + var funcName = "format" + Date.formatFunctions.count++; + Date.formatFunctions[format] = funcName; + var code = "Date.prototype." + funcName + " = function(){return "; + var special = false; + var char = ''; + for (var i = 0; i < format.length; ++i) { + char = format.charAt(i); + if (!special && char == "\\") { + special = true; + } + else if (special) { + special = false; + code += "'" + String.escape(char) + "' + "; + } + else { + code += Date.getFormatCode(char); + } + } + eval(code.substring(0, code.length - 3) + ";}"); +} + +Date.getFormatCode = function(character) { + switch (character) { + case "d": + return "String.leftPad(this.getDate(), 2, '0') + "; + case "D": + return "Date.dayNames[this.getDay()].substring(0, 3) + "; + case "j": + return "this.getDate() + "; + case "l": + return "Date.dayNames[this.getDay()] + "; + case "S": + return "this.getSuffix() + "; + case "w": + return "this.getDay() + "; + case "z": + return "this.getDayOfYear() + "; + case "W": + return "this.getWeekOfYear() + "; + case "F": + return "Date.monthNames[this.getMonth()] + "; + case "m": + return "String.leftPad(this.getMonth() + 1, 2, '0') + "; + case "M": + return "Date.monthNames[this.getMonth()].substring(0, 3) + "; + case "n": + return "(this.getMonth() + 1) + "; + case "t": + return "this.getDaysInMonth() + "; + case "L": + return "(this.isLeapYear() ? 1 : 0) + "; + case "Y": + return "this.getFullYear() + "; + case "y": + return "('' + this.getFullYear()).substring(2, 4) + "; + case "a": + return "(this.getHours() < 12 ? 'am' : 'pm') + "; + case "A": + return "(this.getHours() < 12 ? 'AM' : 'PM') + "; + case "g": + return "((this.getHours() %12) ? this.getHours() % 12 : 12) + "; + case "G": + return "this.getHours() + "; + case "h": + return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + "; + case "H": + return "String.leftPad(this.getHours(), 2, '0') + "; + case "i": + return "String.leftPad(this.getMinutes(), 2, '0') + "; + case "s": + return "String.leftPad(this.getSeconds(), 2, '0') + "; + case "O": + return "this.getGMTOffset() + "; + case "T": + return "this.getTimezone() + "; + case "Z": + return "(this.getTimezoneOffset() * -60) + "; + default: + return "'" + String.escape(character) + "' + "; + } +} + +Date.prototype.getTimezone = function() { + return this.toString().replace( + /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace( + /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3"); +} + +Date.prototype.getGMTOffset = function() { + return (this.getTimezoneOffset() > 0 ? "-" : "+") + + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0") + + String.leftPad(this.getTimezoneOffset() % 60, 2, "0"); +} + +Date.prototype.getDayOfYear = function() { + var num = 0; + Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28; + for (var i = 0; i < this.getMonth(); ++i) { + num += Date.daysInMonth[i]; + } + return num + this.getDate() - 1; +} + +Date.prototype.getWeekOfYear = function() { + // Skip to Thursday of this week + var now = this.getDayOfYear() + (4 - this.getDay()); + // Find the first Thursday of the year + var jan1 = new Date(this.getFullYear(), 0, 1); + var then = (7 - jan1.getDay() + 4); + document.write(then); + return String.leftPad(((now - then) / 7) + 1, 2, "0"); +} + +Date.prototype.isLeapYear = function() { + var year = this.getFullYear(); + return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year))); +} + +Date.prototype.getFirstDayOfMonth = function() { + var day = (this.getDay() - (this.getDate() - 1)) % 7; + return (day < 0) ? (day + 7) : day; +} + +Date.prototype.getLastDayOfMonth = function() { + var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7; + return (day < 0) ? (day + 7) : day; +} + +Date.prototype.getDaysInMonth = function() { + Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28; + return Date.daysInMonth[this.getMonth()]; +} + +Date.prototype.getSuffix = function() { + switch (this.getDate()) { + case 1: + case 21: + case 31: + return "st"; + case 2: + case 22: + return "nd"; + case 3: + case 23: + return "rd"; + default: + return "th"; + } +} + +String.escape = function(string) { + return string.replace(/('|\\)/g, "\\$1"); +} + +String.leftPad = function (val, size, char) { + var result = new String(val); + if (char == null) { + char = " "; + } + while (result.length < size) { + result = char + result; + } + return result; +} + +Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31]; +Date.monthNames = + ["January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December"]; +Date.dayNames = + ["Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday"]; +Date.patterns = { + ISO8601LongPattern:"Y-m-d H:i:s", + ISO8601ShortPattern:"Y-m-d", + ShortDatePattern: "n/j/Y", + LongDatePattern: "l, F d, Y", + FullDateTimePattern: "l, F d, Y g:i:s A", + MonthDayPattern: "F d", + ShortTimePattern: "g:i A", + LongTimePattern: "g:i:s A", + SortableDateTimePattern: "Y-m-d\\TH:i:s", + UniversalSortableDateTimePattern: "Y-m-d H:i:sO", + YearMonthPattern: "F, Y"}; + +Date.parseIsoDate = function(dateString) { + var result = new Date(); + var re = /^(\d\d\d\d)-(\d\d)-(\d\d)( (\d\d):(\d\d):(\d\d))?$/; + var match = dateString.match(re); + if (match != null) { + if (match[5] != null && match[5] != '') { + result = new Date( + parseInt(match[1], 10), + parseInt(match[2], 10) - 1, + parseInt(match[3], 10), + parseInt(match[5], 10), + parseInt(match[6], 10), + parseInt(match[7], 10)); + } + else { + result = new Date( + parseInt(match[1], 10), + parseInt(match[2], 10) - 1, + parseInt(match[3], 10)); + } + } + return result; +} diff --git a/js/formatDate.js b/js/formatDate.js new file mode 100644 index 0000000..11c6197 --- /dev/null +++ b/js/formatDate.js @@ -0,0 +1,290 @@ +Array.prototype.exists = function (x) { + for (var i = 0; i < this.length; i++) { + if (this[i] == x) return true; + } + return false; +} + +Date.prototype.formatDate = function (input,time) { + // formatDate : + // a PHP date like function, for formatting date strings + // See: http://www.php.net/date + // + // input : format string + // time : epoch time (seconds, and optional) + // + // if time is not passed, formatting is based on + // the current "this" date object's set time. + // + // supported: + // a, A, B, d, D, F, g, G, h, H, i, j, l (lowercase L), L, + // m, M, n, O, r, s, S, t, U, w, W, y, Y, z + // + // unsupported: + // I (capital i), T, Z + + var switches = ["a", "A", "B", "d", "D", "F", "g", "G", "h", "H", + "i", "j", "l", "L", "m", "M", "n", "O", "r", "s", + "S", "t", "U", "w", "W", "y", "Y", "z"]; + var daysLong = ["Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday"]; + var daysShort = ["Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat"]; + var monthsShort = ["Jan", "Feb", "Mar", "Apr", + "May", "Jun", "Jul", "Aug", "Sep", + "Oct", "Nov", "Dec"]; + var monthsLong = ["January", "February", "March", "April", + "May", "June", "July", "August", "September", + "October", "November", "December"]; + var daysSuffix = ["st", "nd", "rd", "th", "th", "th", "th", // 1st - 7th + "th", "th", "th", "th", "th", "th", "th", // 8th - 14th + "th", "th", "th", "th", "th", "th", "st", // 15th - 21st + "nd", "rd", "th", "th", "th", "th", "th", // 22nd - 28th + "th", "th", "st"]; // 29th - 31st + + function a() { + // Lowercase Ante meridiem and Post meridiem + return self.getHours() > 11? "pm" : "am"; + } + function A() { + // Uppercase Ante meridiem and Post meridiem + return self.getHours() > 11? "PM" : "AM"; + } + + function B(){ + // Swatch internet time. code simply grabbed from ppk, + // since I was feeling lazy: + // http://www.xs4all.nl/~ppk/js/beat.html + var off = (self.getTimezoneOffset() + 60)*60; + var theSeconds = (self.getHours() * 3600) + + (self.getMinutes() * 60) + + self.getSeconds() + off; + var beat = Math.floor(theSeconds/86.4); + if (beat > 1000) beat -= 1000; + if (beat < 0) beat += 1000; + if ((""+beat).length == 1) beat = "00"+beat; + if ((""+beat).length == 2) beat = "0"+beat; + return beat; + } + + function d() { + // Day of the month, 2 digits with leading zeros + return new String(self.getDate()).length == 1? + "0"+self.getDate() : self.getDate(); + } + function D() { + // A textual representation of a day, three letters + return daysShort[self.getDay()]; + } + function F() { + // A full textual representation of a month + return monthsLong[self.getMonth()]; + } + function g() { + // 12-hour format of an hour without leading zeros + return self.getHours() > 12? self.getHours()-12 : self.getHours(); + } + function G() { + // 24-hour format of an hour without leading zeros + return self.getHours(); + } + function h() { + // 12-hour format of an hour with leading zeros + if (self.getHours() > 12) { + var s = new String(self.getHours()-12); + return s.length == 1? + "0"+ (self.getHours()-12) : self.getHours()-12; + } else { + var s = new String(self.getHours()); + return s.length == 1? + "0"+self.getHours() : self.getHours(); + } + } + function H() { + // 24-hour format of an hour with leading zeros + return new String(self.getHours()).length == 1? + "0"+self.getHours() : self.getHours(); + } + function i() { + // Minutes with leading zeros + return new String(self.getMinutes()).length == 1? + "0"+self.getMinutes() : self.getMinutes(); + } + function j() { + // Day of the month without leading zeros + return self.getDate(); + } + function l() { + // A full textual representation of the day of the week + return daysLong[self.getDay()]; + } + function L() { + // leap year or not. 1 if leap year, 0 if not. + // the logic should match iso's 8601 standard. + var y_ = Y(); + if ( + (y_ % 4 == 0 && y_ % 100 != 0) || + (y_ % 4 == 0 && y_ % 100 == 0 && y_ % 400 == 0) + ) { + return 1; + } else { + return 0; + } + } + function m() { + // Numeric representation of a month, with leading zeros + return self.getMonth() < 9? + "0"+(self.getMonth()+1) : + self.getMonth()+1; + } + function M() { + // A short textual representation of a month, three letters + return monthsShort[self.getMonth()]; + } + function n() { + // Numeric representation of a month, without leading zeros + return self.getMonth()+1; + } + function O() { + // Difference to Greenwich time (GMT) in hours + var os = Math.abs(self.getTimezoneOffset()); + var h = ""+Math.floor(os/60); + var m = ""+(os%60); + h.length == 1? h = "0"+h:1; + m.length == 1? m = "0"+m:1; + return self.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m; + } + function r() { + // RFC 822 formatted date + var r; // result + // Thu , 21 Dec 2000 + r = D() + ", " + j() + " " + M() + " " + Y() + + // 16 : 01 : 07 +0200 + " " + H() + ":" + i() + ":" + s() + " " + O(); + return r; + } + function S() { + // English ordinal suffix for the day of the month, 2 characters + return daysSuffix[self.getDate()-1]; + } + function s() { + // Seconds, with leading zeros + return new String(self.getSeconds()).length == 1? + "0"+self.getSeconds() : self.getSeconds(); + } + function t() { + + // thanks to Matt Bannon for some much needed code-fixes here! + var daysinmonths = [null,31,28,31,30,31,30,31,31,30,31,30,31]; + if (L()==1 && n()==2) return 29; // leap day + return daysinmonths[n()]; + } + function U() { + // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) + return Math.round(self.getTime()/1000); + } + function W() { + // Weeknumber, as per ISO specification: + // http://www.cl.cam.ac.uk/~mgk25/iso-time.html + + // if the day is three days before newyears eve, + // there's a chance it's "week 1" of next year. + // here we check for that. + var beforeNY = 364+L() - z(); + var afterNY = z(); + var weekday = w()!=0?w()-1:6; // makes sunday (0), into 6. + if (beforeNY <= 2 && weekday <= 2-beforeNY) { + return 1; + } + // similarly, if the day is within threedays of newyears + // there's a chance it belongs in the old year. + var ny = new Date("January 1 " + Y() + " 00:00:00"); + var nyDay = ny.getDay()!=0?ny.getDay()-1:6; + if ( + (afterNY <= 2) && + (nyDay >=4) && + (afterNY >= (6-nyDay)) + ) { + // Since I'm not sure we can just always return 53, + // i call the function here again, using the last day + // of the previous year, as the date, and then just + // return that week. + var prevNY = new Date("December 31 " + (Y()-1) + " 00:00:00"); + return prevNY.formatDate("W"); + } + + // week 1, is the week that has the first thursday in it. + // note that this value is not zero index. + if (nyDay <= 3) { + // first day of the year fell on a thursday, or earlier. + return 1 + Math.floor( ( z() + nyDay ) / 7 ); + } else { + // first day of the year fell on a friday, or later. + return 1 + Math.floor( ( z() - ( 7 - nyDay ) ) / 7 ); + } + } + function w() { + // Numeric representation of the day of the week + return self.getDay(); + } + + function Y() { + // A full numeric representation of a year, 4 digits + + // we first check, if getFullYear is supported. if it + // is, we just use that. ppks code is nice, but wont + // work with dates outside 1900-2038, or something like that + if (self.getFullYear) { + var newDate = new Date("January 1 2001 00:00:00 +0000"); + var x = newDate .getFullYear(); + if (x == 2001) { + // i trust the method now + return self.getFullYear(); + } + } + // else, do this: + // codes thanks to ppk: + // http://www.xs4all.nl/~ppk/js/introdate.html + var x = self.getYear(); + var y = x % 100; + y += (y < 38) ? 2000 : 1900; + return y; + } + function y() { + // A two-digit representation of a year + var y = Y()+""; + return y.substring(y.length-2,y.length); + } + function z() { + // The day of the year, zero indexed! 0 through 366 + var t = new Date("January 1 " + Y() + " 00:00:00"); + var diff = self.getTime() - t.getTime(); + return Math.floor(diff/1000/60/60/24); + } + + var self = this; + if (time) { + // save time + var prevTime = self.getTime(); + self.setTime(time); + } + + var ia = input.split(""); + var ij = 0; + while (ia[ij]) { + if (ia[ij] == "\\") { + // this is our way of allowing users to escape stuff + ia.splice(ij,1); + } else { + if (switches.exists(ia[ij])) { + ia[ij] = eval(ia[ij] + "()"); + } + } + ij++; + } + // reset time, back to what it was + if (prevTime) { + self.setTime(prevTime); + } + return ia.join(""); +} diff --git a/js/gui.js b/js/gui.js index f420e7d..cbf7275 100644 --- a/js/gui.js +++ b/js/gui.js @@ -1,13 +1,101 @@ + /** - * initializes all the JS GUI-Stuff + * Note Editor Class */ -function init(){ - new Ajax.Autocompleter('taglookup','tagresult', 'ajax.php', {paramName: 'taglookup', tokens: ','}); - new Ajax.Autocompleter('tageditlookup','tageditresult', 'ajax.php', {paramName: 'taglookup', tokens: ','}); + +/* +NoteEditor.prototype = { + + initialize: function(ident,type,controlId){ + this.type = type; + this.ident = ident; + this.ctl = $(controlId); + // add click handler to control + Event.observe(controlId, 'click', this.edit, false); + }, +*/ + + +/** + * Create the editor component + */ + +function nedit_showEditor(type,dn){ + // if the editor already exists cancel it + if($('nedit_editor') !== null){ + nedit_cleanUp(); + return; + } + + var editor = '
'; + editor += '
'; + + editor += ''; + editor += ''; + editor += '
'; + + new Insertion.Top($('nedit_insert'), editor); + + Event.observe('nedit_save', 'click', function(){ nedit_saveChanges(dn) }, false); + Event.observe('nedit_cancel', 'click', nedit_cleanUp, false); + +// $('nedit_edit').scrollIntoView(); + $('nedit_edit').focus(); +}; + +function nedit_cleanUp(){ + Element.remove('nedit_editor'); +} + +function nedit_saveChanges(dn){ + var content = encodeURI($F('nedit_edit')); + dn = encodeURI(dn); + + $('nedit_editor').innerHTML = "Saving..."; + + var success = function(resp){nedit_complete(resp)}; + var failure = function(resp){nedit_failed(resp)}; + var pars = 'addnote='+dn+'¬e='+content; + + var ajax = new Ajax.Request('ajax.php', {method:'post',postBody:pars,onSuccess:success,onFailure:failure}); +} + +function nedit_complete(resp){ + nedit_cleanUp(); + $('nedit_insert').innerHTML = resp.responseText; +} + +function nedit_failed(resp){ + nedit_cleanUp(); + alert("Saving failed."); } +/** + * initializes all the JS GUI-Stuff + */ +function init(){ + if($('taglookup') !== null) + new Ajax.Autocompleter('taglookup','tagresult', 'ajax.php', {paramName: 'taglookup', tokens: ','}); + if($('tageditlookup') !== null) + new Ajax.Autocompleter('tageditlookup','tageditresult', 'ajax.php', {paramName: 'taglookup', tokens: ','}); + +} + Event.observe(window, 'load', init, false); diff --git a/pix/arrow_right.png b/pix/arrow_right.png new file mode 100644 index 0000000..4bfba64 Binary files /dev/null and b/pix/arrow_right.png differ diff --git a/pix/email.png b/pix/email.png new file mode 100644 index 0000000..5c0e089 Binary files /dev/null and b/pix/email.png differ diff --git a/pix/note.png b/pix/note.png new file mode 100644 index 0000000..2446ae6 Binary files /dev/null and b/pix/note.png differ diff --git a/pix/phone.png b/pix/phone.png new file mode 100644 index 0000000..97401ab Binary files /dev/null and b/pix/phone.png differ diff --git a/templates/entry_show.tpl b/templates/entry_show.tpl index da5f391..bcf378c 100644 --- a/templates/entry_show.tpl +++ b/templates/entry_show.tpl @@ -55,10 +55,9 @@ {/if} - {if $conf.extended} - {include file="extended_show.tpl"} - {/if} + + {$lang.private}
@@ -92,14 +91,6 @@
- {if $entry.note} - {$lang.note} -
- {$entry.note|nl2br} -
- {/if} - - {if $managername} {$lang.manager}
@@ -113,11 +104,28 @@
{/if} + {if $conf.extended} + {include file="extended_show.tpl"} + {/if} - {if $conf.openxchange} - {include file="openxchange_show.tpl"} - {/if} + +
+{$lang.note} + + + + + + +
+ {$entry.note|noteparser} +
+ +{if $conf.openxchange} + {include file="openxchange_show.tpl"} +{/if} +


diff --git a/templates/header.tpl b/templates/header.tpl index 1ee0a46..dd2b15b 100644 --- a/templates/header.tpl +++ b/templates/header.tpl @@ -6,6 +6,7 @@ + diff --git a/templates/style.css b/templates/style.css index c7e0ed1..6dff811 100644 --- a/templates/style.css +++ b/templates/style.css @@ -112,3 +112,23 @@ div.autocomplete li.selected { background-color: #03c; color: #fff; } + +div#nedit_editor textarea{ + border-width:1px; + border-style:solid; + border-color:#000000; + margin:2px; + font-family:Lucida,Helvetica,Verdana,Arial,Sans-Serif; + font-size: 12px; + width: 60%; + height: 10em; +} + +div#nedit_editor input { + border-width:1px; + border-style:solid; + border-color:#000000; + margin:2px; + font-family:Lucida,Helvetica,Verdana,Arial,Sans-Serif; + font-size: 12px; +}