From 9b580dcbe3dd9760e79dbe59660cea4c8fbff6c1 Mon Sep 17 00:00:00 2001 From: Jesse Weaver Date: Tue, 8 Apr 2014 17:42:01 -0600 Subject: [PATCH] Bug 11559 followup - Add support for XML-based fixed field widgets --- .../intranet-tmpl/lib/koha/cateditor/resources.js | 27 +++ .../intranet-tmpl/lib/koha/cateditor/widget.js | 183 +++++++++++++++++---- koha-tmpl/intranet-tmpl/prog/en/css/cateditor.css | 20 ++- .../prog/en/includes/cateditor-ui.inc | 43 ++--- .../prog/en/includes/cateditor-widgets-marc21.inc | 23 +-- 5 files changed, 231 insertions(+), 65 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/lib/koha/cateditor/resources.js diff --git a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/resources.js b/koha-tmpl/intranet-tmpl/lib/koha/cateditor/resources.js new file mode 100644 index 0000000..365f03d --- /dev/null +++ b/koha-tmpl/intranet-tmpl/lib/koha/cateditor/resources.js @@ -0,0 +1,27 @@ +define( [ 'module', 'xslt' ], function( module, XSLT ) { + var _allResources = []; + + var Resources = { + GetAll: function() { + return $.when.call( null, _allResources ); + } + }; + + function _res( name, deferred ) { + Resources[name] = deferred; + _allResources.push(deferred); + } + + $.each( module.config().xslt_result_stylesheets, function( syntax, url ) { + _res( 'xslt/result/' + syntax, XSLT.Get( url ) ); + } ); + + $.each( module.config().xslt_detail_stylesheets, function( syntax, url ) { + _res( 'xslt/detail/' + syntax, XSLT.Get( url ) ); + } ); + + _res( 'marc21/xml/006', $.get( module.config().themelang + '/data/marc21_field_006.xml' ) ); + _res( 'marc21/xml/008', $.get( module.config().themelang + '/data/marc21_field_008.xml' ) ); + + return Resources; +} ); diff --git a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/widget.js b/koha-tmpl/intranet-tmpl/lib/koha/cateditor/widget.js index 93f53e4..5e7bb48 100644 --- a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/widget.js +++ b/koha-tmpl/intranet-tmpl/lib/koha/cateditor/widget.js @@ -1,5 +1,32 @@ -define( function() { +define( [ 'resources' ], function( Resources ) { + var _widgets = {}; + var Widget = { + Register: function( tagfield, widget ) { + _widgets[tagfield] = widget; + }, + + PadNum: function( number, length ) { + var result = number.toString(); + + while ( result.length < length ) result = '0' + result; + + return result; + }, + + PadString: function( result, length ) { + while ( result.length < length ) result = ' ' + result; + + return result; + }, + + PadStringRight: function( result, length ) { + result = '' + result; + while ( result.length < length ) result += ' '; + + return result; + }, + Base: { // Marker utils clearToText: function() { @@ -17,9 +44,28 @@ define( function() { var $node = $( this.node ).find( sel ); $node.val( this.getFixed( start, end ) ); - $node.change( $.proxy( function() { - this.setFixed( start, end, $node.val(), '+input' ); - }, this ) ); + var widget = this; + var $collapsed = $( '' + $node.val() + '' ).insertAfter( $node ); + + function show() { + $collapsed.hide(); + $node.val( widget.getFixed( start, end ).replace(/\s+$/, '') ); + $node.show(); + $node[0].focus(); + } + + function hide() { + $node.hide(); + $collapsed.text( Widget.PadStringRight( $node.val(), end - start ) ).show(); + } + + $node.on( 'change keyup', function() { + widget.setFixed( start, end, $node.val(), '+input' ); + } ).focus( show ).blur( hide ); + + hide(); + + $collapsed.click( show ); }, getFixed: function( start, end ) { @@ -27,7 +73,7 @@ define( function() { }, setFixed: function( start, end, value, source ) { - this.setText( this.text.substring( 0, start ) + this.padString( value.toString().substr( 0, end - start ), end - start ) + this.text.substring( end ), source ); + this.setText( this.text.substring( 0, start ) + Widget.PadStringRight( value.toString().substr( 0, end - start ), end - start ) + this.text.substring( end ), source ); }, setText: function( text, source ) { @@ -36,6 +82,102 @@ define( function() { this.editor.startNotify(); }, + createFromXML: function( resourceId ) { + var widget = this; + + Resources[resourceId].done( function( xml ) { + $(widget.node).find('.widget-loading').remove(); + var $matSelect = $('').appendTo(widget.node); + var $contents = $('').appendTo(widget.node); + var materialInfo = {}; + + $('Tagfield', xml).children('Material').each( function() { + $matSelect.append( '' ); + + materialInfo[ $(this).attr('id') ] = this; + } ); + + $matSelect.change( function() { + widget.loadXMLMaterial( materialInfo[ $matSelect.val() ] ); + } ).change(); + } ); + }, + + loadXMLMaterial: function( materialInfo ) { + var $contents = $(this.node).children('.material-contents'); + $contents.empty(); + + var widget = this; + + $(materialInfo).children('Position').each( function() { + var match = $(this).attr('pos').match(/(\d+)(?:-(\d+))?/); + if (!match) return; + + var start = parseInt(match[1]); + var end = ( match[2] ? parseInt(match[2]) : start ) + 1; + var $input; + var $values = $(this).children('Value'); + + if ($values.length == 0) { + $contents.append( '' + widget.getFixed(start, end) + '' ); + return; + } + + if ( match[2] ) { + $input = $( '' ); + } else { + $input = $( '' ); + + $values.each( function() { + $input.append( '' ); + } ); + } + + $contents.append( $input ); + widget.bindFixed( $input, start, end ); + } ); + }, + + nodeChanged: function() { + this.mark.changed(); + var widget = this; + + var $inputs = $(this.node).find('input, select'); + if ( !$inputs.length ) return; + + $inputs.off('keydown.marc-tab'); + var editor = widget.editor; + + $inputs.each( function( i ) { + $(this).on( 'keydown.marc-tab', function( e ) { + if ( e.which != 9 ) return; // Tab + + var span = widget.mark.find(); + var cur = editor.cm.getCursor(); + + if ( e.shiftKey ) { + if ( i > 0 ) { + $inputs.eq(i - 1).trigger( 'focus' ); + } else { + editor.cm.setCursor( span.from ); + // FIXME: ugly hack + editor.cm.options.extraKeys['Shift-Tab']( editor.cm ); + editor.focus(); + } + } else { + if ( i < $inputs.length - 1 ) { + $inputs.eq(i + 1).trigger( 'focus' ); + } else { + editor.cm.setCursor( span.to ); + editor.focus(); + } + } + + return false; + } ); + } ); + }, + // Template utils insertTemplate: function( sel ) { var wsOnly = /^\s*$/; @@ -45,20 +187,6 @@ define( function() { } } ).appendTo( this.node ); }, - - padNum: function( number, length ) { - var result = number.toString(); - - while ( result.length < length ) result = '0' + result; - - return result; - }, - - padString: function( result, length ) { - while ( result.length < length ) result = ' ' + result; - - return result; - } }, ActivateAt: function( editor, cur, idx ) { @@ -119,8 +247,8 @@ define( function() { } } - if ( !editorWidgets[id] ) return; - var fullBase = $.extend( Object.create( Widget.Base ), editorWidgets[id] ); + if ( !_widgets[id] ) return; + var fullBase = $.extend( Object.create( Widget.Base ), _widgets[id] ); var widget = Object.create( fullBase ); if ( subfield.from == subfield.to ) { @@ -148,20 +276,9 @@ define( function() { if ( widget.postCreate ) { widget.postCreate(); - mark.changed(); } - var $lastInput = $(widget.node).find('input, select').eq(-1); - if ( $lastInput.length ) { - $lastInput.bind( 'keypress', 'tab', function() { - var cur = editor.cm.getCursor(); - editor.cm.setCursor( { line: cur.line } ); - // FIXME: ugly hack - editor.cm.options.extraKeys.Tab( editor.cm ); - editor.focus(); - return false; - } ); - } + widget.nodeChanged(); } ); }, }; diff --git a/koha-tmpl/intranet-tmpl/prog/en/css/cateditor.css b/koha-tmpl/intranet-tmpl/prog/en/css/cateditor.css index d046385..8dd7c06 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/css/cateditor.css +++ b/koha-tmpl/intranet-tmpl/prog/en/css/cateditor.css @@ -118,19 +118,35 @@ body { padding: 4px; } -#editor .subfield-widget select { +#editor .subfield-widget select, #editor .subfield-widget input { height: 1.5em; vertical-align: middle; } #editor .subfield-widget select:focus { - outline: 1px #83A230 solid; + outline: 2px #83A230 solid; +} + +#editor .fixed-widget input { + width: 4em; } #editor .fixed-widget select { width: 3em; } +#editor .fixed-widget .material-select { + width: 4.5em; + margin-right: .5em; +} + +#editor .fixed-collapsed { + display: inline-block; + margin: 0 .25em; + text-align: center; + text-decoration: underline; +} + #editor .hidden-widget { color: #999999; border: solid 2px #AAAAAA; diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc index 15bb328..ba2813b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc @@ -5,6 +5,21 @@ -- 1.9.0