NIHVIVO-803 Moved new implementation of author reordering into main files and removed temporary files.
This commit is contained in:
parent
74fc1fb5d8
commit
ec077b8bb5
4 changed files with 102 additions and 1228 deletions
|
@ -300,8 +300,8 @@ SPARQL queries for existing values. --%>
|
||||||
|
|
||||||
<ul id="authorships" <%= ulClass %>>
|
<ul id="authorships" <%= ulClass %>>
|
||||||
<%
|
<%
|
||||||
String rankPredicateUri = vivoCore + "authorRank";
|
String rankPredicateUri = vivoCore + "authorRank";
|
||||||
|
|
||||||
// RY We should use whatever is used on the individual profile page to list
|
// RY We should use whatever is used on the individual profile page to list
|
||||||
// this property in rank order...
|
// this property in rank order...
|
||||||
DataPropertyComparator comp = new DataPropertyComparator(rankPredicateUri);
|
DataPropertyComparator comp = new DataPropertyComparator(rankPredicateUri);
|
||||||
|
@ -323,20 +323,10 @@ SPARQL queries for existing values. --%>
|
||||||
request.setAttribute("authorshipUri", authorship.getURI());
|
request.setAttribute("authorshipUri", authorship.getURI());
|
||||||
request.setAttribute("authorshipName", authorship.getName());
|
request.setAttribute("authorshipName", authorship.getName());
|
||||||
|
|
||||||
String rankValue = "";
|
|
||||||
String numericRank = "";
|
|
||||||
DataPropertyStatement rankStmt = authorship.getDataPropertyStatement(rankPredicateUri);
|
DataPropertyStatement rankStmt = authorship.getDataPropertyStatement(rankPredicateUri);
|
||||||
if (rankStmt != null) {
|
if (rankStmt != null) {
|
||||||
rankValue = rankStmt.getData();
|
maxRank = Integer.parseInt(rankStmt.getData());
|
||||||
numericRank = rankValue;
|
|
||||||
maxRank = Integer.valueOf(rankValue);
|
|
||||||
String rankDatatypeUri = rankStmt.getDatatypeURI();
|
|
||||||
if ( !StringUtils.isEmpty(rankDatatypeUri) ) {
|
|
||||||
rankValue += "_" + rankDatatypeUri;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
request.setAttribute("rankValue", rankValue);
|
|
||||||
request.setAttribute("numericRank", numericRank);
|
|
||||||
|
|
||||||
request.setAttribute("author", authorship.getRelatedIndividual(vivoCore + "linkedAuthor"));
|
request.setAttribute("author", authorship.getRelatedIndividual(vivoCore + "linkedAuthor"));
|
||||||
|
|
||||||
|
@ -348,25 +338,25 @@ SPARQL queries for existing values. --%>
|
||||||
<%-- This span is here to assign a width to. We can't assign directly to the a.authorName,
|
<%-- 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. --%>
|
for the case when it's followed by an em tag - we want the width to apply to the whole thing. --%>
|
||||||
<span class="authorNameWrapper">
|
<span class="authorNameWrapper">
|
||||||
<c:choose>
|
<c:choose>
|
||||||
<c:when test="${!empty author}">
|
<c:when test="${!empty author}">
|
||||||
<c:set var="authorUri" value="${author.URI}" />
|
<c:set var="authorUri" value="${author.URI}" />
|
||||||
<c:set var="authorName" value="${author.name}" />
|
<c:set var="authorName" value="${author.name}" />
|
||||||
<c:url var="authorHref" value="/individual">
|
<c:url var="authorHref" value="/individual">
|
||||||
<c:param name="uri" value="${authorUri}"/>
|
<c:param name="uri" value="${authorUri}"/>
|
||||||
</c:url>
|
</c:url>
|
||||||
<span class="authorName">${authorName}</span>
|
<span class="authorName">${authorName}</span>
|
||||||
</c:when>
|
</c:when>
|
||||||
|
|
||||||
<c:otherwise>
|
<c:otherwise>
|
||||||
<c:set var="authorUri" value="" />
|
<c:set var="authorUri" value="" />
|
||||||
<c:set var="authorName" value="" />
|
<c:set var="authorName" value="" />
|
||||||
<c:url var="authorshipHref" value="/individual">
|
<c:url var="authorshipHref" value="/individual">
|
||||||
<c:param name="uri" value="${authorshipUri}"/>
|
<c:param name="uri" value="${authorshipUri}"/>
|
||||||
</c:url>
|
</c:url>
|
||||||
<span class="authorName">${authorshipName}</span><em> (no linked author)</em>
|
<span class="authorName">${authorshipName}</span><em> (no linked author)</em>
|
||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
</c:choose>
|
</c:choose>
|
||||||
</span>
|
</span>
|
||||||
<c:url var="deleteAuthorshipHref" value="/edit/primitiveDelete" />
|
<c:url var="deleteAuthorshipHref" value="/edit/primitiveDelete" />
|
||||||
<a href="${deleteAuthorshipHref}" class="remove">Remove</a>
|
<a href="${deleteAuthorshipHref}" class="remove">Remove</a>
|
||||||
|
@ -377,20 +367,19 @@ SPARQL queries for existing values. --%>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
authorshipData.push({
|
authorshipData.push({
|
||||||
"authorshipUri": "${authorshipUri}",
|
"authorshipUri": "${authorshipUri}",
|
||||||
//"numericRank": "${numericRank}",
|
|
||||||
"rankVal": "${rankValue}",
|
|
||||||
"authorUri": "${authorUri}",
|
"authorUri": "${authorUri}",
|
||||||
"authorName": "${authorName}"
|
"authorName": "${authorName}"
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<%
|
<%
|
||||||
}
|
}
|
||||||
|
|
||||||
// A new author will be ranked last when added.
|
// 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
|
// This value is now inserted by JavaScript, but leave it here as a safety net in case page
|
||||||
// load reordering returns an error.
|
// load reordering returns an error.
|
||||||
request.setAttribute("newRank", maxRank + 1);
|
request.setAttribute("newRank", maxRank + 1);
|
||||||
request.setAttribute("rankPred", rankPredicateUri);
|
System.out.println("request rank: " + request.getAttribute("newRank"));
|
||||||
|
request.setAttribute("rankPredicate", rankPredicateUri);
|
||||||
%>
|
%>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -399,7 +388,6 @@ SPARQL queries for existing values. --%>
|
||||||
<p>This publication currently has no authors specified.</p>
|
<p>This publication currently has no authors specified.</p>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
|
|
||||||
<div id="showAddForm">
|
<div id="showAddForm">
|
||||||
<v:input type="submit" value="Add Author" id="showAddFormButton" cancel="true" cancelLabel="Return to Publication" cancelUrl="/individual" />
|
<v:input type="submit" value="Add Author" id="showAddFormButton" cancel="true" cancelLabel="Return to Publication" cancelUrl="/individual" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -421,7 +409,6 @@ SPARQL queries for existing values. --%>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="hidden" name="rank" id="rank" value="${newRank}" />
|
<input type="hidden" name="rank" id="rank" value="${newRank}" />
|
||||||
|
|
||||||
<p class="submit"><v:input type="submit" id="submit" value="Add Author" cancel="true" /></p>
|
<p class="submit"><v:input type="submit" id="submit" value="Add Author" cancel="true" /></p>
|
||||||
|
|
||||||
<p id="requiredLegend" class="requiredHint">* required fields</p>
|
<p id="requiredLegend" class="requiredHint">* required fields</p>
|
||||||
|
@ -429,14 +416,13 @@ SPARQL queries for existing values. --%>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<c:url var="acUrl" value="/autocomplete?type=${foaf}Person&tokenize=false&stem=false" />
|
<c:url var="acUrl" value="/autocomplete?type=${foaf}Person&tokenize=false&stem=false" />
|
||||||
<c:url var="reorderUrl" value="/edit/primitiveRdfEdit" />
|
<c:url var="reorderUrl" value="/edit/reorder" />
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var customFormData = {
|
var customFormData = {
|
||||||
rankPred: '${rankPred}',
|
rankPredicate: '${rankPredicate}',
|
||||||
rankXsdType: '${intDatatypeUri}',
|
acUrl: '${acUrl}',
|
||||||
acUrl: '${acUrl}',
|
reorderUrl: '${reorderUrl}'
|
||||||
reorderUrl: '${reorderUrl}'
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -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));
|
|
||||||
%>
|
|
||||||
|
|
||||||
<c:set var="vivoCore" value="http://vivoweb.org/ontology/core#" />
|
|
||||||
<c:set var="rdfs" value="<%= VitroVocabulary.RDFS %>" />
|
|
||||||
<c:set var="label" value="${rdfs}label" />
|
|
||||||
<c:set var="foaf" value="http://xmlns.com/foaf/0.1/" />
|
|
||||||
<c:set var="personClassUri" value="${foaf}Person" />
|
|
||||||
|
|
||||||
<%-- Unlike other custom forms, this form does not allow edits of existing authors, so there are no
|
|
||||||
SPARQL queries for existing values. --%>
|
|
||||||
|
|
||||||
<%-- Data properties --%>
|
|
||||||
|
|
||||||
<v:jsonset var="newPersonFirstNameAssertion">
|
|
||||||
@prefix foaf: <${foaf}> .
|
|
||||||
?newPerson foaf:firstName ?firstName .
|
|
||||||
</v:jsonset>
|
|
||||||
|
|
||||||
<v:jsonset var="newPersonMiddleNameAssertion">
|
|
||||||
@prefix core: <${vivoCore}> .
|
|
||||||
?newPerson core:middleName ?middleName .
|
|
||||||
</v:jsonset>
|
|
||||||
|
|
||||||
<v:jsonset var="newPersonLastNameAssertion">
|
|
||||||
@prefix foaf: <${foaf}> .
|
|
||||||
?newPerson foaf:lastName ?lastName .
|
|
||||||
</v:jsonset>
|
|
||||||
|
|
||||||
<v:jsonset var="authorshipRankAssertion">
|
|
||||||
@prefix core: <${vivoCore}> .
|
|
||||||
?authorshipUri core:authorRank ?rank .
|
|
||||||
</v:jsonset>
|
|
||||||
|
|
||||||
<%-- This applies to both a new and an existing person --%>
|
|
||||||
<v:jsonset var="n3ForNewAuthorship">
|
|
||||||
@prefix core: <${vivoCore}> .
|
|
||||||
|
|
||||||
?authorshipUri a core:Authorship ;
|
|
||||||
core:linkedInformationResource ?infoResource ;
|
|
||||||
core:authorRank ?rank .
|
|
||||||
|
|
||||||
?infoResource core:informationResourceInAuthorship ?authorshipUri .
|
|
||||||
</v:jsonset>
|
|
||||||
|
|
||||||
<v:jsonset var="n3ForExistingPerson">
|
|
||||||
@prefix core: <${vivoCore}> .
|
|
||||||
?authorshipUri core:linkedAuthor ?personUri .
|
|
||||||
?personUri core:authorInAuthorship ?authorshipUri .
|
|
||||||
</v:jsonset>
|
|
||||||
|
|
||||||
<v:jsonset var="n3ForNewPerson">
|
|
||||||
@prefix foaf: <${foaf}> .
|
|
||||||
@prefix core: <${vivoCore}> .
|
|
||||||
|
|
||||||
?newPerson a foaf:Person ;
|
|
||||||
<${label}> ?label .
|
|
||||||
|
|
||||||
?authorshipUri core:linkedAuthor ?newPerson .
|
|
||||||
?newPerson core:authorInAuthorship ?authorshipUri .
|
|
||||||
</v:jsonset>
|
|
||||||
|
|
||||||
<v:jsonset var="personClassUriJson">${personClassUri}</v:jsonset>
|
|
||||||
|
|
||||||
<c:set var="returnPathAfterSubmit" value="/edit/editRequestDispatch.jsp?subjectUri=${subjectUri}&predicateUri=${predicateUri}" />
|
|
||||||
|
|
||||||
<c:set var="editjson" scope="request">
|
|
||||||
{
|
|
||||||
"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}"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</c:set>
|
|
||||||
|
|
||||||
<%
|
|
||||||
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<Individual> authorships = infoResource.getRelatedIndividuals(predicateUri);
|
|
||||||
|
|
||||||
List<String> customJs = new ArrayList<String>(Arrays.asList(JavaScript.JQUERY_UI.path(),
|
|
||||||
JavaScript.CUSTOM_FORM_UTILS.path(),
|
|
||||||
"/js/browserUtils.js",
|
|
||||||
"/edit/forms/js/addAuthorsToInformationResource1.js"
|
|
||||||
));
|
|
||||||
request.setAttribute("customJs", customJs);
|
|
||||||
|
|
||||||
List<String> customCss = new ArrayList<String>(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<String> ulClasses = new ArrayList<String>();
|
|
||||||
|
|
||||||
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, " ") + "\"";
|
|
||||||
}
|
|
||||||
%>
|
|
||||||
|
|
||||||
<c:set var="title" value="<em>${infoResourceName}</em>"/>
|
|
||||||
<c:set var="requiredHint" value="<span class='requiredHint'> *</span>" />
|
|
||||||
<c:set var="initialHint" value="<span class='hint'>(initial okay)</span>" />
|
|
||||||
|
|
||||||
<jsp:include page="${preForm}" />
|
|
||||||
|
|
||||||
<%-- DO NOT CHANGE IDS, CLASSES, OR HTML STRUCTURE ON THIS PAGE WITHOUT UNDERSTANDING THE IMPACT ON THE JAVASCRIPT! --%>
|
|
||||||
<h2>${title}</h2>
|
|
||||||
|
|
||||||
<%@ include file="unsupportedBrowserMessage.jsp" %>
|
|
||||||
|
|
||||||
<div class="noIE67">
|
|
||||||
<h3>Manage Authors</h3>
|
|
||||||
|
|
||||||
<ul id="authorships" <%= ulClass %>>
|
|
||||||
<%
|
|
||||||
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();
|
|
||||||
%>
|
|
||||||
<script type="text/javascript">
|
|
||||||
var authorshipData = [];
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<%
|
|
||||||
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"));
|
|
||||||
|
|
||||||
%>
|
|
||||||
<li class="authorship">
|
|
||||||
<%-- 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. --%>
|
|
||||||
<span class="author">
|
|
||||||
<%-- 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. --%>
|
|
||||||
<span class="authorNameWrapper">
|
|
||||||
<c:choose>
|
|
||||||
<c:when test="${!empty author}">
|
|
||||||
<c:set var="authorUri" value="${author.URI}" />
|
|
||||||
<c:set var="authorName" value="${author.name}" />
|
|
||||||
<c:url var="authorHref" value="/individual">
|
|
||||||
<c:param name="uri" value="${authorUri}"/>
|
|
||||||
</c:url>
|
|
||||||
<span class="authorName">${authorName}</span>
|
|
||||||
</c:when>
|
|
||||||
|
|
||||||
<c:otherwise>
|
|
||||||
<c:set var="authorUri" value="" />
|
|
||||||
<c:set var="authorName" value="" />
|
|
||||||
<c:url var="authorshipHref" value="/individual">
|
|
||||||
<c:param name="uri" value="${authorshipUri}"/>
|
|
||||||
</c:url>
|
|
||||||
<span class="authorName">${authorshipName}</span><em> (no linked author)</em>
|
|
||||||
</c:otherwise>
|
|
||||||
</c:choose>
|
|
||||||
</span>
|
|
||||||
<c:url var="deleteAuthorshipHref" value="/edit/primitiveDelete" />
|
|
||||||
<a href="${deleteAuthorshipHref}" class="remove">Remove</a>
|
|
||||||
<%-- <a href="${undoHref}" class="undo">Undo</a> --%>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
authorshipData.push({
|
|
||||||
"authorshipUri": "${authorshipUri}",
|
|
||||||
"authorUri": "${authorUri}",
|
|
||||||
"authorName": "${authorName}"
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<%
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
%>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<% if (authorshipCount == 0) { %>
|
|
||||||
<p>This publication currently has no authors specified.</p>
|
|
||||||
<% } %>
|
|
||||||
|
|
||||||
<div id="showAddForm">
|
|
||||||
<v:input type="submit" value="Add Author" id="showAddFormButton" cancel="true" cancelLabel="Return to Publication" cancelUrl="/individual" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%-- DO NOT CHANGE IDS, CLASSES, OR HTML STRUCTURE IN THIS FORM WITHOUT UNDERSTANDING THE IMPACT ON THE JAVASCRIPT! --%>
|
|
||||||
<form id="addAuthorForm" action="<c:url value="/edit/processRdfForm2.jsp"/>" >
|
|
||||||
|
|
||||||
<h3>Add an Author</h3>
|
|
||||||
|
|
||||||
<p class="inline"><v:input type="text" id="lastName" label="Last name ${requiredHint}" cssClass="acSelector" size="30" /></p>
|
|
||||||
<p class="inline"><v:input type="text" id="firstName" label="First name ${requiredHint} ${initialHint}" size="20" /></p>
|
|
||||||
<p class="inline"><v:input type="text" id="middleName" label="Middle name ${initialHint}" size="20" /></p>
|
|
||||||
<input type="hidden" id="label" name="label" value="" /> <!-- Field value populated by JavaScript -->
|
|
||||||
|
|
||||||
<div id="selectedAuthor" class="acSelection">
|
|
||||||
<%-- RY maybe make this a label and input field. See what looks best. --%>
|
|
||||||
<p class="inline"><label>Selected author: </label><span class="acSelectionInfo" id="selectedAuthorName"></span></p>
|
|
||||||
<input type="hidden" id="personUri" name="personUri" value="" /> <!-- Field value populated by JavaScript -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="hidden" name="rank" id="rank" value="${newRank}" />
|
|
||||||
<p class="submit"><v:input type="submit" id="submit" value="Add Author" cancel="true" /></p>
|
|
||||||
|
|
||||||
<p id="requiredLegend" class="requiredHint">* required fields</p>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<c:url var="acUrl" value="/autocomplete?type=${foaf}Person&tokenize=false&stem=false" />
|
|
||||||
<c:url var="reorderUrl" value="/edit/reorder" />
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
var customFormData = {
|
|
||||||
rankPredicate: '${rankPredicate}',
|
|
||||||
acUrl: '${acUrl}',
|
|
||||||
reorderUrl: '${reorderUrl}'
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<jsp:include page="${postForm}"/>
|
|
||||||
|
|
|
@ -5,11 +5,11 @@ var addAuthorForm = {
|
||||||
/* *** Initial page setup *** */
|
/* *** Initial page setup *** */
|
||||||
|
|
||||||
onLoad: function() {
|
onLoad: function() {
|
||||||
console.log($('#rank').val());
|
|
||||||
if (this.disableFormInUnsupportedBrowsers()) {
|
if (this.disableFormInUnsupportedBrowsers()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.mixIn();
|
this.mixIn();
|
||||||
this.initObjects();
|
this.initObjects();
|
||||||
this.initPage();
|
this.initPage();
|
||||||
},
|
},
|
||||||
|
@ -29,7 +29,7 @@ var addAuthorForm = {
|
||||||
},
|
},
|
||||||
|
|
||||||
mixIn: function() {
|
mixIn: function() {
|
||||||
// Mix in the custom form utility methods
|
// Mix in the custom form utility methods
|
||||||
$.extend(this, vitro.customFormUtils);
|
$.extend(this, vitro.customFormUtils);
|
||||||
|
|
||||||
// Get the custom form data from the page
|
// 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.
|
// 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.
|
// NB These must be assigned after the elements have been loaded onto the page.
|
||||||
initObjects: function() {
|
initObjects: function() {
|
||||||
|
|
||||||
this.form = $('#addAuthorForm');
|
this.form = $('#addAuthorForm');
|
||||||
this.showFormButtonWrapper = $('#showAddForm');
|
this.showFormButtonWrapper = $('#showAddForm');
|
||||||
this.showFormButton = $('#showAddFormButton');
|
this.showFormButton = $('#showAddFormButton');
|
||||||
this.removeAuthorshipLinks = $('a.remove');
|
this.removeAuthorshipLinks = $('a.remove');
|
||||||
//this.undoLinks = $('a.undo');
|
//this.undoLinks = $('a.undo');
|
||||||
this.submit = this.form.find(':submit');
|
this.submit = this.form.find(':submit');
|
||||||
this.cancel = this.form.find('.cancel');
|
this.cancel = this.form.find('.cancel');
|
||||||
this.labelField = $('#label');
|
this.labelField = $('#label');
|
||||||
this.firstNameField = $('#firstName');
|
this.firstNameField = $('#firstName');
|
||||||
|
@ -66,23 +66,23 @@ var addAuthorForm = {
|
||||||
|
|
||||||
this.initAuthorshipData();
|
this.initAuthorshipData();
|
||||||
|
|
||||||
// Show elements hidden by CSS for the non-JavaScript-enabled version.
|
// Show elements hidden by CSS for the non-JavaScript-enabled version.
|
||||||
// NB The non-JavaScript version of this form is currently not functional.
|
// NB The non-JavaScript version of this form is currently not functional.
|
||||||
this.removeAuthorshipLinks.show();
|
this.removeAuthorshipLinks.show();
|
||||||
|
|
||||||
//this.undoLinks.hide();
|
//this.undoLinks.hide();
|
||||||
|
|
||||||
this.bindEventListeners();
|
this.bindEventListeners();
|
||||||
|
|
||||||
this.initAutocomplete();
|
this.initAutocomplete();
|
||||||
|
|
||||||
this.initAuthorDD();
|
this.initAuthorDD();
|
||||||
|
|
||||||
if (this.findValidationErrors()) {
|
if (this.findValidationErrors()) {
|
||||||
this.initFormAfterInvalidSubmission();
|
this.initFormAfterInvalidSubmission();
|
||||||
} else {
|
} else {
|
||||||
this.initAuthorListOnlyView();
|
this.initAuthorListOnlyView();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -323,78 +323,29 @@ var addAuthorForm = {
|
||||||
// Reorder authors. Called on page load and after author drag-and-drop and remove.
|
// 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.
|
// Event and ui parameters are defined only in the case of drag-and-drop.
|
||||||
reorderAuthors: function(event, ui) {
|
reorderAuthors: function(event, ui) {
|
||||||
var predicateUri = '<' + this.rankPred + '>',
|
var authorships = $('li.authorship').map(function(index, el) {
|
||||||
rankXsdType = this.rankXsdType,
|
return $(this).data('authorshipUri');
|
||||||
additions = '',
|
}).get();
|
||||||
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);
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: addAuthorForm.reorderUrl,
|
url: addAuthorForm.reorderUrl,
|
||||||
data: {
|
data: {
|
||||||
additions: additions,
|
predicate: addAuthorForm.rankPredicate,
|
||||||
retractions: retractions
|
individuals: authorships
|
||||||
},
|
},
|
||||||
authorships: authorships,
|
traditional: true, // serialize the array of individuals for the server
|
||||||
processData: 'false',
|
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
success: function(data, status, request) {
|
success: function(data, status, request) {
|
||||||
var maxRank;
|
var pos;
|
||||||
$.each(authorships, function(index, obj) {
|
$('.authorship').each(function(index){
|
||||||
// find the authorship with this uri
|
pos = index + 1;
|
||||||
var authorship = addAuthorForm.findAuthorship('authorshipUri', obj.uri),
|
// Set the new position for this element. The only function of this value
|
||||||
// because all ranks have been reordered without gaps,
|
// is so we can reset an element to its original position in case reordering fails.
|
||||||
// we can get the position from the rank
|
addAuthorForm.setPosition(this, pos);
|
||||||
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'));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set the form rank field value.
|
// Set the form rank field value.
|
||||||
$('#rank').val(maxRank + 1);
|
$('#rank').val(pos + 1);
|
||||||
// console.log("value of rank field = " + $('#rank').val());
|
|
||||||
},
|
},
|
||||||
error: function(request, status, error) {
|
error: function(request, status, error) {
|
||||||
// ui is undefined on page load and after an authorship removal.
|
// ui is undefined on page load and after an authorship removal.
|
||||||
|
@ -442,33 +393,6 @@ var addAuthorForm = {
|
||||||
$(authorship).data('position', pos);
|
$(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) {
|
findAuthorship: function(key, value) {
|
||||||
var matchingAuthorship = $(); // if we don't find one, return an empty jQuery set
|
var matchingAuthorship = $(); // if we don't find one, return an empty jQuery set
|
||||||
|
|
||||||
|
@ -487,20 +411,20 @@ var addAuthorForm = {
|
||||||
/* *** Event listeners *** */
|
/* *** Event listeners *** */
|
||||||
|
|
||||||
bindEventListeners: function() {
|
bindEventListeners: function() {
|
||||||
|
|
||||||
this.showFormButton.click(function() {
|
this.showFormButton.click(function() {
|
||||||
addAuthorForm.initFormView();
|
addAuthorForm.initFormView();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.form.submit(function() {
|
this.form.submit(function() {
|
||||||
// NB Important JavaScript scope issue: if we call it this way, this = addAuthorForm
|
// NB Important JavaScript scope issue: if we call it this way, this = addAuthorForm
|
||||||
// in prepareSubmit. If we do this.form.submit(this.prepareSubmit); then
|
// in prepareSubmit. If we do this.form.submit(this.prepareSubmit); then
|
||||||
// this != addAuthorForm in prepareSubmit.
|
// this != addAuthorForm in prepareSubmit.
|
||||||
addAuthorForm.prepareSubmit();
|
addAuthorForm.prepareSubmit();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.lastNameField.blur(function() {
|
this.lastNameField.blur(function() {
|
||||||
// Cases where this event should be ignored:
|
// Cases where this event should be ignored:
|
||||||
// 1. personUri field has a value: the autocomplete select event has already fired.
|
// 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).
|
// 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 ) {
|
if ( addAuthorForm.personUriField.val() || !$(this).val() || $('ul.ui-autocomplete li.ui-menu-item').length ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addAuthorForm.onLastNameChange();
|
addAuthorForm.onLastNameChange();
|
||||||
});
|
});
|
||||||
|
|
||||||
// When hitting enter in last name field, show first and middle name fields.
|
// 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
|
// 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.
|
// 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) {
|
if (event.which === 13) {
|
||||||
addAuthorForm.onLastNameChange();
|
addAuthorForm.onLastNameChange();
|
||||||
return false; // don't submit form
|
return false; // don't submit form
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.removeAuthorshipLinks.click(function() {
|
this.removeAuthorshipLinks.click(function() {
|
||||||
addAuthorForm.removeAuthorship(this);
|
addAuthorForm.removeAuthorship(this);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// this.undoLinks.click(function() {
|
// this.undoLinks.click(function() {
|
||||||
// $.ajax({
|
// $.ajax({
|
||||||
// url: $(this).attr('href')
|
// url: $(this).attr('href')
|
||||||
// });
|
// });
|
||||||
// return false;
|
// return false;
|
||||||
// });
|
// });
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
prepareSubmit: function() {
|
prepareSubmit: function() {
|
||||||
|
@ -654,10 +578,10 @@ var addAuthorForm = {
|
||||||
|
|
||||||
// Disable DD and associated cues if only one author remains
|
// Disable DD and associated cues if only one author remains
|
||||||
disableAuthorDD: function() {
|
disableAuthorDD: function() {
|
||||||
var authorships = $('#authorships'),
|
var authorships = $('#authorships'),
|
||||||
authorNameWrapper = $('.authorNameWrapper');
|
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
|
// 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
|
// 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).
|
// adding an author via Ajax request).
|
||||||
authorships.removeClass('dd');
|
authorships.removeClass('dd');
|
||||||
|
|
||||||
authorNameWrapper.removeAttr('title');
|
authorNameWrapper.removeAttr('title');
|
||||||
},
|
},
|
||||||
|
|
||||||
// RY To be implemented later.
|
// RY To be implemented later.
|
||||||
toggleRemoveLink: function() {
|
toggleRemoveLink: function() {
|
||||||
// when clicking remove: remove the author, and change link text to 'undo'
|
// 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 undo: add the author back, and change link text to 'remove'
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 "<firstname> <lastname>", 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();
|
|
||||||
});
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue