List View Extension Points (CSR)

Applies To: SharePoint 2013, 2016, Office 365

List View Client Side Rendering Primer: 4 of 5

About This Series

This series provides a brief overview of Client Side Rendering for List Views (often referred to as JSLink). Basic extension points and examples are included. The goal of this series is to get developers unfamiliar with this programming model quickly up to speed.

How to Get the Code

The example created using the steps in this series can be found in full as part of the csrShim repository:
https://github.com/thechriskent/csrShim/tree/master/Examples/CSR%20Primer

The full project can be found on GitHub:
https://github.com/thechriskent/csrShim

You can download or clone the repository directly from that site. You can also view the code directly on the site. csrShim is not used in this example and is not required.

In the following examples, we will be targeting on premise SharePoint 2013 using SharePoint Designer 2013.

List View Extension Points

You can override one or more parts of the rendering of your list view. You do not need to specify all the following, but be aware that specifying a single template will use the default render for the other templates (this is different from the OOTB view).

CTX

The CTX object contains all the information about your list view – including all the returned data. This object is provided to the event callback functions and to any template functions.

Although there are many properties (especially when using standard CSR vs csrShim), here are the key properties to pay attention to:

  • CurrentItem
    • This property is only set when passed to the Item template
    • Provides quick access to all properties for the current item
    • Properties match the internal name of the field
    • Properties can sometimes contain periods and therefore these properties cannot be accessed using the standard dot notation
      //Standard Access
      var created = ctx.CurrentItem.Created;
      
      //Access Properties with Periods
      var createdF = ctx.CurrentItem["Created.FriendlyDisplay"];
      
  • firstRow
    • When true, the item is the first item returned
  • lastRow
    • Only available with csrShim!
    • When true, the item is the last item returned
  • Row
    • The array of returned items with their properties
    • These are equivalent to CurrentItem objects
    • This allows access to ALL rows from any template including the Item template
  • FirstRow
    • Available with standard CSR and csrShim with Lists (not feeds/XML)
    • The item ID of the first item returned
  • LastRow
    • Available with standard CSR and csrShim with Lists (not feeds/XML)
    • The item ID of the last item returned
  • ListSchema
    • In standard CSR, contains several properties about the underlying list structure and the view configuration
  • Field
    • Array of the fields returned with the view
    • In standard CSR, several properties (like DisplayName) can be very helpful for dynamic displays. csrShim only provides the Name (internal name).

Event Callbacks

There are 2 events (OnPreRender and OnPostRender) where you can provide callback functions.

OnPreRender

To have a callback function executed BEFORE your templates are applied to the list data, you can specify an anonymous or named function to the OnPreRender property of your CSR object.

The PreRender event can be helpful to declare any necessary SOD dependencies, verify existence of elements, contact additional web service, etc.

(function(){

    var myCSR = {
        BaseViewID: 1,
        ListTemplateType: 100,
        OnPreRender: myFunction
    };

    function myFunction(ctx){
        //Do Stuff
    }
})();

Example

In our HallOfFame.js example from earlier we will add a console message so we know when our rendering is about to start:

    var HallOfFame = {
        BaseViewID: 1,
        ListTemplateType: 100,
        OnPreRender: hofPreRender
    };

    function hofPreRender(ctx){
        if(window.console && window.console.log){
            console.log('Begin Hall Of Fame!');
        }
    }

Here’s what we just did:

  • Line 5 we added a comma to ensure we could add another property
  • Line 6 we added the OnPreRender property and gave it a reference to our function hofPreRender
  • Line 9 this is our callback function
  • Line 10-12 safely logs a message to the console (the checks prevent IE from throwing errors when the console is not visible)

Refreshing the page with the developer tools visible (F12) should show our message. If you don’t see a console message, verify the JS Link property is pointing to the correct page. Also note that console messages logged before the developer tools were open (in IE) will not show and you may need to refresh.

OnPostRender

