2
0

dbwebwidget.pp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2019-Now by Michael Van Canneyt, member of the
  4. Free Pascal development team
  5. WEB Widget Set - DB-Aware widgets
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit dbwebwidget;
  13. {$mode objfpc}
  14. interface
  15. uses
  16. Classes, webwidget, db;
  17. Type
  18. { TCustomDBLoopTemplateWidget }
  19. TDBFieldValueData = Class(TLoopTemplateValue)
  20. Field : TField;
  21. end;
  22. TGetFieldValueEvent = Procedure (Sender : TObject; aData : TDBFieldValueData) of object;
  23. TCustomDBLoopTemplateWidget = Class(TCustomLoopTemplateWidget)
  24. private
  25. FDatasource: TDatasource;
  26. FOnFormatField: TGetFieldValueEvent;
  27. function GetDataset: TDataset;
  28. procedure SetDatasource(AValue: TDatasource);
  29. Protected
  30. Type
  31. TDBLoopEnumerator = Class(TLoopEnumerator)
  32. private
  33. FBof : Boolean;
  34. FDataset : TDataset;
  35. public
  36. Procedure SetDataset(aDataset : TDataset);
  37. Function GetValue(Const aName : String): String; override;
  38. function MoveNext: Boolean; override;
  39. Property Dataset : TDataset Read FDataset;
  40. end;
  41. Protected
  42. function FormatField(aEnum : TDBLoopEnumerator; aField: TField): String;
  43. Function CreateLoopEnumerator (aCurrValues : TLoopTemplateValue) : TLoopEnumerator; override;
  44. class Function CreateCurrValues: TLoopTemplateValue; override;
  45. Protected
  46. Procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  47. Property Datasource : TDatasource Read FDatasource Write SetDatasource;
  48. Property OnFormatField : TGetFieldValueEvent Read FOnFormatField Write FOnFormatField;
  49. Public
  50. Property Dataset : TDataset Read GetDataset;
  51. end;
  52. TDBLoopTemplateWidget = Class(TCustomDBLoopTemplateWidget)
  53. Published
  54. Property HeaderTemplate;
  55. Property ItemTemplate;
  56. Property FooterTemplate;
  57. Property OnGetValue;
  58. Property References;
  59. Property Datasource;
  60. Property OnFormatField;
  61. end;
  62. implementation
  63. { TCustomDBLoopTemplateWidget.TDBLoopEnumerator }
  64. procedure TCustomDBLoopTemplateWidget.TDBLoopEnumerator.SetDataset(aDataset: TDataset);
  65. begin
  66. FDataset:=aDataset;
  67. FBOF:=True;
  68. end;
  69. function TCustomDBLoopTemplateWidget.TDBLoopEnumerator.GetValue(const aName: String): String;
  70. Var
  71. F : TField;
  72. begin
  73. F:=Dataset.Fields.FindField(aName);
  74. if Assigned(F) then
  75. Result:=TCustomDBLoopTemplateWidget(Widget).FormatField(Self,F)
  76. else
  77. Result:=inherited GetValue(aName);
  78. end;
  79. function TCustomDBLoopTemplateWidget.FormatField(aEnum : TDBLoopEnumerator; aField : TField) : String;
  80. Var
  81. F : TDBFieldValueData;
  82. begin
  83. if Assigned(FOnFormatField) then
  84. begin
  85. F:=TDBFieldValueData(aEnum.CurrValues);
  86. F.Field:=aField;
  87. F.Value:=aField.AsString;
  88. FOnFormatField(Self,F);
  89. Result:=F.Value;
  90. end
  91. else
  92. Result:=aField.AsString;
  93. end;
  94. function TCustomDBLoopTemplateWidget.TDBLoopEnumerator.MoveNext: Boolean;
  95. begin
  96. If not Assigned(Dataset) then
  97. exit(False);
  98. if FBOF then
  99. FBof:=False
  100. else
  101. Dataset.Next;
  102. Result:=Not Dataset.EOF;
  103. if Result then
  104. Result:=inherited MoveNext; // Update index;
  105. end;
  106. { TCustomDBLoopTemplateWidget }
  107. function TCustomDBLoopTemplateWidget.GetDataset: TDataset;
  108. begin
  109. if Assigned(FDatasource) then
  110. Result:=FDatasource.Dataset
  111. else
  112. Result:=Nil;
  113. end;
  114. procedure TCustomDBLoopTemplateWidget.SetDatasource(AValue: TDatasource);
  115. begin
  116. if FDatasource=AValue then Exit;
  117. if Assigned(FDatasource) then
  118. FDatasource.RemoveFreeNotification(Self);
  119. FDatasource:=AValue;
  120. if Assigned(FDatasource) then
  121. FDatasource.FreeNotification(Self);
  122. end;
  123. function TCustomDBLoopTemplateWidget.CreateLoopEnumerator(aCurrValues: TLoopTemplateValue): TLoopEnumerator;
  124. Var
  125. DBL : TDBLoopEnumerator;
  126. begin
  127. DBL:=TDBLoopEnumerator.Create(Self,aCurrValues);
  128. DBL.SetDataset(Self.Dataset);
  129. Result:=DBL;
  130. end;
  131. Class function TCustomDBLoopTemplateWidget.CreateCurrValues: TLoopTemplateValue;
  132. begin
  133. Result:=TDBFieldValueData.Create;
  134. end;
  135. procedure TCustomDBLoopTemplateWidget.Notification(AComponent: TComponent; Operation: TOperation);
  136. begin
  137. inherited Notification(AComponent, Operation);
  138. if (Operation=opRemove) and (AComponent=FDatasource) then
  139. FDataSource:=Nil;
  140. end;
  141. end.