NIHVIVO-2279 Flesh out the UI for editing UserAccount, and associating with Individual Profiles

This commit is contained in:
j2blake 2011-07-01 16:19:53 +00:00
parent 50b159710b
commit 89a91757c0
7 changed files with 172 additions and 48 deletions

View file

@ -10,9 +10,10 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -21,10 +22,14 @@ import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory; import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
@ -35,6 +40,8 @@ import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
public abstract class UserAccountsPage { public abstract class UserAccountsPage {
private static final Log log = LogFactory.getLog(UserAccountsPage.class); private static final Log log = LogFactory.getLog(UserAccountsPage.class);
private static final String PERSON_CLASS_URI = "http://xmlns.com/foaf/0.1/Person";
/** /**
* After the account is created, or the password is reset, the user has this * After the account is created, or the password is reset, the user has this
* many days to repond to the email. * many days to repond to the email.
@ -45,6 +52,9 @@ public abstract class UserAccountsPage {
protected final ServletContext ctx; protected final ServletContext ctx;
protected final OntModel userAccountsModel; protected final OntModel userAccountsModel;
protected final UserAccountsDao userAccountsDao; protected final UserAccountsDao userAccountsDao;
protected final VClassDao vclassDao;
protected final IndividualDao indDao;
protected final DataPropertyStatementDao dpsDao;
protected UserAccountsPage(VitroRequest vreq) { protected UserAccountsPage(VitroRequest vreq) {
this.vreq = vreq; this.vreq = vreq;
@ -57,6 +67,9 @@ public abstract class UserAccountsPage {
WebappDaoFactory wdf = (WebappDaoFactory) this.ctx WebappDaoFactory wdf = (WebappDaoFactory) this.ctx
.getAttribute("webappDaoFactory"); .getAttribute("webappDaoFactory");
userAccountsDao = wdf.getUserAccountsDao(); userAccountsDao = wdf.getUserAccountsDao();
vclassDao = wdf.getVClassDao();
indDao = wdf.getIndividualDao();
dpsDao = wdf.getDataPropertyStatementDao();
} }
protected boolean isEmailEnabled() { protected boolean isEmailEnabled() {
@ -95,8 +108,8 @@ public abstract class UserAccountsPage {
* Treat the presence of a certain parameter, with a desired value, as a * Treat the presence of a certain parameter, with a desired value, as a
* boolean flag. * boolean flag.
* *
* An example would be radio buttons with values of "yes" and * An example would be radio buttons with values of "yes" and "no". The
* "no". The expected value would be "yes". * expected value would be "yes".
*/ */
protected boolean isParameterAsExpected(String key, String expected) { protected boolean isParameterAsExpected(String key, String expected) {
return expected.equals(getStringParameter(key, "")); return expected.equals(getStringParameter(key, ""));
@ -117,6 +130,27 @@ public abstract class UserAccountsPage {
return list; return list;
} }
/**
* Create a list of possible profile types.
*
* TODO Right now, these are foaf:Person and it's sub-classes. What will it
* be for Vitro?
*/
protected SortedMap<String, String> buildProfileTypesList() {
String seedClassUri = PERSON_CLASS_URI;
List<String> classUris = vclassDao.getAllSubClassURIs(seedClassUri);
classUris.add(seedClassUri);
SortedMap<String, String> types = new TreeMap<String, String>();
for (String classUri: classUris) {
VClass vclass = vclassDao.getVClassByURI(classUri);
if (vclass != null) {
types.put(classUri, vclass.getName());
}
}
return types;
}
/** /**
* Make these URLs available to all of the pages. * Make these URLs available to all of the pages.
*/ */
@ -129,7 +163,8 @@ public abstract class UserAccountsPage {
map.put("myAccount", UrlBuilder.getUrl("/accounts/myAccount")); map.put("myAccount", UrlBuilder.getUrl("/accounts/myAccount"));
map.put("createPassword", UrlBuilder.getUrl("/accounts/createPassword")); map.put("createPassword", UrlBuilder.getUrl("/accounts/createPassword"));
map.put("resetPassword", UrlBuilder.getUrl("/accounts/resetPassword")); map.put("resetPassword", UrlBuilder.getUrl("/accounts/resetPassword"));
map.put("firstTimeExternal", UrlBuilder.getUrl("/accounts/firstTimeExternal")); map.put("firstTimeExternal",
UrlBuilder.getUrl("/accounts/firstTimeExternal"));
map.put("accountsAjax", UrlBuilder.getUrl("/accountsAjax")); map.put("accountsAjax", UrlBuilder.getUrl("/accountsAjax"));
return map; return map;

View file

@ -6,6 +6,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -26,7 +27,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
private static final String PARAMETER_FIRST_NAME = "firstName"; private static final String PARAMETER_FIRST_NAME = "firstName";
private static final String PARAMETER_LAST_NAME = "lastName"; private static final String PARAMETER_LAST_NAME = "lastName";
private static final String PARAMETER_ROLE = "role"; private static final String PARAMETER_ROLE = "role";
private static final String PARAMETER_ASSOCIATE_WITH_PROFILE = "associate"; private static final String PARAMETER_ASSOCIATED_PROFILE_URI = "associatedProfileUri";
private static final String ERROR_NO_EMAIL = "errorEmailIsEmpty"; private static final String ERROR_NO_EMAIL = "errorEmailIsEmpty";
private static final String ERROR_EMAIL_IN_USE = "errorEmailInUse"; private static final String ERROR_EMAIL_IN_USE = "errorEmailInUse";
@ -39,6 +40,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
private static final String TEMPLATE_NAME = "userAccounts-add.ftl"; private static final String TEMPLATE_NAME = "userAccounts-add.ftl";
private final UserAccountsAddPageStrategy strategy; private final UserAccountsAddPageStrategy strategy;
private final boolean matchingIsEnabled;
/* The request parameters */ /* The request parameters */
private boolean submit; private boolean submit;
@ -47,7 +49,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
private String firstName = ""; private String firstName = "";
private String lastName = ""; private String lastName = "";
private String selectedRoleUri = ""; private String selectedRoleUri = "";
private boolean associateWithProfile; private String associatedProfileUri = "";
/** The result of validating a "submit" request. */ /** The result of validating a "submit" request. */
private String errorCode = ""; private String errorCode = "";
@ -61,6 +63,9 @@ public class UserAccountsAddPage extends UserAccountsPage {
this.strategy = UserAccountsAddPageStrategy.getInstance(vreq, this, this.strategy = UserAccountsAddPageStrategy.getInstance(vreq, this,
isEmailEnabled()); isEmailEnabled());
this.matchingIsEnabled = SelfEditingConfiguration.getBean(vreq)
.isConfigured();
parseRequestParameters(); parseRequestParameters();
if (submit) { if (submit) {
@ -75,8 +80,8 @@ public class UserAccountsAddPage extends UserAccountsPage {
firstName = getStringParameter(PARAMETER_FIRST_NAME, ""); firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
lastName = getStringParameter(PARAMETER_LAST_NAME, ""); lastName = getStringParameter(PARAMETER_LAST_NAME, "");
selectedRoleUri = getStringParameter(PARAMETER_ROLE, ""); selectedRoleUri = getStringParameter(PARAMETER_ROLE, "");
associateWithProfile = isParameterAsExpected( associatedProfileUri = getStringParameter(
PARAMETER_ASSOCIATE_WITH_PROFILE, "yes"); PARAMETER_ASSOCIATED_PROFILE_URI, "");
strategy.parseAdditionalParameters(); strategy.parseAdditionalParameters();
} }
@ -125,26 +130,33 @@ public class UserAccountsAddPage extends UserAccountsPage {
} }
public void createNewAccount() { public void createNewAccount() {
// Assemble the fields into a new UserAccount
UserAccount u = new UserAccount(); UserAccount u = new UserAccount();
u.setEmailAddress(emailAddress); u.setEmailAddress(emailAddress);
u.setFirstName(firstName); u.setFirstName(firstName);
u.setLastName(lastName); u.setLastName(lastName);
u.setExternalAuthId(externalAuthId); u.setExternalAuthId(externalAuthId);
u.setMd5Password(""); u.setMd5Password("");
u.setOldPassword(""); u.setOldPassword("");
u.setPasswordChangeRequired(false); u.setPasswordChangeRequired(false);
u.setPasswordLinkExpires(0); u.setPasswordLinkExpires(0);
u.setLoginCount(0); u.setLoginCount(0);
u.setStatus(Status.INACTIVE); u.setStatus(Status.INACTIVE);
u.setPermissionSetUris(Collections.singleton(selectedRoleUri)); u.setPermissionSetUris(Collections.singleton(selectedRoleUri));
strategy.setAdditionalProperties(u); strategy.setAdditionalProperties(u);
// Create the account.
String uri = userAccountsDao.insertUserAccount(u); String uri = userAccountsDao.insertUserAccount(u);
this.addedAccount = userAccountsDao.getUserAccountByUri(uri); this.addedAccount = userAccountsDao.getUserAccountByUri(uri);
// Associate the profile, as appropriate.
if (matchingIsEnabled) {
SelfEditingConfiguration.getBean(vreq)
.associateIndividualWithUserAccount(indDao, dpsDao,
this.addedAccount, associatedProfileUri);
}
strategy.notifyUser(); strategy.notifyUser();
} }
@ -156,16 +168,18 @@ public class UserAccountsAddPage extends UserAccountsPage {
body.put("firstName", firstName); body.put("firstName", firstName);
body.put("lastName", lastName); body.put("lastName", lastName);
body.put("selectedRole", selectedRoleUri); body.put("selectedRole", selectedRoleUri);
if (associateWithProfile) {
body.put("associate", Boolean.TRUE);
}
body.put("roles", buildRolesList()); body.put("roles", buildRolesList());
body.put("profileTypes", buildProfileTypesList());
body.put("formUrls", buildUrlsMap()); body.put("formUrls", buildUrlsMap());
if (!errorCode.isEmpty()) { if (!errorCode.isEmpty()) {
body.put(errorCode, Boolean.TRUE); body.put(errorCode, Boolean.TRUE);
} }
if (matchingIsEnabled) {
body.put("showAssociation", Boolean.TRUE);
}
strategy.addMoreBodyValues(body); strategy.addMoreBodyValues(body);
return new TemplateResponseValues(TEMPLATE_NAME, body); return new TemplateResponseValues(TEMPLATE_NAME, body);

View file

@ -10,6 +10,7 @@ import java.util.Set;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage; import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage;
@ -45,6 +46,7 @@ public class UserAccountsEditPage extends UserAccountsPage {
private static final String TEMPLATE_NAME = "userAccounts-edit.ftl"; private static final String TEMPLATE_NAME = "userAccounts-edit.ftl";
private final UserAccountsEditPageStrategy strategy; private final UserAccountsEditPageStrategy strategy;
private final boolean matchingIsEnabled;
/* The request parameters */ /* The request parameters */
private boolean submit; private boolean submit;
@ -70,6 +72,9 @@ public class UserAccountsEditPage extends UserAccountsPage {
this.strategy = UserAccountsEditPageStrategy.getInstance(vreq, this, this.strategy = UserAccountsEditPageStrategy.getInstance(vreq, this,
isEmailEnabled()); isEmailEnabled());
this.matchingIsEnabled = SelfEditingConfiguration.getBean(vreq)
.isConfigured();
parseRequestParameters(); parseRequestParameters();
validateUserAccountInfo(); validateUserAccountInfo();
@ -168,6 +173,8 @@ public class UserAccountsEditPage extends UserAccountsPage {
public final ResponseValues showPage() { public final ResponseValues showPage() {
Map<String, Object> body = new HashMap<String, Object>(); Map<String, Object> body = new HashMap<String, Object>();
body.put("userUri", userUri);
if (isSubmit()) { if (isSubmit()) {
body.put("emailAddress", emailAddress); body.put("emailAddress", emailAddress);
body.put("externalAuthId", externalAuthId); body.put("externalAuthId", externalAuthId);
@ -186,12 +193,17 @@ public class UserAccountsEditPage extends UserAccountsPage {
body.put("roles", buildRolesList()); body.put("roles", buildRolesList());
} }
body.put("profileTypes", buildProfileTypesList());
body.put("formUrls", buildUrlsMapWithEditUrl()); body.put("formUrls", buildUrlsMapWithEditUrl());
if (!errorCode.isEmpty()) { if (!errorCode.isEmpty()) {
body.put(errorCode, Boolean.TRUE); body.put(errorCode, Boolean.TRUE);
} }
if (matchingIsEnabled) {
body.put("showAssociation", Boolean.TRUE);
}
strategy.addMoreBodyValues(body); strategy.addMoreBodyValues(body);
return new TemplateResponseValues(TEMPLATE_NAME, body); return new TemplateResponseValues(TEMPLATE_NAME, body);
@ -231,7 +243,11 @@ public class UserAccountsEditPage extends UserAccountsPage {
userAccountsDao.updateUserAccount(userAccount); userAccountsDao.updateUserAccount(userAccount);
// Associate the profile, as appropriate. // Associate the profile, as appropriate.
UserAccountsAssociatedProfileHelper.reconcile(userAccount, associatedProfileUri); if (matchingIsEnabled) {
SelfEditingConfiguration.getBean(vreq)
.associateIndividualWithUserAccount(indDao, dpsDao,
userAccount, associatedProfileUri);
}
// Tell the user. // Tell the user.
strategy.notifyUser(); strategy.notifyUser();

View file

@ -9,6 +9,7 @@ var associateProfileFields = {
if (this.disableFormInUnsupportedBrowsers()) { if (this.disableFormInUnsupportedBrowsers()) {
return; return;
} }
this.mixIn(); this.mixIn();
this.initObjects(); this.initObjects();
this.initPage(); this.initPage();
@ -44,17 +45,19 @@ var associateProfileFields = {
this.associatedArea = $('#associated'); this.associatedArea = $('#associated');
this.associatedProfileNameSpan = $('#associatedProfileName'); this.associatedProfileNameSpan = $('#associatedProfileName');
this.verifyAssociatedProfileLink = $('#verifyProfileLink'); this.verifyAssociatedProfileLink = $('#verifyProfileLink');
this.changeAssociatedProfileLink = $('#changeProfileLink');
this.associatedProfileUriField = $('#associatedProfileUri') this.associatedProfileUriField = $('#associatedProfileUri')
// We want to associate a profile // We want to associate a profile
this.associationOptionsArea = $('#associationOptions'); this.associationOptionsArea = $('#associationOptions');
this.associateProfileNameField = $('#associateProfileName');
}, },
// Initial page setup. Called only at page load. // Initial page setup. Called only at page load.
initPage: function() { initPage: function() {
this.checkForAssociatedProfile(); this.checkForAssociatedProfile();
this.bindEventListeners(); this.bindEventListeners();
this.initAutocomplete();
}, },
bindEventListeners: function() { bindEventListeners: function() {
@ -72,6 +75,39 @@ var associateProfileFields = {
return false; return false;
}); });
this.changeAssociatedProfileLink.click(function() {
associateProfileFields.associatedProfileUriField.val('');
associateProfileFields.associateProfileNameField.val('');
associateProfileFields.showExternalAuthIdNotRecognized();
return false;
});
},
initAutocomplete: function() {
this.associateProfileNameField.autocomplete({
minLength: 3,
source: function(request, response) {
$.ajax({
url: associateProfileFields.ajaxUrl,
dataType: 'json',
data: {
function: "autoCompleteProfile",
term: request.term,
externalAuthId: associateProfileFields.externalAuthIdField.val()
},
complete: function(xhr, status) {
console.log('response text' + xhr.responseText);
var results = jQuery.parseJSON(xhr.responseText);
response(results);
}
});
},
select: function(event, ui) {
associateProfileFields.showSelectedProfile(ui.item);
}
});
}, },
checkForAssociatedProfile: function() { checkForAssociatedProfile: function() {
@ -80,7 +116,7 @@ var associateProfileFields = {
dataType: "json", dataType: "json",
data: { data: {
function: "checkExternalAuth", function: "checkExternalAuth",
userAccountUri: "", userAccountUri: associateProfileFields.userUri,
externalAuthId: associateProfileFields.externalAuthIdField.val() externalAuthId: associateProfileFields.externalAuthIdField.val()
}, },
complete: function(xhr, status) { complete: function(xhr, status) {
@ -88,7 +124,7 @@ var associateProfileFields = {
if (results.idInUse) { if (results.idInUse) {
associateProfileFields.showExternalAuthIdInUse() associateProfileFields.showExternalAuthIdInUse()
} else if (results.matchesProfile) { } else if (results.matchesProfile) {
associateProfileFields.showExternalAuthIdMatchesProfile(results.profileUri, results.profileUri, results.profileLabel) associateProfileFields.showExternalAuthIdMatchesProfile(results.profileUri, results.profileUrl, results.profileLabel)
} else { } else {
associateProfileFields.showExternalAuthIdNotRecognized() associateProfileFields.showExternalAuthIdNotRecognized()
} }
@ -122,13 +158,17 @@ var associateProfileFields = {
this.externalAuthIdInUseMessage.hide(); this.externalAuthIdInUseMessage.hide();
this.associatedArea.hide(); this.associatedArea.hide();
if (this.externalAuthIdField.val().length > 0) { if (this.associationEnabled && this.externalAuthIdField.val().length > 0) {
this.associationOptionsArea.show(); this.associationOptionsArea.show();
} else { } else {
this.associationOptionsArea.hide(); this.associationOptionsArea.hide();
} }
}, },
showSelectedProfile: function(item) {
this.showExternalAuthIdMatchesProfile(item.uri, item.url, item.label);
},
} }
$(document).ready(function() { $(document).ready(function() {

View file

@ -68,6 +68,8 @@
<label for="external-auth-id">External authorization ID</label> <label for="external-auth-id">External authorization ID</label>
<input type="text" name="externalAuthId" value="${externalAuthId}" id="external-auth-id" role="input "/> <input type="text" name="externalAuthId" value="${externalAuthId}" id="external-auth-id" role="input "/>
<#include "userAccounts-associateProfilePanel.ftl">
<p>Roles<span class="requiredHint"> *</span> </p> <p>Roles<span class="requiredHint"> *</span> </p>
<#list roles as role> <#list roles as role>
<input type="radio" name="role" value="${role.uri}" role="radio" <#if selectedRole = role.uri>checked</#if> /> <input type="radio" name="role" value="${role.uri}" role="radio" <#if selectedRole = role.uri>checked</#if> />
@ -75,29 +77,26 @@
<br /> <br />
</#list> </#list>
<#if !emailIsEnabled??>
<label for="initial-password">Initial password<span class="requiredHint"> *</span></label>
<input type="password" name="initialPassword" value="${initialPassword}" id="initial-password" role="input "/>
<p>Minimum of ${minimumLength} characters in length.</p>
<label for="confirm-password">Confirm initial password<span class="requiredHint"> *</span></label>
<input type="text" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input "/>
</#if>
<p>Associate a profile with this account</p>
<input type="radio" name="associate" value="yes" role="radio" <#if associate??>checked</#if> id="associate" />
<label class="inline" for="associate"> Yes</label>
<input type="radio" name="associate" value="no" role="radio" <#if !associate??>checked</#if> id="no-associate" />
<label class="inline" for="no-associate"> No</label>
<#if emailIsEnabled??> <#if emailIsEnabled??>
<p class="note"> <p class="note">
Note: An email will be sent to the address entered above Note: An email will be sent to the address entered above
notifying that an account has been created. notifying that an account has been created.
It will include instructions for activating the account and creating a password. It will include instructions for activating the account and creating a password.
</p> </p>
<#else>
<table>
<tr>
<td>
<label for="initial-password">Initial password<span class="requiredHint"> *</span></label>
<input type="password" name="initialPassword" value="${initialPassword}" id="initial-password" role="input "/>
</td>
<td>
<label for="confirm-password">Confirm initial password<span class="requiredHint"> *</span></label>
<input type="password" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input" />
</td>
</tr>
</table>
<p>Minimum of ${minimumLength} characters in length.</p>
</#if> </#if>
<input type="submit" name="submitAdd" value="Add new account" class="submit"/> or <a class="cancel" href="${formUrls.list}">Cancel</a> <input type="submit" name="submitAdd" value="Add new account" class="submit"/> or <a class="cancel" href="${formUrls.list}">Cancel</a>

View file

@ -21,6 +21,7 @@
<label for="associatedProfileName">Associated profile:</label> <label for="associatedProfileName">Associated profile:</label>
<span class="acSelectionInfo" id="associatedProfileName"></span> <span class="acSelectionInfo" id="associatedProfileName"></span>
<a href="" id="verifyProfileLink">(verify this match)</a> <a href="" id="verifyProfileLink">(verify this match)</a>
<a href="" id="changeProfileLink">(change profile)</a>
</p> </p>
<input type="hidden" id="associatedProfileUri" name="associatedProfileUri" value="" /> <input type="hidden" id="associatedProfileUri" name="associatedProfileUri" value="" />
</div> </div>
@ -36,7 +37,9 @@
<label for="">Create an associated profile</label> <label for="">Create an associated profile</label>
<select name="degreeUri" id="degreeUri" > <select name="degreeUri" id="degreeUri" >
<option value="" selected="selected">Select one</option> <option value="" selected="selected">Select one</option>
<option value="" disabled>Bogus</option> <#list profileTypes?keys as key>
<option value="${key}" >${profileTypes[key]}</option>
</#list>
</select> </select>
</p> </p>
</div> </div>
@ -47,9 +50,20 @@
<script type="text/javascript"> <script type="text/javascript">
var associateProfileFieldsData = { var associateProfileFieldsData = {
<#if userUri??>
userUri: '${userUri}' ,
<#else>
userUri: '' ,
</#if>
<#if showAssociation??>
associationEnabled: true ,
ajaxUrl: '${formUrls.accountsAjax}' ajaxUrl: '${formUrls.accountsAjax}'
</#if>
}; };
</script> </script>
${scripts.add('<script type="text/javascript" src="${urls.base}/js/account/accountAssociateProfile.js"></script>')} ${scripts.add('<script type="text/javascript" src="${urls.base}/js/jquery.js"></script>',
'<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/account/accountAssociateProfile.js"></script>')}

View file

@ -86,14 +86,20 @@
be reset until the user follows the link provided in this email. be reset until the user follows the link provided in this email.
</p> </p>
<#else> <#else>
<table>
<tr>
<td>
<label for="new-password">New password<span class="requiredHint"> *</span></label> <label for="new-password">New password<span class="requiredHint"> *</span></label>
<input type="password" name="newPassword" value="${newPassword}" id="new-password" role="input" /> <input type="password" name="newPassword" value="${newPassword}" id="new-password" role="input" />
</td>
<p>Minimum of ${minimumLength} characters in length.</p> <td>
<p>Leaving this blank means that the password will not be changed.</p>
<label for="confirm-password">Confirm initial password<span class="requiredHint"> *</span></label> <label for="confirm-password">Confirm initial password<span class="requiredHint"> *</span></label>
<input type="password" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input" /> <input type="password" name="confirmPassword" value="${confirmPassword}" id="confirm-password" role="input" />
</td>
</tr>
</table>
<p>Minimum of ${minimumLength} characters in length.</p>
<p>Leaving this blank means that the password will not be changed.</p>
</#if> </#if>
<input type="submit" name="submitEdit" value="Save changes" class="submit" /> or <a class="cancel" href="${formUrls.list}">Cancel</a> <input type="submit" name="submitEdit" value="Save changes" class="submit" /> or <a class="cancel" href="${formUrls.list}">Cancel</a>