Custom Control Properties

Description

The Custom control is a control where the data contents and formatting of a column (or row) is defined by your Xbasic and HTML code.

A custom control can reference a number of grid component and data variables, including the value of data in other grid cells. A custom control can create its own variables to carry values between cells of the grid. There are no important constraints upon what the grid cell of a custom control can display, other than that it must contain valid HTML code. This means, for example, that row-by-row, the type of web control that appears in a grid cell could vary from label to textbox to drop down listbox.

images/01_custom.png
A custom control with a dynamic background and font.
Custom controls cannot be used for data entry to bound table fields.

Properties

Definition

Specify the Xbasic code that computes the HTML for the custom control.

Create a Custom Control

This section explains how to create a custom control similar to the one above. This is a custom control where Xbasic dynamically sets the font and background properties, depending on whether the Unit Price value is above or below the average. The Average for this grid is computed by simply adding an average Summary value to the component.

  1. Open the Grid Builder and go to the Design tab. On the Data Source page choose either dbf or SQL.

  2. On the Query(DBF) or Query(AlphaDAO) page connect to a Table that has some numeric fields in it.

  3. From the Design menu open the Fields page. Move a number of fields from the Available Fields: list into the Selected: fields list.

    images/01_custom2.png
  4. Select one of your numeric fields in the Selected list, this example uses a field called UnitPrice, and in its Field Properties list find the Display Settings section.

  5. Under Display Settings find the Control type property and click the button next to it. Select the Custom option from the Select Control Type dialog.

    images/01_custom3.png
  6. The Field Properties list for custom controls will be displayed. In this list find the Custom Controls Properties section and under it the Definition property.

  7. Click the button next to the Definition property.

    images/01_custom4.png
  8. The Define Xbasic for Custom Control: dialog will open. Delete the default code and replace it with the code below. If your field is not called UnitPrice, replace the name UnitPrice, wherever it occurs in this code, with the name of the field you are using.

    function UnitPrice_render as c (data as p, args as p, PageVars as p)  
    with PageVars  
    if data.UnitPrice > args.summary. UnitPrice.average then 
    UnitPrice_render = <<%html% 
    
    %html% + data. UnitPrice+ "
    " 
    else 
    UnitPrice_render = <<%html% 
    
    %html% + data. UnitPrice+ "
    " 
    end if 
    end 
    UnitPrice_XbasicError: 
    UnitPrice_render = "Error in custom control Xbasic: " + error_text_get() 
    end with 
    end function
    AlphaAnywhere will fill in some of the code above automatically, so if you wanted to you could just save the existing framework and fill in the blanks. In this example, the field name is UnitPrice. As a result, the function is named UnitPrice_Render(). If the name of your customized field is not UnitPrice then swap out UnitPrice for the name of the field you are using. The UnitPrice_Render() function will return a value that is composed of quoted HTML and unquoted Xbasic. In this example, the if and else clauses have similar content. Both are character strings that combine HTML coding and a reference to the quantity field, using the prefix " data. ". Although not a required technique, embedding the HTML inside the ... tags simplifies the coding. Likewise, embedding the tag inside the <<%html% ... %html string simplifies the coding by removing the requirement to escape special characters.
  9. You need to add an average summary value to your control. In the Field Properties list find the Summary values section and check the box next to the Average property.

    images/01_custom5.png
  10. Done. View your custom control in Live Preview.

    images/01_custom6.png

Variables

You may dimension local variables of any type within the fieldname_render() function. However, if you want to create variables that have scope beyond the current grid cell, you must define it as an element of either the:

  • args pointer (valid for the grid page)

  • session pointer (valid for the session)

For example, this code is able to create a running total of the Extension field by adding values to session.rt.

if eval_valid(" session.rt") = .f. then  
    session.rt = Data.EXTENSION  
else  
    session.rt = session.rt + Data.EXTENSION   
end if

Define Xbasic For Custom Control Dialog

As the example above on creating a custom control demonstrates, getting to the Define Xbasic for Custom Control Dialog is fairly straightforward. After defining a grid table you go to the Fields page and add some fields to the Selected: fields list. You then go to the Field Properties list and change the Control type of the selected field control to Custom . From there you go to the Custom Controls Properties and click the button next to the Definition property.

