Category Archives: Sharepoint 2010

CAML Query did not return result for Date Range query

Having developing SharePoint for so many years, I just got to know that you CANNOT perform CAML Query for Date Range where your ISO Value is a DateTime.MinValue.

CAML Query does not support Date Value of DateTime.MinValue

SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.MinValue)

For example, if you were to query the Event Date Time from day 1

<Geq> 
 <FieldRef Name='EventDate' />
 <Value IncludeTimeValue='FALSE' Type = 'DateTime'>" + 
SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.MinValue) + @" </Value>
 </Geq>

DO NOT DO this. You will never get any result. The minimal value that you can insert (had some googling around the web), is 1900/01/01.

Just make sure you conduct a date time in 1900 year onwards and you will be safe.

SharePoint Custom Solution Branding and Tips – Part 2

This is part 2 on how to brand your SharePoint Solution. If you haven’t read my part 1, please do so here.

Often than not, you would want to include your custom List Definition/Instance to be provisioned into your Solution file. In SharePoint 2013, they’ve changed the Site Content page drastically and you can’t really Ignore the BIG BIG icon for each List/Library within your site.

sharepoint site content list icon image

It’s fancy and it’s sleek. So how can I create one for my own solution?

As usual, there isn’t gonna be much documentation provided in MSDN. And most of the time, you just got to crack your head and dig your way out. I’m writing this post here so that you can at least Find my article when you’re googling around.

How to set Image for your List Definition / List Instance

Assuming you have already created a SharePoint 2013 Project solution and added a List Definition.

Add SharePoint “Images” mapped folder into your Project as shown below

right click add image layout folder sharepoint

Prepare TWO icons and you must ensure that the following rules are followed:

  1. Both icons must have same file extension.
  2. One icon is in 16×16 pixel size and the other one is in 96×96 pixel size
  3. File Name of the 16×16 icon must starts with small I: “it” e.g. itmyfancyicon.png
  4. File Name of the 96×96 icon must starts with small L: “lt” e.g. ltmyfancyicon.png
  5. Both file names must be exactly the same except for the first character.

To better helping you to understand, I’m including the two images used below

itmyfancyicon.png itmyfancyicon  (16×16)                  ltmyfancyicon.png ltmyfancyicon (96×96)

After meeting these rules, you need to include them into the Images mapped folder and be placed into the same Folder. (Must)

sharepoint list icon image same folder

Lastly, go to the Elements.xml file of the list definition and modify the Image Attribute to point to “it” (16×16 pixel size) image as shown below. DO NOT specify the one that starts with “L”.

http://wp.ahcheng.com/wp-content/uploads/2016/01/sharepoint-list-definition-image-url-attribute.png

Once you specified to the small “i” image, deploy it and you should see your List is having a nice and Correct images!

http://wp.ahcheng.com/wp-content/uploads/2016/01/sharepoint-list-definition-image-how-to-set-it-properly.png

 

 

EditorPart does not have an ID

Yet another error that I’ve encountered when customizing ToolPart (aka EditorPart) for my own SharePoint Web Part.

The task is to create a custom tool part with custom control that displays a list of SharePoint Lists. This custom control contains a post back logic to update another drop down list base on the selected value.

In order to display your toolpart into the Web Part properties pane, you would need to override the following virtual method in System.Web.UI.WebControls.WebParts.WebPart class


public override EditorPartCollection CreateEditorParts()

I bumped into this error “EditorPart does not have an ID” with the following code that was not done correctly


public override EditorPartCollection CreateEditorParts()
{
 ArrayList editorArray = new ArrayList();
 MyEditorPart part = new MyEditorPart() { ID = this.ID + "_editorPart1" };
 editorArray.Add(part);
 editorArray.Add(new WebPartToolPart() );
 editorArray.Add(new CustomPropertyToolPart());
 EditorPartCollection editorParts = new EditorPartCollection(editorArray);
 return editorParts;

}

The use of including WebPartToolPart and CustompropertyToolPart is to ensure that your custom web part would still display the OOTB Web Part Properties pane (which has the functionality to change Height, Width, ChromeType etc etc)

To use them correctly, you would need to specify an ID for each of the class. After applying the code below, the error is gone.


public override EditorPartCollection CreateEditorParts()
{
 ArrayList editorArray = new ArrayList();
 MyEditorPart part = new MyEditorPart() { ID = this.ID + "_editorPart" };
 editorArray.Add(part);
 WebPartToolPart wpToolPart = new WebPartToolPart() { ID = this.ID + "_wpToolPart" };
editorArray.Add(wpToolPart);

 CustomPropertyToolPart cpToolPart = new CustomPropertyToolPart() { ID = this.ID + "_cpToolPart" };
 editorArray.Add(cpToolPart);
 EditorPartCollection editorParts = new EditorPartCollection(editorArray);
 return editorParts;
}

