NIHVIVO-1024 Reimplement educational training to use autocomplete rather than select list for related organization. This iteration has the form working like roles and position history forms, in two steps, with organization type selection in step 1. Next iteration will implement as single-step form.

This commit is contained in:
rjy7 2010-09-02 15:39:56 +00:00
parent 56856f0704
commit 4cd669ab0a
4 changed files with 170 additions and 604 deletions

View file

@ -1,9 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
#content form .existing {
clear: left;
}
#content form p.inline.year input {
margin-left: 9em;
}

View file

@ -1,441 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
/* RY In a later iteration of the custom form Javascript, we'll create a customForm object
* with subclasses for one-step and two-step forms. The parent object will contain
* the utilities used by all form types.
*/
/* Two-step custom form workflow:
*
* ADD new property form
* Step 1: Initial step, with choice to select existing or add new secondary individual.
* Displays:
* - On page load, unless there are validation error messages in the form
* - if there are validation error messages in the form, we are returning from a failed
* submission, and will go directly to view 2 to display the error messages.
* - After cancelling out of step 2
*
* Step 2: Main data entry step
* Displays:
* - On page load after an attempted submission that fails validation
* - After clicking button or add new link in view 1
* Has three view variations:
* - Select an existing secondary individual view
* - Add new secondary individual view
* - Combined view, if we are returning from a failed validation and can't determine
* which variant of view 2 we had submitted the form from. Contains the select
* existing element plus the add new link.
*
* EDIT existing property form
* View variations are like one-step form, though button text is specific to edit version.
*
*
* We're jerry-rigging one-step forms into the two-step form process due to time constraints.
* In a later iteration of the custom form Javascript, we'll create a customForm object
* with subclasses for one-step and two-step forms. The parent object will contain
* the utilities used by all form types. The two-step edit form will be a type of one-step form.
*
* One-step custom form workflow:
*
* Has two view variations:
* - Combined view, as above for two step form. This is the default view for
* the one-step form, which shows unless we have clicked the add new link
* or are returning from a validation error where we had been in the add new view.
* - Add new secondary individual view. As above for two step form, but add new
* box contains a close link to return to combined view.
*/
var customForm = {
views: {
ADD_STEP_ONE: 1, // not 0, else can't test if (!view)
ADD_NEW: 2,
SELECT_EXISTING: 3,
COMBINED: 4
},
onLoad: function() {
this.mixIn();
this.initObjects();
this.adjustForJs();
this.initForm();
},
mixIn: function() {
// Mix in the custom form utility methods
vitro.utils.borrowMethods(vitro.customFormUtils, this);
},
// 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 = $('#content form');
this.button = $('#submit');
this.or = $('span.or');
this.requiredLegend = $('#requiredLegend');
// These may need to be changed to classes rather than ids, if there are
// multiple sets of divs to show/hide during the workflow.
this.addNewLink = $('.addNewLink');
this.existing = $('.existing');
this.existingSelect = this.existing.children('select');
this.addNew = $('.new');
this.entry = $('.entry');
this.existingOrNew = $('.existingOrNew'); // just the word "or" between existing and add new
this.returnViewField = $("input[name='view']");
this.cancel = this.form.find('.cancel');
// Read values used to control display
this.editType = $("input[name='editType']").val();
this.entryType = $("input[name='entryType']").val().capitalizeWords();
this.secondaryType = $("input[name='secondaryType']").val().capitalizeWords();
// Enforce one step for edit forms, in case the form forgets to
this.formSteps = this.editType === 'edit' ? '1' : $("input[name='steps']").val();
this.returnView = parseInt(this.returnViewField.val()); // returns NaN for empty string
},
// 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() {
var selectExistingLabel = $('.existing label');
selectExistingLabel.html(selectExistingLabel.html().replace(/Select (Existing )?/, ''));
this.existingOrNew.hide();
this.toggleRequiredHints('show', this.addNew);
// The close link in the addNew div closes the addNew div and restores the
// combined view. It is needed for the one-step add form and the edit form
// (which is a one-step form), but not for the two-step add form, since we'd
// want it to restore step 1, but the Cancel link at the bottom of the form
// already performs that function.
if (this.formSteps == 1) {
this.addNew.prepend('<a class="close" href="#">cancel</a>');
}
this.close = this.form.find('.close');
},
initForm: function() {
//Adding a new entry
if (this.editType === 'add') {
this.initAddForm();
// Editing an existing entry
} else {
this.initEditForm();
}
},
/***** ADD form *****/
// Set up add form on page load, or when returning to initial state from step 2
initAddForm: function() {
this.defaultButtonText = 'Create ' + this.entryType;
this.addNewButtonText = 'Create ' + this.secondaryType + ' & ' + this.entryType;
// If a returnView has been specified in the hidden input field, it means we are
// returning from a failed submission due to validation errors. We need to restore
// the view we were on when the form was submitted.
if (this.returnView) {
this.doAddFormStep2(this.returnView);
} else {
this.doAddFormStep1();
}
},
// Reset add form to initial state (step 1) after cancelling out of step 2
resetAddFormToStep1: function() {
customForm.resetForm();
customForm.doAddFormStep1();
},
// Set up the add form for step 1
doAddFormStep1: function() {
if (this.formSteps == 1) {
customForm.doAddFormStep2(customForm.views.COMBINED);
customForm.doClose();
return;
}
customForm.existing.show();
customForm.toggleRequiredHints('hide', customForm.existing);
customForm.addNewLink.show();
customForm.hideFields(customForm.addNew);
customForm.hideFields(customForm.entry);
customForm.requiredLegend.hide();
customForm.button.hide();
customForm.or.hide();
customForm.setReturnView(customForm.views.ADD_STEP_ONE);
// Assign event listeners
customForm.existingSelect.bind('change', function() {
if ($(this).val() != '') {
customForm.doAddFormStep2(customForm.views.SELECT_EXISTING);
return false;
}
});
// Note that addNewLink event listener is different
// in different views.
customForm.addNewLink.bind('click', function() {
customForm.doAddFormStep2(customForm.views.ADD_NEW);
});
},
// Set up add form for step 2. If no view is passed in, we're returning
// from a failed submission due to validation errors, and will attempt to
// determine the previous view from the form data that's been entered.
doAddFormStep2: function(view) {
switch (view) {
case customForm.views.SELECT_EXISTING: { fn = customForm.doAddFormStep2SelectExisting; break; }
case customForm.views.ADD_NEW: { fn = customForm.doAddFormStep2AddNew; break; }
default: { fn = customForm.doAddFormStep2Combined; break; }
}
fn.call(customForm);
customForm.button.show();
customForm.or.show();
customForm.toggleRequiredHints('show', customForm.existing, customForm.addNew);
},
// Most methods below use 'customForm' rather than 'this', because 'this' doesn't reference
// customForm when the method is called from an event listener. Only if the method never
// gets called from an event listener can we use the 'this' reference.
// Step 2: selecting an existing individual
doAddFormStep2SelectExisting: function() {
if (customForm.formSteps == 1) {
customForm.doAddFormStep2Combined();
return;
}
customForm.showSelectExistingFields();
// This hint shows in step 2 but not in step 1
customForm.toggleRequiredHints('show', customForm.existing);
customForm.doButtonForStep2(customForm.defaultButtonText);
customForm.doCancelForStep2();
customForm.setReturnView(customForm.views.SELECT_EXISTING);
},
// Step 2: adding a new individual
doAddFormStep2AddNew: function() {
customForm.showAddNewFields();
customForm.doButtonForStep2(customForm.addNewButtonText);
customForm.doCancelForStep2();
customForm.doClose();
customForm.setReturnView(customForm.views.ADD_NEW);
},
// Step 2: combined view, when we are returning from validation errors and we
// can't determine which view of the form we had been on.
doAddFormStep2Combined: function() {
customForm.showCombinedFields();
customForm.doAddNewLinkForCombinedView();
customForm.doButtonForStep2(customForm.defaultButtonText);
customForm.doCancelForStep2();
customForm.setReturnView(customForm.views.COMBINED);
},
/***** Edit form *****/
initEditForm: function() {
this.defaultButtonText = 'Save Changes';
this.addNewButtonText = 'Create ' + this.secondaryType + ' & Save Changes';
this.toggleRequiredHints('show', this.existing);
switch (this.returnView) {
case this.views.ADD_NEW: { fn = this.doEditFormAddNew; break; }
default: { fn = this.doEditFormCombinedView; break; }
}
// Remember the original org. If we click the add new org link
// but then cancel out of it, we want to restore this value.
this.originalOrg = this.existingSelect.val();
// But we only want to restore the original value from when the
// form loaded. If we've already changed to a new value, we don't
// want to restore that.
this.existingSelect.bind('change', function() {
customForm.originalOrg = null;
});
fn.call(customForm);
},
doEditFormAddNew: function() {
this.showAddNewFields();
this.button.val(this.addNewButtonText);
this.setReturnView(this.views.ADD_NEW);
this.doClose();
},
doEditFormCombinedView: function() {
this.showCombinedFields();
this.button.val(this.defaultButtonText);
this.doAddNewLinkForCombinedView();
this.setReturnView(this.views.COMBINED);
},
unbindEventListeners: function() {
customForm.cancel.unbind('click');
customForm.button.unbind('click');
customForm.addNewLink.unbind('click');
customForm.close.unbind('click');
customForm.existingSelect.unbind('change');
},
// Add event listener to the submit button in step 2
doButtonForStep2: function(text) {
customForm.button.unbind('click');
customForm.button.val(text);
},
// Add event listener to the cancel link in step 2
doCancelForStep2: function() {
if (customForm.formSteps == 1) { return; }
customForm.cancel.unbind('click');
customForm.cancel.bind('click', function() {
customForm.resetAddFormToStep1();
return false;
});
},
doAddNewLinkForCombinedView: function() {
customForm.addNewLink.unbind('click');
customForm.addNewLink.bind('click', function() {
$(this).hide();
// Make sure to clear out what's in the existing select element,
// else it could be submitted even when hidden.
// RY When we have multiple existing and addNew divs, we won't
// show/hide them all, only the siblings of the addNewLink.
// And we'll need to figure out the button text based on which
// div we're opening.
customForm.hideFields(customForm.existing);
customForm.addNew.show();
customForm.button.val(customForm.addNewButtonText);
customForm.doClose();
customForm.setReturnView(customForm.views.ADD_NEW);
return false;
});
},
doClose: function() {
customForm.close.unbind('click');
customForm.close.bind('click', function() {
// RY When we have multiple existing and addNew divs, we won't
// show/hide them all, only the siblings of the addNewLink.
customForm.existing.show();
customForm.hideFields(customForm.addNew);
customForm.addNewLink.show();
customForm.button.val(customForm.defaultButtonText);
customForm.doAddNewLinkForCombinedView();
customForm.setReturnView(customForm.views.COMBINED);
if (customForm.originalOrg) {
customForm.existingSelect.val(customForm.originalOrg);
}
return false;
});
},
resetForm: function() {
// Clear all form data and error messages
customForm.clearFormData();
// Remove previously bound event handlers
customForm.unbindEventListeners();
},
showSelectExistingFields: function() {
customForm.existing.show();
customForm.addNewLink.hide();
customForm.hideFields(customForm.addNew);
customForm.showFieldsForAllViews();
// Adjust the validation error that has been inserted by the server, which
// is phrased appropriately for the non-Javascript version of the form.
$('#organizationUri_validationError').html('Must select an organization.');
},
showAddNewFields: function() {
customForm.hideFields(customForm.existing);
customForm.addNewLink.hide();
customForm.addNew.show();
customForm.showFieldsForAllViews();
// Adjust the validation error that has been inserted by the server, which
// is phrased appropriately for the non-Javascript version of the form.
$('#newOrgName_validationError').html('Must specify an organization.');
},
// This version of the form shows both the existing select and add new link.
// Used when loading edit form, and when returning from failed submission
// of add form when we can't determine which view was being used to make
// the submission.
showCombinedFields: function() {
customForm.existing.show();
customForm.addNewLink.show();
customForm.addNewLink.css('margin-bottom', '1em');
customForm.hideFields(customForm.addNew);
customForm.showFieldsForAllViews();
},
// Show fields that appear in all views for add form step 2 and edit form
showFieldsForAllViews: function() {
customForm.entry.show();
customForm.requiredLegend.show();
},
toggleRequiredHints: function(action /* elements */) {
var hints,
selector = 'span.requiredHint',
numArgs = arguments.length;
if (numArgs < 2) {
return;
}
hints = arguments[1].find(selector);
for (var i = 2; i < numArgs; i++) {
hints.add(arguments[i].find(selector));
}
action == 'show' ? hints.show() : hints.hide();
},
// Set the hidden input field indicating the view to return to if
// the submission fails due to validation errors.
setReturnView: function(value) {
customForm.returnViewField.val(value);
}
};
$(document).ready(function() {
customForm.onLoad();
});