To have a callback function executed AFTER your templates are applied to the list data, you can specify an anonymous or named function to the OnPostRender property of your CSR object.

The PostRender event can be helpful to attach events or run any other code dependent on your HTML being in place.

(function(){

    var myCSR = {
        BaseViewID: 1,
        ListTemplateType: 100,
        OnPostRender: myFunction
    };

    function myFunction(ctx){
        //Do Stuff
    }
})();

Example

In our HallOfFame.js example from earlier we will add another console message so we know when our rendering is all done:

var HallOfFame = {
        BaseViewID: 1,
        ListTemplateType: 100,
        OnPreRender: hofPreRender,
        OnPostRender: hofPostRender
    };

    function hofPreRender(ctx){
        if(window.console && window.console.log){
            console.log('Begin Hall Of Fame!');
        }
    }

    function hofPostRender(ctx){
        if(window.console && window.console.log){
            console.log('Finished Hall Of Fame!');
        }
    }

Here’s what we just did:

  • Line 6 we added a comma to ensure we could add another property
  • Line 7 we added the OnPostRender property and gave it a reference to our function hofPostRender
  • Line 16 this is our callback function
  • Line 17-19 safely logs a message to the console (the checks prevent IE from throwing errors when the console is not visible)

Refreshing the page with the developer tools visible (F12) should show both our PreRender and PostRender messages in the proper order.

Templates

There are several templates that can be specified using the Templates property of your CSR object. You can specify simple strings, “magic” strings, and full functions that return a string.

(function(){

    var myCSR = {
        BaseViewID: 1,
        ListTemplateType: 100,
        Templates: {
            Header: "
<div>I'm the Header!</div>
",
            Item:   "
<div>I'm an Item!</div>
",
            Footer: "
<div>I'm the Footer!</div>
"
        }
    };

})();

Available Templates

  • Header
  • Item
  • Fields
  • Footer

Note – The Footer template is often misused to close any open tags from the header or item templates. This will result in invalid HTML. Although most modern browsers will auto close these open items for you, this may cause hard to track down display issues! The Footer template is rendered inside a div element outside the hierarchy of the Header and Item templates and is designed for standalone paging. It can be used for other things, but it is separate from anything generated in the other templates.

Magic Strings

In the most basic forms, templates can be specified as simple strings (as in the example above). Additionally, when specified as strings you can use special notation to have “magic strings” resolved automatically.

(function(){

    var myCSR = {
        BaseViewID: 1,
        ListTemplateType: 100,
        Templates: {
            Header: "
<div>My BaseViewID is <#=ctx.BaseViewID#></div>
"
        }
    };

})();

The format is to include <#=ctx. Before the name of the property and followed by #>

In nearly every case you will be better supplying a function to the template properties (even for simple strings) since this will give you more flexibility, better readability, and easier extensibility.

Functions

You can specify anonymous or named functions (named functions are best practice coding) to each of the template properties. These functions will be provided with the CTX object as the parameter.

(function(){

    var myCSR = {
        BaseViewID: 1,
        ListTemplateType: 100,
        Templates: {
            Header: myFunction
        }
    };

    function myFunction(ctx){
        //Do Stuff
    }
})();

Example Header

