Symptoms:
You develop a browser-compatible InfoPath form with managed code for business logic.
You use ContactSelector ActiveX control to look up and resolve users from the SharePoint site Users lists (UserInfo table in the Content database).
You then validate list of resolved users and copy some of them to another node in the primary data source. The field displays copied contacts as a concatenated string.
Your logic works when tested in the rich InfoPath client.
Resolved contacts are not copied when tested with Internet Explorer. IE does more postbacks than other browsers. In my case only third request contained the lookup token for contact resolution.
Resolved contacts are copied multiple times in a single postback (even before you are prompted for resolution) when tested with Firefox and other level 2 browsers. When you begin resolving for the first time you are presented a picker window for the first empty node, which you have to delete. The first occurrence of a given contact is never resolved automatically, while the second and others usually are.
FireFox
8;_0_;aabc78a4-2c90-4eb4-b907-efdde6081724;9d08e01d-9d57-4e85-ad88-e7e177dc85e4:ver:1.0.0.69;0;;http%3A%2F%2Fspdev%2FFormServerTemplates%2FtrySZ.xsn;http%3A%2F%2Fspdev%2FFormServerTemplates%2FtrySZ.xsn;http%3A%2F%2Fspdev%2FInForms%2F;http%3A%2F%2Fspdev;http%3A%2F%2Fspdev%2FInForms%2FForms%2FAllItems.aspx;1;1;0;2;1;633988049367884000;;+age6upPf7USGkrCI/yi9kTSjvA6i5NVYPoOO9r4ST0zr2dYVKtUP1eB1ZbMDExztOK7lNa+8W8IF3Jt+yuSyQ==|633988049367728266 18;V1_I1_CP2;;T%252F%252F0%252F%252F%253B_sdja_%252F%252F0%252F%252F [4,["\n \n sdja",["\n \n sdja","","",-1],[true,[["","",0,"",0,[]],["sdja","",0,"",1,[["John Doe","CONTOSO\\sdja",1,"John Doe",""]]]],false],false,false,false],-1,false,false],[5,["\n sdja\n ",["\n sdja\n ","","",-1],[false,[["sdja","",0,"",0,null]],false],false,false,false],-1,false,false],
Internet Explorer
8;_2_;0387bf44-e9a8-48eb-bf89-a31736034aee;9d08e01d-9d57-4e85-ad88-e7e177dc85e4:ver:1.0.0.69;0;;http%3A%2F%2Fspdev%2FFormServerTemplates%2FtrySZ.xsn;http%3A%2F%2Fspdev%2FFormServerTemplates%2FtrySZ.xsn;http%3A%2F%2Fspdev%2FInForms%2F;http%3A%2F%2Fspdev;http%3A%2F%2Fspdev%2FInForms%2FForms%2FAllItems.aspx;1;1;0;2;1;633988006159329000;;k1ayFO2PmR324jVtDEih3Z9aMGrEduuo5q/4JVt5AH0kw6Sd6ynEw5wmqck1Q+GkXniEM+OuLjXrDUC9rIAlQw==|633988006210373259 18;V1_I1_CP2;;T_sdja_%252F%252F0%252F%252F [4,["\n \n sdja",["\n \n sdja","","",-1],[true,[["sdja","",0,"",0,[["John Doe","CONTOSO\\sdja",1,"John Doe",""]]]],true],false,false,false],-1,false,false],[5,["\n \n ",["\n \n ","","",-1],[false,[],true],false,false,false],-1,false,false],
Contact Selector
Information about the control can br found on the InfoPath team blog:
Using the Contact Selector Control
I can add that it is rendered in the browser (Firefox) as HTML table, div and span elements handling events with functions declared in Core.js for all ContactPicker controls.
<TABLE><TBODY> <TR> <TD vAlign=top><BUTTON style="FONT-STYLE: normal; FONT-FAMILY: Segoe UI; FONT-SIZE: 9pt; FONT-WEIGHT: 400; TEXT-DECORATION: none" id=V1_I1_CP2_AddressButton onfocus="return (ContactPicker.OnButtonFocus(this, event));" title="Add contacts from address book" onclick="return (ContactPicker.OnShowAddressBookClick(this, event));"><NOBR><IMG style="VERTICAL-ALIGN: middle" alt="" src="http://spdev/_layouts/inc/contactPickerSelectNames.png?rev=azqd2BNDQfZJX%2Bi5rXdMhQ%3D%3D"> <SPAN style="VERTICAL-ALIGN: middle">Кому: </SPAN></NOBR></BUTTON></TD> <TD style="WIDTH: 100%"><SPAN onmouseover="return (LeafControl.OnMouseOver(this, event));" onmouseout="return (LeafControl.OnMouseOut(this, event));"><SPAN id=V1_I1_CP2_SignIcon></SPAN><SPAN id=V1_I1_CP2_ErrorTip></SPAN> <DIV onkeydown="return (ContactPicker.OnKeyDown(this, event));" id=V1_I1_CP2 class="h_ m_ " onfocus="return (ContactPicker.OnFocus(this, event));" onmouseover="return (ContactPicker.OnMouseOver(this, event));" onmouseout="return (ContactPicker.OnMouseOut(this, event));" onclick="return (ContactPicker.OnClick(this, event));" viewDataNode="3" scriptclass="ContactPicker" maxlines="4" name="V1_I1_CP2" alt> <DIV ondragover="return (ContactPicker.OnEditBoxDragOver(this, event));" oncontrolselect="return (ContactPicker.OnEditBoxControlSelect(this, event));" onblur="return (ContactPicker.OnEditBoxBlur(this, event));" hideFocus style="OVERFLOW-Y: auto; HEIGHT: 15px; WORD-BREAK: break-all" id=V1_I1_CP2_RecipientsList onactivate="return (ContactPicker.OnEditBoxActivate(this, event));" class=hideChildAnchors onfocus="return (ContactPicker.OnEditBoxFocus(this, event));" title="" ondrop="return (ContactPicker.OnEditBoxDrop(this, event));" tabIndex=0 contentEditable=true onmousedown="return (ContactPicker.OnEditBoxMouseDown(this, event));" maxHeight="60"><SPAN class=recipientResolvedUser tabIndex=-1 contentEditable=false ownerid="V1_I1_CP2" displayname="John Doe" objectid="CONTOSO\sdja" objecttype="1" realname="Djaarbekov Stanislav M." orgindex="0"><SPAN tabIndex=-1 contentEditable=true>Doe John Jr.</SPAN></SPAN>; <SPAN class=recipientResolvedUser tabIndex=-1 contentEditable=false ownerid="V1_I1_CP2" displayname="Mary Kay" objectid="LITWARE\mar" objecttype="1" realname="Mary Kay" orgindex="1"><SPAN tabIndex=-1 contentEditable=true>Mary C. Kay</SPAN></SPAN></DIV> <DIV style="DISPLAY: none" id=V1_I1_CP2_NCEContactPicker> <DIV style="OVERFLOW: auto" id=V1_I1_CP2_NCERecipientsList 4?em?></DIV><INPUT onblur="return (ContactPicker.OnEditBoxBlur(this, event));" style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; WIDTH: 100%; BORDER-TOP: 0px; BORDER-RIGHT: 0px" id=V1_I1_CP2_EditBox onfocus="return (ContactPicker.OnEditBoxFocus(this, event));" title="" tabIndex=0></DIV></DIV></SPAN></TD> <TD vAlign=top><BUTTON id=V1_I1_CP2_ResolveButton onfocus="return (ContactPicker.OnButtonFocus(this, event));" title="Resolve names" onclick="return (ContactPicker.OnResolveAllClick(this, event));"><IMG style="VERTICAL-ALIGN: middle" alt="Resolve names" src="http://spdev/_layouts/inc/contactPickerCheckNames.png?rev=ReirwPoq%2Fu%2BOSZA9X276Gg%3D%3D"></BUTTON></TD></TR></TBODY></TABLE>