From ec077b8bb56e5271351bb3dae65e3ca10cfc0899 Mon Sep 17 00:00:00 2001 From: rjy7 Date: Wed, 25 Aug 2010 18:27:46 +0000 Subject: [PATCH] NIHVIVO-803 Moved new implementation of author reordering into main files and removed temporary files. --- .../forms/addAuthorsToInformationResource.jsp | 68 +- .../addAuthorsToInformationResource1.jsp | 430 ------------- .../js/addAuthorsToInformationResource.js | 226 +++---- .../js/addAuthorsToInformationResource1.js | 606 ------------------ 4 files changed, 102 insertions(+), 1228 deletions(-) delete mode 100644 productMods/edit/forms/addAuthorsToInformationResource1.jsp delete mode 100644 productMods/edit/forms/js/addAuthorsToInformationResource1.js diff --git a/productMods/edit/forms/addAuthorsToInformationResource.jsp b/productMods/edit/forms/addAuthorsToInformationResource.jsp index b67b4f16..2e99de93 100644 --- a/productMods/edit/forms/addAuthorsToInformationResource.jsp +++ b/productMods/edit/forms/addAuthorsToInformationResource.jsp @@ -300,8 +300,8 @@ SPARQL queries for existing values. --%> @@ -399,7 +388,6 @@ SPARQL queries for existing values. --%>

This publication currently has no authors specified.

<% } %> -
@@ -421,7 +409,6 @@ SPARQL queries for existing values. --%> -

* required fields

