Smart grid

From Documentation
Author
Kirill Zhukov, application programmer, State Customs Service of Ukraine


Kirill Zhukov.jpg
Kirill has been using ZK almost from the begining of the project - since 2005. All this time he has been working in the State Customs Service of Ukraine. He occupies a post in the information department. Since starting using ZK the main stream of development was conversions of desktop applications into ZK powered web applications.

Date
November 21, 2009
Version
ZK 3.6.3


Introduction

Grid is one of the most popular component we used working with database. Application shows some data in a grid and user may select a record and do some operations with it's data. The standard grid component doesn't allow user to select a row. At first I created the column with position index 0 and genereted checkboxes for each row with "onCheck" event. So I always know the selected checkbox and the corresponding row.

New approach

This method worked but it was unnatural for users used desktop applications. It is more convenient to select row with mouse click. The next javascript code allows to select a row and identified one for use in server application java code (tested with IE (6,7,8), FF, Chrome, Opera, Safari):

var id;
var tds;
var sts = new Array();
function gridHandler(mEvent, rowid) {
    if (rowid.value != '') {
        isIE = false;
        if (mEvent.target)
            el = mEvent.target;
        else if (mEvent.srcElement) {
            el = mEvent.srcElement;
            isIE = true;
        }   
        while (el.nodeName != 'TR' && el.parentNode) {
            el = el.parentNode
        }
        if (el.nodeName == 'TR' && el.id != undefined) {
                if (el.id != '') {
                    if (rowid.value != '-1' && document.getElementById(id)) {
                        for (i = 0; i < tds.length; i++) {
                            if (!isIE)
                                tds[i].setAttribute('style', sts[i])
                            else
                                tds[i].style.backgroundColor = sts[i]
                        }
                    }
                    tds = getChildren(el, "TD");
                    for (i = 0; i < tds.length; i++) {
                        if (!isIE) {
                            sts[i] = tds[i].getAttribute('style');
                            tds[i].setAttribute('style','background-color:#99CCFF')
                        }
                        else {
                            sts[i] = tds[i].style.backgroundColor;
                            tds[i].style.backgroundColor = '#99CCFF'
                        }   
                    }
                    id = el.id;
                    rowid.value = id
                } else {
                    rowid.value = '-1'
                }
                if (document.createEvent) {
                    var evt = document.createEvent('HTMLEvents');
                    evt.initEvent('blur', false, false);
                    rowid.dispatchEvent(evt);
                    var evt1 = document.createEvent('HTMLEvents');
                    evt1.initEvent('change', false, false);
                    rowid.dispatchEvent(evt1)
                }
                else if (document.createEventObject) {
                    rowid.fireEvent('onblur');
                    rowid.fireEvent('onchange')
                }
        }
    }
}
function getChildren(node, filter) {
    var result = new Array();
    var children = node.childNodes;
    for ( var i = 0; i < children.length; i++) {
        node = children[i];
        if (filter == null || node.nodeName.toUpperCase() == filter.toUpperCase() || node.nodeType == node[filter])
            result[result.length] = node
    }
    return result
}

If a grid data set doesn't assume any operations and/or I don't want user can select a row I assign the value of "rowid" textbox to "-1", otherwise the assigned value is empty string "". I put this javascript code in file and place the reference on it in zul file:

<script type="text/javascript" src="smartgrid.js"/>

Then I create the action for grid. The next code show how it looks in zul file:

          <textbox id="rowid" visible="false"/>
          <grid id="resultGrid" action="onmousedown:gridHandler(event,#{rowid})">
                 <columns id="resultColumns"/>
                 <rows id="resultRows"/>
          </grid>

Here I use "proxy" textbox with id "rowid" to pass javascript variable value to server - for more ditails see ZK/How-Tos/Concepts-and-Tricks.

The variable value I put into "proxy" textbox is the id of html element which at the same time is id of row zk component. Then I use Desktop method getComponentByUuid to obtain the selected row component:
Row currentRow = (Row)Executions.getCurrent().getDesktop().getComponentByUuid(id);

You can register "onChange" event for textbox "rowid" and do some action when user click on a row

          EventListener _listener = new EventListener() {
              public void onEvent(Event event) throws UiException { showFirstColumnValue(); event.stopPropagation(); }
          };
          ((Textbox)Path.getComponent("/rowid")).addEventListener("onChange",_listener);
          private void showFirstColumnValue() {
              Row currentRow;
              String id = ((Textbox)Path.getComponent("/rowid")).getValue();
              if ( !id.equals("") && !id.equals("-1") ) {
                 currentRow = (Row)Executions.getCurrent().getDesktop().getComponentByUuid(id);
                 Messagebox.show("The value of first column is "+((Label)currentRow.getChildren().get(0)).getValue(), "Message", Messagebox.OK, Messagebox.INFORMATION);
             }   
          }

or you can get the selected row everywhere in java code without "onChange" event.

Live Demo

Download

Comments



Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.