App-SocialCalc-Multiplayer
view release on metacpan or search on metacpan
socialcalc/socialcalc2demo-0-8-1.html view on Meta::CPAN
</style>
</head>
<body style="background-color:#FFF;" onresize="spreadsheet.DoOnResize();">
<div style="margin:8px 0px 10px 0px;">
<div id="tableeditor" style="margin:8px 0px 10px 0px;">editor goes here</div>
</div>
<div id="msg" onclick="this.innerHTML=' ';"></div>
<script>
function addmsg(str) {document.getElementById("msg").innerHTML += ", "+str;}
function setmsg(str) {document.getElementById("msg").innerHTML = str;}
// window.onerror = function(m, u, l){ addmsg(m+" at line "+l); return true;};
// Create the spreadsheet control, but don't initialize yet
var spreadsheet = new SocialCalc.SpreadsheetControl();
var savestr = "";
// Set up the tabs we want
// Remove Audit
spreadsheet.tabs.splice(spreadsheet.tabnums.audit, 1);
spreadsheet.tabnums = {};
for (var i=0; i<spreadsheet.tabs.length; i++) {
spreadsheet.tabnums[spreadsheet.tabs[i].name] = i;
}
// Add Plain
spreadsheet.tabnums.plain = spreadsheet.tabs.length;
spreadsheet.tabs.push({name: "plain", text: "Plain", html:
'<div id="%id.plaintools" style="display:none;">'+
' <div style="%tbt."> </div>'+
'</div>',
view: "plain",
onclick:
function(s, t) {
s.views.plain.element.innerHTML = s.CreateSheetHTML();
},
onclickFocus: true
});
spreadsheet.views["plain"] = {name: "plain",
divStyle: "border:1px solid black;overflow:auto;",
html: 'Plain View'
};
// Add Graph
spreadsheet.tabnums.graph = spreadsheet.tabs.length;
spreadsheet.tabs.push({name: "graph", text: "Graph", html:
'<div id="%id.graphtools" style="display:none;">'+
' <div style="%tbt.">'+
' <table cellspacing="0" cellpadding="0"><tr>'+
' <td style="vertical-align:middle;padding-right:32px;padding-left:16px;">'+
' <div style="%tbt.">Cells to Graph</div>'+
' <div id="%id.graphrange" style="font-weight:bold;">Not Set</div>'+
' </td>'+
' <td style="vertical-align:top;padding-right:32px;">'+
' <div style="%tbt.">Set Cells To Graph</div>'+
' <select id="%id.graphlist" size="1" onfocus="%s.CmdGotFocus(this);"><option selected>[select range]</option></select>'+
' <input type="button" value="OK" onclick="GraphSetCells();" style="font-size:x-small;">'+
' </td>'+
' <td style="vertical-align:middle;padding-right:4px;">'+
' <div style="%tbt.">Graph Type</div>'+
' <select id="%id.graphtype" size="1" onchange="GraphChanged(this);" onfocus="%s.CmdGotFocus(this);"></select>'+
' </div>'+
' </td>'+
' <td style="vertical-align:middle;padding-right:16px;">'+
' <div style="%tbt."> </div>'+
' <input id="%id.graphhelp" type="button" onclick="DoGraph(true);" value="Help" style="font-size:x-small;">'+
' </div>'+
' </td>'+
' </tr></table>'+
' </div>'+
'</div>',
view: "graph",
onclick: GraphOnClick,
onclickFocus: true
});
spreadsheet.views["graph"] = {name: "graph", divStyle: "overflow:auto;", values: {},
html: '<div style="padding:6px;">Graph View</div>'
};
spreadsheet.editor.SettingsCallbacks.graph = {save: GraphSave, load: GraphLoad};
// Add Help
spreadsheet.tabnums.help = spreadsheet.tabs.length;
spreadsheet.tabs.push({name: "help", text: "Help", html:
'<div id="%id.helptools" style="display:none;">'+
' <div style="%tbt."> </div>'+
'</div>',
view: "help",
onclick: DoHelp,
onclickFocus: true
});
spreadsheet.views["help"] = {name: "help",
divStyle: "border:1px solid black;overflow:auto;",
html: '<div style="padding:6px;">Help View</div>'
};
// Initialize the Spreadsheet Control and display it
spreadsheet.InitializeSpreadsheetControl("tableeditor");
spreadsheet.ExecuteCommand('redisplay', '');
// Done initialization
//
// * * * FUNCTIONS * * *
//
//
// Example of how to get the serialized data
socialcalc/socialcalc2demo-0-8-1.html view on Meta::CPAN
}
function UpdateGraphRangeProposal(editor) {
var ele = document.getElementById(SocialCalc.GetSpreadsheetControlObject().idPrefix+"graphlist");
if (editor.range.hasrange) {
ele.options[0].text = SocialCalc.crToCoord(editor.range.left, editor.range.top) + ":" +
SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
}
else {
ele.options[0].text = "[select range]";
}
}
function GraphSetCells() {
var lele, ele;
var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
var editor = spreadsheet.editor;
lele = document.getElementById(spreadsheet.idPrefix+"graphlist");
if (lele.selectedIndex==0) {
if (editor.range.hasrange) {
spreadsheet.graphrange = SocialCalc.crToCoord(editor.range.left, editor.range.top) + ":" +
SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
}
else {
spreadsheet.graphrange = editor.ecell.coord+":"+editor.ecell.coord;
}
}
else {
spreadsheet.graphrange = lele.options[lele.selectedIndex].value;
}
ele = document.getElementById(spreadsheet.idPrefix+"graphrange");
ele.innerHTML = spreadsheet.graphrange;
SocialCalc.KeyboardFocus();
DoGraph(false);
return;
}
function DoGraph(helpflag) {
var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
var editor = spreadsheet.editor;
var gview = spreadsheet.views.graph.element;
var ginfo = SocialCalc.GraphTypesInfo[spreadsheet.graphtype];
var gfunc = ginfo.func;
if (!spreadsheet.graphrange) {
if (gfunc && helpflag) {
gfunc(spreadsheet, null, gview, spreadsheet.graphtype, helpflag);
}
else {
gview.innerHTML = '<div style="padding:30px;font-weight:bold;">Select a range of cells with numeric values to graph '+
'and use the OK button above to set the range as the graph range.</div>';
}
return;
}
var grange = spreadsheet.graphrange;
var nrange, rparts;
if (grange && grange.indexOf(":")==-1) { // graphing range is a named range
nrange = SocialCalc.Formula.LookupName(spreadsheet.sheet, grange || "");
if (nrange.type != "range") {
gview.innerHTML = "Unknown range name: "+grange;
return;
}
rparts = nrange.value.match(/^(.*)\|(.*)\|$/);
grange = rparts[1] + ":" + rparts[2];
}
var prange = SocialCalc.ParseRange(grange);
var range = {};
if (prange.cr1.col <= prange.cr2.col) {
range.left = prange.cr1.col;
range.right = prange.cr2.col;
}
else {
range.left = prange.cr2.col;
range.right = prange.cr1.col;
}
if (prange.cr1.row <= prange.cr2.row) {
range.top = prange.cr1.row;
range.bottom = prange.cr2.row;
}
else {
range.top = prange.cr2.row;
range.bottom = prange.cr1.row;
}
if (gfunc) {
gfunc(spreadsheet, range, gview, spreadsheet.graphtype, helpflag);
}
return;
}
function GraphChanged(gtobj) {
var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
spreadsheet.graphtype = gtobj.options[gtobj.selectedIndex].value;
DoGraph(false);
}
function GraphSave(editor, setting) {
// Format is:
// sort:range:sortrange:type:sorttype
socialcalc/socialcalc2demo-0-8-1.html view on Meta::CPAN
'<br><br><input type="button" value="Hide Help" onclick="DoGraph(false);">';
gview.innerHTML = str;
return;
}
if (range.left==range.right) { // down
nitems = range.bottom - range.top + 1;
byrow = true;
}
else {
nitems = range.right - range.left + 1;
byrow = false;
}
str = "";
maxheight = (spreadsheet.height-spreadsheet.nonviewheight)-50;
totalwidth = spreadsheet.width-30;
color = "#666";
minval = null;
maxval = null;
for (i=0; i<nitems; i++) {
cr = byrow ? SocialCalc.rcColname(range.left)+(i+range.top) : SocialCalc.rcColname(i+range.left)+range.top;
cr1 = byrow ? SocialCalc.rcColname(range.left-1 || 1)+(i+range.top) : SocialCalc.rcColname(i+range.left)+(range.top-1 || 1);
cell = spreadsheet.sheet.GetAssuredCell(cr);
if (cell.valuetype.charAt(0) == "n") {
val = cell.datavalue - 0;
if (maxval==null || maxval<val) maxval = val;
if (minval==null || minval>val) minval = val;
values.push(val);
cell = spreadsheet.sheet.GetAssuredCell(cr1);
if ((range.right==range.left || range.top==range.bottom) && (cell.valuetype.charAt(0) == "t" || cell.valuetype.charAt(0) == "n")) {
labels.push(cell.datavalue+"");
}
else {
labels.push(cr);
}
}
}
extra = (maxval-minval)*0.1;
minval = minval - (extra || 1);
eachwidth = Math.floor(totalwidth / (values.length || 1))-4 || 1;
str += '<table cellspacing="0" cellpadding="0" width="'+totalwidth+'"><tr>';
for (i=0; i<values.length; i++) {
thisbar = Math.floor((values[i]-minval)*maxheight/(maxval-minval || 1))+1;
val = (values[i]+"").substring(0,7);
str += '<td valign="bottom" style="padding-right:4px;"><table cellspacing="0" cellpadding="0" width="'+eachwidth+'">';
str += '<tr><td align="center" style="font-size:7pt;">'+val+'</td></tr>';
str += '<tr><td><div style="height:'+thisbar+'px;background-color:'+color+';width:100%"> </div></td></tr>';
str += '</table></td>';
}
str += "</tr><tr>";
for (i=0; i<values.length; i++) {
str += '<td align="center" valign="top" style="font-size:8pt;font-weight:bold;padding-top:6px;">'+labels[i]+'</td>';
}
str += "</tr></table>";
gview.innerHTML = str;
}
// This is where loading help text might go:
function DoHelp(s, t) {
var hview = s.views.help.element;
var str =
'HELP TEXT FOLLOWED BY ABOUT TEXT AND LEGAL INFORMATION:<br><br> '+
'Version 0.8.1<br><br> '+
'<i>This is a spreadsheet built on SocialCalc JavaScript code. '+
'</i> '+
'<br><br> '+
'You can use the arrow keys and mouse to select cells in a manner similar to traditional spreadsheets. '+
'This includes using the shift key, as well as dragging. '+
'<br><br> '+
'The scrollbars should work in a normal manner. '+
'Because this is a spreadsheet, you can scroll any amount without needing to create new rows or columns. '+
'Dragging the thumb to the end of a scrollbar attempts to go to the last row or column where there is/was data. '+
'The mousewheel is also supported. '+
'<br><br> '+
'In addition to the scrollbars there are two pane sliders (that start out at the beginning of the scrollbars) '+
'that let you "lock" the upper rows or columns to facilitate keeping column and row headers visible when scrolling. '+
'<br><br> '+
'You can type values in cells. '+
'Press Enter, use an arrow key, or click on a cell to finish. '+
'If you are in a partial formula (e.g., "=1+" or "=SUM(") an arrow key or cell click will '+
'insert the name of the newly selected cell into the formula, similar to a traditional spreadsheet. '+
'Cell ranges are separated by typing a ":", or you can use the drag or shift-click range selection methods. '+
'<br><br> '+
'The program supports many forms of data, such as numbers, text (preceded by a "\'" if necessary '+
'to distinguish it from numbers), dates (e.g., "1/2/3"), dollars ("$1,234.50"), time ("3:45"), '+
'numbers with fractions ("1 1/2"), and "true", "false", and "#N/A". '+
'A value\'s type determines its displayed format if there is no explicit numeric format set for a cell. '+
'The program supports a wide variety of formats (including other currencies) through its custom format functionality '+
'available on the Format tab. '+
'<br><br> '+
'Use the Esc key to cancel during edits. '+
'The Del key deletes the values of the selected cell(s). '+
'<br><br> '+
'The 109 formula functions that the June 2007 Open Document Format "Open Formula" specification '+
'calls the "small group" are available. '+
'(<b><i>A simple reference to all of the functions is provided when you click the "f()" button on the formula bar.</i></b>) '+
'The specification says that: "This group includes approximately 100 functions, '+
'and includes the basic functions that are very widely implemented in spreadsheet applications, '+
'even in resource-constrained environments."<br><br> '+
'The definitions of the functions follow common conventions, '+
'with common syntax similar to many other spreadsheets. '+
'You can, for example, have a function like IF(B10=B3, "Yes", "No"), where B10 and B3 may contain text values '+
'(comparisons are not case-sensitive). '+
'<br><br> '+
'This release has an HTML version of an editing interface. Most buttons on the toolbar display tooltips when you point to them with the mouse pointer. '+
'<br><br> '+
'The program maintains an undo stack accessed through the Undo and Redo buttons on the left of the Edit tab toolbar. '+
'Right now the stack saves up to 50 steps for undoing. '+
'The Ctrl-Z key may be used as a shortcut instead of the Undo button. '+
'<br><br> '+
'There is a <b>Format</b> tab for accessing all of the format settings, both for individual cells as well '+
'as for the sheet-wide defaults that are applied to cells without explicit settings for that attribute. '+
'You can make changes to any or all of the settings and then press the "Save" button in the toolbar above to apply them. '+
'While the cell settings are only displayed for the current cell, on "Save" the same changes are applied to all cells '+
'in the currently highlighted range of cells. '+
'The Sheet settings let you set the default size of columns. To change the width of an individual column click and '+
'drag in the column header. '+
'<br><br> '+
'The <b>Sort</b> tab lets you select a range of cells (which is remembered) to sort, as well as to set which columns '+
'are used to determine the order and the direction. '+
'<br><br> '+
'There is a <b>Comment</b> tab for accessing the optional comment text for the currently selected cell.'+
'<br><br> '+
'The <b>Name</b> tab lets you set named ranges that may be used in formulas.'+
'<br><br> '+
'The <b>Graph</b> tab displays a graph representation of selected cells. It has its own Help button. '+
'<br><br> '+
'The <b>Plain</b> tab shows the sheet rendered without the grid or editing controls. '+
'<br><br> '+
'The <b>Clipboard</b> tab lets you view the SocialCalc clipboard in tab-delimited format, and optionally reload it with new data. '+
'Tab-delimited format is what some browsers and Excel put on the clipboard when you select and then copy cells in a table. '+
'The Clipboard tab also supports CSV format and the SocialCalc Save format (useful for copying from one sheet to another). '+
'Reloading from the SocialCalc Save format must be in correct format -- errors can cause SocialCalc to behave badly.<br><br>'+
'Pressing Ctrl-V when on the Edit tab and not editing a cell assumes that Tab-delimited data is on the regular '+
'clipboard, loads it into the SocialCalc clipboard, and then "pastes" it starting at the current cell. '+
'This is an easy way to copy data from a web page into a spreadsheet. '+
'Similarly, Ctrl-C loads the SocialCalc clipboard and the system clipboard. '+
'Ctrl-V differs from the Paste button in that it only pastes values and formulas, and not formats. '+
'<br><br> '+
'Right now this code is mainly being developed to run under control of a native Python '+
'application running on the OLPC XO. '+
'This version, though, can also be run directly in a browser. '+
'<br><br> '+
'When the program encounters an error, it may display a message at the bottom of the screen. '+
'You can click on the message to erase it. '+
'<br><br> '+
'Comments can be sent to "socialcalc" at "softwaregarden.com". '+
'<br><br> '+
'<hr> '+
'<b>FUNCTION HELP</b> '+
'<br><br> '+
'The following functions are currently supported in formulas (case is ignored in function names): '+
'<style> '+
'.helplist dt {font-weight:bold;} '+
'.helplist dd {padding-bottom:6pt;} '+
'</style> '+
'<div style="padding:6pt 0px 0px 1em;" class="helplist"> '+
'<dl> '+
'<dt>ABS(value)<dd>Absolute value function. '+
'<dt>ACOS(value)<dd>Trigonometric arccosine function. '+
'<dt>AND(value1, value2, ...)<dd>True if all arguments are true. '+
'<dt>ASIN(value)<dd>Trigonometric arcsine function. '+
'<dt>ATAN(value)<dd>Trigonometric arctan function. '+
'<dt>ATAN2(valueX, valueY)<dd>Trigonometric arc tangent function (result is in radians). '+
'<dt>AVERAGE(value, value, ...)<dd>Averages the values. '+
'<dt>CHOOSE(index, value1, value2, ...)<dd>Returns the value specified by the index. The values may be ranges of cells. '+
'<dt>COLUMNS(range)<dd>Returns the number of columns in the range. '+
'<dt>COS(value)<dd>Trigonometric cosine function (value is in radians). '+
'<dt>COUNT(value, value, ...)<dd>Counts the number of numeric values, not blank, text, or error. '+
'<dt>COUNTA(value, value, ...)<dd>Counts the number of non-blank values. '+
'<dt>COUNTBLANK(value, value, ...)<dd>Counts the number of blank values. (Note: "" is not blank.) '+
'<dt>COUNTIF(range, criteria)<dd>Counts the number of number of cells in the range that meet the criteria. '+
'The criteria may be a value ("x", 15, 1+3) or a test (>25). '+
'<dt>DATE(year, month, day)<dd>Returns the appropriate date value given numbers for year, month, and day. '+
'For example: DATE(2006,2,1) for February 1, 2006. '+
'Note: In this program, day "1" is December 31, 1899 and the year 1900 is not a leap year. '+
'Some programs use January 1, 1900, as day "1" and treat 1900 as a leap year. '+
'In both cases, though, dates on or after March 1, 1900, are the same. '+
'<dt>DAVERAGE(databaserange, fieldname, criteriarange)<dd>Averages the values in the specified field in records that meet the criteria. '+
'<dt>DAY(value)<dd>Returns the day of month for a date value. '+
'<dt>DCOUNT(databaserange, fieldname, criteriarange)<dd>Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. '+
'<dt>DCOUNTA(databaserange, fieldname, criteriarange)<dd>Counts the number of non-blank values in the specified field in records that meet the criteria. '+
'<dt>DDB(cost, salvage, lifetime, period [, factor])<dd> '+
'Returns the amount of depreciation at the given period of time '+
'(the default factor is 2 for double-declining balance). '+
'<dt>DEGREES(value)<dd>Converts value in radians in to degrees. '+
'<dt>DGET(databaserange, fieldname, criteriarange)<dd>Returns the value of the specified field in the single record that meets the criteria. '+
'<dt>DMAX(databaserange, fieldname, criteriarange)<dd>Returns the maximum of the numeric values in the specified field in records that meet the criteria. '+
'<dt>DMIN(databaserange, fieldname, criteriarange)<dd>Returns the maximum of the numeric values in the specified field in records that meet the criteria. '+
'<dt>DPRODUCT(databaserange, fieldname, criteriarange)<dd>Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. '+
'<dt>DSTDEV(databaserange, fieldname, criteriarange)<dd>Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. '+
'<dt>DSTDEVP(databaserange, fieldname, criteriarange)<dd>Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. '+
'<dt>DSUM(databaserange, fieldname, criteriarange)<dd>Returns the sum of the numeric values in the specified field in records that meet the criteria. '+
'<dt>DVAR(databaserange, fieldname, criteriarange)<dd>Returns the sample variance of the numeric values in the specified field in records that meet the criteria. '+
'<dt>DVARP(databaserange, fieldname, criteriarange)<dd>Returns the variance of the numeric values in the specified field in records that meet the criteria. '+
'<dt>EVEN(value)<dd>Rounds the value up in magnitude to the nearest even integer. '+
'<dt>EXACT(value1, value2)<dd>Returns "true" if the values are exactly the same, including case, type, etc. '+
'<dt>EXP(value)<dd>Returns e raised to the value power. '+
'<dt>FACT(value)<dd>Returns factorial of the value. '+
'<dt>FALSE( )<dd>Returns the logical value "false". '+
'<dt>FIND(string1, string2 [, start])<dd>Returns the starting position within string2 of the first '+
'occurrence of string1 at or after "start". If start is omitted, 1 is assumed. '+
'<dt>FV(rate, n, payment, [pv, [paytype]])<dd>Returns the future value of repeated payments of money '+
'invested at the given rate for the specified number of periods, '+
'with optional present value (default 0) and payment type '+
'(default 0 = at end of period, 1 = beginning of period). '+
'<dt>HLOOKUP(value, range, row, [rangelookup])<dd>Look for the matching value for the given value in the '+
'range and return the corresponding value in the cell specified by the row offset. '+
'If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. '+
'<dt>HOUR(value)<dd>Returns the hour portion of a time or date/time value. '+
'<dt>IF(logical-expression, true-value, false-value)<dd>Results in true-value if logical-expression is TRUE or non-zero, '+
'otherwise results in false-value. '+
'<dt>INDEX(range, rownum, colnum)<dd>Returns a cell or range reference for the specified row and column in the range. '+
'If range is 1-dimensional, then only one of rownum or colnum are needed. '+
( run in 0.424 second using v1.01-cache-2.11-cpan-ad19def0cd9 )