Content Query Web Part + Calendar = Mad Problems

I recently had to assemble a content query web part (my least favorite thing) pulling data from a Calendar list and experienced hours of pain trying to get it to pull the locations field as well as the start/end time consistently. I share my pain so that other won’t have to endure, and hopefully some tips so that you can skip all the BS and just make a quick web part that should have took about 30 minutes.

I had an extremely painful time working with the Location field for some reason. It would show on ctrl-f5 or the first load of the web part. Then disappear or show intermittently. It was basically unreliable until I used the ID and renamed the fields as described below.

Getting the fields right

Step 1 – Calendar list settings

If you go to the list settings and copy or inspect the link to the Start Time field you’ll see something like this.

/_layouts/15/FldEdit.aspx?List=%7BE84FD6F2%2D11AD%2D443B%2D84A2%2DA6E1B198458D%7D&Field=EventDate

This is good to give you what the field name is but we actually just want the field ID. Next I move up to the parent content type and click “Event”

image

In these columns I copy or inspect Start Time field again and you’ll see this

/_layouts/15/ManageContentTypeField.aspx?ctype=0x010200D536EDB0AB69A047B200ABF60FFE33EF&List=e84fd6f2-11ad-443b-84a2-a6e1b198458d&Field=EventDate&Fid=%7B64cd368d%2D2f95%2D4bfc%2Da1f9%2D8d4324ecb007%7D

