Office 365 Saturday 2015 - Melbourne

I visited sunny Melbourne (so strange!) for Office 365 Saturday last weekend, covering PhantomJS and SharePoint.  We also geeked out in general around the lunch desk and debated the direction of Add-Ins and the future of SharePoint development.

It was so good to see many of the locals turn up - familiar faces and new faces.  We geeked out on PhantomJS and why you need to know about this tool for your toolbox, even if you don't need it right now.

We then flowed onto Colin's session on making a million dollars (in progress) in the App Store. 

Downloads to my presentation and zip files.

Melbourne was so enjoyable.  I had to leave early to catch my flight home.  Next stop is Adelaide:

Office 365 Saturday Adelaide - 12 September 2015

http://www.o365saturdayaustralia.com/adelaide

Fixing SharePoint Promoted Link's New Tab Launch Behaviour

There's a bug with Promoted Links web part in SharePoint 2013 and Office 365, and I have no idea how long it's been there.  This post is about a simple Javascript hack that will fix it.

Story

Robert Crane [O365 MVP] found this one.  Out of the blue, he asks me, hey why does the new tabs always open in the same tab.  I thought, no way, it's always been working.  So naturally, I tried it out and check the anchor tag.  Expecting target="_blank"

TLDR

  • Promoted Links spits out target="="_blank"" for who knows how long.
  • Here's a fix.

SharePoint's Promoted Links Web Part

A quick introduction - this is the Promoted Links web part.  If you have seen SharePoint 2013 or Office 365's SharePoint Online, then you have seen this web part.  It is used everywhere for navigation.

Promoted Link is backed by a regular SharePoint list.  Of interest, is the Launch Behavior column, which lets you decide what to do when a tile is clicked.  You can navigate there Replacing Current Page, open in SharePoint's ModalDialog, or open in a New tab.

Open in New Tab

To prevent spammers running Javascript and creating lots of tabs when you visit a page, a browser gives no way for Javascript to create new tabs.  The only way to do this, is natively in HTML, the tag looks like this:  <a href="http://bing.com" target="_blank">B</a>

SP2013 (and Office 365) spits out this:

What would this do?  Because target="="_blank"" is not a name that the browser knows about, it thinks, ah you want a new tab target, with that name.  So the first click is OK, you navigate to that URL in a new tab.

The problem is that if you click multiple Promoted Tiles, they will all be loaded in the same tab, instead of different new Tabs.

IE11 seems OK

Curiously, IE11 creates new tabs.  This however doesn't work on Edge.

Culprit

There seems to be a bug in sp.ui.tileview.js, adding target= into the attribute.

 

Fix

This can be fixed with a small bit of Javascript.

Edit the Page where your promoted list is giving you trouble.  Say the Home Page.  Insert "Embed Code" in a Web Part zone at the bottom of the page.  (This short cut creates a Script Editor Web Part there)

Paste this bit of script.

<script language='javascript'>
function fixATargetBlank(){
    // using sharepoint's mQuery because I don't want to have
    // dependency on jQuery in this quick script
    m$("a[target][clickaction]").forEach(function(a){a.target="_blank";});
}
// add this function to tell SharePoint to run it on load
_spBodyOnLoadFunctionNames.push("fixATargetBlank");
</script>

The Script Editor will appear blank.  That's OK.  Save the page.

Result

The target is fixed to _blank.  And clicking on the promoted links now opens them in separate new tabs, in all browsers.



PhantomJS and Office 365 Brisbane

I thoroughly enjoyed my trip up to Brisbane.  I got to see some friends, saw my sister and presented PhantomJS with SharePoint and SharePoint Online.

 

The response was tremendous, those that came to my session seems really interested and gave me more ideas for future discussions. 

The presentation and demo are here

The new business case scenarios:

  • Automated Smoke Testing of sites - randomly check pages and DOM exist - "nothing has so far blown up"
  • Smoke Testing of sites with different credentials!
  • Scanning and scrapping text off dynamic (Single Page Application) pages and feed them to SharePoint's Search Indexing Service.  Thus, you can have textual search linking back to dynamic URLs.

I also really enjoyed Elaine's session on SharePoint 2016.


The next Office 365 Saturday in Australia will be in Melbourne.  The registration is up here:

http://www.o365saturdayaustralia.com/melbourne

Clearing SPD Cache from SharePoint Designer

Our good old friend SharePoint Designer is old, but I still find it useful for editing JavaScript files in development for quick tests.

Because SharePoint Designer caches what it thinks the site's contents look like, sometimes, this cache gets out of date with reality and you will see issues when SPD thinks you have some files checked out, but you don't.

And in the past, I would go and Bing and search "clear SharePoint Designer cache" and this will net you:

So there's no shortage of finding the command to clear the folder.

Until Today

I came across this part of the SPD UI by accident.

  • Select Home in the current site. 
  • Go to Site Options.
  • Select Advanced Tab
  • Click Delete Files (temporary files)

You will see that any currently Opened Folders views will be empty. 

As the cache for the site has been dumped.  You need to refresh from the Ribbon Bar and you'll see the status of the items has updated correctly.

SharePoint Designer 2013

The same UI exists for SharePoint Designer 2013 as well.

No more command line, perhaps.

Let me know in the comments if this was something you've ALWAYS known about, or whether it also made you feel foolish that you've been using the command-line or deleting cryptic user profile temporary folders for years, literally.  When there's a button that does this for me.

 

Moving Everyone and Everything to AngularJS

We are late on the boat.  But I'm describing the journey for us, and we are truly on the boat.

 

