autocomplete data property editing - NIHVIVO-3386
This commit is contained in:
parent
aedb1305a1
commit
a38848b5b6
6 changed files with 617 additions and 7 deletions
|
@ -906,6 +906,15 @@
|
|||
<url-pattern>/populateselect</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>DataAutocompleteController</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.search.controller.DataAutocompleteController</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>DataAutocompleteController</servlet-name>
|
||||
<url-pattern>/dataautocomplete</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>ReorderController</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.ReorderController</servlet-class>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||
|
||||
<#-- Individual profile page template for foaf:Person individuals -->
|
||||
|
||||
<#include "individual-setup.ftl">
|
||||
<#import "individual-qrCodeGenerator.ftl" as qr>
|
||||
<#import "lib-vivo-properties.ftl" as vp>
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||
|
||||
<#--If edit submission exists, then retrieve validation errors if they exist-->
|
||||
<#if editSubmission?has_content && editSubmission.submissionExists = true && editSubmission.validationErrors?has_content>
|
||||
<#assign submissionErrors = editSubmission.validationErrors/>
|
||||
</#if>
|
||||
|
||||
<#assign sparqlForAcFilter = editConfiguration.pageData.sparqlForAcFilter />
|
||||
<#assign editMode = editConfiguration.pageData.editMode />
|
||||
|
||||
<h2>${editConfiguration.formTitle}</h2>
|
||||
|
||||
<#--Display error messages if any-->
|
||||
<#if submissionErrors?has_content>
|
||||
<section id="error-alert" role="alert">
|
||||
<img src="${urls.images}/iconAlert.png" width="24" height="24" alert="Error alert icon" />
|
||||
<p>
|
||||
|
||||
<#list submissionErrors?keys as errorFieldName>
|
||||
${submissionErrors[errorFieldName]}
|
||||
</#list>
|
||||
|
||||
</p>
|
||||
</section>
|
||||
</#if>
|
||||
|
||||
<#assign literalValues = "${editConfiguration.dataLiteralValuesAsString}" />
|
||||
|
||||
<form class="customForm" action = "${submitUrl}" method="post">
|
||||
<input type="hidden" name="editKey" id="editKey" value="${editKey}" role="input" />
|
||||
<#if editConfiguration.dataPredicatePublicDescription?has_content>
|
||||
<label for="${editConfiguration.dataLiteral}"><p class="propEntryHelpText">${editConfiguration.dataPredicatePublicDescription}</p></label>
|
||||
</#if>
|
||||
|
||||
<p>
|
||||
<input class="acSelector" size="50" type="text" id="literal" name="literal" value="${literalValues}" />
|
||||
</p>
|
||||
|
||||
<div class="acSelection">
|
||||
<p class="inline">
|
||||
<label>Selected:</label>
|
||||
<span class="acSelectionInfo"></span>
|
||||
|
||||
<a href="#" class="cancel">(Change selection)</a>
|
||||
</p>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<input type="submit" id="submit" value="${editConfiguration.submitLabel}" role="button"/>
|
||||
<span class="or"> or </span>
|
||||
<a title="Cancel" href="${cancelUrl}">Cancel</a>
|
||||
|
||||
</form>
|
||||
|
||||
<#if editConfiguration.includeDeletionForm = true>
|
||||
<#include "defaultDeletePropertyForm.ftl">
|
||||
</#if>
|
||||
<#--Not including defaultFormScripts.ftl which would trigger tinyMce-->
|
||||
<#assign sparqlQueryUrl = "${urls.base}/ajax/sparqlQuery" >
|
||||
<#--Passing in object types only if there are any types returned, otherwise
|
||||
the parameter should not be passed at all to the solr search.
|
||||
Also multiple types parameter set to true only if more than one type returned-->
|
||||
<script type="text/javascript">
|
||||
var customFormData = {
|
||||
acUrl: '${urls.base}/dataautocomplete?',
|
||||
property: '${editConfiguration.predicateUri}',
|
||||
submitButtonTextType: 'simple',
|
||||
editMode: '${editMode}', //Change this to check whether adding or editing
|
||||
supportEdit: 'true',
|
||||
sparqlForAcFilter: '${sparqlForAcFilter}',
|
||||
sparqlQueryUrl: '${sparqlQueryUrl}',
|
||||
defaultTypeName: 'string'
|
||||
};
|
||||
</script>
|
||||
|
||||
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/js/jquery-ui/css/smoothness/jquery-ui-1.8.9.custom.css" />')}
|
||||
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/templates/freemarker/edit/forms/css/customForm.css" />')}
|
||||
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/templates/freemarker/edit/forms/css/customFormWithAutocomplete.css" />')}
|
||||
|
||||
${scripts.add('<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>',
|
||||
'<script type="text/javascript" src="${urls.base}/js/customFormUtils.js"></script>',
|
||||
'<script type="text/javascript" src="${urls.base}/js/browserUtils.js"></script>',
|
||||
'<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/customFormWithDataAutocomplete.js"></script>')}
|
|
@ -184,8 +184,7 @@ var customForm = {
|
|||
this.initFormFullView();
|
||||
}
|
||||
//Disable submit button until selection made
|
||||
this.button.attr('disabled', 'disabled');
|
||||
this.button.addClass('disabledSubmit'); // tlw
|
||||
this.disableSubmit(); // tlw
|
||||
},
|
||||
|
||||
// Bind event listeners that persist over the life of the page. Event listeners
|
||||
|
@ -392,8 +391,7 @@ var customForm = {
|
|||
}
|
||||
if(this.supportEdit) {
|
||||
//On initialization in this mode, submit button is disabled
|
||||
this.button.removeAttr('disabled');
|
||||
this.button.removeClass('disabledSubmit'); // tlw
|
||||
this.enableSubmit(); // tlw
|
||||
}
|
||||
this.setButtonText('existing');
|
||||
|
||||
|
@ -427,8 +425,7 @@ var customForm = {
|
|||
|
||||
//Resetting so disable submit button again for object property autocomplete
|
||||
if(this.supportEdit) {
|
||||
this.button.attr('disabled', 'disabled');
|
||||
this.button.addClass('disabledSubmit');
|
||||
this.disableSubmit();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -539,6 +536,15 @@ var customForm = {
|
|||
this.acSelector.val('')
|
||||
.removeClass(this.acHelpTextClass);
|
||||
}
|
||||
},
|
||||
disableSubmit: function() {
|
||||
//Disable submit button until selection made
|
||||
this.button.attr('disabled', 'disabled');
|
||||
this.button.addClass('disabledSubmit'); // tlw
|
||||
},
|
||||
enableSubmit:function() {
|
||||
this.button.removeAttr('disabled');
|
||||
this.button.removeClass('disabledSubmit');
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -0,0 +1,435 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
var customForm = {
|
||||
|
||||
/* *** Initial page setup *** */
|
||||
|
||||
onLoad: function() {
|
||||
|
||||
if (this.disableFormInUnsupportedBrowsers()) {
|
||||
return;
|
||||
}
|
||||
this.mixIn();
|
||||
this.initObjects();
|
||||
this.initPage();
|
||||
},
|
||||
|
||||
disableFormInUnsupportedBrowsers: function() {
|
||||
var disableWrapper = $('#ie67DisableWrapper');
|
||||
|
||||
// Check for unsupported browsers only if the element exists on the page
|
||||
if (disableWrapper.length) {
|
||||
if (vitro.browserUtils.isIELessThan8()) {
|
||||
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 = $('form.customForm');
|
||||
this.fullViewOnly = $('.fullViewOnly');
|
||||
this.button = $('#submit');
|
||||
this.requiredLegend = $('#requiredLegend');
|
||||
|
||||
|
||||
// These are classed rather than id'd in case we want more than one autocomplete on a form.
|
||||
// At that point we'll use ids to match them up with one another.
|
||||
this.acSelector = this.form.find('.acSelector');
|
||||
this.acSelection = this.form.find('.acSelection');
|
||||
this.acSelectionInfo = this.form.find('.acSelectionInfo');
|
||||
|
||||
this.acSelectorWrapper = this.acSelector.parent();
|
||||
|
||||
this.or = $('span.or');
|
||||
this.cancel = this.form.find('.cancel');
|
||||
this.acHelpTextClass = 'acSelectorWithHelpText';
|
||||
},
|
||||
|
||||
// Set up the form on page load
|
||||
initPage: function() {
|
||||
|
||||
if (!this.editMode) {
|
||||
this.editMode = 'add'; // edit vs add: default to add
|
||||
}
|
||||
|
||||
if (!this.formSteps) { // Don't override formSteps specified in form data
|
||||
if ( !this.fullViewOnly.length || this.editMode === 'edit' || this.editMode === 'repair' ) {
|
||||
this.formSteps = 1;
|
||||
// there may also be a 3-step form - look for this.subTypeSelector
|
||||
}
|
||||
else {
|
||||
this.formSteps = 2;
|
||||
}
|
||||
}
|
||||
|
||||
this.bindEventListeners();
|
||||
|
||||
this.initAutocomplete();
|
||||
|
||||
this.initElementData();
|
||||
|
||||
this.initFormView();
|
||||
|
||||
},
|
||||
|
||||
initFormView: function() {
|
||||
|
||||
// Put this case first, because in edit mode with
|
||||
// validation errors we just want initFormFullView.
|
||||
if (this.editMode == 'repair') {
|
||||
this.initFormFullView();
|
||||
} else if(this.editMode == 'edit') {
|
||||
this.initFormEditFullView();
|
||||
}
|
||||
else if (this.findValidationErrors()) {
|
||||
this.initFormWithValidationErrors();
|
||||
}
|
||||
// If type is already selected when the page loads (Firefox retains value
|
||||
// on a refresh), go directly to full view. Otherwise user has to reselect
|
||||
// twice to get to full view.
|
||||
else if ( this.formSteps == 1 || typeVal.length ) {
|
||||
this.initFormFullView();
|
||||
}
|
||||
else {
|
||||
this.initFormTypeView();
|
||||
}
|
||||
},
|
||||
|
||||
initFormTypeView: function() {
|
||||
|
||||
this.hideFields(this.fullViewOnly);
|
||||
this.button.hide();
|
||||
this.requiredLegend.hide();
|
||||
this.or.hide();
|
||||
|
||||
this.cancel.unbind('click');
|
||||
},
|
||||
|
||||
|
||||
initFormFullView: function() {
|
||||
|
||||
this.fullViewOnly.show();
|
||||
this.or.show();
|
||||
this.requiredLegend.show();
|
||||
this.button.show();
|
||||
this.setButtonText('new');
|
||||
this.setLabels();
|
||||
|
||||
// Set the initial autocomplete help text in the acSelector field.
|
||||
this.addAcHelpText();
|
||||
|
||||
this.cancel.unbind('click');
|
||||
if (this.formSteps > 1) {
|
||||
this.cancel.click(function() {
|
||||
customForm.clearFormData(); // clear any input and validation errors
|
||||
customForm.initFormTypeView();
|
||||
return false;
|
||||
});
|
||||
// In one-step forms, if there is a type selection field, but no value is selected,
|
||||
// hide the acSelector field. The type selection must be made first so that the
|
||||
// autocomplete type can be determined. If a type selection has been made,
|
||||
// unhide the acSelector field.
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
initFormWithValidationErrors: function() {
|
||||
var label = this.acSelector.val();
|
||||
|
||||
// Call initFormFullView first, because showAutocompleteSelection needs
|
||||
// acType, which is set in initFormFullView.
|
||||
this.initFormFullView();
|
||||
|
||||
//See if value exists, either b/c editing or label is in input if validation error
|
||||
if(label.length > 0) {
|
||||
this.showAutocompleteSelection(label);
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
initFormEditFullView: function() {
|
||||
var label = this.acSelector.val();
|
||||
|
||||
// Call initFormFullView first, because showAutocompleteSelection needs
|
||||
// acType, which is set in initFormFullView.
|
||||
this.initFormFullView();
|
||||
|
||||
//See if value exists, either b/c editing or label is in input if validation error
|
||||
if(this.editMode == 'edit' || label.length > 0) {
|
||||
this.showAutocompleteSelection(label);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Bind event listeners that persist over the life of the page. Event listeners
|
||||
// that depend on the view should be initialized in the view setup method.
|
||||
bindEventListeners: function() {
|
||||
|
||||
//no longer need type selector and verify match
|
||||
|
||||
this.acSelector.focus(function() {
|
||||
customForm.deleteAcHelpText();
|
||||
});
|
||||
|
||||
this.acSelector.blur(function() {
|
||||
customForm.addAcHelpText();
|
||||
});
|
||||
|
||||
this.form.submit(function() {
|
||||
customForm.deleteAcHelpText();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
initAutocomplete: function() {
|
||||
|
||||
this.getAcFilter();
|
||||
this.acCache = {};
|
||||
|
||||
this.acSelector.autocomplete({
|
||||
minLength: 3,
|
||||
source: customForm.doAutoComplete,
|
||||
select: function(event, ui) {
|
||||
customForm.showAutocompleteSelection(ui.item.value);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//For debugging, trying to extract auto complete method
|
||||
doAutoComplete: function(request, response) {
|
||||
if (request.term in customForm.acCache) {
|
||||
// console.log('found term in cache');
|
||||
response(customForm.acCache[request.term]);
|
||||
return;
|
||||
}
|
||||
// console.log('not getting term from cache');
|
||||
|
||||
$.ajax({
|
||||
url: customForm.acUrl,
|
||||
dataType: 'json',
|
||||
data: {
|
||||
term: request.term,
|
||||
property: customForm.property
|
||||
},
|
||||
complete: function(xhr, status) {
|
||||
// Not sure why, but we need an explicit json parse here.
|
||||
var results = $.parseJSON(xhr.responseText),
|
||||
filteredResults = customForm.filterAcResults(results);
|
||||
customForm.acCache[request.term] = filteredResults;
|
||||
response(filteredResults);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
// Store original or base text with elements that will have text substitutions.
|
||||
// Generally the substitution cannot be made on the current value, since that value
|
||||
// may have changed from the original. So we store the original text with the element to
|
||||
// use as a base for substitutions.
|
||||
initElementData: function() {
|
||||
|
||||
this.placeholderText = '###';
|
||||
this.labelsWithPlaceholders = this.form.find('label, .label').filter(function() {
|
||||
return $(this).html().match(customForm.placeholderText);
|
||||
});
|
||||
this.labelsWithPlaceholders.each(function(){
|
||||
$(this).data('baseText', $(this).html());
|
||||
});
|
||||
|
||||
this.button.data('baseText', this.button.val());
|
||||
|
||||
|
||||
},
|
||||
//get autocomplete filter with sparql query
|
||||
getAcFilter: function() {
|
||||
|
||||
if (!this.sparqlForAcFilter) {
|
||||
//console.log('autocomplete filtering turned off');
|
||||
this.acFilter = null;
|
||||
return;
|
||||
}
|
||||
|
||||
//console.log("sparql for autocomplete filter: " + this.sparqlForAcFilter);
|
||||
|
||||
// Define this.acFilter here, so in case the sparql query fails
|
||||
// we don't get an error when referencing it later.
|
||||
this.acFilter = [];
|
||||
$.ajax({
|
||||
url: customForm.sparqlQueryUrl,
|
||||
dataType: "json",
|
||||
data: {
|
||||
query: customForm.sparqlForAcFilter
|
||||
},
|
||||
success: function(data, status, xhr) {
|
||||
customForm.setAcFilter(data);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setAcFilter: function(data) {
|
||||
|
||||
var key = data.head.vars[0];
|
||||
|
||||
$.each(data.results.bindings, function() {
|
||||
customForm.acFilter.push(this[key].value);
|
||||
});
|
||||
},
|
||||
|
||||
filterAcResults: function(results) {
|
||||
var filteredResults;
|
||||
|
||||
if (!this.acFilter || !this.acFilter.length) {
|
||||
//console.log('no autocomplete filtering applied');
|
||||
return results;
|
||||
}
|
||||
|
||||
filteredResults = [];
|
||||
$.each(results, function() {
|
||||
//Here this should refer to the results array value being iterated through
|
||||
if ($.inArray(String(this), customForm.acFilter) == -1) {
|
||||
filteredResults.push(String(this));
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
});
|
||||
return filteredResults;
|
||||
},
|
||||
|
||||
// Reset some autocomplete values after type is changed
|
||||
resetAutocomplete: function(typeVal) {
|
||||
// Append the type parameter to the base autocomplete url
|
||||
var glue = this.baseAcUrl.indexOf('?') > -1 ? '&' : '?';
|
||||
this.acUrl = this.baseAcUrl + glue;
|
||||
|
||||
// Flush autocomplete cache when type is reset, since the cached values
|
||||
// pertain only to the previous type.
|
||||
this.acCache = {};
|
||||
},
|
||||
//in our case, we have only the literal value itself
|
||||
showAutocompleteSelection: function(label) {
|
||||
|
||||
this.hideFields(this.acSelectorWrapper);
|
||||
this.acSelection.show();
|
||||
|
||||
this.acSelector.val(label);
|
||||
this.acSelectionInfo.html(label);
|
||||
|
||||
this.setButtonText('existing');
|
||||
|
||||
this.cancel.unbind('click');
|
||||
this.cancel.click(function() {
|
||||
customForm.undoAutocompleteSelection();
|
||||
customForm.initFormFullView();
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
// Cancel action after making an autocomplete selection: undo autocomplete
|
||||
// selection (from showAutocomplete) before returning to full view.
|
||||
undoAutocompleteSelection: function() {
|
||||
|
||||
// The test is not just for efficiency: undoAutocompleteSelection empties the acSelector value,
|
||||
// which we don't want to do if user has manually entered a value, since he may intend to
|
||||
// change the type but keep the value. If no new value has been selected, form initialization
|
||||
// below will correctly empty the value anyway.
|
||||
if (!this.acSelection.is(':hidden')) {
|
||||
this.acSelectorWrapper.show();
|
||||
this.hideFields(this.acSelection);
|
||||
this.acSelector.val('');
|
||||
this.acSelectionInfo.html('');
|
||||
|
||||
if (this.formSteps > 1) {
|
||||
this.acSelection.find('label').html('Selected ');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Set field labels based on type selection. Although these won't change in edit
|
||||
// mode, it's easier to specify the text here than in the jsp.
|
||||
setLabels: function() {
|
||||
var typeName = "string";
|
||||
|
||||
this.labelsWithPlaceholders.each(function() {
|
||||
var newLabel = $(this).data('baseText').replace(customForm.placeholderText, typeName);
|
||||
$(this).html(newLabel);
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
// Set button text based on both type selection and whether it's an autocomplete selection
|
||||
// or a new related individual. Called when setting up full view of form, and after
|
||||
// an autocomplete selection.
|
||||
setButtonText: function(newOrExisting) {
|
||||
var typeText,
|
||||
buttonText,
|
||||
baseButtonText = this.button.data('baseText');
|
||||
|
||||
// Edit mode button doesn't change, so it's specified in the jsp
|
||||
if (this.editMode === 'edit') {
|
||||
return;
|
||||
}
|
||||
|
||||
typeText = "string";
|
||||
|
||||
// Creating new related individual
|
||||
if (newOrExisting === 'new') {
|
||||
if (this.submitButtonTextType == 'compound') { // use == to tolerate nulls
|
||||
// e.g., 'Create Grant & Principal Investigator'
|
||||
buttonText = 'Create ' + typeText + ' & ' + baseButtonText;
|
||||
} else {
|
||||
// In repair mode, baseButtonText is "Edit X". Keep that for this case.
|
||||
// In add mode, baseButtonText is "X", so we get, e.g., "Create Publication"
|
||||
buttonText = this.editMode == 'repair' ? baseButtonText : 'Create ' + baseButtonText;
|
||||
}
|
||||
}
|
||||
// Using existing related individual
|
||||
else {
|
||||
// In repair mode, baseButtonText is "Edit X". Keep that for this case.
|
||||
buttonText = this.editMode == 'repair' ? baseButtonText : 'Add ' + baseButtonText;
|
||||
}
|
||||
|
||||
this.button.val(buttonText);
|
||||
},
|
||||
|
||||
|
||||
// Set the initial help text that appears in the autocomplete field and change the class name
|
||||
addAcHelpText: function() {
|
||||
var typeText = "string";
|
||||
|
||||
// First case applies on page load; second case applies when the type gets changed.
|
||||
if (!this.acSelector.val() || this.acSelector.hasClass(this.acHelpTextClass)) {
|
||||
var helpText = "Select an existing " + typeText + " or create a new one.";
|
||||
//Different for object property autocomplete
|
||||
this.acSelector.val(helpText)
|
||||
.addClass(this.acHelpTextClass);
|
||||
}
|
||||
},
|
||||
|
||||
deleteAcHelpText: function() {
|
||||
if (this.acSelector.hasClass(this.acHelpTextClass)) {
|
||||
this.acSelector.val('')
|
||||
.removeClass(this.acHelpTextClass);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
customForm.onLoad();
|
||||
});
|
|
@ -0,0 +1,78 @@
|
|||
|
||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.FrontEndEditingUtils.EditMode;
|
||||
|
||||
/**
|
||||
* Generates the edit configuration for a default property form.
|
||||
*
|
||||
*/
|
||||
public class AutocompleteDataPropertyFormGenerator extends DefaultDataPropertyFormGenerator {
|
||||
|
||||
//The only thing that changes here are the templates
|
||||
private Log log = LogFactory.getLog(AutocompleteObjectPropertyFormGenerator.class);
|
||||
private String dataPropertyTemplate = "autoCompleteDataPropForm.ftl";
|
||||
|
||||
|
||||
@Override
|
||||
public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq, HttpSession session) {
|
||||
EditConfigurationVTwo ec = super.getEditConfiguration(vreq, session);
|
||||
this.addFormSpecificData(ec, vreq);
|
||||
return ec;
|
||||
}
|
||||
|
||||
public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
|
||||
HashMap<String, Object> formSpecificData = new HashMap<String, Object>();
|
||||
//Filter setting - i.e. sparql query for filtering out results from autocomplete
|
||||
formSpecificData.put("sparqlForAcFilter", getSparqlForAcFilter(vreq));
|
||||
editConfiguration.setTemplate(dataPropertyTemplate);
|
||||
//Add edit model
|
||||
formSpecificData.put("editMode", getEditMode(vreq));
|
||||
editConfiguration.setFormSpecificData(formSpecificData);
|
||||
}
|
||||
|
||||
public String getSparqlForAcFilter(VitroRequest vreq) {
|
||||
String subject = EditConfigurationUtils.getSubjectUri(vreq);
|
||||
String predicate = EditConfigurationUtils.getPredicateUri(vreq);
|
||||
//Get all objects for existing predicate, filters out results from addition and edit
|
||||
String query = "SELECT ?dataLiteral WHERE { " +
|
||||
"<" + subject + "> <" + predicate + "> ?dataLiteral .} ";
|
||||
return query;
|
||||
}
|
||||
|
||||
//Get edit mode
|
||||
public String getEditMode(VitroRequest vreq) {
|
||||
if(isUpdate(vreq))
|
||||
return "edit";
|
||||
else
|
||||
return "add";
|
||||
}
|
||||
|
||||
private boolean isUpdate(VitroRequest vreq) {
|
||||
Integer dataHash = EditConfigurationUtils.getDataHash(vreq);
|
||||
return ( dataHash != null );
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue