Posts Tagged ‘SharePoint Designer

21
Dec
09

Going to Review a FREE Book from Packt Publishing: SharePoint Designer Tutorial

SharePoint Designer Tutorial: Working with SharePoint Websites

Over the weekend, I received a free copy of the book SharePoint Designer Tutorial: Working with SharePoint Websites by Mike Poole.  They have asked me to review it here on my blog, and I never turn down a free book.

Is that enough for the FTC? Check out the article FTC: Bloggers who shill must also tell to read more about the new FTC rules around so-called “blogola”.  I can guarantee you that I am no shill, but who wants to run afoul of the gummint?

One unfortunate thing I noted right off the bat (I thought maybe they had sent me the wrong book) is that, on the copy I received, the text is set up like this on the cover and similarly on the spine:

scan0002

Maybe it’s me, but if I were to glance at this on a bookshelf, I wouldn’t think it was about “SharePoint Designer”, but instead was about SharePoint and *for* designers (meaning graphic designers, layout artists, etc.)

If anyone out there has read this book and has input on it, leave me a comment, and watch for a review later in this space.

27
Nov
09

Interesting New Uses for SPDisplayRelatedInfo

I had a question on my recent article over at EndUserSharePoint.com entitled A jQuery Library for SharePoint Web Services (WSS 3.0 and MOSS): Real World Example – Part 1.  The question was about the SPDisplayRelatedInfo function, and while I was setting things up to see if I had a bug, I found that there were some interesting ways you could use the SPDisplayRelatedInfo function that I hadn’t considered.

I added a Single line of text column to my old standby Sales Opportunities list and called it StateID.  In my EditFormCustom.aspx, I added this call to SPDisplayRelatedInfo:

$().SPServices.SPDisplayRelatedInfo({   
    columnName: "StateID",
    relatedList: "States",
    relatedListColumn: "ID",
    relatedColumns: ["ID", "Title"],
    displayFormat: "table"
});

The States list is one of the lists I use in testing SPCascadeDropdowns, and it has these columns: State (the original Title column) and State Abbreviation. Now, when I typed digits into the StateID column, I got real-time results from the SPDisplayRelatedInfo function as the digits matched the ID of the State item. Cool!

So if I started out with the column empty, I saw:

image

then when I typed 1:

image

then when I typed 2:

image

This also worked if the StateID column was a Number column.  Looking through the code, there was no reason this shouldn’t work, it’s just not the use I had intended.

So then I thought, well what if I wanted to match as I type the State?  I switched the function call to this:

$().SPServices.SPDisplayRelatedInfo({   
    columnName: "StateID",
    relatedList: "States",
    relatedListColumn: "Title",
    relatedColumns: ["ID", "Title", "State_x0020_Abbreviation"],
    displayFormat: "table"
});

Then when I typed Massachusetts, I saw:

image

Hmm, that can’t be right.  I went and checked the States list, and sure enough, I had some junk test data in there that I had forgotten about.  Even cooler!  The SPDisplayRelatedInfo function essentially acts like an as-you-type reference lookup!

These examples aren’t exactly what you’d be doing in the real world, but think about the situation where you had a product code that could be 1-5 digits or numbers or something where you wanted to let the user type instead of dealing with a dropdown. If you come up with another interesting use, let me know about it.

It’s always nice to find out that code you’ve written is *more* useful than you thought (as opposed to the dreaded less useful situation).

24
Nov
09

jQuery Library for SharePoint Web Services v0.4.6 Released

Today I released v0.4.6 of my jQuery Library for SharePoint Web Services.  This version was fun to work on because I’ve got quite a few people out there in the world (California, North Carolina, Sweden) using the library actively, so we were able to work together pretty much real time to get enhancements and bug fixes into the library together.  This was also the first release where I decided to keep a current alpha version posted on Codeplex while I was doing the work.  This was rewarding because there was a real feedback loop going on.  I think this is a better way to go in the future, so watch for more alpha versions you can kick the tires on for me (actually for all of us).

