See Also

Basic Classes

Cell Type Classes

Enumerations

Name Values
EditTypes None
Text
LongText
Integer
YesNoSelect
Checkbox
Date
Password
Currency
Double
TimeWithSeconds
TimeWithoutSeconds
Color
PopupMenu
Multiselect
FormatTypes Text
LongText
Currency
YesNo
Checkbox
Percent
ProgressBar
FontAwesome
Date
Color
Picture
HTML
Password
Tree
Double
TimeWithSeconds
TimeWithoutSeconds
PopupMenu
Multiselect
TextWithButton
Button
ButtonGroup
Chart
Badge
JavaScript
StarRating
SelectionTypes Row
Cell
SortDirections Ascending
Descending
None

Constants

Name Type Value
This class exposes no constants.

Events

Definition Parameters Description
CellChange Row as GraffitiGridRow Fired when the value of a cell has been edited by the user.
Column as GraffitiGridColumn
NewValue as Variant
CellClick Row as GraffitiGridRow Fired when the user clicks a cell.
Column as GraffitiGridColumn
pageX as Integer
pageY as Integer
CelDoubleClick Row as GraffitiGridRow Fired when the user double-clicks a cell.
Column as GraffitiGridColumn
CellMouseEnter row as GraffitiGridRow Raised when the mouse enters a grid cell.
column as GraffitiGridColumn)
CellMouseExit row as GraffitiGridRow Raised when the mouse exits a grid cell.
column as GraffitiGridColumn)
ColumnResized Column as GraffitiGridColumn Fired when a column is resized in the display by the user.
ColumnsReordered None Fired when the columns are reordered by the end-user. Use methods to determine new order.
ContextClick Row as GraffitiGridRow Fired when the user right-clicks on a cell.
Cell as GraffitiGridColumn
X as Integer
Y as Integer
cellLeft as Integer
cellTop as Integer
cellWidth as Integer
cellHeight as Integer
EditBegin Row as GraffitiGridRow Raised when an edit operation has begun.
Column as GraffitiGridColumn
EditEnd Row as GraffitiGridRow Raised when an edit operation has ended either by saving or canceling.
Column as GraffitiGridColumn
EditKeyPress Row as GraffitiGridRow Raised when the user presses a key while editing.
Column as GraffitiGridColumn
KeyCode as Integer
AltKey as Boolean
CtrlKey as Boolean
ShiftKey as Boolean
MetaKey as Boolean
EditorValue as String
EditorButtonPressed Row as GraffitiGridRow Raised when the user clicks the button in a cell editor of type TextWithButton.
Column as GraffitiGridColumn
Value as String
FooterClick Column as GraffitiGridColumn Raised when the user clicks on a cell in the footer.
FooterContextClick Column as GraffitiGridColumn Raised when the user right-clicks on a cell in the footer.
HeaderClicked Column as GraffitiGridColumn Raised when user clicks on a GraffitiGridColumn in the display.
KeyPress Row as GraffitiGridRow Raised when the user presses a keyboard key on the grid but not when editing.
Column as GraffitiGridColumn
KeyCode as Integer
AltKey as Boolean
CtrlKey as Boolean
ShiftKey as Boolean
RowCollapsed Row as GraffitiGridRow Fired when a tree row is collapsed. Children should be removed at this point.
RowExpanded Row as GraffitiGridRow Fired when a tree row is expanded. Children should be added at this point.
RowFromDatabase row as GraffitiGridRow Raised when a row is being processed for addition during an AddRowSet call. This event allows you to modify field data before it reaches the Grid.
RowsReordered None Fired when the user drag reorders rows.
RowToDatabase as Boolean column as GraffitiGridColumn Raised when a row's cell value has been changed and the data needs to be written. Return True if you are handling the write operation.
row as GraffitiGridRow
ScrollPositionChanged X as Integer The user has scrolled the display.
Y as Integer
SelectionChanged None Fired when the user changes the row selection. Use methods to determine new selection.
Sorted ByColumn as GraffitiGridColumn When the user changes the sort order of the display after the rows have been sorted by the new sort order.

