Archive for CAPS

Center content with margin:0 auto

Working in SharePoint I almost expect, on a daily basis, to run into some annoying formatting issue due to an overly-generic CSS rule coming from the Core CSS that’s baked into the platform. Today I had a client trying to center some content (a cool News Rotator using the bxSlider jQuery plug-in, fed via the CorasWorks API) that was being loaded up via Content Editor Web Part (CEWP) but no matter what she did, she couldn’t get the CEWP to center within its parent Web Part Zone.

I then shared a handy CSS trick I picked up along the way; this can be used on any block-level element you want to center within its parent when you have a fixed width applied.
margin:0 auto

Using Firebug, it was clear to the customer that the parent DIV containing the Rotator was filling the horizontal space, but applying a “text-align:center” just resulted in the text within the Rotator items getting centered, not in centering the Rotator itself within its parent DIV.

I looked, saw the fixed width on the Rotator and knew right away that a “margin:0 auto” was all we needed – and voilà, another happy CorasWorks customer!

XSLT 2.0 – Even More on Dates

Recently, I needed to get the minimum and maximum dates from a SharePoint Task list. With XSLT 1.0, you typically accomplish this by iterating over your rows and sorting them in the order you want, then grabbing the first or last value to get the min or max date you want.  This can get cumbersome when you need to do this on more than a couple of fields.

So I took advantage of the opportunity to see what XSLT 2.0 had to offer.  Sure enough there is a min() and max() function and they work just like you would expect them to.

Using a Task list as an example, we can quickly find minimum start and maximum due dates for the entire set of tasks with two lines of XSL applied to our raw CAPS output.

<MinStartDate>

<xsl:value-of select=” min(NewDataSet/Tasks/cw:listitems/rs:data/z:row/@ows_StartDate/xs:dateTime(.))”/>

</MinStartDate>

<MaxDueDate>

<xsl:value-of select=” max(NewDataSet/Tasks/cw:listitems/rs:data/z:row/@ows_DueDate/xs:dateTime(.))”/>

</MaxDueDate>

We have to append our selected node with “/xs:dateTime(.)” so that the XSLT 2.0 engine will compare values as dates and not strings.

You will also want to make sure that you are including “<DateInUtc>TRUE</DateInUtc>” in the CAML of your CAPS call as well.

If you need to refresh your memory about working with dates in xslt 2.0 and CAPS here are our two prior blogs covering formatting and doing calculations.

CorasWorks support for In, Includes and NotIncludes filters in SharePoint

Starting with SharePoint 2010, three new CAML filter operators were added, but scant details and examples mean that even 3+ years later, few people know about or use them. Fortunately, the CorasWorks platform (including CAPS) fully support these new operators – and here’s some insight on how you can take advantage of them!

The <In> operator

This is probably my favorite addition of the three and the one I use most often; what it does is allow you to collapse what would normally be a string of multiple <Or> filters into one single <In> condition.

For example, you want to filter a native Tasks list to show all items that are “Not Started”, “In Progress” or “Waiting on Someone Else”; you would likely string three together three <Eq> conditions inside <Or> operators (or even string two <Neq> filters for the other possible values of “Completed” & “Deferred”).  Something like this:

<Where>
<Or>
<Or>
<Eq>
<FieldRef Name=”Status”/>
<Value Type=”Choice”>Not Started</Value>
</Eq>
<Eq>
<FieldRef Name=”Status”/>
<Value Type=”Choice”>In Progress</Value>
</Eq>
</Or>
<Eq>
<FieldRef Name=”Status”/>
<Value Type=”Choice”>Waiting on Someone Else</Value>
</Eq>
</Or>
</Where>

Now let’s see that same filter written using the <In> operator:

<Where>
<In>
<FieldRef Name=”Status”/>
<Values>
<Value Type=”Choice”>Not Started</Value>
<Value Type=”Choice”>In Progress</Value>
<Value Type=”Choice”>Waiting on Someone Else</Value>
</Values>
</In>
</Where>

How’s that for efficiency? Easier to read and easier to write – bet you never thought you’d say that about a CAML query.

The <Includes> operator

If the <In> operator is akin to a string of <Or> conditions on a single value, the <Includes> operator is a specialized option for working with multi-select Lookup values; think of it as a “contains”, but intelligent enough to differentiate if you have similar text in multiple Lookup values.

