HT for Web TableView Manual

Index


Overview

The HT for Web provides the table component class ht.widget.TableView, which displays the property information of the Data type object in the DataModel container, and supports sorting and filtering functions.

Through tableView = new ht.widget.TableView(dataModel); initialize building a table component object, dataModel parameter is a data model bound to a table component, the table component constructor function will create a new data model for binding when the model is empty.

The getColumnModel() function of the table component returns the column model object, which is essentially a DataModel type object, except that the object is only used to add ht.Column type object, ht.Column type of parent is ht. Data, adds a function interface associated with the attribute definition.

So what the user needs to do is build the ht.Column object based on the attribute information to be displayed, and then added to the columns model returned by the tableView.getColumnModel() function, so that the information about Data in the tableView.getDataModel() model will displayed by the configuration of the ht.Column stored in tableView.getColumnModel().

Column

ht.Column class inherits from ht.Data, you cannot set up a parent-child relationship with the following property functions:

Enumeration is a common property-editing selection application, rendering the drop-down list at edit time, so HT takes a lot of scenarios for enumerated type attributes, setEnum(params) functions to set a single json parameter, or to set parameter information setEnum(enumValues, enumLabels, enumIcons, enumEditable, enumStrict), the following are common cases:

HT automatically detects whether the user has introduced Form Plugins, if the ht.widget.ComboBox component of the form plug-in is introduced, then using it as an editor, otherwise using the select component of the native html, because of the native html select drop-down component is text-only, so many of the parameters above work only for the ht.widget.ComboBox component.

Form Plug-in ht.widget.Slider is also a common and easy-to-use editing component, and this HT also adds the setting of the corresponding column properties of the type, through getSlider() and setSlider(parmas) can specify the slide bar information that the column renders in edit state.