This release has two really nice enhancements:

  • SPCascadeDropdowns now works with multi-select child columns. This was the most requested enhancements over the last few months, and to be honest I dragged my feet on it.  The controls that SharePoint uses for multi-select choices are just plain complicated.  There’s also a whole pile of JavaScript which sites behind it all (groupeditempicker.js) that took some time to dig through.  The good news is that I was able to take advantage of those “native” JavaScript functions and write less of my own code.

Multi-Select Example

  • Both SPCascadeDropdowns and SPDisplayRelatedInfo now have a new CAMLQuery option which allows you to specify additional filters on the relationshipList.  You specify this as an additional CAML fragment which is then <And>ed with the filters which the library uses to grab the allowable values.  For example, the CAMLQuery option can contain a CAML fragment like:
CAMLQuery: "<Gt><FieldRef Name='ID'/><Value Type='Counter'>1</Value></Gt>"

or

CAMLQuery: "<Eq><FieldRef Name='Status'/><Value Type='Text'>Active</Value></Eq>"

Additionally, the $().SPServices.SPCascadeDropdowns and $().SPServices.SPSPDisplayRelatedInfo functions are now *much* more efficient.  As part of the refactoring I did in v0.4.5, there were some unnecessary Web Services calls happening.  With this efficiency change, there are no unneeded calls, so the dropdowns ought to behave almost as fast as they would without the functions sitting behind them.Of course there are some bug fixes as well.

Release Notes

New Functionality

Issue Tracker Item Function Operation Description
NA $().SPServices.SPCascadeDropdowns NA SPCascadeDropdowns now works with multi-select child columns.
NA $().SPServices.SPCascadeDropdowns and $().SPServices.SPSPDisplayRelatedInfo NA Added a new option on SPCascadeDropdowns and SPDisplayRelatedInfo for an additional filter, specified as a CAML fragment which is inserted into the existing filter. See the documentation for details.

 New Operations

Web Service Operation Options MSDN Documentation
Lists UpdateList listName, listProperties, newFields, updateFields, deleteFields, listVersion Lists.UpdateList Method

 Bug Fixes and Efficiency

Issue Tracker Item Function Operation Description
NA $().SPServices.SPCascadeDropdowns and $().SPServices.SPSPDisplayRelatedInfo NA Added an additional check for column value changes within the cascadeDropdown and showRelated private functions to reduce unnecessary Web Service calls. This change makes both functions considerably more efficient and therefore faster.
NA $().SPServices.SPCascadeDropdowns NA Fixed an issue in SPCascadeDropdowns when a child column is a Lookup to a Lookup column, and therefore displayed option values in the format ‘ID;#Value’, e.g., 1;#Massachusetts.
NA All list-based functions NA Tighter code to find z:row elements in XML using the selector: find(“[nodeName=z:row]“) based on a nice trick from Kevin Whinnery.
NA $().SPServices.SPCascadeDropdowns NA Fixed an issue in SPCascadeDropdowns when a parentColumn has multiple childColumns which caused only the first childColumn to be filtered.
NA listNameFromUrl() private function NA More reliable listNameFromUrl() using GetListCollection. The prior version was failing if the list had been renamed.
NA $().SPServices. SPRequireUnique NA Fixed a bug in SPRequireUnique where both values for duplicateAction (0 = warn, 1 = prevent) were acting like prevent. Also made the <span> which contains the messages unique per column in case the function is used more than once on the form.
22
Oct
09

Finding Date/Time Columns on the Page with g_strDateTimeControlIDs

I ran across an interesting little trick in some code I’m working on today.  As usual, not my code, someone else’s that I’m trying to decipher and fix.

One thing that they are doing is sort of slick.  There’s apparently an array created by the datepicker.js JavaScript called g_strDateTimeControlID which is populated with the IDs for all of the date input fields on the page which utilize the Date Picker. (I did some Binging, and there are only 4 references to g_strDateTimeControlID that I found.)  The little calendar icon below is the Date Picker:

