data.htmlactions.pp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. unit Data.HTMLActions;
  2. interface
  3. uses sysutils, classes, web, Rtl.HTMLEventNames, Rtl.HTMLActions, db;
  4. Type
  5. TDBCustomHTMLElementAction = class;
  6. TDBCustomHTMLInputElementAction = Class;
  7. TDBCustomHTMLButtonElementAction = Class;
  8. { THTMLActionDataLink }
  9. THTMLActionDataLink = class(TDataLink)
  10. private
  11. FField: TField;
  12. FFieldName: string;
  13. FAction : TDBCustomHTMLElementAction;
  14. procedure SetFieldName(AValue: string);
  15. protected
  16. procedure DatasetChanged; override;
  17. procedure ActiveChanged; override;
  18. procedure EditingChanged; override;
  19. procedure LayoutChanged; override;
  20. procedure RecordChanged(aField: TField); override;
  21. procedure UpdateData; override;
  22. procedure FocusControl(aField: JSValue); Override;
  23. public
  24. constructor Create(aAction : TDBCustomHTMLElementAction);
  25. function Edit: Boolean; override;
  26. Function CanModify : Boolean;
  27. Procedure Bind;
  28. Procedure UnBind;
  29. property Action: TDBCustomHTMLElementAction read FAction;
  30. property Field: TField read FField;
  31. property FieldName: string read FFieldName write SetFieldName;
  32. end;
  33. { TDBCustomHTMLInputElementAction }
  34. { TDBCustomHTMLElementAction }
  35. TFieldTextData = Record
  36. Field : TField;
  37. Value : String;
  38. end;
  39. TGetFieldTextEvent = procedure(Sender : TObject; var aData : TFieldTextData) of object;
  40. TDBCustomHTMLElementAction = class(THTMLCustomElementAction)
  41. Private
  42. FLink : THTMLActionDataLink;
  43. FOnEndEditing: TNotifyEvent;
  44. FOnLayoutChanged: TNotifyEvent;
  45. FOnStartEditing: TNotifyEvent;
  46. FOnGetFieldText: TGetFieldTextEvent;
  47. function GetDataSource: TDatasource;
  48. function GetField: TField;
  49. function GetFieldName: String;
  50. procedure SetDatasource(AValue: TDatasource);
  51. procedure SetFieldName(AValue: String);
  52. function TransformFieldText(F: TField; const Value: String): String;
  53. Protected
  54. procedure DoKeyDown(aEvent: TJSEvent); virtual;
  55. Procedure ActiveChanged; virtual;
  56. Procedure StartEditing; virtual;
  57. Procedure EndEditing; virtual;
  58. Procedure LayoutChanged; virtual;
  59. procedure CheckMaxLength; virtual;
  60. Property Link : THTMLActionDataLink Read FLink;
  61. Public
  62. Constructor Create(aOwner : TComponent); override;
  63. Destructor Destroy; override;
  64. Procedure ElementToDataset; virtual;
  65. Procedure DatasetToElement; virtual;
  66. Property Field : TField Read GetField;
  67. Property Datasource : TDatasource Read GetDataSource Write SetDatasource;
  68. Property FieldName : String Read GetFieldName Write SetFieldName;
  69. Property OnStartEditing : TNotifyEvent Read FOnStartEditing Write FOnStartEditing;
  70. Property OnEndEditing : TNotifyEvent Read FOnEndEditing Write FOnEndEditing;
  71. Property OnLayoutChanged : TNotifyEvent Read FOnLayoutChanged Write FOnLayoutChanged;
  72. Property OnGetFieldText : TGetFieldTextEvent Read FOnGetFieldText Write FOnGetFieldText;
  73. end;
  74. TDBHTMLElementAction = class(TDBCustomHTMLElementAction)
  75. Published
  76. Property Events;
  77. Property CustomEvents;
  78. Property ElementID;
  79. Property CSSSelector;
  80. Property PreventDefault;
  81. Property StopPropagation;
  82. Property OnExecute;
  83. Property BeforeBind;
  84. Property AfterBind;
  85. Property Datasource;
  86. Property FieldName;
  87. Property OnStartEditing;
  88. Property OnEndEditing;
  89. Property OnLayoutChanged;
  90. Property OnGetFieldText;
  91. end;
  92. TDBCustomHTMLInputElementAction = class(TDBCustomHTMLElementAction)
  93. Protected
  94. procedure DoKeyDown(aEvent: TJSEvent); override;
  95. Procedure ActiveChanged; override;
  96. function NeedsClick(aEl: TJSElement): Boolean;
  97. Procedure StartEditing; override;
  98. Procedure EndEditing; override;
  99. Procedure LayoutChanged; override;
  100. Property Link : THTMLActionDataLink Read FLink;
  101. Public
  102. procedure CheckMaxLength; override;
  103. Procedure ElementToDataset; override;
  104. Procedure DatasetToElement; override;
  105. Procedure BindEvents(aEl : TJSElement); override;
  106. end;
  107. TDBHTMLInputElementAction = class(TDBCustomHTMLInputElementAction)
  108. Published
  109. Property Events;
  110. Property CustomEvents;
  111. Property ElementID;
  112. Property CSSSelector;
  113. Property PreventDefault;
  114. Property StopPropagation;
  115. Property OnExecute;
  116. Property BeforeBind;
  117. Property AfterBind;
  118. Property Datasource;
  119. Property FieldName;
  120. Property OnStartEditing;
  121. Property OnEndEditing;
  122. Property OnLayoutChanged;
  123. Property OnGetFieldText;
  124. end;
  125. { TButtonActionDataLink }
  126. TButtonActionDataLink = class(TDataLink)
  127. private
  128. FAction: TDBCustomHTMLButtonElementAction;
  129. protected
  130. procedure EditingChanged; override;
  131. procedure DataSetChanged; override;
  132. procedure ActiveChanged; override;
  133. Property Action : TDBCustomHTMLButtonElementAction Read Faction;
  134. public
  135. constructor Create(aAction: TDBCustomHTMLButtonElementAction);
  136. end;
  137. { TDBCustomHTMLButtonElementAction }
  138. TDBButtonAction = (baFirst,baPrior,baNext,baLast,baEdit,baAppend,baInsert,baPost,baCancel,baDelete,baApplyUpdates);
  139. TDBButtonActions = Set of TDBButtonAction;
  140. TDBCustomHTMLButtonElementAction = class(THTMLCustomElementAction)
  141. private
  142. FAction: TDBButtonAction;
  143. FLink: TButtonActionDataLink;
  144. FOnDisableControl: TNotifyEvent;
  145. FOnEnableControl: TNotifyEvent;
  146. procedure DoButtonClick(aEvent: TJSEvent);
  147. function GetDataSource: TDatasource;
  148. procedure SetDatasource(AValue: TDatasource);
  149. Protected
  150. procedure EditingChanged; virtual;
  151. procedure DataSetChanged; virtual;
  152. procedure ActiveChanged; virtual;
  153. procedure CheckButtonState; virtual;
  154. Procedure EnableControl; virtual;
  155. Procedure DisableControl; virtual;
  156. Property Link : TButtonActionDataLink Read FLink;
  157. Public
  158. Constructor Create(aOwner : TComponent); override;
  159. Destructor Destroy; override;
  160. procedure ExecuteAction; virtual;
  161. Procedure BindEvents(aEl : TJSElement); override;
  162. Property ButtonAction : TDBButtonAction Read FAction Write FAction default baPost;
  163. Property Datasource : TDatasource Read GetDataSource Write SetDatasource;
  164. Property OnEnableControl : TNotifyEvent Read FOnEnableControl Write FOnEnableControl;
  165. Property OnDisableControl : TNotifyEvent Read FOnDisableControl Write FOnDisableControl;
  166. end;
  167. TDBHTMLButtonElementAction = class(TDBCustomHTMLButtonElementAction)
  168. Published
  169. Property Events;
  170. Property CustomEvents;
  171. Property ElementID;
  172. Property CSSSelector;
  173. Property PreventDefault;
  174. Property StopPropagation;
  175. Property OnExecute;
  176. Property BeforeBind;
  177. Property AfterBind;
  178. Property ButtonAction;
  179. Property Datasource;
  180. Property OnEnableControl;
  181. Property OnDisableControl;
  182. end;
  183. Implementation
  184. uses strutils, rtl.HTMLUtils;
  185. { TButtonActionDataLink }
  186. procedure TButtonActionDataLink.EditingChanged;
  187. begin
  188. inherited EditingChanged;
  189. Action.EditingChanged;
  190. end;
  191. procedure TButtonActionDataLink.DataSetChanged;
  192. begin
  193. inherited DataSetChanged;
  194. Action.DatasetChanged;
  195. end;
  196. procedure TButtonActionDataLink.ActiveChanged;
  197. begin
  198. inherited ActiveChanged;
  199. Action.ActiveChanged;
  200. end;
  201. constructor TButtonActionDataLink.Create(
  202. aAction: TDBCustomHTMLButtonElementAction);
  203. begin
  204. Inherited Create;
  205. Faction:=aAction;
  206. end;
  207. { TDBCustomHTMLButtonElementAction }
  208. function TDBCustomHTMLButtonElementAction.GetDataSource: TDatasource;
  209. begin
  210. Result:=Link.DataSource;
  211. end;
  212. procedure TDBCustomHTMLButtonElementAction.SetDatasource(AValue: TDatasource);
  213. begin
  214. Link.DataSource:=aValue;
  215. end;
  216. procedure TDBCustomHTMLButtonElementAction.EditingChanged;
  217. begin
  218. CheckButtonState;
  219. end;
  220. procedure TDBCustomHTMLButtonElementAction.DataSetChanged;
  221. begin
  222. CheckButtonState;
  223. end;
  224. procedure TDBCustomHTMLButtonElementAction.ActiveChanged;
  225. begin
  226. CheckButtonState;
  227. end;
  228. procedure TDBCustomHTMLButtonElementAction.CheckButtonState;
  229. Var
  230. doEnable : Boolean;
  231. begin
  232. DoEnable:=Link.Active;
  233. if DoEnable then
  234. With Link.Dataset do
  235. Case ButtonAction of
  236. baFirst,
  237. baPrior : DoEnable:=Not BOF;
  238. baNext,
  239. baLast : DoEnable:=Not EOF;
  240. baEdit,
  241. baAppend,
  242. baInsert : DoEnable:=Not (State in dsEditModes);
  243. baPost : DoEnable:= (State in dsEditModes);
  244. baCancel : DoEnable:= (State in dsEditModes);
  245. baApplyUpdates : DoEnable:=GetUpdateCount(True)>0;
  246. end;
  247. if DoEnable then
  248. EnableControl
  249. else
  250. DisableControl;
  251. end;
  252. procedure TDBCustomHTMLButtonElementAction.EnableControl;
  253. begin
  254. if (Element is TJSHTMLButtonElement) then
  255. TJSHTMLButtonElement(Element).disabled:=False;
  256. if Assigned(FOnEnableControl) then
  257. FOnEnableControl(Self);
  258. end;
  259. procedure TDBCustomHTMLButtonElementAction.DisableControl;
  260. begin
  261. if (Element is TJSHTMLButtonElement) then
  262. TJSHTMLButtonElement(Element).disabled:=True;
  263. if Assigned(FOnEnableControl) then
  264. FOnDisableControl(Self);
  265. end;
  266. constructor TDBCustomHTMLButtonElementAction.Create(aOwner: TComponent);
  267. begin
  268. inherited Create(aOwner);
  269. FLink:=TButtonActionDataLink.Create(Self);
  270. Faction:=baPost;
  271. end;
  272. destructor TDBCustomHTMLButtonElementAction.Destroy;
  273. begin
  274. FreeAndNil(FLink);
  275. inherited Destroy;
  276. end;
  277. procedure TDBCustomHTMLButtonElementAction.ExecuteAction;
  278. begin
  279. if Not Assigned(Link.DataSet) then
  280. Exit; // Maybe throw excption ?
  281. With Link.Dataset do
  282. Case ButtonAction of
  283. baFirst : First;
  284. baPrior : Prior;
  285. baNext : Next;
  286. baLast : Last;
  287. baEdit : Edit;
  288. baAppend : Append;
  289. baInsert : Insert;
  290. baPost : Post;
  291. baCancel : Cancel;
  292. baDelete : Delete;
  293. baApplyUpdates : ApplyUpdates;
  294. end;
  295. end;
  296. procedure TDBCustomHTMLButtonElementAction.DoButtonClick(aEvent : TJSEvent);
  297. begin
  298. ExecuteAction;
  299. end;
  300. procedure TDBCustomHTMLButtonElementAction.BindEvents(aEl: TJSElement);
  301. Var
  302. doBindClick : Boolean;
  303. aType : String;
  304. begin
  305. inherited BindEvents(aEl);
  306. doBindClick:=aEl is TJSHTMLButtonElement;
  307. if (not doBindClick) and (aEl is TJSHTMLInputElement) then
  308. begin
  309. aType:=LowerCase(TJSHTMLInputElement(aEl)._type);
  310. doBindClick:=(atype='submit') or (atype='reset');
  311. end;
  312. if DoBindClick then
  313. aEl.addEventListener('click',@DoButtonClick);
  314. CheckButtonState;
  315. end;
  316. { TDBCustomHTMLElementAction }
  317. function TDBCustomHTMLElementAction.GetDataSource: TDatasource;
  318. begin
  319. Result:=Link.DataSource;
  320. end;
  321. function TDBCustomHTMLElementAction.GetField: TField;
  322. begin
  323. Result:=Link.Field;
  324. end;
  325. function TDBCustomHTMLElementAction.GetFieldName: String;
  326. begin
  327. Result:=Link.FieldName;
  328. end;
  329. procedure TDBCustomHTMLElementAction.SetDatasource(AValue: TDatasource);
  330. begin
  331. if aValue=Link.DataSource then exit;
  332. Link.Datasource:=aValue;
  333. end;
  334. procedure TDBCustomHTMLElementAction.SetFieldName(AValue: String);
  335. begin
  336. Link.FieldName:=aValue;
  337. end;
  338. procedure TDBCustomHTMLElementAction.DoKeyDown(aEvent: TJSEvent);
  339. begin
  340. end;
  341. procedure TDBCustomHTMLElementAction.ActiveChanged;
  342. begin
  343. if Link.Active then
  344. begin
  345. CheckMaxLength;
  346. DatasetToElement;
  347. end
  348. else
  349. ClearValue;
  350. if Link.Editing then
  351. StartEditing
  352. else
  353. EndEditing;
  354. end;
  355. procedure TDBCustomHTMLElementAction.StartEditing;
  356. begin
  357. if Assigned(FOnStartEditing) then
  358. FOnStartEditing(Self);
  359. end;
  360. procedure TDBCustomHTMLElementAction.EndEditing;
  361. begin
  362. if Assigned(FOnEndEditing) then
  363. FOnEndEditing(Self);
  364. end;
  365. procedure TDBCustomHTMLElementAction.LayoutChanged;
  366. begin
  367. If Assigned(FOnLayoutChanged) then
  368. FOnLayoutChanged(Self);
  369. end;
  370. constructor TDBCustomHTMLElementAction.Create(aOwner: TComponent);
  371. begin
  372. inherited Create(aOwner);
  373. FLink:=THTMLActionDataLink.Create(Self);
  374. end;
  375. destructor TDBCustomHTMLElementAction.Destroy;
  376. begin
  377. FreeAndNil(FLink);
  378. inherited Destroy;
  379. end;
  380. procedure TDBCustomHTMLElementAction.ElementToDataset;
  381. begin
  382. // Do nothing.
  383. end;
  384. procedure TDBCustomHTMLElementAction.CheckMaxLength;
  385. begin
  386. // Do nothing
  387. end;
  388. Function TDBCustomHTMLElementAction.TransformFieldText(F : TField; const Value: String) : String;
  389. Var
  390. D : TFieldTextData;
  391. begin
  392. if not Assigned(FOnGetFieldText) then
  393. Result:=Value
  394. else
  395. begin
  396. D.Value:=Value;
  397. D.Field:=F;
  398. FOnGetFieldText(Self,D);
  399. Result:=D.Value;
  400. end;
  401. end;
  402. procedure TDBCustomHTMLElementAction.DatasetToElement;
  403. Var
  404. F : TField;
  405. E : TJSHTMLElement;
  406. begin
  407. F:=Field;
  408. E:=Element;
  409. // Writeln(Name,' FieldName : ',FieldName,' field: ',Assigned(F),' element : ',assigned(E));
  410. if Not (Assigned(F) and assigned(E)) then
  411. Exit;
  412. Value:=TransFormFieldText(Field,F.AsString);
  413. end;
  414. Function TDBCustomHTMLInputElementAction.NeedsClick(aEl : TJSElement) : Boolean;
  415. begin
  416. Result:=SameText(aEl.tagName,'select');
  417. if (not Result) and SameText(aEl.tagName,'input') then
  418. Result:=IndexText(String(aEl['type']),['date','time','number','checkbox','radio'])<>-1;
  419. end;
  420. procedure TDBCustomHTMLInputElementAction.BindEvents(aEl: TJSElement);
  421. begin
  422. inherited BindEvents(aEl);
  423. aEl.addEventListener(sEventKeyDown,@DoKeyDown);
  424. if NeedsClick(aEl) then
  425. aEl.addEventListener(sEventClick,@DoKeyDown);
  426. end;
  427. procedure TDBCustomHTMLInputElementAction.DoKeyDown(aEvent : TJSEvent);
  428. begin
  429. if (aEvent is TJSKeyboardEvent)
  430. or (aEvent is TJSMouseEvent) then
  431. begin
  432. if not Link.Edit then
  433. begin
  434. aEvent.preventDefault;
  435. aEvent.stopPropagation;
  436. end;
  437. end;
  438. end;
  439. procedure TDBCustomHTMLInputElementAction.ActiveChanged;
  440. begin
  441. inherited ActiveChanged;
  442. end;
  443. procedure TDBCustomHTMLInputElementAction.StartEditing;
  444. begin
  445. if Element is TJSHTMLInputElement then
  446. TJSHTMLInputElement(Element).readOnly:=Link.ReadOnly;
  447. Inherited;
  448. end;
  449. procedure TDBCustomHTMLInputElementAction.EndEditing;
  450. begin
  451. Inherited;
  452. if Element is TJSHTMLInputElement then
  453. TJSHTMLInputElement(Element).readOnly:=Link.ReadOnly;
  454. end;
  455. procedure TDBCustomHTMLInputElementAction.LayoutChanged;
  456. begin
  457. inherited LayoutChanged;
  458. end;
  459. { THTMLActionDataLink }
  460. procedure THTMLActionDataLink.SetFieldName(AValue: string);
  461. begin
  462. if FFieldName=AValue then Exit;
  463. FFieldName:=AValue;
  464. end;
  465. procedure THTMLActionDataLink.DatasetChanged;
  466. begin
  467. inherited DatasetChanged;
  468. ActiveChanged;
  469. end;
  470. procedure THTMLActionDataLink.ActiveChanged;
  471. begin
  472. if Active then
  473. Bind
  474. else
  475. UnBind;
  476. Action.ActiveChanged;
  477. end;
  478. procedure THTMLActionDataLink.EditingChanged;
  479. begin
  480. if Editing then
  481. Action.StartEditing
  482. else
  483. Action.EndEditing
  484. end;
  485. procedure THTMLActionDataLink.LayoutChanged;
  486. begin
  487. Action.LayoutChanged;
  488. end;
  489. procedure THTMLActionDataLink.RecordChanged(aField: TField);
  490. begin
  491. inherited RecordChanged(aField);
  492. if (aField=FField) or (aField=Nil) then
  493. Action.DatasetToElement;
  494. end;
  495. procedure THTMLActionDataLink.UpdateData;
  496. begin
  497. Action.ElementToDataset;
  498. end;
  499. procedure THTMLActionDataLink.FocusControl(aField: JSValue);
  500. begin
  501. if (aField=Field) then
  502. Action.FocusControl;
  503. end;
  504. constructor THTMLActionDataLink.Create(aAction: TDBCustomHTMLElementAction);
  505. begin
  506. Inherited Create;
  507. FAction:=aAction;
  508. end;
  509. function THTMLActionDataLink.Edit: Boolean;
  510. begin
  511. if CanModify then
  512. Inherited Edit;
  513. Result:=Editing;
  514. end;
  515. function THTMLActionDataLink.CanModify: Boolean;
  516. begin
  517. Result:=not ReadOnly;
  518. if Result then
  519. Result:=(Field<>nil) and Field.CanModify;
  520. end;
  521. procedure TDBCustomHTMLInputElementAction.CheckMaxLength;
  522. Var
  523. El : TJSHTMLElement;
  524. iEl : TJSHTMLInputElement absolute El;
  525. begin
  526. El:=Element;
  527. If Not (assigned(Field) and Assigned(El)) then exit;
  528. if Field.DataType<>ftString then
  529. Exit;
  530. if (El is TJSHTMLInputElement) and SameText(iEl._type,'text') then
  531. iel.maxLength:=Field.Size;
  532. end;
  533. procedure TDBCustomHTMLInputElementAction.ElementToDataset;
  534. Var
  535. F : TField;
  536. E : TJSHTMLElement;
  537. EI : TJSHTMLInputElement absolute E;
  538. begin
  539. F:=Field;
  540. E:=Element;
  541. Writeln(Name,'Elementtodataset FieldName : ',FieldName,' field: ',Assigned(F),' element : ',assigned(E));
  542. if Not Assigned(F) then
  543. exit;
  544. if E is TJSHTMLInputElement then
  545. begin
  546. if (EI._type='checkbox') then
  547. F.AsBoolean:=EI.Checked
  548. else if SameText(EI._type,'date')then
  549. Field.AsDateTime:=ExtractDate(EI.value)
  550. else if SameText(EI._type,'time')then
  551. Field.AsDateTime:=ExtractTime(EI.value)
  552. else
  553. F.AsString:=Value;
  554. end
  555. else
  556. F.AsString:=Value;
  557. end;
  558. procedure TDBCustomHTMLInputElementAction.DatasetToElement;
  559. Var
  560. F : TField;
  561. E : TJSHTMLElement;
  562. EI : TJSHTMLInputElement absolute E;
  563. begin
  564. F:=Field;
  565. E:=Element;
  566. // Writeln(Name,'dataset to element FieldName : ',FieldName,' field: ',Assigned(F),' element : ',assigned(E));
  567. if Not (Assigned(F) and Assigned(E)) then
  568. Exit;
  569. Self.Value:=TransFormFieldText(Field,F.AsString);
  570. if E is TJSHTMLInputElement then
  571. begin
  572. if (EI._type='checkbox') then
  573. EI.Checked:=F.AsBoolean
  574. else if SameText(EI._type,'date') then
  575. EI.Value:=TransFormFieldText(F,FormatHTMLDate(F.AsDateTime))
  576. else if SameText(EI._type,'time') then
  577. EI.Value:=TransFormFieldText(F,FormatHTMLTime(F.AsDateTime))
  578. else
  579. Value:=TransFormFieldText(F,F.AsString);
  580. end
  581. else
  582. Inherited
  583. end;
  584. procedure THTMLActionDataLink.Bind;
  585. begin
  586. If Assigned(Dataset) and (FieldName<>'') then
  587. FField:=Dataset.FieldByName(FieldName);
  588. end;
  589. procedure THTMLActionDataLink.UnBind;
  590. begin
  591. FField:=nil;
  592. end;
  593. end.