From ca8d7678a5ef020f416c2316710fa367489d96aa Mon Sep 17 00:00:00 2001 From: senator Date: Thu, 8 Apr 2010 20:58:50 +0000 Subject: [PATCH] Acq: you can now back up to old search results 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 | 15 +++ Open-ILS/web/js/ui/default/acq/po/view_po.js | 7 ++ Open-ILS/web/js/ui/default/acq/search/unified.js | 117 +++++++++++++++++++-- Open-ILS/web/opac/locale/en-US/lang.dtd | 2 + Open-ILS/web/templates/default/acq/po/view.tt2 | 1 + .../web/templates/default/acq/search/unified.tt2 | 4 +- .../xul/staff_client/chrome/content/main/menu.js | 4 + .../chrome/content/main/menu_frame_menus.xul | 2 + .../chrome/locale/en-US/offline.properties | 1 + 9 files changed, 142 insertions(+), 11 deletions(-) create mode 100644 Open-ILS/web/js/ui/default/acq/common/base64.js 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 index 0000000000..6d62cc7d0f --- /dev/null +++ b/Open-ILS/web/js/ui/default/acq/common/base64.js @@ -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("") + ); +} diff --git a/Open-ILS/web/js/ui/default/acq/po/view_po.js b/Open-ILS/web/js/ui/default/acq/po/view_po.js index f4c886fe56..dbf27902a3 100644 --- a/Open-ILS/web/js/ui/default/acq/po/view_po.js +++ b/Open-ILS/web/js/ui/default/acq/po/view_po.js @@ -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"; + }; } diff --git a/Open-ILS/web/js/ui/default/acq/search/unified.js b/Open-ILS/web/js/ui/default/acq/search/unified.js index 52542b4b4f..0a856467ad 100644 --- a/Open-ILS/web/js/ui/default/acq/search/unified.js +++ b/Open-ILS/web/js/ui/default/acq/search/unified.js @@ -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 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(); + } } ); diff --git a/Open-ILS/web/opac/locale/en-US/lang.dtd b/Open-ILS/web/opac/locale/en-US/lang.dtd index e2d6b31179..9caa0414f8 100644 --- a/Open-ILS/web/opac/locale/en-US/lang.dtd +++ b/Open-ILS/web/opac/locale/en-US/lang.dtd @@ -783,6 +783,8 @@ + + diff --git a/Open-ILS/web/templates/default/acq/po/view.tt2 b/Open-ILS/web/templates/default/acq/po/view.tt2 index 67ae8827bf..828c14168d 100644 --- a/Open-ILS/web/templates/default/acq/po/view.tt2 +++ b/Open-ILS/web/templates/default/acq/po/view.tt2 @@ -1,4 +1,5 @@ [% WRAPPER 'default/base.tt2' %] +
diff --git a/Open-ILS/web/templates/default/acq/search/unified.tt2 b/Open-ILS/web/templates/default/acq/search/unified.tt2 index bd63c18b18..6e8721f90f 100644 --- a/Open-ILS/web/templates/default/acq/search/unified.tt2 +++ b/Open-ILS/web/templates/default/acq/search/unified.tt2 @@ -1,5 +1,7 @@ [% WRAPPER "default/base.tt2" %] [% ctx.page_title = "Acquisitions Search" %] +