So in mid 2014, SharePoint Gurus decided that we'll move everyone to JavaScript.  Traditionally, we are very much an InfoPath, Workflows and Configuration-over-Customization type of Consultancy.

My background is hardcore ASP.NET so I get all the fun stuff of writing Full Trust and Sandbox Solutions.  Custom Web Parts, Feature Receivers and Workflow Activities.  Later, as more work moves to client-side scripting, I would write Full Trust REST service end-points that provide lots of functionality to our InfoPath and Front-End Developers.

As InfoPath goes on a slowly (but surely) spiral of death, we look forward to where we should be investing our company's time and skills.  I was asked to consider and plan out the migration path for the company.

What we looked at:

JQuery

JQuery itself was a good starting point, and possibly the simplest JavaScript library one should start with.  Traditionally, it's used for DOM manipulation, but it's usefulness was extended with jQuery Ajax and jQuery Deferred/Promise.  We use JQuery and the various plugins for JQuery for a lot of things.  Additionally, JQuery works very well with SPServices on SP2007 customizations.

KnockoutJS

KnockoutJS is a DataBinding library.  JQuery is great for creating Read Only, One-Way DOM creation (say, you query an REST end point and want to create a bunch of elements in a table or list).  But JQuery is terrible at keeping track of the UI and the Original JavaScript object for you to post that data back.

KnockoutJS fixes that problem.  The good side is that it's intuitive.  The downside is that because JavaScript properties doesn't have onChanged() method, KnockoutJS creates observable property wrappers instead, and the syntax is not as pretty.

DurandalJS

Since KnockoutJS is only a databinding library, when you want to start looking at creating Single Page Applications, you need more stuff.  You need a Module Loader.  You need a Routing System.  And you need View Composition.

Durandal uses KnockoutJS for data binding, and adds RequireJS for module loading and JQuery for AJAX calls.

Although I loved DurandalJS, ultimately I could not recommend it to the whole company because the creator Rob Eisenberg (@eisenbergeffect) moved to AngularJS (and later to Aurelia.io).  I am keen personally on Aurelia, but it is not ready to introduce to the whole company in 2014.

ASP.NET MVC

I personally LOVE ASP.NET MVC.  But here's the problem - we have developers who are used to ASP.NET WebForms, so for them there are two jumps: first they have to learn ASP.NET MVC and then they still have to learn JavaScript.

JavaScript is required learning.

And ASP.NET MVC needs SharePoint Provider-Hosted apps - we can't, for example, use it with SharePoint 2010 or SharePoint 2007.

We have not turned our backs to ASP.NET MVC forever, it's just for the immediate focus, we are fully committed to client-side (Front-End) development technologies.  A few of our advanced guys will double back and pick up ASP.NET MVC later (or NodeJS).

AngularJS

All choices aside, we decided on pushing forward with AngularJS.  For many in the team, they have experience with JQuery but not DurandalJS nor KnockoutJS - so there's not a lot of wasted learning.

For me, I always compare AngularJS to DurandalJS and the biggest issue I have personally is that AngularJS is...  too magical.  UN-intuitively magical.  There are a lot of very custom syntax that you just have to know.  If you didn't know, you wouldn't know it's available.  But if you are looking at someone else's work, you can generally work backwards and understand Ah that's how it fits.  I wish it was more intuitive.

The biggest advantage for AngularJS is just how much community momentum there is for it.  There are a lot of people that understand it well, and lots of people building applications with it, and discussing it on the Internet - anywhere you look.

Additionally, lots of AngularJS and SharePoint / Office 365 training is available online.  Which means that we don't have to re-invent every wheel.

As a company and for our teams, it is a very safe bet.

There are a few related technology in the stack that we are using:

Bootstrap and Font-Awesome both give the front-end developer two things:  Rapid layout and font-glyphs without mucking around outside of the HTML templates and JavaScript code.

AngularJS + TypeScript

Since AngularJS announced that it will be built in TypeScript, there has been a resurgence of activity on the TypeScript front.

If your team has a lot of C# developers, TypeScript is worth your time to invest into.  It will make your team more productive, and as a team, you will write much better code.

 

What I did NOT look at:

All that said, there's also a lot that's unsaid.  I did not look into Backbone, EmberJS or Telerik KendoUI.  The main reason really is that I was personally very happy with DurandalJS, and if it was up to me personally, I would have chose Aurelia to go next.  But the evaluation we went through is to decide which framework to pursue for the entire company.

I always consider that we should never stop learning.  In the JavaScript space this is even more true.  Just like back in 2008 we decided (in my previous company) that we will pursue JQuery, in 2014 - we made a similar decision to pursue AngularJS.

 

An Army of Front-End Developers

So as a whole, our team is turning from InfoPath designers into Front-End Developers.  We have mastered JQuery and now diving into the fun that is AngularJS Directives.

 

Aim to have An Army of Full-Stack Developers in the nearby future

Moving towards a proper MEAN stack.  There are other components to tackle next:

  • M - MongoDB (a NoSQL document database suitable for storing XML and JSON)
  • E - Express (a lightweight web server, aka IIS)
  • A - AngularJS (front-end)
  • N - NodeJS (run JavaScript on the server, aka C# or .NET Framework)
  • Everything will have to run Provider-Hosted, most likely on Azure

For now - we are Front-End developers and happy with just the UI and storage of the form contents.

  • A - AngularJS
  • S - SharePoint Library (storage of XML and JSON - can be easily loaded via client-side scripting)

Summary

https://twitter.com/alwaysbetonjs

https://twitter.com/alwaysbetonjs