Freitag, 23. November 2012

Issues with Lookup-Fields with each more than 20 items

If you have multiple lookup-fields in your form which reference to more than 20 items (hardcoded limit in the LookupField-Control!), you may notice to the display and behaviour of your control:

- The rendering of the field switches from select-tag to an input-tag and an img-tag. A click on the image shows a layer with the selectfield.
- This only occures to Internet Explorer, not to Firefox.

The naughty thing on this is the issue, that the selectfield-layer appears below the first-clicked lookup-field, no matter, which lookupfield you click afterwards.

Click on the first lookup:



Click on the second lookup:



This bug can be fixed by override a function in the core.js that must be loaded immediatly in the masterpage. A good piece of working code I found here today: http://dipaktele.blogspot.de/2012/07/two-lookup-field-with-more-than-20.html

I copied the code found on this page and added it here:


function FilterChoice(opt, ctrl, strVal, filterVal) {
if (typeof (opt) != "undefined") {
var i,
cOpt = 0,
bSelected = false,
strHtml = "",
strId = opt.id,
strName = opt.name,
strMatch = "",
strMatchVal = "",
strOpts = ctrl.choices,
rgopt = strOpts.split("|"),
offSet = $(ctrl).position(),
x = offSet.left,
y = offSet.top 15,
strHidden = ctrl.optHid,
iMac = rgopt.length - 1,
iMatch = -1,
unlimitedLength = false,
strSelectedLower = "";
if (opt != null && opt.selectedIndex >= 0) {
bSelected = true;
strSelectedLower = opt.options[opt.selectedIndex].innerText;
}
for (i = 0; i < rgopt.length; i = i 2) {
var strOpt = rgopt[i];
while (i < iMac - 1 && rgopt[i 1].length == 0) {
strOpt = strOpt "|";
i ;
if (i < iMac - 1) {
strOpt = strOpt rgopt[i 1];
}
i ;
}
var strValue = rgopt[i 1];
var strLowerOpt = strOpt.toLocaleLowerCase();
var strLowerVal = strVal.toLocaleLowerCase();
if (filterVal.length != 0)
bSelected = true;
if (strLowerOpt.indexOf(strLowerVal) == 0) {
var strLowerFilterVal = filterVal.toLocaleLowerCase();
if ((strLowerFilterVal.length != 0) && (strLowerOpt.indexOf(strLowerFilterVal) == 0) && (strMatch.length == 0))
bSelected = false;
if (strLowerOpt.length > 20) {
unlimitedLength = true;
}
if (!bSelected || strLowerOpt == strSelectedLower) {
strHtml = "<option selected value=\"" strValue "\">" STSHtmlEncode(strOpt) "</option>";
bSelected = true;
strMatch = strOpt;
strMatchVal = strValue;
iMatch = i;
}
else {
strHtml = "<option value=\"" strValue "\">" STSHtmlEncode(strOpt) "</option>";
}
cOpt ;
}
}
var strHandler = " onclick=\"HandleOptDblClick()\" onkeydown=\"HandleOptKeyDown()\"";
var strOptHtml = "";
if (unlimitedLength) {
strOptHtml = "<select tabIndex=\"-1\" ctrl=\"" ctrl.id "\" name=\"" strName "\" id=\"" strId "\"" strHandler;
}
else {
strOptHtml = "<select class=\"ms-lookuptypeindropdown\" tabIndex=\"-1\" ctrl=\"" ctrl.id "\" name=\"" strName "\" id=\"" strId "\"" strHandler;
}
if (cOpt == 0) {
strOptHtml = " style=\"display:none;position:absolute;z-index:2;left:" x "px;top:" y "px\" onfocusout=\"OptLoseFocus(this)\"></select>";
}
else {
strOptHtml = " style=\"position:absolute;z-index:2;left:" x "px;top:" y "px\"" " size=\"" (cOpt <= 8 ? cOpt : 8) "\"" (cOpt == 1 ? "multiple=\"true\"" : "") " onfocusout=\"OptLoseFocus(this)\">" strHtml "</select>";
}
opt.outerHTML = strOptHtml;
var hid = document.getElementById(strHidden);
if (iMatch != 0 || rgopt[1] != "0")
hid.value = strMatchVal;
else
hid.value = "0";
if (iMatch != 0 || rgopt[1] != "0")
return strMatch;
else return "";
}
}

_spBodyOnLoadFunctionNames.push("FilterChoice");
function EnsureSelectElement(ctrl, strId) {
$("#" strId).remove();
var select = document.getElementById(strId);
if (select == null) {
select = document.createElement("SELECT");
ctrl.parentNode.appendChild(select);
select.outerHTML = "<select id=\"" strId "\" ctrl=\"" ctrl.id "\" class=\"ms-lookuptypeindropdown\" name=\"" strId "\" style=\"display:none\" onfocusout=\"OptLoseFocus(this)\"></select>";
FilterChoice(select, ctrl, ctrl.value, "");
}
return document.getElementById(strId); ;
}


After that, the select is displayed correctly:



Please be sure to include there functions in your own js-file that's loaded after the core.js and avoid modifying the original core.js.



Donnerstag, 15. November 2012

New SharePoint 2013 / 15 cmdlets for Powershell you shouldn't use...

I just browse the web for new things that come with SharePoint 2013 / 15. Now I'm landed on the technet-page for all new Powershell-Cmdlets:

http://technet.microsoft.com/library/ff678226%28office.15%29.aspx

A funny thing are a few new cmdlets you explicitely should avoid to use but the funniest imo are Add-SPSocialAppPermissions and Remove-SPSocialAppPermissions.

So if you belong to the 1% of people with a completely working user profile synchronization service without any issues and you are bored of all the perfectly working sharepoint environment, you should definitively run this cmdlet, because "The use of the Add-SPSocialAppPermissions cmdlet can result in profile synchronization connections that are unusable and non-editable".

More cmdlets you called upon not to use are:

- New-SPBECWebServiceApplicationProxy
- Remove-SPSocialAppPermissions
- New-SPBECWebServiceApplicationProxy

If you have any idea, why Microsoft creates such cmdlets not intended to use by people, please leave a comment :-D

Mittwoch, 4. April 2012

ArgumentException when setting SPUser to a UserField in SPListItem

A little hint for everyone that ever got an argument exception if he tried to set a SPUser-object to an userfield in a list item:

SPListItem listItem = list.Items.Add(listRootFolder.ServerRelativeUrl, SPFileSystemObjectType.File, null);
listItem["Owner"] = spUser; <-- if you step through the code while debugging, an argument exception may occur here 
listItem["Url"] = url; 
listItem["Title"] = title; 
listItem.Update();


In case of an argument exception, you have to check if the assigned spUser-object has been opened from the same parent web as the list.

Freitag, 17. Februar 2012

Bugfix for 'Walkthrough: Replacing a Button on the Server Ribbon'

There is an example how to replace a button on the server ribbon available in the MSDN with one issue: it doesn't work ... ;-)

But I found the error and commented it below in the Community Content-section. For completeness I'll post it in my blog again:

There exists no button with the ID 'Ribbon.Library.Actions.ConnectToClient.ReplacementButton' so a javascript-error is thrown in the browser. The part of the xml must changed to this line and then it works:

<CommandUIDefinition Location="Ribbon.Library.Actions.ConnectToClient">
  <Button Id="Ribbon.Library.Actions.ConnectToClient" Command="ReplacementButtonCommand" ...>


Just remove the string '.ReplacementButton' in the Id of the Button from the example and it works.