When the Define Xbasic for Custom Control dialog loads, you will see some code that lays out a default function for you based on whatever field you selected as your custom control. This is only a framework, you will have to create the code that determines what you want your custom control to do. There are, however, some tools to help make this task easier. The Insert button at the top of the dialog can add Row values, Grid Data Values, Summary values, and System variables to your function's code through a series of point and click events. To insert Current Row Values , i.e. the value of any field in the Current Row, click Insert select Data and then choose the FieldName that you want to add to your code . To insert Grid Data Values , or the value of any of the fields on any of the rows of the current grid page, click Insert > Args > Data > RowNumber > FieldName . If the grid has any Summary values , then you can insert any of them by clicking Insert, selecting Args, then Summary, FieldName, and finally the SummaryType you want. Finally, The Define Xbasic for Custom Control dialog provides several System variables that you can use in your calculations by clicking Insert > Args > Info > System variable .

Current Row Values:

images/01_custom7.png
Insert > Data > FieldName

Grid Data Values:

images/01_custom8.png
Insert > Args > Data > RowNumber > FieldName

Summary Values:

images/01_custom9.png
Insert > Args > Summary > FieldName > SummaryType

System Variables

Available System Variables:

Name
Description
Args.Info.TotalPages

Numeric. The number of grid pages required to display all records.

Args.Info.CurrentPage

Numeric. The current grid page.

Args.Info.TotalRecords

Numeric. The number of records returned by the current table query.

Args.Info.RecordsPerPage

Numeric. The maximum number of records to display in a grid page.

Args.Info.Database_type

Character. The type of database.

Args.Info.HasEmptyRows

Logical. Does the current grid page have an empty row?

Args.FirstEmptyRow

Numeric. The row number of the first empty row.

Args.IsNewRecord

Logical. Are you processing a newly input record?

Args.RowNumber

Numeric. The current row number.

Args.Summary

Pointer. The values of various summary calculations.

images/01_custom10.png
Insert > Args > Info > System variable

Custom Controls on an Editable Grid

This topic illustrates several useful techniques when placing a custom control on an editable grid. The grid shown below displays the Extension field is in a custom control.

images/WP_Custom_Controls_on_Editable_Grid.gif

The code that creates the control is as follows. First, the standard boilerplate code.

function EXTENSION_render as c (data as p, args as p, PageVars as p)
with PageVars
on error goto EXTENSION_XbasicError

You cannot define the HTML for the new record rows in an editable grid. as a result, the first thing to do is test whether you are creating a new record. If Args.IsNewRecord is TRUE, then exit.

if Args.IsNewRecord = .t. then   
exit function
end if

This example simply changes the background color of the cell if the value of the Extension field is greater than 100. What you have to do here is define code that can be placed into the cell of a table. The grid is, after all, just a table. Items that you can place into a table cell include:

  • formatted HTML text -

  • image -

  • table -

  • VariableContent- any legal HTML code

In this case the cell will contain a table. The cells will have different background colors ( bgcolor="#00FF00"and bgcolor="#FF0000") and right alignment ( align="right"). The alignment of the grid column has no effect inside this table, so, if you want right alignment, you need to explicitly define it. The table will be wide enough to contain any expected content ( width="80px"). The advantage of explicitly defining the table width is that it avoids having cell contents vary in width according to the data they contain; the behavior you see with label controls.

if Data.EXTENSION > 100 then  
EXTENSION_render = <%html%
<table width="80px"><tr><td bgcolor="#00FF00" align="right"><strong>disp</strong></td></tr></table>
%html%
else 
EXTENSION_render = <%html%
<table width="80px"><tr><td bgcolor="#FF0000" align="right"><strong>disp</strong></td></tr></table>
%html%
end if
disp = alltrim( str (Data.EXTENSION,250,2,"$(") )
EXTENSION_render = stritran(EXTENSION_render, " disp", disp)
end
EXTENSION_XbasicError
EXTENSION_render = "Error"
end with
end function

To simplify the formatting of the Extension amount, the HTML contains the string " disp", which the script replaces with alltrim( str( Data.EXTENSION,250,2,"$(") ).

Advanced use of custom controls in a grid

One of the control types available in the Grid is the custom control. This allows you to define an arbitrary Xbasic function to compute the HTML and Javascript for the control. In the example below, the grid is showing invoices. One of the cells in the grid shows the line items for the invoice. This could have been done using an embedded grid component, but the custom control is a lighter weight, faster solution.

See Also