Methods

Name Parameters Return Type Description
AddChild ParentRow as GraffitiGridRow None Add a child to a parent tree row.
ChildRow as GraffitiGridRow
AddColumn Column as GraffitiGridColumn None Add a header to the grid.
AddRow newRow as GraffitiGridRow None Adds a new row to the grid's data.
AddRows Rows as GraffitiGridRow None Adds the array of rows as specified to the grid.
AddRowSet rs as RowSet None Adds the rows contained within the RowSet to the grid. Only those values which match a grid column will be added. The idField parameter must match a PRIMARY KEY column in your database and you must return that column's values in the RowSet.
idField as String = “id”
Column atIndex as Integer GraffitiGridColumn Retrieve a Column object by the specified criteria, check for Nil after.
Column ID as String GraffitiGridColumn
ColumnCount None Integer Retrieve the number of columns currently added to the Grid (ColumnCount - 1 for iteration).
ColumnIndex ID as String Integer Returns the index of the column, useful for interation.
ColumnIndex Column as GraffitiGridColumn Integer
DeleteAllRows None None Remove all rows from the grid.
DeselectAllRows None Clear the grid's selection.
EditActiveCell None None Edit the cell that is currently selected.
EditCancel None None Cancels the current edit operation.
EditCell Row as Integer None Edit the defined cell.
Column as Integer
EditCell Row as GraffitiGridRow None
Column as GraffitiGridColumn
EditCommit None None Commits the current edit operation.
InsertChild ParentRow as GraffitiGridRow None Insert a child row of a tree row at a given index.
ChildRow as GraffitiGridRow
atIndex as Integer
InsertRow Row as GraffitiGridRow None Insert a row in the display.
intIndex as Integer
NextCell None None Navigate selection to the next cell.
NextRow None None Navigate selection to the next row.
PreviousCell None None Navigate selection to the previous cell.
PreviousRow None None Navigate selection to the previous row.
RemoveCellStyle Row as GraffitiGridRow None Remove a GraffitiStyle from a cell.
Column as GraffitiGridColumn
theStyle as GraffitiStyle
RemoveChild ParentRow as GraffitiGridRow None Remove the defined child row from the parent row.
ChildRow as GraffitiGridRow
RemoveColumn Column as GraffitiGridRowColumn None Remove the specified column from the display.
RemoveColumn columnIndex as Integer
RemoveRow intIndex as Integer None Remove the specified row.
RemoveRow Row as GraffitiGridRow None
ResetGrid None None Removes all Rows and Columns from the Grid. Do not execute when LockUpdate = True, execute before.
Row RowID as String as GraffitiGridRow Finds the row matching the criteria, check for Nil after.
Row RowIndex as Integer as GraffitiGridRow
RowCount None Integer Returns the number of rows currently added, for iteration use RowCount - 1.
RowIndex Row as GraffitiGridRow Integer Returns the current index of the row in the display.
ScrollTo PositionX as Integer None Scrolls the display to the specified coordinates.
PositionY as Integer
ScrollToCell Row as Integer None Scrolls the specified Row/Cell in to view.
Column as Integer
ScrollToCell Row as GraffitiGridRow None
Column as GraffitiGridColumn
ScrollToRow Row as Integer None Scrolls the display along the Y-axis to the specified row.
ScrollToRow Row as GraffitiGridRow None
SearchRows column as GraffitiGridColumn GraffitiGridRows() Returns the rows matching the specified criteria.
value as Variant
limit as Integer = 1
SearchRows RowSetID as Integer GraffitiGridRow Returns the row from the RowSet with the matching ID.
SetActiveCell Row as Integer None Sets the grid selection to the Row and Cell specified. If ForceEdit = True and the Grid is editable, the cell be put in edit mode.
Cell as Integer = 0
ForceEdit as Boolean = False
SetCellStyle Row as GraffitiGridRow None Add a GraffitiStyle to a cell.
Column as GraffitiGridColumn
newStyle as GraffitiStyle
SortBy Column as GraffitiGridColumn None Sort the specified column.
Direction as SortDirections
toCSV columnSeparator as String = “,” String Returns a CSV string of the current grid contents. If rowSeparator is blank, EndOfLine.UNIX will be used.
rowSeparator as String = “”
UpdateDisplay InvalidateAllRows as Boolean = False None Force an update of the grid display.

