org.symbian.tools.wrttools.doc.WRTKit/html/WRTKit_Creating_the_Hello_World_widget-GUID-d638159a-d12b-476c-a74c-99055672b7be.html
changeset 230 7848c135d915
equal deleted inserted replaced
229:716254ccbcc0 230:7848c135d915
       
     1 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       
     2 <html lang="en" xml:lang="en">
       
     3 <head>
       
     4 <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
       
     5 <meta name="copyright" content="(C) Copyright 2005" />
       
     6 <meta name="DC.rights.owner" content="(C) Copyright 2005" />
       
     7 <meta content="concept" name="DC.Type" />
       
     8 <meta name="DC.Title" content="Creating the Hello World widget" />
       
     9 <meta scheme="URI" name="DC.Relation" content="WRTKit_Hello_World_Tutorial-GUID-67e0a561-48ac-4938-8f1b-852422b71380.html" />
       
    10 <meta content="XHTML" name="DC.Format" />
       
    11 <meta content="GUID-D638159A-D12B-476C-A74C-99055672B7BE" name="DC.Identifier" />
       
    12 <meta content="en" name="DC.Language" />
       
    13 <link href="commonltr.css" type="text/css" rel="stylesheet" />
       
    14 <title>
       
    15 Creating the Hello World widget</title>
       
    16 </head>
       
    17 <body id="GUID-D638159A-D12B-476C-A74C-99055672B7BE"><a name="GUID-D638159A-D12B-476C-A74C-99055672B7BE"><!-- --></a>
       
    18 
       
    19 
       
    20 
       
    21     <h1 class="topictitle1">
       
    22 Creating the Hello World widget</h1>
       
    23 
       
    24     <div>
       
    25 
       
    26         <div class="section"><h2 class="sectiontitle">
       
    27 What goes in the widget?</h2>
       
    28 
       
    29             
       
    30             <p>
       
    31 
       
    32                 One of the main reasons why Hello World is a good example to start with is
       
    33                 because it is a minimal widget and shows the minimal set of steps that you
       
    34                 would go through to create a widget that uses the WRTKit for its user interface.
       
    35                 We will create just two files, an HTML file called HelloWorld.html and a JavaScript
       
    36                 file called HelloWorld.js and both will be very short.
       
    37             </p>
       
    38 
       
    39             <p>
       
    40 
       
    41                 Before we'll start writing code let's talk about what exactly it is that we want
       
    42                 to build. A typical Hello World application simply displays the text Hello World
       
    43                 with the minimal amount of code. But because using the WRTKit is so simple, we'll
       
    44                 go one step further and make it a bit fancier.
       
    45             </p>
       
    46 
       
    47             <p>
       
    48 
       
    49                 WRTKit user interfaces are composed of views and controls. A view is one logical
       
    50                 group of stuff that you can see on the screen. A view can be longer than what fits
       
    51                 on the screen at once in which case the user has to scroll, but it's still one view.
       
    52                 For example in a web browser application you might have one view for the bookmarks,
       
    53                 another for settings and a third view for viewing actual web pages. Controls are
       
    54                 user interface elements like buttons, text fields, checkboxes, etc. that either
       
    55                 let the user perform some kind of interactive action or simply shows some information.
       
    56                 When you create a user interface with the WRTKit you create one or more controls,
       
    57                 one or more views, and place the controls on the views. After this, all you have to
       
    58                 do is ask one of the views to be displayed and the rest happens automatically.
       
    59             </p>
       
    60 
       
    61             <p>
       
    62 
       
    63                 Since this is a very simple widget we will just have one view and we'll call it
       
    64                 the "main view". Instead of just saying "Hello World" we will let the user input
       
    65                 their name and then click a button to popup a dialog that says hello to the user
       
    66                 by name. E.g. if the user enters "John" we will popup "Hello John!". But we will
       
    67                 also create some error handling so that if the user doesn't input a name we will
       
    68                 popup a warning dialog that says "Please enter your name!" instead.
       
    69             </p>
       
    70 
       
    71         </div>
       
    72 
       
    73         <div class="section"><h2 class="sectiontitle">
       
    74 The HelloWorld.html file</h2>
       
    75 
       
    76             
       
    77                 <p>
       
    78 
       
    79                 As mentioned earlier, you create user interfaces using JavaScript rather than
       
    80                 HTML when you use the WRTKit. Because of this it's perhaps not so surprising
       
    81                 that the HTML file is extremely short. What might come as a surprise however is
       
    82                 that it's extremely short and nearly identical no matter what kind of widget
       
    83                 you are building if you are using the WRTKit. In fact it typically only has
       
    84                 about 10 lines of code, including the DOCTYPE declaration! Here's what it looks
       
    85                 like:
       
    86             </p>
       
    87 
       
    88 <pre>
       
    89 
       
    90 &lt;?xml version="1.0" encoding="UTF-8"?&gt;
       
    91 &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
       
    92 &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
       
    93     &lt;head&gt;
       
    94         &lt;title&gt;&lt;/title&gt;
       
    95         &lt;script type="text/javascript" src="WRTKit/WRTKit.js"&gt;&lt;/script&gt;
       
    96         &lt;script type="text/javascript" src="HelloWorld.js"&gt;&lt;/script&gt;
       
    97     &lt;/head&gt;
       
    98     &lt;body onload="init()"&gt;
       
    99     &lt;/body&gt;
       
   100 &lt;/html&gt;
       
   101 </pre>
       
   102 
       
   103             <p>
       
   104 
       
   105                 We're using XHTML 1.0 so the DOCTYPE declaration is for XHTML 1.0 Strict. And
       
   106                 because this is XHTML we also have the normal XML declaration (&lt;?xml...).
       
   107                 After that the content should be familiar even if you've used previously only
       
   108                 used HTML rather than XHTML. We have a normal html root level tag with a head
       
   109                 and body. Note that in XHTML tags are case sensitive and should be in lowercase
       
   110                 as in the example above. The xmlns attribute is a name space declaration that
       
   111                 states that all the tags used here are part of the XHTML standard.
       
   112             </p>
       
   113 
       
   114             <p>
       
   115 
       
   116                 Because we're creating a widget and not a web page we don't need to have a title. If you
       
   117                 want you can define one here but you won't see it anywhere. Next comes an important
       
   118                 bit: <samp class="codeph">
       
   119 &lt;script type="text/javascript" src="WRTKit/WRTKit.js"&gt;&lt;/script&gt;.</samp>
       
   120                 That piece of code instructs the Web Runtime to load a JavaScript file called WRTKit.js
       
   121                 from a directory called WRTKit. The WRTKit.js file takes care of loading the WRTKit and
       
   122                 including all the files that are needed by it. Those files are all inside the WRTKit
       
   123                 directory and you don't need to concern yourself with them at this point. In fact
       
   124                 all you need to do to use the WRTKit in a widget is to copy the WRTKit directory into
       
   125                 your own widget's root directory and then include the XHTML script tag presented above
       
   126                 that loads the WRTKit/WRTKit.js JavaScript file. If you are creating a widget of your own
       
   127                 you can find the WRTKit directory in the Library directory in the WRTKit SDK. But for your
       
   128                 convenience it has already been copied to the Hello World example.
       
   129             </p>
       
   130 
       
   131             <p>
       
   132 
       
   133                 Notice that there's another script tag too, this one loading a file called HelloWorld.js.
       
   134                 This is where we'll put all the JavaScript code that implements our Hello World widget.
       
   135                 We could have just written the JavaScript code inline between a &lt;script&gt; and
       
   136                 &lt;/script&gt; tag in the HelloWorld.html file but the HTML file is less cluttered if 
       
   137                 we move all JavaScript to a separate file.
       
   138             </p>
       
   139 
       
   140             <p>
       
   141 
       
   142                 Finally let's look at the body tag. There are two things of interest here. First of all
       
   143                 there's no content between &lt;body&gt; and &lt;/body&gt;. That's because all of the
       
   144                 content will be created by the WRTKit using JavaScript. And that leads us to the other
       
   145                 point of interest in the body: the <samp class="codeph">
       
   146 onload="init()"</samp> attribute of the
       
   147                 body tag. This sets up an event handler that gets called after the widget has loaded
       
   148                 all of its content. The event handler calls a JavaScript function called init(). This
       
   149                 is the point where we jump from the HTML to JavaScript. From this point on everything
       
   150                 will be JavaScript and the place where it all starts is the init() function that gets
       
   151                 called thanks to this little onload event handler for the body tag.
       
   152             </p>
       
   153 
       
   154         </div>
       
   155 
       
   156         <div class="section"><h2 class="sectiontitle">
       
   157 The HelloWorld.js file</h2>
       
   158 
       
   159             
       
   160             <p>
       
   161 
       
   162                 The HTML file that we created above set things up so that there is a function call
       
   163                 to a function named "init()" when the widget is done loading. No such function exists
       
   164                 a this point so we have to create it. The init() function is the entry point to our
       
   165                 JavaScript and this is also where we will start the implementation.
       
   166             </p>
       
   167 
       
   168             <p>
       
   169 
       
   170                 The S60 Web Runtime supports two kinds of user interface interaction: tab and
       
   171                 pointer. The WRTKit supports but methods but usually the tab interaction method
       
   172                 (also known as "navigation mode") is preferred. Unfortunately the pointer based
       
   173                 navigation mode is the default so we'll have to disable it and switch to the tab
       
   174                 navigation mode. Also by default the softkey bar is hidden, which we don't want
       
   175                 because we want to give the user a clue about how to exit the widget. The good news
       
   176                 is that these two tweaks are easy to do and only requires two simple method calls.
       
   177                 The bad news is that those method calls are done through objects that only exist
       
   178                 in the Web Runtime but not in a PC web browser. Due to this, we'll create the
       
   179                 init() function as follows:
       
   180             </p>
       
   181 
       
   182 <pre>
       
   183 
       
   184 // Called from the onload event handler to initialize the widget.
       
   185 function init() {
       
   186     // set tab-navigation mode and show softkeys
       
   187     // (only if we are in the WRT environment)
       
   188     if (window.widget) {
       
   189         widget.setNavigationEnabled(false);
       
   190         menu.showSoftkeys();
       
   191     }
       
   192 }
       
   193 </pre>
       
   194 
       
   195             <p>
       
   196 
       
   197                 We wrapped the calls to disable the pointer navigation and show the softkeys
       
   198                 in an if-clause that checks if there's such an object available as window.widget.
       
   199                 This will evaluate to false on a PC web browser but true in the S60 Web Runtime.
       
   200             </p>
       
   201 
       
   202             <p>
       
   203 
       
   204                 Now that we've tuned the Web Runtime to our liking we can create the actual
       
   205                 user interface. We'll create four things: the so-called "user interface manager"
       
   206                 that is in charge of managing views and other user interface resources, the main
       
   207                 view for the widget, a text field where users can enter their name, and finally
       
   208                 a button that they can click on to popup a notification dialog that says "Hello"
       
   209                 Notice that we don't have to create the notification dialog because this is done
       
   210                 for us by the user interface manager.
       
   211             </p>
       
   212 
       
   213             <p>
       
   214 
       
   215                 Before we create those four objects we will declare four global variables so that
       
   216                 we can access those objects elsewhere in the widget. So let's add the following
       
   217                 to the top of the file (outside the init() function):
       
   218             </p>
       
   219 
       
   220 <pre>
       
   221 
       
   222 // References to the WRTKit user interface manager and main view.
       
   223 var uiManager;
       
   224 var mainView;
       
   225 
       
   226 // References to controls in the main view.
       
   227 var helloButton;
       
   228 var nameField;
       
   229 </pre>
       
   230 
       
   231             <p>
       
   232 
       
   233                 Now that we have some variables that can track the objects we are about to create
       
   234                 we can actually craete those objects. We'll create the objects inside the init()
       
   235                 function so that the user interface gets created right after the widget has loaded.
       
   236             </p>
       
   237 
       
   238             <p>
       
   239 
       
   240                 The first thing we create is the user interface manager. This is quite simple and
       
   241                 requires only a single line of code:
       
   242             </p>
       
   243 
       
   244 <pre>
       
   245 
       
   246 // create UI manager
       
   247 uiManager = new UIManager();
       
   248 </pre>
       
   249 
       
   250             <p>
       
   251 
       
   252                 Next we'll create the main view. The WRTKit allows all kinds of views to be created
       
   253                 if one has special needs for how user interface controls should be laid out. However
       
   254                 in the vast majority of cases the ListView class will be sufficient and that's what
       
   255                 we'll create this time too:
       
   256             </p>
       
   257 
       
   258 <pre>
       
   259 
       
   260 // create main view
       
   261 mainView = new ListView(null, "Hello World");
       
   262 </pre>
       
   263 
       
   264             <p>
       
   265 
       
   266                 The first argument to the ListView constructor is a unique identifier for the view.
       
   267                 All user interface elements in the WRTKit can have a unique identifier. The identifier
       
   268                 is helpful if you want to specifically target a view or control with some CSS style
       
   269                 rule or if you want to identify the source of an event in an event listener callback,
       
   270                 etc. However we don't need it here so we don't bother giving our main view a unique
       
   271                 id and just pass a null identifier value instead. The second argument is a caption for
       
   272                 the view. We'll just call our view "Hello World". The caption will be displayed at the
       
   273                 very top of the screen when we display the main view. But before we do that, let's
       
   274                 create the rest of the user interface.
       
   275             </p>
       
   276 
       
   277             <p>
       
   278 
       
   279                 The widget should have a text field to let users enter their name and a button to
       
   280                 trigger the greeting popup. Both the text field and the button are WRTKit controls
       
   281                 and will be created and added to the main view that we just created. There are two
       
   282                 kinds of buttons in the WRTKit though, form buttons and navigation buttons. Form
       
   283                 buttons are meant to trigger actions whereas navigation buttons are meant for 
       
   284                 situations where clicking it would result in moving from one view to another. Clearly
       
   285                 therefore, we want a form button in this case.
       
   286             </p>
       
   287 
       
   288             <p>
       
   289 
       
   290                 Creating the textfield and form button is done as follows:
       
   291             </p>
       
   292 
       
   293 <pre>
       
   294 
       
   295 // add a text field to the view
       
   296 nameField = new TextField(null, "Enter your name");
       
   297 mainView.addControl(nameField);
       
   298 
       
   299 // add a button to the view
       
   300 helloButton = new FormButton(null, "Say Hello!");
       
   301 mainView.addControl(helloButton);
       
   302 </pre>
       
   303 
       
   304             <p>
       
   305 
       
   306                 The first argument for both the textfield and button is the same as for the view:
       
   307                 an optional unique identifier. We won't need it here either so rather than scratching
       
   308                 our heads trying to come up with a unique identifier that we'll end up ignoring we'll
       
   309                 just define it as null. The second argument for the textfield constructor is a caption.
       
   310                 All controls except buttons have captions and this is the second argument in all
       
   311                 constructors for controls with captions. The caption is displayed above the control
       
   312                 and tells the user what the control does. In our case we want to have a textfield where
       
   313                 the user should enter the name so we'll use "Enter your name" as the control caption.
       
   314                 The second argument for the button constructor is the text for the button. The button
       
   315                 text for form buttons should be a verb or other descriptive text that lets the user know
       
   316                 what happens if the button is pressed. We'll put "Say Hello!" on our button.
       
   317             </p>
       
   318 
       
   319             <p>
       
   320 
       
   321                 After we have created a control we can add it to a view. Custom views can have their
       
   322                 own ways to do so but in the case of the default ListView that you'll use in most cases
       
   323                 you add a control by calling the addControl() method.
       
   324             </p>
       
   325 
       
   326             <p>
       
   327 
       
   328                 The user interface for the main view is now ready and we can show it. Showing a view
       
   329                 is done by calling setView() in the user interface manager. So we'll add one more line
       
   330                 of code to the end of the init() function:
       
   331             </p>
       
   332 
       
   333 <pre>
       
   334 
       
   335 // display the main view
       
   336 uiManager.setView(mainView);
       
   337 </pre>
       
   338 
       
   339             <p>
       
   340 
       
   341                 If you zipped up the widget directory, renamed it HelloWorld.wgz and installed the
       
   342                 widget on an emulator or handset, or just simply ran it in a PC web browser, you'd
       
   343                 notice that the user interface seems to work. There's just one problem. Clicking on
       
   344                 the button doesn't do anything! But don't worry, we're about to fix that.
       
   345             </p>
       
   346 
       
   347         </div>
       
   348 
       
   349         <div class="section"><h2 class="sectiontitle">
       
   350 Handling events</h2>
       
   351 
       
   352             
       
   353             <p>
       
   354 
       
   355                 The thing that is missing is that we have no way of knowing when the button was
       
   356                 pressed. And without knowing when it's pressed we can't react to the press and
       
   357                 show a greeting. A user interface action such as pressing a button is called an
       
   358                 "event". In the WRTKit events are reported to "listener" functions that developers
       
   359                 can register to controls. The way this is done is by creating a function that you
       
   360                 want to get called when an event occurrs, and then calling addEventListener() on
       
   361                 the control whose events you are interested in, passing the function to that method.
       
   362                 However there are many types of events and you are almost surely not interested in
       
   363                 all of them. Because of this you can specify the type of event that you want to get
       
   364                 notified about by giving the event type name to the addEventListener() method. The
       
   365                 event types and their names are described in the
       
   366                 <a href="WRTKit_API_Reference-GUID-00e47c27-0a1a-443f-ae85-cf3381635170.html">
       
   367 WRTKit API Reference</a>
       
   368                 for each control. Note that because controls inherit from other classes they also
       
   369                 inherit event types.
       
   370             </p>
       
   371 
       
   372             <p>
       
   373 
       
   374                 The event type that we're interested in here is "ActionPerformed". That event is
       
   375                 fired by form buttons whenever a user clicks on them. In order to get notified
       
   376                 of this event we'll need two things: create a function that will get called when
       
   377                 the event occurs and register that function as an event listener to our button.
       
   378                 Let's create the function first but leave the implementation empty for now:
       
   379             </p>
       
   380 
       
   381 <pre>
       
   382 
       
   383 // Called when the hello-button is clicked.
       
   384 function helloButtonClicked(event) {}
       
   385 </pre>
       
   386 
       
   387             <p>
       
   388 
       
   389                 Now that we have the event handler callback function we can add the event listener
       
   390                 registration code. Let's put that right after where we create the button in
       
   391                 the init() function:
       
   392             </p>
       
   393 
       
   394 <pre>
       
   395 
       
   396 helloButton.addEventListener("ActionPerformed", helloButtonClicked);
       
   397 </pre>
       
   398 
       
   399             <p>
       
   400 
       
   401                 Now our helloButtonClicked() function will get called whenever the button is
       
   402                 clicked. Notice that the function has an argument called event. This argument
       
   403                 will receive an event object that describes the event that occurred. This can
       
   404                 be useful if you have an event handler function that handles many different
       
   405                 events. The event object contains three properties that you can examine to
       
   406                 decide on what to do: a property called "source" that points back to the control
       
   407                 or view from where the event was fired, a property called "type" that contains
       
   408                 the event type name for this event, and a property called "value" that has
       
   409                 helpful additional info that depends on the event type. You'll find more detailed
       
   410                 information about this in the API Reference.
       
   411             </p>
       
   412 
       
   413         </div>
       
   414 
       
   415         <div class="section"><h2 class="sectiontitle">
       
   416 Notification popup dialogs</h2>
       
   417 
       
   418             
       
   419             <p>
       
   420 
       
   421                 All that remains now is to write the code that shows the greeting popup dialog
       
   422                 when the button is pressed. This code will naturally go in the helloButtonClicked()
       
   423                 function.
       
   424             </p>
       
   425 
       
   426             <p>
       
   427 
       
   428                 Using notification popup dialogs is very easy with the WRTKit. The user interface
       
   429                 manager has two methods: showNotification() and hideNotification() that are used
       
   430                 to show and hide notification popup dialogs. The showNotification() method takes
       
   431                 four arguments: displayTime, type, text and progress. The displayTime argument is
       
   432                 used to supply a time (in milliseconds) for how long the notification popup should
       
   433                 be shown for. We want our greeting to be visible for 3 seconds so we'll pass 3000
       
   434                 to this argument. The type argument is a string that tells the method what kind of
       
   435                 popup to show, which determines the visual style of the popup. We'll be using two types:
       
   436                 "info" and "warning". The "info" type for when we show the greeting and "warning" if
       
   437                 the user didn't enter a name and we want to show a notification dialog that complains
       
   438                 about this. The text argument is simply the text to show in the notification dialog.
       
   439                 And finally the progess argument is a decimal number between 0.0 and 1.0 that is
       
   440                 used in progress dialogs to display how far along a process is.
       
   441             </p>
       
   442 
       
   443             <p>
       
   444 
       
   445                 A progress of 0.0 means "0% progress" and 1.0 means "100% progress". So for example
       
   446                 if some process is 25% completed, you'd pass 0.25 to this argument. If you don't know
       
   447                 how long a process will take you can pass a negative number. This will result in an
       
   448                 animated progress bar that has a visual style that indicates that the progress is
       
   449                 unknown. Typically you'd use the "wait" notification type is you want to show a
       
   450                 progress dialog. If you don't want to show any progress information in the dialog,
       
   451                 such as in our case, you can omit the progress argument or pass a null to it.
       
   452             </p>
       
   453 
       
   454             <p>
       
   455 
       
   456                 Before we can write our code we need one more thing. We need to know what the user
       
   457                 wrote in the name textfield. This value can be retrieved by calling the getText()
       
   458                 method for the textfield. We're now ready to write the code for the helloButtonClicked()
       
   459                 function:
       
   460             </p>
       
   461 
       
   462 <pre>
       
   463 
       
   464 var name = nameField.getText();
       
   465 if (name.length == "") {
       
   466     uiManager.showNotification(3000, "warning", "Please enter your name!");
       
   467 } else {
       
   468     uiManager.showNotification(3000, "info", "Hello " + name + "!");
       
   469 }
       
   470 </pre>
       
   471 
       
   472             <div class="fignone" id="GUID-D638159A-D12B-476C-A74C-99055672B7BE__GUID-A2B73DB1-6494-4806-A11E-2E7F9BB1B3E7"><a name="GUID-D638159A-D12B-476C-A74C-99055672B7BE__GUID-A2B73DB1-6494-4806-A11E-2E7F9BB1B3E7"><!-- --></a><span class="figcap">Figure 1. 
       
   473 The Hello World widget</span>
       
   474 
       
   475                 
       
   476                 <br /><img src="Hello_World_Screenshot_1.png" /><br />
       
   477             </div>
       
   478 
       
   479         </div>
       
   480 
       
   481         <div class="section"><h2 class="sectiontitle">
       
   482 Wrapping up</h2>
       
   483 
       
   484             
       
   485             <p>
       
   486 
       
   487                 The Hello World widget is now done and you can zip it up, rename it to HelloWorld.wgz
       
   488                 and deploy it on a handset or emulator. But before that, let's try it in a normal PC
       
   489                 browser. Testing in a PC browser is useful because it allows you to use deubugging tools
       
   490                 (like the Firebug JavaScript debugger for Firefox) in case something isn't working. Using
       
   491                 a PC browser to test is also very fast because you don't have to install the widget to
       
   492                 the emulator or handset. Just hit reload in the web browser when you make a change and
       
   493                 you can see the results immediately. Of course there are features that will be missing
       
   494                 in a web browser, such as that you won't have access to the Options menu or any other
       
   495                 advanced widget functionality. But for the purpose of rapidly testing user interfaces
       
   496                 it can be very helpful.
       
   497             </p>
       
   498 
       
   499             <p>
       
   500 
       
   501                 There are a couple of points that are good to note now that the widget is ready.
       
   502                 First of all, your widget now works with both the pointer and tab navigation modes. If
       
   503                 you comment out the <samp class="codeph">
       
   504 widget.setNavigationEnabled(false)</samp> call in the init()
       
   505                 function you can try this out. Second, your widget works resolution independently.
       
   506                 You can try this either by resizing the PC browser window or by trying the widget out
       
   507                 with different resolutions in the S60 emulator. Third, the widget correctly handles
       
   508                 screen rotations and other resizes, e.g. if the softkey bar is hidden / shown. Fourth,
       
   509                 the widget looks can be customized without needing to touch any code - simply by changing
       
   510                 the UI.css and image files that you can find in the WRTKit/Resources directory.
       
   511             </p>
       
   512 
       
   513             <p>
       
   514 
       
   515                 But perhaps more important than any of the above is the fact that the WRTKit simplifies
       
   516                 the separation of user interface code from data and logic code. That's not something
       
   517                 that is apparent in a simple widget like this one, but it becomes very important as
       
   518                 you create something more complex and especially if the user interface contains elements
       
   519                 that are created dynamically for example based on data that has been fetched from the
       
   520                 Internet using AJAX.
       
   521             </p>
       
   522 
       
   523         </div>
       
   524 
       
   525     </div>
       
   526 
       
   527 <div>
       
   528 <div class="familylinks">
       
   529 <div class="parentlink"><strong>Parent topic:</strong> <a href="WRTKit_Hello_World_Tutorial-GUID-67e0a561-48ac-4938-8f1b-852422b71380.html">Hello World</a></div>
       
   530 </div>
       
   531 </div>
       
   532 
       
   533 </body>
       
   534 </html>