Look-up Tables: Look-up table entry edit
22 March 2009The final element of our refactoring of the Look-up Table service is to update the Look-up Table entry edit function. As with the Look-up Table edit, the changes to the entry edit function center on adding in code to accommodate the new context concept in the Javascript file that handles the entry edit page. The specific changes can be seen here, and the final result now looks like this:
// lookup_table_edit_example.js
var dataURIStart = '/core/entry/';
var sourceOptionsURIStart = '/core/options/';
var queryParameter = {};
var userId = '';
var userURI = '';
var userName = '';
var context = '';
var tableName = '';
var entryId = '';
var tableDefinition = {};
var newEntry = true;
var sourceNeeded = [];
var sourceIndex = 0;
var visibleRows = 0;
var availableRows = 20;
var inputErrors = '';
/**
* Initialize the page
*/
function initPage() {
loadPagequeryParameter();
ajaxGet('/id/whoami', 'initPageCont','ajaxError');
}
/**
* Loads in any parameters found in the current URL's query string
*/
function loadPagequeryParameter() {
var thisURL = document.location.href;
if (thisURL.indexOf('?') != -1) {
var queryString = thisURL.substring(thisURL.indexOf('?') + 1);
var parts = queryString.split('&');
for (var i=0; i<parts.length; i++) {
var moreParts = parts[i].split('=');
if (moreParts != null && moreParts.length > 1) {
queryParameter[moreParts[0]] = moreParts[1];
}
}
}
}
/**
* Initialize the page (continued)
*/
function initPageCont(xmlDoc) {
var root = xmlDoc.documentElement;
userId = root.getElementsByTagName('remoteUser')[0].attributes[0].value;
userURI = root.getElementsByTagName('remoteUser')[0].attributes[1].value;
userName = root.getElementsByTagName('remoteUser')[0].firstChild.data;
var userLink = '<a class="action" href="javascript:popUpUserData(userURI);" title="' +
userName + '">' + userName + '</a>';
document.getElementById('userLink').innerHTML = userLink;
context = queryParameter.context;
tableName = queryParameter.table;
entryId = queryParameter.entry;
// add context to data URI
dataURIStart += context + '/';
// add context to source options URI
sourceOptionsURIStart += context + '/';
// get table definition
var time = new Date().getTime();
ajaxGet('/core/table/' + context + '/' + tableName + '?t=' + time, 'processTableDefinition',
'ajaxError');
}
/**
* Save off the table definition
*/
function processTableDefinition(xmlDoc) {
// process table definition
var root = xmlDoc.documentElement;
entryEditConfig.table = {};
entryEditConfig.table.id = root.attributes[2].value;
entryEditConfig.table.name = root.getElementsByTagName('displayName')[0].firstChild.data;
entryEditConfig.table.description = root.getElementsByTagName('description')[0].firstChild.data;
var propertyList = root.getElementsByTagName('property');
if (propertyList.length > 0) {
for (var i=0; i<propertyList.length; i++) {
var thisProperty = {};
thisProperty.divName = 'property' + ('0' + i).substring(('0' + i).length - 2) + 'div';
thisProperty.labelName = 'label' + ('0' + i).substring(('0' + i).length - 2);
thisProperty.tagName = 'property' + ('0' + i).substring(('0' + i).length - 2);
thisProperty.id = propertyList[i].attributes[0].value;
thisProperty.name = propertyList[i].getElementsByTagName('name')[0].firstChild.data;
thisProperty.type = propertyList[i].getElementsByTagName('type')[0].firstChild.data;
thisProperty.size = propertyList[i].getElementsByTagName('size')[0].firstChild.data;
thisProperty.label = propertyList[i].getElementsByTagName('label')[0].firstChild.data;
thisProperty.colHeading =
propertyList[i].getElementsByTagName('colHeading')[0].firstChild.data;
thisProperty.inputRequired = false;
if (propertyList[i].getElementsByTagName('inputRequired')[0].firstChild != null) {
if (propertyList[i].getElementsByTagName('inputRequired')[0].firstChild.data == 'true') {
thisProperty.inputRequired = true;
}
}
thisProperty.displayOnList = false;
if (propertyList[i].getElementsByTagName('displayOnList')[0].firstChild != null) {
if (propertyList[i].getElementsByTagName('displayOnList')[0].firstChild.data == 'true') {
thisProperty.displayOnList = true;
}
}
thisProperty.source = '';
if (propertyList[i].getElementsByTagName('source')[0].firstChild != null) {
thisProperty.source = propertyList[i].getElementsByTagName('source')[0].firstChild.data;
var x = sourceNeeded.length;
sourceNeeded[x] = thisProperty.source;
}
thisProperty.notes = '';
if (propertyList[i].getElementsByTagName('notes')[0].firstChild != null) {
thisProperty.notes = propertyList[i].getElementsByTagName('notes')[0].firstChild.data;
}
entryEditConfig.property[i] = thisProperty;
}
}
// set up page title/heading
document.title += ' ' + entryEditConfig.table.name + ' - Entry Edit';
document.getElementById('pageHeading').innerHTML = entryEditConfig.table.name + ' - Entry Edit';
if (entryEditConfig.property.length > 0) {
loadSourceData();
} else {
getTableEntry();
}
}
/**
* Set up the input controls for the additional properties
*/
function loadSourceData() {
if (sourceIndex < sourceNeeded.length) {
var sourceTable = sourceNeeded[sourceIndex];
ajaxGetJson(sourceOptionsURIStart + sourceTable + '.js', 'processSourceOptions','ajaxError');
} else {
formatPropertyInputControls();
}
}
/**
* Process the incoming source options
*/
function processSourceOptions(options) {
var sourceTable = sourceNeeded[sourceIndex];
sourceIndex++;
entryEditConfig.source[sourceTable] = options;
loadSourceData();
}
/**
* Format the HTML input controls for the additional properties
*/
function formatPropertyInputControls() {
for (var i=0; i<entryEditConfig.property.length; i++) {
var thisProperty = entryEditConfig.property[i];
toggleElement(thisProperty.divName, true);
document.getElementById(thisProperty.labelName).innerHTML = thisProperty.label + ":";
document.getElementById('input4' + thisProperty.tagName).innerHTML = getInputControl(i);
}
getTableEntry();
}
/**
* Fetch the table entry to be edited
*/
function getTableEntry() {
if (entryId > '') {
ajaxGet(dataURIStart + tableName + '/' + entryId, 'populateInputFields','ajaxError');
} else {
// even though there is no data, we run through the properties, just to perform any needed
// initialization
for (var i=0; i<entryEditConfig.property.length; i++) {
var thisProperty = entryEditConfig.property[i];
thisProperty.value = '';
populateForm(i);
}
}
}
/**
* Populates the input fields with data from the database
*/
function populateInputFields(xmlDoc) {
var root = xmlDoc.documentElement;
document.getElementById('id').value = root.attributes[0].value;
document.getElementById('id').setAttribute('readonly', 'true');
document.getElementById('description').value =
root.getElementsByTagName('description')[0].firstChild.data;
document.getElementById('description').focus();
for (var i=0; i<entryEditConfig.property.length; i++) {
var thisProperty = entryEditConfig.property[i];
thisProperty.value = '';
if (root.getElementsByTagName(thisProperty.tagName)[0].firstChild != null) {
thisProperty.value = root.getElementsByTagName(thisProperty.tagName)[0].firstChild.data;
}
populateForm(i);
}
newEntry = false;
}
/**
* Hides/shows an element on the page
*/
function toggleElement(elementId, showElement) {
var element = document.getElementById(elementId);
if (showElement) {
element.style.visibility = 'visible';
element.style.display = '';
} else {
element.style.visibility = 'hidden';
element.style.display = 'none';
}
}
/**
* Opens up a new window to display the details of the current user
*/
function popUpUserData(uri) {
var userWindow = window.open(uri, 'userWindow', 'toolbar=no,directories=no,status=no,
scrollbars=yes,resizable=yes,resize=yes,menubar=no,height=400,width=500');
if (window.focus) {
userWindow.focus();
}
}
/**
* Saves the edited data
*/
function saveForm() {
inputErrors = '';
if (newEntry) {
validateEntryId();
} else {
validateData();
}
}
/**
* Validates the entry id on new entries
*/
function validateEntryId() {
entryId = document.getElementById('id').value;
var testPattern = new RegExp('^[a-zA-Z0-9]{0,32}$');
if (testPattern.test(entryId)) {
// entry id is valid format; now make sure it is not already on file
ajaxGet(dataURIStart + tableName + '/' + entryId, 'newEntryAlreadyOnFile',
'checkNewEntryResponse');
} else {
addInputError('The format of the Entry ID is invalid.');
sendInputErrors();
}
}
/**
* Reports a dupicate entry id error
*/
function newEntryAlreadyOnFile(xmlDoc) {
addInputError('The Entry ID specified ("' + entryId + '") is already on file.');
sendInputErrors();
}
/**
* Checks the response code from the duplicate entry check
*/
function checkNewEntryResponse(httpRequest) {
if (httpRequest.status == 404) {
// entry id is not already on file ... validate the rest of the data
validateData();
} else {
// must be some other error ... let the standard error handler take it
ajaxError(httpRequest);
}
}
/**
* Validates the user input
*/
function validateData() {
if (!(document.getElementById('description').value > '')) {
addInputError('Description is required');
}
for (var i=0; i<entryEditConfig.property.length; i++) {
validateProperty(i);
}
if (inputErrors.length > 0) {
sendInputErrors();
} else {
saveUserInput();
}
}
/**
* Adds one input error to the list of errors
*/
function addInputError(errorMessage) {
if (inputErrors.length > 0) {
inputErrors += '\n';
}
inputErrors += errorMessage;
}
/**
* Send input errors
*/
function sendInputErrors() {
var errorMessage = 'The following error(s) have been detected:\n\n';
errorMessage += inputErrors;
errorMessage += '\n\nPlease correct the error(s) and resubmit.';
alert(errorMessage);
}
/**
* Saves the user input
*/
function saveUserInput() {
// field validation has passed; update database
if (newEntry) {
createNewEntry();
} else {
updateExistingEntry();
}
}
/**
* Creates a new entry
*/
function createNewEntry() {
entryId = document.getElementById('id').value;
var xml = '<?xml version="1.0" encoding="UTF-8"?>\n';
xml += '<entry tableName="';
xml += tableName;
xml += '" entryId="';
xml += entryId;
xml += '" xmlns:lookup="http://www.restafarian.org/lookup"
xmlns:xlink="http://www.w3.org/1999/xlink">\n';
xml += ' <description>';
xml += document.getElementById('description').value;
xml += '</description>\n';
for (var i=0; i<entryEditConfig.property.length; i++) {
var thisProperty = entryEditConfig.property[i];
xml += ' <' + thisProperty.tagName + '><![CDATA[';
xml += thisProperty.value;
xml += ']]></' + thisProperty.tagName + '>\n';
}
xml += '</entry>';
ajaxPut(dataURIStart + tableName + '/' + entryId, xml, 'insertEntrySuccessful','ajaxError');
}
/**
* Notifies the user of a successful save operation
*/
function insertEntrySuccessful() {
alert('The table entry has been successfully added.');
history.back();
}
/**
* Updates an existing table
*/
function updateExistingEntry() {
var parameters = 'tableName=' + tableName;
parameters += '&entryId=' + entryId;
parameters += '&description=' + encodeURIComponent(document.getElementById('description').value);
for (var i=0; i<entryEditConfig.property.length; i++) {
var thisProperty = entryEditConfig.property[i];
parameters += '&' + thisProperty.tagName + '=' + encodeURIComponent(thisProperty.value);
}
ajaxPost(dataURIStart + tableName + '/' + entryId, parameters, 'updateEntrySuccessful',
'ajaxError');
}
/**
* Notifies the user of a successful save operation
*/
function updateEntrySuccessful() {
alert('The table entry has been successfully updated.');
history.back();
}
That completes the refactoring of the Look-up Table service to separate look-up tables into various contexts for organization and security purposes. That means that it’s time start looking for a new project!
Leave a reply
You must be logged in to post a comment.





