/* * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at * * http://www.dspace.org/license/ */ // Client-side scripting to support DSpace Choice Control // IMPORTANT NOTE: // This code depends on a *MODIFIED* version of the // script.aculo.us controls v1.8.2, fixed to avoid a bug that // affects autocomplete in Firefox 3. This code is included in DSpace. // Entry points: // 1. DSpaceAutocomplete -- add autocomplete (suggest) to an input field // // 2. DSpaceChoiceLookup -- create popup window with authority choices // // @Author: Larry Stone // $Revision $ // -------------------- support for Autocomplete (Suggest) // Autocomplete utility: // Arguments: // formID -- ID attribute of form tag // args properties: // metadataField -- metadata field e.g. dc_contributor_author // inputName -- input field name for text input, or base of "Name" pair // authorityName -- input field name in which to set authority // containerID -- ID attribute of DIV to hold the menu objects // indicatorID -- ID attribute of element to use as a "loading" indicator // confidenceIndicatorID -- ID of element on which to set confidence // confidenceName - NAME of confidence input (not ID) // contextPath -- URL path prefix (i.e. webapp contextPath) for DSpace. // collection -- db ID of dspace collection to serve as context // isClosed -- true if authority value is required, false = non-auth allowed // XXX Can't really enforce "isClosed=true" with autocomplete, user can type anything // // NOTE: Successful autocomplete always sets confidence to 'accepted' since // authority value (if any) *was* chosen interactively by a human. function DSpaceSetupAutocomplete(formID, args) { if (args.authorityName == null) args.authorityName = dspace_makeFieldInput(args.inputName,'_authority'); var authInput = jQuery('#'+formID + ' input[name=\''+args.authorityName+'\']'); var input = jQuery('#'+formID + ' input[name=\''+args.inputName+'\']'); input.parent('td').attr('style','white-space:nowrap;'); // AJAX menu source, can add &query=TEXT var choiceURL = args.contextPath+"/choices/"+args.metadataField; var collID = args.collection == null ? -1 : args.collection; if (authInput != null) { input.data('previousData', {authority: authInput.val(), value: input.val()}); } var options = { lenght: 2, search: function(event, ui) { jQuery('#'+args.indicatorID).show(); }, source: function( request, response ) { jQuery.ajax({ url: choiceURL, dataType: "xml", data: { query: request.term, collection: collID, format: 'ul' }, success: function( data ) { jQuery('#'+args.indicatorID).hide(); response(jQuery("li", data ).map(function() { return { authority : jQuery(this).attr('authority'), label : jQuery('span.label',this).text(), value : jQuery('span.value',this).text() }; })); } }); }, select: function(event, ui){ input.data('previousData', ui.item); var authority = ui.item.authority; var authValue = authority; if (authInput != null) { authInput.val(authValue); // update confidence input's value too if available. if (args.confidenceName != null) { var confInput = jQuery('#'+formID + ' input[name=\''+args.confidenceName+'\']'); if (confInput != null) { if (authority != '') { confInput.val('accepted'); } else { confInput.val(''); } } } } // make indicator blank if no authority value DSpaceUpdateConfidence(document, args.confidenceIndicatorID, authValue == null || authValue == '' ? 'blank' :'accepted'); } }; input.autocomplete(options).change(function(){ var lastSel = input.data('previousData'); var newauth = ''; var newval = input.val(); if (authInput != null) { newauth = authInput.val(); } if (newauth != lastSel.authority || newval != lastSel.value) { if (authInput != null) { authInput.val(' '); DSpaceUpdateConfidence(document, args.confidenceIndicatorID, 'blank'); } } }); } // -------------------- support for Lookup Popup // Create popup window with authority choices for value of an input field. // This is intended to be called by onClick of a "Lookup" or "Add" button. function DSpaceChoiceLookup(url, field, formID, valueInput, authInput, confIndicatorID, collectionID, isName, isRepeating) { // fill in URL url += '?field='+field+'&formID='+formID+'&valueInput='+valueInput+ '&authorityInput='+authInput+'&collection='+collectionID+ '&isName='+isName+'&isRepeating='+isRepeating+'&confIndicatorID='+confIndicatorID; // primary input field - for positioning popup. var inputFieldName = isName ? dspace_makeFieldInput(valueInput,'_last') : valueInput; var inputField = document.getElementById(formID).elements[inputFieldName]; // scriptactulous magic to figure out true offset: var cOffset = 0; if (inputField != null) cOffset = $(inputField).cumulativeOffset(); var width = 600; // XXX guesses! these should be params, or configured.. var height = 470; var left; var top; if (window.screenX == null) { left = window.screenLeft + cOffset.left - (width/2); top = window.screenTop + cOffset.top - (height/2); } else { left = window.screenX + cOffset.left - (width/2); top = window.screenY + cOffset.top - (height/2); } if (left < 0) left = 0; if (top < 0) top = 0; var pw = window.open(url, 'ignoreme', 'width='+width+',height='+height+',left='+left+',top='+top+ ',toolbar=no,menubar=no,location=no,status=no,resizable'); if (window.focus) pw.focus(); return false; } // Run this as the Lookup page is loaded to initialize DOM objects, load choices function DSpaceChoicesSetup(form) { // find the "LEGEND" in fieldset, which acts as page title, // and save it as a bogus form element, e.g. elements['statline'] var fieldset = document.getElementById('aspect_general_ChoiceLookupTransformer_list_choicesList'); for (i = 0; i < fieldset.childNodes.length; ++i) { if (fieldset.childNodes[i].nodeName == 'LEGEND') { form.statline = fieldset.childNodes[i]; form.statline_template = fieldset.childNodes[i].innerHTML; fieldset.childNodes[i].innerHTML = "Loading..."; break; } } DSpaceChoicesLoad(form); } // populate the "select" with options from ajax request // stash some parameters as properties of the "select" so we can add to // the last start index to query for next set of results. function DSpaceChoicesLoad(form) { var field = form.elements['paramField'].value; var value = form.elements['paramValue'].value; var start = form.elements['paramStart'].value; var limit = form.elements['paramLimit'].value; var formID = form.elements['paramFormID'].value; var collID = form.elements['paramCollection'].value; var isName = form.elements['paramIsName'].value == 'true'; var isRepeating = form.elements['paramIsRepeating'].value == 'true'; var isClosed = form.elements['paramIsClosed'].value == 'true'; var contextPath = form.elements['contextPath'].value; var fail = form.elements['paramFail'].value; var valueInput = form.elements['paramValueInput'].value; var nonAuthority = ""; if (form.elements['paramNonAuthority'] != null) nonAuthority = form.elements['paramNonAuthority'].value; // get value from form inputs in opener if not explicitly supplied if (value.length == 0) { var of = window.opener.document.getElementById(formID); if (isName) value = makePersonName(of.elements[dspace_makeFieldInput(valueInput,'_last')].value, of.elements[dspace_makeFieldInput(valueInput,'_first')].value); else value = of.elements[valueInput].value; // if this is a repeating input, clear the source value so that e.g. // clicking "Next" on a submit-describe page will not *add* the proposed // lookup text as a metadata value: if (isRepeating) { if (isName) { of.elements[dspace_makeFieldInput(valueInput,'_last')].value = null; of.elements[dspace_makeFieldInput(valueInput,'_first')].value = null; } else of.elements[valueInput].value = null; } } // start spinner var indicator = document.getElementById('lookup_indicator_id'); if (indicator != null) indicator.style.display = "inline"; new Ajax.Request(contextPath+"/choices/"+field, { method: "get", parameters: {query: value, format: 'select', collection: collID, start: start, limit: limit}, // triggered by any exception, even in success onException: function(req, e) { window.alert(fail+" Exception="+e); if (indicator != null) indicator.style.display = "none"; }, // when http load of choices fails onFailure: function() { window.alert(fail+" HTTP error resonse"); if (indicator != null) indicator.style.display = "none"; }, // format is