basegrid.lzx
<library>
<include href="base/baselist.lzx"/>
<include href="base/basegridrow.lzx"/>
<include href="base/basegridcolumn.lzx"/>
<include href="utils/layouts/resizelayout.lzx"/>
<class name="basegrid" extends="basecomponent">
<attribute name="contentdatapath" value="*
" type="string" setter="setContentdatapath(contentdatapath)"/>
<attribute name="_selector" value="null
"/>
<attribute name="rowheight" type="number" value="null
"/>
<attribute name="spacing" value="0
" type="number"/>
<attribute name="multiselect" value="true
"/>
<event name="onselect"/>
<attribute name="columns" value="null
"/>
<attribute name="selectable" value="true
"/>
<attribute name="focusable" value="true
"/>
<attribute name="hilite" value="null
"/>
<attribute name="_lastmousex" value="null
"/>
<attribute name="_lastmousey" value="null
"/>
<attribute name="_columnclass" value="lz.basegridcolumn
" when="once"/>
<attribute name="_rowclass" value="lz.basegridrow
" when="once"/>
<attribute name="sizetoheader" value="null
" type="expression"/>
<attribute name="showhlines" type="boolean" value="false
"/>
<attribute name="showvlines" type="boolean" value="false
"/>
<attribute name="bgcolor0" type="color" value="$immediately{null}"/>
<attribute name="bgcolor1" type="color" value="$immediately{null}"/>
<attribute name="shownitems" value="-1
" setter="_setShownItems( shownitems )"/>
<event name="onshownitems"/>
<attribute name="_sortcol" value="null
"/>
<resizelayout name="mainlayout" axis="y"/>
<view name="header" width="${parent.width}" clip="true">
<view name="hcontent"/>
</view>
<view name="content" width="${classroot.width}" clip="true" options="releasetolayout">
<view name="rowparent" width="${parent.width}">
<datalistselector name="_selector" multiselect="$once{classroot.multiselect}">
<handler name="onconstruct">
classroot._selector = this;
</handler>
</datalistselector>
</view>
</view>
<state applied="${parent.sizetoheader}">
<attribute name="width" value="${ header.hcontent.width }"/>
</state>
<method name="getSelection">
if (this._initcomplete) {
// return a single value or an array
var sel = this._selector.getSelection();
if (multiselect) {
// always return an array for multiselect
return sel;
} else {
// single select, just return item or null
if (sel.length == 0) {
return null;
} else {
return sel[0];
}
}
} else {
return this._initialselection;
}
</method>
<method name="setContentdatapath" args="cdp">
if (this.isinited) {
this._getReplicator().setAttribute('datapath', cdp );
}
this.contentdatapath = cdp;
if (this["oncontentdatapath"]) {
this.oncontentdatapath.sendEvent( cdp );
}
</method>
<method name="selectNext">
_moveSelection(1);
</method>
<method name="selectPrev">
_moveSelection(-1);
</method>
<method name="_moveSelection" args="dir">
if (!dir) dir = 1;
var sel = this._selector.getSelection();
var next = null;
if (sel.length == 0) {
next = this._selector.getItemByIndex( 0 );
} else {
var p = sel[0].p;
var repl = content.rowparent.replicator;
if ( repl instanceof LzReplicationManager ){
//find selection in nodes list
var nodes = repl.nodes;
var nextp = null;
for ( var i = 0; i < nodes.length; i++ ){
if ( nodes[ i ] == p ){
nextp = nodes[ i + dir ];
next = this._selector.getItemByIndex( i + dir );
break;
}
}
}
}
_selector.ensureItemInView( next );
select( next );
</method>
<method name="getNumItems">
if (!this['_selector']) return 0; // too early
return this._selector.getNumItems();
</method>
<method name="getItemAt" args="index">
this._selector._ensureItemInViewByIndex(index);
return this._selector.getItemByIndex( index );
</method>
<method name="getIndexForItem" args="item">
return this._selector.findIndex( item );
</method>
<method name="getItem" args="data">
return this._selector.getItemByData( data );
</method>
<method name="removeItemAt" args="index">
var it = this._selector.getItemByIndex( index );
it.datapath.deleteNode();
</method>
<method name="selectItem" args="data">
var item = this._selector.getItemByData( data );
if (item) {
select(item);
}
</method>
<method name="selectItemAt" args="index">
var item = this._selector.getItemByIndex( index );
if (item) {
select(item);
}
</method>
<method name="clearSelection">
if ( this._initcomplete ){
this._setHiliteview( null , false);
this._selector.clearSelection();
} else {
this._initialselection = null;
this.defaultselection = null;
}
if ( this.onselect ) this.onselect.sendEvent();
</method>
<method name="select" args="item">
if ( ! this.selectable ) return;
if (item == null) {
//noop
} else if (this._initcomplete) {
this._selector.select(item);
} else {
if (multiselect) {
if (this._initialselection == null)
this._initialselection = [];
this._initialselection.push(item);
} else {
this._initialselection = item;
}
}
if ( this.onselect ) this.onselect.sendEvent(item);
</method>
<method name="_setHiliteview" args="who, ismouse">
var mousepos = this.getMouse();
if (ismouse && this._lastmousex == mousepos.x && this._lastmousey == mousepos.y){
//the mouse hasn't moved -- we're getting mouseup because the
//grid moved
return;
}
this._lastmousex = mousepos.x;
this._lastmousey = mousepos.y;
if (this.hilite) { this.hilite.setAttribute( "highlighted" , false ); }
this.setAttribute( "hilite" , who );
if (who) { who.setAttribute( "highlighted" , true ); }
</method>
<handler name="onkeydown" method="_dokeydown"/>
<method name="_dokeydown" args="kc">
if ( !selectable ) return;
/* select item on 'space' key */
if (kc == 32 && this.hilite ) {
this.doEnterDown();
return;
}
/* handle arrow key navigation
37 = left arrow, 38 = up arrow
39 = right arrow, 40 = down arrow
*/
if (kc >= 37 && kc <= 40) {
this.setAttribute( 'doesenter', true );
var s = this.hilite;
if (s == null) {
s = getSelection();
if (this.multiselect) s = s[0];
} if (s == null) {
s = content.rowparent.replicator.clones[ 0 ];
}
var next;
if (kc == 39 || kc == 40) {
next = _selector.getNextSubview(s);
}
if (kc == 37 || kc == 38) {
next = _selector.getNextSubview(s, -1);
}
if ( this.hilite ) {
this.hilite.setAttribute( "highlighted" , false );
}
this.setAttribute( "hilite" , next );
if (this.hilite) {
this.hilite.setAttribute( "highlighted" , true );
}
}
</method>
<handler name="onblur" method="_doblur"/>
<method name="_doblur" args="ignore">
if (this.hilite) this.hilite.setAttribute( "highlighted" , false );
this.setAttribute( "hilite" , null );
</method>
<method name="doEnterDown">
select( this.hilite );
</method>
<method name="_getReplicator">
return this.content.rowparent.replicator;
</method>
<method name="init">
this.columns = [];
this.makeCellsAndColumns();
if ( columns.length == 0 ){
this.inferDel = null;
var haddatapath = true;
if ( ! this.datapath ) {
haddatapath = false;
var ovisibility = this.visibility;
this.setAttribute('datapath', "." );
this.datapath.setAttribute( "datacontrolsvisibility",
false );
this.setAttribute('visibility', ovisibility );
}
var cells = this.inferColumns();
if ( columns.length == 0 ){
//no data yet?
this.inferDel = new LzDelegate( this, "inferColumns" );
if ( haddatapath ){
this.inferDel.register( this, "ondata" );
} else {
//try to find dataset...
var iof = contentdatapath.indexOf( ":/" );
if ( iof > -1 ){
var dset = this.datapath.xpathQuery(
contentdatapath.substring( 0 ,
iof + 2 ) );
this.inferDel.register( dset , "ondata" );
}
}
}
}
super.init();
</method>
<method name="makeCellsAndColumns">
var svl = header.hcontent.subviews;
var cells = [];
if ( svl ){
for ( var i = 0; i< svl.length; i++ ){
if ( svl[ i ] instanceof lz.basegridcolumn ) {
this.columns.push( svl[ i ] );
cells.push( svl[ i ]._getCellForColumn() );
}
}
}
if ( ! this.columns.length ) return;
var initArgs = { name: "replicator",
ownerGrid : this ,
selectable : this.selectable };
if ( this.rowheight ) {
initArgs.height = this.rowheight;
}
initArgs.needsSetRegularColor = this.bgcolor0 != null ||
this.bgcolor1 != null;
var r = new _rowclass ( content.rowparent , initArgs, cells , true );
new lz.datapath( r , { replication : "lazy" ,
xpath : this.contentdatapath ,
spacing : this.spacing } );
var noSTH = this.sizetoheader === null;
if ( ! this.hassetwidth ){
if ( noSTH ){
this.setAttribute( "sizetoheader", true );
} else if ( !this.sizetoheader ){
this.setAttribute('width', this.header.hcontent.width );
}
}
//now force it to be boolean
if ( noSTH && !this.sizetoheader){
this.setAttribute( "sizetoheader" , false );
}
if ( ! this.hassetheight ){
this.setAttribute( "shownitems", (this.shownitems != -1 ? this.shownitems : 8) );//take the value of "shownitems" if provided
}
this.header.bringToFront();
</method>
<method name="inferColumns" args="ignore=null">
var res = this.datapath.xpathQuery( this.contentdatapath );
if ( ! res ) return;
if ( res instanceof Array ) res = res[ 0 ];
if ( res != null ){
var usename = true;
if ( res.attributes ){
for ( var k in res.attributes ){
usename = false;
new _columnclass( this , { datapath : '@' + k,
text : k } );
}
}
if ( usename ){
new _columnclass( this , { datapath : 'name()',
text : 'name' } );
new _columnclass( this , { datapath : 'text()',
text : 'text' } );
}
this.makeCellsAndColumns();
if ( this.columns.length && this.inferDel ){
this.inferDel.unregisterAll();
delete this.inferDel;
}
}
</method>
<method name="_setSortCol" args="who">
if ( this._sortcol ){
this._sortcol.setAttribute( 'hasSort' , false );
}
this.setAttribute( "_sortcol" , who );
if ( this._sortcol ){
this._sortcol.setAttribute( 'hasSort' , true );
}
</method>
<method name="_setShownItems" args="s">
this.shownitems = s;
if ( this.rowheight == null ) return;
if(this.isinited){
if ( s != -1 ){
var bottompart = this.height -
(this.content.y + this.content.height );
this.setAttribute('height', bottompart + this.content.y + s * rowheight );
}
}
if ( this.onshownitems ){
this.onshownitems.sendEvent ( s );
}
</method>
<method name="clearSort">
var repl = this._getReplicator();
if (repl != null && repl is LzReplicationManager) {
repl.setOrder( null );
this._setSortCol( null );
repl.setXPath( repl.xpath );
} else {
this._setSortCol( null );
}
</method>
<method name="_setRowHeight" args="h">
this.setAttribute("rowheight", h );
if ( this.shownitems != -1 ){
this.setAttribute( "shownitems" , this.shownitems );
}
</method>
<method name="getNextSelection">
var sel = getSelection();
if ( sel instanceof Array ) {
sel = sel[ 0 ];
}
if ( sel && sel.p ) return this._selector.getItemByData( sel.p );
</method>
<doc>
<tag name="shortdesc"><text>An abstract row-based container for data elements.</text></tag>
<text>
<p><classname>basegrid</classname> is an abstract container for
row-based data stored in a dataset. Because
<classname>basegrid</classname> uses <a href="lz.lazyreplicator.html">lazy replication</a>, it is an efficient way to
present large datasets, and it abstracts some of the complications
involved in maintaining a selection within a dataset.</p>
<example>
<canvas height="150">
<dataset name="contacts" request="true"
src="http:resources/contactsdata.xml"/>
<basegrid datapath="contacts:/resultset" width="200"
height="150">
<basegridcolumn>
<text placement="header">Check 'em off</text>
<checkbox text="$path{ '@displayname'}"
value="$path{'@checked'}">
<handler name="onvalue">
this.parent.parent.datapath.updateData();
</handler>
</checkbox>
</basegridcolumn>
<scrollbar placement="content"/>
</basegrid>
</canvas>
</example>
</text>
</doc>
</class>
</library>
Cross References
Includes
Classes
- <class name="basegrid" extends="basecomponent">