anon-549436's picture
From anon-549436 rss RSS 

Overview 

Overview

 

 
 
Tags:  tomcat  struts ajax  google ajax api  ajax api 
Views:  169
Published:  January 16, 2012
 
0
download

Share plick with friends Share
save to favorite
Report Abuse Report Abuse
 
Related Plicks
Gadgets Intro (Plus Mapplets)

Gadgets Intro (Plus Mapplets)

From: sdiderid
Views: 194 Comments: 0

 
Drupal module development- Hot in Buzz

Drupal module development- Hot in Buzz

From: jakiwatsonn
Views: 13 Comments: 0

 
Word.doc.doc

Word.doc.doc

From: atgtciv
Views: 633 Comments: 0
Word.doc.doc
 
World-wide-web To Print Why It Will Get the job done.20130224.03154 0

World-wide-web To Print Why It Will Get the job done.20130224.031540

From: fangmagic39
Views: 12 Comments: 0

 
NetSuite Application Development Experts

NetSuite Application Development Experts

From: mindfiresolutions
Views: 320 Comments: 0
NetSuite is a leading provider of on-demand, integrated business management software suites such as CRM, accounting, ERP, sales force automation, marketing automation,e-commerce and web site development for midsized -market enterprises and divisions (more)

 
Journey Web 1.0 to 2.0 Nitin Kadam

Journey Web 1.0 to 2.0 Nitin Kadam

From: lxsong
Views: 442 Comments: 0

 
See all 
 
More from this user
Reliance Life Insurance Summer Project Report 2010

Reliance Life Insurance Summer Project Report 2010

From: anon-549436
Views: 137
Comments: 0

 
See all 
 
 
 URL:          AddThis Social Bookmark Button
Embed Thin Player: (fits in most blogs)
Embed Full Player :
 
 

Name

Email (will NOT be shown to other users)

 

 
 
Comments: (watch)
 
 
Notes:
 