Properties

Name Type Default Value Description
AutoEdit Boolean False When True and Editable = True, navigating/clicking the cells in the grid will automatically put them in edit mode.
DatabaseAutoUpdate Boolean True When True, rows that were loaded via AddRowSet and later modified will attempt to update their associated DatabaseRecords.
Editable Boolean False When True, cells can be made editable using the EditActiveCell and EditCell methods.
Editing Read-Only Boolean False Returns True when the user is currently editing a cell.
EnableColumnReorder Boolean False Allow users to drag reorder columns in the display.
EnableRowReorder Boolean False Allow users to drag reorder rows.
FooterRow GraffitiGridRow Automatically instantiated when Nil Row data to display in the Grid's footer.
FooterRowFunction String “” JavaScript function used to validate or format footer row data.
FooterRowHeight Integer 26 Height in pixels of the footer row. Cell values are top-left aligned.
FooterRowVisible Boolean False When True, displays the footer row at the bottom of the Grid's data display area.
ForceFitColumns Boolean False When True, columns are forced to stay inside the viewable area. Resizing one column will resize other proportionally to maintain visibility.
HeaderRowHeight Integer 25
HeaderRowVisible Boolean True Determines if the columns header row is displayed.
ListIndex Read-Only Integer Returns the index of the currently selected row.
LockUpdate Boolean False When True, certain actions are buffered until value is set to False again. This is used to increase the speed at which grids render as lengthy operations (like adding large numbers of rows) are deferred until all of the relevant data for the update is available.
MultiSelectRows Boolean False When True, more than one row may be selected at a time in the display.
RenderedBottomRow Integer -1 The bottom-most row that is currently rendered in the display. This may be a row that is outside the display, but is rendered ahead for scrolling continuity.
RenderedTopRow Integer -1 The top-most row that is currently rendered in the display. This may be a row that is outside the display, but is rendered ahead for scrolling continuity.
RowHeight Integer 25 Height of all rows.
SearchColumnHeaderText String “Search…” Text displayed in the Column selector
SearchFieldPlaceholder String “Search…” Text displayed in the search field when it has no value.
SearchFieldText String “” Text value of the search field.
SearchLabelText String “” Text displayed to the left of the search field.
SearchPanelVisible Boolean False When True, the search panel will be displayed at the top of the control, below the column headers.
SelectedCell Read-Only Integer -1 The column index of the currently selected cell in the display.
SelectedRows Read-Only Array of GraffitiGridRow Nil The currently selected rows in the display.
SelectionType SelectionTypes SelectionTypes.Row Determines how focus on the grid is displayed, either by Row or Cell.
Sortable Boolean True When True, users may sort the grid by clicking column headers. This also disable Tree functionality.
StyleCellBorder GraffitiStyle Nil GraffitiStyle applied to row cells' border. If Nil, uses default Bootstrap style.
StyleHeader GraffitiStyle Nil GraffitiStyle applied to column headers. If Nil, uses default Bootstrap style.
StyleRowEven GraffitiStyle Nil GraffitiStyle applied to even rows. If Nil, uses default Bootstrap style.
StyleRowFooter GraffitiStyle Nil GraffitiStyle applied to the footer row.
StyleRowOdd GraffitiStyle Nil GraffitiStyle applied to odd rows. If Nil, uses default Bootstrap style.
StyleRowSelected GraffitiStyle Nil GraffitiStyle applied to selected rows/cells. If Nil, uses default Bootstrap style.
StyleTextEditor GraffitiStyle Nil GraffitiStyle applied to editor for columns using EditTypes.Text.
TreeView Boolean False When True, the Grid can contain tree rows. Setting to True disables column sorting.

