Acq: you can now back up to old search results
authorsenator <senator@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 8 Apr 2010 20:58:50 +0000 (20:58 +0000)
committersenator <senator@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 8 Apr 2010 20:58:50 +0000 (20:58 +0000)
This works by changing what actually happens when you click "Search."
Instead of running your search instantly, the search interface turns your
search into URL parameters and redirects you.  This way you get a new entry
in your browser history (much as if you were doing a non-AJAX search).

When the search interface is run with these URL paramters, it actually runs
the search and shows you the results.  This has the added benefit of
allowing other interfaces to link to prepopulated searches, and potentially
giving users a way to save searches in the future.

Incidentally also added "new invoice" menu item.

git-svn-id: svn://svn.open-ils.org/ILS/trunk@16178 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/web/js/ui/default/acq/common/base64.js [new file with mode: 0644]
Open-ILS/web/js/ui/default/acq/po/view_po.js
Open-ILS/web/js/ui/default/acq/search/unified.js
Open-ILS/web/opac/locale/en-US/lang.dtd
Open-ILS/web/templates/default/acq/po/view.tt2
Open-ILS/web/templates/default/acq/search/unified.tt2
Open-ILS/xul/staff_client/chrome/content/main/menu.js
Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul
Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties

diff --git a/Open-ILS/web/js/ui/default/acq/common/base64.js b/Open-ILS/web/js/ui/default/acq/common/base64.js
new file mode 100644 (file)
index 0000000..6d62cc7
--- /dev/null
@@ -0,0 +1,15 @@
+dojo.require("dojox.encoding.base64");
+
+function base64Encode(o) {
+    return dojox.encoding.base64.encode(
+        js2JSON(o).split("").map(function(c) { return c.charCodeAt(0); })
+    );
+}
+
+function base64Decode(s) {
+    return JSON2js(
+        dojox.encoding.base64.decode(s).map(
+            function(b) { return String.fromCharCode(b); }
+        ).join("")
+    );
+}
index f4c886f..dbf2790 100644 (file)
@@ -292,6 +292,13 @@ function renderPo() {
         function() {
             location.href = oilsBasePath + '/acq/invoice/view?create=1&attach_po=' + poId;
         };
+
+    dojo.byId("acq-po-view-invoice-link").onclick =
+        function() {
+            location.href = oilsBasePath + "/acq/search/unified?so=" +
+                base64Encode({"jub":[{"purchase_order": PO.id()}]}) +
+                "&rt=invoice";
+        };
 }
 
 
index 52542b4..0a85646 100644 (file)
@@ -1,19 +1,31 @@
 dojo.require("dojo.date.stamp");
+dojo.require("dojox.encoding.base64");
 dojo.require("openils.widget.AutoGrid");
 dojo.require("openils.widget.AutoWidget");
 dojo.require("openils.PermaCrud");
-dojo.require("openils.Util");
 
 var termSelectorFactory;
 var termManager;
 var resultManager;
+var uriManager;
 var pcrud = new openils.PermaCrud();
+var cgi = new openils.CGI();
 
-/* typing save: add getValue() to all HTML <select> elements */
+/* typing save: add {get,set}Value() to all HTML <select> elements */
 HTMLSelectElement.prototype.getValue = function() {
     return this.options[this.selectedIndex].value;
 }
 