Slide 1: AjaxFace Tutorial AjaxFace Tutorial Version 1.5 Copyright © 2006 Vertex Logic, Inc Page 1 of 36
Slide 2: AjaxFace Tutorial Table of Contents 1 Overview......................................................................................................................4 1.1 Benefits..............................................................................................................................4 1.2 Architecture Overview........................................................................................................5 1.3 Easy Prototype and Development Model...........................................................................6 1.4 Using Rest of this Document..............................................................................................6 2 Installation and Directory Structure..........................................................................8 3 How to build a rich client using AjaxFace?...............................................................9 3.1 Development Environment.................................................................................................9 3.2 Overview of the sample application UI...............................................................................9 3.3 Stepwise Creation of Rich Client........................................................................................9 3.3.1 Writing Bootstrap HTML Page......................................................................................10 3.3.2 Add Navigation Bar.......................................................................................................11 3.3.3 Creating Project Management Sub-view.......................................................................12 3.3.4 Setting Navigation.........................................................................................................14 3.3.5 Create Project and User List Sub-views.......................................................................14 3.3.6 Load Data from the Server using AJAX Calls...............................................................14 3.3.7 Loading Multiple Data Source.......................................................................................15 3.3.8 Event Listener for Project Selection..............................................................................16 3.3.9 Loading a New Project on User Selection.....................................................................17 3.3.10 Using Client side Data Cache.....................................................................................17 3.3.11 Using Status Bar.........................................................................................................18 3.3.12 Sending Updates to the Server...................................................................................19 3.4 Using HTML File as Template / Tile.................................................................................19 4 Adding Data Source..................................................................................................20 4.1 Internal Data Structures....................................................................................................20 4.2 Addressing Values...........................................................................................................23 4.3 Data Binding.....................................................................................................................23 4.3.1 Binding Single Object....................................................................................................24 4.3.2 Binding Array of Objects...............................................................................................24 4.3.3 Binding Object Tree .....................................................................................................24 4.3.4 Binding Array of Object Trees.......................................................................................24 4.4 Using data files for Development......................................................................................24 4.5 Using Application Server as Data Source.........................................................................24 4.5.1 Retrieving Data from the Application Server.................................................................24 4.5.2 Submit User Updates....................................................................................................24 5 Adding New Components.........................................................................................27 Page 2 of 36
Slide 3: AjaxFace Tutorial 5.1 Overview of the New Class..............................................................................................27 5.2 Overriding Component Class...........................................................................................27 5.3 New Public API of SelectComp........................................................................................28 5.4 Methods Overridden.........................................................................................................28 5.5 Adding Behavior...............................................................................................................31 5.6 Using Af. Component in Form and Table.........................................................................34 6 Deploying Application..............................................................................................35 7 Debugging Support...................................................................................................36 Page 3 of 36
Slide 4: AjaxFace Tutorial 1 Overview AjaxFace is a framework for building rich WEB UI using client-side rendering architecture. The main component of the framework is a rendering-engine written in JavaScript. Developers use a high level API for constructing UI in JavaScript. The top level object of the UI is represented by an object called ‘view’. The view is an aggregate of various UI artifacts such as Navigation, Tab, Table, Tree, Form, Button, Menu, Toolbar, Data Grids etc. The high level API is used for specifying structure of the view by instantiating components and creating hierarchy. It is similar to Java Swing, .net control UI. One major difference is a high level API supports constructs such as Forms, Live Grids, Flows, Tree, Table-Tree etc. The event propagation and data bindings follow certain patterns which is automatic in most cases or easy to specify and control in specific cases. Another component of the framework is a Data Cache. Data Cache manages application data on the client side. Data Cache uses XML messages for communication with the server using AJAX calls. Data Cache tracks user updates and can communicate with the server optimally by sending the change list. A major change in version 1.5 – ajaxFace introduced namespace called ‘Af’. It means a class such as ‘RptTable’ is referred by ‘Af.RptTable’. Also, previous namespace ‘VL’ used for certain classes has been replaced by new namespace ‘Af’ to be consistent. 1.1 Benefits  Easy to use framework for designing rich WEB UI that in-turn results in multifold improvement in the user productivity and satisfaction.  High level constructs supporting easy UI construction, automatic event propagation and data binding.  Provides rich components. For example, switching between tabs does not require round trip to the server.  Light weight and high performance framework.  No need to learn server side programming models such as ASP, JSP, JSF, Strut etc. At the same time AjaxFace framework can interoperate with ASP, JSP, JSF, Strut etc programming models.  Simplifies development process by supporting UI development without having to write the server side code (as is the case with ASP, JSP etc).  Simplifies UI style customization through comprehensively designed style sheet.  Enables script based programming model.  Supports all commonly used UI interaction components.           Forms Tables Data Grids Tree Table Tree Tabs Navigation Bars Flow Layouts List All commonly used fields Page 4 of 36
Slide 5: AjaxFace Tutorial 1.2 Architecture Overview  HTML pages with the embedded JavaScript API are served by the server. These HTML pages contain JavaScript written using API provided by AjaxFace. The premise here is that these views provide rich interaction and the framework API greatly simplifies writing JavaScript code.  Browser automatically downloads the framework components along with these pages.  Embedded JavaScript code is converted to HTML Elements hierarchy by the rendering engine on the client side. (Java Script Components hierarchy to HTML element hierarchy).  The generated views fetch application data as needed through the Data Cache or directly.  AjaxFace tracks user changes and submit the modified data to the server as XML.  Event listeners, custom components are added by the developer as required. WEB/Application Server (Apache, IIS, Tomcat, Jetty, Java/EJB, .net) HTML Pages with JavaScript API or XML Tags HTML/ XML over HTTP/HTTPS AJAX Calls to send, receive data, commands, response Browser JavaScript Rendering Engine Data Cache Rendered Pages Page 5 of 36
Slide 6: AjaxFace Tutorial 1.3 Easy Prototype and Development Model  Since AjaxFace mixes application data and HTML elements on the client side, it does not require JSP, ASP etc frameworks on the server side.  HTML files can be directly accessed by the browser from the file system.  Initial data source can be created in the form of XML, csv files.  It simplifies prototyping and increases developers’ productivity. XML, .csv files as data source Served by a WEB Server HTML Pages with JavaScript API or XML Tags WEB Server Browser JavaScript Rendering Engine Data Cache Rendered Pages 1.4 Using Rest of this Document This chapter gives an overview of AjaxFace framework. The remaining chapters are as follows:  Chapter 2 - How to install AjaxFace and the installation directory structure.  Chapter 3 - How to build a rich client using AjaxFace API.  Chapter 4 - How to add data source for the rich client. A typical implementation of a Data Cache is discussed. It can be customized to match with the server protocol (as in the Page 6 of 36
Slide 7: AjaxFace Tutorial application level protocol). Alternatively, the server can map the data to match with the default data cache.  Chapter 5 – How to add new components.  Chapter 6 - How to deploy client application with the WEB server.  Chapter 7 – How to use the framework debugging feature to debug an application program.  Chapter 8 - Pointers to more information. Page 7 of 36
Slide 8: AjaxFace Tutorial 2 Installation and Directory Structure In order to install AjaxFace, unzip AjaxFace.zip inside a subdirectory on your machine, say AjaxFace. This directory is the installation of AjaxFace and consists of the following directories.  ‘readme.html’ – read me file.  ‘fw’ subdirectory containing AjaxFace framework.  ‘fw/scripts contain the following javascript files.  OpenSource.js – a file containing open source components (Rico and dynarch calendar component)  AjaxFaceAll.js – AjaxFace framework.  ‘fw/images’ – default images used by the framework components.  ‘fw/css/AjaxFaceAll.css’ – CSS file of the framework.  ‘tutorial’ the source files of the example discussed in this guide.  ‘samples’ – examples of certain components’ usage.  ‘data’ – XML data files that are accessed from the www.vertexlogic.com. Instead of www.vertexlogic.com WEB server, if you choose to use your own server then you can copy these files to your web server. Following that you need to change the ‘baseURL’ variable of each file to point to your server. The default value of ‘baseURL is as follows. var baseURL = "http://www.vertexlogic.com/apps/data/";  ‘doc’ contains the documentation. ‘API’ documentation is accessed from www.vertexlogic.com/ajaxface/api/ajaxface.html WEB site. Page 8 of 36
Slide 9: AjaxFace Tutorial 3 How to build a rich client using AjaxFace? The usage of AjaxFace framework is explained using a project management application. The major functions of this application are related with the viewing and updating of project plan documents. The structure of these documents is similar to plans created using Microsoft Project i.e. ‘a project plan contains tasks, tasks contains sub-tasks and so on. In addition to project management functions, it supports simple user management functions. The project plans are stored as XML files. For the purpose of this tutorial, these files are served off www.vertexlogic.com WEB site. Serving data off www.vertexlogic.com is only for convenience to get a user started quickly. In reality the data will be served off an Application/ WEB server such as App/WEB server such as Web Logic, Web Sphere, Tomcat, IIS, Apache or custom. Chapter 5 discusses how to use your own App/Web Server. The following section describes the steps used to build project management application using AjaxFace. 3.1 Development Environment The development environment is rather simple. In a new subdirectory, copy ‘fw’ subdirectory from the installation. The rest of the document assumes that the user developed code is stored inside a subdirectory of the work directory. In this case, ‘tutorial’ is that sub-directory where source code resides. Later the work directory can be deployed with the WEB server. The deployment with the WEB server is discussed in chapter 5. • • • The new subdirectory containing ‘fw’ directory serves as the work directory. Copy ‘fw’ subdirectory from the AjaxFace installation to your work directory. The following discussion assumes that the ‘tutorial’ subdirectory inside the work directory contains the source code. Once you are familiar with the development environment, you can copy tutorial to any other name and experiment with it. Other than the above setup, user requires a favorite editor and WEB browser for development. HTML Kit available from (http://www.chami.com) encompasses editor and browser in the same pane and is very effective for editing and viewing the application using a single click. 3.2 Overview of the sample application UI The example UI consists of the following components.  A navigation bar.  Project management sub-view containing a tabbed view with two pages.  List of project sub-view showing a tabular view of all projects.  User management view shows a list of users and details of the selected user. 3.3 Stepwise Creation of Rich Client The application is described using a number of steps. Each step has a file name Step-1.html, Step2.html etc. Each step is a progressive succession of the previous step. It means that the same HTML file is modified in each step. In order to explain the required steps, the file of each step is preserved. The following discussion uses a set of AjaxFace API. The higher level meaning of API is intitutive. You can escape the details of APIs at this point. Refer to AjaxFace API Doc for a comprehensive list of APIs, their details and examples on how they are used. Page 9 of 36
Slide 10: AjaxFace Tutorial • See the following table for the details of steps. Table 1 - Stepwise creation of rich client using AjaxFace Step 1 2 3 Brief Description Writing Bootstrap HTML Page Add Navigation Bar Creating Project Management Sub-view Setting Navigation 4 Create Project and User List Sub-views Load Data from the Server using AJAX Calls 5 6 7 8 9 10 Loading Multiple Data Source Event Listener for Project Selection Loading a New Project on User Selection Using Client side Data Cache Using Status Bar Sending Updates to the Server 3.3.1 Writing Bootstrap HTML Page The bootstrap HTML page is a starting page which contains application’s Java Script code. It can directly contain Java Script code or include external JavScript source files. In the following discussion the HTML page embeds the JavaScript code. Step-1.htm is the bootstrap page (which becomes Step-2.htm, Step-3.htm etc in subsequent steps). It contains header, footer etc which are static parts of the page. In addition, it contains a set of HTML elements which serve as the place-holders for the dynamic parts which will be rendered by Java Script code. These place-holders are typically defined as <div> HTML elements and each is assigned a unique identifier. The place-holder elements are used to organize dynamic parts of the view. These dynamic parts are rendered by the JavaScript code using AjaxFace API and mixing application data fetched from the server using AJAX calls. The HTML based page-layout provides the maximum flexibility. The place holder elements can be moved around without having to change the code. An artist can design them for a better look-n-feel without having to learn and touch the JavaScript code. Note that Step_1.html body tag has attribute onload="initializeUI()" defined. This method is called when the HTML page is loaded. This method is used to create the main views and all other subviews. In Step_1.html, this method is empty. The subsequent sections discuss the code executed by this method. Page 10 of 36
Slide 11: AjaxFace Tutorial 3.3.2 Add Navigation Bar Before we discuss JavaScript code for the navigation bar, let us take a look at the lines in the HTML file which include the framework components. The framework components consists of  AjaxFaceAll.js - framework’s code  AjaxFaceAll.css – framework’s style sheet These components are included in the application’s HTML file through the following lines. <link href="../fw/css/AjaxFaceAll.css" type="text/css" rel="stylesheet" /> <script src="../fw/scripts/AjaxFaceAll.js"></script> <script src="../fw/scripts/OpenSource.js"></script> Code Listing 1 – Including framework .js and CSS files • The framework defines an implicit variable called ‘view’. This is analogous to the ‘document’ of the HTML Dom. This is an instance of View class and manages UI components. See API reference for the details of View class. A view is populated with the required components and rendered as HTML elements’ hierarchy using the following invocations. See Step-2.htm’s ‘initializeUI’ method. Before calling view’s render method, it populates it with a horizontal bar component. function initializeUI() { var hnav = createTopNavigation(view); view.render(); } Code Listing 2 – Invoke method to create top navigation and render view function createTopNavigation(view) { new Image().src = "url(images/hbar.gif)"; new Image().src = "url(images/hbaritem.gif)"; // create navigation bar var hnav = new Af.HBar("TopNavigation"); hnav.target = "NavBarArea"; // create a link var nl = new Af.Link("ProjectManagement", "Project View"); // add link to the navigation bar hnav.add(nl); ……… return hnav; } Code Listing 3 – Actual code for creating the navigation bar • In ‘createTopNavigation’ method, a horizontal navigation bar is instantiated and its target is set to ‘NavBarArea’. The target is the ‘html’ element defined in the bootstrap page which Page 11 of 36
Slide 12: AjaxFace Tutorial serves the place-holder for the navigation bar. The target can be any html element of the page such as a ‘div’ or ‘span’ element. • • Also notice that the four links are added to the navigation bar. In ‘render’ method, the Navigation bar is dynamically created and added to its target ‘NavBarArea’ 3.3.3 • • Creating Project Management Sub-view Refer to Step_3.html for the following discussion. The following method creates Project Management sub-view. var pmTabs = createProjectManagementComp(view); Code Listing 4 – Invoke method to create project management view • Project Management sub-view consists of a horizontal tab. The tabbed panel contains two tab-pages. These are created as follows. var tabs = new Af.HTab("PMTabs"); tabs.target = "MainArea"; var table; var flow; ……… tabs.add(flow, "My Tasks"); ……… tabs.add(table, "Plan Tree"); ……… Code Listing 5 – Create HTab and two tabs of Project Management View • The first tab page ‘My Tasks’ is a vertical-flow containing a table and a form. var flow; flow = new Af.Flow("My Tasks"); table = new Af.RptTable("myTasks"); ……… flow.add(table); flow.addSeparator('Details'); var form = new Af.Form("My Tasks Details"); ……… tabs.add(table, "Plan Tree"); Page 12 of 36
Slide 13: AjaxFace Tutorial Code Listing 6 – Create a vertical flow containing a table and a form • The following code creates table and its columns. table = new Af.RptTable("myTasks"); table.sortable = true; var comp = table.addColumn("description", "Description", "44%"); comp.sortable = true; comp = table.addDateColumn("startDate", "Start", "10%"); comp.setFormat('mmddyy'); comp.sortable = true; Code Listing 7 – Create RptTable and its columns • The following code creates a form and its fields. var form = new Af.Form("My Tasks Details"); var t = form.addText('name', 'Name:', 0,0); t.readonly = true; t.maxLength = 30; t = form.addText('description', 'Description:', 0,1); t.width = "450px"; var dt = form.addDate('startDate', 'Start:', 1,0); dt.setFormat('mmddyyyyMonthShort'); ……… ……… Code Listing 8 – Create Form and its fields • Next we want to tie the table with the form, such that whenever a row is selected, the corresponding object is displayed in the form. We do this by specifying the data source of the form to be the object selected in the table. AjaxFace follows a special convention to address the selected object of a table. The format to address the selected object of a table is: <table name>__selectedObject is the reference of the object selected in the table <table name>. The string <table name> is replaced by the actual table name. • In order to the data source of ‘form’ to the selected object of ‘myTasks’ table, we specify as follows. form.dsPath = 'myTasks__selectedObject'; Code Listing 9 – Setting path of the data source of Form to the selected object of the table • Setting the value of ‘dsPath’ is one way of setting the data source of a component. The alternate way is to listen for the table selection event and programmatically set the data source of the form or any other component. This alternate way is discussed later. Page 13 of 36
Slide 14: AjaxFace Tutorial 3.3.4 • • Setting Navigation Continue to refer to Step-3.html for the following discussion. The next step is to specify – when ‘Project Management’ link is selected on the navigation bar, Project Management Sub-view should be displayed in the main area. This is done by setting the source and target of the link. The following code sets source as ‘ProjectManagement’ and target as ‘pmTabs’. The navigations are set after rendering the view. • var lnk = hnav.getLink("ProjectManagement"); lnk.setNavigation(pmTabs, "MainArea", view); Code Listing 10 – Setting specs of navigation of ProjectManagement link 3.3.5 • • Create Project and User List Sub-views Refer to Step_4.html. It creates a Project List and User Management sub-views; link them to the respective links of the navigations. … …. … var projectList = createProjectListComp(view); var userList = createUserListComp(view); view.render(); var lnk = hnav.getLink("ProjectManagement"); lnk.setNavigation(pmTabs, "MainArea", view); lnk = hnav.getLink("ProjectList"); lnk.setNavigation(projectList, "MainArea", view); lnk = hnav.getLink("UserManagement"); lnk.setNavigation(userList, "MainArea", view); Code Listing 10 – Create Project and User List Sub-views 3.3.6 • • Load Data from the Server using AJAX Calls Continue to refer to Step-4.html. ‘loadMethod’ initiates asynchronous AJAX call. function loadData(view) { var req = new Af.DataRequest(baseURL + 'Marketing Campaign.xml', requestCompleted, requestFailed, view, requestTimedout); ajaxEngine.processRequest(req); } Code Listing 11 – Send AJAX request to the server to load 'Marketing Campaign.xml’ file Page 14 of 36
Slide 15: AjaxFace Tutorial • • When the request it completed, the ‘requestCompleted’ method is called back. The response XML is converted to the internal data representation. (The details of internal data are discussed in the following chappter. It also discusses how to convert XML to internal data form). The internal data is a hierarchical data structure. Its element can be addressed by dot (“.”) notations. This is equivalent to XPath and made convenient by JavaScript. • function requestCompleted(response) { var xds = new Af.XMLToDataSet(response.responseXML); var myTasksTable = view.getComponent("myTasks"); myTasksTable.setData(xds.data, "task.subTask"); var planTree = view.getComponent("planTree"); planTree.setData(xds.data, "task.subTask"); myTasksTable.selectRowIndex(0); } Code Listing 12 – Process the AJAX response 3.3.7 • • • • Loading Multiple Data Source Refer to Step-5.html. It initiates 3 calls to the server for loading 3 distinct data sources. These calls are queued and processed in the same order by the AjaxFace framework classes. In the example code, the response of each call is processed in a different call back. Function loadData(view) { var req = new Af.DataRequest(baseURL + 'Marketing Campaign.xml', requestCompleted, requestFailed, view, requestTimedout); ajaxEngine.processRequest(req); var req2 = new Af.DataRequest(baseURL + 'PlanList.xml', requestCompleted2, requestFailed, view, requestTimedout); ajaxEngine.processRequest(req2); var req3 = new Af.DataRequest(baseURL + 'UserList.xml', requestCompleted3, requestFailed, view, requestTimedout); ajaxEngine.processRequest(req3); } Code Listing 13 – Send AJAX request to load multiple data sources Page 15 of 36
Slide 16: AjaxFace Tutorial 3.3.8 • • • Event Listener for Project Selection Refer to Step-6.html. In the previous step we loaded the list of projects, users and a project ‘Marketing Compaign.xml’. This steps demonstrates how to create a pull down list of projects using the project list data source, attaching an event listener to it. When a new project is selected, the event listener loads the selected project. The function ‘createProjectManagementComp’ creates a new form and a DynamicSelect component by calling its ‘addDynamicSelect’ method. The new form is added above the previously created tabs. To do so, it creates an outter flow. • • var outerflow = new Af.Flow("Project Management"); var topForm = new Af.Form("Project Selection Form"); var pl = topForm.addDynamicSelect('projectSelector', 'Selected Project:', 0,0); pl.width = "400px"; pl.defaultLabel = 'Select a project by clicking here'; pl.labelAttrName = 'description'; pl.valueAttrName = 'name'; projectSelector = pl; outerflow.add(topForm); ……… ……… outerflow.add(tabs); ……… Code Listing 14 – Creating a form for project selector and adding it above tabs using another vertical flow • In the ‘initializeUI’ method the project selector component is retrieved from the view and a listener is added to it. The listeners are added after rendering the view. Until ‘render’ method of the view is called, the HTML elements are not created. Since the listeners are added to the HTML elements, it is done after rendering the view. function initializeUI () { ……… var pl = view.getComponent('projectSelector'); pl.addChangeListener(new ProjectChangeListener()); ……… } Code Listing 15 – Adding a listener to the ‘projectSelector’ component Page 16 of 36
Slide 17: AjaxFace Tutorial • When a new project is selected, the ‘changed’ method of the ProjectChangeListener is called. In Step-5.html, it simply prints a message. The next step will demonstrate how a new project is loaded from the server. function ProjectChangeListener() { this.changed = function(comp) { alert('You selected project - ' + comp.element.value + '\nThis step simply prints the message.' + '\nThe next step demonstrates how a new project is loaded.'); } } Code Listing 16 – ProjectChangeListener and its ‘changed’ method 3.3.9 • • • Loading a New Project on User Selection Refer to Step-7.html The ‘changed’ method of the ‘ProjectChangeListener’ calls ‘showSelectedProject’. showSelectedProject’ loads the new project from the server using AJAX call or clears the tables if no project is selected. function ProjectChangeListener() { this.changed = function(comp) { showSelectedProject(); } function showSelectedProject() { var projectSelector = view.getComponent("projectSelector"); var projectName = projectSelector.element.value; if (projectName == null || projectName == '') { clearProjectData(); } else { var req = new Af.DataRequest(baseURL + projectName + '.xml', requestCompleted, requestFailed, view, requestTimedout); ajaxEngine.processRequest(req); } } function clearProjectData() { var planTree = view.getComponent("planTree"); var myTasksTable = view.getComponent("myTasks"); planTree.clearData(); myTasksTable.clearData(); myTasksTable.selectRowIndex(0); } Code Listing 17 – The ‘changed’ method calls ‘showSelectedProject’ } 3.3.10 • • Using Client side Data Cache Refer to Step-8.html. Notice that we add the data source to the client cache in ‘requestCompleted’ method. Page 17 of 36
Slide 18: AjaxFace Tutorial • In ‘showSelectedProject’ method, we retrieve it from the cache. If it was previously fetched and still available then we use it. Else we initiate AJAX call to load it from the server. function requestCompleted(response) { var xds = new Af.XMLToDataSet(response.responseXML); dtCache.setData(xds.data.name, xds.data); showProject(xds.data); } function showSelectedProject() { ……… if (projectName == null || projectName == '') { clearProjectData(); } else { var data = dtCache.get(projectName); if (data == null) { ……… } else { showProject(data); } } } Code Listing 18 – The ‘changed’ method calls ‘showSelectedProject’ 3.3.11 • • • • • • • Using Status Bar Refer to Step-9.html An element with id="statusBarContainer" is used as place hoder for the status bar. If no such element is present then all status messages are ignored. Error messages are displayed on the status bar with red color. In the absence of ‘statusBarContainer’, the erorr messages are displayed using JavaScript ‘alert’. By default, the status message is displayed for few seconds and then they fad away. By passing the second parameter as ‘-1’, the status message can be displayed permanently. function showProject(data) { setStatus("Showing project - " + data.name); ……… } ……… ……… <div id="statusBarContainer" style="height:24px; width:800px; text-align:left"> </div> Code Listing 19 – Using Status Bar and Specifying Status Bar Container Place Holder Element The above discussion concludes 10 steps tutorial on how to create a rich UI using AjaxFace and how to tie it to the server using AJAX calls. Page 18 of 36
Slide 19: AjaxFace Tutorial 3.3.12 Sending Updates to the Server Refer to Section 4.5.2 for the details of how to send user updates to the server. 3.4 Using HTML File as Template / Tile In the above discussion, we used an html file (Step-1.html) as a template to layout UI components. It can be taken a step further. AJAX calls can be used from one HTML file to load another HTML file and use the new file as a template by adding it to any element of the invoker page. Or, you can swap the page by adding the new page to the body element and create different layouts. This allows use of HTML pages as templates, a powerful concept. Refer to the file HtmlAsTile-Lesson.html for the following discussion. In this example, we create a Dash Board by loading an HTML for its layout. function loadData() { var req = new Af.DataRequest(baseURL + 'Accordions.htm', requestCompletedOverviewPage, requestFailedCommon, view, requestTimedoutCommon); ajaxEngine.processRequest(req); } Code Listing 20 – Loading Accordions.html for the layout of Dash Board When 'Accordions.htm' is loaded successfully, we attach it to the ‘MainArea’ element of the main page ‘HtmlAtTile-Lesson.html’ function requestCompletedOverviewPage(response) { var mainArea = document.getElementById('MainArea'); mainArea.innerHTML = response.responseText; initializeAccordions(); overviewPanel = mainArea.childNodes[0]; setStatus("Dash board"); loadMyTasks(); } Code Listing 21 – Attaching Accordions.html to MainArea element of HtmlAsTileLesson.html In the above code initializeAccordions() method in turn adds new HTML elements to the placeholders specified in the Accordions.html. Refer to the ‘HtmlAtTile-Lesson.html’ for more details. Page 19 of 36
Slide 20: AjaxFace Tutorial 4 Adding Data Source 4.1 Internal Data Structures This section discusses the format of internal data structure used for the data binding. AjaxFace uses following forms for internal representation of data.  An Object (JavaScript Object) with the attributes. An attribute can be scalar type (basic type) or vector type (list).  A Collection of Objects represented as an Array.  An Object Tree – this is a special case of ‘1’ above where one or more attributes correspond to related-objects or arrays of related-objects. The attribute as an object correspond to one-to-one association. The attribute as an array of objects correspond to oneto-many relation. The attribute-name is same as association-name.  A List of Object Trees – this is a special case of ‘2’ where top level is a list of objects. Each object in the list further points to related objects. As an example, consider the following XML: <CustomerList> <customer> <name>ABC Inc</name> <phone>123-234-3456</phone> <order> <id>1</id> <description>Pens</description> <qty>300</qty> </order> <order> <id>2</id> <description>Pencils</description> <qty>400</qty> </order> <customer> <customer> <name>Doe Inc</name> <phone>789-345-9876</phone> <order> <id>3</id> <description>Notebooks</description> <qty>700</qty> </order> Page 20 of 36
Slide 21: AjaxFace Tutorial <order> <id>4</id> <description>Folders</description> <qty>100</qty> </order> <customer> <CustomerList> Code Listing 22 – XML stream as data source The above XML represents a data set named ‘CustomerList’. It is a array of ‘two objects (customers)’. Each customer contains an array of two orders. XMLToDataSet.js parses the above XML and creates JavaScript objects and build relations among them. The data structure created for the above XML can be visualized as follows: Page 21 of 36
Slide 22: AjaxFace Tutorial Customer List Customer 1 1 name: ABC Inc phone: … order Order 1 1 Id: 1 2 Order 2 Id: 2 Customer 2 2 name: Doe Inc phone: … order 1 Order 1 Id: 3 2 Order 2 Id: 4 JavaScript code (XMLToDataSet.js) executes something equivalent of the following code. Note that this is just an equivalence. XMLToDataSet.js is a parser to convert above format XML to an object tree. The source code of XMLToDataSet.js is included inside ‘fw/js’ subdirectory. var customerList = new Array(); // first customer var customer = new Object(); customer.name = ‘ABC Inc’; customer.phone = ‘123-234-3456’; // orders of the first customer var orderList = new Array(); var order = new Object(); Page 22 of 36
Slide 23: AjaxFace Tutorial order.id = ‘1’; order.description = ‘Pens’; order.qty = 300; orderList.push(order); // adding first order to the order list order = new Object(); order.id = ‘2’; order.description = ‘Pencils’; order.qty = 400; orderList.push(order); // adding first order to the order list customer.order = orderList; // customer points to the oderList through ‘order’ attribute. customerList.push(customer); // add first order to the list. // similar code will be executed for the second customer and so on. // the resulting ‘cusotmerList’ is a list of Object trees which will be used by the client. Code Listing 23 – Building JavaScript object hierarchy; illustration of processing logic using equivalent code The XML shown above is for the illustration of the format of internal data structure. It is not required that the XML sent by the server has to be exactly in the same format. In the example code you will notice that the AJAX callbacks are used to process the XML. Here, XMLToDataSet is used to convert XML to the internal format described above. You can write an XML parser which is specific to your XML format and using it, create internal data structures in the callbacks. 4.2 Addressing Values In the above example, addressing will be as follows.  customerList[0] will return the fist customer  customerList[0].order[1] will return the second order of the first customer.  CustomerList[0].order[1].id will return ‘2’. 4.3 Data Binding The API to bind the data to a component such as a form, table, table-tree is as follows:  setData(data) where ‘data’ is a single object or an array of objects. For example, ‘customerList’ will bind a list of customer objects to a component.  setData(data, path) where data is an top-level object and path is the address of the actual data to be bound. For example, setData(customerList[0], “order[0]”) will bind the fist order of the first customer to a component. setData(customerList[0], “order”) will bind the list of orders to a component. Page 23 of 36
Slide 24: AjaxFace Tutorial Whether a component is bound to a single object or a list of objects, depends on the type of component. The data binding for each case is discussed below. 4.3.1 Binding Single Object A single object is bound to a Form component. Each field of the Form receives value from a matching name attribute. 4.3.2 Binding Array of Objects A list of objects is typically bound to a RptTable or DynamicSelectComp. Each row corresponds to an object in the list. Each column corresponds to a matching name attribute. 4.3.3 Binding Object Tree When an object tree is bound to Tree component, a node is created for each object. The value of each tree node is retrieved from one of the attributes of each object. The name of this attribute is specified using ‘nodeDataSourceName’ property of the tree. An object tree when bound to a Table Tree, recursively binds each object to one row. A row at the next level is indented with respect to its parent row. The value of each column is retrieved from the matching name attribute. If an object tree is bound to a panel containing a form, table etc, then each part can be bound separately. Alternatively, the ‘dsPath’ attribute of each component can be set in the beginning. If the ‘dsPath’ is set for component, then the binding the top level object to the panel will bind the components to the appropriate data using the ‘dsPath’ as the path from the top-level. 4.3.4 Binding Array of Object Trees An array of object trees is typically bound to a Tree or Table Tree. This is similar to the case discussed above. In this case, tree has more than one top level nodes. 4.4 Using data files for Development You can XML or .CSV file format of arbitrary schema as long as they are converted to the data format described above. You can deploy these files with the WEB Server and access using AJAX API by supplying the URL. 4.5 Using Application Server as Data Source Alternatively, the XML data can be streamed by the application server instead of files. It may be easy to start with XML files as data source and then switch to an application server once the data format is firmed up. 4.5.1 Retrieving Data from the Application Server The retrieving data is similar to accessing data from the file. In this case the URL is processed by an application server and the response it sent back in the form of XML over HTTP/HTTPS. 4.5.2 Submit User Updates AjaxFace automatically records all the changes made by the user. The changes can be extracted as XML and submitted to the server. Refer to Step-10.html for the details. It adds a button bar with ‘Save’ button to the ‘Project Management’ view and a listener to it. Page 24 of 36
Slide 25: AjaxFace Tutorial function createProjectManagementComp(view) { var outerflow = new Af.Flow("Project Management"); var bar = new Af.ButtonBar(); var button = bar.addButton("save", "Save"); button.image = new ImageSpec('images/save.gif'); bar.align = 'right' outerflow.add(bar); ……… ……… } Code Listing 24 – A button bar is added to the Project Management View function initializeUI() { ……… ……… var save = view.getComponent('save'); save.addClickListener(new SaveClickListener()); ……… } Code Listing 25 – A listener is added to the save button When user clicks on ‘Save’ button, ‘clicked’ method is invoked. It retrieves the changes made by the user from the cache and sends to the server. Along with the data it sends the specification of the service which will be invoked by the server. It is not necessary to use the same format. Instead, you can use an appropriate URL and add additional parameter using ‘addParameter: function(name, value)’ method of DataRequest class. The important thing is that AjaxFace provides API to retrieve user changes as XML. function SaveClickListener() { this.clicked = function(comp) { var s = dtCache.getChangeXml(); if (s == null) { ……… // displays a message that there are no changes return; } else { ……… } Page 25 of 36
Slide 26: AjaxFace Tutorial var req = new Af.DataRequest(saveURL, saveRequestCompleted, saveRequestFailed, view, saveRequestTimedout); // sets some service parameters as required by our example server ……… req.xmlDoc = s; ajaxEngine.processRequest(req); } } Code Listing 26 – ‘clicked’ method invoked when user selects ‘Save’, sends changes to the server Page 26 of 36
Slide 27: AjaxFace Tutorial 5 Adding New Components A new component is inherited from ‘Component’ class. The new class overrides certain methods of Component. Any new attribute and methods are added to the new class. If required a behaviorclass is defined. Behavior class is a delegate class and it implments any behavior. The following sections discuss these steps using an example. Component class, its methods and attributes are described in the API Doc. 5.1 Overview of the New Class Say, we need to define a new component which has the following functionality.  It displays a list of enumerations as drop down list.  Each enumeration has a ‘label’ and ‘value’ attribute. The ‘label’ is a user friendly display value. The ‘value’ is the internal value of the component which is received from the server or sent to the server.  In read-only mode, the ‘label’ is shown as non-editable text instead of the drop down list. 5.2 Overriding Component Class We call our new class ‘SelectComp’. It is defined as follows. SelectComp = Class.create(); SelectComp.prototype = (new Af.Component()).extend({ initialize: function(name, displayName) { this._initialize(name, displayName); this.type = 'Select'; }, render: function() { ……… }, renderReadonly: function() { ……… }, internalToDisplayValue : function(iv) { ……… }, setDisplayValue : function() { ……… } }); Code Listing 27 – SelectComp inherits from Component Page 27 of 36
Slide 28: AjaxFace Tutorial 5.3 New Public API of SelectComp SelectComp defines an internal array say ‘options’. It defines a new public method called ‘addOption’ as follows. This method can be called by the application program to add options. SelectComp = Class.create(); SelectComp.prototype = (new Af.Component()).extend({ initialize: function(name, displayName) { ……… this.options = new Array(); }, addOption: function(label, value) { var option = new Object(); option.label = label; option.value = value; this.options.push(option); } }); Code Listing 28 – addOption method to add options to the list of options 5.4 Methods Overridden SelectComp overrides the following methods.  ‘render’ method  ‘renderReadonly’ method  internalToDisplayValue  setDisplayValue Each of these methods is discussed below. • • ‘render’ method renders HTML element to display options using a drop down list. ‘render’ method has to return the element it renders. The returned value is used by the framework class which invokes this method internally. SelectComp = Class.create(); SelectComp.prototype = (new Af.Component()).extend({ initialize: function(name, displayName) { ……… Page 28 of 36
Slide 29: AjaxFace Tutorial }, render: function() { var elem; elem = document.createElement('select'); if (this.cssComp != null) { elem.className = this.cssComp; } else { elem.className = 'Select'; // use default style class } elem.name = this.name; if (this.width) { elem.style.width = this.width; } for (var i=0; i<this.options.length; i++) { var option = this.options[i]; var oe = document.createElement("option"); oe.value=option.value; oe.label = option.label; oe.appendChild(document.createTextNode(option.label)); elem.appendChild(oe); } return elem; }, }); Code Listing 29 – ‘render’ method • • ‘renderReadonly’ method is similar to ‘render’ method. It renders a text node. ‘renderReadonly’ method has to return the element it renders. The returned value is used by the framework class which invokes this method internally. SelectComp = Class.create(); SelectComp.prototype = (new Af.Component()).extend({ initialize: function(name, displayName) { ……… }, renderReadonly: function() { var elem = document.createElement('div'); Page 29 of 36
Slide 30: AjaxFace Tutorial var v = this.value ? this.value : ''; this.textNode = document.createTextNode(v); elem.appendChild(this.textNode); if (this.cssComp != null) { elem.className = this.cssComp; } else { elem.className = 'SelectLabel'; // set the default style class } elem.name = comp.name; if (this.width) { elem.style.width = this.width; } return elem; }, }); Code Listing 30 – ‘renderReadonly’ method • • ‘internalToDisplayValue method converts the internal value to the display value by looking up the ‘options’ array. If the value does not match any entry then it returns the given value as the display value. SelectComp = Class.create(); SelectComp.prototype = (new Af.Component()).extend({ initialize: function(name, displayName) { ……… }, internalToDisplayValue : function(iv) { var dv = iv; if (dv == null) { dv = ''; } var options = this.options; for (var i=0; i<options.length; i++) { if (dv == options[i].value) { dv = this.options[i].label; break; } } Page 30 of 36
Slide 31: AjaxFace Tutorial return dv; }, }); Code Listing 31 – ‘internalToDisplayValue’ method • • ‘setDisplayValue method is called after the internal value of the component has been set by calling its ‘setValue’ method (‘setValue’ inherits from the component). ‘setDisplayValue’ sets the displayable value of the corresponding HTML element. SelectComp = Class.create(); SelectComp.prototype = (new Af.Component()).extend({ initialize: function(name, displayName) { ……… }, setDisplayValue : function() { if (this.textNode != null) { // it is a read-only mode var dv = this.internalToDisplayValue(this.value); this.textNode.data = dv; } else { var options = this.options; var iv = this.value; if (iv == null) { iv = ''; } for (var i=0; i<options.length; i++) { if (iv == options[i].value) { this.element.selectedIndex = i; break; } } } }, }); Code Listing 32 – ‘setDisplayValue’ method 5.5 Adding Behavior Say ‘IntComp’ is a subclass of Component which allows entry of only number character. In order to implement this behavior, the ‘IntComp’ makes use behavior delegate. Page 31 of 36
Slide 32: AjaxFace Tutorial • IntComp class is defined as follows. Notice that it sets ‘IntBehavior’ to implement the required behavior. IntComp = Class.create(); IntComp.prototype = (new Af.Component()).extend({ initialize: function(name, displayName) { this._initialize(name, displayName); this.type = Int; }, render: function() { var elem; elem = document.createElement('input'); elem.type = 'text'; if (this.cssComp != null) { elem.className = this.cssComp; } else { elem.className = 'Int'; } elem.name = this.name; if (this.width) { elem.style.width = this.width; } if (this.value) { elem.setAttribute('value', comp.value); } this.behavior = new Af.IntBehavior(comp, elem); return elem; }, }); Code Listing 33 – IntComp, a subclass of Compnent • • Before we discuss the details of IntBehavior, let us review its base class CompBehavior. It sets ‘onchange’ event handler. When the value changes, it sets the value of component from the element. CompBehavior = Class.create(); CompBehavior.prototype = { initialize: function(comp, elem) { Page 32 of 36
Slide 33: AjaxFace Tutorial this._initialize(comp, elem); }, _initialize: function(comp, elem) { this.comp = comp; if (elem) { var self = this; elem.onchange = function() {self.changed();}; } }, changed: function() { var v = this.comp.getInternalValue(); this.comp.setInternalValue(v); }, } Code Listing 34 – CompBehavior Class • IntBehavior extends CompBehavior and implements behavior to validate the key board input. IntBehavior = Class.create(); IntBehavior.prototype = (new Af.CompBehavior()).extend({ initialize: function(comp, elem) { this this._initialize(comp, elem); if (elem) { var self = this; elem.onkeypress = function(event) {return self.keyPressed(event);}; } }, keyPressed: function(event) { // validate key }, }); Code Listing 35 – IntBehavior Class Page 33 of 36
Slide 34: AjaxFace Tutorial 5.6 Using Af. Component in Form and Table A component is added to a form using APIs such as addText, addBoolean, addInt etc. Similarly a column to a table is added using APIs such as addTextColumn, addBooleanColumn, addIntColumn etc. The example code for each type of API is shown in the following tables. Form = Class.create(); Af.Form.prototype = (new Af.Component()).extend({ ……… addText: function(name, label, row, column) { var comp = new Af.TextComp(name, label); comp.type = 'Text'; this.add(comp, row, column); return comp; }, ……… } Code Listing 36 – Example of ‘addText’ method in Form class RptTable = Class.create(); RptTable.prototype = (new Af.Component()).extend({ ……… addTextColumn: function(name, displayName, width) { var comp = new Af.TextComp(name, displayName); comp.type = 'Text'; if (width) { comp.width = width; } this.addComponent(comp); return comp; }, ……… } Code Listing 37 – Example of ‘addTextColumn’ method in RptTable class In order to add an API for a new component to Form/ RptTable class, sub-class Form/ RptTable classes and add methods such addMyComp/ addMyCompColumn. These method should instantiate MyComp and call this.addComponent. Page 34 of 36
Slide 35: AjaxFace Tutorial 6 Deploying Application In order to deploy the application with your application server or web server, copy ‘fw’ directory and your application’s HTML file with the server. Make sure that your HTML files have relative reference to framework script files and css file. The two directories have the similar relative locations when copied. The rest of the setup is same as deploying any HTML files with you application server (copying inside a subdirectory of web application directory). Page 35 of 36
Slide 36: AjaxFace Tutorial 7 Debugging Support The bugging support can be enabled by invoking ‘enableDebug’ call in the beginning as shown below. function initializeUI() { ……… enableDebug(); debug("initializeUI() ..."); ……… } Code Listing 39 – Enabling debugging Enabling debug creates a text area at the bottom of the page where debug messages are displayed. Following this, you can display a debug message using debug(“debug message”) call. If you decide to display the debug text area at a specific location inside the page, simply create a text area element in the document and set its id=’debug’. If an element with id=’debug’ is found then framework uses it instead of creating one at the bottom. Page 36 of 36

   
Time on Slide Time on Plick
Slides per Visit Slide Views Views by Location