Although it would be better to use an external stylesheet, for this simple example we will be declaring an inline style block to set our CSS for the rest of the list view. We will do this in the header. Additionally, we’d like to show a title box.

    var HallOfFame = {
        BaseViewID: 1,
        ListTemplateType: 100,
        OnPreRender: hofPreRender,
        Templates: {
            Header: hofHeader
        },
        OnPostRender: hofPostRender
    };

    function hofHeader(ctx){
        var styles = '
<style type="text/css">' +
                     '.halloffame{' +
                     ' text-align:center;' +
                     ' width:504px;}' +
                     '.halloffame div{'+
                     ' box-sizing:border-box;}' +
                     '.hof-header{' +
                     ' font-size:18px;' +
                     ' font-weight:bold;' +
                     ' border:solid black 4px;' +
                     ' padding:6px;}' +
                     '.hof-items{' +
                     ' border-right:solid black 4px;}' +
                     '.hof-items:after{' +
                     ' clear:both;' +
                     ' content:"";' +
                     ' display:block;}' +
                     '.hof-item{' +
                     ' float:left;' +
                     ' width:125px;' +
                     ' border-left:solid black 4px;' +
                     ' border-bottom:solid black 4px;' +
                     ' height:100px;}' +
                     '.hof-item div{' +
                     ' color:black;' +
                     ' font-weight:bold;' +
                     ' font-size:15px;}' +
                     '.hof-item:hover{' +
                     ' filter:brightness(75%);}' +
                     '.hof-footer{' +
                     ' border:solid black 4px;' +
                     ' border-top:none;' +
                     ' padding:3px;' +
                     ' font-size:10px;}' +
                     '</style>

';
        var header = '
<div class="halloffame">
<div class="hof-header">- Hall of Fame -</div>
<div class="hof-items">';
        return styles + header;
    }

Here’s what we just did:

  • Line 7 we added a Templates property
  • Line 8 we added a Header property to our Templates object and gave it a reference to our hofHeader function
  • Line 19 this is our template function
  • Lines 20-54 is a massive string to define our style block
  • Line 55 this is our actual HTML. We begin with a wrapper div (that we don’t close in this template) with a class of halloffame since this allows us to target our CSS classes very specifically. We also provide a div to hold our title text
  • Line 56 we return the combined styles and header strings

When you refresh the page now you will get this monstrosity:

lve01

Example Item

We’d like to show each of the items as a box showing the Title and the picture of the Person field. Additionally, we’d like to color the box based on the value of the Color field. When someone clicks on a box, they should be taken to the user’s profile page.

    var HallOfFame = {
        BaseViewID: 1,
        ListTemplateType: 100,
        OnPreRender: hofPreRender,
        Templates: {
            Header: hofHeader,
            Item: hofItem
        },
        OnPostRender: hofPostRender
    };

    function hofItem(ctx){
        var sip = ctx.CurrentItem.Person[0].sip;
        var photoUrl = '/_layouts/15/images/PersonPlaceholder.96x96x32.png';
        if(ctx.CurrentItem.Person[0].picture){
            photoUrl = ctx.CurrentItem.Person[0].picture;
        }
        var photo = '/_layouts/15/userphoto.aspx?accountname=' + sip + '&size=L&url=' + photoUrl;
        var userUrl = _spPageContextInfo.siteServerRelativeUrl + '/_layouts/15/userdisp.aspx?ID=' + ctx.CurrentItem.Person[0].id;                           

        var item = '<a href="' + userUrl + '">' +
                   '
<div class="hof-item" style="background-color:' + ctx.CurrentItem.Color + ';">' +
                   '
<div>' + ctx.CurrentItem.Title + '</div>
' +
                   '  <img style="max-height:72px;max-width:72px;" src="' + photo + '"/>' +
                   '</div>
' +
                   '</a>';
        if(ctx.ListData.LastRow == ctx.CurrentItem.ID){
            var closures = '</div>
</div>
';
            return item + closures;
        } else {
            return item;
        }
    }

