Quick Tip – Hide the browse & toggle options on a CorasWorks Calendar

Here’s a quick tip – if you want to hide the browse and toggle options on the CorasWorks Calendar…

CalendarOptions

…all you need is one line of CSS added to your target page:

div.RadToolBar[id*="CWHeader"]{display:none}

The benefit to doing so is to ensure a smooth user experience when you’re say filtering the Calendar. For example, imagine I’ve applied a dynamic filter to only display items within the Current Week and also set the default display view to “Work Week” – if the user has the ability to toggle the display mode to say “Month” or “Timeline” and then also browse back or forward through time, they’re going to get an empty view (again, by virtue of the filter).

Hiding the browse & toggle options simply ensures they stay within the time frame and display mode that Calendar is targeted to; after all, the Calendar itself and the Design Canvas make it quick & easy to create similar Calendar views with different filter ranges and display modes.

Adding the CSS rule can even be done directly through the webpart as well; just open the web part properties (the native SP “Edit web part” option, not the CorasWorks Display Wizard) and add the CSS within a <style> tag to the “HTML Before” or “HTML After” properties and you’re set. Now the web part can even be placed into the Web Part Gallery with this customization set for use throughout your Site Collection.

Access the URL of a file in a Document Library via Lookup

This was one of those “I can’t believe it works this way” moments in SharePoint; if you’ve spent anytime architecting or building applications on SP, you know the feeling I’m talking about.

I had a simple scenario of wanting to allow users to easily link items in a List to a file in a Document Library; however, rather than requiring they copy-paste the URL to the file (manually or otherwise) within the List item, I wanted to use a Lookup. Worked great at the UI layer for end users; however, as soon as I tried to build a display that leveraged the JOIN ability within the CorasWorks API to pull the file URL based on the Lookup value, I hit a wall – any & all fields that contained some or all of the file name or path cannot be queried via the SPQuery.Joins property. I tried them all, including the most obscure of internal system fields like “LinkFilename2″ but none worked.

A quick search of the web revealed I was not alone; even worse, all the solutions I could find required custom workflows or even custom code and all followed the same pattern – create some event handler to grab the URL of a file after upload & write it to another field. Sure it would work, but getting any custom code installed on this client’s server is not easy and requires a multi-week CCB process. All that just to get the URL of an item I already have a Lookup relationship for?!

Then I had an idea: I knew our CorasWorks Actions provided direct and easy access to any field on a List or Library item, including all hidden & internal system fields. So I took the equally direct and easy approach to solving the problem – I created a Set File URL Action (a CorasWorks Modify Item Action) that wrote the “Server Relative URL” for a document into a field I can access through the JOIN on my query.

ActionDefinition

I then created a List Activation that automatically runs said Action every time a file is added to the Document Library and I’m set – no custom coded event handlers or workflows to have to write & deploy. Another streamlined solution thanks to CorasWorks!

What is the CorasWorks CAPS HTML Viewer web part?

If (hopefully when) you upgrade to CorasWorks v11.3.2, you may have noticed a new web part available to you: the CorasWorks CAPS HTML Viewer.

Great! But was is it…? If you’ve ever used the native Content Editor Web Part (CEWP) to load an HTML file from a Library via the Content Link property, then prepare to upgrade your experience! There are three main limitations to using the CEWP in this way; one, it cannot load an HTML file that is not on the local site (i.e. the same site where the web part resides) unless you’ve enabled Anonymous authentication. This means if you have some centralized content in an HTML file you want to display across multiple sites, you’ll have to enable Anonymous authentication or the CEWP will display a message saying it cannot load the content [Reference here, in the IMPORTANT tag].

Second, also on that same Reference page under the NOTE tag is this quote: “If you enter a URL into the Content Editor Web Part as a relative link, the link converts to an absolute URL when the entry is saved.” It then goes on to say if the page the CEWP is on will then be moved (think DEV to QA/Staging to PROD) “…you will need to edit the Content Editor Web Part on the production server and update the URLs manually.” Eek!