+/* only sets the selected value if such an option is actually available */
+HTMLSelectElement.prototype.setValue = function(s) {
+    for (var i = 0; i < this.options.length; i++) {
+        if (s == this.options[i].value && !this.options[i].disabled) {
+            this.selectedIndex = i;
+            break;
+        }
+    }
+}
+
 /* quickly find elements by the value of a "name" attribute */
 function nodeByName(name, root) {
     return dojo.query("[name='" + name + "']", root)[0];
@@ -206,7 +218,7 @@ function TermManager() {
             field_map[term.field]["class"];
     };
 
-    this.updateRowWidget = function(id) {
+    this.updateRowWidget = function(id, value) {
         var where = nodeByName("widget", this._row(id));
 
         delete this.widgets[id];
@@ -235,11 +247,51 @@ function TermManager() {
                 var inequalities = (term.datatype == "timestamp");
                 self.matchHowAllow(id, "__gte", inequalities);
                 self.matchHowAllow(id, "__lte", inequalities);
+
+                if (value) {
+                    if (typeof(w.attr) == "function")
+                        w.attr("value", value);
+                    else
+                        w.value = value;
+                }
             }
         );
     };
 
-    this.addRow = function() {
+    /* this method is particularly kludgy... puts back together a string
+     * based on object properties that might arrive in indeterminate order. */
+    this._term_reverse_match_how = function(term) {
+        /* only two-key combination we use */
+        if (term.__not && term.__fuzzy)
+            return "__not,__fuzzy";
+
+        /* only other possibilities are single-key or no key */
+        for (var key in term) {
+            if (/^__/.test(key))
+                return key;
+        }
+
+        return null;
+    };
+
+
+    this._term_reverse_selector_field = function(term) {
+        for (var key in term) {
+            if (!/^__/.test(key))
+                return key;
+        }
+        return null;
+    };
+
+    this._term_reverse_selector_value = function(term) {
+        for (var key in term) {
+            if (!/^__/.test(key))
+                return term[key];
+        }
+        return null;
+    };
+
+    this.addRow = function(term, hint) {
         var uniq = (this.rowId)++;
 
         var row = dojo.clone(this.template);
@@ -260,6 +312,16 @@ function TermManager() {
         nodeByName("remove", row).appendChild(this.removerButton(uniq));
 
         dojo.place(row, "acq-unified-terms-tbody", "last");
+
+        if (term && hint) {
+            var field = hint + ":" + this._term_reverse_selector_field(term);
+            selector.setValue(field);
+            this.updateRowWidget(uniq, this._term_reverse_selector_value(term));
+
+            var match_how_value = this._term_reverse_match_how(term);
+            if (match_how_value)
+                match_how.setValue(match_how_value);
+        }
     }
 
     this.removeRow = function(id) {
@@ -267,6 +329,14 @@ function TermManager() {
         dojo.destroy(this._row(id));
     };
 
+    this.reflect = function(search_object) {
+        for (var hint in search_object) {
+            search_object[hint].forEach(
+                function(term) { self.addRow(term, hint); }
+            );
+        }
+    };
+
     this.buildSearchObject = function() {
         var so = {};
 
@@ -421,7 +491,14 @@ function ResultManager(liTable, poGrid, plGrid, invGrid) {
         this.result_types[which].revealer();
     };
 
-    this.search = function(search_obj) {
+    this.go = function(search_object) {
+        location.href = oilsBasePath + "/acq/search/unified?" +
+            "so=" + base64Encode(search_object) +
+            "&rt=" + dojo.byId("acq-unified-result-type").getValue() +
+            "&c=" + dojo.byId("acq-unified-conjunction").getValue();
+    };
+
+    this.search = function(search_object) {
         var count_results = 0;
         var result_type = dojo.byId("acq-unified-result-type").getValue();
         var conjunction = dojo.byId("acq-unified-conjunction").getValue();
@@ -436,7 +513,7 @@ function ResultManager(liTable, poGrid, plGrid, invGrid) {
             this.result_types[result_type].search_options
         ];
 
-        params[conjunction == "and" ? 1 : 2] = search_obj;
+        params[conjunction == "and" ? 1 : 2] = search_object;
 
         fieldmapper.standardRequest(
             ["open-ils.acq", method_name], {
@@ -460,21 +537,41 @@ function ResultManager(liTable, poGrid, plGrid, invGrid) {
     }
 }
 
-/* The rest of the functions below handle the relatively unorganized
- * miscellany of the search interface.
- */
+function URIManager() {
+    var self = this;
+
+    this.search_object = cgi.param("so");
+    if (this.search_object)
+        this.search_object = base64Decode(this.search_object);
+
+    this.result_type = cgi.param("rt");
+    if (this.result_type)
+        dojo.byId("acq-unified-result-type").setValue(this.result_type);
+
+    this.conjunction = cgi.param("c");
+    if (this.conjunction)
+        dojo.byId("acq-unified-conjunction").setValue(this.conjunction);
+}
 
 /* onload */
 openils.Util.addOnLoad(
     function() {
         termManager = new TermManager();
-        termManager.addRow();
         resultManager = new ResultManager(
             new AcqLiTable(),
             dijit.byId("acq-unified-po-grid"),
             dijit.byId("acq-unified-pl-grid"),
             dijit.byId("acq-unified-inv-grid")
         );
+
         openils.Util.show("acq-unified-body");
+
+        uriManager = new URIManager();
+        if (uriManager.search_object) {
+            termManager.reflect(uriManager.search_object);
+            resultManager.search(uriManager.search_object);
+        } else {
+            termManager.addRow();
+        }
     }
 );
index e2d6b31..9caa041 100644 (file)
 
 <!ENTITY staff.main.menu.acq.label "Acquisitions">
 <!ENTITY staff.main.menu.acq.accesskey "A">
+<!ENTITY staff.main.menu.acq.create_invoice.label "New Invoice">
+<!ENTITY staff.main.menu.acq.create_invoice.accesskey "N">
 <!ENTITY staff.main.menu.acq.picklist.label "Selection Lists">
 <!ENTITY staff.main.menu.acq.picklist.accesskey "L">
 <!ENTITY staff.main.menu.acq.bib_search.label "Title Search">
index 67ae882..828c141 100644 (file)
@@ -1,4 +1,5 @@
 [% WRAPPER 'default/base.tt2' %]
+<script src="[% ctx.media_prefix %]/js/ui/default/acq/common/base64.js"> </script>
 <script src='[% ctx.media_prefix %]/js/ui/default/acq/po/view_po.js'> </script>
 <div dojoType="dijit.layout.ContentPane" style="height:100%">
     <div>
index bd63c18..6e8721f 100644 (file)
@@ -1,5 +1,7 @@
 [% WRAPPER "default/base.tt2" %]
 [% ctx.page_title = "Acquisitions Search" %]
+<script src="[% ctx.media_prefix %]/js/ui/default/acq/common/base64.js">
+</script>
 <script src="[% ctx.media_prefix %]/js/ui/default/acq/search/unified.js">
 </script>
 <script>
         </div>
         <div>
             <button
-                onclick="resultManager.search(termManager.buildSearchObject())">
+                onclick="resultManager.go(termManager.buildSearchObject())">
                 Search
             </button>
         </div>
index f7760bc..7f9a1fb 100644 (file)
@@ -703,6 +703,10 @@ main.menu.prototype = {
                 ['oncommand'],
                 function() { open_eg_web_page('conify/global/booking/resource_attr_map'); }
             ],
+            'cmd_acq_create_invoice' : [
+                ['oncommand'],
+                function() { open_eg_web_page('acq/invoice/view?create=1', 'menu.cmd_acq_create_invoice.tab'); }
+            ],
             'cmd_acq_view_picklist' : [
                 ['oncommand'],
                 function() { open_eg_web_page('acq/picklist/list', 'menu.cmd_acq_view_picklist.tab'); }
index 1099558..c8175f3 100644 (file)
@@ -77,6 +77,7 @@
     <command id="cmd_broken" disabled="true" />
     <command id="cmd_open_vandelay" />
     
+    <command id="cmd_acq_create_invoice" />
     <command id="cmd_acq_view_picklist" />
     <command id="cmd_acq_upload" />
     <command id="cmd_acq_view_po" />
         <menuitem label="&staff.main.menu.acq.po.label;" accesskey="&staff.main.menu.acq.po.accesskey;" command="cmd_acq_view_po" />
         <menuitem label="&staff.main.menu.acq.picklist.label;" accesskey="&staff.main.menu.acq.picklist.accesskey;" command="cmd_acq_view_picklist"/>
         <menuseparator />
+        <menuitem label="&staff.main.menu.acq.create_invoice.label;" accesskey="&staff.main.menu.acq.create_invoice.accesskey;" command="cmd_acq_create_invoice"/>
         <menuitem label="&staff.main.menu.acq.upload.label;" accesskey="&staff.main.menu.acq.upload.accesskey;" command="cmd_acq_upload"/>
         <menuitem label="&staff.main.menu.acq.brief_record.label;" accesskey="&staff.main.menu.acq.brief_record.accesskey;" command="cmd_acq_new_brief_record"/>
         <menuitem label="&staff.main.menu.acq.po_events.label;" accesskey="&staff.main.menu.acq.po_events.accesskey;" command="cmd_acq_view_po_events" />
index 5d364b5..0cf279d 100644 (file)
@@ -222,6 +222,7 @@ menu.cmd_local_admin_stat_cats.tab=Statistical Categories Editor
 menu.cmd_local_admin_reports.tab=Reports
 menu.cmd_local_admin_cash_reports.tab=Cash Reports
 menu.cmd_local_admin_transit_list.tab=Transits
+menu.cmd_acq_create_invoice.tab=New Invoice
 menu.cmd_acq_view_picklist.tab=Selection Lists
 menu.cmd_acq_bib_search.tab=Title Search
 menu.cmd_acq_unified_search.tab=Acquisitions Search