@@ -429,14 +416,13 @@ SPARQL queries for existing values. --%> - + diff --git a/productMods/edit/forms/addAuthorsToInformationResource1.jsp b/productMods/edit/forms/addAuthorsToInformationResource1.jsp deleted file mode 100644 index 5939d5d4..00000000 --- a/productMods/edit/forms/addAuthorsToInformationResource1.jsp +++ /dev/null @@ -1,430 +0,0 @@ -<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%> - -<%-- Custom form for adding authors to information resources - -Classes: -core:InformationResource - the information resource being edited -core:Authorship - primary new individual being created -foaf:Person - new or existing individual being linked to - -Data properties of Authorship: -core:authorRank - -Object properties (domain : range): - -core:informationResourceInAuthorship (InformationResource : Authorship) -core:linkedInformationResource (Authorship : InformationResource) - inverse of informationResourceInAuthorship - -core:linkedAuthor (Authorship : Person) -core:authorInAuthorship (Person : Authorship) - inverse of linkedAuthor - ---%> - -<%@ page import="java.util.List" %> -<%@ page import="java.util.ArrayList" %> -<%@ page import="java.util.Arrays" %> -<%@ page import="java.util.Collections" %> - -<%@ page import="com.hp.hpl.jena.rdf.model.Model" %> -<%@ page import="com.hp.hpl.jena.vocabulary.XSD" %> - -<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.Individual" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.DataPropertyComparator" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditConfiguration" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.edit.n3editing.PublicationHasAuthorValidator" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.controller.VitroRequest" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.web.MiscWebUtils" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.utils.StringUtils" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.JavaScript" %> -<%@ page import="edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Css" %> - -<%@ page import="org.json.JSONObject" %> -<%@ page import="org.apache.commons.logging.Log" %> -<%@ page import="org.apache.commons.logging.LogFactory" %> - -<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%> -<%@ taglib prefix="v" uri="http://vitro.mannlib.cornell.edu/vitro/tags" %> - -<%! - public static Log log = LogFactory.getLog("edu.cornell.mannlib.vitro.webapp.jsp.edit.forms.addAuthorsToInformationResource.jsp"); -%> -<% - VitroRequest vreq = new VitroRequest(request); - WebappDaoFactory wdf = vreq.getWebappDaoFactory(); - vreq.setAttribute("defaultNamespace", ""); //empty string triggers default new URI behavior - - vreq.setAttribute("stringDatatypeUriJson", MiscWebUtils.escape(XSD.xstring.toString())); - - String intDatatypeUri = XSD.xint.toString(); - vreq.setAttribute("intDatatypeUri", intDatatypeUri); - vreq.setAttribute("intDatatypeUriJson", MiscWebUtils.escape(intDatatypeUri)); -%> - - - - - - - -<%-- Unlike other custom forms, this form does not allow edits of existing authors, so there are no -SPARQL queries for existing values. --%> - -<%-- Data properties --%> - - - @prefix foaf: <${foaf}> . - ?newPerson foaf:firstName ?firstName . - - - - @prefix core: <${vivoCore}> . - ?newPerson core:middleName ?middleName . - - - - @prefix foaf: <${foaf}> . - ?newPerson foaf:lastName ?lastName . - - - - @prefix core: <${vivoCore}> . - ?authorshipUri core:authorRank ?rank . - - -<%-- This applies to both a new and an existing person --%> - - @prefix core: <${vivoCore}> . - - ?authorshipUri a core:Authorship ; - core:linkedInformationResource ?infoResource ; - core:authorRank ?rank . - - ?infoResource core:informationResourceInAuthorship ?authorshipUri . - - - - @prefix core: <${vivoCore}> . - ?authorshipUri core:linkedAuthor ?personUri . - ?personUri core:authorInAuthorship ?authorshipUri . - - - - @prefix foaf: <${foaf}> . - @prefix core: <${vivoCore}> . - - ?newPerson a foaf:Person ; - <${label}> ?label . - - ?authorshipUri core:linkedAuthor ?newPerson . - ?newPerson core:authorInAuthorship ?authorshipUri . - - -${personClassUri} - - - - -{ - "formUrl" : "${formUrl}", - "editKey" : "${editKey}", - "urlPatternToReturnTo" : "${returnPathAfterSubmit}", - - "subject" : ["infoResource", "${subjectUriJson}" ], - "predicate" : ["predicate", "${predicateUriJson}" ], - "object" : ["authorshipUri", "${objectUriJson}", "URI" ], - - "n3required" : [ "${n3ForNewAuthorship}", "${authorshipRankAssertion}" ], - - "n3optional" : [ "${newPersonFirstNameAssertion}", "${newPersonMiddleNameAssertion}", - "${newPersonLastNameAssertion}", - "${n3ForNewPerson}", "${n3ForExistingPerson}" ], - - "newResources" : { "authorshipUri" : "${defaultNamespace}", - "newPerson" : "${defaultNamespace}" }, - - "urisInScope" : { }, - "literalsInScope": { }, - "urisOnForm" : [ "personUri" ], - "literalsOnForm" : [ "firstName", "middleName", "lastName", "rank", "label" ], - "filesOnForm" : [ ], - "sparqlForLiterals" : { }, - "sparqlForUris" : { }, - "sparqlForExistingLiterals" : { }, - "sparqlForExistingUris" : { }, - "fields" : { - "label" : { - "newResource" : "false", - "validators" : [ "datatype:${stringDatatypeUriJson}" ], - "optionsType" : "UNDEFINED", - "literalOptions" : [ ], - "predicateUri" : "", - "objectClassUri" : "", - "rangeDatatypeUri" : "${stringDatatypeUriJson}", - "rangeLang" : "", - "assertions" : [ "${n3ForNewPerson}" ] - }, - "firstName" : { - "newResource" : "false", - "validators" : [ "datatype:${stringDatatypeUriJson}" ], - "optionsType" : "UNDEFINED", - "literalOptions" : [ ], - "predicateUri" : "", - "objectClassUri" : "", - "rangeDatatypeUri" : "${stringDatatypeUriJson}", - "rangeLang" : "", - "assertions" : [ "${newPersonFirstNameAssertion}" ] - }, - "middleName" : { - "newResource" : "false", - "validators" : [ "datatype:${stringDatatypeUriJson}" ], - "optionsType" : "UNDEFINED", - "literalOptions" : [ ], - "predicateUri" : "", - "objectClassUri" : "", - "rangeDatatypeUri" : "${stringDatatypeUriJson}", - "rangeLang" : "", - "assertions" : [ "${newPersonMiddleNameAssertion}" ] - }, - "lastName" : { - "newResource" : "false", - "validators" : [ "datatype:${stringDatatypeUriJson}" ], - "optionsType" : "UNDEFINED", - "literalOptions" : [ ], - "predicateUri" : "", - "objectClassUri" : "", - "rangeDatatypeUri" : "${stringDatatypeUriJson}", - "rangeLang" : "", - "assertions" : [ "${newPersonLastNameAssertion}" ] - }, - "rank" : { - "newResource" : "false", - "validators" : [ "nonempty" ], - "optionsType" : "UNDEFINED", - "literalOptions" : [ ], - "predicateUri" : "", - "objectClassUri" : "", - "rangeDatatypeUri" : "${intDatatypeUriJson}", - "rangeLang" : "", - "assertions" : ["${authorshipRankAssertion}"] - }, - "personUri" : { - "newResource" : "false", - "validators" : [ ], - "optionsType" : "UNDEFINED", - "literalOptions" : [ ], - "predicateUri" : "", - "objectClassUri" : "${personClassUriJson}", - "rangeDatatypeUri" : "", - "rangeLang" : "", - "assertions" : ["${n3ForExistingPerson}"] - } - } -} - - -<% - log.debug(request.getAttribute("editjson")); - - EditConfiguration editConfig = EditConfiguration.getConfigFromSession(session,request); - if (editConfig == null) { - editConfig = new EditConfiguration((String) request.getAttribute("editjson")); - EditConfiguration.putConfigInSession(editConfig,session); - } - - editConfig.addValidator(new PublicationHasAuthorValidator()); - - Model model = (Model) application.getAttribute("jenaOntModel"); - String objectUri = (String) request.getAttribute("objectUri"); - - //for some reason we are comming from the add new and that is working - //but we also come from the edit, and that is not working. - editConfig.setObject(""); //this will force the edit config to always be an add, never an update - - editConfig.prepareForNonUpdate(model); // we're only adding new, not editing existing - - String subjectUri = vreq.getParameter("subjectUri"); - String predicateUri = vreq.getParameter("predicateUri"); - - String vivoCore = "http://vivoweb.org/ontology/core#"; - - //Individual infoResource = vreq.getWebappDaoFactory().getIndividualDao().getIndividualByURI(subjectUri); - Individual infoResource = ((Individual) request.getAttribute("subject")); - vreq.setAttribute("infoResourceName", infoResource.getName()); - - List authorships = infoResource.getRelatedIndividuals(predicateUri); - - List customJs = new ArrayList(Arrays.asList(JavaScript.JQUERY_UI.path(), - JavaScript.CUSTOM_FORM_UTILS.path(), - "/js/browserUtils.js", - "/edit/forms/js/addAuthorsToInformationResource1.js" - )); - request.setAttribute("customJs", customJs); - - List customCss = new ArrayList(Arrays.asList(Css.JQUERY_UI.path(), - Css.CUSTOM_FORM.path(), - "/edit/forms/css/autocomplete.css", - "/edit/forms/css/addAuthorsToInformationResource.css" - )); - request.setAttribute("customCss", customCss); - - String ulClass = ""; - List ulClasses = new ArrayList(); - - if (authorships.size() > 1) { - // This class triggers application of dd styles. Don't wait for js to add - // the ui-sortable class, because then the page flashes as the styles are updated. - ulClasses.add("dd"); - } - - if (ulClasses.size() > 0) { - ulClass="class=\"" + StringUtils.join(ulClasses, " ") + "\""; - } -%> - - - - - - - -<%-- DO NOT CHANGE IDS, CLASSES, OR HTML STRUCTURE ON THIS PAGE WITHOUT UNDERSTANDING THE IMPACT ON THE JAVASCRIPT! --%> -