Finally, say you want to point to some endpoint (wink wink, CAPS call) that dynamically generates some HTML – so instead of a static HTML file, you want to inject dynamic HTML into a page via web part. The CEWP simply does not support this; use the Content Link property to point it to a Service/API that generates HTML and it will fail to display it.

Fortunately, the CAPS HTML Viewer address all of these limitations. First, not only can you use it to point to any HTML file anywhere within your SharePoint farm – you can do so without having to enable Anonymous authentication.

Additionally, it supports all the CorasWorks built-in variables as well as any Global Variables within your URL. So no more worries about the CEWP converting your relative URLs to absolute ones.

Finally, it fully supports loading dynamic HTML (again, generated via CAPS or any other capable Service/API) into a page; so you’re no longer limited to static HTML files.

No more will you be limited by or struggle with the Content Link property of the Content Editor Web Part – let the CAPS HTML Viewer unlock the full potential of your application design.

Video Embed code (YouTube, Screencast, etc) in SharePoint list items

Ever try to put some embed code into a Multiples lines of text field in SharePoint? If so, chances are you didn’t get the expected result (unless your goal was to display raw HTML & not the embedded video). Your first reaction might be to think, no problem, there’s three different ways to configure a Multiple lines of text field – one has to work, right? Unfortunately not :/

The three options are “Plain Text”, “Rich Text” and “Enhanced Rich Text” – when you try to paste in say the embed code for a YouTube video, your results will be…

  • Plain Text: The raw HTML is saved but it’s also displayed in the Item Forms & List Views, instead of seeing the embedded video.
  • Rich Text: The embed HTML cannot even be saved; if you paste it into the field, when the item saves, it will be stripped out.
  • Embedded Rich Text: This one seems to have the most promise because you can access the “HTML Source” box for the field; not only that, if you post the embed code into the HTML Source, you’ll see the embedded video while still in the List Item form – yay! Save it though, and the embed code is again removed.

You’ll see these results reflected in the screenshots to follow; of the native options, only the field configured as “Plain Text” will even retain the embed code that was pasted in.

So what’s a user to do? Ask IT for a custom coded solution just to display some embedded videos? Hack together something with Content Editor web parts (great for a single video, but what if you need to manage a CMS and video library…)? Buy a solution to stream videos from the SharePoint server (you really want to tax your SharePoint WFEs with video streaming, not to mention YouTube’s player & compression algorithm is world class and likely to perform better…)?

How about a 4th option that makes it as easy as it should be – copy/paste the embed code into a field in the list item & have it just work. Enter the CorasWorks Workplace RTF field!

VideoEmbed-CreateField

Our Workplace RTF field not only allows you to paste video embed HTML into it but, when you do, the embed content is displayed & maintained throughout the Item View & Edit forms (of course, it also works in the CorasWorks Actions).

VideoEmbed-ItemViewForm

VideoEmbed-ItemEditForm

And while the native List Views aren’t capable of rendering the embedded HTML…

VideoEmbed-NativeListView

…fortunately, our smart Grid is:

VideoEmbed-GridView

All told, creating a solution for tracking, managing and displaying your videos from any number of premier video streaming services is now quick & easy with CorasWorks!

JS Date functions not working in SharePoint with IE…?

Ever run into a problem where you have what you know to be valid javascript, trying to work with a Date object, and yet you keep getting JS errors in the console? If you’re working in SharePoint 2010 or older, blame Microsoft ;-)

Joking aside, even if you’re using the latest version of Internet Explorer, because of the meta tags present in the OOTB masterpages of the older versions of SharePoint, IE will load the page in an older Document Mode; IE8 Standards for SP2010 and Quirks for SP2007. You can always, of course, apply a different masterpage or customize the native ones, however you run the risk of encountering issues elsewhere – for example, remove the “IE8″ meta tag from an SP2010 masterpage (or just setting it to a newer version) causes myriad issues with controls like the People Picker, the RTF field, certain menu options in the Item Context Menu, etc.