Here’s what we just did:

  • Line 9 we added an Item property to our Templates object and gave it a reference to our hofItem function
  • Line 60 this is our template function
  • Lines 61-66 is the building of the profile picture image.
    • In standard CSR, a person field is returned as an array of objects with additional properties about a person. One of those properties is the picture property which is the URL to the profile picture for a given user.
    • If a user does not have a profile picture, this property is not included
    • So, we ensure that if the picture is not available we use the standard person placeholder image instead
    • Additionally, if your My Site web application is hosted at a different domain (even sub domain) users using machines not joined to the domain (IE iPads) may be prompted to log in for each profile picture you display.
    • So, instead of using the profile picture directly, we use the userphoto.aspx page to provide us the picture without leaving the domain
  • Line 67 builds the URL to the user profile page using the user id property
  • Lines 69-74 builds our actual HTML for each item.
    • We wrap everything in a link to the user profile
    • We use an inline style to set the background-color to the choice field
      • This is not a good idea and is only used as an obvious example, generally you should not directly incorporate values into markup like this. It would be easy to break simply by adding a choice for a color that is not one of the named HTML colors.
    • Line 67 checks if this item is the last item returned
      • In csrShim we could simply check ctx.CurrentItem.lastRow
      • If this is the last item, we close the wrapper divs left open in the header template and return those after the item.
      • This is necessary since the Footer template will be in a different div and leaving open HTML tags can cause display issues
    • If this wasn’t the last item, we just return the basic item box in line 80

When you refresh the page now things are looking truly amazing:

lve02

Example Footer

We’d like to add some instructions to the bottom to remind people to click on these boxes.

    var HallOfFame = {
        BaseViewID: 1,
        ListTemplateType: 100,
        OnPreRender: hofPreRender,
        Templates: {
            Header: hofHeader,
            Item: hofItem,
            Footer: hofFooter
        },
        OnPostRender: hofPostRender
    };

    function hofFooter(ctx){
        var footer = '
<div class="halloffame">
<div class="hof-footer">Click on a person to learn more</div>
</div>
';
        return footer;
    }

Here’s what we just did:

  • Line 10 we added a Footer property to our Templates object and gave it a reference to our hofFooter function
  • Line 84 this is our template function
  • Line 85 builds standalone HTML to be used as our footer. We provide another wrapper with the halloffame class so that our global styles still get applied. Then we give an unnecessary message encouraging clicks.
  • Line 86 we return the footer

When you refresh the page now you will now be struck at the beauty of our creation:

lve03

Continue?

That’s pretty well everything you need to know about client side rendering with list views. However, the final post in the series provides a quick list of best practices to keep in mind while applying CSR to List Views:

Getting Started (List View CSR)

Applies To: SharePoint 2013, 2016, Office 365

List View Client Side Rendering Primer: 3 of 5

About This Series

This series provides a brief overview of Client Side Rendering for List Views (often referred to as JSLink). Basic extension points and examples are included. The goal of this series is to get developers unfamiliar with this programming model quickly up to speed.

How to Get the Code

The example created using the steps in this series can be found in full as part of the csrShim repository:
https://github.com/thechriskent/csrShim/tree/master/Examples/CSR%20Primer

The full project can be found on GitHub:
https://github.com/thechriskent/csrShim

You can download or clone the repository directly from that site. You can also view the code directly on the site. csrShim is not used in this example and is not required.

In the following examples, we will be targeting on premise SharePoint 2013 using SharePoint Designer 2013.

List Setup

For this example, we will be using a custom list with just 3 columns:

  • Title (Text)
  • Person (User)
  • Color (Choice)

To create the list:

  1. From a site where you have full control or design permissions, using the Site Actions menu (gear) choose Add an App
  2. Choose Custom List
  3. Name the list Hall of Fame and click Create
  4. From Site Contents, hover over the Hall of Fame icon and click the ellipsis to show the panel and choose Settings:
    gs01
  5. Under Columns, click Create column
  6. Give a name of Person and set the type to Person or Group then click OK:
    gs02
  7. Under Columns, click Create column again
  8. Give a name of Color and set the type to Choice (menu to choose from). Replace the choices with Tomato, YellowGreen, DeepSkyBlue, Gold (each on separate lines):
    gs03
  9. Navigate to the Hall of Fame list and add several entries:
    gs04
  10. On a page, choose to Edit and click the Add a Web Part button
  11. Under Apps, choose Hall of Fame
  12. Click Stop Editing

By default, you have a very OOTB view of the list as a table with column headers and not a lot of excitement. So, let’s customize it!

Script Setup