${title}

- -<%@ include file="unsupportedBrowserMessage.jsp" %> - -
-

Manage Authors

- -
    > -<% - String rankPredicateUri = vivoCore + "authorRank"; - - // RY We should use whatever is used on the individual profile page to list - // this property in rank order... - DataPropertyComparator comp = new DataPropertyComparator(rankPredicateUri); - Collections.sort(authorships, comp); - - int maxRank = 0; - int authorshipCount = authorships.size(); - - // for ( ObjectPropertyStatement stmt : authorshipStmts) { - // Individual authorship = stmt.getObject(); -%> - - -<% - for ( Individual authorship : authorships ) { - - request.setAttribute("authorshipUri", authorship.getURI()); - request.setAttribute("authorshipName", authorship.getName()); - - DataPropertyStatement rankStmt = authorship.getDataPropertyStatement(rankPredicateUri); - if (rankStmt != null) { - maxRank = Integer.parseInt(rankStmt.getData()); - } - - request.setAttribute("author", authorship.getRelatedIndividual(vivoCore + "linkedAuthor")); - -%> -
  • - <%-- span.author will be used in the next phase, when we display a message that the author has been - removed. That text will replace the a.authorName, which will be removed. --%> - - <%-- This span is here to assign a width to. We can't assign directly to the a.authorName, - for the case when it's followed by an em tag - we want the width to apply to the whole thing. --%> - - - - - - - - - ${authorName} - - - - - - - - - ${authorshipName} (no linked author) - - - - - Remove - <%-- Undo --%> - -
  • - - -<% - } - - // A new author will be ranked last when added. - // This value is now inserted by JavaScript, but leave it here as a safety net in case page - // load reordering returns an error. - request.setAttribute("newRank", maxRank + 1); - System.out.println("request rank: " + request.getAttribute("newRank")); - request.setAttribute("rankPredicate", rankPredicateUri); -%> - -
- -<% if (authorshipCount == 0) { %> -

This publication currently has no authors specified.

-<% } %> - -
- -
- -<%-- DO NOT CHANGE IDS, CLASSES, OR HTML STRUCTURE IN THIS FORM WITHOUT UNDERSTANDING THE IMPACT ON THE JAVASCRIPT! --%> -
" > - -

Add an Author

- -

-

-

- - -
- <%-- RY maybe make this a label and input field. See what looks best. --%> -

- -
- - -

- -

* required fields

