Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • The HTML file defines the structure of the table view, and indicates to Angular where directives (behaviors) need to be injected.
  • The JavaScript file creates the Angular controller for the view, delegates to the TableBuilderService to build the table, and defines a directive for populating the details panel.
  • The CSS file defines custom styling, if required.
  • The server-side Java code receives requests from the client, fetches the data, formats, sorts and sends back the information to the client.

...

These files are under the directory ~/src/main/java/org/meowster/app.

Info

The exact path depends on the groupId (also used as the Java package) specified when the application was built with onos-create-app.

 

The descriptions for both AppComponent and AppUiComponent remain the same as in the Custom View tutorial.

...

This class extends UiMessageHandler to implement code that handles events from the (client-side) sample application view. Salient features to of note:

(1) implement createRequestHandlers() to provide request handler implementations for specific event types from our view.

Code Block
collapse
languagejavatrue
@Override
protected Collection<RequestHandler> createRequestHandlers() {
    return ImmutableSet.of(
            new SampleDataRequestHandler(),
            new SampleDetailRequestHandler()
    );
}

...

(2) define SampleDataRequestHandler class to handle "sampleDataRequest" events from the client. Note that this class extends TableRequestHandler, which implements most of the functionality required to support the table data model:

Code Block
languagejavacollapsetrue
private static final String SAMPLE_DATA_REQ = "sampleDataRequest";
private static final String SAMPLE_DATA_RESP = "sampleDataResponse";
private static final String SAMPLES = "samples";

... 
 
private final class SampleDataRequestHandler extends TableRequestHandler {
    private SampleDataRequestHandler() {
        super(SAMPLE_DATA_REQ, SAMPLE_DATA_RESP, SAMPLES);
    }
    ...
}

...

Typically, table rows have a unique value (row key) to identify the row (for example, in the Devices table it is the value of the Device.id() property). The default identifier for the column holding the row key is "id". If you want to use a different column identifier for the row key, your class should override defaultColumnId(). For example:

Code Block
languagejavacollapsetrue
private static final String MAC = "mac";
 
...
 
@Override
protected String defaultColumnId() {
    return MAC;
}

...

Note that the column identifiers defined here must match the identifiers defined specified in the HTML snippet snippet for the view (see sample.html below below) for the view. 

 

(2c) optionally override createTableModel() to specify custom cell formatters / comparators. 

Code Block
languagejava
// if required, override createTableModel() to set column formatters / comparators

The following example sets both a formatter and a comparator for the "code" column:

Code Block
languagejavacollapsetrue
@Override
protected TableModel createTableModel() {
    TableModel tm = super.createTableModel();
    tm.setFormatter(CODE, CodeFormatter.INSTANCE);
    tm.setComparator(CODE, CodeComparator.INSTANCE);
    return tm;
}

...

(2d) implement populateTable() to add rows to the supplied table model:

Code Block
languagejavacollapsetruejava
@Override
protected void populateTable(TableModel tm, ObjectNode payload) {
    // ...
    List<Item> items = getItems();
    for (Item item: items) {
        populateRow(tm.addRow(), item);
    }
}
 
private void populateRow(TableModel.Row row, Item item) {
    row.cell(ID, item.id())
        .cell(LABEL, item.label())
        .cell(CODE, item.code());
}

...

(3) define SampleDetailRequestHandler class to handle "sampleDetailRequest" events from the client. Note that this class extends the base RequestHandler class:

Code Block
languagejavacollapsetrue
private static final String SAMPLE_DETAIL_REQ = "sampleDetailsRequest";

...
 
private final class SampleDetailRequestHandler extends RequestHandler {

    private SampleDetailRequestHandler() {
        super(SAMPLE_DETAIL_REQ);
    }

    ...
}

 

(3a) implement process(...) to return detail information about the "selected" row:

Code Block
languagejavacollapsetrue
private static final String SAMPLE_DETAIL_RESP = "sampleDetailsResponse";
private static final String DETAILS = "details";
...
private static final String COMMENT = "comment";
private static final String RESULT = "result";

...
 
@Override
public void process(long sid, ObjectNode payload) {
    String id = string(payload, ID, "(none)");

    // SomeService ss = get(SomeService.class);
    // Item item = ss.getItemDetails(id)

    // fake data for demonstration purposes...
    Item item = getItem(id);

    ObjectNode rootNode = MAPPER.createObjectNode();
    ObjectNode data = MAPPER.createObjectNode();
    rootNode.set(DETAILS, data);

    if (item == null) {
        rootNode.put(RESULT, "Item with id '" + id + "' not found");
        log.warn("attempted to get item detail for id '{}'", id);

    } else {
        rootNode.put(RESULT, "Found item with id '" + id + "'");

        data.put(ID, item.id());
        data.put(LABEL, item.label());
        data.put(CODE, item.code());
        data.put(COMMENT, "Some arbitrary comment");
    }

    sendMessage(SAMPLE_DETAIL_RESP, 0, rootNode);
}

...

Note that the directory naming convention must be observed for the files to be placed in the correct location when the archive is built. Since our view has the unique identifier "sample", its client source files should be placed under the directory ~/src/main/resources/app/view/sample.

~/src/main/resources/app/view/sample/
client filesclient files for UI viewsclient files for "sample" view

There are three files here:

  • sample.html
  • sample.js
  • sample.css

Note again, the convention is to name these files using the identifier for the view; in this case "sample".

...

Tabular views use a combination of Angular directives and factory services to create all the behaviors of the table.

...

The outer <div> element defines the contents of your custom "view". It should be given the id of "ov-" + <view identifier>, ("ov" standing for "Onos View"). Thus in this example the id is "ov-sample".

Table View Header <div>

Image Added

The <div> with class "tabular-header" defines the view's header:

...

Code Block
languagexml
 <div class="ctrl-btns">
        <div class="refresh" ng-class="{active: autoRefresh}"
             icon icon-id="refresh" icon-size="36"
             tooltip tt-msg="autoRefreshTip"
             ng-click="toggleRefresh()"></div>
 </div>
Info

See additional details about tablular view directives.

 

Main Table <div>

The <div> with class "summary-list" defines the actual table.

Code Block
<div class="summary-list" onos-table-resize>


    ...
 
</div>

 

Table Header <div>

foo.

 

Table Row Template <div>

...