it LIIIIIIVVVVVVVVVVVESSSSSSSSSS!
authorLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Mon, 26 Mar 2012 21:18:46 +0000 (17:18 -0400)
committerLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Mon, 26 Mar 2012 21:18:46 +0000 (17:18 -0400)
Signed-off-by: Lebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Open-ILS/src/perlmods/lib/OpenILS/WWW/FlatFielder.pm
Open-ILS/src/templates/conify/flattener_test.tt2
Open-ILS/web/js/dojo/openils/FlattenerStore.js
Open-ILS/web/js/dojo/openils/widget/FlattenerGrid.js

index 03d8a8b..f8216c1 100644 (file)
@@ -78,13 +78,17 @@ sub data_to_xml {
 sub data_to_json {
     my ($args) = @_;
 
-    return OpenSRF::Utils::JSON->perl2JSON({
-        ($$args{hint} ? (hint => $$args{hint}) : ()),
-        ($$args{identifier_field} ? (identifier => $$args{identifier_field}) : ()),
-        ($$args{label_field} ? (label => $$args{label_field}) : ()),
-        ($$args{key} ? (FS_key => $$args{key}) : ()),
-        items => $$args{data}
-    });
+    # Turns out we don't want the data structure you'd use to initialize an
+    # itemfilereadstore or similar. We just want rows.
+
+#    return OpenSRF::Utils::JSON->perl2JSON({
+#        ($$args{hint} ? (hint => $$args{hint}) : ()),
+#        ($$args{id_field} ? (identifier => $$args{id_field}) : ()),
+#        ($$args{label_field} ? (label => $$args{label_field}) : ()),
+#        ($$args{key} ? (FS_key => $$args{key}) : ()),
+#        items => $$args{data}
+#    });
+    return OpenSRF::Utils::JSON->perl2JSON($args->{data});
 }
 
 # Given data and the Apache request object, this sub picks a sub from a
index 85fe5a9..e3f5a5f 100644 (file)
@@ -3,51 +3,14 @@
 <script type="text/javascript">
     dojo.require("dijit.form.Button");
     dojo.require("openils.widget.FlattenerGrid");
-    dojo.require("dojo.data.ItemFileReadStore");
+    //dojo.require("dojo.data.ItemFileReadStore");
+    //dojo.require("openils.DebuggingIFRS");
 
     /*
        var gridData = <esc>:r ~/grid-data
-       */
-    var gridData = {
-        "data":{
-            "identifier":"part_num",
-            "label":"part_num",
-            "items":[
-                {"part_num":7,"min_temp":0,"max_temp":32,"type":"ice","thick":5},
-                {"part_num":8,"min_temp":-10,"max_temp":22,"type":"ice_1","thick":6},
-                {"part_num":9,"min_temp":-20,"max_temp":12,"type":"ice_2","thick":7},
-                {"part_num":10,"min_temp":-30,"max_temp":2,"type":"ice_3","thick":8},
-                {"part_num":11,"min_temp":-40,"max_temp":-8,"type":"ice_4","thick":9},
-                {"part_num":12,"min_temp":-50,"max_temp":-18,"type":"ice_5","thick":10},
-                {"part_num":13,"min_temp":-60,"max_temp":-28,"type":"ice_6","thick":11},
-                {"part_num":14,"min_temp":-70,"max_temp":-38,"type":"ice_7","thick":12},
-                {"part_num":15,"min_temp":-80,"max_temp":-48,"type":"ice_8","thick":13},
-                {"part_num":16,"min_temp":-90,"max_temp":-58,"type":"ice_9","thick":14},
-                {"part_num":17,"min_temp":-100,"max_temp":-68,"type":"ice_10","thick":15},
-                {"part_num":18,"min_temp":-110,"max_temp":-78,"type":"ice_11","thick":16},
-                {"part_num":19,"min_temp":-120,"max_temp":-88,"type":"ice_12","thick":17},
-                {"part_num":20,"min_temp":-130,"max_temp":-98,"type":"ice_13","thick":18},
-                {"part_num":21,"min_temp":-140,"max_temp":-108,"type":"ice_14","thick":19},
-                {"part_num":22,"min_temp":-150,"max_temp":-118,"type":"ice_15","thick":20},
-                {"part_num":23,"min_temp":-160,"max_temp":-128,"type":"ice_16","thick":21},
-                {"part_num":24,"min_temp":-170,"max_temp":-138,"type":"ice_17","thick":22},
-                {"part_num":25,"min_temp":-180,"max_temp":-148,"type":"ice_18","thick":23},
-                {"part_num":26,"min_temp":-190,"max_temp":-158,"type":"ice_19","thick":24},
-                {"part_num":27,"min_temp":-200,"max_temp":-168,"type":"ice_20","thick":25},
-                {"part_num":28,"min_temp":-210,"max_temp":-178,"type":"ice_21","thick":26},
-                {"part_num":29,"min_temp":-220,"max_temp":-188,"type":"ice_22","thick":27},
-                {"part_num":30,"min_temp":-230,"max_temp":-198,"type":"ice_23","thick":28},
-                {"part_num":31,"min_temp":-240,"max_temp":-208,"type":"ice_24","thick":29},
-                {"part_num":32,"min_temp":-250,"max_temp":-218,"type":"ice_25","thick":30},
-                {"part_num":33,"min_temp":-260,"max_temp":-228,"type":"ice_26","thick":31},
-                {"part_num":34,"min_temp":-270,"max_temp":-238,"type":"ice_27","thick":32},
-                {"part_num":35,"min_temp":-280,"max_temp":-248,"type":"ice_28","thick":33},
-                {"part_num":36,"min_temp":-290,"max_temp":-258,"type":"ice_29","thick":34}
-            ]
-        }
-    };
-   var gridStore = new dojo.data.ItemFileReadStore(gridData);
+   var gridStore = new openils.DebuggingIFRS(gridData);
    console.log("gridStore built");
+   */
 
     /* mapClause="{ 'barcode': 'barcode', 'circ_lib_name': 'circ_lib.name', 'circ_lib': 'circ_lib.shortname', 'call_number': { 'path': 'call_number.label', 'sort': true, 'display': true }, 'id': 'id', 'tcn': { 'path': 'call_number.record.tcn_value', 'filter': true, 'sort': true } }" */
 
     id="gridNode"
     jsid="grid"
     dojoType="openils.widget.FlattenerGrid"
-    fmClass="acp"
+    fmClass="'acp'"
     autoHeight="10"
-    query="{__id: '*'}"
-    >
+    query="{'tcn': {'>': '100' },'circ_lib': 'BR1'}">
     <thead>
         <tr>
             <th field="barcode" fpath="barcode">Barcode</th>
-            <th field="circ_lib" fpath="circ_lib.name" width="100px">Circulation Library Name</th>
-            <th field="circ_lib_name" fpath="circ_lib.shortname" width="100px">Circulation Library</th>
-            <th field="call_number" fpath="call_number.label" fsort="true" width="100px">Call Number</th>
-            <th field="tcn" fpath="call_number.record.tcn_value" ffilter="true" width="5em">TCN</th>
+            <th field="circ_lib_name" fpath="circ_lib.name">Circulation Library Name</th>
+            <th field="circ_lib" fpath="circ_lib.shortname">Circulation Library</th>
+            <th field="call_number" fpath="call_number.label" fdisplay="true" fsort="true">Call Number</th>
+            <th field="tcn" fpath="call_number.record.tcn_value" fdisplay="true" ffilter="true">TCN</th>
         </tr>
     </thead>
 </table>
index 6922642..4b36e39 100644 (file)
@@ -3,7 +3,6 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
 
     dojo.provide("openils.FlattenerStore");
 
-    dojo.require("DojoSRF");
     dojo.require("openils.User");
     dojo.require("openils.Util");
 
@@ -13,6 +12,18 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
         return "openils.FlattenerStore: " + this.message;
     };
 