-
-
- - - - - - - - diff --git a/productMods/edit/forms/js/addAuthorsToInformationResource.js b/productMods/edit/forms/js/addAuthorsToInformationResource.js index abe38aa2..e764acbb 100644 --- a/productMods/edit/forms/js/addAuthorsToInformationResource.js +++ b/productMods/edit/forms/js/addAuthorsToInformationResource.js @@ -5,11 +5,11 @@ var addAuthorForm = { /* *** Initial page setup *** */ onLoad: function() { - console.log($('#rank').val()); + if (this.disableFormInUnsupportedBrowsers()) { return; } - this.mixIn(); + this.mixIn(); this.initObjects(); this.initPage(); }, @@ -29,7 +29,7 @@ var addAuthorForm = { }, mixIn: function() { - // Mix in the custom form utility methods + // Mix in the custom form utility methods $.extend(this, vitro.customFormUtils); // Get the custom form data from the page @@ -39,13 +39,13 @@ var addAuthorForm = { // On page load, create references for easy access to form elements. // NB These must be assigned after the elements have been loaded onto the page. initObjects: function() { - - this.form = $('#addAuthorForm'); - this.showFormButtonWrapper = $('#showAddForm'); - this.showFormButton = $('#showAddFormButton'); - this.removeAuthorshipLinks = $('a.remove'); - //this.undoLinks = $('a.undo'); - this.submit = this.form.find(':submit'); + + this.form = $('#addAuthorForm'); + this.showFormButtonWrapper = $('#showAddForm'); + this.showFormButton = $('#showAddFormButton'); + this.removeAuthorshipLinks = $('a.remove'); + //this.undoLinks = $('a.undo'); + this.submit = this.form.find(':submit'); this.cancel = this.form.find('.cancel'); this.labelField = $('#label'); this.firstNameField = $('#firstName'); @@ -66,23 +66,23 @@ var addAuthorForm = { this.initAuthorshipData(); - // Show elements hidden by CSS for the non-JavaScript-enabled version. - // NB The non-JavaScript version of this form is currently not functional. - this.removeAuthorshipLinks.show(); - - //this.undoLinks.hide(); - - this.bindEventListeners(); - - this.initAutocomplete(); - - this.initAuthorDD(); - - if (this.findValidationErrors()) { - this.initFormAfterInvalidSubmission(); - } else { + // Show elements hidden by CSS for the non-JavaScript-enabled version. + // NB The non-JavaScript version of this form is currently not functional. + this.removeAuthorshipLinks.show(); + + //this.undoLinks.hide(); + + this.bindEventListeners(); + + this.initAutocomplete(); + + this.initAuthorDD(); + + if (this.findValidationErrors()) { + this.initFormAfterInvalidSubmission(); + } else { this.initAuthorListOnlyView(); - } + } }, @@ -323,78 +323,29 @@ var addAuthorForm = { // Reorder authors. Called on page load and after author drag-and-drop and remove. // Event and ui parameters are defined only in the case of drag-and-drop. reorderAuthors: function(event, ui) { - var predicateUri = '<' + this.rankPred + '>', - rankXsdType = this.rankXsdType, - additions = '', - retractions = '', - authorships = []; - - $('li.authorship').each(function(index) { - var uri = $(this).data('authorshipUri'), - subjectUri = '<' + uri + '>', - oldRankVal = addAuthorForm.getRankStrVal(this), - newRank = index + 1, - newRankForN3, - oldRank, - oldRankType, - oldRankForN3, - rankVals; - - if (oldRankVal) { - // e.g., 1_http://www.w3.org/2001/XMLSchema#int - // We handle typeless values formatted as either "1" or "1_". - rankVals = oldRankVal.split('_'); - oldRank = rankVals[0]; - oldRankType = rankVals.length > 1 ? rankVals[1] : ''; - oldRankForN3 = addAuthorForm.makeRankDataPropVal(oldRank, oldRankType); - retractions += subjectUri + ' ' + predicateUri + ' ' + oldRankForN3 + ' .'; - } - - newRankForN3 = addAuthorForm.makeRankDataPropVal(newRank, rankXsdType); - additions += subjectUri + ' ' + predicateUri + ' ' + newRankForN3 + ' .'; - - // This data will be used to modify the page after successful completion - // of the Ajax request. - authorship = { - uri: uri, - rankVal: newRank + '_' + rankXsdType - }; - authorships.push(authorship); - - }); - - // console.log(authorships) - // console.log('additions: ' + additions); - // console.log('retractions: ' + retractions); + var authorships = $('li.authorship').map(function(index, el) { + return $(this).data('authorshipUri'); + }).get(); $.ajax({ url: addAuthorForm.reorderUrl, data: { - additions: additions, - retractions: retractions + predicate: addAuthorForm.rankPredicate, + individuals: authorships }, - authorships: authorships, - processData: 'false', + traditional: true, // serialize the array of individuals for the server dataType: 'json', type: 'POST', success: function(data, status, request) { - var maxRank; - $.each(authorships, function(index, obj) { - // find the authorship with this uri - var authorship = addAuthorForm.findAuthorship('authorshipUri', obj.uri), - // because all ranks have been reordered without gaps, - // we can get the position from the rank - pos = addAuthorForm.getRankIntValFromRankVal(obj.rankVal); - // set the new rank and position for this element - addAuthorForm.setRank(authorship, obj.rankVal); - addAuthorForm.setPosition(authorship, pos); - maxRank = pos; - // console.log(authorship.data('authorshipUri') + ' is at rank ' + authorship.data('rankVal')); - }); - + var pos; + $('.authorship').each(function(index){ + pos = index + 1; + // Set the new position for this element. The only function of this value + // is so we can reset an element to its original position in case reordering fails. + addAuthorForm.setPosition(this, pos); + }); // Set the form rank field value. - $('#rank').val(maxRank + 1); - // console.log("value of rank field = " + $('#rank').val()); + $('#rank').val(pos + 1); }, error: function(request, status, error) { // ui is undefined on page load and after an authorship removal. @@ -442,33 +393,6 @@ var addAuthorForm = { $(authorship).data('position', pos); }, - // Get the authorship rank value, which includes xsd type - getRankStrVal: function(authorship) { - return $(authorship).data('rankVal'); - }, - - // Get the authorship numeric rank - getRankIntVal: function(authorship) { - var rankVal = this.getRankStrVal(authorship); - return this.getRankIntValFromRankVal(rankVal); - }, - - getRankIntValFromRankVal: function(rankVal) { - return parseInt(rankVal.split('_')[0]); - }, - - setRank: function(authorship, rankVal) { - $(authorship).data('rankVal', rankVal); - }, - - makeRankDataPropVal: function(rank, xsdType) { - var rankVal = '"' + rank + '"'; - if (xsdType) { - rankVal += '^^<' + xsdType + '>' - } - return rankVal; - }, - findAuthorship: function(key, value) { var matchingAuthorship = $(); // if we don't find one, return an empty jQuery set @@ -487,20 +411,20 @@ var addAuthorForm = { /* *** Event listeners *** */ bindEventListeners: function() { - - this.showFormButton.click(function() { - addAuthorForm.initFormView(); - return false; - }); - - this.form.submit(function() { - // NB Important JavaScript scope issue: if we call it this way, this = addAuthorForm - // in prepareSubmit. If we do this.form.submit(this.prepareSubmit); then - // this != addAuthorForm in prepareSubmit. - addAuthorForm.prepareSubmit(); - }); + + this.showFormButton.click(function() { + addAuthorForm.initFormView(); + return false; + }); + + this.form.submit(function() { + // NB Important JavaScript scope issue: if we call it this way, this = addAuthorForm + // in prepareSubmit. If we do this.form.submit(this.prepareSubmit); then + // this != addAuthorForm in prepareSubmit. + addAuthorForm.prepareSubmit(); + }); - this.lastNameField.blur(function() { + this.lastNameField.blur(function() { // Cases where this event should be ignored: // 1. personUri field has a value: the autocomplete select event has already fired. // 2. The last name field is empty (especially since the field has focus when the form is displayed). @@ -508,31 +432,31 @@ var addAuthorForm = { if ( addAuthorForm.personUriField.val() || !$(this).val() || $('ul.ui-autocomplete li.ui-menu-item').length ) { return; } - addAuthorForm.onLastNameChange(); - }); - - // When hitting enter in last name field, show first and middle name fields. + addAuthorForm.onLastNameChange(); + }); + + // When hitting enter in last name field, show first and middle name fields. // NB This event fires when selecting an autocomplete suggestion with the enter // key. Since it fires first, we undo its effects in the ac select event listener. - this.lastNameField.keydown(function(event) { + this.lastNameField.keydown(function(event) { if (event.which === 13) { addAuthorForm.onLastNameChange(); return false; // don't submit form } - }); - - this.removeAuthorshipLinks.click(function() { + }); + + this.removeAuthorshipLinks.click(function() { addAuthorForm.removeAuthorship(this); return false; - }); - -// this.undoLinks.click(function() { -// $.ajax({ -// url: $(this).attr('href') -// }); -// return false; -// }); - + }); + +// this.undoLinks.click(function() { +// $.ajax({ +// url: $(this).attr('href') +// }); +// return false; +// }); + }, prepareSubmit: function() { @@ -654,10 +578,10 @@ var addAuthorForm = { // Disable DD and associated cues if only one author remains disableAuthorDD: function() { - var authorships = $('#authorships'), + var authorships = $('#authorships'), authorNameWrapper = $('.authorNameWrapper'); - authorships.sortable({ disable: true } ); + authorships.sortable({ disable: true } ); // Use class dd rather than jQuery UI's class ui-sortable, so that we can remove // the class if there's fewer than one author. We don't want to remove the ui-sortable @@ -665,13 +589,13 @@ var addAuthorForm = { // adding an author via Ajax request). authorships.removeClass('dd'); - authorNameWrapper.removeAttr('title'); + authorNameWrapper.removeAttr('title'); }, // RY To be implemented later. toggleRemoveLink: function() { - // when clicking remove: remove the author, and change link text to 'undo' - // when clicking undo: add the author back, and change link text to 'remove' + // when clicking remove: remove the author, and change link text to 'undo' + // when clicking undo: add the author back, and change link text to 'remove' } }; diff --git a/productMods/edit/forms/js/addAuthorsToInformationResource1.js b/productMods/edit/forms/js/addAuthorsToInformationResource1.js deleted file mode 100644 index 8b6afcfe..00000000 --- a/productMods/edit/forms/js/addAuthorsToInformationResource1.js +++ /dev/null @@ -1,606 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -var addAuthorForm = { - - /* *** Initial page setup *** */ - - onLoad: function() { - - if (this.disableFormInUnsupportedBrowsers()) { - return; - } - this.mixIn(); - this.initObjects(); - this.initPage(); - }, - - disableFormInUnsupportedBrowsers: function() { - this.disableWrapper = $('#ie67DisableWrapper'); - - // Check for unsupported browsers only if the element exists on the page - if (this.disableWrapper.length) { - if (vitro.browserUtils.isIELessThan8()) { - this.disableWrapper.show(); - $('.noIE67').hide(); - return true; - } - } - return false; - }, - - mixIn: function() { - // Mix in the custom form utility methods - $.extend(this, vitro.customFormUtils); - - // Get the custom form data from the page - $.extend(this, customFormData); - }, - - // On page load, create references for easy access to form elements. - // NB These must be assigned after the elements have been loaded onto the page. - initObjects: function() { - - this.form = $('#addAuthorForm'); - this.showFormButtonWrapper = $('#showAddForm'); - this.showFormButton = $('#showAddFormButton'); - this.removeAuthorshipLinks = $('a.remove'); - //this.undoLinks = $('a.undo'); - this.submit = this.form.find(':submit'); - this.cancel = this.form.find('.cancel'); - this.labelField = $('#label'); - this.firstNameField = $('#firstName'); - this.middleNameField = $('#middleName'); - this.lastNameField = $('#lastName'); - this.lastNameLabel = $('label[for=lastName]'); - this.personUriField = $('#personUri'); - this.firstNameWrapper = this.firstNameField.parent(); - this.middleNameWrapper = this.middleNameField.parent(); - this.lastNameWrapper = this.lastNameField.parent(); - this.selectedAuthor = $('#selectedAuthor'); - this.selectedAuthorName = $('#selectedAuthorName'); - - }, - - // Initial page setup. Called only at page load. - initPage: function() { - - this.initAuthorshipData(); - - // Show elements hidden by CSS for the non-JavaScript-enabled version. - // NB The non-JavaScript version of this form is currently not functional. - this.removeAuthorshipLinks.show(); - - //this.undoLinks.hide(); - - this.bindEventListeners(); - - this.initAutocomplete(); - - this.initAuthorDD(); - - if (this.findValidationErrors()) { - this.initFormAfterInvalidSubmission(); - } else { - this.initAuthorListOnlyView(); - } - }, - - - /* *** Set up the various page views *** */ - - // This initialization is done only on page load, not when returning to author list only view - // after hitting 'cancel.' - initAuthorListOnlyView: function() { - - if ($('.authorship').length) { // make sure we have at least one author - // Reorder authors on page load so that previously unranked authors get a rank. Otherwise, - // when we add a new author, it will get put ahead of any previously unranked authors, instead - // of at the end of the list. (It is also helpful to normalize the data before we get started.) - this.reorderAuthors(); - } - this.showAuthorListOnlyView(); - }, - - // This view shows the list of existing authors and hides the form. - // There is a button to show the form. We do this on page load, and after - // hitting 'cancel' from full view. - showAuthorListOnlyView: function() { - this.hideForm(); - this.showFormButtonWrapper.show(); - }, - - // View of form after returning from an invalid submission. On this form, - // validation errors entail that we were entering a new person, so we show - // all the fields straightaway. - initFormAfterInvalidSubmission: function() { - this.initForm(); - this.showFieldsForNewPerson(); - }, - - // Initial view of add author form. We get here by clicking the show form button, - // or by cancelling out of an autocomplete selection. - initFormView: function() { - - this.initForm(); - - this.hideFieldsForNewPerson(); - - // This shouldn't be needed, because calling this.hideFormFields(this.lastNameWrapper) - // from showSelectedAuthor should do it. However, it doesn't work from there, - // or in the cancel action, or if referring to this.lastNameField. None of those work, - // however. - $('#lastName').val(''); - - return false; - - }, - - // Form initialization common to both a 'clean' form view and when - // returning from an invalid submission. - initForm: function() { - - // Hide the button that shows the form - this.showFormButtonWrapper.hide(); - - this.hideSelectedAuthor(); - - this.cancel.unbind('click'); - this.cancel.bind('click', function() { - addAuthorForm.showAuthorListOnlyView(); - return false; - }); - - // Reset the last name field. It had been hidden if we selected an author from - // the autocomplete field. - this.lastNameWrapper.show(); - - // Show the form - this.form.show(); - this.lastNameField.focus(); - }, - - hideSelectedAuthor: function() { - this.selectedAuthor.hide(); - this.selectedAuthorName.html(''); - this.personUriField.val(''); - }, - - showFieldsForNewPerson: function() { - this.firstNameWrapper.show(); - this.middleNameWrapper.show(); - }, - - hideFieldsForNewPerson: function() { - this.hideFields(this.firstNameWrapper); - this.hideFields(this.middleNameWrapper); - }, - - /* *** Ajax initializations *** */ - - /* Autocomplete */ - initAutocomplete: function() { - - // Make cache a property of this so we can access it after removing - // an author. - this.acCache = {}; - this.setAcFilter(); - - this.lastNameField.autocomplete({ - minLength: 2, - source: function(request, response) { - if (request.term in addAuthorForm.acCache) { - // console.log('found term in cache'); - response(addAuthorForm.acCache[request.term]); - return; - } - // console.log('not getting term from cache'); - - // If the url query params are too long, we could do a post - // here instead of a get. Add the exclude uris to the data - // rather than to the url. - $.ajax({ - url: addAuthorForm.acUrl, - dataType: 'json', - data: { - term: request.term - }, - complete: function(xhr, status) { - // Not sure why, but we need an explicit json parse here. jQuery - // should parse the response text and return a json object. - var results = jQuery.parseJSON(xhr.responseText), - filteredResults = addAuthorForm.filterAcResults(results); - addAuthorForm.acCache[request.term] = filteredResults; - response(filteredResults); - } - - }); - }, - // Select event not triggered in IE6/7 when selecting with enter key rather - // than mouse. Thus form is disabled in these browsers. - // jQuery UI bug: when scrolling through the ac suggestions with up/down arrow - // keys, the input element gets filled with the highlighted text, even though no - // select event has been triggered. To trigger a select, the user must hit enter - // or click on the selection with the mouse. This appears to confuse some users. - select: function(event, ui) { - addAuthorForm.showSelectedAuthor(ui); - } - }); - - }, - - setAcFilter: function() { - this.acFilter = []; - - $('.authorship').each(function() { - var uri = $(this).data('authorUri'); - addAuthorForm.acFilter.push(uri); - }); - }, - - removeAuthorFromAcFilter: function(author) { - var index = $.inArray(author, this.acFilter); - if (index > -1) { // this should always be true - this.acFilter.splice(index, 1); - } - }, - - filterAcResults: function(results) { - var filteredResults = []; - if (!this.acFilter.length) { - return results; - } - $.each(results, function() { - if ($.inArray(this.uri, addAuthorForm.acFilter) == -1) { - // console.log("adding " + this.label + " to filtered results"); - filteredResults.push(this); - } - else { - // console.log("filtering out " + this.label); - } - }); - return filteredResults; - }, - - // After removing an authorship, selectively clear matching autocomplete - // cache entries, else the associated author will not be included in - // subsequent autocomplete suggestions. - clearAcCacheEntries: function(name) { - name = name.toLowerCase(); - $.each(this.acCache, function(key, value) { - if (name.indexOf(key) == 0) { - delete addAuthorForm.acCache[key]; - } - }); - }, - - // Action taken after selecting an author from the autocomplete list - showSelectedAuthor: function(ui) { - - this.personUriField.val(ui.item.uri); - this.selectedAuthor.show(); - - // Transfer the name from the autocomplete to the selected author - // name display, and hide the last name field. - this.selectedAuthorName.html(ui.item.label); - // NB For some reason this doesn't delete the value from the last name - // field when the form is redisplayed. Thus it's done explicitly in initFormView. - this.hideFields(this.lastNameWrapper); - // These get displayed if the selection was made through an enter keystroke, - // since the keydown event on the last name field is also triggered (and - // executes first). So re-hide them here. - this.hideFieldsForNewPerson(); - - // Cancel restores initial form view - this.cancel.unbind('click'); - this.cancel.bind('click', function() { - addAuthorForm.initFormView(); - return false; - }); - }, - - /* Drag-and-drop */ - initAuthorDD: function() { - - var authorshipList = $('#authorships'), - authorships = authorshipList.children('li'); - - if (authorships.length < 2) { - return; - } - - $('.authorNameWrapper').each(function() { - $(this).attr('title', 'Drag and drop to reorder authors'); - }); - - authorshipList.sortable({ - cursor: 'move', - stop: function(event, ui) { - addAuthorForm.reorderAuthors(event, ui); - } - }); - }, - - // Reorder authors. Called on page load and after author drag-and-drop and remove. - // Event and ui parameters are defined only in the case of drag-and-drop. - reorderAuthors: function(event, ui) { - var authorships = $('li.authorship').map(function(index, el) { - return $(this).data('authorshipUri'); - }).get(); - - $.ajax({ - url: addAuthorForm.reorderUrl, - data: { - predicate: addAuthorForm.rankPredicate, - individuals: authorships - }, - traditional: true, // serialize the array of individuals for the server - dataType: 'json', - type: 'POST', - success: function(data, status, request) { - var pos; - $('.authorship').each(function(index){ - pos = index + 1; - // Set the new position for this element. The only function of this value - // is so we can reset an element to its original position in case reordering fails. - addAuthorForm.setPosition(this, pos); - }); - // Set the form rank field value. - $('#rank').val(pos + 1); - }, - error: function(request, status, error) { - // ui is undefined on page load and after an authorship removal. - if (ui) { - // Put the moved item back to its original position. - // Seems we need to do this by hand. Can't see any way to do it with jQuery UI. ?? - var pos = addAuthorForm.getPosition(ui.item), - nextpos = pos + 1, - authorships = $('#authorships'), - next = addAuthorForm.findAuthorship('position', nextpos); - - if (next.length) { - ui.item.insertBefore(next); - } - else { - ui.item.appendTo(authorships); - } - - alert('Reordering of authors failed.'); - } - } - }); - }, - - // On page load, associate data with each authorship element. Then we don't - // have to keep retrieving data from or modifying the DOM as we manipulate the - // authorships. - initAuthorshipData: function() { - $('.authorship').each(function(index) { - $(this).data(authorshipData[index]); - - // RY We might still need position to put back an element after reordering - // failure. Rank might already have been reset? Check. - // We also may need position to implement undo links: we want the removed authorship - // to show up in the list, but it has no rank. - $(this).data('position', index+1); - }); - }, - - getPosition: function(authorship) { - return $(authorship).data('position'); - }, - - setPosition: function(authorship, pos) { - $(authorship).data('position', pos); - }, - - findAuthorship: function(key, value) { - var matchingAuthorship = $(); // if we don't find one, return an empty jQuery set - - $('.authorship').each(function() { - var authorship = $(this); - if ( authorship.data(key) === value ) { - matchingAuthorship = authorship; - return false; // stop the loop - } - }); - - return matchingAuthorship; - }, - - - /* *** Event listeners *** */ - - bindEventListeners: function() { - - this.showFormButton.click(function() { - addAuthorForm.initFormView(); - return false; - }); - - this.form.submit(function() { - // NB Important JavaScript scope issue: if we call it this way, this = addAuthorForm - // in prepareSubmit. If we do this.form.submit(this.prepareSubmit); then - // this != addAuthorForm in prepareSubmit. - addAuthorForm.prepareSubmit(); - }); - - this.lastNameField.blur(function() { - // Cases where this event should be ignored: - // 1. personUri field has a value: the autocomplete select event has already fired. - // 2. The last name field is empty (especially since the field has focus when the form is displayed). - // 3. Autocomplete suggestions are showing. - if ( addAuthorForm.personUriField.val() || !$(this).val() || $('ul.ui-autocomplete li.ui-menu-item').length ) { - return; - } - addAuthorForm.onLastNameChange(); - }); - - // When hitting enter in last name field, show first and middle name fields. - // NB This event fires when selecting an autocomplete suggestion with the enter - // key. Since it fires first, we undo its effects in the ac select event listener. - this.lastNameField.keydown(function(event) { - if (event.which === 13) { - addAuthorForm.onLastNameChange(); - return false; // don't submit form - } - }); - - this.removeAuthorshipLinks.click(function() { - addAuthorForm.removeAuthorship(this); - return false; - }); - -// this.undoLinks.click(function() { -// $.ajax({ -// url: $(this).attr('href') -// }); -// return false; -// }); - - }, - - prepareSubmit: function() { - var firstName, - middleName, - lastName, - name; - - // If selecting an existing person, don't submit name fields - if (this.personUriField.val() != '') { - this.firstNameField.attr('disabled', 'disabled'); - this.middleNameField.attr('disabled', 'disabled'); - this.lastNameField.attr('disabled', 'disabled'); - } - else { - firstName = this.firstNameField.val(); - middleName = this.middleNameField.val(); - lastName = this.lastNameField.val(); - - name = lastName; - if (firstName) { - name += ', ' + firstName; - } - if (middleName) { - name += ' ' + middleName; - } - - this.labelField.val(name); - } - - }, - - onLastNameChange: function() { - this.showFieldsForNewPerson(); - this.firstNameField.focus(); - // this.fixNames(); - }, - - // User may have typed first name as well as last name into last name field. - // If so, when showing first and middle name fields, move anything after a comma - // or space into the first name field. - // RY Space is problematic because they may be entering " ", but - // comma is a clear case. -// fixNames: function() { -// var lastNameInput = this.lastNameField.val(), -// names = lastNameInput.split(/[, ]+/), -// lastName = names[0]; -// -// this.lastNameField.val(lastName); -// -// if (names.length > 1) { -// //firstName = names[1].replace(/^[, ]+/, ''); -// this.firstNameField.val(names[1]); -// } -// }, - - removeAuthorship: function(link) { - // RY Upgrade this to a modal window - var message = 'Are you sure you want to remove this author?'; - if (!confirm(message)) { - return false; - } - $.ajax({ - url: $(link).attr('href'), - type: 'POST', - data: { - deletion: $(link).parents('.authorship').data('authorshipUri') - }, - dataType: 'json', - context: link, // context for callback - complete: function(request, status) { - var authorship, - authorUri; - - if (status === 'success') { - - authorship = $(this).parents('.authorship'); - - // Clear autocomplete cache entries matching this author's name, else - // autocomplete will be retrieved from the cache, which excludes the removed author. - addAuthorForm.clearAcCacheEntries(authorship.data('authorName')); - - // Remove this author from the acFilter so it is included in autocomplete - // results again. - addAuthorForm.removeAuthorFromAcFilter(authorship.data('authorUri')); - - authorship.fadeOut(400, function() { - var numAuthors; - - // For undo link: add to a deletedAuthorships array - - // Remove from the DOM - $(this).remove(); - - // Actions that depend on the author having been removed from the DOM: - numAuthors = $('.authorship').length; // retrieve the length after removing authorship from the DOM - if (numAuthors > 0) { - // Reorder to remove any gaps - addAuthorForm.reorderAuthors(); - - // If less than two authors remaining, disable drag-drop - if (numAuthors < 2) { - addAuthorForm.disableAuthorDD(); - } - } - }); - -// $(this).hide(); -// $(this).siblings('.undo').show(); -// author.html(authorName + ' has been removed'); -// author.css('width', 'auto'); -// author.effect('highlight', {}, 3000); - } else { - alert('Error processing request: author not removed'); - } - } - }); - }, - - // Disable DD and associated cues if only one author remains - disableAuthorDD: function() { - var authorships = $('#authorships'), - authorNameWrapper = $('.authorNameWrapper'); - - authorships.sortable({ disable: true } ); - - // Use class dd rather than jQuery UI's class ui-sortable, so that we can remove - // the class if there's fewer than one author. We don't want to remove the ui-sortable - // class, in case we want to re-enable DD without a page reload (e.g., if implementing - // adding an author via Ajax request). - authorships.removeClass('dd'); - - authorNameWrapper.removeAttr('title'); - }, - - // RY To be implemented later. - toggleRemoveLink: function() { - // when clicking remove: remove the author, and change link text to 'undo' - // when clicking undo: add the author back, and change link text to 'remove' - } - -}; - -$(document).ready(function() { - addAuthorForm.onLoad(); -}); -