From 98c027b00ca19ae4ff61c8a09275c34253c1414b Mon Sep 17 00:00:00 2001 From: rjy7 Date: Tue, 22 Jun 2010 17:52:37 +0000 Subject: [PATCH] NIHVIVO-646 Adding an existing person as an author on the add authors to publications form --- .../user/vivo-core-1.1-annotations.rdf | 3 +- .../forms/addAuthorsToInformationResource.jsp | 65 +++++--- .../css/addAuthorsToInformationResource.css | 11 +- productMods/edit/forms/css/customForm.css | 11 ++ .../js/addAuthorsToInformationResource.js | 140 +++++++++++++----- themes/vivo-basic/templates/page/default.ftl | 3 +- 6 files changed, 172 insertions(+), 61 deletions(-) diff --git a/productMods/WEB-INF/ontologies/user/vivo-core-1.1-annotations.rdf b/productMods/WEB-INF/ontologies/user/vivo-core-1.1-annotations.rdf index 97084ebe..a360aa5f 100644 --- a/productMods/WEB-INF/ontologies/user/vivo-core-1.1-annotations.rdf +++ b/productMods/WEB-INF/ontologies/user/vivo-core-1.1-annotations.rdf @@ -3,7 +3,7 @@ xmlns:j.0="http://vitro.mannlib.cornell.edu/ns/vitro/0.7#" > - + @@ -1796,6 +1796,7 @@ true + addAuthorsToInformationResource.jsp 1 diff --git a/productMods/edit/forms/addAuthorsToInformationResource.jsp b/productMods/edit/forms/addAuthorsToInformationResource.jsp index 72690136..3ac90486 100644 --- a/productMods/edit/forms/addAuthorsToInformationResource.jsp +++ b/productMods/edit/forms/addAuthorsToInformationResource.jsp @@ -28,14 +28,14 @@ core:authorInAuthorship (Person : Authorship) - inverse of linkedAuthor <%@ 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.dao.VitroVocabulary"%> -<%@ page import="edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditConfiguration"%> -<%@ page import="edu.cornell.mannlib.vitro.webapp.edit.n3editing.CreateLabelFromNameFields"%> -<%@ 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.beans.Individual" %> +<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.DataPropertyComparator" %> +<%@ 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.controller.freemarker.UrlBuilder.JavaScript" %> <%@ page import="edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Css" %> @@ -69,6 +69,7 @@ core:authorInAuthorship (Person : Authorship) - inverse of linkedAuthor + <%-- Unlike other custom forms, this form does not allow edits of existing authors, so there are no SPARQL queries for existing values. --%> @@ -125,6 +126,8 @@ SPARQL queries for existing values. --%> ?newPerson core:authorInAuthorship ?authorshipUri . +${personClassUri} + @@ -169,7 +172,7 @@ SPARQL queries for existing values. --%> }, "firstName" : { "newResource" : "false", - "validators" : [ "nonempty", "datatype:${stringDatatypeUriJson}" ], + "validators" : [ "datatype:${stringDatatypeUriJson}" ], "optionsType" : "UNDEFINED", "literalOptions" : [ ], "predicateUri" : "", @@ -191,7 +194,7 @@ SPARQL queries for existing values. --%> }, "lastName" : { "newResource" : "false", - "validators" : [ "nonempty", "datatype:${stringDatatypeUriJson}" ], + "validators" : [ "datatype:${stringDatatypeUriJson}" ], "optionsType" : "UNDEFINED", "literalOptions" : [ ], "predicateUri" : "", @@ -210,6 +213,17 @@ SPARQL queries for existing values. --%> "rangeDatatypeUri" : "${intDatatypeUriJson}", "rangeLang" : "", "assertions" : ["${authorshipRankAssertion}"] + }, + "personUri" : { + "newResource" : "false", + "validators" : [ ], + "optionsType" : "UNDEFINED", + "literalOptions" : [ ], + "predicateUri" : "", + "objectClassUri" : "${personClassUriJson}", + "rangeDatatypeUri" : "", + "rangeLang" : "", + "assertions" : ["${n3ForExistingPerson}"] } } } @@ -223,12 +237,8 @@ SPARQL queries for existing values. --%> editConfig = new EditConfiguration((String) request.getAttribute("editjson")); EditConfiguration.putConfigInSession(editConfig,session); } - - // Doing this in Javascript instead. - // For now the field names in CreateLabelFromFieldNames.processEditSubmission() are - // hard-coded. If we want flexibility in naming them, we can pass in a map of - // the field names when creating the preprocessor. - // editConfig.addEditSubmissionPreprocessor(new CreateLabelFromNameFields(editConfig)); + + //editConfig.addValidator(new PublicationHasAuthorValidator()); Model model = (Model) application.getAttribute("jenaOntModel"); String objectUri = (String) request.getAttribute("objectUri"); @@ -295,23 +305,34 @@ SPARQL queries for existing values. --%> +<% + if (authorships.size() == 0) { + %>

