// --------------------------------------------------------------------------------------------------------------------------
// Support script for Extended API demonstration
// --------------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------------
// Members in red are JavaScript keywords
// Members in blue are TreeGrid functions and properties, contain link to documentation
// Members in bold are global functions and variables in this script
// Strings are "pink", numbers are blue
// --------------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------------
var IDisable, IStyle, DLog; // Pointers to html controls
var FRow; // Actual focused row for update
var Styles = [ // Style settings
"Style='G' Grid = 'Grid.gif' Toolbar='Toolbar.gif' Height = '17' Line = '21' Tree = '26' Panel = '13' Sort = '14' Filter = '17' Row = '17'",
"Style='GL' Grid = 'GridLight.gif' Toolbar='ToolbarLight.gif' Height = '17' Line = '21' Tree = '26' Panel = '13' Sort = '14' Filter = '17' Row = '17'",
"Style='GB' Grid = 'GridBigger.gif' Toolbar='Toolbar.gif' Height = '21' Line = '21' Tree = '26' Panel = '18' Sort = '14' Filter = '17' Row = '17'",
"Style='GG' Grid = 'GridGame.gif' Toolbar='Toolbar.gif' Height = '17' Line = '21' Tree = '26' Panel = '13' Sort = '14' Filter = '17' Row = '17'"
];
// --------------------------------------------------------------------------------------------------------------------------
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Main and starting functions
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// --------------------------------------------------------------------------------------------------------------------------
// Creates grid from JavaScript
// --- Prepares and clears controls on pages ---
DLog = GetElem("LOG");
IStyle = GetElem("IStyle");
IDisable = GetElem("IDisable");
DLog.value = "";
IDisable.checked = false;
IStyle.checked = false;
GetElem("IColor").value = "002";
GetElem("SData").selectedIndex = 0;
GetElem("SStyle").selectedIndex = 0;
// --- creates grid ---
var D = new TDataIO(); // new object for communication
D.Layout.Url = "../Data/CalcAPIDef.xml";
D.Data.Url = "../Data/CalcAPIData.xml";
Resize(); // User function to resize main tag to resize it to whole window
TreeGrid(D,"GRID"); // Creates new grid, this grid will now be accessed from Grids[0] property
}
// --------------------------------------------------------------------------------------------------------------------------
// Loads data chosen from the first combo
var idx = GetElem("SData").selectedIndex; // The first combo, contains selected data
var Def = [ // Def contain layout definitions, for examples only, for tutorials is used only data file
"CalcAPIDef.xml","CalcDef.xml","UserDef.xml","BooksDef.xml","Data1Def.xml","Data2Def.xml","Data3Def.xml","Data4Def.xml","UnknownDef.xml",""
];
var Data = [ // Data contain data xml, for examples there are also used layouts from Def, for tutorials this is the only data
"CalcAPIData.xml","CalcData.xml","UserData.xml","BooksData.xml","Data1S.xml","Data2S.xml","Data3S.xml","Data4S.xml","UnknownData.xml",
"Basic1 Empty grid.xml","Basic2 Rows.xml","Basic3 Fixed rows.xml","Basic4 Columns.xml","Basic5 Fixed columns.xml","Basic6 Tree.xml","Basic7 Settings.xml",
"Advanced1 Cells.xml","Advanced2 Formats.xml","Advanced3 Permissions.xml","Advanced4 Sorting.xml","Advanced5 Filters.xml","Advanced6 Defaults.xml","Advanced7 Defaults children.xml",
"Calc1 Columns.xml","Calc2 Rows.xml","Calc3 Order.xml","Calc4 Tree.xml",
"Editing1 Basics.xml","Editing2 Multiline.xml","Editing3 Mask.xml","Editing4 Advanced types.xml",
"Expert1 Spanning.xml","Expert2 User rows.xml","Expert3 Header.xml","Expert4 Body.xml"];
var G = Grids[0];
var D = G.Data;
if(idx>=9){ // Tutorials
D.Data.Url = "../../Tutorials/"+Data[idx];
}
else { // Examples
D.Layout.Url = "../Data/"+Def[idx];
D.Data.Url = "../Data/"+Data[idx];
}
if(idx==34) D.Page.Url="../../Tutorials/Expert4 Page.xml"; // special case, this tutorial uses paging
else D.Page.Url = null; // standard case
if(idx==30) D.Layout.Bonus="<Grid><Cfg BaseUrl='../'/></Grid>"; // special case, this tutorial uses Img expected to be from another location
else D.Layout.Bonus=null; // standard case
var sidx = GetElem("SStyle").selectedIndex;
D.Data.Bonus="<Grid><Cfg MaxWidth='0' MaxHeight='0'/><Img "+Styles[sidx]+"/></Grid>"; // Suppresses MaxHeigth and MaxWidth for any data that has them set, because main tag is positioned in <TABLE> and sets selected style
G.Reload(); // Reloads new data to grid
FRow = null; // Nulls FRow - no focused row in grid
}
// --------------------------------------------------------------------------------------------------------------------------
// Called when window is resized to set extents of the grid to maximize its area
var D = GetElem("GRID");
var R = GetElem("RIGHT");
var S = GetWindowSize();
D.style.width = S[0] - 240;
var h = S[1] - 270 - D.parentNode.offsetTop;;
if(h<R.offsetHeight) h = R.offsetHeight;
D.style.height = h;
}
// --------------------------------------------------------------------------------------------------------------------------
// Helper function, logs string to LOG DIV
function Log(str,ln,color,size){
if(IDisable.checked) return;
var D = document.createElement(ln?"DIV":"SPAN");
D.innerHTML = str+(ln?"":"; ");
if(color) D.style.color = color;
if(size) D.style.fontSize = size;
DLog.appendChild(D);
DLog.scrollTop = 10000;
}
// --------------------------------------------------------------------------------------------------------------------------
// Helper function, escapes the string for using in XML/HTML (to display in log)
if(str.length>50) str = str.slice(0,50)+" ... ";
return str.replace(/&/g,"&").replace(/</g,"<");
}
// --------------------------------------------------------------------------------------------------------------------------
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Event handlers
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// --------------------------------------------------------------------------------------------------------------------------
// Style event handlers
// --------------------------------------------------------------------------------------------------------------------------
Grids.OnGetColor = function(G,row,col,r,g,b,type){
if(IStyle.checked) Log("OnGetColor("+row.id+","+col+","+r+","+g+","+b+","+type+")",0,"#CAC");
if(row[col+"Marked"] && !type) return "rgb("+r+","+(g-64)+","+b+")"; // Checks custom attribute set by function Color
if(G.id=="Books" && !Get(row,"Spanned")) return "rgb("+r+","+g+","+(b-20)+")";// Support function for particular example
}
Grids.OnGetClass = function(G,row,col,cls){
if(IStyle.checked) Log("OnGetClass("+row.id+","+col+","+cls+")",0,"#ACC");
if(G.id.slice(0,4)=="List") return ListGetClass(G,row,col,cls);
return cls;
}
Grids.OnGetType = function(G,row,col,type){
if(IStyle.checked) Log("OnGetType("+row.id+","+col+","+type+")",0,"#CCA");
return type;
}
Grids.OnGetFormat = function(G,row,col,format,edit){
if(IStyle.checked) Log("OnGetFormat("+row.id+","+col+","+format+","+edit+")",0,"#CAA");
return format;
}
Grids.OnGetEnum = function(G,row,col,enuma){
if(IStyle.checked) Log("OnGetEnum("+row.id+","+col+","+enuma.join("|")+")",0,"#ACA");
if(G.id=="List3") return List3GetEnum(G,row,col,enuma); // Support function for particular example
return enuma;
}
Grids.OnCanEdit = function(G,row,col,can){
if(IStyle.checked) Log("OnCanEdit("+row.id+","+col+","+can+")",0,"#AAC");
if(G.id=="List3") return List3CanEdit(G,row,col,can); // Support function for particular example
return can;
}
// --------------------------------------------------------------------------------------------------------------------------
// State event handlers
// --------------------------------------------------------------------------------------------------------------------------
Grids.OnValueChanged = function(G,row,col,val){
Log("OnValueChanged: User <b>set value</b> in cell ["+row.id+","+col+"], from value '"+Esc(G.GetString(row,col))+"' to '"+Esc(G.ValueToString(val,G.GetType(row,col),G.GetFormat(row,col)))+"'.",1);
if(G.id.slice(0,4)=="List") return List3ValueChanged(G,row,col,val); // Support function for particular example
return val;
}
Grids.OnAfterValueChanged = function(G,row,col){
Log("OnAfterValueChanged: User <b>CHANGED value</b> in cell ["+row.id+","+col+"] to '"+G.GetString(row,col)+"'.",1);
}
Grids.OnResultMask = function(G,row,col,val){
Log("OnResultMask: Value '"+Esc(val)+"' tried to save to cell ["+row.id+","+col+"] collides with mask.",1,"red");
return 0;
}
Grids.OnRowMoveToGrid = function(G,row,togrid,torow,copy){
// not used in this example
}
Grids.OnRowMove = function(G,row,oldparent,oldnext){
var log = "OnRowMove: User <b>MOVED row</b> '"+row.id+"' ";
if(oldparent==row.parentNode) log+="inside "+(oldparent.tagName=='I'?"parent row '"+oldparent.id+"'":"root");
else log+="from "+(oldparent.tagName=='I'?"parent row '"+oldparent.id+"'":"root")+" to "+(row.parentNode.tagName=='I'?"parent row '"+row.parentNode.id+"'":"root");
log+=" "+(row.nextSibling?"before row '"+row.nextSibling.id+"'":"as the last row");
Log(log,1);
}
Grids.OnCanDrag = function(G,row,togrid,torow,type){
// log is not used due too many statements
return type;
}
Grids.OnRowDelete = function(G,row,type){
Log("OnRowDelete: User <b>"+(type==1?"DELETED":"UNDELETED")+" row</b> '"+row.id+"'.",1);
}
Grids.OnCanRowDelete = function(G,row,type){
Log("OnCanRowDelete: User tries to <b>"+(type!=3?"DELETE":"UNDELETE")+" row</b> '"+row.id+"'.",1);
return type;
}
Grids.OnCanRowAdd = function(G,parent,next){
Log("OnCanRowAdd: User tries to <b>ADD new row</b> to "+(parent&&parent.tagName=='I'?"parent row '"+parent.id+"'":"root") + " " + (next?"before row '"+next.id+"'":"as the last row"),1);
return true;
}
Grids.OnRowAdd = function(G,row){
Log("OnRowAdd: User <b>ADDED new row</b> '"+row.id+"' to "+(row.parentNode.tagName=='I'?"parent row '"+row.parentNode.id+"'":"root") + " " + (row.nextSibling?"before row '"+row.nextSibling.id+"'":"as the last row"),1);
if(G.id=="CalcAPI") row.X = row.id; // Support code for particular example
FillIds();
return true;
}
Grids.OnExpand = function(G,row){
Log("OnExpand: User <b>"+(row.Expanded?"COLLAPSES":"EXPANDS")+" row</b> '"+row.id+"'",1);
}
// --------------------------------------------------------------------------------------------------------------------------
// Sort and filter event handlers
// --------------------------------------------------------------------------------------------------------------------------
Grids.OnSort = function(G,col){
Log("OnSort: User <b>SORTS</b> grid according to column '"+col+"'",1);
}
Grids.OnCanFilter = function(G,start){
var F = G.GetRowById("Filter"), cls="";
if(F){
for(var c=G.GetFirstCol();c;c=G.GetNextCol(c)){
if(Get(F,c+"Filter")) cls+=(cls?",":"")+c;
}
if(start){
if(cls) Log("OnCanFilter: TreeGrid is <b>filtered</b> according to columns "+cls,1,"#aaa");
else Log("OnCanFilter: TreeGrid is <b>not filtered</b>",1,"#aaa");
}
else {
if(cls) Log("OnCanFilter: User <b>FILTERS</b> grid according to columns "+cls,1);
else Log("OnCanFilter: User <b>CLEARS FILTERS</b> in grid",1);
}
}
else {
Log("OnCanFilter: TreeGrid has no filter",1,"#aaa");
}
return true;
}
Grids.OnRowFilter = function(G,row,show){
//if(row.firstChild) show = true; // suppress filter for rows with children
Log("OnRowFilter: row '"+row.id+"' is "+(show?"VISIBLE":"HIDDEN"),0,"#CCC");
return show;
}
// --------------------------------------------------------------------------------------------------------------------------
// Click and key event handlers
// --------------------------------------------------------------------------------------------------------------------------
Grids.OnButtonClick = function(G,row,col){
Log("OnButtonClick: User <b>clicked right button</b> in cell ["+row.id+","+col+"]",1);
G.ShowDialog(row,col,"<DIV style='background:#ffffaa;border:2px inset #ddaadd; padding:10px;'> User dialog on<br>row '"
+ Esc(G.GetString)(row,"A")+"'<br>column '" + Esc(G.GetCaption(col))+"'<br>"
+"<BR><DIV align=center><BUTTON style='width:60;' onclick='Grids[0].CloseDialog();'>OK</BUTTON></DIV></DIV>");
}
Grids.OnLinkClick = function(G,row,col,url,target){
Log("OnLinkClick: User <b>clicked link</b> at cell ["+row.id+","+col+"]. Url is '"+Esc(url)+"', target is "+target+".",1);
}
Grids.OnClick = function(G,row,col,x,y,handled){
Log("OnClick: User <b>clicked</b> cell ["+row.id+","+col+"] at ["+x+","+y+"]."+(col!="Panel"&&row!=G.XHeader?" Cell value is '"+Esc(G.GetString(row,col))+"'.":"")+" Event "+(handled?"WAS":"was NOT")+" handled yet.",1);
}
Grids.OnDblClick = function(G,row,col,x,y){
Log("OnDblClick: User <b>double clicked</b> cell ["+row.id+","+col+"] at ["+x+","+y+"]."+(col!="Panel"&&row!=G.XHeader?" Cell value is '"+Esc(G.GetString(row,col))+"'.":""),1);
}
Grids.OnRightClick = function(G,row,col,x,y){
Log("OnRightClick: User <b>right clicked</b> cell ["+row.id+","+col+"] at ["+x+","+y+"]."+(col!="Panel"&&row!=G.XHeader?" Cell value is '"+Esc(G.GetString(row,col))+"'.":""),1);
ShowMenu(G,row,col,x,y);
return true;
}
Grids.OnKeyDown = function(G,key){ Log("Keydown: "+key,0,"#CCC"); }
Grids.OnKeyPress = function(G,key){ Log("Keypress: "+key,0,"#CCC"); }
Grids.OnTabOutside = function(G,move){
if(move>0){
Log("User pressed tab key on the last cell and focus is moved to next control");
GetElem("SData").focus();
return true;
}
else {
Log("User pressed tab key on the first cell and focus is moved to previous control");
GetElem("IStyle").focus();
return true;
}
}
Grids.OnFocus = function(G,row,col,orow,ocol,fpagepos){
if(fpagepos!=null) var S = "OnFocus: User <b>focused</b> cell on page ["+(row.id?row.id:G.GetPageNum(row))+","+col+"] on position "+fpagepos+".";
else var S = "OnFocus: User <b>focused</b> cell ["+row.id+","+col+"]"+(col?", with value '"+Esc(G.GetString(row,col))+"'":"")+".";
Log(S+" Original focused cell was ["+(orow?orow.id:"none")+","+(ocol?ocol:"none")+"].",1);
FRow = row;
if(fpagepos==null) SetDRow(G,row); // Sets row values in DRow tag's inputs
}
Grids.OnSelect = function(G,row,type){
var t = ["unselected","selected","changed selection of"];
Log("OnSelect: User <b>"+t[type-0]+"</b> row "+row.id+".",1);
}
Grids.OnStartEdit = function(G,row,col){
Log("OnStartEdit: User <b>STARTED editation</b> in cell ["+row.id+","+col+"], with value '"+Esc(G.GetString(row,col))+"'.",1);
}
Grids.OnEndEdit = function(G,row,col,save){
Log("OnEndEdit: User <b>"+(save?"FINISHED":"CANCELED")+" editation</b> in cell ["+row.id+","+col+"], with original value '"+Esc(G.GetString(row,col))+"'.",1);
}
// --------------------------------------------------------------------------------------------------------------------------
// Data event handlers
// --------------------------------------------------------------------------------------------------------------------------
Grids.OnDataSend = function(G,D,Data){
if(!Data) Data="";
if(Data.length>50) Data = Data.slice(0,50)+" ...";
Log("OnDataSend: TreeGrid sends data '"+Esc(Data)+"' to '"+D.Url+"'",1,"#CCC");
}
Grids.OnDataError = function(G,code,mess,dataio,row){ Log("OnDataError: TreeGrid failed in data communication with code["+code+"] and message '"+mess+"'. Url was "+dataio.Url+".",1,"red"); }
Grids.OnDataReceive = function(G,row){ Log("OnDataReceive: TreeGrid receives data "+(row?" for row "+row.id:""),1,"#CCC"); }
Grids.OnDownloadPage = function(G,row,func){ Log("OnDownloadPage: TreeGrid requests data for page "+(row.id?row.id:G.GetPageNum(row)),1); }
Grids.OnReadData = function(G,D){ Log("OnReadData: TreeGrid reads data from '"+(D.Url?D.Url:D.Tag)+"'",1,"#AAA"); }
Grids.OnSave = function (G,row,autoupdate){ Log("OnSave: TreeGrid saves changes"+(row?" in row "+row.id:"")+" to server."+(autoupdate?" Event was fired from auto update.":""),1); }
Grids.OnReload = function(G){ Log("OnReload: TreeGrid starts reloading",1,"blue"); }
Grids.OnLoaded = function(G){ Log("OnLoaded: TreeGrid loaded its data",1,"#CCC"); }
Grids.OnLoadError = function(G) { Log("OnLoadError: TreeGrid failed to load",1,"red"); }
Grids.OnRenderStart = function(G){ Log("OnRenderStart: TreeGrid started rendering",1,"#CCC"); }
Grids.OnRenderFinish = function(G){
FillIds();
Log("OnRenderFinish: TreeGrid finished rendering",1,"blue");
Log(" ",1); Log(" ",1); Log(" ",1);
Log("--------------------------",1);
Log("<b>TreeGrid Extended API example</b>",1,"red","16px");
Log("<i>In </i><b>this window</b><i> are displayed all events fired by TreeGrid and logged from user event handlers by </i><b>Log</b><i> function. You can </i><b>clear</b><i>, </i><b>disable</b><i> event log or </i><b>enable style events</b><i>.</i>",1,"#0AA","14px");
Log("<i>In the </i><b>right window</b><i> you can run functions to demonstrate TreeGrid Extended API. In the first combo you can select data example to load in grid. "
+"In second combo you can change TreeGrid's style. In next controls you can focus any cell. Color/Select/Filter any cell that contains given value. And also change any value of focused row.</i>",1,"#0AA","14px");
Log("<i>By </i><b>right click</b><i> on any cell you can display </i><b>pop-up menu</b><i> and select presented options. For various cells and rows are different menu options, for </i><b>header</b><i> is there also another set of options.</i>",1,"#0AA","14px");
Log("<i>Remember, some functions can be very slow, especially with logging enabled and large data. Also remember, this example is universal and some functions can be unsuitable for some data examples.</i>",1,"#066","14px");
Log("--------------------------",1);
}
Grids.OnRenderPageStart = function(G,row){ Log("OnRenderPageStart: TreeGrid started rendering "+(row.id?"row '"+row.id+"' children":"page "+G.GetPageNum(row)),1,"#CCC"); }
Grids.OnRenderPageFinish = function(G,row){ Log("OnRenderPageFinish: TreeGrid finished rendering page "+(row.id?"row '"+row.id+"' children":"page "+G.GetPageNum(row)),1,"#CCC"); }
Grids.OnLoadCfg = function(G){ Log("OnLoadCfg: TreeGrid loads configuration from cookies",1,"#CCC"); }
Grids.OnCfgLoaded = function(G){ Log("OnCfgLoaded: TreeGrid loaded configuration from cookies",1,"#CCC"); }
Grids.OnSaveCfg = function(G){ Log("OnSaveCfg: TreeGrid saves configuration to cookies",1,"#CCC"); }
// --------------------------------------------------------------------------------------------------------------------------
// Panel event handlers
// --------------------------------------------------------------------------------------------------------------------------
Grids.OnGetUserPanel = function (G){
Log("OnGetUserPanel: User defined panel returned",1,"#ccc");
return "<td><button class=GButton onclick='alert(\"User toolbar button clicked!\");'>User</button></td>";
}
Grids.OnPanelClick = function(G,idx){ Log("OnPanelClick: User clicked to toolbar button with idx "+idx,1); }
Grids.OnCanShowPanelItem = function(G,idx,show){
Log("OnCanShowPanelItem: Panel button ["+idx+"] is <b>"+(show?"visible":"hidden")+"</b>",0,"#ccc");
return show;
}
Grids.OnCanShowCfgItem = function(G,idx,show){
Log("OnCanShowCfgItem: Configuration menu item ["+idx+"] is <b>"+(show?"visible":"hidden")+"</b>",0,"#ccc");
return show;
}
// --------------------------------------------------------------------------------------------------------------------------
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Controlling functions
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// --------------------------------------------------------------------------------------------------------------------------
// Function called after click on any item of user right click menu
// Runs appropriate command
// idx is option index, Items is array of option names
function MenuClick(idx,G, row,col,Items){
Log("User menu item '<b>"+Items[idx]+"</b>' selected.",1,"red");
switch(Items[idx]){
case 'Unselect':
case 'Select' :
G.SelectRow(row); break; // Changes selection of the row
case 'Select all':
case 'Unselect all':
G.SelectAllRows(); break; // Changes selection of all rows
case 'Delete' :
G.DeleteRow(row,2); break; // Deletes the row
case 'Undelete' :
G.DeleteRow(row,3); break; // Undeletes the row
case 'Delete selected':
case 'Undelete selected':
G.DeleteSelectedRows(); // Deletes or undeletes all selected rows
break;
case 'Collapse' :
G.Collapse(row); break; // Collapses the row
case 'Expand' :
G.Expand(row); break; // Expands the row
case 'Change value' :
var val = prompt('Change cell value',G.GetString(row,col)); // Lets user to change the value as string
if(val!=null) {
G.SetString(row,col,val); // Sets the changed value and recalculates the grid
G.RefreshCell(row,col); // Refreshes the cell to display new value
G.ColorRow(row); // Colors the row to change color according to changes
}
break;
case 'Add child' :
var r = G.AddRow(row,null,true); // Adds new row to the children of the row, to the end
G.ScrollIntoView(r); // Scrolls grid to display new row
break;
case 'Add next' :
var r = G.AddRow(row.parentNode,G.GetNext(row),true); // Adds new row after the row, to the same parent
G.ScrollIntoView(r); // Scrolls grid to display new row
break;
case 'Sort descending':
G.SortClick(col,0); // Sorts grid descending according to the col
break;
case 'Sort ascending':
G.SortClick(col,1); // Sorts grid ascending according to the col
break;
case 'Hide column':
G.HideCol(col); // Hides the column (column can be displayed from menu columns, it can be run from toolbar)
G.SaveCfg(); // Updates configuration in cookies
break;
}
}
// --------------------------------------------------------------------------------------------------------------------------
// Function shows popup menu on cell
// Called from OnRightClick event
function ShowMenu(G,row,col,x,y){
Log("User displayed popup menu",1);
var Items=new Array(), p = 0;
if(row==G.XHeader){ // row is header row
var R = G.GetSelRows(); // returns all selected rows as array
if(R.length){ // If there is at least one selected row
Items[p++] = "Unselect all";
for(var i=0,del=0;i<R.length;i++) if(Is(R[i],"Deleted")) { del=1; break; }
if(del) Items[p++] = "Undelete selected"; // If there is at least one delete row in grid
else Items[p++] = "Delete selected"; // No deleted row in grid
}
else Items[p++] = "Select all"; // No selected row in grid
if(col!="Panel"){ // Column is not left panel
Items[p++] = "Sort descending";
Items[p++] = "Sort ascending";
Items[p++] = "Hide column";
}
}
else { // row is not header row
Items[p++] = Is(row,"Selected") ? "Unselect" : "Select";
Items[p++] = Is(row,"Deleted") ? "Undelete" : "Delete";
if(G.HasChildren(row)){ // If row has at least one visible child
if(Is(row,"Expanded")) Items[p++] = "Collapse"; // For expanded row
else Items[p++] = "Expand"; // For collapsed row
}
if(G.CanEdit(row,col)) Items[p++] = "Change value";// If value can be edited by user
if(!row.Fixed && G.GetCDef(row)) Items[p++] = "Add child"; // If this is body row (no foot or head) and has set CDef attribute
if(!row.Fixed) Items[p++] = "Add next"; // If this is body row (no foot or head)
}
G.ShowMenu(row,col,Items,null,MenuClick,null,"User menu",x,y,Items); // Shows user menu with given items and caption on given position
}
// --------------------------------------------------------------------------------------------------------------------------
// Function called from button Focus to focus chosen row
// Also called when SIds or SCols combo changed
// --- gets row and col from combos ---
var S = GetElem('SIds');
var id = S.options[S.selectedIndex].value;
var G = Grids[0];
var row = G.GetRowById(id);
var S = GetElem('SCols');
var col = S.options[S.selectedIndex].value;
Log("User run command <b>Focus</b> for cell ["+id+","+col+"].",1,"red");
if(!row){ // Row with given id is not present in the grid
alert("Unknown id");
return;
}
if(!Is(row,"Visible")){ // Row is not visible (is hidden by filter or is deleted
alert("Selected row is hidden and cannot be focused");
return;
}
setTimeout(function(){ // Delays the code, otherwise the grid will loose focus to the select box
G.Focus(row,col,null,true); // Focuses the row and also expands row's parent if it is collapsed (set by last parameter)
},10);
}
// --------------------------------------------------------------------------------------------------------------------------
// Called to prepare controls for new data
// Called from OnRenderFinish and OnRowAdd event handlers
// Fills all ids of rows to SIds select box
// Fills all column names to SCols select box
// Generates inputs in DRow tag for every column, to let user to change values
var G = Grids[0]; // There is only one grid on page
// --- fills all rows' ids ---
var S = GetElem("SIds");
S.options.length = 0;
var A = new Array(), id=1;
// Variable rows
for(var r=G.GetFirst();r;r=G.GetNext(r)) { // Base cycle for iteration through all variable rows
if(!r.id) r.id = "R"+(id<10?'0':"")+(id++); // Generate id, if row has not any
A[A.length] = r.id;
}
A.sort(); // sorts ids to better display in combo
// Fixed rows
var F = G.GetFixedRows(); id=1;
for(var i=0;i<F.length;i++){
if(!F[i].id) F[i].id = "F"+(id<10?'0':"")+(id++);
A[A.length] = F[i].id;
}
for(var i=0;i<A.length;i++){ // generates new options in select box
S.options[S.options.length] = new Option(A[i],A[i]);
}
// --- fills all columns' names ---
var S = GetElem("SCols");
S.options.length = 0;
var A = new Array();
//for(var c=G.GetFirstCol();c;c=G.GetNextCol(c)) A[A.length] = c; // Base cycle for iteration through all visible columns according to their position
for(var c in G.Cols) if(c!='Panel') A[A.length] = c; // Base cycle for iteration throught all columns
A.sort(); // sorts column names to better display in combo
for(var i=0;i<A.length;i++){ // generates new options in select box
S.options[S.options.length] = new Option(A[i],A[i]);
}
// --- creates inputs for every column ---
var D = GetElem("DRow"), A = new Array(), p=0;
A[p++] = "<div id=ID_ID>Row</div>";
for(var c in G.Cols) if(c!='Panel'){ // Base cycle for iteration throught all columns
A[p++] = G.GetCaption(c)+" ";
A[p++] = "<input id=ID"+c+" type=text style='width:80;font-size:10px;' onkeydown='if(event.keyCode==13 || event.charCode==13) Update(this);'><br>";
}
D.innerHTML = A.join("");
var I = D.getElementsByTagName("input");
for(var i=0;i<I.length;i++){ // Sets with of all inputs to maximize it
I[i].style.width = D.offsetWidth-I[i].offsetLeft-10;
}
Resize(); // Height of the tag was changed
}
// --------------------------------------------------------------------------------------------------------------------------
// Function for coloring/filtering/selecting found rows/cells
// Fro button=0 restores all rows
// For button=1 sets user attribute col+"Marked" if cell contains the searched value
// For button=2 hides row if any cell contains the searched value
// For button=3 selects rows if any cell contains the searched value
// Called when user presses the button or presses enter in input tag
var G = Grids[0];
var V = GetElem("IColor").value;
Log("User run command <b>Color ("+button+")</b> with value '"+Esc(V)+"'.",1,"red");
// --- main function to change row's state or color ---
function color(r){
var found = false;
for(var c in G.Cols){
if(c=="Panel") continue;
var t = G.GetType(r,c), M = 0;
if(t=="Int" || t=="Float") { // Number types compares as number
M = V-0==G.GetValue(r,c);
}
else {
var S = G.GetString(r,c);
if(!S) M=!V;
else M = V?S.search(V)>=0:0; // Other then number types searches for appearance
}
if(M) found = true;
if(button!=1) M=0; // only button 'Color' colors the rows
r[c+"Marked"]=M; // Color, sets custom attribute, this attribute will be used in event OnGetColor
}
if(button==2 && !found) G.HideRow(r); // Filter
else G.ShowRow(r);
if(!Is(r,"Selected") && button==3 && found || Is(r,"Selected") && (button!=3 || !found)) G.SelectRow(r); // Select
if(found && button) G.ExpandParents(r); // Expands all parents of the row to make the row visible
G.ColorRow(r); // Updates color of the row
}
// --- iteration of all rows ---
G.Rendering = true; // Suppresses updating grid layout after every change, speeds up the action. It is good especially for Filter (button==2), because it shows/hides rows
//for(var r=G.GetFirstVisible();r;r=G.GetNextVisible(r)) color(r); // Base cycle for iteration through all visible variable rows
for(var r=G.GetFirst();r;r=G.GetNext(r)) if(!Is(r,"Deleted")) color(r); // Base cycle for iteration through all non deleted rows
var F = G.GetFixedRows(); for(var i=0;i<F.length;i++) color(F[i]); // Base cycle for iteration through fixed rows
G.Rendering = false; // Restores original state
G.SetScrollBars(); // Updates grid layout
}
// --------------------------------------------------------------------------------------------------------------------------
// Sets focused row values in DRow tag's inputs
// Called from OnFocus event handler
// --- sets the first row - id, parents, page ---
var I = document.getElementById("ID_ID");
var S = "", r = row.parentNode;
while(r.tagName=="I"){ S += (S?",":"")+(r.id?r.id:"???"); r=r.parentNode; } // fills parents from tree
S = "Id="+(row.id?row.id:"???")+(S?"; parents="+S:"")+"; page="+(r.id?r.id:G.GetPageNum(r));
I.innerHTML = S;
// --- sets values ---
for(var col in G.Cols) if(col!='Panel'){ // Base cycle for iteration throught all columns
var I = document.getElementById("ID"+col);
if(I){
var type = G.GetType(row,col);
I.value = G.ValueToString(G.GetValue(row,col),type,type=="Enum" ? G.GetEnum(row,col) : G.GetFormat(row,col,1)); // Gets string in editing format
I.disabled = !G.CanEdit(row,col); // Disables input if value cannot be edited
}
}
}
// --------------------------------------------------------------------------------------------------------------------------
// Updates inputs value after change
// Called when user presses enter in any input tag in DRow tag
// I is the tag input
var G = Grids[0], row = FRow; // FRow is backup of focused row in the grid, because if grid user clicks on any control on page, the grid looses focus and clears Grids[0].FRow property
if(!FRow){ // (new) data was loaded and user did not clicked on any row yet
alert("No row focused yet");
return;
}
var col = I.id.slice(2); // input's id is "ID"+column_name
var type = G.GetType(row,col);
var val = G.StringToValue(I.value,type,type=="Enum" ? G.GetEnum(row,col) : G.GetFormat(row,col,1)); // Converts string in editing format to value of given type
G.SetValue(row,col,val); // sets the value and recalculates grid
G.RefreshCell(row,col); // Refreshes the cell to display new value
G.ColorRow(row); // Colors the row to change color according to changes
}
// --------------------------------------------------------------------------------------------------------
// Changes style of TreeGrid, does not reload, just re-renders
var G = Grids[0];
G.ChangeStyle("<Grid><Img "+Styles[idx]+"/></Grid>"); // Changes style by changing settings in <Img/>
}
// --------------------------------------------------------------------------------------------------------------------------