Examples

Creating a Basic Column

A basic column definition would look like this, as seen in the grid object Open events in pgeGrid of the demo:

var titleHeader as new GraffitiGridColumn( "title", "Title" )
titleHeader.Editor = GraffitiGrid.EditTypes.Text
titleHeader.Formatter = GraffitiGrid.FormatTypes.Text
me.AddColumn( titleHeader )

We’re creating a column with the id title, which any added rows must match.

Creating a Basic Row

Here’s a basic row to match the column above, which can be seen in the Open events of the grid components on pgeGrid of the demo project:

var dict as new Dictionary( "title" : "Row" )
var newRow as new GraffitiGridRow( dict )
me.AddRow( newRow )

Disable Column Sorting

Column sorting is controlled per-column. To disable column sorting you must set the Sortable property of your GraffitiGridColumn instance to False:

dim newColumn as new GraffitiGridColumn( "columnID", "Column Text", "columnField" )
newColumn.Sortable = False
me.AddHeader( newColumn )

Edit Selected Cells

If you don't want all cells to be editable, you should set the Editable property of the GraffitiWebGrid instance to True, the AutoEdit property to false, then use logic in the CellClick event (or elsewhere) to trigger the Edit.

For using column indices:

Sub CellClick(Row as Integer, Column as Integer) Handles CellClick
  If Column = 1 Then me.EditActiveCell
End Sub

For using column fields or other properties:

Sub CellClick(Row as GraffitiGridRow, Column as GraffitiGridColumn, pageX as Integer, pageY as Integer) Handles CellClick
    if Column.ID = "columnFieldValue" then me.EditActiveCell()
End Sub

Retrieving Value from Selected Row

This is done by reading the SelectedRows array:

Sub SelectionChanged() Handles SelectionChanged
  if me.SelectedRows.Ubound >= 0 then
    dim selRow as GraffitiGridRow = me.SelectedRows(0)
    dim firstColumn as GraffitiGridColumn = me.Column(0)
    dim rowColumnValue as String = selRow.Cell( firstColumn )
    '// Do something with rowColumnValue here. Note that GraffitiGridRow.Cell
    '   returns a variant which matches the data type of that column, so String
    '   may not be the correct data type depending on what you're project is
    '   doing.
  end if
  End Sub

Dynamically Adding Rows When User Presses Enter

The below KeyPress event will create a new (mostly) empty row when the user highlights the last cell in the last row and presses the Enter key.

Sub KeyPress(Row as GraffitiGridRow, Column as GraffitiGridColumn, KeyCode as Integer, AltKey as Boolean, CtrlKey as Boolean, ShiftKey as Boolean) Handles KeyPress
  if KeyCode = 13 and row = me.Row( me.RowCount - 1 ) and Column = me.Column( me.ColumnCount - 1 ) then
    var newRow as new GraffitiGridRow( new Dictionary( "title" : "Dynamic Row" ) )
    me.AddRow( newRow )
 
    me.EditCell( newRow, me.Column(0) )
  end if
End Sub

Sample Column of FormatTypes.JavaScript

Var jsHeader As New GraffitiGridColumn( "jsformatter", "jsformatter" )
jsHeader.Formatter = GraffitiGrid.FormatTypes.JavaScript
var jsFormatter() as String
jsFormatter.Add( "function (rowIndex, cellIndex, cellValue, column, row) {" )
jsFormatter.Add( "  return '<strong>From JavaScript</strong>: ' + row['title'];" )
jsFormatter.Add( "}" )
jsHeader.FormatterJavaScript = string.FromArray( jsFormatter, "" )
jsHeader.Width = 130
Me.AddColumn( jsHeader )

It is your responsibility to provide functioning JavaScript code and implement your own error checking. Make use of JavaScript's Try...Catch blocks and Debugger statement as necessary.

Example FooterRowFunction