To use the JS Link property of the XSLTListView web part we added in the steps above (step 11), we’ll need a JavaScript file to point to.

  1. Open your site in SharePoint Designer
  2. Using the All Files navigation option, open a Document Library (generally, the Style Library is a great location for these types of resources)
  3. In the File dropdown choose JavaScript:
    gs05
  4. Name the file js
  5. Return to the page (in the browser) where you added the web part
  6. Edit the page and using the dropdown on the web part choose Edit Web Part
  7. In the web part tool pane, expand the Miscellaneous section
  8. In the JS Link box, Provide the path (You can use SPURLs) to the JavaScript file we created earlier then click OK:
    gs06
  9. Nothing will happen (we haven’t provided any code yet). Click Stop Editing on the page
  10. Return to SharePoint Designer and Right-Click on the HallOfFame.js file and choose Edit File in Advanced Mode
  11. Enter the code from the CSR Boilerplate Code below

CSR Boilerplate Code

(function(){

    var HallOfFame = {
        BaseViewID: 1,
        ListTemplateType: 100
    };

    SP.SOD.executeFunc('clienttemplates.js','SPClientTemplates',function(){
        SPClientTemplates.TemplateManager.RegisterTemplateOverrides(HallOfFame);
    });

})()

The above code is simply boilerplate for the extension points we will fill in below. Here is what this code currently does:

  • Line 1 is the declaration of an immediately invoked function expression (IFFE) that will ensure our code will not be placed in the global namespace. This convention should always be used with JS Link files.
  • Lines 3-6 is the beginning of our template object. Soon we will be adding more properties to help determine how the list is formatted. For now, we’ve specified the BaseViewID and the ListTemplateType which is how we target the Custom List (type 100) so that SharePoint knows what data to provide us.
  • Line 8 uses a Script On Demand (SOD) method to only call our function once the clienttemplates.js file has loaded and the SPClientTemplates object is ready to be used. This is essential to prevent our script from executing before SharePoint is ready.
  • Line 9 registers our template object with the SharePoint CSR engine

Refreshing at this point will still not apply anything since we did not provide any Templates just yet.

Continue?

Everything is in place for us to provide some actual CSR templates, but in order to do so we need to understand what templates are even available and how to use them. So, check out the next post in this series:

Benefits of Client Side Rendering

Applies To: SharePoint 2013, 2016, Office 365

List View Client Side Rendering Primer: 2 of 5

About This Series

This series provides a brief overview of Client Side Rendering for List Views (often referred to as JSLink). Basic extension points and examples are included. The goal of this series is to get developers unfamiliar with this programming model quickly up to speed.

XSLT Alternative

Extensible Stylesheet Language (XSL) is the XML based language used to transform XML generally into either HTML or XML. XSL Transformations (XSLT) is the set of XSL templates to be used in specific transformations.

Benefits

  • Rendering performed Server-Side
  • Very Fast
  • Generally, great caching
  • Many traditional SP developers already have XSL knowledge

Limitations

  • Difficult to learn
  • Out Of The Box (OOTB) examples are overly complex
  • Impossible to debug
  • SP limits use to XSLT 1.0 which, even with the ddwrt functions, is not equivalent to the power of XSLT 2.0+
  • Office 365’s server distribution model negates many of the caching benefits seen in on premises versions (although still fast, large datasets and complicated transforms suffer from more performance issues in the cloud)
  • Non-XSL integrations (JavaScript, CSS, etc.) can be very difficult

XSLT is continuing to be supported (and even improved) in current versions of SharePoint. Many of the OOTB features continue to take advantage of it and there is little alternative in SharePoint 2010/2007.

XSLT continues to be an easy way to make minor tweaks to OOTB rendering. Additionally, there is no reliance on end user technologies (JavaScript and, depending on the complexity, modern browsers) since the rendering is performed on the server before being delivered to the client.

 

