htmlwidgets.pp 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693
  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. TParagraphWidget = Class(TWebWidget)
  739. Protected
  740. Function HTMLTag : String; override;
  741. end;
  742. Function ViewPort : TViewPort;
  743. Const
  744. TextTagNames : Array[TTextTag] of string
  745. = ('p','b','i','u','s','span','quote','blockquote','h1','h2','h3','h4','h5','h6','pre','ruby','article','address','abbr','');
  746. RowKindNames : Array[TRowKind] of string = ('header','body','footer');
  747. implementation
  748. uses DateUtils;
  749. resourcestring
  750. SErrInvalidIndex = 'Index %d not in valid range of [0..%d]';
  751. Function ViewPort : TViewPort;
  752. begin
  753. Result:=TViewPort.Instance;
  754. end;
  755. { TTableRowCountEnumerator }
  756. Const
  757. CellTags : Array[TRowKind] of string = ('th','td','td');
  758. { TDivWidget }
  759. function TDivWidget.HTMLTag: String;
  760. begin
  761. Result:='DIV';
  762. end;
  763. function TParagraphWidget.HTMLTag : String;
  764. begin
  765. Result:='P';
  766. end;
  767. { TSelectWidget.TStringsSelectOptionEnumerator }
  768. constructor TSelectWidget.TStringsSelectOptionEnumerator.Create(ASelect: TCustomSelectWidget);
  769. begin
  770. inherited Create(ASelect);
  771. FCurrent:=-1;
  772. end;
  773. function TSelectWidget.TStringsSelectOptionEnumerator.OptionText: String;
  774. begin
  775. Result:=TSelectWidget(Select).Items[FCurrent];
  776. end;
  777. function TSelectWidget.TStringsSelectOptionEnumerator.HasValue: boolean;
  778. begin
  779. Result:=FCurrent<TSelectWidget(Select).Values.Count;
  780. end;
  781. function TSelectWidget.TStringsSelectOptionEnumerator.Value: string;
  782. begin
  783. Result:=TSelectWidget(Select).Values[FCurrent];
  784. end;
  785. function TSelectWidget.TStringsSelectOptionEnumerator.MoveNext: Boolean;
  786. begin
  787. Result:=FCurrent<TSelectWidget(Select).Items.Count-1;
  788. if Result then
  789. Inc(FCurrent);
  790. end;
  791. { TCustomSelectWidget.TSelectOptionEnumerator }
  792. constructor TCustomSelectWidget.TSelectOptionEnumerator.Create(ASelect: TCustomSelectWidget);
  793. begin
  794. FSelect:=ASelect;
  795. end;
  796. function TCustomSelectWidget.TSelectOptionEnumerator.HasValue: boolean;
  797. begin
  798. Result:=False;
  799. end;
  800. function TCustomSelectWidget.TSelectOptionEnumerator.Value: string;
  801. begin
  802. Result:='';
  803. end;
  804. constructor TTableRowCountEnumerator.Create(ATable: TCustomTableWidget; aCount: Integer);
  805. begin
  806. Inherited Create(aTable);
  807. FRowCount:=aCount;
  808. end;
  809. function TTableRowCountEnumerator.MoveNext: Boolean;
  810. begin
  811. Result:=Inherited MoveNext and (CurrentRow<RowCount)
  812. end;
  813. { TTableWidgetCellData }
  814. procedure TTableWidgetCellData.SetRowColKind(aRow, aCol: Integer; aKind: TRowKind);
  815. begin
  816. if (aRow<>-1) then
  817. FRow:=aRow;
  818. if (aCol<>-1) then
  819. FCol:=aCol;
  820. FKind:=aKind;
  821. end;
  822. procedure TTableWidgetCellData.Reset;
  823. begin
  824. Ftag:='td';
  825. FClassNames:='';
  826. FText:='';
  827. FContent:=Nil;
  828. FAsHTML:=False;
  829. end;
  830. constructor TTableWidgetCellData.Create(aTable: TCustomTableWidget; aTableID: String);
  831. begin
  832. FTable:=aTable;
  833. FTableID:=aTableID;
  834. SetRowColKind(0,0,rkBody);
  835. end;
  836. { TCustomTableWidget }
  837. procedure TCustomTableWidget.SetColumns(AValue: TCustomTableColumns);
  838. begin
  839. if FColumns=AValue then Exit;
  840. FColumns.Assign(AValue);
  841. end;
  842. procedure TCustomTableWidget.SetCaption(AValue: String);
  843. begin
  844. if FCaption=AValue then Exit;
  845. FCaption:=AValue;
  846. if isRendered then Refresh;
  847. end;
  848. function TCustomTableWidget.DoCellClick(aEvent: TJSMouseEvent): boolean;
  849. begin
  850. If Assigned(FOnCellClick) then
  851. FOnCellClick(Self,aEvent);
  852. If Assigned(FOnRowClick) then
  853. FOnRowClick(Self,aEvent);
  854. Result:=False;
  855. // Writeln('On click for cell',aEvent.targetElement.innerText);
  856. end;
  857. function TCustomTableWidget.DoHeaderCellClick(aEvent: TJSMouseEvent): boolean;
  858. begin
  859. If Assigned(FOnHeaderCellClick) then
  860. FOnHeaderCellClick(Self,aEvent);
  861. If Assigned(FOnHeaderRowClick) then
  862. FOnHeaderRowClick(Self,aEvent);
  863. Result:=False;
  864. // Writeln('On click for header cell',aEvent.targetElement.innerText);
  865. end;
  866. function TCustomTableWidget.DoFooterCellClick(aEvent: TJSMouseEvent): boolean;
  867. begin
  868. If Assigned(FOnFooterCellClick) then
  869. FOnFooterCellClick(Self,aEvent);
  870. If Assigned(FOnFooterRowClick) then
  871. FOnFooterRowClick(Self,aEvent);
  872. Result:=False;
  873. // Writeln('On click for Footer cell',aEvent.targetElement.innerText);
  874. end;
  875. function TCustomTableWidget.DoRowClick(aEvent: TJSMouseEvent): boolean;
  876. begin
  877. If Assigned(FOnRowClick) then
  878. FOnRowClick(Self,aEvent);
  879. Result:=False;
  880. // Writeln('On click for Row',aEvent.targetElement.innerText);
  881. end;
  882. function TCustomTableWidget.DoHeaderRowClick(aEvent: TJSMouseEvent): boolean;
  883. begin
  884. If Assigned(FOnHeaderRowClick) then
  885. FOnHeaderRowClick(Self,aEvent);
  886. Result:=False;
  887. // Writeln('On click for Header Row',aEvent.targetElement.innerText);
  888. end;
  889. function TCustomTableWidget.DoFooterRowClick(aEvent: TJSMouseEvent): boolean;
  890. begin
  891. If Assigned(FOnFooterRowClick) then
  892. FOnFooterRowClick(Self,aEvent);
  893. Result:=False;
  894. // Writeln('On click for Footer Row',aEvent.targetElement.innerText);
  895. end;
  896. procedure TCustomTableWidget.SetTableOptions(AValue: TTableOptions);
  897. begin
  898. if FTableOptions=AValue then Exit;
  899. FTableOptions:=AValue;
  900. if IsRendered then
  901. Refresh;
  902. end;
  903. procedure TCustomTableWidget.AppendCaption(aCaptionElement: TJSHTMLElement);
  904. begin
  905. aCaptionElement.InnerHTML:=Caption;
  906. end;
  907. function TCustomTableWidget.GetRowEnumerator(aKind: TRowKind): TTableRowEnumerator;
  908. begin
  909. Case aKind of
  910. rkHeader : Result:=TTableRowCountEnumerator.Create(Self,1);
  911. rkFooter : Result:=TTableRowCountEnumerator.Create(Self,1);
  912. rkBody : Result:=GetBodyRowEnumerator;
  913. end;
  914. end;
  915. procedure TTableRowEnumerator.GetCellData(aCell: TTableWidgetCellData);
  916. Var
  917. K : TRowKind;
  918. begin
  919. K:=aCell.Kind;
  920. Case K of
  921. rkHeader:
  922. begin
  923. aCell.Tag:='th';
  924. aCell.Text:=ACell.Column.Caption;
  925. end;
  926. rkFooter,
  927. rkBody :
  928. begin
  929. aCell.Tag:='td';
  930. end;
  931. end;
  932. end;
  933. function TCustomTableWidget.HTMLTag: String;
  934. begin
  935. Result:='table';
  936. end;
  937. function TCustomTableWidget.RenderCell(aCell: TTableWidgetCellData): TJSHTMLElement;
  938. Const
  939. Aligns : Array[TAlignment] of string = ('left','right','center');
  940. RowChecks : Array[TRowKind] of TTableOption = (toHeaderCellDataRow,toBodyCellDataRow,toFooterCellDataRow);
  941. ColChecks : Array[TRowKind] of TTableOption = (toHeaderCellDataCol,toBodyCellDataCol,toFooterCellDataCol);
  942. Var
  943. C : TJSHtmlElement;
  944. cl : THTMLNotifyEvent;
  945. K : TRowKind;
  946. M : THTMLClickEventHandler;
  947. elID : string;
  948. begin
  949. K:=aCell.Kind;
  950. if toCellID in TableOptions then
  951. elID:=aCell.TableID+'-'+RowKindNames[K]+'-'+IntToStr(ACell.Row)+'-'+IntToStr(aCell.Col)
  952. else
  953. elID:='';
  954. C:=CreateElement(aCell.Tag,elID);
  955. if aCell.Content<>Nil then
  956. C.AppendChild(aCell.Content)
  957. else if aCell.AsHTML then
  958. C.innerHTML:=aCell.text
  959. else
  960. C.innerText:=aCell.text;
  961. C.className:=AddClasses(aCell.Column.ClassNames,aCell.ClassNames);
  962. if ACell.Column.Alignment<>taLeftJustify then
  963. C.Style.setProperty('text-align',Aligns[ACell.Column.Alignment]);
  964. Case K of
  965. rkBody :
  966. begin
  967. CL:=FOnCellClick;
  968. M:=@DoCellClick;
  969. end;
  970. rkHeader :
  971. begin
  972. CL:=FOnHeaderCellClick;
  973. M:=@DoHeaderCellClick;
  974. end;
  975. rkFooter :
  976. begin
  977. CL:=FOnFooterCellClick;
  978. M:=@DoFooterCellClick;
  979. end;
  980. else
  981. CL:=Nil;
  982. M:=nil;
  983. end;
  984. if Assigned(cl) or (RowChecks[K] in TableOptions) then
  985. begin
  986. C.dataset['row']:=ACell.Row;
  987. C.Dataset['kind']:=RowKindNames[K];
  988. end;
  989. if Assigned(cl) or (ColChecks[K] in TableOptions) then
  990. begin
  991. C.dataset['col']:=ACell.Col;
  992. C.Dataset['kind']:=RowKindNames[K];
  993. end;
  994. if Assigned(M) then
  995. C.OnClick:=M;
  996. Result:=C;
  997. end;
  998. procedure TCustomTableWidget.RenderRow(aEnum: TTableRowEnumerator; aParent: TJSHTMLElement; aKind: TRowKind; aCell: TTableWidgetCellData);
  999. Var
  1000. I: integer;
  1001. begin
  1002. For I:=0 to CustomColumns.Count-1 do
  1003. begin
  1004. aCell.Reset;
  1005. aCell.FColumn:=CustomColumns[i];
  1006. aCell.SetRowColKind(-1,I,aKind);
  1007. // Writeln(CellKinds[aKind],' cell before : ',aCell.Tag,' data : ',aCell.Text);
  1008. aEnum.GetCellData(aCell);
  1009. // Writeln(CellKinds[aKind],' cell after : ',aCell.Tag,' data : ',aCell.Text);
  1010. if aCell.Tag='' then
  1011. ACell.Tag:=CellTags[aKind];
  1012. if Assigned(FOnGetCellData) then
  1013. FOnGetCellData(Self,aEnum,aCell);
  1014. aParent.appendChild(RenderCell(aCell));
  1015. end;
  1016. end;
  1017. procedure TCustomTableWidget.RenderRows(aParent: TJSHTMLElement; aKind: TRowKind; aCell: TTableWidgetCellData);
  1018. Const
  1019. TableRowChecks : Array[TRowKind] of TTableOption = (toHeaderRowData,toBodyRowData,toFooterRowData);
  1020. Var
  1021. RowEl : TJSHTMLElement;
  1022. Enum : TTableRowEnumerator;
  1023. M : THTMLClickEventHandler;
  1024. cl : THTMLNotifyEvent;
  1025. elid : String;
  1026. begin
  1027. Enum:=GetRowEnumerator(aKind);
  1028. if Enum=Nil then
  1029. Exit;
  1030. try
  1031. While Enum.MoveNext do
  1032. begin
  1033. if toRowID in TableOptions then
  1034. elID:=aCell.TableID+'-'+RowKindNames[aKind]+'-'+IntToStr(Enum.CurrentRow)
  1035. else
  1036. elID:='';
  1037. RowEl:=CreateElement('tr',elID);
  1038. aCell.SetRowColKind(Enum.CurrentRow,-1,aKind);
  1039. Case aKind of
  1040. rkBody :
  1041. begin
  1042. CL:=FOnRowClick;
  1043. M:=@DoRowClick;
  1044. end;
  1045. rkHeader :
  1046. begin
  1047. CL:=FOnHeaderRowClick;
  1048. M:=@DoHeaderRowClick;
  1049. end;
  1050. rkFooter :
  1051. begin
  1052. CL:=FOnFooterRowClick;
  1053. M:=@DoFooterRowClick;
  1054. end;
  1055. end;
  1056. if Assigned(CL) or (TableRowChecks[Akind] in TableOptions) then
  1057. begin
  1058. RowEl.dataset['row']:=Enum.CurrentRow;
  1059. RowEl.dataset['kind']:=RowKindNames[aKind];
  1060. end;
  1061. if Assigned(M) then
  1062. RowEl.OnClick:=M;
  1063. RenderRow(Enum,RowEl,aKind,aCell);
  1064. aParent.AppendChild(RowEl);
  1065. end;
  1066. finally
  1067. Enum.Free;
  1068. end;
  1069. end;
  1070. procedure TCustomTableWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1071. begin
  1072. inherited ApplyWidgetSettings(aElement);
  1073. RenderData(aElement);
  1074. end;
  1075. procedure TCustomTableWidget.RenderData(aElement: TJSHTMLElement);
  1076. Var
  1077. El : TJSHTMLElement;
  1078. aCell : TTableWidgetCellData;
  1079. begin
  1080. if (Caption<>'') then
  1081. begin
  1082. El:=CreateElement('caption',aElement.ID+'-caption');
  1083. AppendCaption(EL);
  1084. aElement.AppendChild(EL);
  1085. end;
  1086. aCell:=CreateCellData(aElement.ID);
  1087. If (CustomColumns.Count=0) then
  1088. CreateDefaultColumns;
  1089. if toHeaderRow in TableOptions then
  1090. begin
  1091. if toHeader in TableOptions then
  1092. begin
  1093. El:=CreateElement('thead',aElement.ID+'-head');
  1094. aElement.AppendChild(el);
  1095. end
  1096. else
  1097. El:=aElement;
  1098. aCell.SetRowColKind(-1,-1,rkHeader);
  1099. RenderRows(El,rkHeader,aCell);
  1100. end;
  1101. if toBody in TableOptions then
  1102. begin
  1103. El:=CreateElement('tbody',aElement.ID+'-body');
  1104. aElement.AppendChild(el);
  1105. end
  1106. else
  1107. El:=aElement;
  1108. aCell.SetRowColKind(-1,-1,rkBody);
  1109. RenderRows(El,rkBody,aCell);
  1110. if toFooterRow in TableOptions then
  1111. begin
  1112. if toFooter in TableOptions then
  1113. begin
  1114. El:=CreateElement('tFoot',aElement.ID+'-foot');
  1115. aElement.AppendChild(el);
  1116. end
  1117. else
  1118. El:=aElement;
  1119. aCell.SetRowColKind(-1,-1,rkFooter);
  1120. RenderRows(El,rkFooter,aCell);
  1121. end;
  1122. end;
  1123. function TCustomTableWidget.CreateCellData(const aTableID : String): TTableWidgetCellData;
  1124. begin
  1125. Result:=TTableWidgetCellData.Create(Self,aTableID);
  1126. end;
  1127. function TCustomTableWidget.CreateColumns: TCustomTableColumns;
  1128. begin
  1129. Result:=TCustomTableColumns.Create(TCustomTableColumn);
  1130. end;
  1131. function TCustomTableWidget.DefaultTableOptions: TTableOptions;
  1132. begin
  1133. Result:=[toHeader,toBody,toFooter,toHeaderRow]
  1134. end;
  1135. procedure TCustomTableWidget.CreateDefaultColumns;
  1136. begin
  1137. // Do nothing
  1138. end;
  1139. constructor TCustomTableWidget.Create(aOwner: TComponent);
  1140. begin
  1141. inherited Create(aOwner);
  1142. FTableOptions:=DefaultTableOptions;
  1143. FColumns:=CreateColumns;
  1144. end;
  1145. destructor TCustomTableWidget.Destroy;
  1146. begin
  1147. FreeAndNil(FColumns);
  1148. inherited Destroy;
  1149. end;
  1150. procedure TCustomTableWidget.RefreshBody;
  1151. begin
  1152. if Not Assigned(Element) then
  1153. Refresh
  1154. else
  1155. begin
  1156. Element.Innerhtml:='';
  1157. RenderData(Element);
  1158. end;
  1159. end;
  1160. { TCustomTableColumn }
  1161. procedure TCustomTableColumn.SetAlignment(AValue: TAlignment);
  1162. begin
  1163. if FAlignment=AValue then Exit;
  1164. FAlignment:=AValue;
  1165. end;
  1166. function TCustomTableColumn.GetCaption: String;
  1167. begin
  1168. Result:=FCaption;
  1169. end;
  1170. procedure TCustomTableColumn.SetCaption(AValue: String);
  1171. begin
  1172. if FCaption=AValue then Exit;
  1173. FCaption:=AValue;
  1174. end;
  1175. procedure TCustomTableColumn.SetClassNames(AValue: String);
  1176. begin
  1177. if FClassNames=AValue then Exit;
  1178. FClassNames:=AValue;
  1179. end;
  1180. function TCustomTableColumn.GetDisplayName: string;
  1181. begin
  1182. Result:=Caption;
  1183. end;
  1184. procedure TCustomTableColumn.Assign(Source: TPersistent);
  1185. Var
  1186. C : TCustomTableColumn;
  1187. begin
  1188. if Source is TCustomTableColumn then
  1189. begin
  1190. C:=Source as TCustomTableColumn;
  1191. FCaption:=C.FCaption;
  1192. FClassNames:=C.FClassNames;
  1193. FAlignment:=C.Alignment;
  1194. end
  1195. else
  1196. inherited Assign(Source);
  1197. end;
  1198. { TCustomTableColumns }
  1199. function TCustomTableColumns.GetCustomColumn(Index : Integer): TCustomTableColumn;
  1200. begin
  1201. Result:=TCustomTableColumn(Items[Index]);
  1202. end;
  1203. procedure TCustomTableColumns.SetCustomColumn(Index : Integer; AValue: TCustomTableColumn);
  1204. begin
  1205. Items[Index]:=aValue;
  1206. end;
  1207. function TCustomTableColumns.Add(aCaption: String): TCustomTableColumn;
  1208. begin
  1209. Result:=add as TCustomTableColumn;
  1210. Result.Caption:=aCaption;
  1211. end;
  1212. { TTableRowEnumerator }
  1213. constructor TTableRowEnumerator.Create(ATable: TCustomTableWidget);
  1214. begin
  1215. FTable:=aTable;
  1216. FCurrent:=-1;
  1217. end;
  1218. function TTableRowEnumerator.MoveNext: Boolean;
  1219. begin
  1220. Inc(FCurrent);
  1221. Result:=True;
  1222. end;
  1223. { TCustomTextWidget }
  1224. procedure TCustomTextWidget.SetEnvelopeTag(AValue: TTextTag);
  1225. begin
  1226. // Writeln('Setting text tag : ',aValue);
  1227. if FEnvelopeTag=AValue then Exit;
  1228. FEnvelopeTag:=AValue;
  1229. if (FEnvelopeTag=ttCustom) and (FCustomTag='') then
  1230. FCustomTag:='div';
  1231. if IsRendered then
  1232. Refresh;
  1233. end;
  1234. procedure TCustomTextWidget.SetCustomTag(AValue: String);
  1235. begin
  1236. if FCustomTag=AValue then Exit;
  1237. FCustomTag:=AValue;
  1238. if (FCustomTag<>'') then
  1239. FEnvelopeTag:=ttCustom;
  1240. if IsRendered then
  1241. Refresh;
  1242. end;
  1243. procedure TCustomTextWidget.SetTextMode(AValue: TTextMode);
  1244. begin
  1245. if FTextMode=AValue then Exit;
  1246. FTextMode:=AValue;
  1247. if IsRendered then
  1248. ApplyText(Element);
  1249. end;
  1250. procedure TCustomTextWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1251. begin
  1252. // Writeln('ApplyWidgetSettings: ',aElement.tagName);
  1253. inherited ApplyWidgetSettings(aElement);
  1254. ApplyText(aElement);
  1255. end;
  1256. procedure TCustomTextWidget.ApplyText(aElement: TJSHTMLElement);
  1257. begin
  1258. if FTextMode=tmText then
  1259. aElement.innerText:=GetText
  1260. else
  1261. aElement.innerHTML:=GetText;
  1262. end;
  1263. function TCustomTextWidget.HTMLTag: String;
  1264. begin
  1265. Result:=TextTagNames[FEnvelopeTag];
  1266. if Result='' then
  1267. Result:='div';
  1268. // Writeln('Getting element tag: ',Result);
  1269. end;
  1270. { TTextLinesWidget }
  1271. procedure TTextLinesWidget.SetLines(AValue: TStrings);
  1272. begin
  1273. if FLines=AValue then Exit;
  1274. FLines.Assign(AValue);
  1275. end;
  1276. procedure TTextLinesWidget.SetForceLineBreaks(AValue: Boolean);
  1277. begin
  1278. if FForceLineBreaks=AValue then Exit;
  1279. FForceLineBreaks:=AValue;
  1280. if IsRendered then
  1281. ApplyText(Element);
  1282. end;
  1283. procedure TTextLinesWidget.DoLinesChanged(Sender: TObject);
  1284. begin
  1285. if IsRendered then
  1286. ApplyText(Element);
  1287. end;
  1288. function TTextLinesWidget.GetText: String;
  1289. Var
  1290. I : integer;
  1291. begin
  1292. if (FTextMode=tmHTML) and ForceLineBreaks then
  1293. begin
  1294. Result:='';
  1295. For I:=0 to FLines.Count-1 do
  1296. Result:=Result+flines[i]+'<br/>';
  1297. end
  1298. else
  1299. Result:=FLines.Text;
  1300. end;
  1301. procedure TTextLinesWidget.ApplyText(aElement: TJSHTMLElement);
  1302. Var
  1303. I : integer;
  1304. begin
  1305. if (TextMode=tmHTML) or (Not ForceLineBreaks) then
  1306. inherited ApplyText(aElement)
  1307. else
  1308. begin
  1309. For I:=0 to FLines.Count-1 do
  1310. begin
  1311. aElement.AppendChild(Document.createTextNode(FLines[i]));
  1312. aElement.AppendChild(CreateElement('br',''));
  1313. end;
  1314. end;
  1315. end;
  1316. constructor TTextLinesWidget.Create(aOwner: TComponent);
  1317. begin
  1318. inherited Create(aOwner);
  1319. FLines:=TstringList.Create;
  1320. TstringList(FLines).OnChange:=@DoLinesChanged;
  1321. end;
  1322. destructor TTextLinesWidget.Destroy;
  1323. begin
  1324. FLines:=TstringList.Create;
  1325. inherited Destroy;
  1326. end;
  1327. { TTextWidget }
  1328. procedure TTextWidget.SetText(AValue: String);
  1329. begin
  1330. if FText=AValue then Exit;
  1331. FText:=AValue;
  1332. if IsRendered then
  1333. ApplyText(Element);
  1334. end;
  1335. function TTextWidget.GetText: String;
  1336. begin
  1337. Result:=FText;
  1338. end;
  1339. { TLabelWidget }
  1340. procedure TLabelWidget.ApplyLabelFor(aLabelElement : TJSHTMLLabelElement);
  1341. begin
  1342. if Assigned(FlabelFor) then
  1343. begin
  1344. FlabelFor.EnsureElement;
  1345. aLabelElement.for_:=FlabelFor.ElementID;
  1346. end
  1347. else
  1348. aLabelElement.for_:='';
  1349. end;
  1350. procedure TLabelWidget.SetLabelFor(AValue: TWebWidget);
  1351. begin
  1352. if (FLabelFor=AValue) then Exit;
  1353. if Assigned(FLabelFor) then
  1354. FLabelFor.RemoveFreeNotification(Self);
  1355. FLabelFor:=AValue;
  1356. if Assigned(FLabelFor) then
  1357. FLabelFor.FreeNotification(Self);
  1358. If IsRendered then
  1359. ApplyLabelFor(LabelElement);
  1360. end;
  1361. function TLabelWidget.GetText: String;
  1362. begin
  1363. if IsElementDirty then
  1364. FText:=Element.InnerText;
  1365. Result:=FText;
  1366. end;
  1367. function TLabelWidget.GetLabelEl: TJSHTMLLabelElement;
  1368. begin
  1369. Result:=TJSHTMLLabelElement(Element);
  1370. end;
  1371. procedure TLabelWidget.SetText(AValue: String);
  1372. begin
  1373. If Text=aValue then exit;
  1374. Ftext:=aValue;
  1375. If IsRendered then
  1376. Element.innerText:=aValue;
  1377. end;
  1378. procedure TLabelWidget.Notification(AComponent: TComponent; Operation: TOperation);
  1379. begin
  1380. inherited Notification(AComponent, Operation);
  1381. if (Operation=opRemove) and (aComponent=FLabelFor) then
  1382. FLabelFor:=Nil;
  1383. end;
  1384. procedure TLabelWidget.SetName(const NewName: TComponentName);
  1385. Var
  1386. Old : String;
  1387. begin
  1388. Old:=Name;
  1389. inherited SetName(NewName);
  1390. if (csDesigning in ComponentState) then
  1391. if Old=Text then
  1392. Text:=Old;
  1393. end;
  1394. procedure TLabelWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1395. var
  1396. lbl : TJSHTMLLabelElement absolute aElement;
  1397. begin
  1398. inherited ApplyWidgetSettings(aElement);
  1399. lbl.InnerText:=Text;
  1400. ApplyLabelFor(Lbl);
  1401. end;
  1402. function TLabelWidget.HTMLTag: String;
  1403. begin
  1404. Result:='label';
  1405. end;
  1406. { TSelectWidget }
  1407. function TCustomSelectWidget.GetSelectedIndex: Integer;
  1408. begin
  1409. if IsRendered then
  1410. FSelectedIndex:=SelectElement.selectedIndex;
  1411. Result:=FSelectedIndex
  1412. end;
  1413. function TCustomSelectWidget.GetMultiple: Boolean;
  1414. begin
  1415. if IsElementDirty then
  1416. FMultiple:=SelectElement.multiple;
  1417. Result:=FMultiple;
  1418. end;
  1419. function TCustomSelectWidget.GetItemCount: Integer;
  1420. begin
  1421. Result:=Length(Options);
  1422. end;
  1423. function TCustomSelectWidget.GetSelected(Index : Integer): Boolean;
  1424. begin
  1425. if (Index<0) or (Index>=Length(Foptions)) then
  1426. Raise EWidgets.CreateFmt(SErrInvalidIndex,[Index,Length(Foptions)-1]);
  1427. Result:=FOptions[Index].Selected
  1428. end;
  1429. function TCustomSelectWidget.GetSelect: TJSHTMLSelectElement;
  1430. begin
  1431. Result:=TJSHTMLSelectElement(Element);
  1432. end;
  1433. function TCustomSelectWidget.GetSelectionCount: Integer;
  1434. begin
  1435. Result:=SelectElement.selectedOptions.length;
  1436. end;
  1437. function TCustomSelectWidget.GetSelectionItem(aIndex : Integer): String;
  1438. begin
  1439. if (aIndex<0) or (aindex>=GetSelectionCount) then
  1440. Raise EWidgets.CreateFmt(SErrInvalidIndex,[aIndex,GetSelectionCount-1]);
  1441. Result:=TJSHTMLOptionElement(SelectElement.selectedOptions.item(aIndex)).innerText;
  1442. end;
  1443. function TCustomSelectWidget.GetSelectionValue(aIndex : Integer): String;
  1444. begin
  1445. if (aIndex<0) or (aindex>=GetSelectionCount) then
  1446. Raise EWidgets.CreateFmt(SErrInvalidIndex,[aIndex,GetSelectionCount-1]);
  1447. Result:=TJSHTMLOptionElement(SelectElement.selectedOptions.item(aIndex)).value;
  1448. end;
  1449. function TCustomSelectWidget.GetSize: Integer;
  1450. begin
  1451. if IsElementDirty then
  1452. FSize:=SelectElement.Size;
  1453. Result:=FSize;
  1454. end;
  1455. procedure TCustomSelectWidget.SetMultiple(AValue: Boolean);
  1456. begin
  1457. If (AValue=Multiple) then exit;
  1458. FMultiple:=aValue;
  1459. If IsRendered then
  1460. SelectElement.multiple:=FMultiple;
  1461. end;
  1462. procedure TCustomSelectWidget.SetSelected(Index : Integer; AValue: Boolean);
  1463. begin
  1464. if (Index<0) or (Index>=Length(Foptions)) then
  1465. Raise EWidgets.CreateFmt(SErrInvalidIndex,[Index,Length(Foptions)-1]);
  1466. FOptions[Index].Selected:=aValue;
  1467. end;
  1468. procedure TCustomSelectWidget.SetSelectedIndex(AValue: Integer);
  1469. begin
  1470. if (SelectedIndex=aValue) then
  1471. Exit;
  1472. FSelectedIndex:=aValue;
  1473. if IsRendered then
  1474. SelectElement.SelectedIndex:=FSelectedIndex;
  1475. if Assigned(OnChange) then
  1476. OnChange(Self,Nil);
  1477. end;
  1478. procedure TCustomSelectWidget.SetSize(AValue: Integer);
  1479. begin
  1480. If (AValue=Size) then exit;
  1481. FSize:=aValue;
  1482. If IsRendered then
  1483. SelectElement.Size:=FSize;
  1484. end;
  1485. procedure TCustomSelectWidget.BuildOptions(aSelect: TJSHTMLSelectElement);
  1486. Var
  1487. O : TJSHTMLOptionElement;
  1488. Idx : Integer;
  1489. enum : TSelectOptionEnumerator;
  1490. begin
  1491. // Clear
  1492. SetLength(FOptions,0);
  1493. aSelect.InnerHTML:='';
  1494. // Rebuild
  1495. Idx:=0;
  1496. enum:=CreateOptionEnumerator;
  1497. While enum.MoveNext do
  1498. begin
  1499. O:=TJSHTMLOptionElement(CreateElement('option',''));
  1500. O.innerText:=enum.OptionText;
  1501. if enum.HasValue then
  1502. O.value:=enum.Value;
  1503. if Idx=FSelectedIndex then
  1504. O.selected:=True;
  1505. aSelect.AppendChild(O);
  1506. Inc(Idx);
  1507. end;
  1508. SetLength(Foptions,Idx);
  1509. Dec(idx);
  1510. While Idx>=0 do
  1511. begin
  1512. FOptions[Idx]:=TJSHTMLOptionElement(aSelect.Children[Idx]);
  1513. dec(Idx);
  1514. end;
  1515. end;
  1516. constructor TCustomSelectWidget.Create(aOWner: TComponent);
  1517. begin
  1518. inherited Create(aOWner);
  1519. FSelectedIndex:=-1;
  1520. end;
  1521. procedure TCustomSelectWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1522. Var
  1523. el : TJSHTmlSelectElement absolute aElement;
  1524. begin
  1525. inherited ApplyWidgetSettings(aElement);
  1526. el.multiple:=Self.Multiple;
  1527. el.Size:=Self.Size;
  1528. BuildOptions(el);
  1529. // We need to force this.
  1530. if SelectedIndex=-1 then
  1531. el.selectedIndex:=-1;
  1532. end;
  1533. function TCustomSelectWidget.HTMLTag: String;
  1534. begin
  1535. Result:='select';
  1536. end;
  1537. { TSelectWidget }
  1538. function TSelectWidget.GetItems: TStrings;
  1539. begin
  1540. Result:=FItems;
  1541. end;
  1542. function TSelectWidget.GetValues: TStrings;
  1543. begin
  1544. Result:=FValues;
  1545. end;
  1546. procedure TSelectWidget.OptionsChanged(Sender: TObject);
  1547. begin
  1548. if IsRendered then
  1549. BuildOptions(SelectElement);
  1550. end;
  1551. procedure TSelectWidget.setItems(AValue: TStrings);
  1552. begin
  1553. If (AValue=FItems) then exit;
  1554. FItems.Assign(aValue);
  1555. end;
  1556. procedure TSelectWidget.setValues(AValue: TStrings);
  1557. begin
  1558. If (AValue=FValues) then exit;
  1559. FValues.Assign(aValue);
  1560. end;
  1561. function TSelectWidget.CreateOptionEnumerator: TSelectOptionEnumerator;
  1562. begin
  1563. Result:=TStringsSelectOptionEnumerator.Create(Self);
  1564. end;
  1565. constructor TSelectWidget.Create(aOWner: TComponent);
  1566. begin
  1567. inherited Create(aOWner);
  1568. FItems:=TStringList.Create;
  1569. TStringList(FItems).OnChange:=@OptionsChanged;
  1570. FValues:=TStringList.Create;
  1571. TStringList(FValues).OnChange:=@OptionsChanged;
  1572. end;
  1573. destructor TSelectWidget.Destroy;
  1574. begin
  1575. FreeAndNil(FItems);
  1576. FreeAndNil(FValues);
  1577. inherited Destroy;
  1578. end;
  1579. { TImageWidget }
  1580. function TImageWidget.GetHeight: Integer;
  1581. begin
  1582. if IsElementDirty then
  1583. FHeight:=ImgElement.Height;
  1584. Result:=Fheight;
  1585. end;
  1586. function TImageWidget.GetImg: TJSHTMLImageElement;
  1587. begin
  1588. Result:=TJSHTMLImageElement(Element);
  1589. end;
  1590. function TImageWidget.GetSrc: String;
  1591. begin
  1592. if IsElementDirty then
  1593. FSrc:=ImgElement.Src;
  1594. Result:=FSrc;
  1595. end;
  1596. function TImageWidget.GetWidth: Integer;
  1597. begin
  1598. if IsElementDirty then
  1599. FWidth:=ImgElement.Width;
  1600. Result:=FWidth;
  1601. end;
  1602. procedure TImageWidget.SetHeight(AValue: Integer);
  1603. begin
  1604. if AValue=Height then exit;
  1605. FHeight:=AValue;
  1606. If isrendered then
  1607. ImgElement.Height:=aValue;
  1608. end;
  1609. procedure TImageWidget.SetSrc(AValue: String);
  1610. begin
  1611. if AValue=Src then exit;
  1612. FSrc:=AValue;
  1613. If isrendered then
  1614. ImgElement.Src:=FSrc;
  1615. end;
  1616. procedure TImageWidget.SetWidth(AValue: Integer);
  1617. begin
  1618. if AValue=Width then exit;
  1619. FWidth:=AValue;
  1620. If isrendered then
  1621. ImgElement.Width:=aValue;
  1622. end;
  1623. procedure TImageWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1624. var
  1625. img : TJSHTMLImageElement absolute aElement;
  1626. begin
  1627. inherited ApplyWidgetSettings(aElement);
  1628. Img.Src:=FSrc;
  1629. Img.Height:=FHeight;
  1630. Img.Width:=FWidth;
  1631. end;
  1632. function TImageWidget.HTMLTag: String;
  1633. begin
  1634. Result:='img';
  1635. end;
  1636. { TTextAreaWidget }
  1637. procedure TTextAreaWidget.SetLines(AValue: TStrings);
  1638. begin
  1639. if FLines=AValue then Exit;
  1640. FLines.Assign(AValue);
  1641. end;
  1642. procedure TTextAreaWidget.SetMaxLength(AValue: Cardinal);
  1643. begin
  1644. if FMaxLength=AValue then Exit;
  1645. FMaxLength:=AValue;
  1646. if IsRendered then
  1647. TextArea.maxLength:=aValue;
  1648. end;
  1649. procedure TTextAreaWidget.SetReadonly(AValue: Boolean);
  1650. begin
  1651. If aValue=ReadOnly then exit;
  1652. FReadOnly:=aValue;
  1653. if IsRendered then
  1654. TextArea.Readonly:=FReadOnly;
  1655. end;
  1656. procedure TTextAreaWidget.SetRequired(AValue: Boolean);
  1657. begin
  1658. If aValue=Required then exit;
  1659. FRequired:=aValue;
  1660. if IsRendered then
  1661. TextArea.Required:=FRequired;
  1662. end;
  1663. function TTextAreaWidget.GetColumns: Cardinal;
  1664. begin
  1665. if IsElementDirty then
  1666. FColumns:=TextArea.Cols;
  1667. Result:=FColumns;
  1668. end;
  1669. procedure TTextAreaWidget.DoLineChanges(Sender: TObject);
  1670. begin
  1671. if isRendered and not FIgnoreChanges then
  1672. ApplyLines(TextArea);
  1673. end;
  1674. function TTextAreaWidget.GetLines: TStrings;
  1675. begin
  1676. // We may want to change this to something more efficient. Maybe handle onchange
  1677. // Note that if yo
  1678. if IsElementDirty then
  1679. begin
  1680. FIgnoreChanges:=True;
  1681. try
  1682. LinesFromHTML(Element.InnerHTml);
  1683. finally
  1684. FIgnoreChanges:=False;
  1685. end;
  1686. end;
  1687. Result:=FLines;
  1688. end;
  1689. function TTextAreaWidget.GetReadOnly: Boolean;
  1690. begin
  1691. if IsElementDirty then
  1692. FReadonly:=TextArea.readOnly;
  1693. Result:=FReadonly;
  1694. end;
  1695. function TTextAreaWidget.GetRequired: Boolean;
  1696. begin
  1697. if IsElementDirty then
  1698. FRequired:=TextArea.Required;
  1699. Result:=FRequired;
  1700. end;
  1701. function TTextAreaWidget.GetRows: Cardinal;
  1702. begin
  1703. if IsElementDirty then
  1704. FRows:=TextArea.Rows;
  1705. Result:=FRows;
  1706. end;
  1707. function TTextAreaWidget.GetText: String;
  1708. begin
  1709. if IsElementDirty then
  1710. Result:=Element.InnerHTML
  1711. else
  1712. Result:=FLines.Text;
  1713. end;
  1714. function TTextAreaWidget.GetValueName: string;
  1715. begin
  1716. if IsElementDirty then
  1717. FValueName:=Element.Name;
  1718. Result:=FValueName;
  1719. end;
  1720. procedure TTextAreaWidget.SetColumns(AValue: Cardinal);
  1721. begin
  1722. if AValue=FColumns then exit;
  1723. FColumns:=aValue;
  1724. if isRendered then
  1725. TextArea.cols:=aValue;
  1726. end;
  1727. procedure TTextAreaWidget.SetRows(AValue: Cardinal);
  1728. begin
  1729. if AValue=FRows then exit;
  1730. FRows:=aValue;
  1731. if isRendered then
  1732. TextArea.Rows:=aValue;
  1733. end;
  1734. procedure TTextAreaWidget.SetText(AValue: String);
  1735. begin
  1736. if isRendered then
  1737. element.InnerText:=aValue
  1738. else
  1739. LinesFromHTML(aValue);
  1740. end;
  1741. procedure TTextAreaWidget.SetValueName(AValue: string);
  1742. begin
  1743. if aValue=FValueName then exit;
  1744. FValueName:=aValue;
  1745. if IsRendered then
  1746. TextArea.Name:=aValue;
  1747. end;
  1748. procedure TTextAreaWidget.SetName(const NewName: TComponentName);
  1749. var
  1750. Old : String;
  1751. begin
  1752. Old:=Name;
  1753. inherited SetName(NewName);
  1754. if csDesigning in ComponentState then
  1755. begin
  1756. if (FLines.Count=0) then
  1757. FLines.Add(Name)
  1758. else if (FLines.Count=1) and (FLines[0]=Old) then
  1759. FLines[0]:=Name;
  1760. end;
  1761. end;
  1762. procedure TTextAreaWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1763. var
  1764. area : TJSHTMLTextAreaElement absolute aElement;
  1765. begin
  1766. inherited ApplyWidgetSettings(aElement);
  1767. if FMaxLength>0 then
  1768. area.maxlength:=FMaxLength;
  1769. if FColumns>0 then
  1770. area.cols:=FColumns;
  1771. if FRows>0 then
  1772. area.Rows:=FRows;
  1773. if FLines.Count>0 then
  1774. ApplyLines(area);
  1775. if FValueName<>'' then
  1776. area.Name:=FValueName;
  1777. area.Readonly:=FReadOnly;
  1778. area.Required:=FRequired;
  1779. ApplyWrap(area);
  1780. end;
  1781. constructor TTextAreaWidget.Create(aOwner: TComponent);
  1782. begin
  1783. inherited Create(aOwner);
  1784. FLines:=TStringList.Create;
  1785. TStringList(FLines).OnChange:=@DoLineChanges;
  1786. FColumns:=50;
  1787. FRows:=10;
  1788. end;
  1789. destructor TTextAreaWidget.Destroy;
  1790. begin
  1791. FreeAndNil(Flines);
  1792. inherited;
  1793. end;
  1794. class function TTextAreaWidget.AllowChildren: Boolean;
  1795. begin
  1796. Result:=False;
  1797. end;
  1798. function TTextAreaWidget.GetTextArea: TJSHTMLTextAreaElement;
  1799. begin
  1800. Result:=TJSHTMLTextAreaElement(Element);
  1801. end;
  1802. procedure TTextAreaWidget.ApplyWrap(aElement :TJSHTMLTextAreaElement);
  1803. Const
  1804. Wraps : Array[TTextAreaWrap] of string = ('soft','hard','off');
  1805. begin
  1806. aElement.wrap:=Wraps[FWrap];
  1807. end;
  1808. procedure TTextAreaWidget.ApplyLines(aElement: TJSHTMLTextAreaElement);
  1809. begin
  1810. aElement.innerHTML:=FLines.Text;
  1811. end;
  1812. procedure TTextAreaWidget.LinesFromHTML(aHTML: String);
  1813. begin
  1814. FLines.Text:= StringReplace(aHTML,'<br>',sLineBreak,[rfIgnoreCase,rfReplaceAll]);
  1815. end;
  1816. procedure TTextAreaWidget.SetWrap(AValue: TTextAreaWrap);
  1817. begin
  1818. if FWrap=AValue then Exit;
  1819. FWrap:=AValue;
  1820. if IsRendered then
  1821. ApplyWrap(TextArea)
  1822. end;
  1823. function TTextAreaWidget.HTMLTag: String;
  1824. begin
  1825. result:='textarea';
  1826. end;
  1827. { TCheckboxInputWidget }
  1828. function TCheckboxInputWidget.InputType: String;
  1829. begin
  1830. Result:='checkbox';
  1831. end;
  1832. { TRadioInputWidget }
  1833. function TRadioInputWidget.InputType: String;
  1834. begin
  1835. Result:='radio';
  1836. end;
  1837. { THiddenInputWidget }
  1838. class function THiddenInputWidget.AllowChildren: Boolean;
  1839. begin
  1840. Result:=False;
  1841. end;
  1842. function THiddenInputWidget.InputType: String;
  1843. begin
  1844. Result:='hidden';
  1845. end;
  1846. { TFileInputWidget }
  1847. procedure TFileInputWidget.SetMultiple(AValue: Boolean);
  1848. begin
  1849. if FMultiple=AValue then Exit;
  1850. FMultiple:=AValue;
  1851. if Isrendered then
  1852. InputElement.multiple:=FMultiple;
  1853. end;
  1854. function TFileInputWidget.GetMultiple: Boolean;
  1855. begin
  1856. if IsElementDirty then
  1857. FMultiple:=InputElement.multiple;
  1858. Result:=FMultiple;
  1859. end;
  1860. function TFileInputWidget.GetFileName(aIndex : Integer): String;
  1861. begin
  1862. Result:=InputElement.files.Files[aIndex].name;
  1863. end;
  1864. function TFileInputWidget.GetFileSize(aIndex : Integer): NativeInt;
  1865. begin
  1866. Result:=InputElement.files.Files[aIndex].Size;
  1867. end;
  1868. function TFileInputWidget.GetFileType(aIndex : Integer): String;
  1869. begin
  1870. Result:=InputElement.files.Files[aIndex]._Type;
  1871. end;
  1872. function TFileInputWidget.GetFileCount: Integer;
  1873. begin
  1874. Result:=InputElement.files.Length;
  1875. end;
  1876. function TFileInputWidget.GetFileDate(aIndex : Integer): TDateTime;
  1877. begin
  1878. Result:=JSDateToDateTime(InputElement.files.Files[aIndex].lastModifiedDate);
  1879. end;
  1880. function TFileInputWidget.GetFileInfo(aIndex : Integer): TFileInfo;
  1881. Var
  1882. f : TJSHTMLFile;
  1883. begin
  1884. F:=InputElement.files.Files[aIndex];
  1885. Result.Name:=F.name;
  1886. Result.Size:=F.size;
  1887. Result.FileType:=F._type;
  1888. Result.TimeStamp:= JSDateToDateTime(F.lastModifiedDate);
  1889. end;
  1890. procedure TFileInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1891. Var
  1892. Old : String;
  1893. begin
  1894. Old:=FValue;
  1895. FValue:='';
  1896. try
  1897. inherited ApplyWidgetSettings(aElement);
  1898. TJSHTMLInputElement(aElement).multiple:=FMultiple;
  1899. finally
  1900. FValue:=Old;
  1901. end;
  1902. end;
  1903. class function TFileInputWidget.AllowChildren: Boolean;
  1904. begin
  1905. Result:=False;
  1906. end;
  1907. function TFileInputWidget.InputType: String;
  1908. begin
  1909. Result:='file';
  1910. end;
  1911. { TDateInputWidget }
  1912. function TDateInputWidget.GetDate: TDateTime;
  1913. var
  1914. aDate : TDateTime;
  1915. begin
  1916. if IsElementDirty then
  1917. begin
  1918. aDate:=ScanDateTime('yyyy-mm-dd',Value);
  1919. if aDate<>0 then
  1920. FDate:=aDate;
  1921. end;
  1922. Result:=FDate;
  1923. end;
  1924. procedure TDateInputWidget.SetDate(AValue: TDateTime);
  1925. begin
  1926. FDate:=aValue;
  1927. Value:=FormatDateTime('yyyy-mm-dd',FDate);
  1928. end;
  1929. function TDateInputWidget.InputType: String;
  1930. begin
  1931. Result:='date';
  1932. end;
  1933. class function TDateInputWidget.AllowChildren: Boolean;
  1934. begin
  1935. Result:=False;
  1936. end;
  1937. { TCheckableInputWidget }
  1938. procedure TCheckableInputWidget.SetChecked(AValue: Boolean);
  1939. begin
  1940. // Get actual value
  1941. if Checked=AValue then Exit;
  1942. if isRendered then
  1943. InputElement.checked:=aValue;
  1944. FChecked:=AValue;
  1945. end;
  1946. procedure TCheckableInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1947. begin
  1948. inherited ApplyWidgetSettings(aElement);
  1949. TJSHTMLInputElement(aElement).Checked:=FChecked;
  1950. end;
  1951. function TCheckableInputWidget.GetChecked: Boolean;
  1952. begin
  1953. if IsElementDirty then
  1954. FChecked:=InputElement.Checked;
  1955. Result:=FChecked;
  1956. end;
  1957. { TButtonInputWidget }
  1958. procedure TButtonInputWidget.SetButtonType(AValue: TInputButtonType);
  1959. begin
  1960. if FButtonType=AValue then Exit;
  1961. FButtonType:=AValue;
  1962. if IsRendered then
  1963. Refresh;
  1964. end;
  1965. procedure TButtonInputWidget.SetSrc(AValue: String);
  1966. begin
  1967. if FSrc=AValue then Exit;
  1968. FSrc:=AValue;
  1969. if IsRendered and (ButtonType=ibtImage) then
  1970. Element.setAttribute('src',FSrc);
  1971. end;
  1972. procedure TButtonInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1973. begin
  1974. inherited ApplyWidgetSettings(aElement);
  1975. if ButtonType=ibtImage then
  1976. aElement.setAttribute('src',FSrc);
  1977. end;
  1978. function TButtonInputWidget.InputType: String;
  1979. Const
  1980. Types : Array[TInputButtonType] of string = ('submit','reset','image');
  1981. begin
  1982. Result:=Types[FButtonType]
  1983. end;
  1984. class function TButtonInputWidget.AllowChildren: Boolean;
  1985. begin
  1986. Result:=False;
  1987. end;
  1988. { TTextInputWidget }
  1989. function TTextInputWidget.GetAsNumber: NativeInt;
  1990. begin
  1991. Result:=StrToIntDef(Value,0);
  1992. end;
  1993. function TTextInputWidget.GetMaxLength: NativeInt;
  1994. begin
  1995. if IsElementDirty then
  1996. FMaxLength:=InputElement.maxLength;
  1997. Result:=FMaxLength;
  1998. end;
  1999. function TTextInputWidget.GetMinLength: NativeInt;
  2000. begin
  2001. if IsElementDirty then
  2002. FMinLength:=InputElement.minLength;
  2003. Result:=FMinLength;
  2004. end;
  2005. function TTextInputWidget.GetTextType: TInputTextType;
  2006. begin
  2007. Result:=FTextType;
  2008. end;
  2009. procedure TTextInputWidget.SetAsNumber(AValue: NativeInt);
  2010. begin
  2011. Value:=IntToStr(aValue);
  2012. end;
  2013. procedure TTextInputWidget.SetMaxLength(AValue: NativeInt);
  2014. begin
  2015. if (aValue=FMaxLength) then exit;
  2016. FMaxLength:=aValue;
  2017. if IsRendered then
  2018. InputElement.maxLength:=FMaxLength;
  2019. end;
  2020. procedure TTextInputWidget.SetMinLength(AValue: NativeInt);
  2021. begin
  2022. if (aValue=FMinLength) then exit;
  2023. FMinLength:=aValue;
  2024. if IsRendered then
  2025. InputElement.minLength:=FMinLength;
  2026. end;
  2027. procedure TTextInputWidget.SetTextType(AValue: TInputTextType);
  2028. begin
  2029. if aValue=FTextType then exit;
  2030. FTextType:=aValue;
  2031. if IsRendered then
  2032. Refresh;
  2033. end;
  2034. procedure TTextInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2035. var
  2036. inp : TJSHTMLInputElement absolute aElement;
  2037. begin
  2038. inherited ApplyWidgetSettings(aElement);
  2039. if FMaxLength<>0 then
  2040. inp.maxLength:=FMaxLength;
  2041. if FMinLength<>0 then
  2042. inp.minLength:=FMinLength;
  2043. end;
  2044. class function TTextInputWidget.AllowChildren: Boolean;
  2045. begin
  2046. Result:=False;
  2047. end;
  2048. function TTextInputWidget.InputType: String;
  2049. Const
  2050. Types : Array[TInputTextType] of string =
  2051. ('text','password','number','email','search','tel','url','color');
  2052. begin
  2053. Result:=Types[FTextType];
  2054. end;
  2055. { TWebPage }
  2056. constructor TWebPage.Create(AOwner: TComponent);
  2057. begin
  2058. inherited Create(AOwner);
  2059. Classes:='WebPage';
  2060. end;
  2061. class function TWebPage.DefaultParentElement: TJSHTMLElement;
  2062. begin
  2063. Result:=TViewport.Instance.Element;
  2064. end;
  2065. class function TWebPage.DefaultParent: TCustomWebWidget;
  2066. begin
  2067. Result:=TViewport.Instance;
  2068. end;
  2069. procedure TWebPage.DoUnRender(aParent: TJSHTMLElement);
  2070. begin
  2071. inherited DoUnRender(aParent);
  2072. end;
  2073. function TWebPage.HTMLTag: String;
  2074. begin
  2075. Result:='div';
  2076. end;
  2077. { TViewPort }
  2078. function TViewPort.HTMLTag: String;
  2079. begin
  2080. Result:='body';
  2081. end;
  2082. class function TViewPort.FixedParent: TJSHTMLElement;
  2083. begin
  2084. Result:=TJSHTMLElement(Document.documentElement);
  2085. end;
  2086. class function TViewPort.FixedElement: TJSHTMLElement;
  2087. begin
  2088. Result:=TJSHTMLElement(Document.Body);
  2089. end;
  2090. function TViewPort.DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement;
  2091. begin
  2092. Result:=FixedElement;
  2093. end;
  2094. constructor TViewPort.Create(aOwner: TComponent);
  2095. begin
  2096. inherited Create(aOwner);
  2097. EnsureElement;
  2098. end;
  2099. class function TViewPort.Instance: TViewPort;
  2100. begin
  2101. if Finstance=Nil then
  2102. FInstance:=TViewPort.Create(Nil);
  2103. Result:=FInstance;
  2104. end;
  2105. { TButtonWidget }
  2106. { TButtonWidget }
  2107. procedure TButtonWidget.SetText(AValue: String);
  2108. begin
  2109. if FText=AValue then Exit;
  2110. FText:=AValue;
  2111. if IsRendered then
  2112. ApplyText(Element);
  2113. end;
  2114. procedure TButtonWidget.SetTextMode(AValue: TTextMode);
  2115. begin
  2116. if FTextMode=AValue then Exit;
  2117. FTextMode:=AValue;
  2118. if IsRendered then
  2119. ApplyText(Element)
  2120. end;
  2121. procedure TButtonWidget.SetName(const NewName: TComponentName);
  2122. Var
  2123. Old : String;
  2124. begin
  2125. Old:=Name;
  2126. inherited SetName(NewName);
  2127. if (FText=Old) and (csDesigning in ComponentState) then
  2128. FText:=NewName;
  2129. end;
  2130. function TButtonWidget.HTMLTag: String;
  2131. begin
  2132. Result:='button';
  2133. end;
  2134. procedure TButtonWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2135. begin
  2136. Inherited;
  2137. ApplyText(aElement);
  2138. end;
  2139. Procedure TButtonWidget.ApplyText(aElement : TJSHTMLElement);
  2140. begin
  2141. if FTextMode=tmText then
  2142. aElement.InnerText:=FText
  2143. else
  2144. aElement.InnerHTML:=FText;
  2145. end;
  2146. procedure TButtonWidget.Click;
  2147. begin
  2148. DispatchEvent('click');
  2149. end;
  2150. { TCustomInputWidget }
  2151. function TCustomInputWidget.GetValue: String;
  2152. Var
  2153. Inp : TJSHTMLInputElement;
  2154. begin
  2155. Inp:=InputElement;
  2156. If Assigned(Inp) then
  2157. Result:=Inp.value
  2158. else
  2159. Result:=FValue
  2160. end;
  2161. function TCustomInputWidget.GetText: String;
  2162. Var
  2163. Inp : TJSHTMLElement;
  2164. begin
  2165. Inp:=Element;
  2166. If Assigned(Inp) then
  2167. Result:=Inp.InnerText
  2168. else
  2169. Result:=FText;
  2170. // Writeln('Getting text: ',Result,' inner : ',FText);
  2171. end;
  2172. function TCustomInputWidget.GetReadOnly: Boolean;
  2173. begin
  2174. if IsElementDirty then
  2175. FReadonly:=InputElement.readOnly;
  2176. Result:=FReadonly;
  2177. end;
  2178. function TCustomInputWidget.GetRequired: Boolean;
  2179. begin
  2180. if IsElementDirty then
  2181. FRequired:=InputElement.Required;
  2182. Result:=FRequired;
  2183. end;
  2184. function TCustomInputWidget.GetValueName: String;
  2185. Var
  2186. Inp : TJSHTMLInputElement;
  2187. begin
  2188. Inp:=InputElement;
  2189. If Assigned(Inp) then
  2190. Result:=Inp.Name
  2191. else
  2192. begin
  2193. Result:=FValueName;
  2194. if Result='' then
  2195. Result:=Name;
  2196. end;
  2197. end;
  2198. procedure TCustomInputWidget.SetReadonly(AValue: Boolean);
  2199. begin
  2200. If aValue=ReadOnly then exit;
  2201. FReadOnly:=aValue;
  2202. if IsRendered then
  2203. InputElement.Readonly:=FReadOnly;
  2204. end;
  2205. procedure TCustomInputWidget.SetRequired(AValue: Boolean);
  2206. begin
  2207. If aValue=Required then exit;
  2208. FRequired:=aValue;
  2209. if IsRendered then
  2210. InputElement.Required:=FRequired;
  2211. end;
  2212. procedure TCustomInputWidget.SetText(AValue: String);
  2213. Var
  2214. Inp : TJSHTMLElement;
  2215. begin
  2216. Writeln('Setting text: ',AValue,' previous : ',Text);
  2217. if aValue=Text then exit;
  2218. FText:=aValue;
  2219. Inp:=Element;
  2220. If Assigned(Inp) then
  2221. Inp.innerText:=aValue;
  2222. end;
  2223. procedure TCustomInputWidget.SetValue(AValue: String);
  2224. Var
  2225. Inp : TJSHTMLInputElement;
  2226. begin
  2227. if aValue=Value then exit;
  2228. FValue:=aValue;
  2229. Inp:=InputElement;
  2230. If Assigned(Inp) then
  2231. Inp.value:=aValue;
  2232. end;
  2233. procedure TCustomInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2234. var
  2235. Inp : TJSHTMLInputElement absolute aElement;
  2236. begin
  2237. Inherited;
  2238. if (ExternalElement) and (FValue='') then
  2239. FValue:=TJSHTMLInputElement(aElement).value
  2240. else
  2241. begin
  2242. Inp._type:=InputType;
  2243. Inp.name:=FValueName;
  2244. Inp.value:=FValue;
  2245. Inp.Required:=FRequired;
  2246. Inp.ReadOnly:=FReadOnly;
  2247. Writeln('Setting inner text to "',FText,'"');
  2248. Inp.innerHtml:=FText;
  2249. Writeln('Setting inner text is now "',Inp.innerText,'"');
  2250. end;
  2251. end;
  2252. function TCustomInputWidget.HTMLTag: String;
  2253. begin
  2254. Result:='input';
  2255. end;
  2256. function TCustomInputWidget.GetInputElement: TJSHTMLInputElement;
  2257. begin
  2258. Result:=TJSHTMLInputElement(Element);
  2259. end;
  2260. procedure TCustomInputWidget.SetValueName(AValue: String);
  2261. Var
  2262. Inp : TJSHTMLInputElement;
  2263. begin
  2264. if aValue=ValueName then exit;
  2265. FValueName:=aValue;
  2266. Inp:=InputElement;
  2267. If Assigned(Inp) then
  2268. Inp.name:=aValue;
  2269. end;
  2270. procedure TCustomInputWidget.SetName(const NewName: TComponentName);
  2271. Var
  2272. Old : String;
  2273. begin
  2274. Old:=Name;
  2275. inherited SetName(NewName);
  2276. if (Value=Old) then
  2277. Value:=NewName;
  2278. end;
  2279. end.