If your organization’s timeline for upgrading to SP2013 is a long-term effort, consider allowing/enabling your users to run Firefox or Chrome (Chrome Frame was a nice alternative until it was retired at the end of 2013). I know, not the most ideal answer – but at least you can stop banging your head on your desk wondering why your perfectly valid JS for manipulating Dates keeps throwing errors in IE.

Using jQuery to create a slide-left-and-fade effect

A couple years ago I had the idea of adding a UI effect to an application I had built (a lightweight Task board) that mimicked the notification bar in Android – specifically, an item could be “swiped” off the board and the DIV representing the item would have an animation sliding left (or right) while also fading out.

SlideLeftAndFade

Accomplishing that effect was as simple as one line of jQuery:

$('YourSelector').stop(true,true).animate({left:'-=600',opacity:'hide'},1000);

That’s it! You can then implement this upon any sort of event or user interaction (mine happens here upon clicking a “Mark Complete” button) and you’re set.

And for those wondering what makes it all work, the .stop() ensures no conflicting animations are being run (this particular application allows users to re-order & shuffle their board) and the animation itself handles the sliding & fading out via the “left: ‘-=600′” (move the element 600 pixels to the left of where it currently is) & “opacity: ‘hide’” (change the opacity to hide the element) properties.

UPDATED: CorasWorks Application Service capabilities index

It’s been a year since the CorasWorks Application Service was first released publicly – and if you missed it before, we previously posted a concise listing of everything you could do with the version of CAPS that launched with v11.3.0.

Now that CorasWorks v11.3.2 has been released, it seems like the right time to update the capabilities index for CAPS as much has been added in the last two platform releases. Just see for yourself…

Added in v11.3.1

  • Addition of a new “ProcessGlobalVariables” method providing create, edit & delete capabilities for your CorasWorks Global Variables
  • Addition of a new “ProcessList” method providing create, edit & delete capabilities for SharePoint Lists & Libraries
  • Addition of a new “StartWorkflow” method allowing you to kickoff SharePoint workflows via CAPS call
    • Addition of a new “RunOptions” parameter to the StartWorkflow method to allow for setting the corresponding run parameters (Added in v11.3.2)
  • Addition of a new “ListType=External” parameter to the ProcessBatchData operation to provide create, edit & delete capabilities against External Lists leveraging External Content Types
  • Addition of a new global “DatesInUtc” parameter, available on all CAPS operations, for telling the Service to interpret & use the UTC value of any & all CorasWorks date variables within your call
  • Addition of a new global “ContentDisposition” parameter, available on all CAPS operations, for specifying the Content-Disposition header you want the Service to specify for its response
  • Addition of a new “Title” parameter to the CopyFile method, which enables the renaming of a CorasWorks Action or Central View definition if that is what’s being copied
  • Improved error handling for mal-formed XSLT paths

Added in v11.3.2

  • Addition of a new “GetContentTypes” method for enumerating all the available Content Types
  • Addition of a collection of new parameters on the “GiteSiteCollections” method…
    • GetSubsites = true/false, if true returns the children of the site the CAPS call runs in the context of
    • SiteLevels = Integer, specifies the number of levels deep to iterate through & return children sites
    • StartAtRoot = true/false, if true tells CAPS to start enumerating subsites from the root of the Site Collection
  • Addition of a pair of new parameters on the “GetSiteUsers” method…
    • GetUserProfiles = true/false, if true returns the data from the User Profile Service instead of the User Information List of the current site collection (Requires use of Server CAL and User Profile Service)
    • Properties, a comma-separated list of the properties on the object that you wish to return (if absent/null, all properties are returned)
  • Addition of a new “Properties” parameter to the GetSiteInfo and GetListInfo methods, a comma-separated list of the properties on the object that you wish to return (if absent/null, all properties are returned)

CAPS is like a fine wine – it just keeps getting better with age!

Quick Tip – Attribute Value Templates in XSLT

