Adding Calculated Fields to a List
Description
Calculated fields can be added to a List control using Custom Controls and Computed columns.
Discussion
Defining Calculated Fields Server-Side
Custom controls can be added to the List control. Similar to Custom controls in the Grid Component, the HTML rendered for a Custom control in the List is defined using Xbasic.
To add a Custom control to the List, click the Add Item button on the Fields tab and select "Custom control":
After the Custom control has been added, the HTML to show for the control needs to be defined. This is done using the Definition property for the Custom Control.
The Define Xbasic for Custom Control dialog is an Xbasic editor used to define the HTML rendered for the Custom control. The values for fields in the List control can be accessed in the ds argument passed to the function that computes the HTML for the control. For example, the Xbasic below shows the definition for a Custom Control that calculates the subtotal for an individual line item for an Order based on the value of the UnitPrice and Quantity fields:
function xbasicSubtotal_render as c (ds as p, tmpl as p) 'Specify the Xbasic that returns the HTML for this control. 'This function must return xbasicSubtotal_render, which should 'contain the HTML that will be displayed. 'The 'ds' argument that is passed in contains the current 'values for each of the fields in the current List row. 'For example: ds.data("Firstname") '------------------------------------------------------------------- on error goto xbasicSubtotal_xbasicError ' Get the price and quantity ordered dim unitPrice as N = convert_type(ds.data("UnitPrice"),"N") dim quantity as N = convert_type(ds.data("Quantity"),"N") ' Calculate the subtotal dim subtotal as N subtotal = unitPrice * quantity 'Format as a dollar amount dim html as c html = alltrim(str(subtotal,250,2,"$(")) 'Return the HTML to be displayed xbasicSubtotal_render = html end xbasicSubtotal_xbasicError: xbasicSubtotal_render = "Error in custom control xbasic: " + error_text_get() end function
The resulting List with the custom control is shown below:
Defining Calculated Fields Client-Side
Client-side calculated fields can be added to the List as Computed columns. Computed columns are defined using JavaScript and are calculated on the client (i.e. in the browser.
When defining Computed columns,
- Any number of client-side computed columns can be defined.
- Computed columns are defined using JavaScript.
- Field definitions are defined using the format data.CALCULATED_FIELD_NAME = Expression; where CALCULATED_FIELD_NAME is the name of the calculated field and Expression; is a JavaScript expression that computes the field's value.
- References to existing fields must use the data. prefix (all lower case.)
- Field names a case-sensitive.
- Field definitions must end with a semi-colon.
- The JavaScript definition can reference index, a zero-based row number for the current record being rendered.
- Anonymous functions can be used to build complex expressions (see examples below.)
For example, the code below defines three computed columns: subTotal, discountAmount and Total. The three columns are computed using fields from the List's data source:
data.subTotal = ($u.s.toNum(data.Quantity) * $u.s.toNum(data.UnitPrice)); data.discountAmount = $u.s.toNum(data.Quantity) * $u.s.toNum(data.Discount) * $u.s.toNum(data.UnitPrice); data.Total = ($u.s.toNum(data.Quantity) * ($u.s.toNum(data.UnitPrice) - $u.s.toNum(data.Discount) * $u.s.toNum(data.UnitPrice)));
Computed columns can reference other computed columns as long as the referenced computed columns were defined first. For example, discountAmount can reference subTotal because subTotal is defined first in the Computed column definition dialog. Because Computed columns can used in this fashion, the above example can be rewritten to reference existing Computed columns as follows:
data.subTotal = ($u.s.toNum(data.Quantity) * $u.s.toNum(data.UnitPrice)); data.discountAmount = data.subTotal * $u.s.toNum(data.Discount); data.Total = data.subTotal - data.discountAmount;
Computed columns can also use anonymous functions. Anonymous functions can make it easier to define fields that require complex calculations since multiple lines can be used to define the calculation. An anonymous function is a JavaScript function that is immediately evaluated. This is accomplished by adding parentheses at the end of the function definition to call the function. EG:
data.CALCULATED_FIELD_NAME = function(data,index) { var fieldValue; // JavaScript to compute field value return fieldValue; }(data,index);
To use the values of the data and index variables in the field calculation, they are passed to the anonymous function as parameters. At the end of the function definition, the anonymous function is called by adding (data,index); after the closing curly brace.
In the example below, the subTotal, discountAmount, and Total columns have been rewritten using anonymous functions:
data.subTotal = function (data,index) { var price = $u.s.toNum(data.UnitPrice); var qty = $u.s.toNum(data.Quantity); return price * qty; }(data,index); data.discountAmount = function (data,index) { var subtotal = data.subTotal; var discount = $u.s.toNum(data.Discount) return subtotal * discount; }(data,index); data.Total = function (data,index) { var subtotal = data.subTotal; var discountAmount = data.discountAmount; return subtotal - discountAmount; }(data,index);
The image below shows the List control rendered with the three Computed columns: subTotal, discountAmount and Total
Videos
To learn more about Custom columns and Computed columns in a List control, watch the videos below.
Creating Custom Controls in a List Control
Just as the Grid Component allows you to define a "Custom Control" control type, the List allows you to define "Custom Controls" to compute values to be shown in the List.
The "custom control" is defined by an Xbasic function that will return the HTML to show in the List. The Xbasic function takes as its input an object that allows the function to see all of the data in the current row of the List.
In this example, we define a very simple Custom Control field for the List that combines data from the "firstname" and "lastname" columns in the List.
Creating Computed Columns for a List Control
The List control allows you to define computed columns. A computed column displays a value that is computed from other data in the current row. Computed columns can be calculated server-side (in which case Xbasic functions can be used in the calculation), or they can be computed client-side (in which case Javascript functions can be used in the calculation).
To define a server-side computed column, you would actually define a "Custom Control" as shown in the previous video.
In this video, we show how a client-side computed column can be added to the List.