0

This is all for SharePoint 2010. I have in my form the ability to put in a user in a people picker and then the users click a button that pulls in the user's email address and dept phone number. This works fine with any owners of the site (people who have full control), however it works with no one else. I get access denied when $(xData.responseXML) runs. I'm not sure if this can be fixed within the site collection level of if there are permissions that need to be changed in Central Admin (which is not an option). If anyone knows a fix, I'd appreciate it...or if anyone knows a better way to get another user's phone number (email works straight from people picker), I'll take that as well.

Basically what I'm doing is extracting the user's email from the people picker, using SPServices to GetUserLoginFromEmail and then using the login and SPServices GetUserProfileByName to get the phone number. Here is the full code:

function getPeople(){
var personField = "Contact Name";  // this must match the display name of the people picker field
var assigned; // value from people picker field
var userEmail; // stores the assigned's email
var userLogin; // assigned's login ie: (domain\name)
var trueLogin; // asigned's login converted for javascript ie: (domain\\name)
var workPhone; // stores assigned's work phone

// Get people picker value
assigned = $().SPServices.SPFindPeoplePicker({ 
    peoplePickerDisplayName: personField,
    checkNames: true
});
// intiate check names - don't have to do another timeout here as we should already
// have proper values here, simply doing it again as a secondary check
assigned.checkNames.click();
// get the users email from the SPFindPeoplePicker dictionary
userEmail = assigned.dictionaryEntries[0].Email;
// use the email to get the user's login information
$().SPServices({
    operation: 'GetUserLoginFromEmail',
    emailXml: "<Users><User Email='" + userEmail + "'/></Users>",
    async: false,
    completefunc: function (xData, Status) {
        $(xData.responseXML).find("User").each(function() {
            userLogin = $(this).attr("Login");
        });
    }
});
// convert the login to javascript usable login
trueLogin = userLogin.replace(/\\/g,'\\');
// Get user information
$().SPServices({
    operation: "GetUserProfileByName",
    async: false,
    AccountName: trueLogin,
    completefunc: function (xData, Status) {
        workPhone = getUPValue(xData.responseXML, "WorkPhone");
    }
});
// fill out the text boxes with information
getField('input','Contact Email').value = userEmail;
getField('input','Contact Phone').value = workPhone;
}
// gets the value of the called profile field
function getUPValue(x, p) {
var thisValue = $(x).SPFilterNode("PropertyData").filter(function() {
    return $(this).find("Name").text() == p;
}).find("Values").text();
return thisValue;
}

When I hard coded my login and ran the page, the GetUserProfileByName worked fine. So it only seems to be the GetUserLoginFromEmail that is not working with the permissions the way they are.

Thanks for any and all help/suggestions. By the way, client-side code is my only option at this point.

1

EDIT: I'll leave what I wrote below, but that information is only good if you've already saved the form and are back in to do an edit. To fix it, change the line:

acctName = assigned.dictionaryEntries[0].AccountName;

To

var peopleData = $("div[id='divEntityData']");
acctName = peopleData.attr("description");

I don't know how well this will scale, if the same attributes are used in SharePoint 2013, but for SP1 of 2010, this works for now. I believe if you have more than one people picker on the page you'll have to iterate through them to find the one you want to work with (just so happens, the one I'm working with is the first one on the page, so I didn't have to worry about that).

Original Post: Alright, after thumbing through the html on the page and understanding how SPFindPeoplePicker works, I found a dictionary entry for the login. So for anyone wondering it is AccountName. So here is my new code to get this working - I can bypass using GetUserLoginFromEmail altogether:

function GetPeople(){
var personField = "Contact Name";  // this must match the display name of the people picker field
var assigned; // value from people picker field
var userEmail; // stores the assigned's email
var workPhone; // stores assigned's work phone
var acctName; // stores the login

// Get people picker value
assigned = $().SPServices.SPFindPeoplePicker({ 
    peoplePickerDisplayName: personField,
    checkNames: true
});
// intiate check names - don't have to do another timeout here as we should already
// have proper values here, simply doing it again as a secondary check
assigned.checkNames.click();
// get the users email from the SPFindPeoplePicker dictionary
userEmail = assigned.dictionaryEntries[0].Email;
acctName = assigned.dictionaryEntries[0].AccountName;

// Get user information
$().SPServices({
    operation: "GetUserProfileByName",
    async: false,
    AccountName: acctName,
    completefunc: function (xData, Status) {
        workPhone = getUPValue(xData.responseXML, "WorkPhone");
    }
});
// fill out the text boxes with information
getField('input','Contact Email').value = userEmail;
getField('input','Contact Phone').value = workPhone;
}
// gets the value of the called profile field
function getUPValue(x, p) {
var thisValue = $(x).SPFilterNode("PropertyData").filter(function() {
    return $(this).find("Name").text() == p;
}).find("Values").text();
return thisValue;
}

Had I known a couple weeks ago about this, it would have saved a bunch of headaches. For all the curious ones out there, looks like in 2010 the array of Dictionary Entries is:

  • SPUserID
  • AccountName (ie login)
  • Email
  • Department
  • PrincipalType
  • Title
| improve this answer | |
0

As I recall, the user and groups operations require admin/full control privs to use. You might want to try using the user profile service operations to get the pieces of information. You can gat all the data you need out of your GetUserProfileByName call.

You'd just need to alter the code a little bit to split the email address retrieved by the $().SPServices.SPFindPeoplePicker call and append your domain to it and pass that into your GetUserProfileByName call.

| improve this answer | |
  • Thanks for the suggestion, after reading your post, I decided to go through the html line by line to see what I could gather out of it...lead me to the conclusion I posted above. – Djuwal Apr 23 '14 at 18:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.