For the past couple of days I’ve been working on an experimental IntraWeb (a.k.a., "VCL for the Web") project. Since I typically generate user interfaces dynamically, I wanted to see how that worked with IntraWeb. On the surface, it’s fairly similar to the regular VCL, but there are some important differences.
Rule number one is that all components you create must have the Name property set. The regular VCL doesn’t require this for components created in code, but IntraWeb uses the Component.Name as part of the HTML id, and if the id isn’t set, the JavaScript generated by IntraWeb won’t work. So always set the Name.
Another thing to note is that the default property values don’t always make sense. If a component looks different when you dynamically generated at runtime versus when you drop it on an IntraWeb form in the designer, take a close look at the text DFM. You’ll probably find non-default property values set by the designer. If you replicate this in your code, you should end up with a component looks the same at runtime.
With all that said, here’s some simple code to add tabs at runtime to an existing tab control:
uses Graphics, IWContainerBorderOptions; procedure TfrmUIPageGroup.ClearPageControls; var iPage: integer; begin for iPage := Pred(TabControl.Pages.Count) downto 0 do begin TObject(TabControl.Pages[iPage]).Free; end; end; procedure TMyIntraWebForm.AddSomeTabs; var iPage, iTabTop, iTabHeight, iTabWidth: integer; NewTab: TIWTabPage; begin // need to have a design-time page to copy sizing properties from Assert(TabControl.Pages.Count > 0); iTabTop := TIWTabPage(TabControl.Pages[0]).Top; iTabHeight := TIWTabPage(TabControl.Pages[0]).Height; iTabWidth := TIWTabPage(TabControl.Pages[0]).Width; ClearPageControls; for iPage := 0 to 2 do begin NewTab := TIWTabPage.Create(TabControl); NewTab.BorderOptions.NumericWidth := 0; NewTab.BorderOptions.BorderWidth := cbwNumeric; NewTab.BorderOptions.Style := cbsNone; NewTab.BorderOptions.Color := clNone; NewTab.Color := clWebWHITE; NewTab.Top := iTabTop; NewTab.Width := iTabWidth; NewTab.Height := iTabHeight; // WordPress changes the single quote to a typographic quote here, so cutting // and pasting the next two lines won't work. Sorry; I haven't figured out how // to stop that NewTab.Name := 'DynamicPage' + IntToStr(iPage); NewTab.Title := 'Page ' + IntToStr(iPage); NewTab.Parent := TabControl; // TabOrder determines the order of tabs (really!) in this control // It must be set *after* Parent NewTab.TabOrder := iPage; end; end;
Alignment may not work as expected, either. If I build on this example by creating a control, parenting it to the tab sheet, and setting the Align property to alClient, that control’s size or position doesn’t actually change.
Finally, there is the issue of layout managers. If you use TIWTemplateProcessorHTML or TIWLayoutMgrHTML, there will not be a placeholder in your template for your dynamically generated component. There is probably a way around this, but I have not fully investigated the issue yet. One possible solution would be to do the dynamic component generation inside of a custom IntraWeb control.
{ 4 } Comments
The issue with dynamic controls and templates is a bit like the egg-chicken issue. If you create a Template, then you need to know about controls that do not exist yet.
If you know the names of the controls that may be created dynamically later on, then you can place the corresponding variables in the template upfront. IW will just ignore unknown variables.
Olaf, what would be ideal is a way to dynamically alter the template. You can do this in ASP.NET templates by putting in inline code, for example.
I’m thinking that a more "IntraWeb-ish" approach to this would be to have an event on the layout managers which would be called for each placeholder in the template. That event would allow alteration of the placeholder before the template itself is processed. I could, for example, turn one placeholder into 10 placeholders with markup in between. After the event is called for each placeholder, IntraWeb would process the template as usual.
Theoretically WordPress shouldn’t alter anything inside a PRE tag and most of the time it doesn’t, but if you switch back and forth between the code view and the editor, or if you edit the post after it has been published, the editor will mess with the quotes. This is documented in the WordPress Codex:
http://codex.wordpress.org/Writing_Code_in_Your_Posts#Quotes_in_Codes
One solution is to install a plugin that handles the special (non)formatting required by source code snippets. Here’s a few (I haven’t tried any of them yet)
http://priyadi.net/archives/2005/09/27/wordpress-plugin-code-autoescape/
http://www.semiologic.com/software/wp-fixes/unfancy-quote/
Finally Lorelle has something to say on the topic (although I couldn’t spot any real solutions in her article):
http://www.blogherald.com/2007/07/16/writing-and-publishing-code-in-your-wordpress-blog-posts/
FYI, the Arcana template processor (recently open sourced in the Elite Suite) does support altering the template before it’s processed. You must do so as a string replacement, but it does work.
{ 1 } Trackback
[...] recently wrote about limitations in creating IntraWeb components dynamically when using the template processor component. It looks like the Arcana template processor, recently [...]
Post a Comment