A Web Part or Web Form Control on this Page cannot be displayed or imported. The type could not be found or it is not registered as safe.

This is a very common error that SharePoint Developers often face. As stated in the error message, this is due to SafeControl Elements in Web.Config file of your SharePoint Application not being added correctly, or perhaps pointing to the wrong type name.

Resolution

To solve this issue, you’ll need to make sure that the SafeControl Entries in your SharePoint solution projects is configured correctly.

Step 1 – Find out what is the correct type name.

  1. Navigate to your .webpart file in Visual Studio that you’ve misconfigured.
  2. Double clicking it to open the webpart file.
  3. Copy the Type Name and exclude the last node
    web part register 1
  4. Alternatively, go to your web part .cs file and copy the Namespace
    web part register 2

Now that you have the correct type name. You need to…

Step 2 – Specify the right Safe Entry

  1. Click on the Web Part
  2. Under Properties panel, click on the … icon beside Safe Control Entries
    web part register 3
  3. Enter the value found in Step 1 into Namespace field as shown below.
    web part register 4
  4. Deploy and Done!

PowerShell script to Open or Close SharePoint Web Parts

If you ever need to make changes to your SharePoint Web Parts such as hiding/showing, this post will help you to cut down unnecessary time.

Run the PowerShell script below via SharePoint Management Shell.

Change the Parameter accordingly base on your environment.


$web = Get-SPWeb [URL]
$f = $web.GetFile("Pages/Default.aspx");

if( $f.CheckOutStatus -eq "None" )
{
  $f.CheckOut();
}
$wpm = $f.GetLimitedWebPartManager("Shared")
$webParts = $wpm.WebParts | ? {$_.GetType().Name -eq "ContentEditorWebPart"} //Change for your own web part type
if($webParts.GetType().Name -eq "Object[]")
{
  $webParts | % {
    #$wpm.CloseWebPart($_);
    $wpm.OpenWebPart($_);
    $wpm.SaveChanges($_);
  }
}
else
{
  #$wpm.CloseWebPart($webParts)
  $wpm.OpenWebPart($webParts)
  $wpm.SaveChanges($webParts)
}

$f.CheckIn("");
$f.Publish("");

The example above will check if the page is check out before making any changes to the web parts. Subsequently, it closes/opens all content editor web parts within it and check in and publish the page. You can additional perform more tasks such as DeleteWebPart or AddWebPart, MoveWebPart or only make changes to only certain type of web part by changing PowerShell rules

 

Convert SharePoint 2010 Solution to 2013 – 15 Hive Folder only

Bumped into this problem where I was trying to convert old codes from SharePoint 2010 to SharePoint 2013.

One issue that you will encounter is that all your Element Files being uploaded to 14 Hive folder (the old 2010 path) rather than the new 15 Hive folder.

If you deploy your solution directly into a SP2013 environment, you will encounter reference link broken or file not found due to codes/files not being deployed to 15 Hive.

One Workaround is to actually deploy your solution with switch -CompatibilityLevel All (for detail please refer here ). However, you can’t always remember to do this steps and in order for you to really upgrade your solution to SP2013, You need to make some changes to the manifest file. And steps below show you how to change it permanently and only stick to 15 hive folder.

Resolution

  1. Open your SharePoint solution via Visual Studio.
  2. Expand the Package folder and Double click “Package.package
  3. Under Properties Panel, change the property “SharePoint Product Version” from 14.0 to 15.0
    upgrade sp2010 to sp2013 solution
  4. Package it and done!

P/S What I additional did to make sure there is no reference link broken is to Find ALL “_layouts/“, “_CONTROLTEMPLATES/” and replace with “_layouts/15/” and “_CONTROLTEMPLATES/15/

Changing Default HomePage for Document Center to a Document Library

As stated in the Title, it is easier said than done to change the default landing page of a Document Center. If you have done publishing sites often, you will usually go to “Welcome Page” in the site setting page to do it.

welcome page publishing

But in Document Center site, this feature is missing and what’s even worse, that there is no Pages or Site Pages library for you to set the homepage

[I’m referring to the set homepage feature below]

make home page

So how to change the default landing page for SharePoint Document Center?

The trick is simple, all you need to do is to go to the Document Library that you want to make default home page.

Hit on the “Edit Page” menu under Site Action gear.

edit page in document library

Once the Document Library page is in Edit Mode, you shall see additional Ribbon Tabs appear and shown below, Go to “Pages” tabs and now you can set the HOME PAGE! (hidden gem)

document library make homepage

There are alternative ways of doing this such as running PowerShell etc. but I personally find this the quickest and easiest way to do it.

