From 9d22b5982e1e8d93f9bb09d9f5cd45a341193f57 Mon Sep 17 00:00:00 2001 From: dbs Date: Tue, 5 Oct 2010 06:08:49 +0000 Subject: [PATCH] Backport MARC Editor user interface enhancements from trunk r16878 - Enable plain up-arrow and down-arrow to jump to next row in MARC editor 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. r16884 - Reclaim cataloguing real estate by hiding unnecessary rows in fixed field grid editor The fixed field grid editor currently shows blank rows for fixed field attributes that don't apply to the currently displayed MARC record type. We can hide these rows and offer more screen real estate for the MARC record proper. r16897 - Initial support for wrapping long subfields in the MARC editor Limitations of the current approach are that the line width is arbitrarily set to break at 100 characters, and is only calculated on a per-subfield basis. So if a given field contains 50 subfields, each with 90 characters, this commit isn't going to help you. (But really... in that scenario, you're beyond help anyway!) Also, the double-dagger aligns itself at the top of the box rather than the middle once the box goes into multiline mode, which is annoying; but long 505 fields that scroll ten screens to the right are more annoying, so I'll commit this for now rather than waste more time trying to CSS it into shape. r16903 - Refactor cursor up/down and wrap long fields using Dojo git-svn-id: svn://svn.open-ils.org/ILS/branches/rel_1_6@18164 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/xul/staff_client/server/cat/marcedit.js | 64 ++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/Open-ILS/xul/staff_client/server/cat/marcedit.js b/Open-ILS/xul/staff_client/server/cat/marcedit.js index 7adbaa38e2..c29af00fe2 100644 --- a/Open-ILS/xul/staff_client/server/cat/marcedit.js +++ b/Open-ILS/xul/staff_client/server/cat/marcedit.js @@ -78,6 +78,17 @@ function xml_escape_unicode ( str ) { ); } +function wrap_long_fields (node) { + var text_size = dojo.attr(node, 'size'); + var hard_width = 100; + if (text_size > hard_width) { + dojo.attr(node, 'multiline', 'true'); + dojo.attr(node, 'cols', hard_width); + var text_rows = (text_size / hard_width) + 1; + dojo.attr(node, 'rows', text_rows); + } +} + function my_init() { try { @@ -371,6 +382,31 @@ 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) { + var keep_looking = true; + while (keep_looking && (direction == 'up' ? row = row.previousSibling : row = row.nextSibling)) { + // Is it a datafield? + dojo.query('hbox hbox textbox', row).forEach(function(node, index, arr) { + node.focus(); + keep_looking = false; + }); + + // No, it's a control field; use the first textbox + if (keep_looking) { + dojo.query('textbox', row).forEach(function(node, index, arr) { + node.focus(); + keep_looking = false; + }); + } + } + + return true; +} + + function createMARCTextbox (element,attrs) { var box = createComplexXULElement('textbox', attrs, Array.prototype.slice.apply(arguments, [2]) ); @@ -507,6 +543,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 @@ -566,7 +610,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'); + } } }; @@ -1103,6 +1155,16 @@ function toggleFFE () { function changeFFEditor (type) { var grid = document.getElementById('leaderGrid'); grid.setAttribute('type',type); + + // Hide FFEditor rows that we don't need for our current type + // If all of the labels for a given row do not include our + // desired type in their set attribute, we can hide that row + dojo.query('rows row', grid).forEach(function(node, index, arr) { + if (dojo.query('label[set~=' + type + ']', node).length == 0) { + node.hidden = true; + } + }); + } function fillFixedFields (rec) { @@ -1419,6 +1481,8 @@ function marcDatafield (field) { marcSubfield(sf) ); + dojo.query('.marcSubfield', sf_box).forEach(wrap_long_fields); + if (sf.@code == '' && (!current_focus || current_focus.className.match(/Ind/))) current_focus = sf_box.lastChild.childNodes[1]; } -- 2.11.0