function(row, column, allRows) {
  if (column.id == "perc") {
    var total = 0;
    allRows.forEach(function(currentRow) {
      total += currentRow.perc;
    });
    var totalSpan = $("<span />" ).text(toDouble(total) + " %");
    totalSpan.css("color", ((total >= 0) ? "#0f0" : "#f00"));
    return totalSpan.prop("outerHTML");
  } else {
    return row[column.id];
  }
}

To express numbers in a localized format, you can use the toDouble function in your FooterRowFunction JavaScript. toDouble has a single parameter and will convert, for example, 1000.50 to 1000,50 for locales where the decimal character is a comma.

It is your responsibility to provide functioning JavaScript code and implement your own error checking. Make use of JavaScript's Try...Catch blocks and Debugger statement as necessary.

Implementing Column-Based Contextual Menus

To implement a contextual menu, you will add a GraffitiMenu class to the page/container that houses the Grid. Then, when creating your columns, you will create and assign a GraffitiMenuItem to the GraffitiColumn.ContextMenu property. This can be seen in the Open event of gwgDemo on pgeGrid in the demo project:

var TitleMenu as new GraffitiMenuItem( "TitleMenu" )
TitleMenu.Children.AddRow( new GraffitiMenuItem( "item1", "This menu is tied to" ) )
TitleMenu.Children.AddRow( new GraffitiMenuItem( True ) )
TitleMenu.Children.AddRow( new GraffitiMenuItem( "item2", "Right-Click for Title cells" ) )
GraffitiMenu1.AddMenu( TitleMenu )
 
dim titleHeader as new GraffitiGridColumn( "title", "Title" )
titleHeader.ContextMenu = TitleMenu
me.AddColumn( titleHeader )

You will respond to menu selections in the MenuAction event of the GraffitiMenu instance you’ve added to the page:

select case InMenu.Name
case "TitleMenu"
  var selRow as GraffitiGridRow = gwgDemo.SelectedRows(0)
  MessageBox( ChildItem.Name + " ContextClick on " + selRow.Cell( gwgDemo.Column( "title" ) ) )
case "type"
  var typeColumn as GraffitiGridColumn = gwgDemo.Column("type")
  clickRow.Cell(typeColumn) = ChildItem.Caption
end select

Implementing Event-Based Contextual Menus

As was shown previously, you will add a GraffitiMenu instance to the page/container, then create a GraffitiMenuItem and add that:

var EditMenuItem as new GraffitiMenuItem( "EditMenu" )
EditMenuItem.Children.AddRow( new GraffitiMenuItem( "text", "Plain Text" ) )
EditMenuItem.Children.AddRow( new GraffitiMenuItem( "undo", "Undo", "fa fa-undo", false, "u" ) )
EditMenuItem.Children.AddRow( new GraffitiMenuItem( True ) )
EditMenuItem.Children.AddRow( new GraffitiMenuItem( "cut", "Cut", "fa fa-cut", false, "t" ) )
EditMenuItem.Children.AddRow( new GraffitiMenuItem( "copy", "Copy", "fa fa-copy", false, "c" ) )
EditMenuItem.Children.AddRow( new GraffitiMenuItem( "paste", "Paste", "fa fa-paste", True, "p" ) )
EditMenuItem.Children.AddRow( new GraffitiMenuItem( "delete", "Delete", "fa fa-times", false, "d" ) )
EditMenuItem.Children.AddRow( new GraffitiMenuItem( True ) )
EditMenuItem.Children.AddRow( new GraffitiMenuItem( "selall", "Select All", "fa fa-i-cursor", false, "s" ) )
GraffitiMenu1.AddMenu( EditMenuItem )

Then, in the ContextClick event of your Grid, you will show the GraffitiMenuItem:

var contextMenu as GraffitiMenuItem = GraffitiMenu1.MenuByName( "EditMenu" )
GraffitiMenu1.ShowMenu( contextMenu, cellLeft, cellTop + cellHeight )

