The Situation
In SharePoint 2010, when you have a list that allows attachments and also has required fields, if not all the required fields are filled out, the attachments disappear when the page reloads to display error text. This is a known bug, but you can work around it by doing custom validation with PreSaveAction(), ensuring that all required fields are filled out before submission. But, if you have a people picker field, the resolution of the entered name happens asynchronously, and might not resolve before PreSaveAction runs.
The Solution
By combining SpServices.SPFindPeoplePicker and some custom jQuery, you can make sure that the people picker has resolved before the form submits.
The Code
Assuming you have a people picker field names “Contact Person” use SpServices to get a handle on the field and call checkNames to start resolving the people picker.
var contactPerson = $().SPServices.SPFindPeoplePicker({
peoplePickerDisplayName: "Contact Person",
checkNames: true
});
When a people picker resolves, it adds a span with the class “ms-entity-resolved” to the row. You can then look for that span to make sure that a name has been entered and resolved.
if (typeof contactPerson.row.find("span[class='ms-entity-resolved']").html() == 'undefined') {
contactPerson.row.find("td[class='ms-formbody']").append('
');
errorCount++;
}
The code above will add a descriptive error after the description for the people picker.

Assuming this is your only required field, here’s the entire PreSaveAction function.
function PreSaveAction() {
//clear the errors
$('div.ms-formvalidation').remove();
// set an error count;
var errorCount = 0;
//check for contact person
var contactPerson = $().SPServices.SPFindPeoplePicker({
peoplePickerDisplayName: "Contact Person",
checkNames: true
});
if (typeof contactPerson.row.find("span[class='ms-entity-resolved']").html() == 'undefined') {
contactPerson.row.find("td[class='ms-formbody']").append('
');
errorCount++;
}
if (errorCount == 0){
return true;
}
else {
return false;
}
} // end presaveaction
I also run check names on change of the field following the people picker in my form, which hopefully gives the async function time to return before you get to PreSaveAction. In this example, the following field was a table of radio buttons, and I ran check names on click:
// try to resolve the contact person whenever someone clicks a button in the approval group
$('table[title="Theme"] :radio').bind("click", function(){
//check for contact person
var contactPerson = $().SPServices.SPFindPeoplePicker({
peoplePickerDisplayName: "Contact Person",
checkNames: true
});
});
u591au722du53d6u6642u9593u4f11u606fu5566uff01~~nwork hard and take care la ^.^ Click https://zhoutest.wordpress.com/
Hi 🙂 Thanks for this simple yet useful code!
Is there a way to use .focus() to the field also?
Um, I’d have to Google that and do some research into it. Feel free to play around with it, though.
Hi Deanna, for some reasons when I’m testing the code, the ms-entity-resolved is still undefined even if i placed a name in it. would you know why?
Thanks again!
If it’s undefined, you’re probably not waiting long enough. It should be there, once the people picker resolves. (Though, I haven’t tested this code in a long time, and who knows what Microsoft may have changed in various updates.)
Thanks Deanna. I’m still trying to troubleshoot it…