Client Side Rendering Benefits

  • Data retrieved Server Side
  • “Faster” page loads since only the data and the formatting logic is downloaded to the client and the markup is created there. Practically speaking, standard pages will not see much benefit from this.
  • Rapid development (debugging, simplified templates, etc.)
  • Many more JavaScript developers
  • Flexible Targeting
  • Easy integration with web services, JavaScript frameworks, etc.

Client Side Rendering Limitations

  • Potential for flashing based on client performance
  • Not fully supported – Display templates are used in some search web parts, but only the XSLTListView web part provides the JS Link property
  • Targeting multiple list views on the same page requires fragile or hacky workarounds

csrShim

csrShim is an open source solution that fills the gap of many of the limitations presented by OOTB client side rendering.

csrShim is an XSLT solution that can be used to:

  • Enable JSLink CSR with Content by Query web parts
  • Enable JSLink CSR with XMLViewer web parts supporting RSS, RDF, Atom, and Atom2
  • Can be easily extended to enable JSLink CSR with XMLViewer web parts and custom XML
  • Solve the multiple list views per page issue through simple parameter configuration

csrShim is available through GitHub at:
https://github.com/thechriskent/csrShim

jslink-pronunciation

Continue?

Alright, now you know why CSR is usually better than its predecessor, XSLT. You’ve gotten a small introduction to csrShim (although not required in any way for this series, the methods and techniques discussed for list view CSR will apply there too).

“CSR sounds awesome!!”, you scream. Well, since you’re super excited to give this thing a go and avoiding eye contact with your coworkers is probably a good idea right now, head on over to the next post in this series:

An Introduction to Client Side Rendering

Applies To: SharePoint 2013, 2016, Office 365

List View Client Side Rendering Primer: 1 of 5

About This Series

This series provides a brief overview of Client Side Rendering for List Views (often referred to as JSLink). Basic extension points and examples are included. The goal of this series is to get developers unfamiliar with this programming model quickly up to speed.

Introduction

Client Side Rendering (CSR) is a technology that provides extension points (templates) that use JavaScript to render the data to a SharePoint page. CSR is often referred to as JSLink in reference to the list view web part’s JS Link property. However, CSR can be used for far more than just rendering list views (although this is the most common use and the focus of this series).

Client Side Rendering was introduced with SharePoint 2013 and is fully supported in SharePoint 2016 and Office 365.

A Selective History of Drawing Data in SharePoint

sp-drawing-data-history

SharePoint 2007 incorporated the use of XSLT 1.0 to render list views through XML based web parts such as Content by Query web parts (CQWP) and DataView web parts (DVWP). This allowed developers to customize the display but required specialized knowledge, was very difficult to troubleshoot, and was very poorly documented. This approach is still available in all current versions; however, the usage is not generally recommended.

SharePoint 2010 brought several improvements to XSLT support and Microsoft embraced community sourced documentation. The most important introduction was the new XSLTListView web part that simplified individual list view display and provided a simpler (single stylesheet) usage of XSLT. The XSLTListView web part is still the recommended approach in 2010 and continues to be valid in all current versions.

SharePoint 2013 introduced Client Side Rendering. The primary focus of Client Side Rendering was on pre-defined display templates but an additional property was added to the XSLTListView web part, JS Link, that allowed the easy incorporation of JavaScript files wherever the list view was rendered. This allowed a more web standards based approach and opened the technology up to non-traditional SharePoint developers.

SharePoint 2016 (and Office 365) have not brought much more for Client Side Rendering. XSLT performance was improved illustrating their understanding of the wide usage of that technology still going forward. However, with the introduction of the new SharePoint Framework (SPFx), many use cases for CSR may be replaced. However, only the web part customization piece of SPFx has been released and only in Office 365 at the time this post was written. However, Microsoft has indicated that the framework will cover many of the other traditionally display template focused areas as well.

JSLink vs Display Templates

At a high-level, CSR can be broken down into two categories: JSLink and Display Templates. Although it is a bit of a misnomer to refer to them separately, the general usage of these terms can be defined as:

  • Display Templates
    • Templates used in Web Parts using Search
  • JSLink
    • Property on XSLTListView web parts
    • JavaScript files used for CSR