And, finally, handle the result (if any) in the GraffitiMenu instance’s MenuAction event.

Notes

Column Direct Modification

For GraffitiWebGrid 2.0, much of the functionality for manipulating Column properties has been moved from the GraffitiWebGrid class to GraffitiGridColumns. This allows you to do things like:

dim colorColumn as GraffitiGridColumn = gridInstance.Column( "colorval" )
cololColumn.Visible = False

Row Direct Modification

As with Column Direct Modification above, Rows are implemented in the same fashion, allowing:

dim colorColumn as GraffitiGridColumn = gridInstance.Column( "colorval" )
dim rowZero as GraffitiGridRow = gridInstance.Row( 0 )
rowZero.Cell( colorColumn ) = RGB( 0, 0, 0 )

Header/Cell Dimensions

When applying GraffitiStyles to your grid elements, you must remember that header style dimensions must match cell style dimensions. For example, if you are using a GraffitiStyle for your grid's cells that has a border-left value of 1px, your header cell GraffitiStyle must match this. Failure to do this will result in headers and columns not lining up correctly in the display. Remember that borders may be a transparent color if you do not wish to display a border on one of these two elements.

This also applies to other dimension-altering properties like margins and padding.

Sorting and Tree Rows

Tree children are independent rows, and will be sorted as such. At the time of this writing (R27) sorting should, in most scenarios, be disabled on Tree grids.

Hidden Columns and Resizing

If you use hidden columns in the grid, you must set their Resizeable property to False. Failure to do so will result in header-column resizing that doesn't match row-column resizing.

Formatting Double or Currency values when using JavaScript functions

It may be necessary to use JavaScript’s toFixed function on these values to get the desired number of decimal places in your Grid display.

The built-in SearchPanel doesn’t allow for much customization and only supports a limited number of column types to make it as fast as possible. If you wish to customize the search, especially on very large datasets, it’s recommended that you build search functionality which searches your data sever-side then displays the results.

The currently supported column types for search are:

  • Double
  • Integer
  • LongText
  • Percent
  • Text
  • TextWithButton
  • YesNoSelect
  • Password

Common Problems

Errors when copying a row from one Grid instance to another

This is unsupported. If you wish to move or reuse a GraffitiGridRow instance in multiple Grids, you must use the GraffitiGridRow.Clone (Release 44+) method to create a copy for each Grid instance where you wish to display the row. Even then updates to the data are not shared across Grid instances and each GraffitiGridRow instance must be updated individually.

Selected Rows are out of order

Multiple row selection does not guarantee that the order of rows will be maintained upon selection either by the order in which they are selected or the order in which they are added to the Grid.

I receive the following Runtime Exception: The data could not be converted to text with this encoding.

This is a common error when you're loading non-UTF8 data from MySQL for use in Xojo Web projects. To address this issue, you should execute the following commands upon connecting:

myDatabase.SQLExecute("set names utf8 collate utf8_general_ci")
myDatabase.SQLExecute("set character set utf8")

Columns are rendered, but I don't see any rows!

Make sure that your row data matches up to your column IDs. Additionally, column names should not consist of only a numeric value, or being with a number. As an example, item0 is valid, while 0 or 0item is not.

When embedded in WebContainers or WebTabPanels, the Grid will sometimes display incorrectly

This is caused by the Grid being initialized when not visible, and may only occur sporadically depending on how and when the Grid is loaded by the project and client browser. To address this, you can call the UpdateDisplay method on your Grid control instance. WebTabPanel.PanelChanged is a good place to do this for that parent control, or in the Shown event of a WebContainer.

Make sure that none of your column definitions uses id as the column ID. This is used internally to track the rows, and will cause problems. Alternatively, use something like myID or rowID. Other strings to avoid are:

  • name
  • field
  • editor
  • formatter
  • sorter
  • focusable
  • minWidth
  • resizable
  • selectable
  • cssClass
  • headerCssClass
  • toolTip

Additionally, IDs with a leading underscore are reserved for internal use.