Wednesday, June 17, 2015

Simple 'Sticky' Plugin compatible with SharePoint 2010 + SharePoint 2013

Sticky elements. Not only do they make me hungry when I hear about them, but they are also very nice for keeping the user aware of their current context, keeping some key UI elements like toolbars in close reach, and I am sure lots of other things.


Here is a very tiny jQuery plugin that I developed for making elements sticky. There are many others out there - some that do more - but none I could find that were 100% compatible with the default SharePoint master pages. If you have done any work with the scrollable areas within the default SharePoint HTML, you know what I am talking about. The way the ribbon and the 'workspace' areas work are a little funky. This plugin gives you the power of sticky within this context - and should also work fine for any situation where you want something to be sticky within a scrollable DIV element.


Usage:
  1. Include script in page.
  2. $("<selector>").floater();


Options:
  • startOffset  When the 'stickiness' should be invoked.
  • offsetY  When stuck, how close to the parent element should element be.
  • stickyClass Css class added to element when stuck. Removed when un-stuck.
  • onStart Event to invoke when sticky happens.
  • onStop Event to invoke when un-sticky happens.

Tuesday, April 29, 2014

Custom Content Type Deployment Tip for Visual Studio 2010

Scenario: You add a custom content type to your Visual Studio 2010 project. Because you have been bitten by the lowercase Content Type ID problem before (see here: https://connect.microsoft.com/VisualStudio/feedback/details/709500/visual-studio-2010-sharepoint-project-template-content-type-generated-through-visual-studio-has-id-guid-in-lower-case-causing-custom-actions-to-fail ), you quickly turn the Content Type ID to UPPERCASE using the handing Ctrl+Shift+U shortcut. You are pretty much a shortcut badass. Visual Studio 2010 generates Content Type ID’s lowercase by default.

Visual Studio gives you:
<ContentType ID="0x010059b2dab8444144e68f7f9baaa134dbf0" …
..so then you upper-case it to:
<ContentType ID="0X010059B2DAB8444144E68F7F9BAAA134DBF0" …
…to ‘avoid’ problems.



Problem: When you try to deploy your solution, you get a ‘Value is out of range’ error. No logged info beyond that. Helpful as always.

Solution: See the ‘X’ near the beginning of the Content Type ID? It MUST be lowercase. When upper-casing it, you may accidentally uppercase that character too. This totally explodes whatever parsing is done on that ID when it is read from the schema file.

And then you fix it:
<ContentType ID="0x010059B2DAB8444144E68F7F9BAAA134DBF0" …
 
Wednesday, April 16, 2014

SharePoint 2013 Chrome Control Parameters List

I had a hard time Google-Binging this information – so here is what I dug directly out of the source:

Param Name Description
siteTitle The title of the site.
siteUrl The url of the site. [This is easy!]
clientTag ? Tag the page ?
appWebUrl The current app web url.
onCssLoaded Callback function for when chrome control is done loading. [Great naming there!]
assetId ? The app’s id in the catalog ?
appStartPage Start page of app web. Need to test this…
rightToLeft For those languages that go against the grain.
appTitle Title of the app. [Back to easy street!]
appIconUrl The url of the app icon.
appTitleIconUrl Titles need icons too.
appHelpPageUrl The url of your very useful help page.
appHelpPageOnClick Use this to alert(‘No help 4 U!’)
settingsLinks Array of links to put under the ‘options’ wheel.
language ¿QuĂ© diablos?
bottomHeaderVisible Hide the bottom header.
topHeaderVisible Guessing this may hide the top header. Since chrome control does so much to everything in addition to the top header [sarcasm], I can see never using this option.

Tuesday, December 17, 2013

SharePoint s4-notnotdlg: The opposite of s4-notdlg

[Until I do, this is a warning about this only being tested in 2010]
So there is a CSS class in SharePoint that allows you to have content that will NOT show up in any dialog: The s4-notdlg class. Pretty easy: just add the class to your fancy branding, elements, etc. and it will be excluded when element is displayed in a SharePoint dialog.

 

But what about the opposite: Is there a class that lets you have content that will ONLY display in a dialog? No, there is not. But through the magic of CSS selectors, you can accomplish this behavior pretty easily:

Tuesday, November 12, 2013

Use SharePoint Modal Dialog to Prompt for Text

You need to prompt the user for some text from somewhere within a SharePoint site. How to you go about this?
  1. Use the JavaScript 'window.prompt' method? Too ugly and limited style and validation options.
  2. Incorporate a jQuery plugin that makes for easy prompting? May or may not work with SharePoint, and even then it will most likely have a UI style that is different.
  3. Use the SharePoint dialog API to show a modal page? Close - but that means we have to create and deploy an entire ASPX or HTM page to show within the dialog. That is a lot for what boils down to a label and a text box.
  4. Embed the script below and move on to checking on your Klout status.

Yeah, I like #4 too - except for the Klout part.


What this script does:
  • Shows a SharePoint modal dialog and injects content and style, so it looks like the rest of your UI.
  • Does not require you to build another page for the dialog UI.
  • Returns the text the user entered.
  • Validates that the user typed in something by default. You can optionally provide a maximum length or a custom validation function to use.
  • Requires jQuery. Probably could be written to be dependency-free, but that would be many more lines of code - especially the CSS cloning part.

Tuesday, September 10, 2013

Using DispEx in a Link to a SharePoint Document

I needed to create a link to a document the same way SharePoint does it: using the DispEx client side function. The DispEx function performs all of the magic involved with opening an Office document directly in the appropriate Office app in a nice way, as long as you are using Internet Explorer of course. I believe it also uses ActiveX to do this, but that will be for another ran.. I mean blog post.

Searching for how to create such a link proved worthless. There are a few posts and Q&A’s on Stack Overflow out there, even at least one from one of those soon-to-be-extinct MVP’s – but they all hard coded most of the parameters for the function. It is true that the function has a plethora of parameters, but having them hard coded is not desirable – especially when the parameters are based on user-configurable settings, such as the ‘Force Checkout’ option in a document library.
 
Below is some code to create the ‘click’ script for the anchor element, gleaned via ILSpy and modified to accept an SPFile parameter. The DispEx  function (and dependencies) also require that the anchor element have an HREF attribute set to the server-relative URL of the file. In the case of an SPFile instance, this would be FIle.ServerRelativeURL.
        private string GetFileViewScript(SPFile file)
{
string text = SPUtility.MapToControl(SPContext.Current.Web, file.Name, string.Empty);
string text2 = (file.Item.ParentList.DefaultItemOpen == DefaultItemOpen.Browser) ? "1" : "0";
SPFieldLookupValue sPFieldLookupValue = file.Item["CheckedOutUserId"] as SPFieldLookupValue;
string scriptLiteralToEncode = (sPFieldLookupValue == null) ? string.Empty : sPFieldLookupValue.LookupValue;
string text3 = (SPContext.Current.Web.CurrentUser != null) ? SPContext.Current.Web.CurrentUser.ID.ToString(CultureInfo.InvariantCulture) : string.Empty;
string text4 = file.Item.ParentList.ForceCheckout ? "1" : "0";

return string.Format(CultureInfo.InvariantCulture, "return DispEx(this,event,'{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}')", new object[]
{
"TRUE",
"FALSE",
"FALSE",
text,
text2,
text,
string.Empty,
string.Empty,
SPHttpUtility.EcmaScriptStringLiteralEncode(scriptLiteralToEncode),
text3,
text4,
(string)file.Item["IsCheckedoutToLocal"],
(string)file.Item["PermMask"]
});
}

Friday, September 6, 2013

SendEmail from CurrentUser Caution in SharePoint 2010

This is a quick one I ran across, and yes: it was really annoying:

The SPUtility’s SendEmail method has several overloads. Check it out if you want to: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.utilities.sputility.sendemail(v=office.14).aspx

The most flexible overloads accept a StringDictionary. The dictionary allows us to specify any email headers we want to, most notably the ‘to’, ‘subject’, ‘cc’, and ‘from’ headers.

In the SendEmail overloads that are not taking a StringDictionary, notice there is no ‘from’ parameter. This is because the current Web Application’s outbound email address is automatically used as the ‘from’ address when using those methods.

When using on of the StringDictionary overloads, one would think leaving out the ‘from’ header would result in the same thing: the current Web Application’s outbound email address is used. This is NOT THE CASE.

What happens is that if the ‘from’ header is not in the StringDictionary or if it is null, the current user’s email address will be used as the FROM address in the email. If your email server has any type of security hardening this will result in the email being rejected since the app pool probably does not have the necessary rights to send an email on any old user’s behalf.

How to fix? Couldn’t be easier:

            ...
//email sendin code
StringDictionary headers = new StringDictionary();
headers.Add("to", toAddress);
if (!string.IsNullOrEmpty(fromAddress))
{
headers.Add("from", fromAddress);
}
else
{
headers.Add("from", GetFromEmailAddress(web));
}
headers.Add("subject", subject);
headers.Add("content-type", "text/html");

SPUtility.SendEmail(web, headers, body);
...

//get the FROM email address configured for the web app
internal static string GetFromEmailAddress(SPWeb web)
{
return web.Site.WebApplication.OutboundMailSenderAddress;
}

 
© I caught you a delicious bass.
Back to top