Advanced Markup Language generation for IntraWeb

By: Doychin Bondzhev

Abstract: Article describes how to use an undocumented feature in IntraWeb to create complex controls that require multiple tags.

Who am I

My name is Doychin Bondzhev. I'm from Bulgaria and I was working for Atozed Software as senior developer on core parts of IntraWeb. Right now I work at my own company called dSoft-Bulgaria where we do J2EE projects, so probably my next article will be based on my current work on some Java stuff we did here. This is my first article on computer subject so it will be very short. I will try to show you how to generate complex HTML code when doing custom IntraWeb components.

A little theory
When you write your own custom controls for IntraWeb first you have to decide the platform on which your components will work. IntraWeb current supports 3 different platforms. These are:
  • HTML 4.0 for Internet Explorer and Netscape/Mozilla
  • HTML 3.2 for Mobile devices that support it
  • and WML/XHTMLMP for WAP mobile devices

For each of these platforms there is a base control and base component classes.

Platform Components base class Controls base class
HTML 4.0 TIWBaseHTMLComponent TIWCustomControl
TIWControl
HTML 3.0 TIWBaseHTMLComponent TIWCustomControl32
TIWControl32
WML/XHTMLMP TIWBaseWAPComponent TIWCustomControlWAP

As you can see there is 2 possibilities for control ancestors for HTML. The reason these 2 are there is because the versions before IntraWeb 6 had only one class for HTML controls and it was TIWControl/TIWControl32 correspondingly.

In version 6 TIWCustomControl and TIWCustomControl32 were introduced as ancestor classes for HTML based controls and also the methods that were used to support input functionality were removed from the base classes.

So in order to create an input control you have to descends from TIWCustomControl and implement IIWInputControl when you control will receive value from the browser and IIWSubmitControl if it will be submit control.

For example TIWEdit implements both interfaces because it receives value from the browser and also can trigger submit.

For more information and how to use these interfaces you can check the IntraWeb documentation.

Back to our main subject

So as you can see you can do a lot of things with IntraWeb but lets talk about Markup Language generation. For HTML code when you create a descendant class you have to override RenderHTML method. This method returns result of type TIWHTMLTag. For WML/XHTMLMP there is another method RenderWAP with result type TIWWAPTag. In both cases you can use the technique I will describe later. Of course there must be some reason to do this.

Lets see what happens after we create our HTML tag object and return it as result. There is few things that happen and they all depend on the way your form is configured. For example additional attributes are added if your control is input control. Also it could be placed inside other HTML tags for some reason. Layout managers also make changes to tag objects. If you use partial update mode all html tags for one control are placed inside one SPAN tag so they can be later modified by Update code. All these changes and modifications are applayed to the tag that we return as result from RenderHTML method.

As you can see you have to have all these things in mind when you create your own controls. Of course there is one feature in TIWHTMLTag class that is not documented at all in IntraWeb.

Sometimes we need to create complex controls which cosists from more HTML tags not from only one. This is not a problem when we create for example non input control. But for input controls we have to probvide an INPUT tag that will be used as holder of the value of the control.

For that purpose we need to construct complex HTML tags like this:

<span>Label value</span><input type="hidden" value="test value">
<script>
  // Some JavaScript here that does something with our control.
</script>

and in this case we have to return as result the HTML Tag object that is for INPUT tag which will receive all additional attributes

In order to achieve this we will use this code in our RenderHTML method:

function TMyTestIWControl.RenderHTML(AContext: TIWBaseHTMLComponentContext): TIWHTMLTag;
var
  ownerTag: TIWHTMLTag;
begin
  ownerTag := TIWHTMLTag.CreateHTMLTag('');
  with ownerTag.Contents.AddTag('SPAN') do begin
    Contents.AddText('Label value');
  end;

  result := TIWHTMLTag.CreateHTMLTag('INPUT', cbSimpleClose);
  with result do begin
    AddStringParam('type', 'hidden');
  end;
  ownerTag.Contents.AddTagAsObject(result, true);
  with ownerTag.Contents.AddTag('SCRIPT') do begin
    Contents.AddText(#13 + '// Some JavaScript here that does something with our control' + #13);
  end;
end;

In order to test this create new IntraWeb standalone application for HTML 4. Append one new Unit and in this unit define new control class that descends from
TIWControl. We choose TIWControl in order to use built in support for submit and value. Override RenderHTML method and into it's body copy code from above.

Now in Form onCreate event handler add this code:

with TMyTestIWControl.Create(self) do begin
    Parent := Self;
end;

As result when you run your test application you will see the text Label value in the top left corner of your browser window.

That's it for now. I hope you enjoyed reading this article.


Server Response from: ETNASC04