{
$Id: header,v 1.1 2000/07/13 06:33:45 michael Exp $
This file is part of the Free Component Library (FCL)
Copyright (c) 1999-2000 by the Free Pascal development team
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
unit fpdatasetform;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, fphtml, htmldefs, htmlwriter, db, htmlelements;
type
THTMLDatasetFormProducer = class;
TFormFieldItem = class;
TFormButtonItem = class;
TFieldCellEvent = procedure (Sender:THTMLDatasetFormProducer; FieldDef:TFormFieldItem;
IsLabel:boolean; Cell : THTMLCustomelement) of object;
TButtonEvent = procedure (Sender:THTMLDatasetFormProducer; ButtonDef:TFormButtonItem;
Button : THTML_button) of object;
TProducerEvent = procedure (Sender:THTMLDatasetFormProducer; FieldDef:TFormFieldItem;
Producer:THTMLContentProducer) of object;
THTMLElementEvent = procedure (Sender:THTMLDatasetFormProducer; element : THTMLCustomElement) of object;
TFieldCheckEvent = procedure (aField:TField; var check:boolean) of object;
TFormInputType = (fittext,fitpassword,fitcheckbox,fitradio,fitfile,fithidden,
fitproducer,fittextarea,fitrecordselection);
{ TTablePosition }
TTablePosition = class (TPersistent)
private
FAlignHor: THTMLalign;
FAlignVer: THTMLvalign;
FColSpan: integer;
FLeft: integer;
FRowSpan: integer;
FTop: integer;
protected
procedure AssignTo(Dest: TPersistent); override;
public
constructor create;
published
property Left : integer read FLeft write FLeft;
property Top : integer read FTop write FTop;
property ColSpan : integer read FColSpan write FColSpan default 1;
property RowSpan : integer read FRowSpan write FRowSpan default 1;
property AlignVertical : THTMLvalign read FAlignVer write FAlignVer default vaEmpty;
property AlignHorizontal : THTMLalign read FAlignHor write FAlignHor default alEmpty;
end;
{ TFormFieldItem }
TFormFieldItem = class (TCollectionItem)
private
FAction: string;
FField: TField;
FFieldName: string;
FInputType: TFormInputType;
FLabelCaption: string;
FLabelAbove : boolean;
FLabelPos: TTablePosition;
FProducer: THTMLContentProducer;
FValuePos: TTablePosition;
procedure SetLabelPos(const AValue: TTablePosition);
procedure SetValuePos(const AValue: TTablePosition);
protected
procedure AssignTo(Dest: TPersistent); override;
public
constructor Create(ACollection: TCollection); override;
destructor Destroy; override;
property Field : TField read FField;
published
property Fieldname : string read FFieldName write FFieldname;
// the field to show/edit
property LabelCaption : string read FLabelCaption write FLabelCaption;
// the text to show for the control
property LabelPos : TTablePosition read FLabelPos write SetLabelPos;
// place of the label in the table-grid
property LabelAbove : boolean read FLabelAbove write FLabelAbove default false;
// if not SeparateLabel then place a
between label and edit/value
property ValuePos : TTablePosition read FValuePos write SetValuePos;
// place of the value in the table-grid
{ only when editting: }
property InputType : TFormInputType read FInputType write FInputType default fittext;
// the type of form control to use
property Producer : THTMLContentProducer read FProducer write FProducer;
// the producer to include when generating the value
{ only when showing: }
property Action : string read FAction write FAction;
// the link to include in the value
end;
{ TFormFieldCollection }
TFormFieldCollection = class (TCollection)
private
function GetItem(index : integer): TFormFieldItem;
procedure SetItem(index : integer; const AValue: TFormFieldItem);
public
constructor create;
function AddField (afieldname, acaption : string) : TFormFieldItem;
property Items [index : integer] : TFormFieldItem read GetItem write SetItem;
end;
TFormButtonType = (fbtSubmit, fbtReset, fbtPushbutton);
TImagePlace = (ipOnly, ipBefore, ipAfter, ipUnder, ipAbove);
{ TFormButtonItem }
TFormButtonItem = class (TCollectionItem)
private
FButtonType: TFormButtonType;
FCaption: string;
FImage: string;
FName: string;
FImagePlace: TImagePlace;
FValue: string;
protected
procedure AssignTo(Dest: TPersistent); override;
public
constructor create (ACollection : TCollection); override;
published
property Name : string read FName write FName;
property Value : string read FValue write FValue;
property Caption : string read FCaption write FCaption;
// Text on button, or as hint with image
property Image : string read FImage write FImage;
// Image to show on the button
property ImagePlace : TImagePlace read FImagePlace write FImagePlace;
// where the image is placed regarding from the caption.
// if ipOnly; the caption is placed in the alternate text of the image (hint)
property ButtonType : TFormButtonType read FButtonType write FButtonType default fbtPushButton;
// Where the button is used for
end;
{ TFormButtonCollection }
TFormButtonCollection = class (TCollection)
private
function GetItem(index : integer): TFormButtonItem;
procedure SetItem(index : integer; const AValue: TFormButtonItem);
public
constructor create;
function AddButton (aname, avalue, acaption : string) : TFormButtonItem;
function AddButton (aname, acaption : string) : TFormButtonItem;
function AddButton (acaption : string) : TFormButtonItem;
property Items [index : integer] : TFormButtonItem read GetItem write SetItem;
end;
TCellType = (ctEmpty, ctInput, ctLabel, ctProducer, ctSpanned);
{ TTableCell }
TTableCell = class (TCollectionItem)
private
FAlignHor: THTMLalign;
FAlignVer: THTMLvalign;
FCaption: string;
FCellType: TCellType;
FChecked: boolean;
FColSpan: integer;
FEndRow: boolean;
FFormField: TFormFieldItem;
FIncludeBreak: boolean;
FInputType: TFormInputType;
FIsLabel: boolean;
FLink: string;
FMaxLength: integer;
FName: string;
FProducer: THTMLContentProducer;
FRowSpan: integer;
FSize: integer;
FSpanned: boolean;
FValue: string;
public
function WriteContent (aWriter : THTMLWriter) : THTMLCustomElement;
function WriteHeader (aWriter : THTMLWriter) : THTMLCustomElement;
property FormField : TFormFieldItem read FFormField write FFormField;
// field definition that origintated this cell
property IsLabel : boolean read FIsLabel write FIsLabel;
// Label or Value ?
property Caption : string read FCaption write FCaption;
// label to place with the edit/value if not separateLabel
property IncludeBreak : boolean read FIncludeBreak write FIncludeBreak;
// place
between label and edit/value if label is included in cell
property CellType : TCellType read FCellType write FCellType;
{ Cell properties: }
property ColSpan : integer read FColSpan write FColSpan;
property RowSpan : integer read FRowSpan write FRowSpan;
property AlignVertical : THTMLvalign read FAlignVer write FAlignVer default vaEmpty;
property AlignHorizontal : THTMLalign read FAlignHor write FAlignHor default alEmpty;
property Value : string read FValue write FValue;
// Contains the text for labels, or the value for input, or unused for producer and empty
{ properties to correctly generate the rows and the table ends }
property EndOfRow : boolean read FEndRow write FEndRow;
property SpannedOut : boolean read FSpanned write FSpanned;
{ only for input: }
property Name : string read FName write FName;
// name of the control
property InputType : TFormInputType read FInputType write FInputType;
// type of the input element
property Size : integer read FSize write FSize;
// size of text input element
property MaxLength : integer read FMaxLength write FMaxLength;
// MaxLength of text input element
property Checked : boolean read FChecked write FChecked;
// checked or not for radio,checkbox
{ only for labels: }
property Link : string read FLink write FLink;
// link to place around the text
{ only for producers: }
property Producer : THTMLContentProducer read FProducer write FProducer;
// producer to include
end;
{ TTableDef }
TTableDef = class (TCollection)
private
fCols, fRows : integer;
function GetCell(x, y : integer): TTableCell;
function GetItem(index: integer): TTableCell;
public
Constructor Create (acols, arows : integer);
function CopyTablePosition (position : TTablePosition) : TTableCell;
property Cells [x,y : integer] : TTableCell read GetCell; default;
property items [index:integer] : TTableCell read GetItem;
end;
TButtonVerPosition = (bvpTop, bvpBottom);
TButtonVerPositionSet = set of TButtonVerPosition;
TButtonHorPosition = (bhpLeft, bhpCenter, bhpJustify, bhpRight);
TFormMethod = (fmGet, fmPost);
{ THTMLDatasetFormProducer }
THTMLDatasetFormProducer = class (THTMLContentProducer)
private
FOnInitializeProducer : TProducerEvent;
FOnFieldChecked : TFieldCheckEvent;
FAfterTBodyCreate,
FAfterTableCreate : THTMLElementEvent;
FAfterButtonCreate: TButtonEvent;
FAfterCellCreate: TFieldCellEvent;
Fbuttonrow: TFormButtonCollection;
FButtonsHor: TButtonHorPosition;
FButtonsVer: TButtonVerPositionSet;
FControls: TFormFieldCollection;
FDatasource: TDatasource;
FFormAction: string;
FFormMethod: TFormMethod;
FIncludeHeader: boolean;
FSeparateLabel: boolean;
FTableCols: integer;
FTableRows: integer;
FTableDef : TTableDef;
FPage: integer;
FRecordsPerPage: integer;
procedure SetIncludeHeader(const AValue: boolean);
procedure SetSeparateLabel(const AValue: boolean);
procedure WriteButtons (aWriter : THTMLWriter);
procedure WriteTableDef (aWriter : THTMLWriter);
procedure WriteHeaderTableDef (aWriter : THTMLWriter);
procedure CorrectCellSpans;
procedure SearchControlFields;
protected
function WriteContent (aWriter : THTMLWriter) : THTMLCustomElement; override;
procedure FillTableDef (IsHeader:boolean); virtual;
procedure ControlToTableDef (aControldef : TFormFieldItem; IsHeader:boolean); virtual; abstract;
function StartForm (aWriter : THTMLWriter) : THTMLCustomElement; virtual;
procedure EndForm (aWriter : THTMLWriter); virtual;
property TableDef : TTableDef read FTableDef;
function SingleRecord : boolean; dynamic;
// generate form for 1 record or for the selected pages
property RecordsPerPage : integer read FRecordsPerPage write FRecordsPerPage default 20;
// number of records to show
property Page : integer read FPage write FPage default -1;
// page to show. -1 shows all records. zero based
property IncludeHeader : boolean read FIncludeHeader write SetIncludeHeader;
// create a header cell for each control
public
constructor create (aOwner : TComponent); override;
destructor destroy; override;
published
property FormAction : string read FFormAction write FFormAction;
// action of the form (link), if not given; don't use a form element
property FormMethod : TFormMethod read FFormMethod write FFormMethod;
// method of the form, Get or Post
Property DataSource : TDataSource read FDataSource write FDataSource;
// the data to use
property Controls : TFormFieldCollection read FControls write FControls;
// configuration of the fields and how to generate the html
property SeparateLabel : boolean read FSeparateLabel write SetSeparateLabel;
// place label and value/edit in same table cell
property buttonrow : TFormButtonCollection read Fbuttonrow write Fbuttonrow;
// buttons to place in the form
property TableCols : integer read FTableCols write FTableCols default 2;
// number columns in the grid for 1 record
property TableRows : integer read FTableRows write FTableRows;
// number of rows in the grid for 1 record
property ButtonsHorizontal : TButtonHorPosition read FButtonsHor write FButtonsHor default bhpleft;
// where to place the buttons horizontally
property ButtonsVertical : TButtonVerPositionSet read FButtonsVer write FButtonsVer default [bvpTop,bvpBottom];
// where to place the buttons vertically
property OnInitializeProducer : TProducerEvent read FOnInitializeProducer write FOnInitializeProducer;
// Called before the producer creates it's HTML code
property AfterCellCreate : TFieldCellEvent read FAfterCellCreate write FAfterCellCreate;
// Called after each creation of a cell in the table makeup in the form
property AfterButtonCreate : TButtonEvent read FAfterButtonCreate write FAfterButtonCreate;
// Called after each creation of a button
property AfterTableCreate : THTMLElementEvent read FAfterTableCreate write FAfterTableCreate;
// Called after the creation of the table
property AfterTBodyCreate : THTMLElementEvent read FAfterTBodyCreate write FAfterTBodyCreate;
// Called after finishing the tbody of each record
property OnFieldChecked : TFieldCheckEvent read FOnFieldChecked write FOnFieldChecked;
// return if the field is true or false if the false string differs from '0','false','-'
end;
{ THTMLDatasetFormEditProducer }
THTMLDatasetFormEditProducer = class (THTMLDatasetFormProducer)
procedure ControlToTableDef (aControldef : TFormFieldItem; IsHeader:boolean); override;
end;
{ THTMLDatasetFormShowProducer }
THTMLDatasetFormShowProducer = class (THTMLDatasetFormProducer)
protected
procedure ControlToTableDef (aControldef : TFormFieldItem; IsHeader:boolean); override;
end;
{ THTMLDatasetFormGridProducer }
THTMLDatasetFormGridProducer = class (THTMLDatasetFormProducer)
protected
procedure ControlToTableDef (aControldef : TFormFieldItem; IsHeader:boolean); override;
function SingleRecord : boolean; override;
public
constructor Create (aOwner : TComponent); override;
published
property RecordsPerPage;
property Page;
property IncludeHeader;
end;
implementation
{ TTableDef }
function TTableDef.GetItem(index: integer): TTableCell;
begin
result := TTableCell (inherited items[index]);
end;
function TTableDef.GetCell(x, y : integer): TTableCell;
var r : integer;
begin
r := x + (y * fcols);
result := getItem (r);
end;
constructor TTableDef.Create(acols, arows: integer);
var r, t : integer;
begin
inherited create (TTableCell);
fRows := aRows;
fCols := aCols;
for r := 1 to aRows do
begin
for t := 1 to aCols-1 do
Add;
TTableCell(Add).EndOfRow := True;
end;
end;
function TTableDef.CopyTablePosition(position: TTablePosition): TTableCell;
begin
result := Cells[position.left,position.top];
with result do
begin
AlignHorizontal := position.AlignHorizontal;
AlignVertical := position.FAlignVer;
ColSpan := position.ColSpan;
RowSpan := position.RowSpan;
end;
end;
{ TTablePosition }
procedure TTablePosition.AssignTo(Dest: TPersistent);
begin
inherited AssignTo(Dest);
if dest is TTablePosition then
with TTablePosition(Dest) do
begin
FTop := self.FTop;
FLeft := self.FLeft;
FColSpan := self.FColSpan;
FRowSpan := self.FRowSpan;
FAlignVer := self.FAlignVer;
FalignHor := self.FAlignHor;
end;
end;
constructor TTablePosition.create;
begin
inherited create;
FColSpan := 1;
FRowSpan := 1;
FAlignVer := vaEmpty;
FAlignHor := alEmpty;
end;
{ TFormFieldItem }
procedure TFormFieldItem.SetLabelPos(const AValue: TTablePosition);
begin
FLabelPos.assign(AValue);
end;
procedure TFormFieldItem.SetValuePos(const AValue: TTablePosition);
begin
FValuePos.assign(AValue);
end;
procedure TFormFieldItem.AssignTo(Dest: TPersistent);
begin
inherited AssignTo(Dest);
if dest is TFormFieldItem then
with TFormFIeldItem(Dest) do
begin
FAction := self.FAction;
FFieldName := self.FFieldName;
FInputType := self.FInputType;
FLabelCaption := self.FLabelCaption;
FLabelPos.assign (self.FLabelPos);
FProducer := self.FProducer;
FValuePos.assign(self.FValuePos);
end;
end;
constructor TFormFieldItem.Create(ACollection: TCollection);
begin
inherited Create(ACollection);
FLabelPos := TTablePosition.Create;
FValuePos := TTablePosition.Create;
end;
destructor TFormFieldItem.Destroy;
begin
FLabelPos.Free;
FValuePos.Free;
inherited Destroy;
end;
{ TFormFieldCollection }
function TFormFieldCollection.GetItem(index : integer): TFormFieldItem;
begin
result := TFormFieldItem(inherited items[index]);
end;
procedure TFormFieldCollection.SetItem(index : integer;
const AValue: TFormFieldItem);
begin
inherited items[index] := AValue;
end;
constructor TFormFieldCollection.create;
begin
inherited create (TFormFieldItem);
end;
function TFormFieldCollection.AddField(afieldname, acaption: string): TFormFieldItem;
begin
result := TFormFieldItem (Add);
result.fieldname := afieldname;
result.labelcaption := acaption;
end;
{ TFormButtonItem }
procedure TFormButtonItem.AssignTo(Dest: TPersistent);
begin
inherited AssignTo(Dest);
if dest is TFormButtonItem then
with TFormButtonItem(Dest) do
begin
FButtonType := self.FButtonType;
FCaption := self.FCaption;
FImage := self.FImage;
FImagePlace := self.FImagePlace;
FName := self.FName;
FValue := self.FValue;
end;
end;
constructor TFormButtonItem.create(ACollection: TCollection);
begin
inherited create(ACollection);
ButtonType := fbtPushButton;
end;
{ TFormButtonCollection }
function TFormButtonCollection.GetItem(index: integer): TFormButtonItem;
begin
result := TFormButtonItem(inherited items[index]);
end;
procedure TFormButtonCollection.SetItem(index: integer;
const AValue: TFormButtonItem);
begin
inherited items[index] := AValue;
end;
constructor TFormButtonCollection.create;
begin
inherited create (TFormButtonItem);
end;
function TFormButtonCollection.AddButton(aname, avalue, acaption: string): TFormButtonItem;
begin
result := TFormButtonItem(Add);
with result do
begin
name := aname;
value := avalue;
caption := acaption;
end;
end;
function TFormButtonCollection.AddButton(aname, acaption: string): TFormButtonItem;
begin
result := AddButton (aName, aCaption, acaption);
end;
function TFormButtonCollection.AddButton(acaption: string): TFormButtonItem;
begin
result := AddButton (acaption, acaption, acaption);
end;
{ THTMLDatasetFormProducer }
procedure THTMLDatasetFormProducer.WriteButtons(aWriter: THTMLWriter);
procedure WriteButton (aButton : TFormButtonItem);
const ButtonTypes : array[TFormButtontype] of THTMLbuttontype = (btsubmit,btreset,btbutton);
var b : THTML_Button;
begin
with aWriter do
begin
b := Startbutton;
with b do
begin
Name := aButton.name;
Value := aButton.value;
TheType := ButtonTypes[aButton.ButtonType];
if aButton.Image = '' then
Text (aButton.Caption)
else
begin
if aButton.ImagePlace in [ipAfter, ipUnder] then
begin
Text (aButton.Caption);
if aButton.ImagePlace = ipUnder then
linebreak;
end;
with image do
begin
src := aButton.image;
if aButton.ImagePlace = ipOnly then
alt := aButton.Caption;
end;
if aButton.ImagePlace in [ipBefore, ipAbove] then
begin
if aButton.ImagePlace = ipAbove then
linebreak;
Text (aButton.Caption);
end;
end;
if assigned (FAfterButtonCreate) then
FAfterButtonCreate (self, aButton, b);
Endbutton;
end;
end;
end;
const ButHorAlign : array[TButtonHorPosition] of THTMLalign = (alleft,alcenter,aljustify,alright);
var r : integer;
begin
with aWriter do
begin
StartTableRow;
with StartTableCell do
begin
ColSpan := inttostr(FTableCols);
align := ButHorAlign[ButtonsHorizontal];
end;
for r := 0 to buttonrow.count-1 do
WriteButton (buttonrow.Items[r]);
EndTableCell;
EndTableRow;
end;
end;
procedure THTMLDatasetFormProducer.SetSeparateLabel(const AValue: boolean);
begin
if AValue <> FSeparateLabel then
begin
FSeparateLabel := AValue;
if AValue then
FIncludeHeader := false;
end;
end;
procedure THTMLDatasetFormProducer.SetIncludeHeader(const AValue: boolean);
begin
if FIncludeHeader <> AValue then
begin
FIncludeHeader := AValue;
if AValue then
SeparateLabel := false;
end;
end;
procedure THTMLDatasetFormProducer.WriteTableDef(aWriter: THTMLWriter);
var r : integer;
c : THTMLCustomelement;
begin
c := aWriter.Starttablebody;
if assigned (FAfterTBodyCreate) then
FAfterTBodyCreate (self, c);
aWriter.StartTableRow;
with tabledef do
begin
for r := 0 to count-2 do
with TTableCell (Items[r]) do
begin
if CellType <> ctSpanned then
begin
if (CellType = ctProducer) and assigned (FOnInitializeProducer) then
FOnInitializeProducer (self, FFormField, Producer);
c := WriteContent(aWriter);
if assigned (FAfterCellCreate) then
FAfterCellCreate(self, Items[r].FormField, IsLabel, c);
end;
if EndOfRow then
begin
aWriter.EndTableRow;
aWriter.StartTableRow;
end;
end;
TTableCell(Items[Count-1]).WriteContent(aWriter);
end;
aWriter.EndTableRow;
aWriter.Endtablebody;
end;
procedure THTMLDatasetFormProducer.WriteHeaderTableDef(aWriter: THTMLWriter);
var r : integer;
c : THTMLCustomelement;
begin
aWriter.Starttablehead;
aWriter.StartTableRow;
with tabledef do
begin
for r := 0 to count-2 do
with TTableCell (Items[r]) do
begin
c := WriteHeader(aWriter);
if assigned (FAfterCellCreate) then
FAfterCellCreate(self, Items[r].FormField, true, c);
if EndOfRow then
begin
aWriter.EndTableRow;
aWriter.StartTableRow;
end;
end;
TTableCell(Items[Count-1]).WriteContent(aWriter);
end;
aWriter.EndTableRow;
aWriter.Endtablehead;
end;
procedure THTMLDatasetFormProducer.CorrectCellSpans;
var r, s, t : integer;
c : TTableCell;
ReachedEnd : boolean;
begin
for r := 0 to TableDef.count-1 do
with TableDef.items[r] do
if CellType <> ctSpanned then
begin
// CollSpan marking other cells as spanned
s := 1;
c := TableDef.Items[r];
while (s < ColSpan) and not c.EndOfRow do
begin
c := TableDef.Items[r+s];
c.celltype := ctSpanned;
inc (s);
end;
// the same for rowsapn
s := 1;
t := r + (s*tablecols);
while (s < rowspan) and (t < TableDef.count) do
begin
TableDef.items[t].CellType := ctSpanned;
inc (s);
inc (t, tablecols);
end;
end;
end;
procedure THTMLDatasetFormProducer.SearchControlFields;
var r : integer;
begin
for r := 0 to FControls.count-1 do
with FControls.items[r] do
FField := datasource.dataset.FindField(FFieldname);
end;
function THTMLDatasetFormProducer.StartForm(aWriter: THTMLWriter) : THTMLCustomElement;
const MethodAttribute : array[TFormMethod] of string = ('GET','POST');
var t : THTMLCustomElement;
begin
if FormAction <> '' then
begin
result := aWriter.Startform;
with THTML_Form(result) do
begin
method := MethodAttribute[self.FormMethod];
action := FormAction;
end;
t := aWriter.Starttable;
end
else
begin
t := aWriter.Starttable;
result := t;
end;
if assigned (FAfterTableCreate) then
FAfterTableCreate (self, t);
end;
procedure THTMLDatasetFormProducer.EndForm(aWriter: THTMLWriter);
begin
with aWriter do
begin
EndTable;
if FormAction <> '' then
Endform;
end;
end;
function THTMLDatasetFormProducer.WriteContent(aWriter: THTMLWriter): THTMLCustomElement;
var r : integer;
begin
if assigned (datasource) and assigned(datasource.dataset) then
begin
Ftabledef := TTableDef.Create (TableCols, TableRows);
try
SearchControlFields;
result := StartForm (aWriter);
if bvpTop in ButtonsVertical then
WriteButtons (aWriter);
if SingleRecord then
begin
FillTableDef (false);
CorrectCellSpans;
WriteTableDef (aWriter);
end
else
with datasource.dataset do
begin
if FIncludeHeader then
begin
FillTableDef (true);
CorrectCellSpans;
WriteHeaderTableDef (aWriter);
end;
if Page < 0 then
first
else
RecNo := ((Page-1) * RecordsPerPage) + 1; // zero based? yes: + 1 has to be deleted
r := 0;
while not eof and (r < RecordsPerPage) do
begin
FillTableDef (false);
CorrectCellSpans;
WriteTableDef (aWriter);
Next;
inc (r);
end;
end;
if bvpBottom in ButtonsVertical then
WriteButtons (aWriter);
EndForm (aWriter)
finally
tabledef.Free;
end;
end;
end;
procedure THTMLDatasetFormProducer.FillTableDef (IsHeader:boolean);
var r : integer;
begin
for r := 0 to Controls.Count-1 do
ControlToTableDef (Controls.items[r], IsHeader);
end;
function THTMLDatasetFormProducer.SingleRecord: boolean;
begin
result := true;
end;
constructor THTMLDatasetFormProducer.create(aOwner: TComponent);
begin
inherited create(aOwner);
FTableCols := 2;
FButtonsHor := bhpLeft;
FButtonsVer := [bvpTop, bvpBottom];
Fbuttonrow := TFormButtonCollection.create;
FControls := TFormFieldCollection.Create;
end;
destructor THTMLDatasetFormProducer.destroy;
begin
Fbuttonrow.Free;
FControls.Free;
inherited destroy;
end;
{ THTMLDatasetFormEditProducer }
procedure THTMLDatasetFormEditProducer.ControlToTableDef (aControldef : TFormFieldItem; IsHeader:boolean);
procedure PlaceFieldValue;
var check : boolean;
begin
with TableDef.CopyTablePosition(aControlDef.ValuePos) do
begin
case aControlDef.inputtype of
fittext,
fitpassword,
fitcheckbox,
fitradio,
fitfile,
fithidden,
fittextarea :
begin
CellType := ctInput;
InputType := aControlDef.InputType;
Name := aControlDef.Field.FieldName;
Size := aControlDef.Field.DisplayWidth;
MaxLength := aControldef.Field.Size;
if aControlDef.inputType in [fitcheckbox,fitradio] then
begin
with aControlDef.Field do
Checked := not isnull and (asstring <> '0') and (asstring <> '-')
and (comparetext(asstring,'false') <> 0);
if assigned (FOnFieldChecked) then
FOnFieldChecked (aControlDef.Field, check);
Checked := check;
end;
end;
fitproducer :
begin
CellType := ctProducer;
Producer := aControlDef.Producer;
end;
fitrecordselection : ;
end;
IsLabel := false;
Value := aControlDef.FField.asstring;
if not FSeparateLabel and not FIncludeHeader then
begin
Caption := aControldef.LabelCaption;
IncludeBreak := aControldef.LabelAbove;
end;
end;
end;
procedure PlaceLabel;
begin
with TableDef.CopyTablePosition(aControlDef.LabelPos) do
begin
CellType := ctLabel;
IsLabel := true;
Value := aControldef.labelcaption;
end;
end;
begin
if assigned (aControlDef.FField) then
PlaceFieldValue;
if FSeparateLabel and (aControlDef.LabelCaption <> '') then
PlaceLabel;
end;
{ THTMLDatasetFormShowProducer }
(**** TTableCell *****
property IsLabel : boolean read FIsLabel write FIsLabel;
// Label or Value ?
property CellType : TCellType read FCellType write FCellType;
ctEmpty, ctInput, ctLabel, ctProducer, ctSpanned
{ Cell properties: }
property ColSpan : integer read FColSpan write FColSpan;
property RowSpan : integer read FRowSpan write FRowSpan;
property AlignVertical : THTMLvalign read FAlignVer write FAlignVer default vaEmpty;
property AlignHorizontal : THTMLalign read FAlignHor write FAlignHor default alEmpty;
property Value : string read FValue write FValue;
// Contains the text for labels, or the value for input, or unused for producer and empty
{ only for input: }
property Name : string read FName write FName;
// name of the control
property InputType : TFormInputType read FInputType write FInputType;
// type of the input element
property Size : integer read FSize write FSize;
// size of text input element
property MaxLength : integer read FMaxLength write FMaxLength;
// MaxLength of text input element
property Checked : boolean read FChecked write FChecked;
// checked or not for radio,checkbox
{ only for labels: }
property Link : string read FLink write FLink;
// link to place around the text
{ only for producers: }
property Producer : THTMLContentProducer read FProducer write FProducer;
// producer to include
***** TFormFieldItem *****
property Fieldname : string read FFieldName write FFieldname;
property Field : TField
// the field to show/edit
property LabelCaption : string read FLabelCaption write FLabelCaption;
// the text to show for the control
property InputType : TFormInputType read FInputType write FInputType default fittext;
// the type of form control to use
(fittext,fitpassword,fitcheckbox,fitradio,fitfile,fithidden,fitproducer,fittextarea,fitrecordselection)
property Producer : THTMLContentProducer read FProducer write FProducer;
// the producer to include when generating the value
property Action : string read FAction write FAction;
// when showing the link to include in the value
property LabelPos : TTablePosition read FLabelPos write SetLabelPos;
// place of the label in the table-grid
property ValuePos : TTablePosition read FValuePos write SetValuePos;
// place of the value in the table-grid *)
procedure THTMLDatasetFormShowProducer.ControlToTableDef (aControldef : TFormFieldItem; IsHeader:boolean);
procedure PlaceFieldValue;
begin
with TableDef.CopyTablePosition(aControlDef.ValuePos) do
begin
CellType := ctLabel;
IsLabel := false;
Value := aControlDef.FField.asstring;
if not FSeparateLabel and not FIncludeHeader then
begin
Caption := aControldef.LabelCaption;
IncludeBreak := aControldef.LabelAbove;
end;
end;
end;
procedure PlaceLabel;
begin
with TableDef.CopyTablePosition(aControlDef.LabelPos) do
begin
CellType := ctLabel;
IsLabel := true;
Value := aControldef.labelcaption;
end;
end;
begin
if assigned (aControlDef.FField) then
PlaceFieldValue;
if FSeparateLabel and (aControlDef.LabelCaption <> '') then
PlaceLabel;
end;
{ THTMLDatasetFormGridProducer }
procedure THTMLDatasetFormGridProducer.ControlToTableDef (aControldef : TFormFieldItem; IsHeader:boolean);
procedure PlaceFieldValue;
begin
with TableDef.CopyTablePosition(aControlDef.ValuePos) do
begin
CellType := ctLabel;
IsLabel := false;
Value := aControlDef.FField.asstring;
if not FSeparateLabel and not FIncludeHeader then
begin
Caption := aControldef.LabelCaption;
IncludeBreak := aControldef.LabelAbove;
end;
end;
end;
procedure PlaceLabel;
begin
with TableDef.CopyTablePosition(aControlDef.LabelPos) do
begin
CellType := ctLabel;
IsLabel := true;
Value := aControldef.labelcaption;
end;
end;
begin
if assigned (aControlDef.FField) then
PlaceFieldValue;
if FSeparateLabel and (aControlDef.LabelCaption <> '') then
PlaceLabel;
end;
function THTMLDatasetFormGridProducer.SingleRecord: boolean;
begin
Result := false;
end;
constructor THTMLDatasetFormGridProducer.Create(aOwner: TComponent);
begin
inherited create(aOwner);
RecordsPerPage := 20;
Page := -1;
end;
{ TTableCell }
function TTableCell.WriteContent(aWriter: THTMLWriter) : THTMLCustomElement;
procedure WriteLabel;
var HasLink : boolean;
begin
HasLink := (Link <> '');
if HasLink then
aWriter.Anchor(Value).href := Link
else
aWriter.Text (Value);
end;
procedure WriteTextArea;
begin
aWriter.textarea(value).name := Name;
end;
procedure WriteInput;
var s, m : string;
begin
if size > 0 then
s := inttostr(size)
else
s := '';
if MaxLength > 0 then
m := inttostr(MaxLength)
else
m := '';
case InputType of
fittext :
with aWriter.FormText (Name, Value) do
begin
Size := s;
MaxLength := m;
end;
fitpassword :
with aWriter.FormPasswd (Name) do
begin
if self.Value <> '' then
Value := self.value;
Size := s;
MaxLength := m;
end;
fitcheckbox, fitrecordselection :
aWriter.FormCheckbox (Name, Value, checked);
fitradio :
aWriter.FormRadio(Name, Value, checked);
fitfile :
aWriter.FormFile(Name, Value);
fithidden :
aWriter.FormHidden (Name, Value);
end;
end;
procedure WriteProducer;
begin
with Producer do
begin
ParentElement := aWriter.CurrentElement;
HTMLDocument := aWriter.Document;
WriteContent (aWriter);
end;
end;
var c : THTML_td;
begin
if CellType <> ctSpanned then
with aWriter do
begin
c := Starttablecell;
with c do
begin
if self.ColSpan > 1 then
colspan := IntToStr(self.Colspan);
if self.RowSpan > 1 then
Rowspan := IntToStr(self.Rowspan);
align := AlignHorizontal;
valign := AlignVertical;
end;
if Self.Caption <> '' then
begin
span(self.caption);
if IncludeBreak then
linebreak;
end;
case CellType of
ctEmpty : ;
ctInput :
if InputType = fittextarea then
WriteTextArea
else
WriteInput;
ctLabel : WriteLabel;
ctProducer : WriteProducer;
end;
Endtablecell;
result := c;
end
else
result := nil;
end;
function TTableCell.WriteHeader(aWriter: THTMLWriter) : THTMLCustomElement;
var c : THTML_th;
s : string;
begin
with aWriter do
begin
c := Starttableheadcell;
with c do
begin
if self.ColSpan > 1 then
ColSpan := IntToStr(self.Colspan);
if self.RowSpan > 1 then
RowSpan := IntToStr(self.Rowspan);
align := AlignHorizontal;
valign := AlignVertical;
end;
if CellType <> ctLabel then
begin
s := FormField.LabelCaption;
if self.Link <> '' then
aWriter.Anchor(s).href := self.Link
else
aWriter.Text (s);
end
else
aWriter.Text ('');
Endtablecell;
result := c;
end;
end;
end.