This publication currently has no authors specified.

<% + } +%> +
-
" > + +

Add an Author

${initialHint}

${initialHint}

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

+ +
+ " /> - - - - +

* required fields

diff --git a/productMods/edit/forms/css/addAuthorsToInformationResource.css b/productMods/edit/forms/css/addAuthorsToInformationResource.css index f8bb783e..1f123519 100644 --- a/productMods/edit/forms/css/addAuthorsToInformationResource.css +++ b/productMods/edit/forms/css/addAuthorsToInformationResource.css @@ -16,7 +16,8 @@ /* Hide elements not used in non-JS version of form */ #showAddForm, -a.remove { +a.remove, +#selectedAuthor { display: none; } @@ -28,6 +29,10 @@ a.remove { margin-left: 2em; } +form h3 { + margin-bottom: .5em; +} + form a:link.cancel, form a:visited.cancel, #authors a:link.remove, #authors a:visited.remove, #showAddForm a:link.cancel, #showAddForm a:visited.cancel { @@ -67,3 +72,7 @@ form a:hover.cancel, #content form p.inline span.hint { margin-left: .5em; } + +#selectedAuthor { + clear: left; +} diff --git a/productMods/edit/forms/css/customForm.css b/productMods/edit/forms/css/customForm.css index e914ae7d..076a3ea4 100644 --- a/productMods/edit/forms/css/customForm.css +++ b/productMods/edit/forms/css/customForm.css @@ -103,3 +103,14 @@ option { #content form textarea { width: 30%; } + + +/* jQuery UI autocomplete */ +ul.ui-autocomplete { + font-size: .95em; +} + +li.ui-menu-item a.ui-corner-all { + text-align: left; + padding-left: .25em; +} \ No newline at end of file diff --git a/productMods/edit/forms/js/addAuthorsToInformationResource.js b/productMods/edit/forms/js/addAuthorsToInformationResource.js index e04dc42b..494c69ae 100644 --- a/productMods/edit/forms/js/addAuthorsToInformationResource.js +++ b/productMods/edit/forms/js/addAuthorsToInformationResource.js @@ -5,9 +5,8 @@ var addAuthorForm = { onLoad: function() { this.mixIn(); - this.initObjects(); - this.adjustForJs(); - this.initForm(); + this.initObjects(); + this.initPage(); }, mixIn: function() { @@ -15,12 +14,12 @@ var addAuthorForm = { vitro.utils.borrowMethods(vitro.customFormUtils, this); }, - // On page load, create references within the customForm scope to DOM elements. + // On page load, create references within the addAuthorForm scope to DOM elements. // NB These must be assigned after the elements have been loaded onto the page. initObjects: function() { this.form = $('#addAuthorForm'); - this.showFormDiv = $('#showAddForm'); + this.showFormButtonWrapper = $('#showAddForm'); this.showFormButton = $('#showAddFormButton'); this.removeLinks = $('a.remove'); this.submit = this.form.find(':submit'); @@ -32,42 +31,103 @@ var addAuthorForm = { this.personUriField = $('#personUri'); this.firstNameWrapper = this.firstNameField.parent(); this.middleNameWrapper = this.middleNameField.parent(); - }, + this.lastNameWrapper = this.lastNameField.parent(); + this.selectedAuthor = $('#selectedAuthor'); + this.selectedAuthorName = $('#selectedAuthorName'); - // On page load, make changes to the non-Javascript version for the Javascript version. - // These are features that will NOT CHANGE throughout the workflow of the Javascript version. - adjustForJs: function() { - - // Show elements that are hidden by css on load since not used in non-JS version - this.showFormDiv.show(); - this.removeLinks.show(); - - this.form.hide(); }, - initForm: function() { + // Initial page setup. Called only at page load. + initPage: function() { + + // Show elements hidden by CSS for the non-JavaScript-enabled version. + // NB The non-JavaScript version of this form is currently not functional. + this.removeLinks.show(); - this.firstNameWrapper.hide(); - this.middleNameWrapper.hide(); + this.bindEventListeners(); + + this.setUpAutocomplete(); + + this.initAuthorListOnlyView(); + }, + + bindEventListeners: function() { this.showFormButton.click(function() { - addAuthorForm.showFormDiv.hide(); - addAuthorForm.form.show(); + addAuthorForm.initFormView(); return false; }); this.submit.click(function() { - addAuthorForm.insertLabel(); // might be insertLabelOrPersonUri - }); + addAuthorForm.prepareFieldValuesForSubmit(); + }); + }, + + // This view shows the list of existing authors and hides the form. + // There is a button to show the form. + initAuthorListOnlyView: function() { + this.hideForm(); + this.showFormButtonWrapper.show(); + }, + + // Initial view of add author form + initFormView: function() { + + // Hide the button that shows the form + this.showFormButtonWrapper.hide(); + + // Hide form fields that shouldn't display on first view. + // Includes clearing their contents. + this.hideFields(this.firstNameWrapper); + this.hideFields(this.middleNameWrapper); + this.hideSelectedAuthor(); - this.cancel.click(function() { - addAuthorForm.hideFields(addAuthorForm.form); - addAuthorForm.showFormDiv.show(); + this.cancel.unbind('click'); + this.cancel.bind('click', function() { + addAuthorForm.initAuthorListOnlyView(); return false; }); - - this.setUpAutocomplete(); + // Reset the last name field. It had been hidden if we selected an author from + // the autocomplete field. + this.lastNameWrapper.show(); + // 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(''); + + // Show the form + this.form.show(); + + return false; + }, + + // 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 field to the selected author + // name display, and hide the last name field. + this.selectedAuthorName.html(this.lastNameField.val()); + // NB For some reason this doesn't delete the value from the last name + // field when the form is redisplayed. Need to do in initFormView. + this.hideFields(this.lastNameWrapper); + + // Cancel restores form to initial state + this.cancel.unbind('click'); + this.cancel.bind('click', function() { + addAuthorForm.initFormView(); + return false; + }); + }, + + hideSelectedAuthor: function() { + this.selectedAuthor.hide(); + this.selectedAuthorName.html(''); + this.personUriField.val(''); }, setUpAutocomplete: function() { @@ -84,45 +144,53 @@ var addAuthorForm = { $.ajax({ url: url, - dataType: "json", + dataType: 'json', data: request, success: function(data) { cache[request.term] = data; response(data); } - // on select: fill in person uri + }); - } + }, + select: function(event, ui) { + addAuthorForm.showSelectedAuthor(ui); + } }); }, - insertLabel: function() { + prepareFieldValuesForSubmit: function() { var firstName, middleName, lastName, name; - if (!this.firstNameField.is(':hidden')) { + // 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; + name += ', ' + firstName; } if (middleName) { - name += " " + middleName; + name += ' ' + middleName; } this.labelField.val(name); } - else { - } }, + // 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" diff --git a/themes/vivo-basic/templates/page/default.ftl b/themes/vivo-basic/templates/page/default.ftl index 34cf3ea3..ffd25044 100644 --- a/themes/vivo-basic/templates/page/default.ftl +++ b/themes/vivo-basic/templates/page/default.ftl @@ -26,11 +26,12 @@ <#-- We don't do title here because some pages don't get a title, or it may not be the same as the text. <h2>${title}</h2> --> ${body} + <#-- <@dumpDataModel /> --> </div> <!-- content --> </div> <!-- contentwrap --> <#include "partials/footer.ftl"> - + </div> <!-- wrap --> <#include "partials/scripts.ftl">