Sticking with our Task list example, imagine wanting to filter by the multi-select Lookup that is the Predecessors column to find all Tasks that have a specific predecssor – this would allow you to see all the Tasks that might be impacted by a specific one slipping. You can’t use an <Eq> condition because that would only bring back items whose only predecessor is the Task you want – again, the <Includes> gives you the advantage of working more like an intelligent contains, like such:

<Where>
<Includes>
<FieldRef Name=’Predecessors’/>
<Value Type=’Lookup’>Task 4</Value>
</Includes>
</Where>

The <NotIncludes> operator

This one is now simple because it’s just the inverse of <Includes>. Still specifically built for multi-select Lookups, it would allow you to filter for, in our same scenario, all Tasks that do not have a given Task as a predecessor – it’s the intelligent version of a “does not contain” filter, implemented as:

<Where>
<NotIncludes>
<FieldRef Name=’Predecessors’/>
<Value Type=’Lookup’>Task 4</Value>
</NotIncludes>
</Where>

References

Not that there’s much more detail there, but here are the corresponding MSDN links for these operators as well:

XSLT 2.0 – More on Dates

Dates.  The “when” of it all.  Working with dates can be frustrating when building client side applications for SharePoint due to the limitations of XSLT 1.0.   Our resident CAPS and XSLT 2.0 expert, Steve Evangelista, blogged a while back about how much easier it is to format dates with our new CAPS service because you can leverage XSLT and XPath 2.0 functions. Having recently helped Steve with a project to create a complicated Gantt chart for resource management, I wanted to take a moment to repeat Steve’s message and also let all of you know how powerful and easy it is to perform date calculations with XSLT 2.0.

One of the first things we need to do is make sure we properly reference the XML namespaces we’ll need to make use of in our xsl:stylesheet node; namely:

The first thing you have to do when with working with dates in XSLT 2.0 is to make sure you recast your date values from your underlying XML, which are all strings, to “date”, “time” and/or “dateTime” types depending on your needs.

You are now ready to do some calculations.  Lets start with a common scenario — finding the difference between two dates:

<xsl:value-of “select=”xs:dateTime(DateTime1)-xs:dateTime(DateTime2)” />

DateTime1 and DateTime2 are two date values from your data in the format of  “yyyy-MM-ddThh:mm:ss” for the dateTime type.  If you’re only interested in dates then use xs:date and if you are only interested in time, use xs:time instead of xs:dateTime.

This gets you a raw value, but we can get what we’re really after by wrapping that calculation in another XPath function.

<xsl:value-of select=”days-from-duration(xs:dateTime(DateTime1)-xs:dateTime(DateTime2))” />

The XPath function “days-from-duration” converts the raw results of our date calculation into something meaningful for your grid display or chart.

If we were only interested in the number of hours, we could have used the XPath function “hours-from-duration”.

It’s that easy.  No need to use any complicated XSLT 1.0 templates, depend on EXSLT libraries or write javascript.   All you need to do is include these XSLT 2.0 functions in XSL  stylesheets that you can apply to your CAPS requests’ XML output.

The w3schools.com website is a great place to learn more about XML, XSLT & XPath. For a listing of XPath 2.0 date/time/duration functions you can go directly to this page:

http://www.w3schools.com/xpath/xpath_functions.asp#datetime

Have fun and keep building.

Adding XSLT 2.0 IntelliSense to Visual Studio

With the release of the CorasWorks Application Service (CAPS), the ability to leverage XSLT 2.0 within our SharePoint applications has been a major boost to our capability set. And for anyone that’s written XSLT, you know using an IDE that is schema-aware, and thus able to provide element, attribute and value completion options can make it all the easier.

As someone that works predominantly in Visual Studio, I knew there must be an option to switch the default XSLT schema from 1.0 (which is the default because that’s all native .Net supports) to 2.0. And sure enough, there is!

  1. Browse to the install directory for Visual Studio on your machine. By default this is typically “C:\Program Files\Microsoft Visual Studio XX.x” where “XX.x” is your version of Visual Studio. If you’re using a 64-bit machine, it will be the x86 version of the “Program Files” directory.
  2. Within the install directory, open the “Xml” folder, then the “Schemas” folder
  3. Make a copy of the existing “xslt.xsd” file therein; I renamed mine to “schema-for-xslt1.0.xsd”
  4. Download the official XSLT 2.0 XSD from W3C here and save it as “xslt.xsd” to the same Schemas directory above.
  5. If you have Visual Studio currently open, restart it.
  6. Once you open an XML, XSL or XSLT file, the XML menu will appear in the Toolbar:
    XML-Menu-VS
  7. Click the “Schemas…” option, which will open the XML Schemas dialog. Locate the XSD file copied in Step 3 and toggle “Use” option to Disabled:
    XSL-Schema
  8. The newly downloaded XSD for XSLT 2.0 should already be enabled by default but, if not, be sure to do so.
  9. Enjoy XSLT 2.0 IntelliSense within Visual Studio :)

Polling Data with JavaScript’s setInterval() Function

I wrote earlier this year about making use of JavaScript’s setTimeout() function to improve the efficiency of some custom JavaScript/jQuery I wrote for a complex hierarchical report. Using setTimeout, the report let users quickly see the health of numerous projects that needed to update many columns and rows of results based on the user’s filter and view selections.

The setTimeout() function also has a very useful cousin called setInterval() that lets us call a function repeatedly until we either tell it not to with clearInterval() or the user closes the window. We can use this function to automatically update a section of a page with current information from a SharePoint list/library or other data sources. A good example of why we would do this is retrieving the number of the tasks for the currently logged in user that are past due. By wrapping an AJAX request to our CAPS service in a setInterval() function on a frequent interval (say every 60 seconds – 60000 miliseconds), we can unobtrusively and asynchronously update a past-due task notification on our custom page.

After our page loads we simply make a call to some custom script with setInterval() like this:

setInterval(getPastDueTasks(currentUser), 60000);

What we are doing here is calling our function  - getPastDueTasks(currentUser) – that makes our CAPS call to our task list using AJAX. Because we set the interval to 60000 milliseconds, our task list will be polled every minute. On success, our AJAX request will update an object on our page with the number of tasks that are past due and show a large red exclamation point if there are any. Since we’ve also made the object a hyperlink, the user can bring up the list of past due tasks so they can take action on them.

This is just on example, but I know you all are a creative lot so have fun with this and keep building.

Securing & Hardening SharePoint Sites for External Users

For most organizations, it’s not a question of “If” but “When” – when will you want, or need, to collaborate with an external user on an application hosted in within your SharePoint farm? Over the years, CorasWorks has helped customers across numerous verticals, with a myriad of use cases and requirements, improve the efficiency of their solutions by giving external stakeholders direct access to the data they should see. More importantly, our platform and best practices have enabled customers to architect and implement their own secure solutions as well. Let’s look at the key concepts that allow this.

Basic Security

As a favorite childhood cartoon of mine reminded me every Saturday morning, knowing is half the battle. Liam Cleary, a SharePoint MVP, did a great write up in 2012 on educating site owners and SharePoint administrators on just what might be out there and visible to the world with the default settings. I suggest a quick read; after all, the first step in good security is knowing what you’re protecting.

Setting up Your Collaboration Spot

Whether it’s an Intranet-Extranet scenario, a customer/vendor portal, a system for publishing approved content from a private site to a public one or anything else in which you want to decouple source data from the end user, there’s a few basic concepts that the CorasWorks v11 platform will help you leverage to separate & secure your solution.

  1. First, because all the CorasWorks components support full CRUD (Create, Read, Update, Delete) operations across Site Collections and Web Applications, you can securely segment your external partners & users from your internal ones.
  2. The CorasWorks platform also contains numerous features for copying and/or moving content from one place to another; again, across Lists & Libraries, across Sites, across Site Collections and across Web Apps.

    Leveraging our Actions and/or CAPS, you can enable process owners and approvers to push content from a secured, internal site to an open or partner-secured external site. You can also automate the process using Timers (i.e. every Monday at 5AM, check for and publish the newest approved content) or Triggers (i.e. upon Status=Approved for Release, publish to external site).

  3. And perhaps the most powerful option: if you do not want to copy or move data between sites but instead want to give your external users direct access to only the data they should see – say a customer portal that you want to display real-time inventory data – then CorasWorks is the tool to use.Our platform enables the creation of a secure “proxy” within the SharePoint farm that can process requests between say a Customer Portal site and a secured internal site.

    This design allows you to leverage a service account to provide full CRUD operations against any SharePoint data in the farm, but invisible to the end user – so they cannot see anything but the data you choose to expose to them (i.e. think column-level security). The end user is unable to even see where the data comes from, and their account doesn’t have access to it even if they did.

Couple this with some easy changes to secure away some of the “revealing” pages that Liam describes, like the All Site Content page (we’ll cover this in a future blog), and you’ve got a robust yet secure option for collaborating with all your stakeholders, internal or external.

The CorasWorks Platform – When to use What