This is what I want – I’ll get the actual field ID. using a url decoder [http://meyerweb.com/eric/tools/dencoder/]

Fid=%7B64cd368d%2D2f95%2D4bfc%2Da1f9%2D8d4324ecb007%7D

Fid={64cd368d-2f95-4bfc-a1f9-8d4324ecb007}

Step 2 – Content Query

Once you’ve exported the content query so we can edit it in notepad, search for CommonViewFields

Add the Start Time field to this property

<property name=”CommonViewFields” type=”string”>{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},DateTime;</property>

Next search for DataColumnRenames, add the following. The EventStartDateTime is what you would use in the xslt to pull this property. You can call it what you like at this point.

<property name=”DataColumnRenames” type=”string”>{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},EventStartDateTime;</property>

Below is a snippet of me using the EventStartDateTime in my xslt. I’m assigning it to a variable to i can further manipulate it.

image

Step 3 – Repeat

You can repeat the following steps for a fool proof method of getting the fields you want into your content query web part. If you use the column ID and rename it you should have no issues.

 

Location Field

{288f5f32-8462-4175-8f09-dd7ba29359a9},Text;

Start Time

{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},DateTime;

End Time

{2684f9f2-54be-429f-ba06-76754fc056bf},DateTime;

 

<property name=”CommonViewFields” type=”string”>{288f5f32-8462-4175-8f09-dd7ba29359a9},Text;{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},DateTime;{2684f9f2-54be-429f-ba06-76754fc056bf},DateTime;</property>

<property name=”DataColumnRenames” type=”string”>{2684f9f2-54be-429f-ba06-76754fc056bf},EventEndDateTime;{288f5f32-8462-4175-8f09-dd7ba29359a9},EventLocation;{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},EventStartDateTime;</property>

 

Troubleshooting

From this day forward I vowed to always include this debugging template in my ItemStyle.xsl. It will basically just dump the raw data to your screen, so you can see what fields you have

   1: <xsl:template name="DisplayRawData" match="Row[@Style='DisplayRawData']" mode="itemstyle">

   2:   <xsl:for-each select="@*">

   3:     <xsl:value-of select="name()"/>

   4:     <xsl:text> = </xsl:text>

   5:     <xsl:value-of select="."/>

   6:     <br/>

   7:   </xsl:for-each>

   8:   <br/>

   9:   <br/>

  10:   <br/>

  11: </xsl:template>

If you set the Item style: DisplayRawData, you’ll get a dump of the fields and values that are available. In the screen shot below you’ll notice then fields that we’ve renamed and they data

image

Permanently Removing the Recent Node from Quick Launch for SharePoint 2013

Introduction

Yesterday I was tasked to remove the “Recent” node from the quick launch for a customers SharePoint online site. I’ve decided to release the solution in hopes that other people could take advantage of it. The picture below will show you the “Recent” node.

Recent Node

This node was undesired by the user because they wanted to have control over the quick launch navigation. They mentioned that every time they add a new list or library then new items will be added under the “Recent” node. When they go and delete it from the Navigation section in Look & Feel, it will just re-appear when they create a new list or library. Basically they wanted it gone.

Approach

I chose an approach similar to this blog article http://www.jasperoosterveld.com/2013/02/sharepoint-2013-remove-recent-in-quick.html however, I needed it to work on sandbox for o365 and SPO. I also decided to sharpen my JavaScript Client Object model skills and write a small script that will remove the “Recent” node whenever it is created.

I paired this with the jQuery as suggested in the article to hide the “Recent” node. Except I made one modification to it you can see below. I’ve added the id #sideBox to have this only search in the Quick Launch. I explain more about why I remove and hide it in the next section.

this > jQuery(“.ms-core-listMenu-item:contains(‘Recent’)”).parent().hide();

to this > jQuery(“#sideBox .ms-core-listMenu-item:contains(‘Recent’)”).parent().hide(); 

The Solution

The entire solution & the pre-built .wsp can be downloaded from CodePlex – http://rr.codeplex.com

The sandbox solution is composed of two components:

  1. RemoveRecent.js – JavaScript Client Object Model code which removes the “Recent” node from the quick launch if detected on page refresh.
  2. HideRecent.js – jQuery code to hide the “Recent” node

Why remove and hide?

Since the RemoveRecent.js runs client side there is a case where you may see the “Recent” node. For example you just finished creating a new list and the page refresh. The code to remove the node in RemoveRecent.js is called asynchronously. The list or library is removed from the back end but on the client side is not updated. This could be handled with a refresh but that causes a double refresh once you create a new list and there is a delay between the refreshes. I felt that this created a bad user experience. The answer to that was to also hide the node using HideRecent.js

 

Hope this may be useful to some of you out there.

Reuse DataForm Web Part, change ListId to ListName, and scrub GUIDs

Intro

I know there are quite a few posts out there on this, but i’m writing this here for myself as a rollup of the information and highlighting what needs to be done in order for this to work perfectly.

For those not familiar with the issue let me re-hash it quickly. When you create a Data View Web Part (DVWP) or New/Display/Edit form in SharePoint Designer you’ll be directly binding those web parts to your list. If you look at the code you’ll see the list GUIDs below.

<WebPartPages:DataFormWebPart runat=”server” EnableOriginalValue=”False” DisplayName=”My Links” ViewFlag=”8″ ViewContentTypeId=”” Default=”FALSE” ListUrl=”” ListDisplayName=”” ListName=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” ListId=”62f19be4-6465-4293-b580-36c49ec8f35b” PageType=”PAGE_NEWFORM”………………………

Copying this to another site collection or environment won’t work unless your lists have exactly the same GUID. Basically these web parts are non-reusable. Well there is a way to move them.

Two articles that I ALWAYS refer too – but they don’t do it partially or not as cleanly as I want.

http://sympmarc.com/2008/12/16/replacing-listids-with-listnames-in-data-view-web-parts/

http://blogs.msdn.com/b/joshuag/archive/2008/11/10/easily-making-the-data-form-web-part-reusable.aspx

There are a few places you need to rename the ListId from in order for this to work.

  1. The <DataFormWebPart>
  2. The <DataSources>
  3. The <ParameterBindings>
  4. The <XSL:StyleSheet><Params>

Step 1 – DataFormWebPart

This is an original:

<WebPartPages:DataFormWebPart runat=”server” EnableOriginalValue=”False” DisplayName=”My Links” ViewFlag=”8″ ViewContentTypeId=””
Default=”FALSE” ListUrl=”” ListDisplayName=”” ListName=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” ListId=”62f19be4-6465-4293-b580-36c49ec8f35b”
    PageType=”PAGE_NEWFORM” PageSize=”-1″ UseSQLDataSourcePaging=”True” DataSourceID=”” ShowWithSampleData=”False” AsyncRefresh=”False”
ManualRefresh=”False” AutoRefresh=”False” AutoRefreshInterval=”60″ NoDefaultStyle=”TRUE” InitialAsyncDataFetch=”False” Title=”My Links”
FrameType=”None” SuppressWebPartChrome=”False” Description=”” IsIncluded=”True” PartOrder=”2″ FrameState=”Normal” AllowRemove=”True”
AllowZoneChange=”True” AllowMinimize=”True” AllowConnect=”True” AllowEdit=”True” AllowHide=”True” IsVisible=”True” DetailLink=”” HelpLink=””
HelpMode=”Modeless” Dir=”Default” PartImageSmall=”” MissingAssembly=”Cannot import this Web Part.” PartImageLarge=”” IsIncludedFilter=””
ExportControlledProperties=”True” ConnectionID=”00000000-0000-0000-0000-000000000000″ ID=”g_b881fc6c_50db_4108_825a_a5b252da499d”
ChromeType=”None” ExportMode=”All” __MarkupType=”vsattributemarkup” __WebPartId=”{B881FC6C-50DB-4108-825A-A5B252DA499D}” __AllowXSLTEditing=”true”
WebPart=”true” Height=”” Width=””>

Remove ListId and ListName completely.

Step 2 – Data Sources

These are the original data sources. I ALWAYS remove the one’s I’m not using. If your DVWP or List Form does not use the delete then remove it. In my current working example I’m working with an add new item form so all I need it the <InsertParameter>

<DataSources>
<SharePoint:SPDataSource runat=”server” DataSourceMode=”ListItem” SelectCommand=”&lt;View&gt;&lt;Query&gt;&lt;Where&gt;&lt;Eq&gt;&lt;FieldRef Name=&quot;ContentType&quot;/&gt;&lt;Value Type=&quot;Text&quot;&gt;Link&lt;/Value&gt;&lt;/Eq&gt;&lt;/Where&gt;&lt;/Query&gt;&lt;/View&gt;” UseInternalName=”True” UseServerDataFormat=”True” ID=”My_x0020_Links2″>
<SelectParameters>
<WebPartPages:DataFormParameter ParameterKey=”ListID” PropertyName=”ParameterValues” DefaultValue=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” Name=”ListID”/>
<WebPartPages:DataFormParameter ParameterKey=”MaximumRows” PropertyName=”ParameterValues” DefaultValue=”10″ Name=”MaximumRows”/>
</SelectParameters>
<UpdateParameters>
<WebPartPages:DataFormParameter ParameterKey=”ListItemId” PropertyName=”ParameterValues” DefaultValue=”0″ Name=”ListItemId”/>
<WebPartPages:DataFormParameter ParameterKey=”ListID” PropertyName=”ParameterValues” DefaultValue=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” Name=”ListID”/>
</UpdateParameters>
<InsertParameters>
<WebPartPages:DataFormParameter ParameterKey=”ListItemId” PropertyName=”ParameterValues” DefaultValue=”0″ Name=”ListItemId”/>
<WebPartPages:DataFormParameter ParameterKey=”ListID” PropertyName=”ParameterValues” DefaultValue=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” Name=”ListID”/>
</InsertParameters>
<DeleteParameters>
<WebPartPages:DataFormParameter ParameterKey=”ListItemId” PropertyName=”ParameterValues” DefaultValue=”0″ Name=”ListItemId”/>
<WebPartPages:DataFormParameter ParameterKey=”ListID” PropertyName=”ParameterValues” DefaultValue=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” Name=”ListID”/>
</DeleteParameters>
</SharePoint:SPDataSource>
</DataSources>

My updated XML below. I’ve changed the DataFormParameter, Name & ParameterKey to “ListName” and in DefaultValue I’m using the “Links” as the internal name of my list. I’m also specifying the an asp:Parameter of the “WebUrl” so that this can connect to the proper list. This {sitecollectionroot} was pulled from this article – http://blogs.msdn.com/b/joshuag/archive/2008/11/10/easily-making-the-data-form-web-part-reusable.aspx

<DataSources>
<SharePoint:SPDataSource runat=”server” DataSourceMode=”ListItem” UseInternalName=”true” UseServerDataFormat=”True” selectcommand=”&lt;View&gt;&lt;Query&gt;&lt;Where&gt;&lt;Eq&gt;&lt;FieldRef Name=&quot;ContentType&quot;/&gt;&lt;Value Type=&quot;Text&quot;&gt;Link&lt;/Value&gt;&lt;/Eq&gt;&lt;/Where&gt;&lt;/Query&gt;&lt;/View&gt;” id=”My_x0020_Links1″>
<InsertParameters>
<WebPartPages:DataFormParameter Name=”ListItemId” ParameterKey=”ListItemId” PropertyName=”ParameterValues” DefaultValue=”0″/>
<WebPartPages:DataFormParameter Name=”ListName” ParameterKey=”ListName” PropertyName=”ParameterValues” DefaultValue=”Links”/>
<asp:Parameter runat=”server” Name=”WebUrl” DefaultValue=”{sitecollectionroot}” />
        </InsertParameters>
</SharePoint:SPDataSource>
</DataSources>

Step 3 – Parameter Bindings

Your ParameterBindings should normally look similar to this. I just completely remove the ListId line as it’s not needed in MY xslt

<ParameterBindings>
<ParameterBinding Name=”dvt_apos” Location=”Postback;Connection”/>
<ParameterBinding Name=”ManualRefresh” Location=”WPProperty[ManualRefresh]“/>
<ParameterBinding Name=”UserID” Location=”CAMLVariable” DefaultValue=”CurrentUserName”/>
<ParameterBinding Name=”Today” Location=”CAMLVariable” DefaultValue=”CurrentDate”/>
<ParameterBinding Name=”ListItemId” Location=”QueryString(ID)” DefaultValue=”0″/>
    <ParameterBinding Name=”ListID” Location=”None” DefaultValue=”{62F19BE4-6465-4293-B580-36C49EC8F35B}”/>
<ParameterBinding Name=”MaximumRows” Location=”None” DefaultValue=”10″/>
</ParameterBindings>

Step 4 – XSL Style Sheet Params

In the very top of the XSL:StyleSheet you see a list of xsl:params. I just remove the ListID param as I’m not normally using it in my XSL.

<xsl:stylesheet …………[cut for brevity] ……………………>
<xsl:output method=”html” indent=”no”/>
<xsl:decimal-format NaN=””/>
<xsl:param name=”dvt_apos”>&apos;</xsl:param>
<xsl:param name=”ManualRefresh”/>
<xsl:param name=”ListItemId”>0</xsl:param>
<xsl:param name=”ListID”>{62F19BE4-6465-4293-B580-36C49EC8F35B}</xsl:param>
            <xsl:param name=”MaximumRows”>10</xsl:param>
<xsl:param name=”FavoriteLink” />
<xsl:variable name=”dvt_1_automode”>0</xsl:variable>

Finished…

Each step of the way you can save and test. When you are finished you should be GUID free.

Conclusion

This may not be a silver bullet for all scenarios of using the DVWP or some of the list form web part through designer. This is what I’ve found to work for me time after time. There may be cases when you need the ListID in the XSLT and you’d want to keep it there and replace the ListID with ListName there.

If you find this not to work please contact me and we’ll sort it out and keep this post current.

Deploying Composed Look – The Declarative Method – Part 2

Back in December I posted a lengthy article on how to deploy a Composed Look for SharePoint 2013. If you haven’t read that it can be found here – http://tommdaly.wordpress.com/2012/12/19/deploying-a-custom-composed-look-in-sharepoint-2013/. In that article I described the two methods declarative and imperative. Given all the recent buzz around the deprecated sandbox solutions many of our clients are very anti code for their sandbox and online farms/tenants. I’ll keep this post short and sweet but this expands upon the declarative method.

Going back to my old post, I provided this excerpt of the elements.xml I used to provision the Composed Look to the Composed Looks list. You might wonder how did I get this, well I made a .wsp via Design Manager, renamed it to .cab, and extracted the files. In there I found the elements.xml that was used to deploy the composed look. Using this I was unhappy because if you look closely below you’ll see some URLs in there. I’m not a fan of using URLs or hard coding ANYTHING. If you’ve been working with SharePoint a long time then you know that this is not always possible in their xml with data views, and provisioning. (yes there are hacks & work arounds but lets not go there)

 

So here is my new snippet of XML for the elements.xml file which is used to create the new list item. I’ve removed the URLs completed and replaced them with ~sitecollection. Alternatively you could use ~site if you just wanted the web URLs to be replaced. No matter what site you upload this to the master page, image, theme, fonts will be connected up properly and no more messy URLs. A few other fields have been cleaned up:

  • Removed HyperlinkBarUrl from <ListInstance>
  • Removed Description from <ListInstance>
  • Display Order Field simplified
  • Removed FileLeafRef Field
  • Removed ID Field – It will generate the next available, if you set this to 100 then then next available ID becomes 101 when adding another via the UI.

image

download this as file

 

I’ve found that deploying this twice it will NOT overwrite itself. So if you make a change you’ll have to delete the Composed Look via the UI and then redeploy. I don’t see any parameters which allow list rows to be overwritten http://msdn.microsoft.com/en-us/library/ms478860.aspx so this may be a limitation. It would be amazing to be able to overwrite itself for any changes.

Free Floating Quick Launch Navigation for SharePoint 2010 using jQuery

Recently I was asked to make a free floating navigation element, so that when you scroll down the page it would follow. There are many adaptations of this but for standard html websites, but I was unable to find a SharePoint specific one. Until writing this post I just recently noticed an alternate but similar approach here http://blog.muhimbi.com/2009/08/how-to-float-sharepoint-quick-launch.html

Instructions

Download the code snippet from here : http://www.bandrsolutions.com/TomBlogFiles/stickyQL.js

Add the script references to the files in the Master Page, or CEWP.

2013-08-18_1932

Once you add that to your pages it’s activated. This is tested to work on standard V4.master.

 

Notes

If you’re quick launch is larger than the view then it will constantly be scrolling down, and you’ll never see the bottom of the quick launch .

Your quick launch must be smaller than the actual view.

I’m using jQuery from the Google hosted API libraries – https://developers.google.com/speed/libraries/devguide#jquery

Here is a look at the actual script

2013-08-18_1934

 

Demo

My Sticky Footer Solution for SharePoint 2013–Pure JavaScript Solution

Last year I posted a blog article which described the issue with SharePoint 2010 and having a footer. Well similarly SharePoint 2013 has some of the same obstacles when adding a footer. If you are interested in reading more detail into the issue w/ 2010 then go here: My SharePoint 2010 Sticky Footer Solution.

It basically boils down to these 2 issues:

  1. If you just add a footer to your master page it will be displayed directly under the page content. On a page that has little content then the footer may show half way up the page.
  2. Alternatively if you try a pure CSS sticky footer solution it may not work correctly either because SharePoint uses the page height to calculate where the scroll bars will go (mainly due to the header / ribbon always being at the top).

[Update 10/9/2013] – Added code from Robert, to handle MDS type pages.

[Update 9/1/2013] – I noticed that these scripts do not work on Team Sites, this is due to the Minimal Download Strategy Feature that is enabled. Turn that off and this work perfectly fine. I’m still researching how to make the scripts how with that feature enabled.

I’ve also updated the code to use it’s own function to detect height. Padding (top/bottom) can sometimes throw off the size computations.

Link the script file

As you can see below I’ve hosted my file in the Style Library

<!-- Custom JS -->
<SharePoint:ScriptLink runat="server"
 Name="~SiteCollection/Style Library/js/stickyFooter.js" 
 Localizable="False"  LoadAfterUI="True"/>

The Footer Control

Simply add this div after s4-bodyContainer in the master page file.

<div class="s4-notdlg noindex" id="Footer">
&copy; My Footer Solution 2013
</div>

As you can see below an export of the DOM from the IE Dev Toolbar.

footer

Here below you can see where in the Master Page (based on seattle.master) I look for the id=”DeltaPlaceHolderUtilityContent” and you’ll see 3 </div> above it. I put it right between the 2nd & 3rd </div>

mp_footer

The Script File

Download stickyFooter2013.js Here

This script is a pure JavaScript solution which will work with a default master page. If you customize it then you’ll need to account for any differences. It basically adds the suite bar + ribbon + body + footer, and if that’s smaller than the viewport aka viewable area. It will expand the body by the difference so that they are equal.

This also operates in it’s own namespace so there won’t be any collisions

I also bind to the window resize event so if the size of the screen changes the ribbon should stay on the bottom.

sf

Enjoy!

SharePoint 2013 Theme Builder Tool

SharePoint 2013 Theme Builder Tool

I just wanted to post this here in case anyone stumble across it… There is a tool released by Microsoft to assist with building SharePoint 2013 Themes more specifically the theme color palettes. This will help a lot when working with the .spcolor files and building custom Composed Looks.