Previously, I blogged about a quick & easy shorthand method for referencing an XSL variable within an attribute value – this capability is really a subset of a capability called “Attribute Value Templates” in XSL (reference).

What’s great about what I’ll call AVTs for short is that you’re not limited to just referencing existing XSL variables; once an AVT is instantiated – by use of the wrapping {} curly brackets – that attribute can then be any valid XSL expression.

Take for example a common use case of dynamically generating some HTML using XSL and, in doing so, wanting to create HTML attributes using data points from your source XML. In the past, you may have done something like this:

<div>
   <xsl:attribute name="id">
      <xsl:value-of select="concat('Task',TaskID)"/>
   </xsl:attribute>
   <xsl:value-of select="Title"/>
</div>

But using an AVT, this same line could be re-written as:

<div id="{concat('Task',TaskID)}">
   <xsl:value-of select="Title"/>
</div>

This is just a simple example but, in general, if you can create an expression as part of a “value-of select”, you can do it within an AVT. Support for full expressions within an AVT thus helps ensure you can write stylesheets that are now both smaller and easier to read.

Simple jQuery for character counts on an input box

A quick tip here on adding a simple character count element to accompany an HTML input.

Imagine you’ve added the “maxlength” attribute to a text input box and now want to provide some real-time feedback to your users as they fill out that input indicating the amount of characters remaining. In my experience, there’s 4 key JS events you’ll want to bind to for maximum likelihood that your character counter updates on all changes: keyup, focusout, paste & cut.

Normally, a simple jQuery $.on() would be all you need, something like this:

$('#MyText').on('keyup focusout paste cut',function(){
  $('#CharCounter').text(255 - $(this).val().length);
});

Try that though & you’ll see a small issue; the paste & cut events aren’t updating correctly. They actually are running, but the reason the counter seems off is that the timing of the events causes the bound function to run before the value of the input is actually changed; they literally fire so fast, the result of the cut or paste hasn’t actually changed the value if the input when it fires.

Fortunately, this is readily addresses by adding a small (even 10ms) setTimeout() function call – and by checking the event.type that triggers the call, you can conditional only use the setTimeout() for those two events.

Not content to stop there though, I wanted a more flexible, reusable solution. Consider the below which then adds a few key features:

  • The aforementioned conditional check for the firing event has been added
  • Initialized via input class so that it can be easily reused within a given form
  • The “maxlength” to substract the char count from is pulled from the input itself instead of hardcoded in the function
  • A custom “data-CountElem” attribute is added to the input markup to identify (by ID) the element you want to write/update the char count to

Check out the jsFiddle here – code below:

$('.UseCharCount').on('keyup focusout paste cut',function(event){
  var self = $(this);
  if(event.type == 'keyup' || event.type == 'focusout')
    $('#' + self.attr('data-CountElem')).text(self.attr('maxlength') - self.val().length);
  else if(event.type == 'paste' || event.type == 'cut') {
    setTimeout(function(){
      $('#' + self.attr('data-CountElem')).text(self.attr('maxlength') - self.val().length);
    },10);
  }
});

Triggering a SharePoint List View’s AJAX refresh with jQuery

With the release of SP2010, we were given snazzy new List View web parts that included a whole set of AJAX options:

AJAXOptions

And it wasn’t long after starting to use these that you may have decided you wanted to be able to trigger an AJAX refresh (Asynchronous update) through your own client-side script. This is great if you have other interactive elements on the screen that will result in the underlying data changing and you want to display them to the user without requiring a full page reload. Enter jQuery!

The easiest way to achieve this is to first enable the “Show Manual Refresh Button” – don’t worry, can easily hide the resulting button from your end users with this CSS snippet:

#ManualRefresh {display:none}

Then, whenever you want to trigger an AJAX refresh of the List View, just fire off this one line of jQ:

$('#ManualRefresh').parent().trigger('click');

And the existing button (perhaps hidden by the above CSS) on the page will take it from there :)