As in Delphi's libraries, a significant portion of IntraWeb's available controls
Here is the predefined TUserSession class (and its constructor) for an IntraWeb application with a data module:
type TUserSession = class (TComponent) public DataModule1: TDataModule1; constructor Create(AOwner: TComponent); override; end; constructor TUserSession.Create(AOwner: TComponent); begin inherited; Datamodule1 := TDatamodule1.Create(AOwner); end;
The unit of the data module doesn't have a global variable for it; if it did, all the data would be shared among all sessions, with severe risks of trouble in case of concurrent
function DataModule1: TDataModule1; begin Result := TUserSession(RWebApplication.Data).Datamodule1; end;
This means you can write code like the following:
DataModule1.SimpleDataSet1
But instead of accessing a global data module, you are using the current session's data module.
In the first sample program featuring database data, called IWScrollData, I've added to the data module a SimpleDataSet component and to the main form an IWDBGrid component with the following configuration:
object IWDBGrid1: TIWDBGrid Anchors = [akLeft, akTop, akRight, akBottom] BorderSize = 1CellPadding = 0 CellSpacing = 0 Lines = tlRows UseFrame = False DataSource = DataSource1 FromStart = False Options = [dgShowTitles] RowAlternateColor = clSilver RowLimit = 10 RowCurrentColor = clTeal end
The most important settings are the removal of a frame hosting the control with its own scroll bars (the
UseFrame
property), the fact that the data is displayed form the current data set position (the
FromStart
property), and the number of rows to be displayed in the browser (the
RowLimit
property). In the
Figure 21.7:
The data-aware grid of the IWScrollData example
The program opens the data set when the form is created, using the data set hooked to the current data source:
procedure TformMain.IWAppFormCreate(Sender: TObject); begin DataSource1.DataSet.Open ; end;
The example's relevant code is in the button code, which can be used to move through the data showing the following page or returning to the previous one. Here is the code for one of the two
procedure TformMain.btnNextClick(Sender: TObject); var i: Integer; begin nPos := nPos + 10; if nPos > DataSource1.DataSet.RecordCount - 10 then nPos := DataSource1.DataSet.RecordCount - 10; DataSource1.DataSet.First; for i := 0 to nPos do DataSource1.DataSet.Next; end;
The grid of the IWScrollData example shows a single page of a table's data;
The example customizes the grid in a second powerful way: It sets the
Figure 21.8:
The main form of the IWGridDemo example uses a framed grid with hyperlinks to the secondary form.
Listing 21.1 shows a summary of the grid's key properties. Notice in particular the last name column, which as mentioned has a linked field (which turns the
procedure TGridForm.IWDBGrid1Columns1Click(ASender: TObject; const AValue: String); begin with TRecordForm.Create (WebApplication) do begin StartID := AValue; Show; end; end;
Listing 21.1: Properties of the IWDBGrid in the IWGridDemo Example
|
|
object IWDBGrid1: TIWDBGrid Anchors = [akLeft, akTop, akRight, akBottom] UseFrame = True UseWidth = True Columns = < item Alignment = taLeftJustifyBGColor = clNone DoSubmitValidation = True Font.Color = clNone Font.Enabled = True Font.Size = 10 Font.Style = [] Header = False Height = '0' VAlign = vaMiddle Visible = True Width = '0' Wrap = False BlobCharLimit = 0 CompareHighlight = hcNone DataField = 'FIRST_NAME' Title.Alignment = taCenter Title.BGColor = clNone Title.DoSubmitValidation = True Title.Font.Color = clNone Title.Font.Enabled = True Title.Font.Size = 10 Title.Font.Style = [] Title.Header = False Title.Height = '0' Title.Text = 'FIRST_NAME' Title.VAlign = vaMiddle Title.Visible = True Title.Width = '0' Title.Wrap = False end item DataField = 'LAST_NAME' LinkField = 'EMP_NO' OnClick = IWDBGrid1Columns1Click end item DataField = 'HIRE_DATE' end item DataField = 'JOB_CODE' end item DataField = 'JOB_COUNTRY' end item DataField = 'JOB_GRADE' end item DataField = 'PHONE_EXT' end > DataSource = DataSource1 Options = [dgShowTitles] end
|
|
By setting the second form's StartID property, you can locate the proper record:
procedure TRecordForm.SetStartID( const Value: string); begin FStartID := Value; DataSource1.DataSet.Locate( 'EMP_NO' , Value, []); end;
| Tip |
The IWDBGrid columns have also an
OnTitleClick
event you can handle to
|
The secondary form is hooked to the same data module as the main form. So, after the database data is updated, you can see it in the grid (but the updates are kept only in memory, because the program doesn't have an ApplyUpdates call). The secondary form uses a few edit controls and a navigator, provided by IntraWeb. You can see this form at run time in Figure 21.9.
Figure 21.9:
The secondary form of the IWGridDemo example allows a user to edit the data and navigate through records.
Regardless of how you use it, the IWDBGrid component produces HTML with the database data embedded in the cells, but it cannot work on the data on the client side. A different component (or a set of IntraWeb
| Note |
This architecture is similar to Delphi's native Internet Express architecture, which I'll cover in Chapter 22 ("Using XML Technologies"). |
You can use several IntraWeb components for a client-side application, but these are the most important ones:
IWClientSideDataSet An in-memory dataset you define by setting the ColumnNames and Data properties within your program's code. In future updates, you will be able to edit client-side data, sort it, filter it, define master-detail structures, and more.
IWClientSideDataSetDBLink A data provider you can connect to any Delphi dataset, connecting it with the DataSource property.
IWDynGrid A dynamic grid component connected to one of the two previous components using the Data property. This component moves all the data to the browser and can
operate on it on the client via JavaScript.
There are other client-side components in IntraWeb, such as IWCSLabel, IWCSNavigator, and IWDynamicChart (which works only with Internet Explorer). As an example of using this approach, I've built the IWClientGrid example. The program has little code, because there is a lot available in the components being used. Here are the
object formMain: TformMain SupportedBrowsers = [brIE, brNetscape6] OnCreate = IWAppFormCreate object IWDynGrid1: TIWDynGrid Align = alClient Data = IWClientSideDatasetDBLink1 end object DataSource1: TDataSource Left = 72 Top = 88 end object IWClientSideDatasetDBLink1: TIWClientSideDatasetDBLink DataSource = DataSource1 end end
The dataset from the data module is hooked to the DataSource when the form is created. The resulting grid, shown in Figure 21.10, allows you to sort the data on any cell (using the small arrow after the column title) and filter the data displayed on one of the field's possible values. In the figure, for example, you can sort the employee data by last name and filter it by country and job grade.
Figure 21.10:
The grid of the IWClientGrid example supports custom sorting and filtering without re-fetching the data on the web server.
This functionality is possible because the data is moved to the browser within the JavaScript code. Here is a snippet of one of the scripts embedded in the page's HTML:
< script language ="Javascript1.2"> var IWDYNGRID1_TitleCaptions = [ "EMP_NO","FIRST_NAME","LAST_NAME","PHONE_EXT", "DEPT_NO","JOB_CODE","JOB_GRADE","JOB_COUNTRY" ]; var IWDYNGRID1_CellValues = new Array(); IWDYNGRID1_CellValues[0] = [2, 'Robert','Nelson','332','600','VP' ,2, 'USA' ]; IWDYNGRID1_CellValues[1] = [4, 'Bruce','Young','233','621','Eng' ,2, 'USA' ]; IWDYNGRID1_CellValues[2] = [5, 'Kim','Lambert','22','130','Eng' ,2, 'USA' ]; IWDYNGRID1_CellValues[3] = [8, 'Leslie','Johnson','410','180','Mktg' ,3, 'USA' ]; IWDYNGRID1_CellValues[4] = [9, 'Phil','Forest','229','622','Mngr' ,3, 'USA' ];
| Note |
The reason to use this JavaScript-based approach, instead of an XML-based approach featured by other similar technologies, is that only Internet Explorer has support for XML data islands . Mozilla and Netscape lack this feature and have limited XML support in general. Mimicking it in JavaScript, as Internet Explorer does, is very expensive at run time. |