DatePicker

You can use the g_strDateTimeControlIDs array like this:

var eventDateID = g_strDateTimeControlIDs["SPEventDate"];
document.getElementById(eventDateID).value = date;

Note the ‘SP’ ahead of the column name.

That’s certainly simpler than writing your own JavaScript/jQuery to find the control, and makes it easy to set the date value, whether it be from a Query String value or some calculation.  Because the array is constructed and used by the Date Picker, so it should be available on the page where ever the Date Picker is seen.

20
Oct
09

Passing a Source Parameter on the Query String with Multiple Other Parameters

I’ve posted on similar tricks to this in the past, but this little trick is really helpful and worth calling out on its own.  Say that you’d like to pass a Source parameter on the query String, as SharePoint often does for you:

http://servername/sites/sitename/Lists/MyList/EditForm.aspx?ID=275&Source=http://servername/sites/sitename/default.aspx

Simple, and you see it all the time as you navigate around in SharePoint. In many cases, you’d also like to pass additional parameters that will “travel along” with the Source parameter.  The trick for this is to simply encode the ampersand (&) character so that it won’t be treated as the start of a new Query String parameter, but instead just a part of the Source parameter. The ASCII value for the ampersand is 26 in hex, so you encode it as %26 in the URL:

http://servername/sites/sitename/Lists/MyList/EditForm.aspx?ID=275&Source=/sites/sitename/default.aspx?ProjectID=123%26Boolean=0%26EmployeeID=345

Note that I’m passing in the relative URL for the default.aspx page.  Get into the habit of using relative URLs all the time and you’ll be in much better shape in general.

With the above URL, when you are finished with the EditForm.aspx page, whether by clicking OK or Cancel, you’ll be redirected to:

http://servername/sites/sitename/default.aspx?ProjectID=123&Boolean=0&EmployeeID=345

19
Oct
09

jQuery Library for SharePoint Web Services v0.4.0 Released

This release contains two functions I’ve wanted to get into the library for a long time: $().SPServices.SPRedirectWithID and $().SPServices.SPRequireUnique.  These two functions show how you can solve tricky problems with jQuery and the SharePoint Web Services much better than any of the other approaches available, IMHO.

$().SPServices.SPRequireUnique allows you to specify a page to redirect to after creating a new list item with a NewForm.aspx (or your customization of it).  The two posts discussing this topic on my blog are together the #1 most read by a long shot. (You can read these two old posts: Redirect to Another Page from NewForm.aspx with the New Item’s ID: Redux and Redirect to Another Page from NewForm.aspx with the New Item’s ID to see where my thinking used to be.)

$().SPServices.SPRequireUnique lets you require unique values in a Single line of text column.  Generally you would use this on the Title column so that you can use a reference list relationally, such as the lists I use in the examples for $().SPServices.SPCascadeDropdowns to contain the States and Regions.

The release is rounded out with a couple of new Lists Web Service operations (CheckInFile and CheckOutFile) and exposing a couple of the nifty “utility” functions ($().SPServices.SPGetLastItemId and $().SPServices.SPSPGetDisplayFromStatic) I wrote in the process of building the first two functions above.

You can download jQuery Library for SharePoint Web Services from Codeplex.

Release Notes

New Functions

Function Description
$().SPServices.SPRedirectWithID This function allows you to redirect to a another page from a new item form with the new item’s ID. This allows chaining of forms from item creation onward.
$().SPServices.SPRequireUnique Checks to see if the value for a column on the form is unique in the list.
$().SPServices.SPGetLastItemId Function to return the ID of the last item created on a list by a specific user. Useful for maintaining parent/child relationships.
$().SPServices.SPSPGetDisplayFromStatic This function returns the DisplayName for a column based on the StaticName.

New Operations

Web Service Operation Options MSDN Documentation
Lists CheckInFile pageUrl, comment, CheckinType Lists.CheckInFile Method
  CheckOutFile pageUrl, checkoutToLocal, lastmodified Lists.CheckOutFile Method

 

