Tags:
create new tag
, view all tags
-- PedroRio - 18 Feb 2011

XEO Web Components - Samples.

This section has snippets of code to perform a certain operation (and explanation of the snippet)

Index

  • Opening a viewer
  • Opening a viewer (in a window)
  • Finding a component in the component tree
  • Finding the selected line in a gridpanel
  • Setting the active tab
  • Refreshing a list after the creation of a new instance in an edit viewer
  • Executing a SQL statement against the database
  • Passing a parameter from a main menu entry to the list viewer
Opening a new viewer

A fairly common operation will be opening a viewer in response to a user clicking a button or something similar. To do so, in the bean method where you want to open the viewer use the following code:

XML Definition

<xvw:menu text='Open Tab' target='tab' serverAction='#{viewBean.openTab}'>

Java Code

public void openTab(){
  //Create a XUIViewRoot representing the viewer (viewer can be located in the source code, or in the webapp of the application)
  XUIViewRoot viewRoot = getSessionContext().createChildView("viewers/path/to/viewer/Viewer.xvw");
  //Set the newly created viewroot as the view root of the request  
  getRequestContext().setViewRoot(viewRoot);  
  //Render the response
  getRequestContext().renderResponse();  
}

_

Opening a new viewer (in a window)

Sometimes you'll want to open a viewer inside a small window (and not in a new tab). To do that you must add the xvw:window component to your viewer, and execute the same code as the previous example.

Viewer Definition

<xvw:viewer beanClass="org.xeoframework.examples.MyBean" beanId="viewBean">
        <xeo:formEdit>
             <xvw:window width='500' height='300'>
                          <!-- Remaining components -->
                      </xvw:window>
        </xeo:formEdit>
    </xvw:viewer>

Menu (important, notice the absence of the "target" property, which defaults to "self")

<xvw:menu text='Open Window' serverAction='#{viewBean.openWindow}'> 

Java Code (same code as above, only change needed to be done for this example is adding the xvw:window component and removing the target property)

XUIViewRoot viewRoot = getSessionContext().createChildView("viewers/Objecto/MyViewer.xvw");
getRequestContext().setViewRoot(viewRoot);
getRequestContext().renderResponse();

_

Finding a component in the component tree

One regular task when implementing a method using the Java API in a bean is to find a given component and retrieve a certain property value, or changing a set of properties (as well as adding a new child to the component). In order to do that, you must be able to find the component in the component tree of a viewer. There are two ways of finding a component: By type and by identifier.

Find a component by type

In this situation, if you only have one instance of a given type/class, you can find the component by its class. If you were looking for a TreePanel component you could use the following code:

XUIComponentBase myComp = getViewRoot().findComponent(TreePanel.class);
TreePanel panel = (TreePanel) myComp;
if (panel != null){
    // Do normal processing
}

You could also just use:

TreePanel panel = (TreePanel) getViewRoot().findComponent(TreePanel.class);

Beware that you should only use the findComponent method with the class as parameter if you're certain there's only one instance of the component in the current viewer. If there are more than one, it's undefined which one will be returned by the method. If you have more than one instance of a given type/class of components you should see the following section.

Find a component by identifier

If have multiple instances of a given component type/class in your viewer the only reliable way of finding them is to given them an identifier and search for that identifier. To find a component by its identifier you actually need to know the identifier of the parent form component and the component itself, because component identifiers are created like the following:

formIdentifier:componentIdentifier

So, if your form has an identifier like "myForm" and your component an identifier like "comp", the full identifier for the component will be:

myForm:comp

To find the component using its identifier, you should declare the form of the viewer with an id attribute as well as your component and then use the following code:

Form

<xvw:form id='myForm'>

Component

<xvw:treePanel id='comp'>

Bean

TreePanel panel = (TreePanel) getViewRoot().findComponent("myForm:comp");

In case you don't know the (or don't want to add) the identifier of the form component you can also use the following code, to search for the form component and retrieve its identifier:

XUIForm form = (XUIForm) getViewRoot().findComponent(XUIForm.class)
String formID = form.getClientId();
TreePanel panel = (TreePanel) getViewRoot.findComponent(formID+":"+"myComp");

The getClientId method retrieves the identifier of the form that it's autogenerated by the framework (if one was not declared in the xml definition).

Finding the selected line in a panel (gridpanel, list, bridge)

A popular programming task with XEO Web Components is to have a gridPanel component (or list/bridge) and have toolbar with a button that will trigger some action on a selected line from the panel. To do that you need the following code in the method invoked by the button.

//import netgest.bo.xwc.components.connectors.*;
//import netgest.bo.xwc.components.classic.GridPanel;

public void processLine(){
        
        //Find the GridPanel that has the selected line
        GridPanel panel = (GridPanel) getViewRoot().findComponent(GridPanel.class);
        //Retrieve the current active row (a DataRecordConnecor)
        DataRecordConnector currentLine = panel.getActiveRow();
        //Find the column that has a meaningful value (i.e. and id, for example)
        DataFieldConnector currentColumn = currentLine.getAttribute("BOUI");
        //Retrieve the value for that column
        String value = currentColumn.getValue().toString();
        
        //Use the value of the BOUI to load and process the instance
        try {
            XEOApplication app = XEOApplication.getDefaultApplication();
            boObject b = app.getSecureObjectManager().
                loadObject(getEboContext(), Long.valueOf(value));
            
            //Process the instance
            
            b.update();
        } catch (boRuntimeException e) { /* Log or deal with the exception*/}
    }

