--- /dev/null
+[% WRAPPER base.tt2 %]
+<style type="text/css">
+ h1 { margin-bottom: 0.5ex; }
+ .body-part { margin: 1ex 0; }
+ .clear-both { clear: both; }
+ #cbho-field-order-space > div { float: left; }
+ .show-access-key { font-weight: bold; border-bottom: 1px dashed black; }
+ #cbho-name { width: 30em; }
+ #cbho-loading { text-align: center; }
+ select { width: 30em; }
+ #cbho-field-order option.post-rtime { color: #ccc; }
+ .needs-saved { background-color: #f96; }
+</style>
+<h1>[% l('Best-Hold Selection Sort Order') %]</h1>
+
+<!-- Hidden after JS load. Prevents early clicks from breaking anything. -->
+<div id="cbho-loading">
+ <img src="[% ctx.media_prefix %]/opac/images/progressbar_green-old.gif"
+ alt="[% l('Interface loading') %]" />
+ <!-- <audio src="knight rider theme ;)" /> -->
+</div>
+
+<div id="cbho-main-body" class="hidden"><!-- main body -->
+ <div class="body-part">
+ <span dojoType="dijit.form.Button" onClick="module.new_cbho()">[% l('Create New') %]</span>
+ [% l('or') %]
+ <span dojoType="dijit.form.Button" onClick="module.edit_cbho()">[% l('Edit Existing') %]</span>
+ </div>
+
+ <div class="body-part hidden" id="cbho-edit-space"><!-- editing space -->
+ <p id="cbho-editing"></p>
+ <div id="cbho-name-edit-space">
+ [% l('Name:') %]
+ <input id="cbho-name" type="text" onchange="module.editor_changed(true);" />
+ </div>
+ <div id="cbho-field-order-space" class="body-part">
+ <div>
+ [% l('Order:') %]
+ </div>
+ <div>
+ <select id="cbho-field-order" size="10"> </select>
+ </div>
+ <div>
+ <button onclick="module.editor_move(-1); return false;"
+ accesskey="[% l('k') %]">
+ ↑ [% l('Move Up') %]
+ </button>
+ <span class="show-access-key">[% l('k') %]</span>
+ <br />
+ <button onclick="module.editor_move(1); return false;"
+ accesskey="[% l('j') %]">
+ ↓ [% l('Move Down') %]
+ </button>
+ <span class="show-access-key">[% l('j') %]</span>
+ </div>
+ </div>
+
+ <div class="clear-both"></div>
+
+ <div class="body-part"><!-- save changes -->
+ <p><em>[% l('Because rtime, a high-precision timestamp, is ' _
+ 'essentially unique among holds, ' _
+ 'no fields arranged after rtime really have any effect in ' _
+ 'determining best-hold selection.') %]</em></p>
+
+ <button id="cbho-save-changes"
+ onclick="module.editor_save(); return false" disabled="disabled">
+ [% l('Save Changes') %]
+ </button>
+ </div><!-- save changes -->
+ </div><!-- editing space -->
+
+</div><!-- main body -->
+
+<script type="text/javascript">
+ dojo.require("dijit.form.Button");
+ dojo.require("dijit.form.TextBox");
+ dojo.require("openils.conify.BestHoldOrder");
+
+ var module; /* single point of pollution of global namespace */
+
+ openils.Util.addOnLoad(
+ function() {
+ module = openils.conify.BestHoldOrder;
+ module.init();
+ }
+ );
+</script>
+[% END %]
--- /dev/null
+if (!dojo._hasResource["openils.conify.BestHoldOrder"]) {
+ dojo.requireLocalization("openils.conify", "conify");
+
+ dojo._hasResource["openils.conify.BestHoldOrder"] = true;
+ dojo.provide("openils.conify.BestHoldOrder");
+ dojo.provide("openils.conify.SetOrderer");
+
+ dojo.require("dojo.string");
+ dojo.require("openils.Util");
+
+(function() {
+ var localeStrings =
+ dojo.i18n.getLocalization("openils.conify", "conify");
+
+ /* This helper module is OO. */
+ dojo.declare(
+ "openils.conify.SetOrderer", null, {
+ "constructor": function(select, field_map, format_string) {
+ this.select = select; /* HTML <select> node */
+ this.field_map = field_map; /* object of id:label pairs */
+ this.format_string = format_string || "[${0}] ${1}";
+ },
+
+ "clear": function() {
+ dojo.forEach(
+ this.select.options,
+ dojo.hitch(
+ this, function(o) { this.select.options.remove(o); }
+ )
+ );
+ },
+
+ /* This trusts that what you are passing is actually a set (no
+ * repeats). */
+ "set": function(
+ set, pos_callback /* called for each set member's <option>
+ node now and at any position change */
+ ) {
+ this.clear();
+ this.pos_callback = pos_callback;
+ dojo.forEach(
+ set, dojo.hitch(this, function(o, p) { this.add(o, p); })
+ );
+ },
+
+ /* For now this trusts that your item is in the field_map */
+ "add": function(item, position) {
+ var option = dojo.create(
+ "option", {
+ "value": item,
+ "innerHTML": dojo.string.substitute(
+ this.format_string, [item, this.field_map[item]]
+ )
+ }
+ );
+
+ this.select.options.add(option);
+ if (this.pos_callback)
+ this.pos_callback(option, position);
+ },
+
+ /* Returns option values in order, as a set, assuming you didn't
+ * add dupes. */
+ "get": function() {
+ /* XXX Could probably use dojo.forEach() here, but don't have
+ * time to check whether it's sure to preserve order
+ * with pseudo-arrays or NodeLists or whatever this is. */
+ var list = [];
+ for (var i = 0; i < this.select.options.length; i++)
+ list.push(this.select.options[i].value);
+
+ return list;
+ },
+
+ "move_selected": function(offset) {
+ var si = this.select.selectedIndex;
+ var opt = this.select.options[si];
+ var len = this.select.options.length;
+ var newpos = si + offset;
+
+ if (newpos >= 0 && newpos < len) {
+ this.select.options.remove(opt);
+ this.select.options.add(opt, newpos);
+
+ if (this.pos_callback)
+ for (var i = 0; i < len; i++)
+ this.pos_callback(this.select.options[i], i);
+
+ return true;
+ } else {
+ return false;
+ }
+ },
+ }
+ );
+
+ /* This module is *not* OO. */
+ dojo.declare("openils.conify.BestHoldOrder", null, {});
+
+ var module = openils.conify.BestHoldOrder;
+
+ /* We could get these from the IDL, but if we add more fields to that
+ * later, we have no particular mechanism for determining what is or
+ * isn't metadata. */
+ module.fields = ["pprox", "hprox", "aprox", "priority", "cut", "depth",
+ "htime", "rtime", "approx", "shtime"];
+
+ module.init = function() {
+ module.field_labels = {};
+ dojo.forEach(
+ module.fields, function(f) {
+ module.field_labels[f] = fieldmapper.IDL.fmclasses.cbho.
+ field_map[f].label
+ }
+ );
+
+ module.set_orderer = new openils.conify.SetOrderer(
+ dojo.byId("cbho-field-order"),
+ module.field_labels,
+ localeStrings.CBHO_FIELD_DISPLAY
+ );
+
+ openils.Util.hide("cbho-loading");
+ openils.Util.show("cbho-main-body");
+ };
+
+ module.new_cbho = function() {
+ module.cbho = new fieldmapper.cbho();
+
+ module.editor_start();
+ };
+
+ module.edit_cbho = function() {
+ };
+
+ module.editor_start = function() {
+ /* XXX make following conditional on new vs edit */
+ dojo.byId("cbho-editing").innerHTML = localeStrings.CBHO_EDITING_NEW;
+
+ dojo.attr(dojo.byId("cbho-name"), "value", module.cbho.name() || "");
+ module.editor_reset_order();
+
+ openils.Util.show("cbho-edit-space");
+ module.editor_changed(false);
+ };
+
+ /* Used to set all <option> nodes in the set_orderer to appear disabled if
+ * they now come after rtime. */
+ module.set_pos_callback = function(opt_node, pos) {
+ var method = module.rtime_reached ? "addClass" : "removeClass";
+ dojo[method](opt_node, "post-rtime");
+
+ if (opt_node.value == "rtime")
+ module.rtime_reached = true;
+ };
+
+ module.editor_reset_order = function() {
+ module.rtime_reached = false;
+ module.set_orderer.set(module.fields, module.set_pos_callback);
+ };
+
+ module.editor_move = function(offset) {
+ module.rtime_reached = false;
+ if (module.set_orderer.move_selected(offset))
+ module.editor_changed(true);
+
+ /* Without this, focus is now on the up or down button, breaking
+ * the user's ability to select other rows with the arrow keys. */
+ dojo.byId("cbho-field-order").focus();
+ };
+
+ module.editor_changed = function(yes) {
+ dojo.attr("cbho-save-changes", "disabled", !yes);
+ dojo[yes ? "addClass" : "removeClass"]("cbho-edit-space","needs-saved");
+ };
+
+ module.editor_save = function() {
+ module.editor_changed(false);
+ };
+
+})();
+
+}