NIHVIVO-646 Organized methods into logical groupings to improve readability.

This commit is contained in:
rjy7 2010-07-04 17:17:15 +00:00
parent 3772389dd7
commit 51b4fb24c2

View file

@ -2,6 +2,8 @@
var addAuthorForm = {
/* *** Initial page setup *** */
onLoad: function() {
this.mixIn();
this.initObjects();
@ -60,6 +62,310 @@ var addAuthorForm = {
}
},
/* *** Set up the various page views *** */
// This view shows the list of existing authors and hides the form.
// There is a button to show the form.
initAuthorListOnlyView: function() {
this.hideForm();
this.showFormButtonWrapper.show();
},
// 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.initAuthorListOnlyView();
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();
},
hideSelectedAuthor: function() {
this.selectedAuthor.hide();
this.selectedAuthorName.html('');
this.personUriField.val('');
},
showFieldsForNewPerson: function() {
this.firstNameWrapper.show();
this.middleNameWrapper.show();
this.toggleLastNameLabel('Name', 'Last name');
},
hideFieldsForNewPerson: function() {
this.hideFields(this.firstNameWrapper);
this.hideFields(this.middleNameWrapper);
this.toggleLastNameLabel('Last name', 'Name');
},
toggleLastNameLabel: function(currentText, newText) {
var lastNameLabelText = this.lastNameLabel.html(),
newLastNameLabelText = lastNameLabelText.replace(currentText, newText);
this.lastNameLabel.html(newLastNameLabelText);
},
/* *** Ajax initializations *** */
/* Autocomplete */
initAutocomplete: function() {
// Make cache a property of this so we can access it after removing
// an author.
this.acCache = {};
this.baseAcUrl = $('.acUrl').attr('id');
this.setAcUrl();
$('#lastName').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: request,
complete: function(xhr) {
// Not sure why, but we need an explicit json parse here. jQuery
// should parse the response text and return an json object.
var results = jQuery.parseJSON(xhr.responseText);
addAuthorForm.acCache[request.term] = results;
response(results);
}
});
},
select: function(event, ui) {
addAuthorForm.showSelectedAuthor(ui);
}
});
},
setAcUrl: function() {
var url = this.baseAcUrl,
existingAuthors = $('#authorships .authorLink');
//console.log("in setAcUrl()");
//console.log("number of existing authors: " + existingAuthors.length);
existingAuthors.each(function() {
url += '&excludeUri=' + $(this).attr('id');
});
this.acUrl = url;
},
// 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);
// This shouldn't be needed, because they are already hidden, but for some reason on select
// these fields get displayed, even before entering the select event listener.
this.hideFields(this.firstNameWrapper);
this.hideFields(this.middleNameWrapper);
// Cancel restores form to initial state
this.cancel.unbind('click');
this.cancel.bind('click', function() {
addAuthorForm.initFormView();
return false;
});
return false;
},
/* Drag-and-drop */
initAuthorDD: function() {
var authorshipList = $('#authorships'),
authorships = authorshipList.children();
if (authorships.length < 2) {
return;
}
authorships.each(function() {
$(this).children('.author').attr('title', 'Drag and drop to reorder authors');
});
authorshipList.sortable({
stop: function(event, ui) {
var predicateUri = '<' + $('.rankPred').attr('id') + '>',
rankXsdType = $('.rankXsdType').attr('id'),
additions = '',
retractions = '',
authorships = [];
$('li.authorship').each(function(index) {
var uri = $(this).attr('id'),
subjectUri = '<' + uri + '>',
oldRankVal = addAuthorForm.getRankVal(this),
newRank = index + 1,
newRankForN3,
oldRank,
oldRankType,
oldRankForN3,
rankVals;
rankVals = oldRankVal.split('_'); // e.g., 1_http://www.w3.org/2001/XMLSchema#int
oldRank = rankVals[0];
oldRankType = rankVals[1];
oldRankForN3 = addAuthorForm.makeRankDataPropVal(oldRank, oldRankType);
newRankForN3 = addAuthorForm.makeRankDataPropVal(newRank, rankXsdType);
additions += subjectUri + ' ' + predicateUri + ' ' + newRankForN3 + ' .';
retractions += subjectUri + ' ' + predicateUri + ' ' + oldRankForN3 + ' .';
// 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({
url: $('.reorderUrl').attr('id'),
data: {
additions: additions,
retractions: retractions
},
authorships: authorships,
processData: 'false',
dataType: 'json',
type: 'POST',
success: function(data, status, request) {
$.each(authorships, function(index, obj) {
// find the element with this uri as id
var el = $('li[id=' + obj.uri + ']'),
// because all ranks have been reordered without gaps,
// we can get the position from the rank
pos = obj.rankVal.split('_')[0];
// set the new rank and position for this element
addAuthorForm.setRankVal(el, obj.rankVal);
addAuthorForm.setPosition(el, pos);
});
},
error: function(request, status, error) {
// 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),
//ui.item.children('.position').attr('id'),
nextpos = pos + 1,
authorships = $('#authorships'),
next = authorships.find('.position[id=' + nextpos + ']').parent();
if (next.length) {
ui.item.insertBefore(next);
} else {
ui.item.appendTo(authorships);
}
alert('Reordering of authors failed.');
}
});
} // end stop callback
});
},
getPosition: function(authorship) {
return parseInt($(authorship).children('.position').attr('id'));
},
setPosition: function(authorship, pos) {
$(authorship).children('.position').attr('id', pos);
},
// Get the authorship rank value, which includes xsd type
getRankVal: function(authorship) {
return $(authorship).children('.rank').attr('id');
},
// Get the integer value from the authorship rank value
getRank: function(authorship) {
return this.getRankVal(authorship).split('_')[0];
},
setRankVal: function(authorship, rank) {
$(authorship).children('.rank').attr('id', rank);
},
makeRankDataPropVal: function(rank, xsdType) {
var rankVal = '"' + rank + '"';
if (xsdType) {
rankVal += '^^<' + xsdType + '>'
}
return rankVal;
},
/* *** Event listeners *** */
bindEventListeners: function() {
this.showFormButton.click(function() {
@ -97,7 +403,6 @@ var addAuthorForm = {
this.removeAuthorshipLinks.click(function() {
addAuthorForm.removeAuthorship(this);
return false;
});
@ -110,6 +415,58 @@ var addAuthorForm = {
},
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.
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?";
@ -185,359 +542,13 @@ var addAuthorForm = {
authorship.children('.author').attr('title', '');
},
onLastNameChange: function() {
this.showFieldsForNewPerson();
this.firstNameField.focus();
this.fixNames();
},
showFieldsForNewPerson: function() {
this.firstNameWrapper.show();
this.middleNameWrapper.show();
this.toggleLastNameLabel('Name', 'Last name');
},
// 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.
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]);
}
},
hideFieldsForNewPerson: function() {
this.hideFields(this.firstNameWrapper);
this.hideFields(this.middleNameWrapper);
this.toggleLastNameLabel('Last name', 'Name');
},
toggleLastNameLabel: function(currentText, newText) {
var lastNameLabelText = this.lastNameLabel.html(),
newLastNameLabelText = lastNameLabelText.replace(currentText, newText);
this.lastNameLabel.html(newLastNameLabelText);
},
// This view shows the list of existing authors and hides the form.
// There is a button to show the form.
initAuthorListOnlyView: function() {
this.hideForm();
this.showFormButtonWrapper.show();
},
// 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.initAuthorListOnlyView();
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();
},
// 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);
// This shouldn't be needed, because they are already hidden, but for some reason on select
// these fields get displayed, even before entering the select event listener.
this.hideFields(this.firstNameWrapper);
this.hideFields(this.middleNameWrapper);
// Cancel restores form to initial state
this.cancel.unbind('click');
this.cancel.bind('click', function() {
addAuthorForm.initFormView();
return false;
});
return false;
},
hideSelectedAuthor: function() {
this.selectedAuthor.hide();
this.selectedAuthorName.html('');
this.personUriField.val('');
},
initAuthorDD: function() {
var authorshipList = $('#authorships'),
authorships = authorshipList.children();
if (authorships.length < 2) {
return;
}
authorships.each(function() {
$(this).children('.author').attr('title', 'Drag and drop to reorder authors');
});
authorshipList.sortable({
stop: function(event, ui) {
var predicateUri = '<' + $('.rankPred').attr('id') + '>',
rankXsdType = $('.rankXsdType').attr('id'),
additions = '',
retractions = '',
authorships = [];
$('li.authorship').each(function(index) {
var uri = $(this).attr('id'),
subjectUri = '<' + uri + '>',
oldRankVal = addAuthorForm.getRankVal(this),
newRank = index + 1,
newRankForN3,
oldRank,
oldRankType,
oldRankForN3,
rankVals;
rankVals = oldRankVal.split('_'); // e.g., 1_http://www.w3.org/2001/XMLSchema#int
oldRank = rankVals[0];
oldRankType = rankVals[1];
oldRankForN3 = addAuthorForm.makeRankDataPropVal(oldRank, oldRankType);
newRankForN3 = addAuthorForm.makeRankDataPropVal(newRank, rankXsdType);
additions += subjectUri + ' ' + predicateUri + ' ' + newRankForN3 + ' .';
retractions += subjectUri + ' ' + predicateUri + ' ' + oldRankForN3 + ' .';
// 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({
url: $('.reorderUrl').attr('id'),
data: {
additions: additions,
retractions: retractions
},
authorships: authorships,
processData: 'false',
dataType: 'json',
type: 'POST',
success: function(data, status, request) {
$.each(authorships, function(index, obj) {
// find the element with this uri as id
var el = $('li[id=' + obj.uri + ']'),
// because all ranks have been reordered without gaps,
// we can get the position from the rank
pos = obj.rankVal.split('_')[0];
// set the new rank and position for this element
addAuthorForm.setRankVal(el, obj.rankVal);
addAuthorForm.setPosition(el, pos);
});
},
error: function(request, status, error) {
// 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),
//ui.item.children('.position').attr('id'),
nextpos = pos + 1,
authorships = $('#authorships'),
next = authorships.find('.position[id=' + nextpos + ']').parent();
if (next.length) {
ui.item.insertBefore(next);
} else {
ui.item.appendTo(authorships);
}
alert('Reordering of authors failed.');
}
});
} // end stop callback
});
},
getPosition: function(authorship) {
return parseInt($(authorship).children('.position').attr('id'));
},
setPosition: function(authorship, pos) {
$(authorship).children('.position').attr('id', pos);
},
// Get the authorship rank value, which includes xsd type
getRankVal: function(authorship) {
return $(authorship).children('.rank').attr('id');
},
// Get the integer value from the authorship rank value
getRank: function(authorship) {
return this.getRankVal(authorship).split('_')[0];
},
setRankVal: function(authorship, rank) {
$(authorship).children('.rank').attr('id', rank);
},
makeRankDataPropVal: function(rank, xsdType) {
var rankVal = '"' + rank + '"';
if (xsdType) {
rankVal += '^^<' + xsdType + '>'
}
return rankVal;
},
initAutocomplete: function() {
// Make cache a property of this so we can access it after removing
// an author.
this.acCache = {};
this.baseAcUrl = $('.acUrl').attr('id');
this.setAcUrl();
$('#lastName').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: request,
complete: function(xhr) {
// Not sure why, but we need an explicit json parse here. jQuery
// should parse the response text and return an json object.
var results = jQuery.parseJSON(xhr.responseText);
addAuthorForm.acCache[request.term] = results;
response(results);
}
});
},
select: function(event, ui) {
addAuthorForm.showSelectedAuthor(ui);
}
});
},
setAcUrl: function() {
var url = this.baseAcUrl,
existingAuthors = $('#authorships .authorLink');
//console.log("in setAcUrl()");
//console.log("number of existing authors: " + existingAuthors.length);
existingAuthors.each(function() {
url += '&excludeUri=' + $(this).attr('id');
});
this.acUrl = url;
},
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);
}
},
// 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();