htmlwidgets.pp 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681
  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 : Basic bare HTML 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 htmlwidgets;
  13. {$mode objfpc}
  14. interface
  15. uses
  16. Classes, SysUtils, webwidget, js, web;
  17. Type
  18. TTextMode = (tmText,tmHTML);
  19. { TButtonWidget }
  20. TButtonWidget = Class(TWebWidget)
  21. private
  22. FText: String;
  23. FTextMode: TTextMode;
  24. procedure SetText(AValue: String);
  25. procedure SetTextMode(AValue: TTextMode);
  26. Protected
  27. procedure ApplyText(aElement: TJSHTMLElement);
  28. Procedure SetName(const NewName: TComponentName); override;
  29. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  30. Public
  31. Procedure Click;
  32. Function HTMLTag : String; override;
  33. Published
  34. Property Text : String Read FText Write SetText;
  35. Property TextMode : TTextMode Read FTextMode Write SetTextMode;
  36. end;
  37. { TViewPort }
  38. TViewPort = Class(TCustomWebWidget)
  39. Private
  40. Class var FInstance : TViewPort;
  41. Protected
  42. Class Function FixedParent : TJSHTMLElement; override;
  43. Class Function FixedElement : TJSHTMLElement; override;
  44. Function DoRenderHTML(aParent,aElement : TJSHTMLElement) :TJSHTMLElement; override;
  45. Public
  46. Constructor Create (aOwner: TComponent); override;
  47. Function HTMLTag : String; override;
  48. Class Function Instance : TViewPort;
  49. Property Element;
  50. end;
  51. { TWebPage }
  52. TWebPage = Class(TCustomWebWidget)
  53. private
  54. Protected
  55. Class Function DefaultParentElement: TJSHTMLElement; override;
  56. Class Function DefaultParent : TCustomWebWidget; override;
  57. Procedure DoUnRender(aParent : TJSHTMLElement) ; override;
  58. Public
  59. Constructor Create(AOwner : TComponent); override;
  60. Function HTMLTag : String; override;
  61. // Later on, allow IFrame;
  62. Published
  63. Property ParentID;
  64. Property ElementID;
  65. Property Classes;
  66. Property Styles;
  67. Property StyleRefresh;
  68. Property Visible;
  69. // Events
  70. Property BeforeRenderHTML;
  71. Property AfterRenderHTML;
  72. Property OnAbort;
  73. Property OnAnimationCancel;
  74. Property OnAnimationEnd;
  75. Property OnAnimationIteration;
  76. Property OnAnimationStart;
  77. Property OnAuxClick;
  78. Property OnBlur;
  79. Property OnCancel;
  80. Property OnCanPlay;
  81. Property OnCanPlayThrough;
  82. Property OnChange;
  83. Property OnClick;
  84. Property OnCompositionEnd;
  85. Property OnCompositionStart;
  86. Property OnCompositionUpdate;
  87. Property OnContextMenu;
  88. Property OnCopy;
  89. Property OnCut;
  90. Property OnCueChange;
  91. Property OnDblClick;
  92. Property OnDurationChange;
  93. Property OnEnded ;
  94. Property OnError ;
  95. Property OnFocus;
  96. Property OnFocusIn ;
  97. Property OnFocusOut ;
  98. Property OnGotPointerCapture;
  99. Property OnInput;
  100. Property OnInvalid;
  101. Property OnKeyDown;
  102. Property OnKeyPress;
  103. Property OnKeyUp;
  104. Property OnLoad;
  105. Property OnLoadedData;
  106. Property OnLoadedMetaData;
  107. Property OnLoadend;
  108. Property OnLoadStart;
  109. Property OnLostPointerCapture;
  110. Property OnMouseDown;
  111. Property OnMouseEnter;
  112. Property OnMouseLeave;
  113. Property OnMouseMove;
  114. Property OnMouseOut;
  115. Property OnMouseUp;
  116. Property OnOverFlow;
  117. Property OnPaste;
  118. Property OnPause;
  119. Property OnPlay;
  120. Property OnPointerCancel;
  121. Property OnPointerDown;
  122. Property OnPointerEnter;
  123. Property OnPointerLeave;
  124. Property OnPointerMove;
  125. Property OnPointerOut;
  126. Property OnPointerOver;
  127. Property OnPointerUp;
  128. Property OnReset;
  129. Property OnResize;
  130. Property OnScroll;
  131. Property OnSelect;
  132. Property OnSubmit;
  133. Property OnTouchStart;
  134. Property OnTransitionCancel;
  135. Property OnTransitionEnd;
  136. Property OnTransitionRun;
  137. Property OnTransitionStart;
  138. Property OnWheel;
  139. end;
  140. { TCustomInputWidget }
  141. TCustomInputWidget = Class(TWebWidget)
  142. private
  143. FValue : String;
  144. FValueName : String;
  145. FText : String;
  146. FReadOnly : Boolean;
  147. FRequired : Boolean;
  148. function GetReadOnly: Boolean;
  149. function GetRequired: Boolean;
  150. function GetText: String;
  151. function GetValue: String;
  152. function GetValueName: String;
  153. procedure SetReadonly(AValue: Boolean);
  154. procedure SetRequired(AValue: Boolean);
  155. procedure SetText(AValue: String);
  156. procedure SetValue(AValue: String);
  157. function GetInputElement: TJSHTMLInputElement;
  158. procedure SetValueName(AValue: String);
  159. Protected
  160. Procedure SetName(const NewName: TComponentName); override;
  161. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  162. Property InputElement : TJSHTMLInputElement Read GetInputElement;
  163. // Text to show (checkbox etc). Enable in descendents as needed
  164. Property Text : String Read GetText Write SetText;
  165. Public
  166. function InputType : String; virtual; abstract;
  167. Function HTMLTag : String; override;
  168. // Value as string
  169. Property Value : String Read GetValue Write SetValue;
  170. // Value Name to use when submitting using form.
  171. Property ValueName : String Read GetValueName Write SetValueName;
  172. Property ReadOnly : Boolean Read GetReadOnly Write SetReadonly;
  173. Property Required : Boolean Read GetRequired Write SetRequired;
  174. end;
  175. { TTextInputWidget }
  176. TInputTextType = (ittText,ittPassword,ittNumber,ittEmail,ittSearch,ittTelephone,ittURL,ittColor);
  177. TTextInputWidget = class(TCustomInputWidget)
  178. private
  179. FMaxLength : Integer;
  180. FMinLength : Integer;
  181. FTextType : TInputTextType;
  182. function GetAsNumber: NativeInt;
  183. function GetMaxLength: NativeInt;
  184. function GetMinLength: NativeInt;
  185. function GetTextType: TInputTextType;
  186. procedure SetAsNumber(AValue: NativeInt);
  187. procedure SetMaxLength(AValue: NativeInt);
  188. procedure SetMinLength(AValue: NativeInt);
  189. procedure SetTextType(AValue: TInputTextType);
  190. Protected
  191. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  192. Public
  193. Class Function AllowChildren : Boolean; override;
  194. function InputType : String; override;
  195. Published
  196. Property Value;
  197. Property ValueName;
  198. Property Required;
  199. Property TextType : TInputTextType Read GetTextType Write SetTextType;
  200. property AsNumber : NativeInt Read GetAsNumber Write SetAsNumber;
  201. Property MaxLength : NativeInt Read GetMaxLength Write SetMaxLength;
  202. Property MinLength : NativeInt Read GetMinLength Write SetMinLength;
  203. // Todo: List support
  204. end;
  205. { TButtonInputWidget }
  206. TInputButtonType = (ibtSubmit,ibtReset,ibtImage);
  207. TInputButtonTypes = set of TInputButtonType;
  208. TButtonInputWidget = class(TCustomInputWidget)
  209. private
  210. FButtonType: TInputButtonType;
  211. FSrc: String;
  212. procedure SetButtonType(AValue: TInputButtonType);
  213. procedure SetSrc(AValue: String);
  214. Public
  215. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  216. function InputType : String; override;
  217. Class Function AllowChildren : Boolean; override;
  218. Published
  219. Property ButtonType : TInputButtonType Read FButtonType Write SetButtonType;
  220. Property Value;
  221. Property ValueName;
  222. Property Src : String Read FSrc Write SetSrc;
  223. end;
  224. { TCheckableInputWidget }
  225. TCheckableInputWidget = class(TCustomInputWidget)
  226. private
  227. FChecked: Boolean;
  228. function GetChecked: Boolean;
  229. procedure SetChecked(AValue: Boolean);
  230. Protected
  231. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  232. Public
  233. Property Value;
  234. Property ValueName;
  235. Property Checked : Boolean Read GetChecked Write SetChecked;
  236. Property Text;
  237. end;
  238. { TRadioInputWidget }
  239. TRadioInputWidget = class(TCheckableInputWidget)
  240. private
  241. Public
  242. function InputType : String; override;
  243. Published
  244. Property Value;
  245. Property ValueName;
  246. Property Checked;
  247. Property Text;
  248. end;
  249. { TCheckboxInputWidget }
  250. TCheckboxInputWidget = class(TCheckableInputWidget)
  251. private
  252. Public
  253. function InputType : String; override;
  254. Published
  255. Property Value;
  256. Property ValueName;
  257. Property Checked;
  258. Property Text;
  259. end;
  260. { TDateInputWidget }
  261. TDateInputWidget = class(TCustomInputWidget)
  262. private
  263. FDate: TDateTime;
  264. function GetDate: TDateTime;
  265. procedure SetDate(AValue: TDateTime);
  266. Public
  267. function InputType : String; override;
  268. Class Function AllowChildren : Boolean; override;
  269. Published
  270. Property Required;
  271. Property ValueName;
  272. Property Date : TDateTime Read GetDate Write SetDate;
  273. end;
  274. { TFileInputWidget }
  275. TFileInfo = record
  276. Name : String;
  277. TimeStamp : TDateTime;
  278. FileType : String;
  279. Size : NativeInt;
  280. end;
  281. TFileInputWidget = class(TCustomInputWidget)
  282. private
  283. FMultiple: Boolean;
  284. function GetFileCount: Integer;
  285. function GetFileDate(aIndex : Integer): TDateTime;
  286. function GetFileInfo(aIndex : Integer): TFileInfo;
  287. function GetFileName(aIndex : Integer): String;
  288. function GetFileSize(aIndex : Integer): NativeInt;
  289. function GetFileType(aIndex : Integer): String;
  290. function GetMultiple: Boolean;
  291. procedure SetMultiple(AValue: Boolean);
  292. Protected
  293. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  294. Public
  295. Class Function AllowChildren : Boolean; override;
  296. function InputType : String; override;
  297. Property FileCount : Integer read GetFileCount;
  298. Property Files[aIndex : Integer] : String Read GetFileName;
  299. Property FileSizes[aIndex : Integer] : NativeInt Read GetFileSize;
  300. Property FileTypes[aIndex : Integer] : String Read GetFileType;
  301. Property FileDates[aIndex : Integer] : TDateTime Read GetFileDate;
  302. Property FileInfos[aIndex : Integer] : TFileInfo Read GetFileInfo;
  303. Published
  304. Property ValueName;
  305. Property Required;
  306. Property Multiple : Boolean Read GetMultiple Write SetMultiple;
  307. end;
  308. { THiddenInputWidget }
  309. THiddenInputWidget = class(TCustomInputWidget)
  310. Public
  311. Class Function AllowChildren : Boolean; override;
  312. function InputType : String; override;
  313. Published
  314. Property ValueName;
  315. Property Value;
  316. Property Required;
  317. end;
  318. { TTextAreaWidget }
  319. TTextAreaWrap = (tawSoft,tawHard,tawOff);
  320. TTextAreaWidget = Class(TWebWidget)
  321. private
  322. FLines: TStrings;
  323. FIgnoreChanges : Boolean;
  324. FMaxLength: Cardinal;
  325. FValueName : String;
  326. FRows,
  327. FColumns : Cardinal;
  328. FWrap: TTextAreaWrap;
  329. FRequired,
  330. FReadOnly : Boolean;
  331. procedure ApplyWrap(aElement: TJSHTMLTextAreaElement);
  332. procedure DoLineChanges(Sender: TObject);
  333. function GetColumns: Cardinal;
  334. function GetLines: TStrings;
  335. function GetReadOnly: Boolean;
  336. function GetRequired: Boolean;
  337. function GetRows: Cardinal;
  338. function GetText: String;
  339. function GetValueName: string;
  340. procedure SetColumns(AValue: Cardinal);
  341. procedure SetLines(AValue: TStrings);
  342. procedure SetMaxLength(AValue: Cardinal);
  343. procedure SetReadonly(AValue: Boolean);
  344. procedure SetRequired(AValue: Boolean);
  345. procedure SetRows(AValue: Cardinal);
  346. procedure SetText(AValue: String);
  347. procedure SetValueName(AValue: string);
  348. Function GetTextArea : TJSHTMLTextAreaElement;
  349. procedure SetWrap(AValue: TTextAreaWrap);
  350. Protected
  351. procedure ApplyLines(aElement: TJSHTMLTextAreaElement);
  352. procedure LinesFromHTML(aHTML : String);
  353. Procedure SetName(const NewName: TComponentName); override;
  354. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  355. Property TextArea :TJSHTMLTextAreaElement Read GetTextArea;
  356. Public
  357. Constructor Create(aOwner : TComponent); override;
  358. Destructor Destroy; override;
  359. Class Function AllowChildren : Boolean; override;
  360. Function HTMLTag : String; override;
  361. Property InnerHTML : String Read GetText Write SetText;
  362. Published
  363. Property ValueName : string Read GetValueName Write SetValueName;
  364. Property Rows : Cardinal Read GetRows Write SetRows;
  365. Property Columns : Cardinal Read GetColumns Write SetColumns;
  366. Property Lines : TStrings Read GetLines Write SetLines;
  367. Property MaxLength : Cardinal Read FMaxLength Write SetMaxLength;
  368. Property Wrap : TTextAreaWrap Read FWrap Write SetWrap;
  369. Property ReadOnly : Boolean Read GetReadOnly Write SetReadonly;
  370. Property Required : Boolean Read GetRequired Write SetRequired;
  371. end;
  372. { TImageWidget }
  373. TImageWidget = class(TWebWidget)
  374. private
  375. FHeight: Integer;
  376. FWidth: Integer;
  377. FSrc : String;
  378. function GetHeight: Integer;
  379. function GetImg: TJSHTMLImageElement;
  380. function GetSrc: String;
  381. function GetWidth: Integer;
  382. procedure SetHeight(AValue: Integer);
  383. procedure SetSrc(AValue: String);
  384. procedure SetWidth(AValue: Integer);
  385. Protected
  386. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  387. Property ImgElement : TJSHTMLImageElement Read GetImg;
  388. Public
  389. Function HTMLTag : String; override;
  390. Published
  391. Property Src : String Read GetSrc Write SetSrc;
  392. Property Width : Integer Read GetWidth Write SetWidth;
  393. Property Height : Integer Read GetHeight Write SetHeight;
  394. end;
  395. { TSelectWidget }
  396. TJSHTMLOptionElementArray = Array of TJSHTMLOptionElement;
  397. TCustomSelectWidget = Class;
  398. { TCustomSelectWidget }
  399. TCustomSelectWidget = class(TWebWidget)
  400. Private
  401. FSize,
  402. FSelectedIndex : Integer;
  403. FOptions : TJSHTMLOptionElementArray;
  404. FMultiple : Boolean;
  405. function GetMultiple: Boolean;
  406. function GetSelected(Index : Integer): Boolean;
  407. function GetSelectedIndex: Integer;
  408. function GetSelect: TJSHTMLSelectElement;
  409. function GetSelectionCount: Integer;
  410. function GetSelectionItem(aIndex : Integer): String;
  411. function GetSelectionValue(aIndex : Integer): String;
  412. function GetSize: Integer;
  413. procedure SetMultiple(AValue: Boolean);
  414. procedure SetSelected(Index : Integer; AValue: Boolean);
  415. procedure SetSelectedIndex(AValue: Integer);
  416. procedure SetSize(AValue: Integer);
  417. Protected
  418. Type
  419. { TSelectOptionEnumerator }
  420. TSelectOptionEnumerator = Class
  421. private
  422. FSelect: TCustomSelectWidget;
  423. public
  424. constructor Create(ASelect : TCustomSelectWidget); reintroduce; virtual;
  425. Function OptionText : String; virtual; abstract;
  426. Function HasValue : boolean; virtual;
  427. Function Value : string; virtual;
  428. function MoveNext: Boolean; virtual; abstract;
  429. Property Select: TCustomSelectWidget Read FSelect;
  430. end;
  431. Protected
  432. function GetItemCount: Integer; virtual;
  433. Function CreateOptionEnumerator : TSelectOptionEnumerator; virtual; abstract;
  434. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  435. Procedure BuildOptions(aSelect : TJSHTMLSelectElement); virtual;
  436. Property Options : TJSHTMLOptionElementArray Read Foptions;
  437. Property SelectElement : TJSHTMLSelectElement Read GetSelect;
  438. Protected
  439. // Can be made public/published
  440. // Items that are selected
  441. Property ItemCount : Integer Read GetItemCount;
  442. Property Selected[Index : Integer] : Boolean Read GetSelected Write SetSelected;
  443. Property SelectionCount : Integer Read GetSelectionCount;
  444. Property SelectionValue[aIndex : Integer] : String Read GetSelectionValue;
  445. Property SelectionItem[aIndex : Integer] : String Read GetSelectionItem;
  446. property SelectedIndex : Integer Read GetSelectedIndex Write SetSelectedindex;
  447. Property Multiple : Boolean Read GetMultiple Write SetMultiple;
  448. Property Size : Integer Read GetSize Write SetSize;
  449. Public
  450. Constructor Create(aOWner : TComponent); override;
  451. Function HTMLTag : String; override;
  452. end;
  453. TSelectWidget = class(TCustomSelectWidget)
  454. private
  455. FItems : TStrings;
  456. FValues : TStrings;
  457. function GetItems: TStrings;
  458. function GetValues: TStrings;
  459. procedure OptionsChanged(Sender: TObject);
  460. procedure setItems(AValue: TStrings);
  461. procedure setValues(AValue: TStrings);
  462. Protected
  463. Type
  464. { TStringsSelectOptionEnumerator }
  465. TStringsSelectOptionEnumerator = Class(TSelectOptionEnumerator)
  466. FCurrent : Integer;
  467. constructor Create(ASelect : TCustomSelectWidget); override;
  468. Function OptionText : String; override;
  469. Function HasValue : boolean; override;
  470. Function Value : string; override;
  471. function MoveNext: Boolean; override;
  472. end;
  473. Function CreateOptionEnumerator: TSelectOptionEnumerator; override;
  474. Public
  475. Constructor Create(aOWner : TComponent); override;
  476. Destructor Destroy; override;
  477. Property SelectionCount;
  478. Property SelectionValue;
  479. Property SelectionItem;
  480. Property Selected;
  481. Property Options;
  482. Property SelectElement;
  483. Property ItemCount;
  484. Published
  485. Property Items : TStrings Read GetItems Write setItems;
  486. Property Values : TStrings Read GetValues Write setValues;
  487. property SelectedIndex;
  488. Property Multiple;
  489. property size;
  490. property Classes;
  491. end;
  492. { TLabelWidget }
  493. TLabelWidget = Class(TWebWidget)
  494. private
  495. FLabelFor: TWebWidget;
  496. FText: String;
  497. function GetLabelEl: TJSHTMLLabelElement;
  498. function GetText: String;
  499. procedure SetLabelFor(AValue: TWebWidget);
  500. procedure SetText(AValue: String);
  501. Protected
  502. procedure ApplyLabelFor(aLabelElement: TJSHTMLLabelElement);
  503. Procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  504. Procedure SetName(const NewName: TComponentName); override;
  505. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  506. Property LabelElement : TJSHTMLLabelElement Read GetLabelEl;
  507. Public
  508. Function HTMLTag : String; override;
  509. Property Text : String Read GetText Write SetText;
  510. Property LabelFor : TWebWidget Read FLabelFor Write SetLabelFor;
  511. end;
  512. TTextTag = (ttParagraph,ttBold,ttItalic,ttUnderline,ttStrikeThrough,ttSpan,ttQuote,ttBlockQuote,ttH1,ttH2,ttH3,ttH4,ttH5,ttH6,ttPre,ttRuby,ttArticle,ttAddress,ttAbbr,ttCustom);
  513. { TTextWidget }
  514. { TCustomTextWidget }
  515. TCustomTextWidget = Class(TCustomWebWidget)
  516. private
  517. FCustomTag: String;
  518. FEnvelopeTag: TTextTag;
  519. FTextMode: TTextMode;
  520. procedure SetCustomTag(AValue: String);
  521. procedure SetEnvelopeTag(AValue: TTextTag);
  522. procedure SetTextMode(AValue: TTextMode);
  523. Protected
  524. procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  525. procedure ApplyText(aElement : TJSHTMLElement); virtual;
  526. Function GetText : String; virtual; abstract;
  527. Public
  528. Function HTMLTag : String; override;
  529. Published
  530. Property CustomTag : String Read FCustomTag Write SetCustomTag;
  531. Property EnvelopeTag : TTextTag Read FEnvelopeTag Write SetEnvelopeTag;
  532. Property TextMode : TTextMode Read FTextMode Write SetTextMode;
  533. end;
  534. TTextWidget = Class(TCustomTextWidget)
  535. private
  536. FText : String;
  537. procedure SetText(AValue: String);
  538. Protected
  539. Function GetText : String; override;
  540. published
  541. Property Text : String Read FText Write SetText;
  542. end;
  543. { TTextLinesWidget }
  544. TTextLinesWidget = Class(TCustomTextWidget)
  545. private
  546. FLines : TStrings;
  547. FForceLineBreaks: Boolean;
  548. procedure DoLinesChanged(Sender: TObject);
  549. procedure SetLines(AValue: TStrings);
  550. procedure SetForceLineBreaks(AValue: Boolean);
  551. Protected
  552. Function GetText : String; override;
  553. procedure ApplyText(aElement : TJSHTMLElement); override;
  554. Public
  555. Constructor Create(aOwner : TComponent); override;
  556. Destructor Destroy; override;
  557. published
  558. Property Lines : TStrings Read FLines Write SetLines;
  559. // When forcelinebreaks is true a <br> will be appended to every line.
  560. // Note that for TextMode=tmText this means the lines will be rendered as-is, but there will still be a <br> between the lines
  561. Property ForceLineBreaks : Boolean Read FForceLineBreaks Write SetForceLineBreaks;
  562. end;
  563. { TCustomTableColumn }
  564. TColumnOption = (coHeader,coCaptionHeader);
  565. TColumnOptions = set of TColumnOption;
  566. TCustomTableColumn = Class(TCollectionItem)
  567. private
  568. FAlignment: TAlignment;
  569. FCaption: String;
  570. FClassNames: String;
  571. procedure SetAlignment(AValue: TAlignment);
  572. procedure SetCaption(AValue: String);
  573. procedure SetClassNames(AValue: String);
  574. Protected
  575. Function GetDisplayName: string; override;
  576. function GetCaption: String; virtual;
  577. Public
  578. Procedure Assign(Source : TPersistent); override;
  579. Property Alignment : TAlignment Read FAlignment Write SetAlignment;
  580. Property Caption : String Read GetCaption Write SetCaption;
  581. Property ClassNames : String Read FClassNames Write SetClassNames;
  582. end;
  583. { TCustomTableColumns }
  584. TCustomTableColumns = Class(TCollection)
  585. private
  586. function GetCustomColumn(Index : Integer): TCustomTableColumn;
  587. procedure SetCustomColumn(Index : Integer; AValue: TCustomTableColumn);
  588. Protected
  589. Property CustomColumns [Index : Integer] : TCustomTableColumn Read GetCustomColumn Write SetCustomColumn; default;
  590. Public
  591. Function Add(aCaption : String): TCustomTableColumn; overload;
  592. end;
  593. { TCustomTableWidget }
  594. TTableOption = (toHeader, // use THead tag
  595. toHeaderRow, // Create header row
  596. toBody, // use TBody tag
  597. toFooter, // use TFoot tag
  598. toFooterRow, // create footer row
  599. toRowID, // add ID to tr: -kind-row
  600. toCellID, // add ID to cell td: -kind-row-col
  601. toHeaderRowData, // Add rowno to <tr data-row> for header.
  602. toHeaderCellDataRow, // Add rowno to <th data-row> for header. Automatic if onheadercellclick is set.
  603. toHeaderCellDataCol, // Add colno to <th data-col> for header. Automatic if onheadercellclick is set.
  604. toBodyRowData, // Add rowno to <tr data-row> for body.
  605. toBodyCellDataRow, // Add rowno to <th data-row> for body. Automatic if oncellclick is set.
  606. toBodyCellDataCol, // Add colno to <th data-col> for body. Automatic if oncellclick is set.
  607. tofooterRowData, // Add rowno to <tr data-row> for footer
  608. tofooterCellDataRow, // Add rowno to <th data-row> for footer. Automatic if onfootercellclick is set.
  609. tofooterCellDataCol // Add colno to <th data-col> for footer. Automatic if onfootercellclick is set.
  610. );
  611. TTableOptions = Set of TTableOption;
  612. TRowKind = (rkHeader,rkBody,rkFooter);
  613. Type
  614. TCustomTableWidget = Class;
  615. // Constructed only once when rendering !
  616. { TTableWidgetCelldata }
  617. TTableWidgetCellData = Class
  618. private
  619. FAsHTML: Boolean;
  620. FClassNames: String;
  621. FCol: Integer;
  622. FColumn: TCustomTableColumn;
  623. FContent: TJSHTMLElement;
  624. FKind: TRowKind;
  625. FRow: Integer;
  626. FTable: TCustomTableWidget;
  627. FTableID: String;
  628. FTag: String;
  629. FText: String;
  630. Protected
  631. Procedure SetRowColKind(aRow,aCol : Integer; aKind : TRowKind); virtual;
  632. Procedure Reset; // do not reset row,col, column
  633. Public
  634. Constructor Create(aTable : TCustomTableWidget;aTableID : String); virtual;
  635. Property Table : TCustomTableWidget Read FTable;
  636. Property Column : TCustomTableColumn Read FColumn;
  637. Property Row : Integer Read FRow;
  638. Property Col : Integer Read FCol;
  639. Property Kind : TRowKind Read FKind;
  640. Property Tag : String Read FTag Write FTag;
  641. Property ClassNames : String Read FClassNames Write FClassNames;
  642. Property Text : String Read FText Write FText;
  643. Property AsHTML : Boolean Read FAsHTML Write FAsHTML;
  644. Property Content : TJSHTMLElement Read FContent Write FContent;
  645. Property TableID : String Read FTableID;
  646. end;
  647. TTableRowEnumerator = Class
  648. private
  649. FTable: TCustomTableWidget;
  650. FCurrent : Integer;
  651. public
  652. constructor Create(ATable : TCustomTableWidget); reintroduce; virtual;
  653. Procedure GetCellData(aCell : TTableWidgetCellData); virtual;
  654. function MoveNext: Boolean; virtual;
  655. property CurrentRow : Integer Read FCurrent;
  656. Property Table : TCustomTableWidget Read FTable;
  657. end;
  658. TTableRowCountEnumerator = Class (TTableRowEnumerator)
  659. private
  660. FRowCount: Integer;
  661. public
  662. constructor Create(ATable : TCustomTableWidget;aCount : Integer); reintroduce;
  663. function MoveNext: Boolean; override;
  664. Property RowCount : Integer read FRowCount;
  665. end;
  666. TOnCellDataEvent = Procedure (Sender : TObject; Enum : TTableRowEnumerator; aCell : TTableWidgetCellData) of object;
  667. TCustomTableWidget = Class(TCustomWebWidget)
  668. private
  669. FCaption: String;
  670. FColumns: TCustomTableColumns;
  671. FOnCellClick: THTMLNotifyEvent;
  672. FOnFooterCellClick: THTMLNotifyEvent;
  673. FOnFooterRowClick: THTMLNotifyEvent;
  674. FOnHeaderCellClick: THTMLNotifyEvent;
  675. FOnHeaderRowClick: THTMLNotifyEvent;
  676. FOnRowClick: THTMLNotifyEvent;
  677. FTableOptions: TTableOptions;
  678. FOnGetCellData : TOnCellDataEvent;
  679. procedure SetCaption(AValue: String);
  680. procedure SetColumns(AValue: TCustomTableColumns);
  681. procedure SetTableOptions(AValue: TTableOptions);
  682. Public
  683. Protected
  684. procedure AppendCaption(aCaptionElement: TJSHTMLElement); virtual;
  685. procedure RenderData(aElement: TJSHTMLElement); virtual;
  686. function DoCellClick(aEvent: TJSMouseEvent): boolean; virtual;
  687. function DoHeaderCellClick(aEvent: TJSMouseEvent): boolean;virtual;
  688. function DoFooterCellClick(aEvent: TJSMouseEvent): boolean;virtual;
  689. function DoRowClick(aEvent: TJSMouseEvent): boolean; virtual;
  690. function DoHeaderRowClick(aEvent: TJSMouseEvent): boolean;virtual;
  691. function DoFooterRowClick(aEvent: TJSMouseEvent): boolean;virtual;
  692. function CreateColumns: TCustomTableColumns; virtual;
  693. Function DefaultTableOptions: TTableOptions; virtual;
  694. Procedure CreateDefaultColumns; virtual;
  695. Function GetRowEnumerator(aKind : TRowKind) : TTableRowEnumerator; virtual;
  696. function RenderCell(aCell: TTableWidgetCellData): TJSHTMLElement; virtual;
  697. procedure RenderRow(aEnum : TTableRowEnumerator; aParent: TJSHTMLElement; aKind: TRowKind; aCell: TTableWidgetCellData); virtual;
  698. procedure RenderRows(aParent: TJSHTMLElement; aKind : TRowKind; aCell: TTableWidgetCellData); virtual;
  699. Procedure ApplyWidgetSettings(aElement : TJSHTMLElement); override;
  700. Function HTMLTag : String; override;
  701. Function CreateCellData(const aTableID : String) : TTableWidgetCellData; virtual;
  702. Function GetBodyRowEnumerator : TTableRowEnumerator; virtual; abstract;
  703. Protected
  704. // These can be made public/published
  705. Property CustomColumns : TCustomTableColumns Read FColumns Write SetColumns;
  706. Property TableOptions : TTableOptions read FTableOptions write SetTableOptions;
  707. Property Caption : String Read FCaption Write SetCaption;
  708. Property OnGetCellData : TOnCellDataEvent Read FOnGetCellData Write FOnGetCellData;
  709. Property OnCellClick : THTMLNotifyEvent Read FOnCellClick Write FOnCellClick;
  710. Property OnHeaderCellClick : THTMLNotifyEvent Read FOnHeaderCellClick Write FOnHeaderCellClick;
  711. Property OnFooterCellClick : THTMLNotifyEvent Read FOnFooterCellClick Write FOnFooterCellClick;
  712. Property OnRowClick : THTMLNotifyEvent Read FOnRowClick Write FOnRowClick;
  713. Property OnHeaderRowClick : THTMLNotifyEvent Read FOnHeaderRowClick Write FOnHeaderRowClick;
  714. Property OnFooterRowClick : THTMLNotifyEvent Read FOnFooterRowClick Write FOnFooterRowClick;
  715. Public
  716. Constructor Create(aOwner : TComponent); override;
  717. Destructor Destroy; override;
  718. Procedure RefreshBody;
  719. end;
  720. TTableWidget = Class(TCustomTableWidget)
  721. Public
  722. Property CustomColumns;
  723. Property TableOptions;
  724. Property Caption;
  725. Property OnGetCellData;
  726. Property OnCellClick;
  727. Property OnHeaderCellClick;
  728. Property OnFooterCellClick;
  729. Property OnRowClick;
  730. Property OnHeaderRowClick;
  731. Property OnFooterRowClick;
  732. end;
  733. { TDivWidget }
  734. TDivWidget = Class(TWebWidget)
  735. Protected
  736. Function HTMLTag : String; override;
  737. end;
  738. Function ViewPort : TViewPort;
  739. Const
  740. TextTagNames : Array[TTextTag] of string
  741. = ('p','b','i','u','s','span','quote','blockquote','h1','h2','h3','h4','h5','h6','pre','ruby','article','address','abbr','');
  742. RowKindNames : Array[TRowKind] of string = ('header','body','footer');
  743. implementation
  744. uses DateUtils;
  745. resourcestring
  746. SErrInvalidIndex = 'Index %d not in valid range of [0..%d]';
  747. Function ViewPort : TViewPort;
  748. begin
  749. Result:=TViewPort.Instance;
  750. end;
  751. { TTableRowCountEnumerator }
  752. Const
  753. CellTags : Array[TRowKind] of string = ('th','td','td');
  754. { TDivWidget }
  755. function TDivWidget.HTMLTag: String;
  756. begin
  757. Result:='DIV';
  758. end;
  759. { TSelectWidget.TStringsSelectOptionEnumerator }
  760. constructor TSelectWidget.TStringsSelectOptionEnumerator.Create(ASelect: TCustomSelectWidget);
  761. begin
  762. inherited Create(ASelect);
  763. FCurrent:=-1;
  764. end;
  765. function TSelectWidget.TStringsSelectOptionEnumerator.OptionText: String;
  766. begin
  767. Result:=TSelectWidget(Select).Items[FCurrent];
  768. end;
  769. function TSelectWidget.TStringsSelectOptionEnumerator.HasValue: boolean;
  770. begin
  771. Result:=FCurrent<TSelectWidget(Select).Values.Count;
  772. end;
  773. function TSelectWidget.TStringsSelectOptionEnumerator.Value: string;
  774. begin
  775. Result:=TSelectWidget(Select).Values[FCurrent];
  776. end;
  777. function TSelectWidget.TStringsSelectOptionEnumerator.MoveNext: Boolean;
  778. begin
  779. Result:=FCurrent<TSelectWidget(Select).Items.Count-1;
  780. if Result then
  781. Inc(FCurrent);
  782. end;
  783. { TCustomSelectWidget.TSelectOptionEnumerator }
  784. constructor TCustomSelectWidget.TSelectOptionEnumerator.Create(ASelect: TCustomSelectWidget);
  785. begin
  786. FSelect:=ASelect;
  787. end;
  788. function TCustomSelectWidget.TSelectOptionEnumerator.HasValue: boolean;
  789. begin
  790. Result:=False;
  791. end;
  792. function TCustomSelectWidget.TSelectOptionEnumerator.Value: string;
  793. begin
  794. Result:='';
  795. end;
  796. constructor TTableRowCountEnumerator.Create(ATable: TCustomTableWidget; aCount: Integer);
  797. begin
  798. Inherited Create(aTable);
  799. FRowCount:=aCount;
  800. end;
  801. function TTableRowCountEnumerator.MoveNext: Boolean;
  802. begin
  803. Result:=Inherited MoveNext and (CurrentRow<RowCount)
  804. end;
  805. { TTableWidgetCellData }
  806. procedure TTableWidgetCellData.SetRowColKind(aRow, aCol: Integer; aKind: TRowKind);
  807. begin
  808. if (aRow<>-1) then
  809. FRow:=aRow;
  810. if (aCol<>-1) then
  811. FCol:=aCol;
  812. FKind:=aKind;
  813. end;
  814. procedure TTableWidgetCellData.Reset;
  815. begin
  816. Ftag:='td';
  817. FClassNames:='';
  818. FText:='';
  819. FContent:=Nil;
  820. FAsHTML:=False;
  821. end;
  822. constructor TTableWidgetCellData.Create(aTable: TCustomTableWidget; aTableID: String);
  823. begin
  824. FTable:=aTable;
  825. FTableID:=aTableID;
  826. SetRowColKind(0,0,rkBody);
  827. end;
  828. { TCustomTableWidget }
  829. procedure TCustomTableWidget.SetColumns(AValue: TCustomTableColumns);
  830. begin
  831. if FColumns=AValue then Exit;
  832. FColumns.Assign(AValue);
  833. end;
  834. procedure TCustomTableWidget.SetCaption(AValue: String);
  835. begin
  836. if FCaption=AValue then Exit;
  837. FCaption:=AValue;
  838. if isRendered then Refresh;
  839. end;
  840. function TCustomTableWidget.DoCellClick(aEvent: TJSMouseEvent): boolean;
  841. begin
  842. If Assigned(FOnCellClick) then
  843. FOnCellClick(Self,aEvent);
  844. If Assigned(FOnRowClick) then
  845. FOnRowClick(Self,aEvent);
  846. Result:=False;
  847. // Writeln('On click for cell',aEvent.targetElement.innerText);
  848. end;
  849. function TCustomTableWidget.DoHeaderCellClick(aEvent: TJSMouseEvent): boolean;
  850. begin
  851. If Assigned(FOnHeaderCellClick) then
  852. FOnHeaderCellClick(Self,aEvent);
  853. If Assigned(FOnHeaderRowClick) then
  854. FOnHeaderRowClick(Self,aEvent);
  855. Result:=False;
  856. // Writeln('On click for header cell',aEvent.targetElement.innerText);
  857. end;
  858. function TCustomTableWidget.DoFooterCellClick(aEvent: TJSMouseEvent): boolean;
  859. begin
  860. If Assigned(FOnFooterCellClick) then
  861. FOnFooterCellClick(Self,aEvent);
  862. If Assigned(FOnFooterRowClick) then
  863. FOnFooterRowClick(Self,aEvent);
  864. Result:=False;
  865. // Writeln('On click for Footer cell',aEvent.targetElement.innerText);
  866. end;
  867. function TCustomTableWidget.DoRowClick(aEvent: TJSMouseEvent): boolean;
  868. begin
  869. If Assigned(FOnRowClick) then
  870. FOnRowClick(Self,aEvent);
  871. Result:=False;
  872. // Writeln('On click for Row',aEvent.targetElement.innerText);
  873. end;
  874. function TCustomTableWidget.DoHeaderRowClick(aEvent: TJSMouseEvent): boolean;
  875. begin
  876. If Assigned(FOnHeaderRowClick) then
  877. FOnHeaderRowClick(Self,aEvent);
  878. Result:=False;
  879. // Writeln('On click for Header Row',aEvent.targetElement.innerText);
  880. end;
  881. function TCustomTableWidget.DoFooterRowClick(aEvent: TJSMouseEvent): boolean;
  882. begin
  883. If Assigned(FOnFooterRowClick) then
  884. FOnFooterRowClick(Self,aEvent);
  885. Result:=False;
  886. // Writeln('On click for Footer Row',aEvent.targetElement.innerText);
  887. end;
  888. procedure TCustomTableWidget.SetTableOptions(AValue: TTableOptions);
  889. begin
  890. if FTableOptions=AValue then Exit;
  891. FTableOptions:=AValue;
  892. if IsRendered then
  893. Refresh;
  894. end;
  895. procedure TCustomTableWidget.AppendCaption(aCaptionElement: TJSHTMLElement);
  896. begin
  897. aCaptionElement.InnerHTML:=Caption;
  898. end;
  899. function TCustomTableWidget.GetRowEnumerator(aKind: TRowKind): TTableRowEnumerator;
  900. begin
  901. Case aKind of
  902. rkHeader : Result:=TTableRowCountEnumerator.Create(Self,1);
  903. rkFooter : Result:=TTableRowCountEnumerator.Create(Self,1);
  904. rkBody : Result:=GetBodyRowEnumerator;
  905. end;
  906. end;
  907. procedure TTableRowEnumerator.GetCellData(aCell: TTableWidgetCellData);
  908. Var
  909. K : TRowKind;
  910. begin
  911. K:=aCell.Kind;
  912. Case K of
  913. rkHeader:
  914. begin
  915. aCell.Tag:='th';
  916. aCell.Text:=ACell.Column.Caption;
  917. end;
  918. rkFooter,
  919. rkBody :
  920. begin
  921. aCell.Tag:='td';
  922. end;
  923. end;
  924. end;
  925. function TCustomTableWidget.HTMLTag: String;
  926. begin
  927. Result:='table';
  928. end;
  929. function TCustomTableWidget.RenderCell(aCell: TTableWidgetCellData): TJSHTMLElement;
  930. Const
  931. Aligns : Array[TAlignment] of string = ('left','right','center');
  932. RowChecks : Array[TRowKind] of TTableOption = (toHeaderCellDataRow,toBodyCellDataRow,toFooterCellDataRow);
  933. ColChecks : Array[TRowKind] of TTableOption = (toHeaderCellDataCol,toBodyCellDataCol,toFooterCellDataCol);
  934. Var
  935. C : TJSHtmlElement;
  936. cl : THTMLNotifyEvent;
  937. K : TRowKind;
  938. M : THTMLClickEventHandler;
  939. elID : string;
  940. begin
  941. K:=aCell.Kind;
  942. if toCellID in TableOptions then
  943. elID:=aCell.TableID+'-'+RowKindNames[K]+'-'+IntToStr(ACell.Row)+'-'+IntToStr(aCell.Col)
  944. else
  945. elID:='';
  946. C:=CreateElement(aCell.Tag,elID);
  947. if aCell.Content<>Nil then
  948. C.AppendChild(aCell.Content)
  949. else if aCell.AsHTML then
  950. C.innerHTML:=aCell.text
  951. else
  952. C.innerText:=aCell.text;
  953. C.className:=AddClasses(aCell.Column.ClassNames,aCell.ClassNames);
  954. if ACell.Column.Alignment<>taLeftJustify then
  955. C.Style.setProperty('text-align',Aligns[ACell.Column.Alignment]);
  956. Case K of
  957. rkBody :
  958. begin
  959. CL:=FOnCellClick;
  960. M:=@DoCellClick;
  961. end;
  962. rkHeader :
  963. begin
  964. CL:=FOnHeaderCellClick;
  965. M:=@DoHeaderCellClick;
  966. end;
  967. rkFooter :
  968. begin
  969. CL:=FOnFooterCellClick;
  970. M:=@DoFooterCellClick;
  971. end;
  972. else
  973. CL:=Nil;
  974. M:=nil;
  975. end;
  976. if Assigned(cl) or (RowChecks[K] in TableOptions) then
  977. begin
  978. C.dataset['row']:=ACell.Row;
  979. C.Dataset['kind']:=RowKindNames[K];
  980. end;
  981. if Assigned(cl) or (ColChecks[K] in TableOptions) then
  982. begin
  983. C.dataset['col']:=ACell.Col;
  984. C.Dataset['kind']:=RowKindNames[K];
  985. end;
  986. if Assigned(M) then
  987. C.OnClick:=M;
  988. Result:=C;
  989. end;
  990. procedure TCustomTableWidget.RenderRow(aEnum: TTableRowEnumerator; aParent: TJSHTMLElement; aKind: TRowKind; aCell: TTableWidgetCellData);
  991. Var
  992. I: integer;
  993. begin
  994. For I:=0 to CustomColumns.Count-1 do
  995. begin
  996. aCell.Reset;
  997. aCell.FColumn:=CustomColumns[i];
  998. aCell.SetRowColKind(-1,I,aKind);
  999. // Writeln(CellKinds[aKind],' cell before : ',aCell.Tag,' data : ',aCell.Text);
  1000. aEnum.GetCellData(aCell);
  1001. // Writeln(CellKinds[aKind],' cell after : ',aCell.Tag,' data : ',aCell.Text);
  1002. if aCell.Tag='' then
  1003. ACell.Tag:=CellTags[aKind];
  1004. if Assigned(FOnGetCellData) then
  1005. FOnGetCellData(Self,aEnum,aCell);
  1006. aParent.appendChild(RenderCell(aCell));
  1007. end;
  1008. end;
  1009. procedure TCustomTableWidget.RenderRows(aParent: TJSHTMLElement; aKind: TRowKind; aCell: TTableWidgetCellData);
  1010. Const
  1011. TableRowChecks : Array[TRowKind] of TTableOption = (toHeaderRowData,toBodyRowData,toFooterRowData);
  1012. Var
  1013. RowEl : TJSHTMLElement;
  1014. Enum : TTableRowEnumerator;
  1015. M : THTMLClickEventHandler;
  1016. cl : THTMLNotifyEvent;
  1017. elid : String;
  1018. begin
  1019. Enum:=GetRowEnumerator(aKind);
  1020. if Enum=Nil then
  1021. Exit;
  1022. try
  1023. While Enum.MoveNext do
  1024. begin
  1025. if toRowID in TableOptions then
  1026. elID:=aCell.TableID+'-'+RowKindNames[aKind]+'-'+IntToStr(Enum.CurrentRow)
  1027. else
  1028. elID:='';
  1029. RowEl:=CreateElement('tr',elID);
  1030. aCell.SetRowColKind(Enum.CurrentRow,-1,aKind);
  1031. Case aKind of
  1032. rkBody :
  1033. begin
  1034. CL:=FOnRowClick;
  1035. M:=@DoRowClick;
  1036. end;
  1037. rkHeader :
  1038. begin
  1039. CL:=FOnHeaderRowClick;
  1040. M:=@DoHeaderRowClick;
  1041. end;
  1042. rkFooter :
  1043. begin
  1044. CL:=FOnFooterRowClick;
  1045. M:=@DoFooterRowClick;
  1046. end;
  1047. end;
  1048. if Assigned(CL) or (TableRowChecks[Akind] in TableOptions) then
  1049. begin
  1050. RowEl.dataset['row']:=Enum.CurrentRow;
  1051. RowEl.dataset['kind']:=RowKindNames[aKind];
  1052. end;
  1053. if Assigned(M) then
  1054. RowEl.OnClick:=M;
  1055. RenderRow(Enum,RowEl,aKind,aCell);
  1056. aParent.AppendChild(RowEl);
  1057. end;
  1058. finally
  1059. Enum.Free;
  1060. end;
  1061. end;
  1062. procedure TCustomTableWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1063. begin
  1064. inherited ApplyWidgetSettings(aElement);
  1065. RenderData(aElement);
  1066. end;
  1067. procedure TCustomTableWidget.RenderData(aElement: TJSHTMLElement);
  1068. Var
  1069. El : TJSHTMLElement;
  1070. aCell : TTableWidgetCellData;
  1071. begin
  1072. if (Caption<>'') then
  1073. begin
  1074. El:=CreateElement('caption',aElement.ID+'-caption');
  1075. AppendCaption(EL);
  1076. aElement.AppendChild(EL);
  1077. end;
  1078. aCell:=CreateCellData(aElement.ID);
  1079. If (CustomColumns.Count=0) then
  1080. CreateDefaultColumns;
  1081. if toHeaderRow in TableOptions then
  1082. begin
  1083. if toHeader in TableOptions then
  1084. begin
  1085. El:=CreateElement('thead',aElement.ID+'-head');
  1086. aElement.AppendChild(el);
  1087. end
  1088. else
  1089. El:=aElement;
  1090. aCell.SetRowColKind(-1,-1,rkHeader);
  1091. RenderRows(El,rkHeader,aCell);
  1092. end;
  1093. if toBody in TableOptions then
  1094. begin
  1095. El:=CreateElement('tbody',aElement.ID+'-body');
  1096. aElement.AppendChild(el);
  1097. end
  1098. else
  1099. El:=aElement;
  1100. aCell.SetRowColKind(-1,-1,rkBody);
  1101. RenderRows(El,rkBody,aCell);
  1102. if toFooterRow in TableOptions then
  1103. begin
  1104. if toFooter in TableOptions then
  1105. begin
  1106. El:=CreateElement('tFoot',aElement.ID+'-foot');
  1107. aElement.AppendChild(el);
  1108. end
  1109. else
  1110. El:=aElement;
  1111. aCell.SetRowColKind(-1,-1,rkFooter);
  1112. RenderRows(El,rkFooter,aCell);
  1113. end;
  1114. end;
  1115. function TCustomTableWidget.CreateCellData(const aTableID : String): TTableWidgetCellData;
  1116. begin
  1117. Result:=TTableWidgetCellData.Create(Self,aTableID);
  1118. end;
  1119. function TCustomTableWidget.CreateColumns: TCustomTableColumns;
  1120. begin
  1121. Result:=TCustomTableColumns.Create(TCustomTableColumn);
  1122. end;
  1123. function TCustomTableWidget.DefaultTableOptions: TTableOptions;
  1124. begin
  1125. Result:=[toHeader,toBody,toFooter,toHeaderRow]
  1126. end;
  1127. procedure TCustomTableWidget.CreateDefaultColumns;
  1128. begin
  1129. // Do nothing
  1130. end;
  1131. constructor TCustomTableWidget.Create(aOwner: TComponent);
  1132. begin
  1133. inherited Create(aOwner);
  1134. FTableOptions:=DefaultTableOptions;
  1135. FColumns:=CreateColumns;
  1136. end;
  1137. destructor TCustomTableWidget.Destroy;
  1138. begin
  1139. FreeAndNil(FColumns);
  1140. inherited Destroy;
  1141. end;
  1142. procedure TCustomTableWidget.RefreshBody;
  1143. begin
  1144. if Not Assigned(Element) then
  1145. Refresh
  1146. else
  1147. begin
  1148. Element.Innerhtml:='';
  1149. RenderData(Element);
  1150. end;
  1151. end;
  1152. { TCustomTableColumn }
  1153. procedure TCustomTableColumn.SetAlignment(AValue: TAlignment);
  1154. begin
  1155. if FAlignment=AValue then Exit;
  1156. FAlignment:=AValue;
  1157. end;
  1158. function TCustomTableColumn.GetCaption: String;
  1159. begin
  1160. Result:=FCaption;
  1161. end;
  1162. procedure TCustomTableColumn.SetCaption(AValue: String);
  1163. begin
  1164. if FCaption=AValue then Exit;
  1165. FCaption:=AValue;
  1166. end;
  1167. procedure TCustomTableColumn.SetClassNames(AValue: String);
  1168. begin
  1169. if FClassNames=AValue then Exit;
  1170. FClassNames:=AValue;
  1171. end;
  1172. function TCustomTableColumn.GetDisplayName: string;
  1173. begin
  1174. Result:=Caption;
  1175. end;
  1176. procedure TCustomTableColumn.Assign(Source: TPersistent);
  1177. Var
  1178. C : TCustomTableColumn;
  1179. begin
  1180. if Source is TCustomTableColumn then
  1181. begin
  1182. C:=Source as TCustomTableColumn;
  1183. FCaption:=C.FCaption;
  1184. FClassNames:=C.FClassNames;
  1185. FAlignment:=C.Alignment;
  1186. end
  1187. else
  1188. inherited Assign(Source);
  1189. end;
  1190. { TCustomTableColumns }
  1191. function TCustomTableColumns.GetCustomColumn(Index : Integer): TCustomTableColumn;
  1192. begin
  1193. Result:=TCustomTableColumn(Items[Index]);
  1194. end;
  1195. procedure TCustomTableColumns.SetCustomColumn(Index : Integer; AValue: TCustomTableColumn);
  1196. begin
  1197. Items[Index]:=aValue;
  1198. end;
  1199. function TCustomTableColumns.Add(aCaption: String): TCustomTableColumn;
  1200. begin
  1201. Result:=add as TCustomTableColumn;
  1202. Result.Caption:=aCaption;
  1203. end;
  1204. { TTableRowEnumerator }
  1205. constructor TTableRowEnumerator.Create(ATable: TCustomTableWidget);
  1206. begin
  1207. FTable:=aTable;
  1208. FCurrent:=-1;
  1209. end;
  1210. function TTableRowEnumerator.MoveNext: Boolean;
  1211. begin
  1212. Inc(FCurrent);
  1213. Result:=True;
  1214. end;
  1215. { TCustomTextWidget }
  1216. procedure TCustomTextWidget.SetEnvelopeTag(AValue: TTextTag);
  1217. begin
  1218. // Writeln('Setting text tag : ',aValue);
  1219. if FEnvelopeTag=AValue then Exit;
  1220. FEnvelopeTag:=AValue;
  1221. if (FEnvelopeTag=ttCustom) and (FCustomTag='') then
  1222. FCustomTag:='div';
  1223. if IsRendered then
  1224. Refresh;
  1225. end;
  1226. procedure TCustomTextWidget.SetCustomTag(AValue: String);
  1227. begin
  1228. if FCustomTag=AValue then Exit;
  1229. FCustomTag:=AValue;
  1230. if (FCustomTag<>'') then
  1231. FEnvelopeTag:=ttCustom;
  1232. if IsRendered then
  1233. Refresh;
  1234. end;
  1235. procedure TCustomTextWidget.SetTextMode(AValue: TTextMode);
  1236. begin
  1237. if FTextMode=AValue then Exit;
  1238. FTextMode:=AValue;
  1239. if IsRendered then
  1240. ApplyText(Element);
  1241. end;
  1242. procedure TCustomTextWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1243. begin
  1244. // Writeln('ApplyWidgetSettings: ',aElement.tagName);
  1245. inherited ApplyWidgetSettings(aElement);
  1246. ApplyText(aElement);
  1247. end;
  1248. procedure TCustomTextWidget.ApplyText(aElement: TJSHTMLElement);
  1249. begin
  1250. if FTextMode=tmText then
  1251. aElement.innerText:=GetText
  1252. else
  1253. aElement.innerHTML:=GetText;
  1254. end;
  1255. function TCustomTextWidget.HTMLTag: String;
  1256. begin
  1257. Result:=TextTagNames[FEnvelopeTag];
  1258. if Result='' then
  1259. Result:='div';
  1260. // Writeln('Getting element tag: ',Result);
  1261. end;
  1262. { TTextLinesWidget }
  1263. procedure TTextLinesWidget.SetLines(AValue: TStrings);
  1264. begin
  1265. if FLines=AValue then Exit;
  1266. FLines.Assign(AValue);
  1267. end;
  1268. procedure TTextLinesWidget.SetForceLineBreaks(AValue: Boolean);
  1269. begin
  1270. if FForceLineBreaks=AValue then Exit;
  1271. FForceLineBreaks:=AValue;
  1272. if IsRendered then
  1273. ApplyText(Element);
  1274. end;
  1275. procedure TTextLinesWidget.DoLinesChanged(Sender: TObject);
  1276. begin
  1277. if IsRendered then
  1278. ApplyText(Element);
  1279. end;
  1280. function TTextLinesWidget.GetText: String;
  1281. Var
  1282. I : integer;
  1283. begin
  1284. if (FTextMode=tmHTML) and ForceLineBreaks then
  1285. begin
  1286. Result:='';
  1287. For I:=0 to FLines.Count-1 do
  1288. Result:=Result+flines[i]+'<br/>';
  1289. end
  1290. else
  1291. Result:=FLines.Text;
  1292. end;
  1293. procedure TTextLinesWidget.ApplyText(aElement: TJSHTMLElement);
  1294. Var
  1295. I : integer;
  1296. begin
  1297. if (TextMode=tmHTML) or (Not ForceLineBreaks) then
  1298. inherited ApplyText(aElement)
  1299. else
  1300. begin
  1301. For I:=0 to FLines.Count-1 do
  1302. begin
  1303. aElement.AppendChild(Document.createTextNode(FLines[i]));
  1304. aElement.AppendChild(CreateElement('br',''));
  1305. end;
  1306. end;
  1307. end;
  1308. constructor TTextLinesWidget.Create(aOwner: TComponent);
  1309. begin
  1310. inherited Create(aOwner);
  1311. FLines:=TstringList.Create;
  1312. TstringList(FLines).OnChange:=@DoLinesChanged;
  1313. end;
  1314. destructor TTextLinesWidget.Destroy;
  1315. begin
  1316. FLines:=TstringList.Create;
  1317. inherited Destroy;
  1318. end;
  1319. { TTextWidget }
  1320. procedure TTextWidget.SetText(AValue: String);
  1321. begin
  1322. if FText=AValue then Exit;
  1323. FText:=AValue;
  1324. if IsRendered then
  1325. ApplyText(Element);
  1326. end;
  1327. function TTextWidget.GetText: String;
  1328. begin
  1329. Result:=FText;
  1330. end;
  1331. { TLabelWidget }
  1332. procedure TLabelWidget.ApplyLabelFor(aLabelElement : TJSHTMLLabelElement);
  1333. begin
  1334. if Assigned(FlabelFor) then
  1335. begin
  1336. FlabelFor.EnsureElement;
  1337. aLabelElement.for_:=FlabelFor.ElementID;
  1338. end
  1339. else
  1340. aLabelElement.for_:='';
  1341. end;
  1342. procedure TLabelWidget.SetLabelFor(AValue: TWebWidget);
  1343. begin
  1344. if (FLabelFor=AValue) then Exit;
  1345. if Assigned(FLabelFor) then
  1346. FLabelFor.RemoveFreeNotification(Self);
  1347. FLabelFor:=AValue;
  1348. if Assigned(FLabelFor) then
  1349. FLabelFor.FreeNotification(Self);
  1350. If IsRendered then
  1351. ApplyLabelFor(LabelElement);
  1352. end;
  1353. function TLabelWidget.GetText: String;
  1354. begin
  1355. if IsElementDirty then
  1356. FText:=Element.InnerText;
  1357. Result:=FText;
  1358. end;
  1359. function TLabelWidget.GetLabelEl: TJSHTMLLabelElement;
  1360. begin
  1361. Result:=TJSHTMLLabelElement(Element);
  1362. end;
  1363. procedure TLabelWidget.SetText(AValue: String);
  1364. begin
  1365. If Text=aValue then exit;
  1366. Ftext:=aValue;
  1367. If IsRendered then
  1368. Element.innerText:=aValue;
  1369. end;
  1370. procedure TLabelWidget.Notification(AComponent: TComponent; Operation: TOperation);
  1371. begin
  1372. inherited Notification(AComponent, Operation);
  1373. if (Operation=opRemove) and (aComponent=FLabelFor) then
  1374. FLabelFor:=Nil;
  1375. end;
  1376. procedure TLabelWidget.SetName(const NewName: TComponentName);
  1377. Var
  1378. Old : String;
  1379. begin
  1380. Old:=Name;
  1381. inherited SetName(NewName);
  1382. if (csDesigning in ComponentState) then
  1383. if Old=Text then
  1384. Text:=Old;
  1385. end;
  1386. procedure TLabelWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1387. var
  1388. lbl : TJSHTMLLabelElement absolute aElement;
  1389. begin
  1390. inherited ApplyWidgetSettings(aElement);
  1391. lbl.InnerText:=Text;
  1392. ApplyLabelFor(Lbl);
  1393. end;
  1394. function TLabelWidget.HTMLTag: String;
  1395. begin
  1396. Result:='label';
  1397. end;
  1398. { TSelectWidget }
  1399. function TCustomSelectWidget.GetSelectedIndex: Integer;
  1400. begin
  1401. if IsRendered then
  1402. FSelectedIndex:=SelectElement.selectedIndex;
  1403. Result:=FSelectedIndex
  1404. end;
  1405. function TCustomSelectWidget.GetMultiple: Boolean;
  1406. begin
  1407. if IsElementDirty then
  1408. FMultiple:=SelectElement.multiple;
  1409. Result:=FMultiple;
  1410. end;
  1411. function TCustomSelectWidget.GetItemCount: Integer;
  1412. begin
  1413. Result:=Length(Options);
  1414. end;
  1415. function TCustomSelectWidget.GetSelected(Index : Integer): Boolean;
  1416. begin
  1417. if (Index<0) or (Index>=Length(Foptions)) then
  1418. Raise EWidgets.CreateFmt(SErrInvalidIndex,[Index,Length(Foptions)-1]);
  1419. Result:=FOptions[Index].Selected
  1420. end;
  1421. function TCustomSelectWidget.GetSelect: TJSHTMLSelectElement;
  1422. begin
  1423. Result:=TJSHTMLSelectElement(Element);
  1424. end;
  1425. function TCustomSelectWidget.GetSelectionCount: Integer;
  1426. begin
  1427. Result:=SelectElement.selectedOptions.length;
  1428. end;
  1429. function TCustomSelectWidget.GetSelectionItem(aIndex : Integer): String;
  1430. begin
  1431. if (aIndex<0) or (aindex>=GetSelectionCount) then
  1432. Raise EWidgets.CreateFmt(SErrInvalidIndex,[aIndex,GetSelectionCount-1]);
  1433. Result:=TJSHTMLOptionElement(SelectElement.selectedOptions.item(aIndex)).innerText;
  1434. end;
  1435. function TCustomSelectWidget.GetSelectionValue(aIndex : Integer): String;
  1436. begin
  1437. if (aIndex<0) or (aindex>=GetSelectionCount) then
  1438. Raise EWidgets.CreateFmt(SErrInvalidIndex,[aIndex,GetSelectionCount-1]);
  1439. Result:=TJSHTMLOptionElement(SelectElement.selectedOptions.item(aIndex)).value;
  1440. end;
  1441. function TCustomSelectWidget.GetSize: Integer;
  1442. begin
  1443. if IsElementDirty then
  1444. FSize:=SelectElement.Size;
  1445. Result:=FSize;
  1446. end;
  1447. procedure TCustomSelectWidget.SetMultiple(AValue: Boolean);
  1448. begin
  1449. If (AValue=Multiple) then exit;
  1450. FMultiple:=aValue;
  1451. If IsRendered then
  1452. SelectElement.multiple:=FMultiple;
  1453. end;
  1454. procedure TCustomSelectWidget.SetSelected(Index : Integer; AValue: Boolean);
  1455. begin
  1456. if (Index<0) or (Index>=Length(Foptions)) then
  1457. Raise EWidgets.CreateFmt(SErrInvalidIndex,[Index,Length(Foptions)-1]);
  1458. FOptions[Index].Selected:=aValue;
  1459. end;
  1460. procedure TCustomSelectWidget.SetSelectedIndex(AValue: Integer);
  1461. begin
  1462. if (SelectedIndex=aValue) then
  1463. Exit;
  1464. FSelectedIndex:=aValue;
  1465. if IsRendered then
  1466. SelectElement.SelectedIndex:=FSelectedIndex;
  1467. if Assigned(OnChange) then
  1468. OnChange(Self,Nil);
  1469. end;
  1470. procedure TCustomSelectWidget.SetSize(AValue: Integer);
  1471. begin
  1472. If (AValue=Size) then exit;
  1473. FSize:=aValue;
  1474. If IsRendered then
  1475. SelectElement.Size:=FSize;
  1476. end;
  1477. procedure TCustomSelectWidget.BuildOptions(aSelect: TJSHTMLSelectElement);
  1478. Var
  1479. O : TJSHTMLOptionElement;
  1480. Idx : Integer;
  1481. enum : TSelectOptionEnumerator;
  1482. begin
  1483. // Clear
  1484. SetLength(FOptions,0);
  1485. aSelect.InnerHTML:='';
  1486. // Rebuild
  1487. Idx:=0;
  1488. enum:=CreateOptionEnumerator;
  1489. While enum.MoveNext do
  1490. begin
  1491. O:=TJSHTMLOptionElement(CreateElement('option',''));
  1492. O.innerText:=enum.OptionText;
  1493. if enum.HasValue then
  1494. O.value:=enum.Value;
  1495. if Idx=FSelectedIndex then
  1496. O.selected:=True;
  1497. aSelect.AppendChild(O);
  1498. Inc(Idx);
  1499. end;
  1500. SetLength(Foptions,Idx);
  1501. Dec(idx);
  1502. While Idx>=0 do
  1503. begin
  1504. FOptions[Idx]:=TJSHTMLOptionElement(aSelect.Children[Idx]);
  1505. dec(Idx);
  1506. end;
  1507. end;
  1508. constructor TCustomSelectWidget.Create(aOWner: TComponent);
  1509. begin
  1510. inherited Create(aOWner);
  1511. FSelectedIndex:=-1;
  1512. end;
  1513. procedure TCustomSelectWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1514. Var
  1515. el : TJSHTmlSelectElement absolute aElement;
  1516. begin
  1517. inherited ApplyWidgetSettings(aElement);
  1518. el.multiple:=Self.Multiple;
  1519. el.Size:=Self.Size;
  1520. BuildOptions(el);
  1521. // We need to force this.
  1522. if SelectedIndex=-1 then
  1523. el.selectedIndex:=-1;
  1524. end;
  1525. function TCustomSelectWidget.HTMLTag: String;
  1526. begin
  1527. Result:='select';
  1528. end;
  1529. { TSelectWidget }
  1530. function TSelectWidget.GetItems: TStrings;
  1531. begin
  1532. Result:=FItems;
  1533. end;
  1534. function TSelectWidget.GetValues: TStrings;
  1535. begin
  1536. Result:=FValues;
  1537. end;
  1538. procedure TSelectWidget.OptionsChanged(Sender: TObject);
  1539. begin
  1540. if IsRendered then
  1541. BuildOptions(SelectElement);
  1542. end;
  1543. procedure TSelectWidget.setItems(AValue: TStrings);
  1544. begin
  1545. If (AValue=FItems) then exit;
  1546. FItems.Assign(aValue);
  1547. end;
  1548. procedure TSelectWidget.setValues(AValue: TStrings);
  1549. begin
  1550. If (AValue=FValues) then exit;
  1551. FValues.Assign(aValue);
  1552. end;
  1553. function TSelectWidget.CreateOptionEnumerator: TSelectOptionEnumerator;
  1554. begin
  1555. Result:=TStringsSelectOptionEnumerator.Create(Self);
  1556. end;
  1557. constructor TSelectWidget.Create(aOWner: TComponent);
  1558. begin
  1559. inherited Create(aOWner);
  1560. FItems:=TStringList.Create;
  1561. TStringList(FItems).OnChange:=@OptionsChanged;
  1562. FValues:=TStringList.Create;
  1563. TStringList(FValues).OnChange:=@OptionsChanged;
  1564. end;
  1565. destructor TSelectWidget.Destroy;
  1566. begin
  1567. FreeAndNil(FItems);
  1568. FreeAndNil(FValues);
  1569. inherited Destroy;
  1570. end;
  1571. { TImageWidget }
  1572. function TImageWidget.GetHeight: Integer;
  1573. begin
  1574. if IsElementDirty then
  1575. FHeight:=ImgElement.Height;
  1576. Result:=Fheight;
  1577. end;
  1578. function TImageWidget.GetImg: TJSHTMLImageElement;
  1579. begin
  1580. Result:=TJSHTMLImageElement(Element);
  1581. end;
  1582. function TImageWidget.GetSrc: String;
  1583. begin
  1584. if IsElementDirty then
  1585. FSrc:=ImgElement.Src;
  1586. Result:=FSrc;
  1587. end;
  1588. function TImageWidget.GetWidth: Integer;
  1589. begin
  1590. if IsElementDirty then
  1591. FWidth:=ImgElement.Width;
  1592. Result:=FWidth;
  1593. end;
  1594. procedure TImageWidget.SetHeight(AValue: Integer);
  1595. begin
  1596. if AValue=Height then exit;
  1597. FHeight:=AValue;
  1598. If isrendered then
  1599. ImgElement.Height:=aValue;
  1600. end;
  1601. procedure TImageWidget.SetSrc(AValue: String);
  1602. begin
  1603. if AValue=Src then exit;
  1604. FSrc:=AValue;
  1605. If isrendered then
  1606. ImgElement.Src:=FSrc;
  1607. end;
  1608. procedure TImageWidget.SetWidth(AValue: Integer);
  1609. begin
  1610. if AValue=Width then exit;
  1611. FWidth:=AValue;
  1612. If isrendered then
  1613. ImgElement.Width:=aValue;
  1614. end;
  1615. procedure TImageWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1616. var
  1617. img : TJSHTMLImageElement absolute aElement;
  1618. begin
  1619. inherited ApplyWidgetSettings(aElement);
  1620. Img.Src:=FSrc;
  1621. Img.Height:=FHeight;
  1622. Img.Width:=FWidth;
  1623. end;
  1624. function TImageWidget.HTMLTag: String;
  1625. begin
  1626. Result:='img';
  1627. end;
  1628. { TTextAreaWidget }
  1629. procedure TTextAreaWidget.SetLines(AValue: TStrings);
  1630. begin
  1631. if FLines=AValue then Exit;
  1632. FLines.Assign(AValue);
  1633. end;
  1634. procedure TTextAreaWidget.SetMaxLength(AValue: Cardinal);
  1635. begin
  1636. if FMaxLength=AValue then Exit;
  1637. FMaxLength:=AValue;
  1638. if IsRendered then
  1639. TextArea.maxLength:=aValue;
  1640. end;
  1641. procedure TTextAreaWidget.SetReadonly(AValue: Boolean);
  1642. begin
  1643. If aValue=ReadOnly then exit;
  1644. FReadOnly:=aValue;
  1645. if IsRendered then
  1646. TextArea.Readonly:=FReadOnly;
  1647. end;
  1648. procedure TTextAreaWidget.SetRequired(AValue: Boolean);
  1649. begin
  1650. If aValue=Required then exit;
  1651. FRequired:=aValue;
  1652. if IsRendered then
  1653. TextArea.Required:=FRequired;
  1654. end;
  1655. function TTextAreaWidget.GetColumns: Cardinal;
  1656. begin
  1657. if IsElementDirty then
  1658. FColumns:=TextArea.Cols;
  1659. Result:=FColumns;
  1660. end;
  1661. procedure TTextAreaWidget.DoLineChanges(Sender: TObject);
  1662. begin
  1663. if isRendered and not FIgnoreChanges then
  1664. ApplyLines(TextArea);
  1665. end;
  1666. function TTextAreaWidget.GetLines: TStrings;
  1667. begin
  1668. // We may want to change this to something more efficient. Maybe handle onchange
  1669. // Note that if yo
  1670. if IsElementDirty then
  1671. begin
  1672. FIgnoreChanges:=True;
  1673. try
  1674. LinesFromHTML(Element.InnerHTml);
  1675. finally
  1676. FIgnoreChanges:=False;
  1677. end;
  1678. end;
  1679. Result:=FLines;
  1680. end;
  1681. function TTextAreaWidget.GetReadOnly: Boolean;
  1682. begin
  1683. if IsElementDirty then
  1684. FReadonly:=TextArea.readOnly;
  1685. Result:=FReadonly;
  1686. end;
  1687. function TTextAreaWidget.GetRequired: Boolean;
  1688. begin
  1689. if IsElementDirty then
  1690. FRequired:=TextArea.Required;
  1691. Result:=FRequired;
  1692. end;
  1693. function TTextAreaWidget.GetRows: Cardinal;
  1694. begin
  1695. if IsElementDirty then
  1696. FRows:=TextArea.Rows;
  1697. Result:=FRows;
  1698. end;
  1699. function TTextAreaWidget.GetText: String;
  1700. begin
  1701. if IsElementDirty then
  1702. Result:=Element.InnerHTML
  1703. else
  1704. Result:=FLines.Text;
  1705. end;
  1706. function TTextAreaWidget.GetValueName: string;
  1707. begin
  1708. if IsElementDirty then
  1709. FValueName:=Element.Name;
  1710. Result:=FValueName;
  1711. end;
  1712. procedure TTextAreaWidget.SetColumns(AValue: Cardinal);
  1713. begin
  1714. if AValue=FColumns then exit;
  1715. FColumns:=aValue;
  1716. if isRendered then
  1717. TextArea.cols:=aValue;
  1718. end;
  1719. procedure TTextAreaWidget.SetRows(AValue: Cardinal);
  1720. begin
  1721. if AValue=FRows then exit;
  1722. FRows:=aValue;
  1723. if isRendered then
  1724. TextArea.Rows:=aValue;
  1725. end;
  1726. procedure TTextAreaWidget.SetText(AValue: String);
  1727. begin
  1728. if isRendered then
  1729. element.InnerText:=aValue
  1730. else
  1731. LinesFromHTML(aValue);
  1732. end;
  1733. procedure TTextAreaWidget.SetValueName(AValue: string);
  1734. begin
  1735. if aValue=FValueName then exit;
  1736. FValueName:=aValue;
  1737. if IsRendered then
  1738. TextArea.Name:=aValue;
  1739. end;
  1740. procedure TTextAreaWidget.SetName(const NewName: TComponentName);
  1741. var
  1742. Old : String;
  1743. begin
  1744. Old:=Name;
  1745. inherited SetName(NewName);
  1746. if csDesigning in ComponentState then
  1747. begin
  1748. if (FLines.Count=0) then
  1749. FLines.Add(Name)
  1750. else if (FLines.Count=1) and (FLines[0]=Old) then
  1751. FLines[0]:=Name;
  1752. end;
  1753. end;
  1754. procedure TTextAreaWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1755. var
  1756. area : TJSHTMLTextAreaElement absolute aElement;
  1757. begin
  1758. inherited ApplyWidgetSettings(aElement);
  1759. if FMaxLength>0 then
  1760. area.maxlength:=FMaxLength;
  1761. if FColumns>0 then
  1762. area.cols:=FColumns;
  1763. if FRows>0 then
  1764. area.Rows:=FRows;
  1765. if FLines.Count>0 then
  1766. ApplyLines(area);
  1767. if FValueName<>'' then
  1768. area.Name:=FValueName;
  1769. area.Readonly:=FReadOnly;
  1770. area.Required:=FRequired;
  1771. ApplyWrap(area);
  1772. end;
  1773. constructor TTextAreaWidget.Create(aOwner: TComponent);
  1774. begin
  1775. inherited Create(aOwner);
  1776. FLines:=TStringList.Create;
  1777. TStringList(FLines).OnChange:=@DoLineChanges;
  1778. FColumns:=50;
  1779. FRows:=10;
  1780. end;
  1781. destructor TTextAreaWidget.Destroy;
  1782. begin
  1783. FreeAndNil(Flines);
  1784. inherited;
  1785. end;
  1786. class function TTextAreaWidget.AllowChildren: Boolean;
  1787. begin
  1788. Result:=False;
  1789. end;
  1790. function TTextAreaWidget.GetTextArea: TJSHTMLTextAreaElement;
  1791. begin
  1792. Result:=TJSHTMLTextAreaElement(Element);
  1793. end;
  1794. procedure TTextAreaWidget.ApplyWrap(aElement :TJSHTMLTextAreaElement);
  1795. Const
  1796. Wraps : Array[TTextAreaWrap] of string = ('soft','hard','off');
  1797. begin
  1798. aElement.wrap:=Wraps[FWrap];
  1799. end;
  1800. procedure TTextAreaWidget.ApplyLines(aElement: TJSHTMLTextAreaElement);
  1801. begin
  1802. aElement.innerHTML:=FLines.Text;
  1803. end;
  1804. procedure TTextAreaWidget.LinesFromHTML(aHTML: String);
  1805. begin
  1806. FLines.Text:= StringReplace(aHTML,'<br>',sLineBreak,[rfIgnoreCase,rfReplaceAll]);
  1807. end;
  1808. procedure TTextAreaWidget.SetWrap(AValue: TTextAreaWrap);
  1809. begin
  1810. if FWrap=AValue then Exit;
  1811. FWrap:=AValue;
  1812. if IsRendered then
  1813. ApplyWrap(TextArea)
  1814. end;
  1815. function TTextAreaWidget.HTMLTag: String;
  1816. begin
  1817. result:='textarea';
  1818. end;
  1819. { TCheckboxInputWidget }
  1820. function TCheckboxInputWidget.InputType: String;
  1821. begin
  1822. Result:='checkbox';
  1823. end;
  1824. { TRadioInputWidget }
  1825. function TRadioInputWidget.InputType: String;
  1826. begin
  1827. Result:='radio';
  1828. end;
  1829. { THiddenInputWidget }
  1830. class function THiddenInputWidget.AllowChildren: Boolean;
  1831. begin
  1832. Result:=False;
  1833. end;
  1834. function THiddenInputWidget.InputType: String;
  1835. begin
  1836. Result:='hidden';
  1837. end;
  1838. { TFileInputWidget }
  1839. procedure TFileInputWidget.SetMultiple(AValue: Boolean);
  1840. begin
  1841. if FMultiple=AValue then Exit;
  1842. FMultiple:=AValue;
  1843. if Isrendered then
  1844. InputElement.multiple:=FMultiple;
  1845. end;
  1846. function TFileInputWidget.GetMultiple: Boolean;
  1847. begin
  1848. if IsElementDirty then
  1849. FMultiple:=InputElement.multiple;
  1850. Result:=FMultiple;
  1851. end;
  1852. function TFileInputWidget.GetFileName(aIndex : Integer): String;
  1853. begin
  1854. Result:=InputElement.files.Files[aIndex].name;
  1855. end;
  1856. function TFileInputWidget.GetFileSize(aIndex : Integer): NativeInt;
  1857. begin
  1858. Result:=InputElement.files.Files[aIndex].Size;
  1859. end;
  1860. function TFileInputWidget.GetFileType(aIndex : Integer): String;
  1861. begin
  1862. Result:=InputElement.files.Files[aIndex]._Type;
  1863. end;
  1864. function TFileInputWidget.GetFileCount: Integer;
  1865. begin
  1866. Result:=InputElement.files.Length;
  1867. end;
  1868. function TFileInputWidget.GetFileDate(aIndex : Integer): TDateTime;
  1869. begin
  1870. Result:=JSDateToDateTime(InputElement.files.Files[aIndex].lastModifiedDate);
  1871. end;
  1872. function TFileInputWidget.GetFileInfo(aIndex : Integer): TFileInfo;
  1873. Var
  1874. f : TJSHTMLFile;
  1875. begin
  1876. F:=InputElement.files.Files[aIndex];
  1877. Result.Name:=F.name;
  1878. Result.Size:=F.size;
  1879. Result.FileType:=F._type;
  1880. Result.TimeStamp:= JSDateToDateTime(F.lastModifiedDate);
  1881. end;
  1882. procedure TFileInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1883. Var
  1884. Old : String;
  1885. begin
  1886. Old:=FValue;
  1887. FValue:='';
  1888. try
  1889. inherited ApplyWidgetSettings(aElement);
  1890. TJSHTMLInputElement(aElement).multiple:=FMultiple;
  1891. finally
  1892. FValue:=Old;
  1893. end;
  1894. end;
  1895. class function TFileInputWidget.AllowChildren: Boolean;
  1896. begin
  1897. Result:=False;
  1898. end;
  1899. function TFileInputWidget.InputType: String;
  1900. begin
  1901. Result:='file';
  1902. end;
  1903. { TDateInputWidget }
  1904. function TDateInputWidget.GetDate: TDateTime;
  1905. var
  1906. aDate : TDateTime;
  1907. begin
  1908. if IsElementDirty then
  1909. begin
  1910. aDate:=ScanDateTime('yyyy-mm-dd',Value);
  1911. if aDate<>0 then
  1912. FDate:=aDate;
  1913. end;
  1914. Result:=FDate;
  1915. end;
  1916. procedure TDateInputWidget.SetDate(AValue: TDateTime);
  1917. begin
  1918. FDate:=aValue;
  1919. Value:=FormatDateTime('yyyy-mm-dd',FDate);
  1920. end;
  1921. function TDateInputWidget.InputType: String;
  1922. begin
  1923. Result:='date';
  1924. end;
  1925. class function TDateInputWidget.AllowChildren: Boolean;
  1926. begin
  1927. Result:=False;
  1928. end;
  1929. { TCheckableInputWidget }
  1930. procedure TCheckableInputWidget.SetChecked(AValue: Boolean);
  1931. begin
  1932. // Get actual value
  1933. if Checked=AValue then Exit;
  1934. if isRendered then
  1935. InputElement.checked:=aValue;
  1936. FChecked:=AValue;
  1937. end;
  1938. procedure TCheckableInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1939. begin
  1940. inherited ApplyWidgetSettings(aElement);
  1941. TJSHTMLInputElement(aElement).Checked:=FChecked;
  1942. end;
  1943. function TCheckableInputWidget.GetChecked: Boolean;
  1944. begin
  1945. if IsElementDirty then
  1946. FChecked:=InputElement.Checked;
  1947. Result:=FChecked;
  1948. end;
  1949. { TButtonInputWidget }
  1950. procedure TButtonInputWidget.SetButtonType(AValue: TInputButtonType);
  1951. begin
  1952. if FButtonType=AValue then Exit;
  1953. FButtonType:=AValue;
  1954. if IsRendered then
  1955. Refresh;
  1956. end;
  1957. procedure TButtonInputWidget.SetSrc(AValue: String);
  1958. begin
  1959. if FSrc=AValue then Exit;
  1960. FSrc:=AValue;
  1961. if IsRendered and (ButtonType=ibtImage) then
  1962. Element.setAttribute('src',FSrc);
  1963. end;
  1964. procedure TButtonInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1965. begin
  1966. inherited ApplyWidgetSettings(aElement);
  1967. if ButtonType=ibtImage then
  1968. aElement.setAttribute('src',FSrc);
  1969. end;
  1970. function TButtonInputWidget.InputType: String;
  1971. Const
  1972. Types : Array[TInputButtonType] of string = ('submit','reset','image');
  1973. begin
  1974. Result:=Types[FButtonType]
  1975. end;
  1976. class function TButtonInputWidget.AllowChildren: Boolean;
  1977. begin
  1978. Result:=False;
  1979. end;
  1980. { TTextInputWidget }
  1981. function TTextInputWidget.GetAsNumber: NativeInt;
  1982. begin
  1983. Result:=StrToIntDef(Value,0);
  1984. end;
  1985. function TTextInputWidget.GetMaxLength: NativeInt;
  1986. begin
  1987. if IsElementDirty then
  1988. FMaxLength:=InputElement.maxLength;
  1989. Result:=FMaxLength;
  1990. end;
  1991. function TTextInputWidget.GetMinLength: NativeInt;
  1992. begin
  1993. if IsElementDirty then
  1994. FMinLength:=InputElement.minLength;
  1995. Result:=FMinLength;
  1996. end;
  1997. function TTextInputWidget.GetTextType: TInputTextType;
  1998. begin
  1999. Result:=FTextType;
  2000. end;
  2001. procedure TTextInputWidget.SetAsNumber(AValue: NativeInt);
  2002. begin
  2003. Value:=IntToStr(aValue);
  2004. end;
  2005. procedure TTextInputWidget.SetMaxLength(AValue: NativeInt);
  2006. begin
  2007. if (aValue=FMaxLength) then exit;
  2008. FMaxLength:=aValue;
  2009. if IsRendered then
  2010. InputElement.maxLength:=FMaxLength;
  2011. end;
  2012. procedure TTextInputWidget.SetMinLength(AValue: NativeInt);
  2013. begin
  2014. if (aValue=FMinLength) then exit;
  2015. FMinLength:=aValue;
  2016. if IsRendered then
  2017. InputElement.minLength:=FMinLength;
  2018. end;
  2019. procedure TTextInputWidget.SetTextType(AValue: TInputTextType);
  2020. begin
  2021. if aValue=FTextType then exit;
  2022. FTextType:=aValue;
  2023. if IsRendered then
  2024. Refresh;
  2025. end;
  2026. procedure TTextInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2027. var
  2028. inp : TJSHTMLInputElement absolute aElement;
  2029. begin
  2030. inherited ApplyWidgetSettings(aElement);
  2031. if FMaxLength<>0 then
  2032. inp.maxLength:=FMaxLength;
  2033. if FMinLength<>0 then
  2034. inp.minLength:=FMinLength;
  2035. end;
  2036. class function TTextInputWidget.AllowChildren: Boolean;
  2037. begin
  2038. Result:=False;
  2039. end;
  2040. function TTextInputWidget.InputType: String;
  2041. Const
  2042. Types : Array[TInputTextType] of string =
  2043. ('text','password','number','email','search','tel','url','color');
  2044. begin
  2045. Result:=Types[FTextType];
  2046. end;
  2047. { TWebPage }
  2048. constructor TWebPage.Create(AOwner: TComponent);
  2049. begin
  2050. inherited Create(AOwner);
  2051. Classes:='WebPage';
  2052. end;
  2053. class function TWebPage.DefaultParentElement: TJSHTMLElement;
  2054. begin
  2055. Result:=TViewport.Instance.Element;
  2056. end;
  2057. class function TWebPage.DefaultParent: TCustomWebWidget;
  2058. begin
  2059. Result:=TViewport.Instance;
  2060. end;
  2061. procedure TWebPage.DoUnRender(aParent: TJSHTMLElement);
  2062. begin
  2063. inherited DoUnRender(aParent);
  2064. end;
  2065. function TWebPage.HTMLTag: String;
  2066. begin
  2067. Result:='div';
  2068. end;
  2069. { TViewPort }
  2070. function TViewPort.HTMLTag: String;
  2071. begin
  2072. Result:='body';
  2073. end;
  2074. class function TViewPort.FixedParent: TJSHTMLElement;
  2075. begin
  2076. Result:=TJSHTMLElement(Document.documentElement);
  2077. end;
  2078. class function TViewPort.FixedElement: TJSHTMLElement;
  2079. begin
  2080. Result:=TJSHTMLElement(Document.Body);
  2081. end;
  2082. function TViewPort.DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement;
  2083. begin
  2084. Result:=FixedElement;
  2085. end;
  2086. constructor TViewPort.Create(aOwner: TComponent);
  2087. begin
  2088. inherited Create(aOwner);
  2089. EnsureElement;
  2090. end;
  2091. class function TViewPort.Instance: TViewPort;
  2092. begin
  2093. if Finstance=Nil then
  2094. FInstance:=TViewPort.Create(Nil);
  2095. Result:=FInstance;
  2096. end;
  2097. { TButtonWidget }
  2098. { TButtonWidget }
  2099. procedure TButtonWidget.SetText(AValue: String);
  2100. begin
  2101. if FText=AValue then Exit;
  2102. FText:=AValue;
  2103. if IsRendered then
  2104. ApplyText(Element);
  2105. end;
  2106. procedure TButtonWidget.SetTextMode(AValue: TTextMode);
  2107. begin
  2108. if FTextMode=AValue then Exit;
  2109. FTextMode:=AValue;
  2110. if IsRendered then
  2111. ApplyText(Element)
  2112. end;
  2113. procedure TButtonWidget.SetName(const NewName: TComponentName);
  2114. Var
  2115. Old : String;
  2116. begin
  2117. Old:=Name;
  2118. inherited SetName(NewName);
  2119. if (FText=Old) and (csDesigning in ComponentState) then
  2120. FText:=NewName;
  2121. end;
  2122. function TButtonWidget.HTMLTag: String;
  2123. begin
  2124. Result:='button';
  2125. end;
  2126. procedure TButtonWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2127. begin
  2128. Inherited;
  2129. ApplyText(aElement);
  2130. end;
  2131. Procedure TButtonWidget.ApplyText(aElement : TJSHTMLElement);
  2132. begin
  2133. if FTextMode=tmText then
  2134. aElement.InnerText:=FText
  2135. else
  2136. aElement.InnerHTML:=FText;
  2137. end;
  2138. procedure TButtonWidget.Click;
  2139. begin
  2140. DispatchEvent('click');
  2141. end;
  2142. { TCustomInputWidget }
  2143. function TCustomInputWidget.GetValue: String;
  2144. Var
  2145. Inp : TJSHTMLInputElement;
  2146. begin
  2147. Inp:=InputElement;
  2148. If Assigned(Inp) then
  2149. Result:=Inp.value
  2150. else
  2151. Result:=FValue
  2152. end;
  2153. function TCustomInputWidget.GetText: String;
  2154. Var
  2155. Inp : TJSHTMLElement;
  2156. begin
  2157. Inp:=Element;
  2158. If Assigned(Inp) then
  2159. Result:=Inp.InnerText
  2160. else
  2161. Result:=FText;
  2162. // Writeln('Getting text: ',Result,' inner : ',FText);
  2163. end;
  2164. function TCustomInputWidget.GetReadOnly: Boolean;
  2165. begin
  2166. if IsElementDirty then
  2167. FReadonly:=InputElement.readOnly;
  2168. Result:=FReadonly;
  2169. end;
  2170. function TCustomInputWidget.GetRequired: Boolean;
  2171. begin
  2172. if IsElementDirty then
  2173. FRequired:=InputElement.Required;
  2174. Result:=FRequired;
  2175. end;
  2176. function TCustomInputWidget.GetValueName: String;
  2177. Var
  2178. Inp : TJSHTMLInputElement;
  2179. begin
  2180. Inp:=InputElement;
  2181. If Assigned(Inp) then
  2182. Result:=Inp.Name
  2183. else
  2184. begin
  2185. Result:=FValueName;
  2186. if Result='' then
  2187. Result:=Name;
  2188. end;
  2189. end;
  2190. procedure TCustomInputWidget.SetReadonly(AValue: Boolean);
  2191. begin
  2192. If aValue=ReadOnly then exit;
  2193. FReadOnly:=aValue;
  2194. if IsRendered then
  2195. InputElement.Readonly:=FReadOnly;
  2196. end;
  2197. procedure TCustomInputWidget.SetRequired(AValue: Boolean);
  2198. begin
  2199. If aValue=Required then exit;
  2200. FRequired:=aValue;
  2201. if IsRendered then
  2202. InputElement.Required:=FRequired;
  2203. end;
  2204. procedure TCustomInputWidget.SetText(AValue: String);
  2205. Var
  2206. Inp : TJSHTMLElement;
  2207. begin
  2208. Writeln('Setting text: ',AValue,' previous : ',Text);
  2209. if aValue=Text then exit;
  2210. FText:=aValue;
  2211. Inp:=Element;
  2212. If Assigned(Inp) then
  2213. Inp.innerText:=aValue;
  2214. end;
  2215. procedure TCustomInputWidget.SetValue(AValue: String);
  2216. Var
  2217. Inp : TJSHTMLInputElement;
  2218. begin
  2219. if aValue=Value then exit;
  2220. FValue:=aValue;
  2221. Inp:=InputElement;
  2222. If Assigned(Inp) then
  2223. Inp.value:=aValue;
  2224. end;
  2225. procedure TCustomInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2226. var
  2227. Inp : TJSHTMLInputElement absolute aElement;
  2228. begin
  2229. Inherited;
  2230. if (ExternalElement) and (FValue='') then
  2231. FValue:=TJSHTMLInputElement(aElement).value
  2232. else
  2233. begin
  2234. Inp._type:=InputType;
  2235. Inp.name:=FValueName;
  2236. Inp.value:=FValue;
  2237. Inp.Required:=FRequired;
  2238. Inp.ReadOnly:=FReadOnly;
  2239. Writeln('Setting inner text to "',FText,'"');
  2240. Inp.innerHtml:=FText;
  2241. Writeln('Setting inner text is now "',Inp.innerText,'"');
  2242. end;
  2243. end;
  2244. function TCustomInputWidget.HTMLTag: String;
  2245. begin
  2246. Result:='input';
  2247. end;
  2248. function TCustomInputWidget.GetInputElement: TJSHTMLInputElement;
  2249. begin
  2250. Result:=TJSHTMLInputElement(Element);
  2251. end;
  2252. procedure TCustomInputWidget.SetValueName(AValue: String);
  2253. Var
  2254. Inp : TJSHTMLInputElement;
  2255. begin
  2256. if aValue=ValueName then exit;
  2257. FValueName:=aValue;
  2258. Inp:=InputElement;
  2259. If Assigned(Inp) then
  2260. Inp.name:=aValue;
  2261. end;
  2262. procedure TCustomInputWidget.SetName(const NewName: TComponentName);
  2263. Var
  2264. Old : String;
  2265. begin
  2266. Old:=Name;
  2267. inherited SetName(NewName);
  2268. if (Value=Old) then
  2269. Value:=NewName;
  2270. end;
  2271. end.