15
Oct
09

SharePoint Form Radio Buttons: Switch from Vertical to Horizontal with jQuery

I’ve seen a few threads over on the MSDN SharePoint – Design and Customization about doing this, but never felt the need to make it happen myself.  My answer has always been “jQuery would be the way to go with this”.  Well, I was building a custom form the other day, and those pesky vertical radio buttons got to bugging me, too, so I decided to fix ‘em with jQuery.

The form in question is a multi-item edit form, with one row per item, which lets the user set the column values and then check in each item using SharePoint’s Lists Web Services.   And, yes, I’m using my jQuery Library for SharePoint Web Services for this! (The released version doesn’t have the CheckInFile operation in it; what better way to test adding it in than to really use it?  Next release, it’ll be there.)

Each row contains these column types: Name, Lookup, Lookup, and finally, the radio buttons.  Because I’ve customized the form, it’s easy for me to add an id to the table cell which will contain the radio buttons when the page is rendered: 

<td id="AuditRequired{$Pos}">
    <SharePoint:FormField runat="server" id="ff4{$Pos}" ControlMode="Edit" FieldName="Audit_x0020_Required" ItemId="<a href="mailto:{@ID">{@ID</a>}" __designer:bind="{ddwrt:DataBind('u',concat('ff4',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@Audit_x0020_Required')}"/>
    <!--<SharePoint:FieldDescription runat="server" id="ff4description{$Pos}" FieldName="Audit_x0020_Required" ControlMode="Edit"/>-->
   </td>

 The reason for adding the id to the table cell is that, surprisingly, SharePoint doesn’t give you anything good to select on for the radio button group.  If you haven’t customized the form, then your initial selector would need to be more complicated. Note that I’m being a good doobie and making each id unique by appending the $Pos variable (this is an indicator for the row number which SharePoint generates, and takes the form ‘_1′, ‘_2′, etc.).  Making the ids unique is good practice for cross-browser compatibility.

With the id in place, my jQuery looks like this:

$().find("[id^='AuditRequired']").each(function() {
  var radios = "";
  $(this).find("tr").each(function() {
    radios += $(this).html();
  });
  $(this).find("tr:first").html(radios).nextAll().remove();
});

Let’s break that down a little:

  • Line 01: Finds all of the table cells with the id starting with (that’s the ^= bit) ‘AuditRequired’, and then does an each loop for them
  • Line 03: Finds each table row in $(this), which references the table cell found in Line 01
  • Line 04: Appends the contents of that table row (the table cell containing the radio button) to the radios variable.
  • Line 06: Finds the first table row, sets the html for that row to the radios variable containing all of the cells with radio buttons, then finds all of the other rows and removes them.

The net effect of this is to convert the view of the radio buttons from the default vertical arrangement to a horizontal arrangement, which tightens up my form nicely. Simple!

14
Oct
09

Source Redirect After Uploading Multiple Documents

There are times where you want to control how the page flow works during and after the document upload process.  The simplest path that this takes is:

  • from a view in the Document Library, clicking on the Upload button
  • which takes you to _layouts/Upload.aspx where you specify the document you want to upload
  • then to the EditForm.aspx to enter the metadata for the document
  • then back to the Document Library view you started on

The way SharePoint “knows” which page to return you to is the Source Query String Parameter.  In the case above, the Source will be the Document Library view you started from, perhaps something like this (note that certain characters are encoded):

Source=http%3A%2F%2Fservername%sitename%libname%2FForms%2FAllItems%2Easpx

You might want to place links elsewhere in your site which takes the user to the document upload page without having to visit the Document Library itself or expose the toolbar on a List View Web Part. To do this, you can simply place a link like this anywhere you want it (carriage returns added for easier reading):

http://servername/sitename/_layouts/Upload.aspx
?List=%7B44C0ABF5%2D0F8E%2D419E%2DAF50%2D952AEDA989FE%7D
&Source=http%3A%2F%2Fservername%2Fsitename%2Fdefault.aspx

If you want to take the user directly to the multiple documents upload page, all you need to do is add this parameter to the Query String: MultipleUpload=1, like this:

http://servername/sitename/_layouts/Upload.aspx
?List=%7B44C0ABF5%2D0F8E%2D419E%2DAF50%2D952AEDA989FE%7D
&Source=http%3A%2F%2Fservername%2Fsitename%2Fdefault.aspx
&MultipleUpload=1

There’s one bugaboo in this: the Source needs to be an absolute URL, not a relative one. If you specify a relative URL, you will be taken to the right page, but the multiple document upload page won’t function. When you click on the OK button, nothing will happen.

So this:

&Source=http%3A%2F%2Fservername%2Fsitename%2Fdefault.aspx

is good, and this:

&Source=%2Fsitename%2Fdefault.aspx

is bad.

As I’ve posted before, you can pass additional parameters with the Source by including them in the URL like this:

http://servername/sitename/_layouts/Upload.aspx
?List=%7B44C0ABF5%2D0F8E%2D419E%2DAF50%2D952AEDA989FE%7D
&MultipleUpload=1
&Source=http%3A%2F%2Fservername%2Fsitename%2Fdefault.aspx?ProjectID=200&SubProject=345

Note that to do this, you need to have your Source Query String parameter in the last position in the URL.  This is required due to the ? you need to pass the additional parameters on the Source redirect URL.

12
Oct
09

SharePoint Forms Reality Check

As is often the case recently, inspiration for this post came from a thread over at the MSDN SharePoint – Design and Customization forum.  In this particular thread, I suggested using the PreSaveAction (see my post entitled Validation on SharePoint Forms – Part Four for details on how this works) and some script to do some validation on a form.  The reason in this case was that the form was very long (due to a large number of columns) and users weren’t seeing the error messages higher up on the page when they clicked "OK".

Hmmm… that should work, but it means I need to add this javascript to every list I make and change the content of the script based on which fields need to be validated. Unless there is some neat little way for Javascript to figure out which of the fields require content? I can’t imagine so.
From a usability point of view Sharepoint is implementing a pretty bad default way of validating forms here. Well, just gotta work my way around it.
Thanks for the help.

I think you always need to put SharePoint through the 80/20 mental test.  The way the out of the box forms work is absolutely fine for [at least] 80% of the use cases.  IMHO, Microsoft is interested in selling seats to the development community and keeping that ecosystem up and running in a healthy way.  That’s where the other 20% comes in.  The other thing to consider is that these default forms are pretty amazing in that they just work, and they work regardless what types of columns you throw at them.

09
Oct
09

SharePoint Lookup Column Based on a Calculated Column Woes

I’ve been working on trying to improve the performance of some DVWPs I wrote about a year ago as part of an application that I inherrited from others. (Was that tactful enough?) One of the things that I’ve been trying to do is to filter on the LookupId of a Lookup column, but I couldn’t for the life of me get it to work. I’ve done this dozens of times, but in this case I was getting nowhere.

I finally figured it out. The Lookup column is based on a Calculated column, which is itself built out of two strings which are concatenated. Here’s a simple example.  If the reference list looks like this:

ID ColumnA ColumnB CalcColumn
1 Blue Cow Blue – Cow
2 Red Sheep Red – Sheep

where CalcColumn is calculated as =[ColumnA]&” – “&[ColumnB], and you create a Lookup column in another list which uses CalcColumn for its values, you’ll see this in the values:

string;#Blue – Cow
string;#Red – Sheep

where you would expect:

1;#Blue – Cow
2;#Red – Sheep

Therefore, you can’t get at the LookupId of the Lookup column because it isn’t available.  (See my post on Using the ID Value for a Lookup Column for how this *ought* to work.)

Moral of the story: Don’t use a calculated column for your Lookup column source.  Now on to some list rebuilding…




 

January 2010
M T W T F S S
« Dec    
 123
45678910
11121314151617
18192021222324
25262728293031

Twitter Updates