You may need a few modifications if:

  1. You have more than one instance of a gridPanel/list/bridge component in your viewer
  2. If you allow multiple lines to be selected and want to process them all

If you fall in situation 1, you'll need to see the previous section, titled "Finding a component in the component tree".

If you fall in situation 2, you'll need the following code:

public void processLines(){
            
      //Find the GridPanel that has the selected line
      GridPanel panel = (GridPanel) getViewRoot().findComponent(GridPanel.class);
      //Retrieve the selected lines (a DataRecordConnector[])
      DataRecordConnector[] currentLines = panel.getSelectedRows();
      //Iterate through all the lines
      for (DataRecordConnector currentLine : currentLines){
          //Find the column that has a meaningful value (i.e. and id, for example)
          DataFieldConnector currentColumn = currentLine.getAttribute("BOUI");
          //Retrieve the value for that column
          String value = currentColumn.getValue().toString();
          //Use the value of the BOUI to load and process the instance
          try {
              XEOApplication app = XEOApplication.getDefaultApplication();
              boObject b = app.getSecureObjectManager().
              loadObject(getEboContext(), Long.valueOf(value));
              //Process the instance
              b.update();
          } catch (boRuntimeException e) { /* Log or deal with the exception*/}
       }
 }

The main difference from the previous situation is the getSelectedRows method that returns a DataRecordConnector array with all the lines that are selected in the panel.

Changing the current active tab

If a user is interacting with a given viewer that has several tabs, you may want to set a given tab as active in response to a given action (for example a button click). In order to do that you can use the following code (you'll need to add an identifier to the tab you want to set as active, for this example let's assume it's "t1"):

Tabs tabs = (Tabs) getViewRoot().findComponent(Tabs.class);
tabs.setActiveTab("t1");

If you have more than one instance of the Tabs component you'll need to find the component by its identifier (see finding a component above).

Refreshing a list after creating a new instance in an edit viewer

When you create a new instance in a edit viewer (and you have the list viewer in a open tab) you'll notice that the instance is not imediately added to the list (you need to refresh the list). This is made for performance reasons, but there are times when you may want to refresh the list after closing the tab. To do that, you have to override the canCloseTab method in the XEOEditBean with the following code:

@Override
public void canCloseTab(){
    super.canCloseTab();
    //Retrieve the parent view for the current edit bean 
    //(which will be the list viewer) and trigger the synching (essentially re-rendering) of that viewer.
    getParentView().syncClientView();
}

You can actually use this trick to refresh currenty viewer (by using getViewRoot().syncClientView()) or you can refresh any viewer that was created by its parent using the createChildView method (because it sets that viewer has a parent of the created one, so when you invoke getParentView() on the child, the parent will be returned instead of null.

Making a direct database connection (to execute a SQL statement)

Most of the time in a XEO Application you'll only need to execute BOQL statements, but there may be times where you need to execute SQL statements directly agains the database, to do that you'll need the following:

        Statement stmt = null;
        Connection connection = getEboContext().getConnectionData();
        try {
            stmt = connection.prepareCall("select * from TABLE");
            ResultSet rs = stmt.executeQuery();
            
            while (rs.next()) {
                // Process the lines
            }
            
            
        } catch (SQLException e) { /* Log or treat the exception */
        }finally{
            //Close the connections
            try {
                stmt.close();
                connection.close()
            } catch (SQLException e) {/* Log or treat the exeception */    }
        }

_

Passing a parameter from the menu entry in a main viewer to the list viewer(or from any menu to another viewer)

When you create a menu entry in a Main viewer, to open a list viewer you usually do the following:

<xvw:menu text='Menu Name' value="{viewerName:'Object/list.xvw', boql:select Object}"
target='Tab' serverAction="#{viewBean.listObject}" />

Which will open the list viewer for "Object" in a new tab. You may want, however, to pass aditional parameters to the bean of the list viewer that will be open. In order to that, you can add the new parameters to the "value" property of the menu component (it must be a valid JSON string), in the following example to add a "type" parameter.

<xvw:menu text='Menu Name' value="{viewerName:'Object/list.xvw', boql:select Object, type: 'sunny'}"
target='Tab' serverAction="#{viewBean.listObject}"  />

All you have to do in the list viewer's bean is to add a constructor that will catch the parameter, like the following:

private String type = null;

public ObjectListBean(){
        try {
            //Retrieve the current context 
            XUIRequestContext oRequestContext = XUIRequestContext.getCurrentContext();
            //Create a JSON Object from the string passed in the "value" property of the Menu component
            JSONObject jsonObject = new JSONObject( 
                (String)((XUICommand)oRequestContext.getEvent().getSource()).getValue() 
            );
            type = jsonObject.getString( "type" );
        } catch ( Exception ex ) {
            //Log exception
        }
    }


public String getType(){
   return type;
}

Beware of the following:

When creating a constructor for a bean, if the code that it's executed in the constructor generates an exception. The viewer will not load and the message you'll see is only "Error loading class [path.to.your.bean] for the viewer [Path/toYour/viewer.xvw]".

Edit | Attach | Print version | History: r9 | r7 < r6 < r5 < r4 | Backlinks | Raw View | Raw edit | More topic actions...
Topic revision: r5 - 2011-02-21 - PedroRio
 

No permission to view TWiki.WebTopBar

This site is powered by the TWiki collaboration platform Powered by Perl

No permission to view TWiki.WebBottomBar