The above example warning level information stored in the alarmSeverity property of the attr type of the Data object, the first column set the ·setSortFunc sort function, to set the Cleared alarm level to the top, the other alarm level value higher in the upper layer of the effect, also called tableView.setSortColumn` specifies the current row sequence.

var column = new ht.Column();
column.setName("alarmSeverity");
column.setAccessType('attr');
column.setSortFunc(function(v1, v2, d1, d2){
    if(v1 === v2){
        return 0;
    }
    // keep 'Cleared' on top
    if(v1 === 0){
        return -1;
    }
    if(v2 === 0){
        return 1;
    }
    // compare value
    if(v1 > v2){
        return -1;
    }else{
        return 1;
    }                  
});
columnModel.add(column);                
tableView.setSortColumn(column);

The second column overloads the column.getValue custom to get the value, depending on the attr type's property alarmSeverity value, the corresponding alert level color is found through the configuration of the map object. By setting valueType as the color type, HT automatically renders the property in a way filled with a cell background color.

column = new ht.Column();
column.setValueType('color');
column.getValue = function(data){
    var alarmSeverity = data.getAttr('alarmSeverity'),
        color = map[alarmSeverity].color;
    return tableView.isSelected(data) ? ht.Default.darker(color) : color;
};
columnModel.add(column);

The third column overloads the column.drawCell custom cell rendering effect, which returns the row index tableView.getRowIndex(data), draw the index information between cells by ht.Default.drawText and draws a different row background color based on the parity of the index.

column = new ht.Column();             
column.drawCell = function (g, data, selected, column, x, y, w, h, tableView) {
    var index = tableView.getRowIndex(data);

    // draw background
    var color = index % 2 === 0 ? '#ECF0F1' : '#3498DB';
    g.fillStyle = selected ? ht.Default.darker(color) : color;
    g.beginPath();
    g.rect(x, y, w, h);
    g.fill();

    // draw label
    color = selected ? 'white' : 'black';
    ht.Default.drawText(g, 'row ' + index, null, color, x, y, w, h, 'center');
};
columnModel.add(column);

Column fourth overloads the column.drawCell custom cell rendering effect, according to the alarmSeverity value of attr, find the corresponding alarm level name and color information for rendering by the map object's configuration.

column = new ht.Column();
column.setWidth(200);    
column.drawCell = function (g, data, selected, column, x, y, w, h, tableView) {
    var alarmSeverity = data.getAttr('alarmSeverity'),
        info = map[alarmSeverity],
        color = info.color;

    // draw background                    
    g.fillStyle = selected ? ht.Default.darker(color) : color;
    g.beginPath();
    g.rect(x, y, w, h);
    g.fill();

    // draw label     
    color = selected ? 'white' : 'black';
    ht.Default.drawText(g, info.name, null, color, x, y, w, h, 'center');
};
columnModel.add(column);

Tableheader

ht.widget.TableHeader table header components are often combined with TableView and TreeTableView to present Column information and provide Column with positive and negative sort switches, column widths stretching, And the change of the column order position.

Through tableHeader = new ht.widget.TableHeader(tableView/treeTableView); initialize building a header component object that can introduce tableView or treeTableView table component object is bound, tableHeader will automatically listen to the column model of tableView.getColumnModel(), when the user clicks the sort, or the column width change and the column order change and so on, the corresponding modification to the column model Column attribute, the header component is automatically refreshed when the user modifies the Column attribute through the API.

The above example constructs two ht.widget.TableHeader header components that bind the same tableView object, so that two headers can achieve an interactive synchronization effect.

tableHeader1 = new ht.widget.TableHeader(tableView);
tableHeader2 = new ht.widget.TableHeader(tableView);

borderPane = new ht.widget.BorderPane();
borderPane.setTopView(tableHeader1);
borderPane.setCenterView(tableView);
borderPane.setBottomView(tableHeader2);

TableView provides a function of addColumns and setColumns, which can be easily added Column by json format in bulk, and the following code is used in the above example:

tableView.addColumns([
    {
        displayName: 'Severity',
        name: 'alarmSeverity',
        accessType: 'attr',
        sortOrder: 'desc',
        tag: 'sortableColumn',
        sortFunc: function(v1, v2, d1, d2){
            if(v1 === v2){
                return 0;
            }
            // keep 'Cleared' on top
            if(v1 === 0){
                return -1;
            }
            if(v2 === 0){
                return 1;
            }
            // compare value
            if(v1 > v2){
                return -1;
            }else{
                return 1;
            }                  
        }
    },
    // ...                           
]);

In the example, only the first column allows sorting, and the sortable property of the other columns is set to false, which is used to sort the column in order to initialize the display, and the code specifically sets the tag logo for the first column, through tableView.getColumnModel().getDataByTag(' sortableColumn') finds the column object.

tableView.setSortColumn(tableView.getColumnModel().getDataByTag('sortableColumn'));

Note tableView.getColumnModel() is the DataModel, Column is also inherited from Data type, so have the tag and other related operations of data container.

TablePane

The previous section example uses the BorderPane container to combine TableView and TableHeader objects, most of which are in need of integrated use, for which HT provides ht.widget.TablePane and ht.widget.TreeTablePane, the two components built the TableView and TreeTableView objects separately and also built a TableHeader object, the TableHeader component displayed in the top, and the TableView and TreeTableView components displayed in the bottom.

ht.widget.TablePane and ht.widget.TreeTablePane constructors can introduce the TableView and TreeTableView objects, and automatically create a TableView and TreeTableView objects, other common functions are as follows:

The above example inherits from ht.Column expands com.hightopo.LanguageColumn and com.hightopo.LanguageColumn two column types, the primary purpose is to initialize the necessary parameter configuration information in a constructor, that can avoid the large number of duplicate configuration information when the same type column needs to be defined in many places, and facilitates the uniform modification of parameter information.

com = {};
com.hightopo = {}; 

var LanguageColumn = com.hightopo.LanguageColumn = function(){
    LanguageColumn.superClass.constructor.call(this);                    
    this.setName('Language');
    this.setAccessType('attr');
    this.setEnum({values: [1, 2, 3, 4, 5, 6], labels: ['C', 'C++', 'Java', 'JS', 'AS', 'C#']});
    this.setEditable(true);
    this.setSortFunc(function(v1, v2, d1, d2){
        if(v1 === v2){
            return 0;
        }
        if(v1 === 2){
            return 1;
        }
        if(v2 === 2){
            return -1;
        }
        if(v1 === 5){
            return -1;
        }
        if(v2 === 5){
            return 1;
        }
        return v1 - v2;
    });                    
}; 
ht.Default.def('com.hightopo.LanguageColumn', ht.Column, {
});     

var SexColumn = com.hightopo.SexColumn = function(){
    SexColumn.superClass.constructor.call(this);                    
    this.setName('Sex');
    this.setAccessType('attr');
    this.setEnum(['Male', 'Female']);                   
    this.setEditable(true);                    
}; 
ht.Default.def('com.hightopo.SexColumn', ht.Column, {
});  

With the above class encapsulation, the configuration of the column properties reduces many parameters, notice the className keyword in the following code, the HT will be based on this className special keyword information to replace the default ht.Column type, the attribute component also replaces the default ht.Property type by className special keyword information.

tablePane.addColumns([
    {
        name: 'id',
        width: 60,
        tag: 'id'
    },
    {
        className: 'com.hightopo.LanguageColumn',
        width: 100,
        tag: 'language'
    },
    {
        className: 'com.hightopo.SexColumn',
        width: 100,
        tag: 'sex'
    }
]);

propertyView.addProperties([
    {
        name: 'id'
    },
    {
        className: 'com.hightopo.LanguageProperty',
        editable: true
    },
    {
        className: 'com.hightopo.SexProperty',
        editable: true
    }                    
]);

By tablePane.getTableHeader().setResizable(false), the header is set to an immutable column width:

tablePane.getTableHeader().setResizable(false);

Through the tablePane.addViewListener to isten tablePane component event, when the beginValidate event is triggered, each column width is allocated according to the current component widths, and the tag parameter has been set while defined column, so that the corresponding column can be found through columnModel.getDataByTag('language'):

tablePane.addViewListener(function(e){
    if(e.kind === 'beginValidate'){
        var columnModel = tablePane.getColumnModel(),
            width = tablePane.getWidth();
        columnModel.getDataByTag('id').setWidth(width * 0.2);
        columnModel.getDataByTag('language').setWidth(width * 0.4);
        columnModel.getDataByTag('sex').setWidth(width * 0.4);                        
    }
});

TableView

Table component class ht.widget.TableView main configurable properties and functions are as follows:

The following is the default implementation of the getCurrentSortFunc function, while called the sortFunc of the TableView, the two parameters are d1 and d2, two different Data objects, while called Column sortFunc is introduced the v1,v2,d1,d2 four parameters, that is, the first two parameters of the Data object corresponding to the value of the column.

getCurrentSortFunc: function () {
    var column = this._sortColumn;
    if (column && column.isSortable()) {
        var func = column.getSortFunc(),
                tableView = this,
                order = 'asc' === column.getSortOrder() ? 1 : -1;            
        if (!func) {
            func = ht.Default.sortFunc;
        }
        return function (d1, d2) {
            var v1 = tableView.getValue(d1, column),
                v2 = tableView.getValue(d2, column);
            return func.call(tableView, v1, v2, d1, d2) * order;
        };
    }
    return this._sortFunc;
}

The following code uses the tableHeader.getView().style to get the bottom div component of the header, using the css repeat-x to tile the progressive color background.

tableHeader = tablePane.getTableHeader();
tableHeader.getView().style.background = 'url(images/header.png) repeat-x';

The following code overloads the drawRowBackground function, drawing the effect of the table row alternating zebra.

tableView.drawRowBackground = function(g, data, selected, x, y, width, height){
    if(tableView.isSelected(data)){
        g.fillStyle = '#87A6CB';
    }
    else if(tableView.getRowIndex(data) % 2 === 0){
        g.fillStyle = '#F1F4F7';
    }
    else{
        g.fillStyle = '#FAFAFA';
    }
    g.beginPath();
    g.rect(x, y, width, height);
    g.fill();
};

The following code sets the visible filter, the filter determines whether the Data object is visible by the element selection state of the toolbar, the filter only set once, and the filter rule changes as the toolbar state changes, but the state of the toolbar element does not distribute any events. So the action of the tool bar button shows that the tableView.invalidateModel(); notification table is being updated for data reload.

tableView.setVisibleFunc(function(data){                    
    var nation = data.a('nation'),
        sex = data.a('sex');                    
    // filter nation 
    if(!toolbar.getItemById('nation-all').selected){
        if(toolbar.getItemById('uk').selected && nation !== 0){
            return false;
        }
        if(toolbar.getItemById('usa').selected && nation !== 1){
            return false;
        }
        if(toolbar.getItemById('mexico').selected && nation !== 2){
            return false;
        }
    } 
    // filter sex
    if(!toolbar.getItemById('sex-all').selected){
        if(toolbar.getItemById('man').selected && sex !== 0){
            return false;
        }
        if(toolbar.getItemById('woman').selected && sex !== 1){
            return false;
        }
    }
    return true;
});

The following code overloads the drawCell function in the added column, through ht.Default.drawStretchImage function draws the corresponding icon at the center of the cell, and the third parameter of the drawStretchImage function can be introduced in the type of fill, uniform or centerUniform.

tablePane.addColumns([
    {
        name: 'index',
        displayName: 'Index',
        accessType: 'attr',
        align: 'center'
    },
    {
        name: 'nation',
        displayName: 'Nation',
        accessType: 'attr',
        align: 'center',
        drawCell: function (g, data, selected, column, x, y, w, h, view) {
            var image = ht.Default.getImage('images/' + nations[data.a('nation')] + '.png');
            ht.Default.drawStretchImage(g, image, 'centerUniform', x, y, w, h);
        }

    },
    {
        name: 'sex',
        displayName: 'Sex',
        accessType: 'attr',
        align: 'center',
        drawCell: function (g, data, selected, column, x, y, w, h, view) {
            var image = ht.Default.getImage('images/' + sexs[data.a('sex')] + '.png');
            ht.Default.drawStretchImage(g, image, 'centerUniform', x, y, w, h);
        }
    }
]);

Welcome to contact us service@hightopo.com