Enable plain up-arrow and down-arrow to jump to next row in MARC editor
authordbs <dbs@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 8 Jul 2010 14:15:04 +0000 (14:15 +0000)
committerdbs <dbs@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 8 Jul 2010 14:15:04 +0000 (14:15 +0000)
As TAB/shift-TAB move between each editable element of the MARC record,
we already have fine-grained keyboard navigation. However, moving down
10 data fields requires around 50 TAB presses or more, depending on how
many subfields are in the intervening data fields, or a looonng hold of
the tab key; not good for RSI.

The up-arrow and down-arrow keys, then, move directly to the next or
previous row, placing the focus in the first editable subfield element
rather than in the tag name (under the assumption that cataloguers are
most likely to want to edit the contents of a given subfield, and not
the tag name or indicators).

Now, in the worst-case scenario, a cataloguer who wants to edit the tag
name of a field 10 rows below their current position will have to
make 14 key presses (10 down arrows, 4 shift-TABs). Not too shabby.

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

Open-ILS/xul/staff_client/server/cat/marcedit.js

index 15441cb..673ad55 100644 (file)
@@ -339,6 +339,43 @@ function createCheckbox (attrs) {
     return createComplexXULElement('checkbox', attrs, Array.prototype.slice.apply(arguments, [1]) );
 }
 
+// Find the next textbox that we can use for a focus point
+// For control fields, use the first editable text box
+// For data fields, focus on the first subfield text box
+function setFocusToNextTag (row, direction) {
+    while (direction == 'up' ? row = row.previousSibling : row = row.nextSibling) {
+        var children = row.childNodes;
+        for (var i = 0; i <  children.length; i++) {
+                       // This would be way cleaner with dojo.query()
+            if (row.className  == 'marcDatafieldRow') {
+                // marcSubfield lives in hbox.hbox.textbox
+                var hboxKids = children[i].childNodes;
+                if (children[i].tagName == 'hbox') {
+                    for (var j = 0; j < hboxKids.length; j++) {
+                        var msfBoxKids = hboxKids[j].childNodes;
+                        if (hboxKids[j].className == 'marcSubfieldBox') {
+                            for (var k = 0; k < msfBoxKids.length; k++) {
+                                if (msfBoxKids[k].className == 'plain marcSubfield') {
+                                        msfBoxKids[k].focus();
+                                        return false;
+                                }
+                            }
+
+                        }
+                    }
+                }
+            } else {
+                if (children[i].tagName == 'textbox') {
+                    children[i].focus();
+                    return false;
+                }
+            }
+        }
+    }
+    return true;
+}
+
+
 function createMARCTextbox (element,attrs) {
 
     var box = createComplexXULElement('textbox', attrs, Array.prototype.slice.apply(arguments, [2]) );
@@ -475,6 +512,14 @@ function createMARCTextbox (element,attrs) {
                     event.preventDefault();
 
                     return false;
+                } else {
+                    if (event.keyCode == 38) {
+                        return setFocusToNextTag(row, 'up');
+                    }
+                    if (event.keyCode == 40) {
+                        return setFocusToNextTag(row, 'down');
+                    }
+                    return false;
                 }
 
             } else if (event.keyCode == 46 && event.ctrlKey) { // ctrl+del
@@ -534,7 +579,15 @@ function createMARCTextbox (element,attrs) {
                 createControlField('008','                                        ');
                 loadRecord(xml_record);
             }
+
             return true;
+
+        } else { // event on a control field
+            if (event.keyCode == 38) { 
+                return setFocusToNextTag(row, 'up'); 
+            } else if (event.keyCode == 40) { 
+                return setFocusToNextTag(row, 'down');
+            }
         }
     };