View file

@ -47,9 +47,10 @@ core:dateTimePrecision (DateTimeValue : DateTimeValuePrecision)
<%@ 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.edit.n3editing.PersonHasPositionValidator"%>
<%@ page import="org.apache.commons.logging.Log" %>
<%@ page import="org.apache.commons.logging.LogFactory" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.JavaScript" %>
<%@ page import="edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Css" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%>
<%@ taglib prefix="v" uri="http://vitro.mannlib.cornell.edu/vitro/tags" %>
@ -72,23 +73,14 @@ core:dateTimePrecision (DateTimeValue : DateTimeValuePrecision)
<c:set var="orgClass" value="http://xmlns.com/foaf/0.1/Organization" />
<c:set var="degreeClass" value="${vivoCore}AcademicDegree" />
<%-- Data properties --%>
<%-- Then enter a SPARQL query for each field, by convention concatenating the field id with "Existing"
to convey that the expression is used to retrieve any existing value for the field in an existing individual.
Each of these must then be referenced in the sparqlForExistingLiterals section of the JSON block below
and in the literalsOnForm --%>
<%-- Define predicates used in n3 assertions and sparql queries --%>
<c:set var="majorFieldPred" value="${vivoCore}majorField" />
<v:jsonset var="majorFieldExisting" >
SELECT ?majorFieldExisting WHERE {
?edTrainingUri <${majorFieldPred}> ?majorFieldExisting }
</v:jsonset>
<%-- Pair the "existing" query with the skeleton of what will be asserted for a new statement involving this field.
The actual assertion inserted in the model will be created via string substitution into the ? variables.
NOTE the pattern of punctuation (a period after the prefix URI and after the ?field) --%>
<v:jsonset var="majorFieldAssertion" >
?edTrainingUri <${majorFieldPred}> ?majorField .
</v:jsonset>
<c:set var="yearPred" value="${vivoCore}year" />
<c:set var="deptPred" value="${vivoCore}departmentOrSchool" />
<c:set var="infoPred" value="${vivoCore}supplementalInformation" />
<c:set var="degreeEarned" value="${vivoCore}degreeEarned" />
<c:set var="degreeOutcomeOf" value="${vivoCore}degreeOutcomeOf" />
<c:set var="orgGrantingDegree" value="${vivoCore}organizationGrantingDegree" />
<%-- For new datetime handling in ontology - v1.2
<c:set var="dateTimeValue" value="${vivoCore}DateTimeValue" />
@ -96,96 +88,112 @@ core:dateTimePrecision (DateTimeValue : DateTimeValuePrecision)
<c:set var="precisionValue" value="${vivoCore}YearPrecision" />
<c:set var="hasPrecision" value="${vivoCore}dateTimePrecision" />
<v:jsonset var="yearExisting" >
<v:jsonset var="existingYearQuery" >
SELECT ?existingYear WHERE {
?edTrainingUri <${hasDateTimeValue}> ?existingYear }
?edTraining <${hasDateTimeValue}> ?existingYear . }
</v:jsonset>
<v:jsonset var="yearAssertion" >
@prefix core: <${vivoCore}> .
?dateTime a core:DateTimeValue ;
core:dateTime ?year ;
core:dateTimeValuePrecision core:YearPrecision .
?edTrainingUri core:dateTimeValue ?dateTime .
?edTraining core:dateTimeValue ?dateTime .
</v:jsonset>
--%>
<c:set var="yearPred" value="${vivoCore}year" />
<v:jsonset var="yearExisting" >
SELECT ?existingYear WHERE {
?edTrainingUri <${yearPred}> ?existingYear }
</v:jsonset>
<v:jsonset var="yearAssertion" >
?edTrainingUri <${yearPred}> ?year .
<%-- Assertions for adding a new educational training entry --%>
<v:jsonset var="orgTypeAssertion">
?org a ?orgType .
</v:jsonset>
<c:set var="deptPred" value="${vivoCore}departmentOrSchool" />
<v:jsonset var="deptExisting" >
SELECT ?existingDept WHERE {
?edTrainingUri <${deptPred}> ?existingDept }
</v:jsonset>
<v:jsonset var="deptAssertion" >
?edTrainingUri <${deptPred}> ?dept .
<v:jsonset var="orgLabelAssertion">
?org <${label}> ?orgLabel .
</v:jsonset>
<c:set var="infoPred" value="${vivoCore}supplementalInformation" />
<v:jsonset var="infoExisting" >
SELECT ?existingInfo WHERE {
?edTrainingUri <${infoPred}> ?existingInfo }
</v:jsonset>
<v:jsonset var="infoAssertion" >
?edTrainingUri <${infoPred}> ?info .
</v:jsonset>
<%-- Object properties --%>
<%-- Note there is really no difference in how things are set up for an object property except
below in the n3ForEdit section, in whether the ..Existing variable goes in SparqlForExistingLiterals
or in the SparqlForExistingUris, as well as perhaps in how the options are prepared --%>
<c:set var="degreeEarned" value="${vivoCore}degreeEarned" />
<c:set var="degreeOutcomeOf" value="${vivoCore}degreeOutcomeOf" />
<v:jsonset var="degreeExisting" >
SELECT ?existingDegreeUri WHERE {
?edTrainingUri <${degreeEarned}> ?existingDegreeUri }
</v:jsonset>
<v:jsonset var="degreeAssertion" >
?edTrainingUri <${degreeEarned}> ?degreeUri .
?degreeUri <${degreeOutcomeOf}> ?edTrainingUri .
?edTraining <${degreeEarned}> ?degree .
?degree <${degreeOutcomeOf}> ?edTraining .
</v:jsonset>
<c:set var="orgGrantingDegree" value="${vivoCore}organizationGrantingDegree" />
<%-- This property has no inverse --%>
<v:jsonset var="organizationUriExisting" >
SELECT ?existingOrgUri WHERE {
?edTrainingUri <${orgGrantingDegree}> ?existingOrgUri }
</v:jsonset>
<v:jsonset var="organizationUriAssertion" >
?edTrainingUri <${orgGrantingDegree}> ?organizationUri .
<v:jsonset var="majorFieldAssertion" >
?edTraining <${majorFieldPred}> ?majorField .
</v:jsonset>
<v:jsonset var="newOrgNameAssertion">
?newOrg <${label}> ?newOrgName .
</v:jsonset>
<%-- Break up the new org type and subclass assertions, so that if there is no subclass,
the org type still gets asserted. --%>
<v:jsonset var="newOrgTypeAssertion">
?newOrg a ?newOrgType .
<v:jsonset var="yearAssertion" >
?edTraining <${yearPred}> ?year .
</v:jsonset>
<v:jsonset var="n3ForStmtToPerson">
<v:jsonset var="deptAssertion" >
?edTraining <${deptPred}> ?dept .
</v:jsonset>
<v:jsonset var="infoAssertion" >
?edTraining <${infoPred}> ?info .
</v:jsonset>
<v:jsonset var="n3ForNewEdTraining">
@prefix core: <${vivoCore}> .
?person core:educationalTraining ?edTrainingUri .
?person core:educationalTraining ?edTraining .
?edTrainingUri core:educationalTrainingOf ?person ;
a core:EducationalTraining .
?edTraining a core:EducationalTraining ;
core:educationalTrainingOf ?person ;
<${orgGrantingDegree}> ?org .
</v:jsonset>
<v:jsonset var="n3ForNewOrg">
?newOrg <${label}> ?newOrgName ;
a ?newOrgType .
?edTrainingUri <${orgGrantingDegree}> ?newOrg .
<%-- This property has no inverse --%>
<v:jsonset var="n3ForEdTrainingToOrg" >
?edTraining <${orgGrantingDegree}> ?org .
</v:jsonset>
<%-- Queries for editing an existing educational training entry --%>
<v:jsonset var="orgQuery" >
SELECT ?existingOrg WHERE {
?edTraining <${orgGrantingDegree}> ?existingOrg . }
</v:jsonset>
<v:jsonset var="orgLabelQuery" >
SELECT ?existingOrgLabel WHERE {
?edTraining <${orgGrantingDegree}> ?existingOrg .
?existingOrg <${label}> ?existingOrgLabel .
}
</v:jsonset>
<v:jsonset var="orgTypeQuery" >
SELECT ?existingOrgType WHERE {
?edTraining <${orgGrantingDegree}> ?existingOrg .
?existingOrg a ?existingOrgType .
}
</v:jsonset>
<v:jsonset var="degreeQuery" >
SELECT ?existingDegree WHERE {
?edTraining <${degreeEarned}> ?existingDegree . }
</v:jsonset>
<v:jsonset var="majorFieldQuery" >
SELECT ?existingMajorField WHERE {
?edTraining <${majorFieldPred}> ?existingMajorField . }
</v:jsonset>
<v:jsonset var="yearQuery" >
SELECT ?existingYear WHERE {
?edTraining <${yearPred}> ?existingYear . }
</v:jsonset>
<v:jsonset var="deptQuery" >
SELECT ?existingDept WHERE {
?edTraining <${deptPred}> ?existingDept . }
</v:jsonset>
<v:jsonset var="infoQuery" >
SELECT ?existingInfo WHERE {
?edTraining <${infoPred}> ?existingInfo . }
</v:jsonset>
<v:jsonset var="orgClassUriJson">${orgClass}</v:jsonset>
<v:jsonset var="degreeClassUriJson">${degreeClass}</v:jsonset>
@ -197,36 +205,38 @@ the org type still gets asserted. --%>
"subject" : ["person", "${subjectUriJson}" ],
"predicate" : ["predicate", "${predicateUriJson}" ],
"object" : ["edTrainingUri", "${objectUriJson}", "URI" ],
"object" : ["edTraining", "${objectUriJson}", "URI" ],
"n3required" : [ "${n3ForStmtToPerson}", "${majorFieldAssertion}" ],
"n3required" : [ "${n3ForNewEdTraining}", "${majorFieldAssertion}" ],
"n3optional" : [ "${organizationUriAssertion}", "${n3ForNewOrg}",
"${newOrgNameAssertion}", "${newOrgTypeAssertion}",
"n3optional" : [ "${n3ForEdTrainingToOrg}",
"${orgLabelAssertion}", "${orgTypeAssertion}",
"${degreeAssertion}", "${deptAssertion}", "${infoAssertion}", "${yearAssertion}" ],
"newResources" : { "edTrainingUri" : "${defaultNamespace}",
"newOrg" : "${defaultNamespace}" },
"newResources" : { "edTraining" : "${defaultNamespace}",
"org" : "${defaultNamespace}" },
"urisInScope" : { },
"literalsInScope": { },
"urisOnForm" : [ "organizationUri", "newOrgType", "degreeUri" ],
"literalsOnForm" : [ "majorField", "year", "dept", "info", "newOrgName"],
"urisOnForm" : [ "org", "orgType", "degree" ],
"literalsOnForm" : [ "orgLabel", "majorField", "year", "dept", "info" ],
"filesOnForm" : [ ],
"sparqlForLiterals" : { },
"sparqlForUris" : { },
"sparqlForExistingLiterals" : {
"majorField" : "${majorFieldExisting}",
"year" : "${yearExisting}",
"dept" : "${deptExisting}",
"info" : "${infoExisting}"
"orgLabel" : "${orgLabelQuery}",
"majorField" : "${majorFieldQuery}",
"year" : "${yearQuery}",
"dept" : "${deptQuery}",
"info" : "${infoQuery}"
},
"sparqlForExistingUris" : {
"organizationUri" : "${organizationUriExisting}",
"degreeUri" : "${degreeExisting}"
"org" : "${orgQuery}",
"orgType" : "${orgTypeQuery}",
"degree" : "${degreeQuery}"
},
"fields" : {
"degreeUri" : {
"degree" : {
"newResource" : "false",
"validators" : [ ],
"optionsType" : "INDIVIDUALS_VIA_VCLASS",
@ -259,7 +269,7 @@ the org type still gets asserted. --%>
"rangeLang" : "",
"assertions" : ["${yearAssertion}"]
},
"organizationUri" : {
"org" : {
"newResource" : "false",
"validators" : [ ],
"optionsType" : "INDIVIDUALS_VIA_VCLASS",
@ -268,9 +278,9 @@ the org type still gets asserted. --%>
"objectClassUri" : "${orgClassUriJson}",
"rangeDatatypeUri" : "",
"rangeLang" : "",
"assertions" : [ "${organizationUriAssertion}" ]
"assertions" : [ "${n3ForEdTrainingToOrg}" ]
},
"newOrgName" : {
"orgLabel" : {
"newResource" : "false",
"validators" : [ ],
"optionsType" : "UNDEFINED",
@ -279,9 +289,9 @@ the org type still gets asserted. --%>
"objectClassUri" : "",
"rangeDatatypeUri" : "${stringDatatypeUriJson}",
"rangeLang" : "",
"assertions" : [ "${n3ForNewOrg}" ]
"assertions" : [ "${orgLabelAssertion}" ]
},
"newOrgType" : {
"orgType" : {
"newResource" : "false",
"validators" : [ ],
"optionsType" : "CHILD_VCLASSES",
@ -290,7 +300,7 @@ the org type still gets asserted. --%>
"objectClassUri" : "${orgClassUriJson}",
"rangeDatatypeUri" : "",
"rangeLang" : "",
"assertions" : [ "${newOrgTypeAssertion}" ]
"assertions" : [ "${orgTypeAssertion}" ]
},
"dept" : {
"newResource" : "false",
@ -326,8 +336,6 @@ the org type still gets asserted. --%>
EditConfiguration.putConfigInSession(editConfig,session);
}
editConfig.addValidator(new PersonHasPositionValidator());
Model model = (Model) application.getAttribute("jenaOntModel");
String objectUri = (String) request.getAttribute("objectUri");
if (objectUri != null) { // editing existing
@ -343,79 +351,87 @@ the org type still gets asserted. --%>
<%
if (objectUri != null) { // editing existing entry
%>
<c:set var="editType" value="edit" />
<c:set var="editMode" value="edit" />
<c:set var="titleVerb" value="Edit" />
<c:set var="title" value="Edit educational background entry for ${subjectName}" />
<%-- NB This will be the button text when Javascript is disabled. --%>
<c:set var="submitLabel" value="Save Changes" />
<c:set var="submitButtonText" value="Edit Educational Training" />
<c:set var="disabledVal" value="disabled" />
<%
} else { // adding new entry
%>
<c:set var="editType" value="add" />
<c:set var="title" value="Create educational background entry for ${subjectName}" />
<%-- NB This will be the button text when Javascript is disabled. --%>
<c:set var="submitLabel" value="Create Educational Background" />
<c:set var="editMode" value="add" />
<c:set var="titleVerb" value="Create" />
<c:set var="submitButtonText" value="Educational Training" />
<c:set var="disabledVal" value="" />
<% }
List<String> customJs = new ArrayList<String>(Arrays.asList("/js/utils.js",
"/js/customFormUtils.js",
"/edit/forms/js/customForm.js"
//, "/edit/forms/js/customFormOneStep.js"
));
List<String> customJs = new ArrayList<String>(Arrays.asList(JavaScript.JQUERY_UI.path(),
JavaScript.CUSTOM_FORM_UTILS.path(),
"/edit/forms/js/customFormWithAutocomplete.js"
));
request.setAttribute("customJs", customJs);
List<String> customCss = new ArrayList<String>(Arrays.asList("/edit/forms/css/customForm.css",
"/edit/forms/css/personHasEducationalTraining.css"
));
request.setAttribute("customCss", customCss);
List<String> customCss = new ArrayList<String>(Arrays.asList(Css.JQUERY_UI.path(),
Css.CUSTOM_FORM.path(),
"/edit/forms/css/autocomplete.css",
"/edit/forms/css/customFormWithAutocomplete.css"
));
request.setAttribute("customCss", customCss);
%>
<c:set var="requiredHint" value="<span class='requiredHint'> *</span>" />
<c:set var="view" value='<%= vreq.getAttribute("view") %>' />
<c:set var="yearHint" value="<span class='hint'>(YYYY)</span>" />
<jsp:include page="${preForm}" />
<h2>${title}</h2>
<h2>${titleVerb}&nbsp;educational training entry for <%= subjectName %></h2>
<form class="${editType}" action="<c:url value="/edit/processRdfForm2.jsp"/>" >
<form action="<c:url value="/edit/processRdfForm2.jsp"/>" >
<div class="entry">
<v:input type="select" label="Degree" id="degreeUri" />
<v:input type="text" label="Major Field of Degree ${requiredHint}" id="majorField" size="30" />
<p class="inline year"><v:input type="text" label="Year <span class='hint'>(YYYY)</span>" id="year" size="4" /></p>
</div>
<div class="relatedIndividual">
<div class="existing">
<v:input type="select" label="Organization Granting Degree ${requiredHint}" id="organizationUri" /><span class="existingOrNew">or</span>
<p class="inline"><v:input type="select" label="Organization Type ${requiredHint}" name="orgType" disabled="${disabledVal}" id="typeSelector" /></p>
<div class="fullViewOnly">
<p><v:input type="text" id="relatedIndLabel" name="orgLabel" label="Name ${requiredHint}" cssClass="acSelector" disabled="${disabledVal}" size="50" /></p>
<%-- Store these values in hidden fields, because the displayed fields are disabled and don't submit. This ensures that when
returning from a validation error, we retain the values. --%>
<c:if test="${editMode == 'edit'}">
<v:input type="hidden" id="orgType" />
<v:input type="hidden" id="orgLabel" />
</c:if>
<div class="acSelection">
<%-- RY maybe make this a label and input field. See what looks best. --%>
<p class="inline"><label></label><span class="acSelectionInfo"></span> <a href="<c:url value="/individual?uri=" />" class="verifyMatch">(Verify this match)</a></p>
<v:input type="hidden" id="org" cssClass="acUriReceiver" /> <!-- Field value populated by JavaScript -->
</div>
<div class="addNewLink">
If your organization is not listed, please <a href="#">add a new organization</a>.
</div>
<div class="new">
<h6>Add a New Organization</h6>
<v:input type="text" label="Organization Name ${requiredHint}" id="newOrgName" size="30" />
<v:input type="select" label="Select Organization Type ${requiredHint}" id="newOrgType" />
</div>
</div>
<div class="entry">
<v:input type="select" label="Degree" id="degree" />
<v:input type="text" label="Major Field of Degree ${requiredHint}" id="majorField" size="30" />
<v:input type="text" label="Year ${yearHint}" id="year" size="4" />
<v:input type="text" label="Department or School Name within the Organization" id="dept" size="50" />
<v:input type="text" label="Supplemental Information" id="info" size="50" />
<p>e.g., <em>Postdoctoral training</em> or <em>Transferred</em></p>
</div>
<!-- Processing information for Javascript -->
<input type="hidden" name="editType" value="${editType}" />
<input type="hidden" name="entryType" value="educational background" />
<input type="hidden" name="secondaryType" value="organization" />
<input type="hidden" name="steps" value="1" />
<input type="hidden" name="view" value="${view}" />
<p class="submit"><v:input type="submit" id="submit" value="${submitLabel}" cancel="true"/></p>
<p class="submit"><v:input type="submit" id="submit" value="${submitButtonText}" cancel="true"/></p>
<p id="requiredLegend" class="requiredHint">* required fields</p>
</form>
<c:url var="acUrl" value="/autocomplete?tokenize=true&stem=true" />
<script type="text/javascript">
var customFormData = {
acUrl: '${acUrl}',
editMode: '${editMode}',
submitButtonTextType: 'compound'
};
</script>
<jsp:include page="${postForm}"/>

View file

@ -314,7 +314,7 @@
<h2>${titleVerb}&nbsp;position entry for <%= subjectName %></h2>
<form class="${editMode}" action="<c:url value="/edit/processRdfForm2.jsp"/>" >
<form action="<c:url value="/edit/processRdfForm2.jsp"/>" >
<p class="inline"><v:input type="select" label="Organization Type ${requiredHint}" name="orgType" disabled="${disabledVal}" id="typeSelector" /></p>