[Commits] r2293 - in extensions/geoext.ux: examples tests ux ux/FeatureBrowser ux/FeatureBrowser/examples ux/FeatureBrowser/lib ux/FeatureBrowser/lib/GeoExt.ux ux/FeatureBrowser/tests ux/FeatureBrowser/tests/lib ux/FeatureBrowser/tests/lib/GeoExt.ux

commits at geoext.org commits at geoext.org
Mon Aug 30 10:05:05 CEST 2010


Author: fredj
Date: 2010-08-30 10:05:05 +0200 (Mon, 30 Aug 2010)
New Revision: 2293

Added:
   extensions/geoext.ux/ux/FeatureBrowser/
   extensions/geoext.ux/ux/FeatureBrowser/examples/
   extensions/geoext.ux/ux/FeatureBrowser/examples/featurebrowser.html
   extensions/geoext.ux/ux/FeatureBrowser/examples/featurebrowser.js
   extensions/geoext.ux/ux/FeatureBrowser/lib/
   extensions/geoext.ux/ux/FeatureBrowser/lib/GeoExt.ux/
   extensions/geoext.ux/ux/FeatureBrowser/lib/GeoExt.ux/FeatureBrowser.js
   extensions/geoext.ux/ux/FeatureBrowser/tests/
   extensions/geoext.ux/ux/FeatureBrowser/tests/index.html
   extensions/geoext.ux/ux/FeatureBrowser/tests/lib/
   extensions/geoext.ux/ux/FeatureBrowser/tests/lib/GeoExt.ux/
   extensions/geoext.ux/ux/FeatureBrowser/tests/lib/GeoExt.ux/FeatureBrowser.html
   extensions/geoext.ux/ux/FeatureBrowser/tests/list-tests.html
Modified:
   extensions/geoext.ux/examples/index.html
   extensions/geoext.ux/tests/list-tests.html
Log:
Add the FeatureBrowser ux (http://trac.geoext.org/wiki/ux/FeatureBrowser). p=pgiraud, r=elemoine,ahocevar,fredj (closes #288)

Modified: extensions/geoext.ux/examples/index.html
===================================================================
--- extensions/geoext.ux/examples/index.html	2010-08-30 07:54:56 UTC (rev 2292)
+++ extensions/geoext.ux/examples/index.html	2010-08-30 08:05:05 UTC (rev 2293)
@@ -10,6 +10,7 @@
              <li><a href="../ux/SimplePrint/examples/SimplePrint.html">SimplePrint Form using GeoExt.data.PrintProvider</a></li>
              <li><a href="../ux/Measure/examples/measure.html">Measure tools</a></li>
              <li><a href="../ux/FeatureEditing/examples/feature-editor-grid.html">Feature editor grid</a></li>
+             <li><a href="../ux/FeatureBrowser/examples/featurebrowser.html">Feature browser</a></li>
          </ul>
     </body>
 </html>

Modified: extensions/geoext.ux/tests/list-tests.html
===================================================================
--- extensions/geoext.ux/tests/list-tests.html	2010-08-30 07:54:56 UTC (rev 2292)
+++ extensions/geoext.ux/tests/list-tests.html	2010-08-30 08:05:05 UTC (rev 2293)
@@ -6,4 +6,5 @@
   <li>../../geoext.ux/ux/Measure/tests/lib/GeoExt.ux/MeasureArea.html</li>
   <li>../../geoext.ux/ux/Measure/tests/lib/GeoExt.ux/MeasureLength.html</li>
   <li>../../geoext.ux/ux/FeatureEditing/tests/lib/GeoExt.ux/FeatureEditorGrid.html</li>
+  <li>../../geoext.ux/ux/FeatureBrowser/tests/lib/GeoExt.ux/FeatureBrowser.html</li>
 </ul>

Added: extensions/geoext.ux/ux/FeatureBrowser/examples/featurebrowser.html
===================================================================
--- extensions/geoext.ux/ux/FeatureBrowser/examples/featurebrowser.html	                        (rev 0)
+++ extensions/geoext.ux/ux/FeatureBrowser/examples/featurebrowser.html	2010-08-30 08:05:05 UTC (rev 2293)
@@ -0,0 +1,22 @@
+<html>
+    <head>
+        <title>FeatureBrowser Example</title>
+
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-3.2.1/resources/css/ext-all.css" /> 
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-3.2.1/examples/shared/examples.css" /> 
+        
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-3.2.1/adapter/ext/ext-base.js"></script> 
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-3.2.1/ext-all.js"></script>
+        <script src="http://www.openlayers.org/api/2.9.1/OpenLayers.js"></script>
+        <script type="text/javascript" src="../../../../geoext/lib/GeoExt.js"></script>
+        
+        <!-- script resources for this ux -->
+        <script type="text/javascript" src="../lib/GeoExt.ux/FeatureBrowser.js"></script>
+        
+        <script type="text/javascript" src="featurebrowser.js"></script>
+    </head>
+    <body>
+        <h1>Feature Browser</h1>
+        <p style="margin-bottom:15px;">See <a href="featurebrowser.js">featurebrowser.js</a> for the source code.</p>
+    </body>
+</html>

Added: extensions/geoext.ux/ux/FeatureBrowser/examples/featurebrowser.js
===================================================================
--- extensions/geoext.ux/ux/FeatureBrowser/examples/featurebrowser.js	                        (rev 0)
+++ extensions/geoext.ux/ux/FeatureBrowser/examples/featurebrowser.js	2010-08-30 08:05:05 UTC (rev 2293)
@@ -0,0 +1,52 @@
+Ext.onReady(function() {
+
+    // required for tooltips
+    Ext.QuickTips.init();
+
+    features = [
+        new OpenLayers.Feature.Vector(null, {
+            name: 'toto',
+            age: '20',
+            photo: 'http://bits.ohloh.net/attachments/30093/GeoExt_med.png',
+            type: 'employee'
+        }),
+        new OpenLayers.Feature.Vector(null, {
+            foo: 'bar',
+            dude: 'truite',
+            type: 'thing'
+        })
+    ];
+
+    var browser = new GeoExt.ux.FeatureBrowser({
+        title: 'Feature Browser - no template',
+        renderTo: Ext.getBody(),
+        width: 200,
+        height: 200,
+        features: features,
+        bodyStyle: "padding: 5px;"
+    });
+
+    var browser = new GeoExt.ux.FeatureBrowser({
+        title: 'Feature Browser - \'type\' attribute dependent template',
+        renderTo: Ext.getBody(),
+        width: 200,
+        height: 200,
+        features: features,
+        tplFeatureAttribute: 'type',
+        tpl: {
+            'employee': new Ext.Template(
+                '<b>{name}</b>({age})<br />',
+                '<img src="{photo}" />'
+            )
+        },
+        bodyStyle: "padding: 5px;"
+    });
+    var browser = new GeoExt.ux.FeatureBrowser({
+        title: 'Feature Browser - single feature',
+        renderTo: Ext.getBody(),
+        width: 200,
+        height: 200,
+        features: [features[0]],
+        bodyStyle: "padding: 5px;"
+    });
+});

Added: extensions/geoext.ux/ux/FeatureBrowser/lib/GeoExt.ux/FeatureBrowser.js
===================================================================
--- extensions/geoext.ux/ux/FeatureBrowser/lib/GeoExt.ux/FeatureBrowser.js	                        (rev 0)
+++ extensions/geoext.ux/ux/FeatureBrowser/lib/GeoExt.ux/FeatureBrowser.js	2010-08-30 08:05:05 UTC (rev 2293)
@@ -0,0 +1,206 @@
+/**
+ * Copyright (c) 2008-2010 The Open Source Geospatial Foundation
+ * 
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+
+Ext.namespace("GeoExt.ux");
+
+/** api: (define)
+ *  module = GeoExt.ux
+ *  class = FeatureBrowser
+ *  base_link = `Ext.Panel <http://dev.sencha.com/deploy/dev/docs/?class=Ext.Panel>`_
+ */
+
+/** api: constructor
+ *  .. class:: FeatureBrowser(config)
+ *      
+ *      Creates a Panel to browse in a features list,
+ *  show attributes for each using templates.
+ */
+GeoExt.ux.FeatureBrowser = Ext.extend(Ext.Panel, {
+
+    /* begin i18n */
+    /** api: config[counterText]
+     *  ``String`` i18n, The counter message to display (defaults to "{0} of
+     *  {1}). Note that this string is formatted using {0} as a token for index
+     *  and {1} as a token for total. These tokens should be preserved when
+     *  overriding this string if showing those values is desired.
+     */
+    counterText: "{0} of {1} features",
+
+    /** api: config[elseTpl]
+     *  ``Ext.Template`` | ``Ext.XTemplate`` Ext.Template or Ext.XTemplate
+     *  to be used for features which don't match any of the tpl keys.
+     *  Will be taken into account only if tpl is an Object. Optional.
+     */
+    elseTpl: null, 
+
+    /** api: config[tpl]
+     * ``Ext.Template`` | ``Ext.XTemplate`` | ``Object`` | ``Function``
+     *  Ext.Template or Ext.XTemplate to be applied for each feature with
+     *  feature.attributes as context. If provided as an Object, each key
+     *  may correspond to the value for the tplFeatureAttribute key in the
+     *  feature attributes. The corresponding value has to be a valid template.
+     *  Optional.
+     */
+    tpl: undefined,
+
+    /** api: config[tplFeatureAttribute]
+     *  ``String`` | ``Number``
+     *  The attribute which value is to be compared with one of the tpl members
+     *  when provided as an Object. Mandatory is tpl is a Object. Optional.
+     */
+    tplFeatureAttribute: null,
+
+    /** api: config[skippedFeatureAttributes]
+     *  ``Array(String)``
+     *  Specifies the feature attributes to skip in the default Ext.Template
+     *  created by this component. Only applies when the ``tpl`` option is
+     *  not set. Optional.
+     */
+    skippedFeatureAttributes: null,
+    
+    /** api: config[features]
+     *  ``Array`` Array of ``OpenLayers.Feature.Vector`` to build the
+     *  FeatureBrowser with. Required.
+     */
+    features: null,
+
+    /** private: method[initComponent]
+     */
+    initComponent: function() {
+
+        this.layout = "card";
+
+        var nbFeatures = this.features.length;
+
+        this.items = [];
+        var feature, tpl;
+        for (var i = 0; i < nbFeatures; i++) {
+            feature = this.features[i];
+            tpl = this.getTemplateForFeature(feature);
+            
+            this.items.push(new Ext.BoxComponent({
+                id: 'card-'+ this.id + i,
+                html: tpl.apply(feature.attributes)
+            }));
+        }
+
+        if (nbFeatures > 1) {
+            this.bbar = [
+                {xtype: 'tbtext', id: 'counter-' + this.id},
+                '->',
+                {
+                    id: 'move-prev' + this.id,
+                    iconCls: "x-tbar-page-prev",
+                    handler: this.navHandler.createDelegate(this, 
+                        [-1, nbFeatures, this.features]),
+                    disabled: true,
+                    listeners: {
+                        click: function(button, e) {
+                            e.stopEvent();
+                        }
+                    }
+                },
+                {
+                    id: 'move-next' + this.id,
+                    iconCls: "x-tbar-page-next",
+                    handler: this.navHandler.createDelegate(this, 
+                        [1, nbFeatures, this.features]),
+                    listeners: {
+                        click: function(button, e) {
+                            e.stopEvent();
+                        }
+                    }
+                }
+            ];
+        }
+        this.activeItem = 0;
+
+        GeoExt.ux.FeatureBrowser.superclass.initComponent.apply(this, arguments);
+
+        // add custom events
+        this.addEvents(
+        
+            /** api: events[featureselected]
+             *  Fires when a feature is displayed in the FeatureBrowser.
+             *  Application may use this to highlight it on the map, for
+             *  example.
+             *
+             *  Listener arguments:
+             *  * panel - :class:`GeoExt.ux.FeatureBrowser` This panel.
+             *  * feature - ``OpenLayers.Feature.Vector`` The selected feature
+             */
+            'featureselected'
+        );
+        this.fireEvent('featureselected', this, this.features[0]);
+
+        var counter = Ext.getCmp('counter-' + this.id);
+        counter && counter.setText(
+            String.format(this.counterText, 1, nbFeatures)
+        );
+    },
+
+    /** private: method[navHandler]
+     *  The navigation handler method. Called when navigation buttons 
+     *  (next or previous) are clicked
+     */
+    navHandler: function(direction, total, features) {
+        var lay = this.getLayout();
+        var i = lay.activeItem.id.split('card-' + this.id)[1];
+        var next = parseInt(i, 10) + direction;
+        lay.setActiveItem(next);
+        this.fireEvent('featureselected', this, features[next]);
+        Ext.getCmp('move-prev' + this.id).setDisabled(next === 0);
+        Ext.getCmp('move-next' + this.id).setDisabled(next == total - 1);
+
+        var counter = Ext.getCmp('counter-' + this.id);
+        counter && counter.setText(
+            String.format(this.counterText, next + 1, total)
+        );
+    },
+
+    /** private: method[getTemplateForFeature]
+     *  Returns a template for the given feature.
+     *
+     *  :param feature: ``OpenLayers.Feature.Vector`` The feature to create
+     *      a template with.
+     *
+     *  :return: ``Ext.Template`` | ``Ext.XTemplate`` The created template.
+     */
+    getTemplateForFeature: function(feature) {
+        var tpl,
+            attributes = feature.attributes;
+
+        if (this.tpl instanceof Ext.Template) {
+            tpl = this.tpl;
+        } else if (typeof this.tpl === 'object') {
+            tpl = this.tpl[attributes[this.tplFeatureAttribute]] ||
+                  this.elseTpl;
+        } else if (typeof this.tpl === 'function') {
+            // currently unsupported
+        }
+
+        // create a default template with key/value pairs
+        if (!tpl) {
+            var templateString = '';
+            for (var k in attributes) {
+                if (attributes.hasOwnProperty(k) &&
+                    (this.skippedFeatureAttributes == null ||
+                     this.skippedFeatureAttributes.indexOf(k) === -1)) {
+
+                    templateString += '<div>' +
+                                      '<b>' + k + ': </b>' +
+                                      '{' + k + '}' +
+                                      '</div>';
+                }
+            }
+            tpl = new Ext.Template(templateString);
+        }
+
+        return tpl;
+    }
+});

Added: extensions/geoext.ux/ux/FeatureBrowser/tests/index.html
===================================================================
--- extensions/geoext.ux/ux/FeatureBrowser/tests/index.html	                        (rev 0)
+++ extensions/geoext.ux/ux/FeatureBrowser/tests/index.html	2010-08-30 08:05:05 UTC (rev 2293)
@@ -0,0 +1,4 @@
+<html>
+    <head><meta http-equiv="refresh" content="0;url=../../../../geoext/tests/run-tests.html?testlist=../../geoext.ux/ux/FeatureBrowser/tests/list-tests.html"></head>
+    <body></body>
+</html>

Added: extensions/geoext.ux/ux/FeatureBrowser/tests/lib/GeoExt.ux/FeatureBrowser.html
===================================================================
--- extensions/geoext.ux/ux/FeatureBrowser/tests/lib/GeoExt.ux/FeatureBrowser.html	                        (rev 0)
+++ extensions/geoext.ux/ux/FeatureBrowser/tests/lib/GeoExt.ux/FeatureBrowser.html	2010-08-30 08:05:05 UTC (rev 2293)
@@ -0,0 +1,143 @@
+<!DOCTYPE html>
+<html debug="true">
+  <head>
+    <script type="text/javascript" src="http://www.openlayers.org/api/2.9.1/OpenLayers.js"></script>
+    <script type="text/javascript" src="http://extjs.cachefly.net/ext-3.2.1/adapter/ext/ext-base.js"></script> 
+    <script type="text/javascript" src="http://extjs.cachefly.net/ext-3.2.1/ext-all.js"></script>
+    <script type="text/javascript" src="../../../../../../geoext/lib/GeoExt.js"></script>
+    <script type="text/javascript" src="../../../lib/GeoExt.ux/FeatureBrowser.js"></script>
+
+    <script type="text/javascript">
+        var features = [
+            new OpenLayers.Feature.Vector(null, {
+                foo: "foo0",
+                bar: "bar0",
+                baz: "baz0"
+            }),
+            new OpenLayers.Feature.Vector(null, {
+                foo: "foo1",
+                bar: "bar1",
+                baz: "baz1"
+            })
+        ];
+
+        function test_initialize(t) {
+            t.plan(3);
+            var browser;
+
+            browser = new GeoExt.ux.FeatureBrowser({
+                features: features
+            });
+            t.ok(browser instanceof GeoExt.ux.FeatureBrowser, "Instance created correctly");
+            t.eq(browser.items.getCount(), 2, "Correct number of items");
+            browser.destroy();
+
+            browser = new GeoExt.ux.FeatureBrowser({
+                features: [features[0]]
+            });
+            t.ok(browser.getBottomToolbar() == null, "No bbar required");
+            browser.destroy();
+        }
+
+        function test_events(t) {
+            t.plan(3);
+            var browser;
+
+            var count = 0;
+            var selectedFeature;
+            browser = new GeoExt.ux.FeatureBrowser({
+                renderTo: Ext.getBody(),
+                features: features,
+                listeners: {
+                    featureselected: function(panel, feature) {
+                        count++;
+                        selectedFeature = feature;
+                    }
+                }
+            });
+            t.ok(selectedFeature == features[0], "featureselected listener called with correct argument");
+
+            var nextBtn = Ext.getCmp('move-next' + browser.id);
+            nextBtn.handler.call(nextBtn, nextBtn, Ext.EventObject)
+            t.eq(count, 2, "featureselected event triggered twice");
+            t.ok(selectedFeature == features[1], "featureselected listener called with correct argument");
+            browser.destroy();
+        }
+
+        function test_getTemplate(t) {
+            t.plan(7);
+
+            var browser, tpl;
+            
+            // no template
+            browser = new GeoExt.ux.FeatureBrowser({
+                features: features
+            });
+            tpl = browser.getTemplateForFeature(features[0]);
+            t.eq(tpl.apply(features[0].attributes),
+                 '<div><b>foo: </b>foo0</div><div><b>bar: </b>bar0</div><div><b>baz: </b>baz0</div>',
+                "Template is correct when no template given"
+            );
+
+            // no template, with skippedFeatureAttributes
+            browser = new GeoExt.ux.FeatureBrowser({
+                features: features,
+                skippedFeatureAttributes: ["bar", "baz"]
+            });
+            tpl = browser.getTemplateForFeature(features[0]);
+            t.eq(tpl.apply(features[0].attributes),
+                 '<div><b>foo: </b>foo0</div>',
+                "Template is correct when no template given and skippedFeatureAttributes provided"
+            );
+
+            // a unique template
+            browser = new GeoExt.ux.FeatureBrowser({
+                features: features,
+                tpl: new Ext.Template('{foo}')  
+            });
+            tpl = browser.getTemplateForFeature(features[0]);
+            t.eq(tpl.apply(features[0].attributes), 'foo0',
+                "Template is correct when a template is given"
+            );
+            tpl = browser.getTemplateForFeature(features[1]);
+            t.eq(tpl.apply(features[1].attributes), 'foo1',
+                "Template is correct when a template is given"
+            );
+
+            // a hash
+            browser = new GeoExt.ux.FeatureBrowser({
+                features: features,
+                tplFeatureAttribute: 'foo',
+                tpl: {
+                    'foo0': new Ext.Template('{foo}')
+                }
+            });
+            tpl = browser.getTemplateForFeature(features[0]);
+            t.eq(tpl.apply(features[0].attributes), 'foo0',
+                "Template is correct when tpl is a hash and feature matches"
+            );
+            tpl = browser.getTemplateForFeature(features[1]);
+            t.eq(tpl.apply(features[1].attributes),
+                 '<div><b>foo: </b>foo1</div><div><b>bar: </b>bar1</div><div><b>baz: </b>baz1</div>',
+                "Template is correct when tpl is a hash and feature doesn't match"
+            );
+
+            // a hash and elseTpl defined
+            browser = new GeoExt.ux.FeatureBrowser({
+                features: features,
+                tplFeatureAttribute: 'foo',
+                elseTpl: new Ext.Template('truite'),
+                tpl: {
+                    'never': 'something'
+                }
+            });
+            tpl = browser.getTemplateForFeature(features[1]);
+            t.eq(tpl.apply(features[1].attributes), 'truite',
+                "Template is correct when tpl is a hash, elseTpl given and feature doesn't match"
+            );
+        }
+    </script>
+  <body>
+    <div id="map" style="width:600px;height:400px;"></div>
+  </body>
+</html>

Added: extensions/geoext.ux/ux/FeatureBrowser/tests/list-tests.html
===================================================================
--- extensions/geoext.ux/ux/FeatureBrowser/tests/list-tests.html	                        (rev 0)
+++ extensions/geoext.ux/ux/FeatureBrowser/tests/list-tests.html	2010-08-30 08:05:05 UTC (rev 2293)
@@ -0,0 +1,3 @@
+<ul id="testlist">
+  <li>../../geoext.ux/ux/FeatureBrowser/tests/lib/GeoExt.ux/FeatureBrowser.html</li>
+</ul>



More information about the Commits mailing list