Display templates actually refers to predefined JavaScript associations with fields, lists, views, contenttypes, forms, and search results. In practical use, however, you’ll generally see these referred to as JSLink even though JSLink is only for the property association.

The focus of this series is on the use of JSLink in XSLTListView web parts.

Continue?

Now that you know the basic terms and have an idea of what this CSR/JSLink stuff are, it’s time to find out why you should use it. Check out the next post in this series:

Fixing Access Denied Issue with Adding Images to your Site Feed

Applies To: SharePoint 2013

The SharePoint Site Feed can be an easy tool for quick discussion and sharing (especially if you don’t have Yammer) and is included in several site templates by default. I ran into an issue that surprised me when attempting to post a reply. I had no trouble posting links and messages, but trying to add an image (clicking the camera icon) gave me an Access Denied error. Huh?

Turns out this isn’t an issue with the user’s account but rather with the App Pool Identity account. Taking a look at the documentation for Site Feeds and you’ll see this sentence:

“In SharePoint Server 2013, we recommend that the same service account be used for both the My Site host web application and the web application hosting the team sites.”

Well, crap. Turns out that I used different app pool accounts for the My Site web application vs my standard web application. So do we need to switch one or the other? Nope! Thankfully, I came across this helpful bit of powershell that will fix this issue for you:

$wa = Get-SPWebApplication "http://my.wirebear.local"
$wa.GrantAccessToProcessIdentity("wirebear\SP_Pool")

You’ll need to run this from the SharePoint Management Shell or use the Add-PSSnapin Microsoft.SharePoint.PowerShell command.

The first line gets the web application where your My Sites are hosted using the Get-SPWebApplication command. Obviously, you’ll need to specify your My Site host web application’s URL or name (instead of mine).

The second line is where the magic happens. The GrantAccessToProcessIdentity method grants permission to the specified App Pool account (use the service account running your problem web application’s app pool).

That’s it. No need to reset IIS or anything else. Just refresh the page with Site Feed on it and now you can upload photos. Here’s one to get you started:

581669_10200896834489112_601749778_n

Autosave in Visio

Applies To: Microsoft Visio

Did you know that unlike EVERY OTHER Microsoft Office program, Visio does NOT have autosaving turned on by default? If so, you probably found out the hard way like me.

Making Visio diagrams comes up pretty often when documenting workflows, server configurations, etc. Each of these diagrams always takes me far longer than it should and losing one that I have been working on makes we weep uncontrollably naked in the corner for 4+ hours. Here, I made a diagram:

Autosave Diagram

 

Generally I’m slapping Ctrl-S like it’s a gopher in one of those gopher slapping games or in some other situation where frequent slapping occurs. But for whatever reason when I’m trying to get those lines perfectly aligned to the grid or I’m making minor font tweaks, etc. I tend to lose my rhythm. Then if an errant update, a crash, or me dumbly closing the wrong window while ignoring the warning dialogs puts an end to my precious diagram, I go searching for the auto recovery files just like I would with Word or Excel.

But if you haven’t manually configured this, they are no where. All you’ll find in your AppData folder are shape caches and regret.

Turning on Visio Autosave

These instructions are for Visio 2013 but should generally work for 2010 and 2016 as well.

  1. Open Visio
  2. Click the File tab/menu in the upper left
  3. Choose Options
    FileMenu
  4. In the Options dialog, choose the Save section from the navigation on the left
  5. Check the box next to Save AutoRecover information every X minutes
    SaveOptions
  6. Click OK
  7. Reap the benefits of lower blood pressure

I’ve set mine to 5 minutes since I’m extra paranoid (The standard setting for other office programs is 10 minutes).

Go do this before you forget. It’s too late for me, perhaps you’ll do better.

post-36423-earn-this-gif-earn-it-Tom-Hank-nFkP