So you have the CorasWorks Platform and are diving into creating awesome solutions for all of your users, hopefully even show off how great you are and how wonderful SharePoint can be.  Maybe you are a power user and you are ready to take on a larger challenge and dive into the world of XML and XSLT.  Or, perhaps, you are already an advanced builder, but you are looking to deliver some quick wins to your users.   Well, I’ve been in your shoes and this blog will help guide you along your way as you come to master our tools.

Basic Components

Our Basic Components are very powerful and, for the most part, you can put one on a page, point it to an existing SharePoint List or Library anywhere in your farm and be up and running in minutes.   If you have similar data on multiple sites – again, anywhere in your farm – you can even quickly aggregate them all together into one nice centrally located view.   Once you start adding Actions through the CorasWorks Action Wizard, you are really on your way to building most any type of basic application.

While the Basic Components are very powerful, especially when combined with our Action framework, they come at a cost.  As a general rule the easier something is to use, the less flexibility it will have.  At some point most of us will find ourselves needing to build a solution where the basic components just won’t meet the requirements.

CAPS (and previously the Advanced Components)

Our new CorasWorks Application Service, known as CAPS, provides you with an incredible amount of power and flexibility when it comes to building more complex solutions and having control over the user interface and experience.   With CAPS you can quickly and easily work with any data from across your SharePoint environment.  Our legacy Advanced Components also provided a more extensible framework; the External Data Provider let you easily connect to a variety of external data sources, while the Mashup Adapter let you combine data from a variety of sources into one ready to consume output.

The data retrieved and aggregated through all of the above manners can be transformed using XSLT.  With the legacy Advanced Components, you were limited to XSLT 1.0, but with CAPS you have the full power of XSLT 2.0 at your disposal, making CorasWorks the only application development platform on SharePoint with an XSLT 2.0 processor.  Using XSLT or even client-side scripting consuming JSON (which CAPS also supports), creating a rich UI is easier than ever.  Even the legacy Custom Display Adapter or Chart Display Adapter have vast degrees of flexibility, your only limitation often being imagination and skill.

A Place for Everything

The beautiful part about the CorasWorks platform is that you’re never completely locked into one path or the other; you can mix Basic Components, CAPS, legacy Advanced Components and even other 3rd party and custom controls.   Need to build a solution with a complex multi-level nesting of hierarchal data? Make the most of CAPS and client-side technology to create a UI that loads child data on demand.  Need your users be able to quickly update data and manage lookup values?   Give them some Basic Grids and Actions.   Want to empower those same users to setup different views of data retrieved from multiple SharePoint and non-SharePoint sources?  Connect the output from CAPS (or a legacy Advanced Provider) to a Basic Grid by selecting the “Advanced View (XML Based)” option as your view type so your users can make use of Basic Grid functions they are already familiar with including grouping, sorting and conditional formatting.

Wrapping Up

There is never just one way to design and build a solution, and ultimately those decisions will be driven by factors such as time and cost as well as other considerations such as your user base.  With the entirety of the CorasWorks Platform, you have the ability to approach a solution from a variety of ways.   As a general rule though, think of the Basic Components as a way to quickly connect to SharePoint Lists and Libraries, empowering your users to work with that data through our Actions.   CAPS, and the legacy Advanced Components before it, come into play when the underlying data becomes more complicated through joining multiple sets of data together, applying complex transformations through XSLT, and/or working with external data sources.  You will also want to leverage client-side technologies with CAPS when you want to have more control over the user interface and experience.

I hope this article has been helpful as a high level review of when and how to leverage everything CorasWorks has to offer. Keep building!

Split, Join & Distinct – Working with Strings in XSLT 2.0

Here at CorasWorks, the ability to leverage XSLT 2.0 within our SharePoint-based applications – thanks to the CorasWorks Application Service – has added a lot in the way of efficiency. We’ve previously blogged about the myriad of Date Formatting options (here), and using RegEx to parse content from the ugly HTML markup SharePoint creates for multi-line text fields (here). Another area though that has improved vastly with XSLT 2.0 is string functions; specifically, let’s look at the tokenize(), string-join() and distinct-values() functions.

As is often the case, it’s not that these sort of routines weren’t possible in XSLT 1.0; they were just inefficient, took more lines of script to write and were possibly even prohibitively complex to come up with on your own. The new functions in XSLT 2.0, by contrast, are optimized, compact and intuitive to write.

Take splitting a string based on some delimiter, a fairly common use case; using the tokenize() function within a for-each statement makes this trivial. For example, SharePoint frequently stores certain data as a string delimited by the characters “;#” – item attachments and multi-select Choice, Person & Lookup values are just some of the data points SharePoint stores in this format. With XSLT 2.0, these values could be parsed out simply as such:

<xsl:for-each select=“tokenize(MyColumn,’;#’)”>

<Item><xsl:value-of select=“.”/></Item>

</xsl:for-each>

The inverse is also equally straightforward; assume you have an XML node set you’d like to concatenate the values for using some delimiter of your choosing. This example would take the Assigned To values for all Tasks and join them into a single element called “StringJoin” with each value separated by a semicolon and a space using the string-join() function:

<StringJoin>

<xsl:value-of select=”string-join(Tasks/AssignedTo/text(),’; ‘)”/>

</StringJoin>

Following that example though, if more than one Task is assigned to the same person, you’d get duplicate names in the “StringJoin” value; so let’s see how a node set could be created with just the distinct names via the distinct-values() function:

<xsl:for-each select=“distinct-values(Tasks/AssignedTo)”>

<DistinctName><xsl:value-of select=“.”/></DistinctName>

</xsl:for-each>

These three functions go a long way to optimizing and simplifying the XSLT you may write, and we’re lucky to be the only application platform on SharePoint that supports them and all the other advantages XSLT 2.0 affords!

Formatting Dates & Times in XSLT 2.0

The CorasWorks Application Service brings the power of XSLT 2.0 to SharePoint 2010 & 2013 – and with it, the myriad of new functions and capabilities the 2.0 spec includes. A common need, especially when working with SharePoint data, is to reformat Date and Time values as SharePoint returns them in the format yyyy-MM-dd hh:mm:ss (or sometimes even yyyy-MM-ddThh:mm:ssZ). Let’s deconstruct this real quick, since knowing your input will ensure you apply the right options to get the desired output.

Let’s reference the date CAPS was released – July 15, 2013 at midnight – for all the below:

Format String Description Result
yyyy 4-digit year 2013
MM 2-digit month 07
dd 2-digit day 15
hh 2-digit hour (12-hour format) 12
mm 2-digit minute 00
ss 2-digit second 00

With XSLT 2.0, not only is Date & Time formatting now supported natively, but the options you can specify are extremely flexible, including multilingual support (dependent on support being enabled in your XSL processor).

Here are some of the most common use-cases and how to implement them:

Format String Description Result
format-date($Date,
‘[M]/[D]/[Y]‘)
Default US format 7/15/2013
format-date($Date,
‘[M01]/[D01]/[Y0001]‘)
2-digit month, slash,
2-digit day, slash,
2-digit year
07/15/13
format-date($Date,
‘[D1o] [MNn], [YWw]‘)
Ordinal day month name,
year as words
15th July,
Two Thousand and Thirteen
format-date($Date,
‘The [Dwo] day of [MNn], [Y]‘)
Date as a word, name of month, year The fifteenth day of July, 2013
format-date($Date,
‘[FNn], [MNn] [D1o], [Y]‘)
Day of week, month name, year Monday, July 15th, 2013
format-date($Date,
‘[MNn] [D1o] is the [dwo] day of [Y]‘)
Day of year July 15th is the
one hundred and ninety-sixth day of 2013
format-date($Date,
‘[FNn,3-3]., [MNn] [D1o], [Y]‘)
Day of week abbrev., month, day ordinal,
year
Mon., July 15th, 2013
format-date($Date,
‘[MNn,3-3]. [D1o], [Y]‘)
Abbreviated month, day ordinal, year Jul. 15th, 2013
format-time($Time,
‘[H]:[m] is the [m1o] minute of the [Hwo] hour’)
Minute ordinal and
hour ordinal
8:30 is the 30th minute of the eighth hour
format-time($Time,
‘[h02]:[m] – or [h02][m] in military format’)
Time in 24hr clock, or in military format 08:30 – or 0830 in military format
format-time($Time,
‘[H]:[m] can be clarified as [H]:[m] [P]‘)
Time with AM/PM lowercase 8:30 can be clarified as 8:30 a.m.
format-time($Time,
‘[H]:[m] can be clarified as [H]:[m] [PN]‘)
Time with AM/PM uppercase 8:30 can be clarified as 8:30 A.M.
format-time($Time,
‘[H]:[m] can be clarified as [H]:[m][PN,2-2]‘)
Time with AM/PM uppercase and no periods 8:30 can be clarified as 8:30AM

Hopefully these cover all the common usage scenarios and you can take advantage of the greatly improved Date & Time formatting in XSLT 2.0. For more info, check out the detailed spec on the W3 site here.