+    function lazy(o) {
+        if (typeof o == "object") {
+            if (o.part_num)
+                return "[object with part_num: " + o.part_num + "]";
+            else
+                return "[object with keys: " + openils.Util.objectProperties(o).join(",") + "]";
+        } else {
+            return o;
+        }
+    }
+
+
     dojo.declare(
         "openils.FlattenerStore", null, {
 
@@ -23,8 +34,8 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
 
         "fmClass": null,
         "mapClause": null,
-        "whereClause": null,
         "sloClause": null,
+        "limit": 25,
 
 
         "constructor": function(/* object */ args) {
@@ -32,31 +43,34 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
             this._current_items = {};
         },
 
-        "_prepare_flattener_url": function(req) {
-            var url = "/opac/extras/flattener?";
-
+        "_prepare_flattener_params": function(req) {
             var limit = (!isNaN(req.count) && req.count != Infinity) ?
                 req.count : this.limit;
 
-            var slo = dojo.clone(this.sloClause);
-            slo.limit = limit;
+            //            XXX TODO
+            //            get offset(start) too, mixing base sort if any, check
+            //            grid sorting (multicolumn)
+//            var slo = dojo.clone(this.sloClause);
+//            slo.limit = limit;
+//
+            var slo = {"limit": limit, "sort": "barcode"};
 
             // XXX offset
-            var parts = [
-                "hint=" + this.fmClass,
-                "ses=" + openils.User.authtoken,
-                "where=" + dojo.toJson(this.whereClause),
-                "slo=" + dojo.toJson(slo),
-                "identifier=" + fieldmapper.IDL.fmclasses[this.fmClass].pkey
-            ];
+            var content = {
+                "hint": this.fmClass,
+                "ses": openils.User.authtoken,
+                "where": dojo.toJson(req.query),
+                "slo": dojo.toJson(slo)
+                //"identifier": this.fmIdentifier
+            };
 
             if (this.mapKey) { /* XXX TODO, get a map key */
-                parts.push("key=" + this.mapKey);
+                content.key = this.mapKey;
             } else {
-                parts.push("map=" + dojo.toJson(this.mapClause));
+                content.map = dojo.toJson(this.mapClause);
             }
 
-            return url + parts.join("&");
+            return content;
         },
 
         "_display_attributes": function() {
@@ -74,6 +88,7 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
             /* object */ item,
             /* string */ attribute,
             /* anything */ defaultValue) {
+            console.log("getValue(" + lazy(item) + ", " + attribute + ", " + defaultValue + ")")
             if (!this.isItem(item))
                 throw new FlattenerStoreError("getValue(): bad item " + item);
             else if (typeof attribute != "string")
@@ -84,6 +99,7 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
         },
 
         "getValues": function(/* object */ item, /* string */ attribute) {
+            console.log("getValues(" + item + ", " + attribute + ")");
             if (!this.isItem(item) || typeof attribute != "string")
                 throw new FlattenerStoreError("bad arguments");
 
@@ -92,6 +108,7 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
         },
 
         "getAttributes": function(/* object */ item) {
+            console.log("getAttributes(" + item + ")");
             if (!this.isItem(item))
                 throw new FlattenerStoreError("getAttributes(): bad args");
             else
@@ -99,6 +116,7 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
         },
 
         "hasAttribute": function(/* object */ item, /* string */ attribute) {
+            console.log("hasAttribute(" + item + ", " + attribute + ")");
             if (!this.isItem(item) || typeof attribute != "string") {
                 throw new FlattenerStoreError("hasAttribute(): bad args");
             } else {
@@ -110,6 +128,7 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
             /* object */ item,
             /* string */ attribute,
             /* anything */ value) {
+            console.log("containsValue(" + item + ", " + attribute + ", " + value + ")");
             if (!this.isItem(item) || typeof attribute != "string")
                 throw new FlattenerStoreError("bad data");
             else
@@ -118,16 +137,15 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
                 );
         },
 
-        /* =========== not dealt with at all below here yet ============ */
-
         "isItem": function(/* anything */ something) {
+            console.log("isItem(" + lazy(something) + ")");
             if (typeof something != "object" || something === null)
                 return false;
 
-            var fields = [];
+            var fields = this._display_attributes()
 
-            for (var i = 0; i < _autosuggest_fields.length; i++) {
-                var cur = _autosuggest_fields[i];
+            for (var i = 0; i < fields.length; i++) {
+                var cur = fields[i];
                 if (typeof something[cur] == "undefined")
                     return false;
             }
@@ -135,15 +153,27 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
         },
 
         "isItemLoaded": function(/* anything */ something) {
+            console.log("isItemLoaded(" + something + ")");
             return this.isItem(something);  /* for this store,
                                                items are always loaded */
         },
 
         "close": function(/* object */ request) { /* no-op */ return; },
-        "getLabel": function(/* object */ item) { return "match"; },
-        "getLabelAttributes": function(/* object */ item) { return ["match"]; },
+
+        /* =========== not dealt with at all below here yet ============ */
+
+        "getLabel": function(/* object */ item) {
+            console.log("getLabel(" + item + ")");
+            return "match";
+        },
+        "getLabelAttributes": function(/* object */ item) {
+            console.log("getLabelAttributes(" + item + ")");
+            return ["match"];
+        },
 
         "loadItem": function(/* object */ keywordArgs) {
+            console.log("loadItem(" + dojo.toJson(keywordArgs) + ")");
+
             if (!this.isItem(keywordArgs.item))
                 throw new FlattenerStoreError("not an item; can't load it");
 
@@ -171,17 +201,20 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
             //  callback to the *req* object for the caller's use, but
             //  the one we provide does nothing but issue an alert().
 
-            if (!this.cm_cache.is_done) {
-                if (typeof req.onComplete == "function")
-                    req.onComplete.call(callback_scope, [], req);
-                return;
-            }
+            console.log("fetch(" + dojo.toJson(req) + ")");
+            /* if-not-ready-then-act-as-if-empty. this is how you do that. */
+
+//            if (!this.cm_cache.is_done) {
+//                if (typeof req.onComplete == "function")
+//                    req.onComplete.call(callback_scope, [], req);
+//                return;
+//            }
             this._current_items = {};
 
             var callback_scope = req.scope || dojo.global;
-            var url = this._prepare_flattener_url(req);
+            var post_params = this._prepare_flattener_params(req);
 
-            if (!url) {
+            if (!post_params) {
                 if (typeof req.onComplete == "function")
                     req.onComplete.call(callback_scope, [], req);
                 return;
@@ -192,11 +225,13 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
                 if (when < self._last_fetch) /* Stale response. Discard. */
                     return;
 
+                console.log(dojo.toJson(obj));
+                if (typeof req.onBegin == "function")
+                    req.onBegin.call(callback_scope, obj.length, req);
+
                 dojo.forEach(
-                    obj.val,
+                    obj,
                     function(item) {
-                        item.id = item.field + "_" + item.term;
-
                         self._current_items[item.id] = item;
 
                         if (typeof req.onItem == "function")
@@ -217,13 +252,12 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
                 alert("The 'abort' operation is not supported");
             };
 
-            if (typeof req.onBegin == "function")
-                req.onBegin.call(callback_scope, -1, req);
-
             var fetch_time = this._last_fetch = (new Date().getTime());
 
-            dojo.xhrGet({
-                "url": url,
+            console.log(dojo.toJson(post_params));
+            dojo.xhrPost({
+                "url": "/opac/extras/flattener",
+                "content": post_params,
                 "handleAs": "json",
                 "sync": false,
                 "preventCache": true,
@@ -239,15 +273,20 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
         /* *** Begin dojo.data.api.Identity methods *** */
 
         "getIdentity": function(/* object */ item) {
+            console.log("getIdentity(" + item + ")");
             if (!this.isItem(item))
                 throw new FlattenerStoreError("not an item");
 
             return item.id;
         },
 
-        "getIdentityAttributes": function(/* object */ item) { return ["id"]; },
+        "getIdentityAttributes": function(/* object */ item) {
+            console.log("getIdentityAttributes(" + item + ")");
+            return ["id"];
+        },
 
         "fetchItemByIdentity": function(/* object */ keywordArgs) {
+            console.log("fetchItemByIdentity(" + dojo.toJson(keywordArgs)+ ")");
             if (keywordArgs.identity == undefined)
                 return null; // Identity API spec unclear whether error callback
                              // would need to be run, so we won't.
@@ -271,6 +310,7 @@ if (!dojo._hasResource["openils.FlattenerStore"]) {
          *     APIs they're implementing. *** */
 
         "getFeatures": function() {
+            console.log("getFeatures()");
             return {
                 "dojo.data.api.Read": true,
                 "dojo.data.api.Identity": true
index 0ff31b9..62dc592 100644 (file)
@@ -1,6 +1,7 @@
 if (!dojo._hasResource["openils.widget.FlattenerGrid"]) {
     dojo.provide("openils.widget.FlattenerGrid");
 
+    dojo.require("DojoSRF");
     dojo.require("dojox.grid.DataGrid");
     dojo.require("openils.FlattenerStore");
 
@@ -8,6 +9,8 @@ if (!dojo._hasResource["openils.widget.FlattenerGrid"]) {
         "openils.widget.FlattenerGrid",
         [dojox.grid.DataGrid], {
             "columnReordering": true,
+            "fmClass": null,
+            "fmIdentifier": null,
 
             "_generate_map": function() {
                 var map = this.mapClause = {};
@@ -28,19 +31,35 @@ if (!dojo._hasResource["openils.widget.FlattenerGrid"]) {
                                 };
                             } else {
                                 map[field.field] = {
-                                    "path": field.fpath,
                                     "sort": true,
                                     "filter": true,
                                     "display": true
                                 };
                             }
+                            map[field.field].path = field.fpath;
                         }
                     }
                 );
 
+                /* make sure we always have a field for fm identifier */
+                if (!map[this.fmIdentifier]) {
+                    map[this.fmIdentifier] = {
+                        "path": this.fmIdentifier,
+                        "display": true,
+                        "sort": false,
+                        "filter": false
+                    };
+                }
+
                 return map;
             },
 
+            "constructor": function(args) {
+                dojo.mixin(this, args);
+                this.fmIdentifier = this.fmIdentifier ||
+                    fieldmapper.IDL.fmclasses[this.fmClass].pkey;
+            },
+
             "startup": function() {
                 if (!this.store) {
                     this.store = new openils.FlattenerStore({
@@ -48,6 +67,8 @@ if (!dojo._hasResource["openils.widget.FlattenerGrid"]) {
                         "mapClause": (this.mapClause || this._generate_map())
                     });
                 }
+
+                this.inherited(arguments);
             }
         }
     );