Checking for a Resolved People Picker Before Submit

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('

Please enter a contact person. Click the checkmark and wait for the name to resolve before saving your work.

');
errorCount++;

}

The code above will add a descriptive error after the description for the people picker.

Be sure to give your users a descriptive error so that if the people picker resolves in the meantime, they'll know what to do.

Be sure to give your users a descriptive error so that if the people picker resolves in the meantime, they’ll know what to do.

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('

Please enter a contact person. Click the checkmark and wait for the name to resolve before saving your work.

');
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
});

});

Advertisements