SharePoint brings more power than ever to the end user. As usual, this is a double-edged sword. Its utility as a development platform is unmatched, but since many of the development tools are accessible from the browser UI, the dividing lines can get blurred.
Requirements-gathering (and subsequent documentation) can be tricky, and it's easy for us technical types to get confused about functional versus technical. Business users do not care about technical requirements and they should not have the opportunity to dictate them. If you have to explain a term (for example, "list" or "metadata column") to an end user, then most likely it does not belong under the heading of "functional requirements".
Functional requirements are about what the end user needs to accomplish. An excellent guide for this is the concept of the User Story, as employed in Agile
project management (we're kind of big on that here at Improving). The basic format is as follows:
As a _______ (what type of user),
I want _________
so that I can ___________
This
kind of requirement requires (heh) that you also define acceptance
criteria, by which you can determine that the
requirement has been fulfilled. The end result is that nobody can claim confusion about what you're trying to do, since the team has already agreed on the definition of "done".
Here at Improving Enterprises, we have a relatively new annual tradition of forming a moustache team for Movember. For those who are new to the concept, Movember is a month-long fundraising effort for men's cancer research. Each year, men (Mo Bros) from around the world join in sprouting a symbol of solidarity -- with the goal of eradicating men's cancers.
If you're able, please consider donating to this vital effort. You can read up on where the money goes and how it is spent, you can learn about the history of Movember, and of course you can see goofy pictures of me with incomplete facial hair (if you're into that sort of thing).
Thank you for your time, your money, or merely your attention. To show my gratitude, here's what the genetic recombination of Burt Reynolds and Derek Zoolander would look like if he had some sort of mental problem.
Typical SharePoint 2010 install. I had created all my domain users, set up my servers, and started installing the prerequisites. When the first box in the farm restarted and the preparation utility came up, I was asked for credentials and provided them, only to be rejected. At first I thought it was a standard "access denied" error, but a look at the fine print revealed the error titling this post.
I tried Run As Administrator; still no success.
Eventually I realized that I was signed in as the farm account, though I had not yet made it a local administrator. I right-clicked Computer Management, ran THAT with the proper credentials, made the farm account local admin, and all was right with the world.
Sometimes it's the little things.
Custom list. Custom New/Edit/View forms. Everything works perfectly... until the latest round of updates.
Now if you Bingle this error message, you'll get about twenty possible causes that run the gamut from a known bug, an unknown bug, and fixed/not fixed/hotfixed/workaround bug, all the way to corrupt content types and invalid form data.
In my case, however, it turned out to be a misspelled column name in a FormField control.
I'm just glad it's Friday.
Occasionally, you have a calendar full of all-day events and you don't want the calendar cluttered up with redundant timestamps. Here's a simple client-side script, suitable for framing (or a master page, or a content editor web part) that will cut down on the visual noise.
<script language="JavaScript">
var allDates = document.getElementsByTagName("nobr");
for(var i=0;i 0) {
allDates[i].innerHTML = allDates[i].innerHTML.replace("12:00 AM","");
}
}
</script>
This is a fairly common request, but the solution is often missing one crucial point. To use a custom New/Edit/Display form on your list, proceed as follows:
- Open your site in SharePoint Designer.
- Right-click the desired List (under the Lists node) and select Properties.
- Click the Supporting Files tab.
- Under Content type specific forms, select the Item content type (this is the part most people forget). If you are using a custom content type, select that; just make sure that the Folder type is NOT selected.
- Use the Browse button to select your custom forms in each category.
- Click OK.
This post is long overdue, but since the question keeps popping up on various SharePoint discussion lists, I figured I'd document the answer here (next time I can just post a link instead of typing the whole thing out again).
In a SPD workflow, you cannot trigger a SharePoint workflow when a column changes; you can only use the ItemChanged event. To get more granular, then, you need to add some extra bits.
Let's say you have a list called "5K Races" with a column called StartTime, and you want to execute some actions when the StartTime value changes. Simply perform the following steps:
1) Create an additional column (same datatype) called OldStartTime.
2) When the workflow starts, compare StartTime to OldStartTime.
a) If they are equal, then do nothing (end).
b) If they are NOT equal, proceed with your workflow.
3) If 2b, then set OldStartTime to the value of StartTime.
By performing step 3, you ensure that by the end of the workflow, OldStartTime will be equal to StartTime -- this is important because the workflow will continue to run every time a particular item is changed, but by taking away the criterion that would cause the workflow to run the second time, you have avoided an endless loop situation.
Monday morning, the calls started. For some reason, long-time users were unable to edit list items. I figured we had a permissions issue, so I popped in to look at the Site Settings -- and found that I couldn't. A quick trip to Central Administration showed that I was still listed as a Site Collection Administrator, but I had no power at all on the site collection in question.
A quick glance at the logs told me that the server had recently shut down unexpectedly (this is a Hyper-V virtual machine). Apparently, in the confusion, somehow SharePoint decided to lock the site collection as Read Only. This can be remedied in one of two ways:
1) In Central Administration, go to Application Management->SharePoint Site Management->Site collection quotas and locks. Once you have arrived, select the correct application and site collection, and you will have the opportunity to view and set the lock status of the collection (it most likely will be set to "Read-only", and you'll want to move that radio button to "Not locked").
2) Fire up stsadm and issue the following command:
stsadm -o setsitelock -url http://myportalsitecollection -lock none
This came up today on the [sharepointdiscussions] list. A user needed to display a read-only field in a phone number format; it's pretty simple, but it may be just what you need.
Assuming your list item contains a field called "Phone Number" (with a space), the following XPath will give you a number in the classic US telephone format:
<xsl:value-of select="concat('(',substring(@Phone_x0020_Number,1,3),')',substring(@Phone_x0020_Number,4,3),'-',substring(@Phone_x0020_Number,7,4))" />
If you need to mask an input, try this jQuery solution.
This came up on a discussion list lately, so I threw together some code to meet the need. In short, a colleague needed to take the results of an InfoPath form survey and give them to the user in Word format. The form data was already in a list item, so it was a simple matter of using the SharePoint API to get the list item, formatting the data appropriately, and using response headers to make the client machine treat the response as MS Word content.
The following rudimentary code can be run in an ASPX (or an assembly) in the 12 hive. When you link to the page, send the list name and item ID in the querystring and use them to grab the appropriate data.
// Clear the current response headers and set them up to look like a word doc.
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Charset ="";
HttpContext.Current.Response.ContentType ="application/msword";
string strFileName = "ThatWordFileYouWanted"+ ".doc";
HttpContext.Current.Response.AddHeader("Content-Disposition", "inline;filename=" + strFileName);
// Using the current site, get the List by name and then the Item by ID (from the URL).
string myListName = HttpContext.Current.Request.Querystring["listName"];
int myID = Convert.ToInt32(HttpContext.Current.Request.Querystring["itemID"]);
SPSite oSite = SPContext.Current.Site;
SPWeb oWeb = oSite.OpenWeb();
SPList oList = oWeb.Lists["MyListName"];
SPListItem oListItem = oList.Items.GetItemById(myID);
// Build a string with the data -- format it with HTML if you like.
StringBuilder strHTMLContent = newStringBuilder();
// *
// Here's where you pull individual fields out of the list item.
// *
// Once everything is ready, spit it out to the client machine.
HttpContext.Current.Response.Write(strHTMLContent);
HttpContext.Current.Response.End();
HttpContext.Current.Response.Flush();
More Posts
Next page »