Hope it helps!

 

Enable Search feature for SharePoint Lookup Table – Single Value Only

Today I want to talk about how to enable search feature in your SharePoint New/Edit Form for SharePoint Lookup field… I’m gonna use jQuery and jQuery UI’s Autocomplete widget to fulfill this feature.

Let’s assume you have a list called “Lookup” with all your items (to be lookup) and a list “Lookup Test” that lookup to list “Lookup”‘ title. By default, a lookup field does not allow you to do “contains” search (which is kinda very common to have nowadays).

I’m attaching the comparison of the before and after applying the tricks that I’m gonna cover in this post.

search lookup comparison

This is assuming that you already have a SharePoint Designer 2013 and you’ve created two lists as mentioned above.

First of all, Open your SharePoint Designer, navigate to your SharePoint Site and Open the New Form of the “Lookup Test” list.

search lookup designer 2

Once it is opened, make sure you have already click “Advanced Mode” in order to edit the NewForm.aspx

search lookup field 1

Scroll to place holder “PlaceHolderAdditionalPageHead” content placeholder and include the necessary JS/CSS


<script src="https://code.jquery.com/jquery-1.11.3.min.js" type="text/javascript"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.css"/>

<style>
.custom-combobox {
position: relative;
display: inline-block;
}
.custom-combobox-toggle {
position: absolute;
top: 0;
bottom: 0;
margin-left: -1px;
padding: 0;
}
.custom-combobox-input {
margin: 0;
padding: 5px 10px;
}
</style>

search lookup field 2

Scroll to right before the closing tag of placeholder “PlaceHolderMain” and insert the following JS Code


<script type="text/javascript">
(function( $ ) {
$.widget( "custom.combobox", {
_create: function() {
this.wrapper = $( "<span>" )
.addClass( "custom-combobox" )
.insertAfter( this.element );

this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
},

_createAutocomplete: function() {
var selected = this.element.children( ":selected" ),
value = selected.val() ? selected.text() : "";

this.input = $( "<input>" )
.appendTo( this.wrapper )
.val( value )
.attr( "title", "" )
.addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy( this, "_source" )
})
.tooltip({
tooltipClass: "ui-state-highlight"
});

this._on( this.input, {
autocompleteselect: function( event, ui ) {
ui.item.option.selected = true;
this._trigger( "select", event, {
item: ui.item.option
});
},

autocompletechange: "_removeIfInvalid"
});
},

_createShowAllButton: function() {
var input = this.input,
wasOpen = false;

$( "<a>" )
.attr( "tabIndex", -1 )
.attr( "title", "Show All Items" )
.tooltip()
.appendTo( this.wrapper )
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass( "ui-corner-all" )
.addClass( "custom-combobox-toggle ui-corner-right" )
.mousedown(function() {
wasOpen = input.autocomplete( "widget" ).is( ":visible" );
})
.click(function() {
input.focus();

// Close if already visible
if ( wasOpen ) {
return;
}

// Pass empty string as value to search for, displaying all results
input.autocomplete( "search", "" );
});
},

_source: function( request, response ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
response( this.element.children( "option" ).map(function() {
var text = $( this ).text();
if ( this.value && ( !request.term || matcher.test(text) ) )
return {
label: text,
value: text,
option: this
};
}) );
},

_removeIfInvalid: function( event, ui ) {

// Selected an item, nothing to do
if ( ui.item ) {
return;
}

// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children( "option" ).each(function() {
if ( $( this ).text().toLowerCase() === valueLowerCase ) {
this.selected = valid = true;
return false;
}
});

// Found a match, nothing to do
if ( valid ) {
return;
}

// Remove invalid value
this.input
.val( "" )
.attr( "title", value + " didn't match any item" )
.tooltip( "open" );
this.element.val( "" );
this._delay(function() {
this.input.tooltip( "close" ).attr( "title", "" );
}, 2500 );
this.input.autocomplete( "instance" ).term = "";
},

_destroy: function() {
this.wrapper.remove();
this.element.show();
}
});
})( jQuery );

</script>

The similar javascript can be found in jQuery UI Autocomplete Combobox example

Within the same location, insert the following script to convert the lookup field into combo box with search feature.


//Change the lookupField base on the internal field name that you want to enable search feature.

var lookupField = "Lookup";

ExecuteOrDelayUntilBodyLoaded(function(){

$('select[id^="' + lookupField + '"][id$="LookupField"]').combobox();

});

search lookup field 3

Save your NewForm.aspx  and you will be prompted warning message saying that the page will no longer base on the site definition, which is okay. Click Yes to see the miracle!

Once you are happy, make sure you do the same steps for your EditForm.aspx.