Create non group attached Modern Team Site collection with Flow – Team site (no Office 365 group)

Creating a  site collection with Flow is not straightforward

The intention is to create a “Team site (no Office 365 group)”  – a modern teams site that does NOT have a corresponding team – the client wanted to group using Teams by client name and then have each project be represented by a channel – more on that another time.

createsitecollection

Flow Action: Send HTTP request to sharepoint

Site address:  https://tenant.sharepoint.com

Method:Post
Uri: /_api/SPSiteManager/create
Headers:

Accept: application/json;odata=none

Body:

{
“request”: {
“WebTemplate”: “STS#3”,
“Title”: “@{variables(‘ProjectName’)}“,
“Url”: “https://tenant.sharepoint.com/sites/@{variables(‘ProjectName’)}“,
“Description”: “test”,
“Classification”: “”,
“Lcid”: 1033,
“ShareByEmailEnabled”: false,
“Owner”: “i:0#.f|membership|Admin@mycompany.com
}
}

Site address needs to be your main tenant url (not the admin path)

Text in blue is obviously referencing variables in the flow or needs to be updated with your values

The Web Template is

  • non-group associated Team Site: STS#3
References here

Show Description on Modern SharePoint Document Libraries

Build an application extension as per the tutorial Build your first SharePoint Framework Extension

Install sp-pnpjs and include this import line

import pnp from "sp-pnp-js";

Replace the class content as follows

/** A Custom Action which can be run during execution of a Client Side Application */
export default class ListPropertiesApplicationCustomizer
  extends BaseApplicationCustomizer {
  @override
  public onInit(): Promise {
    this.getList();
    return Promise.resolve();
  }
  public getList(): Promise {
    //get the ID of the list from the page context
    const listId: Guid = this.context.pageContext.list.id;
    console.log(listId);
   
      pnp.sp.web.lists.getById(listId.toString()).get().then(r => {
        // the list object properties are all returned as per the object model
        console.log(r.Description);
        //Find the list title element using native typescript 
        var parent = document.getElementsByClassName("StandaloneList-title");
        //create a new div
        var newDiv = document.createElement('div');
        //style the new div as you wish
        newDiv.setAttribute("style", "color:red; border-bottom: 1px solid blue; font-size:14px; ");
        // add the decription content
        newDiv.textContent = r.Description;
        //append to the document under the list title
        parent[0].appendChild(newDiv)
      });   
    return Promise.resolve();
  }
}

The styling and the placement is up to you.

 

SharePoint Designer 2013 Workflows – How to get Task Process ID

A recent project needed several task management workflows, which meant exploring the pros and cons of each option in SharePoint designer.

Using the “Start Task Process” has the benefit of the workflow being aware of the outcome and “waiting” until the task process is complete. this means you can easily act upon the result, approve or reject, later on.

However you cannot easily get to the other task fields, or the ID, if you need to add extra data. The “Start Task Process” only returns the outcome as a variable but the biggest issue is that the workflow does not progress after this task has been created, it waits, so leaves no chance to update it before completion.

The solution
The workflow needs to perform some actions in parallel, sort of, and a “HTTP Web Service Action”.
The web service can get the ID of the latest Task by using the following URL

[%Workflow Context:Current Site URL%] /sites/mySite/_api/web/lists/getbytitle('tasks')/items?$top=1&$orderby=Id%20desc

Using this URL in a “Call HTTP web service” to return “ResponseContent”

The next action is get item from dictionary

Get d/results(0) from Variable: ResponseContent (Output to Variable: ResponseContent )

Following with this

Get Id from Variable: ResponseContent (Output to Variable: TaskId )

This can only work if the workflow runs in a parallel block but with a tweak to run slightly after – this ensures the task item is definitely there.

Setting up the call web service can be done in this way

Do the web service setup steps as normal then add a parallel block

Add and configure start task process into it

The following actions will run in parallel:
 Start a task process with Variable: Region (Task outcome to Variable: Outcome1 )

Then add an If block

If Current Item:ID is greater than 0

This allows a run of actions sequentially (but still in parallel to the task). Without this the next steps would all trigger at the same time.

Add a pause before continuing just to ensure the task IS created

 Pause for 0 days, 0 hours, 1 minutes

Then call the web service

Call [URL]... HTTP web service with request (ResponseContent to Variable: ResponseContent |ResponseHeaders to responseHeaders |ResponseStatusCode to Variable: responseCode1 )

Manage the results

Get d/results(0) from Variable: ResponseContent (Output to Variable: ResponseContent )
Get Id from Variable: ResponseContent (Output to Variable: TaskId )

You can then update an item in a list using the newly found TaskId

After that you can continue outside of the parallel block and wait for the task to be Completed.

Activate SharePoint site features using CSOM and javascript

In order to activate a feature via the client side we simply have to know the GUID of the feature.

If this is a site scoped feature this is pretty straight forward.

The following can be run from a script editor webpart;


var featureCollection;
var oneFeature;
var site;
var guid
function findFeatureId() {
var clientContext = new SP.ClientContext();
site = clientContext.get_web();
clientContext.load(site);
featureCollection = site.get_features();
clientContext.load(featureCollection);
clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}
function onQuerySucceeded() {
var listEnumerator = featureCollection.getEnumerator();
var featureInfo = '';
while (listEnumerator.moveNext()) {
oneFeature = listEnumerator.get_current();
featureInfo += 'Feature ID: ' + oneFeature.get_definitionId() + '\n';
guid = oneFeature.get_definitionId();
}
alert(featureInfo);
}
function onQueryFailed(sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

We can then use the GUID found with the next function


function activateFeature(rawGuid){
//get contextr of newly created site
var clientContext = new SP.ClientContext($site_url);
web = clientContext.get_web();
//Activate Features
ActivateWebFeature(web);
function ActivateWebFeature(web){
//trinedy branding feature GUID
var guid = new SP.Guid('{'+rawGuid+'}');
var featDefinition = web.get_features().add(guid, true, SP.FeatureDefinitionScope.farm);
}
}

This is especially useful when running with a function that manages site creation.

CSS for InfoPath forms – The best way to style InfoPath forms for Mobile

Infopath forms in SharePoint have some weird css styles when inspected.

There area number of ways to include css (see this link: Add-a-Custom-Style-Sheet-to-a-View.aspx) but they are limited by the weird, and what appears to be, computed class names.An example

This is really frustrating when trying to target specific elements, nobody wants to write css with that!!

I find embedded form web parts to be the best way to include Infopath forms in Sharepoint and they allow some external manipulation – such as query string integration and filtering – and also enable easier styling on the rendered objects via a script editor webpart.

Script Editor webpart

An interesting problem raised its head – making InfoPath forms ready for mobile & tablet and finger friendly – the multi choice selection boxes have very little in way of styling that you can access, just padding, font size, borders… The lines are too close together and the checkboxes are too small.

Sadly these boxes don’t have a nice targetable name, they are part of a fieldset in a stupidly named div, so we can’t easily specify what to manipulate and just chuck in some css. We also want to change all the checkboxes throughout the form not just one field.

We can however use attribute selectors in CSS = [attribute$=value]

See here for more info http://www.w3schools.com/css/css_attribute_selectors.asp

Simply add the following code to the script editor webpart and bingo… finger friendly InfoPath


<Style>
input[type="checkbox"]{
padding:5px;
height:25px;
width:25px;
}
</Style>

Easiest way to read ULS log error with Correlation ID

Easiest way to read ULS log error with Correlation ID

Simply run this in Powershell and replace the GUID with the one presented


$guid = "d17a4766-5115-4be4-8138-9962885912bc"
Get-SPLogevent starttime (get-date).addminutes(-65) | ?{$_.Correlation -eq $guid} | select Message | Format-table property messageautosize

SharePoint and web UI Elements

Came across ​something I saved a while ago from a Quora response to the question…

What are the some of the most interesting UI elements of recent times?

The majority of these suggestions that I have included were provided by Stephen P Anderson

You can read the rest of the answers here, lots of them refer to styling and I wanted to focus on interactions mostly.

I didn’t compile this list, I have removed a few but I’ll try to state my view on how as as SharePoint dev they might be well utilised, especially given the freedom the app model affords us.

  • “Sticky” headers/sidebar content – critical elements stay fixed as you scroll down the page (the way the GMail header stays fixed as you scroll through an email, lots of “share” functionality on blogs/magazines stays with you as you scroll down the page). See also http://fab.com/inspiration/ main nav. The text formatting options in Quora and Basecamp Next stay with you as you write longer posts.
  • Responsive layouts. ‘Nuff said about this! (well device channels aren’t gonna cut it – stick RWD in your branding)
  • Direct manipulation of objects (vs toggling between CRUD states). See how minutes.io puts you directly into the meetings page.
  • Web fonts – especially more humanistic/geometric typefaces like Proxima Nova, Museo Sans, and (soon) Gotham. See http://www.fastcompany.com/
  • More “discoverable” controls (for better “cleaner interface” or worse “how do I do x…!?”); the Metro UI from Microsoft is able to produce cleaner screens because secondary elements are “hidden” in corners and edges (see:http://msdn.microsoft.com/en-us/… ) We’re all used to this in the ribbon so embrace this technique)
  • Appropriate use of 3D effects – see http://selection.datavisualization.ch/ which are not too hard to achieve and can add richness
  • The ‘+’ that changes to an ‘×’ (and vice versa) – see Path mobile app,http://www.teehanlax.com/work/ (sidebar navigation), and invoicemachine.com (adding/deleting an invoice)
  • Drop down options loaded with information and even pictures (modern drop downs often aren’t based on an actual UI drop down controls). we’ve all come across mega dropdown menus for navigation but including controls or extra content in your app can mean a much better UX flow
  • Bigger type sizes, hit areas, buttons and white space – so that Web apps might also be touch friendly w/o a lot of refactoring – we all know this is going to be useful
  • Options that resemble “cards” (think Pinterest.com and all the clones) – I can see this being a great technique for showing search result content, much richer for certain uses than a standard results list. We are now seeing this for people search and it’s a welcome development.
  • A move away from noticable gradients and drop shadows (still used, just in a much subtler way)
  • “Fake” drop shadows or borders – the ultralight 5 pix shadow that doesn’t “fade” away (Google apps do this a lot).
  • “As you need it” functionality – instead of functionality being exposed by default, it’s presented in a series of sequenced moments (clicking on “add a comment” link or box turns into expanded box with more options, OR rating something exposes a comment field – contextual and reactive based upon a users actions
  • Direct manipulation of default data, vs wizards to set things up
  • Auto save functionality (vs big “Save” button)
  • More drawers and slideouts from the top, bottom and edges. Similar to mega drop down menus but some different directions!
  • Inline expanding areas for additional information/actions – the SP “grouped by” list views are a good example, gives the users a broader view and the option to expand to see detail.
  • Very, very subtle textures, to draw light contrast that guides the eye through a page. See http://subtlepatterns.com/ as a resource for these. See Pinterest, Basecamp Next, and Branch.com as examples of sites with this subtle background that draws your focus to the content (focus area)
  • Flat, monochromatic, small icons for common actions. Seehttp://twitter.github.com/bootstrap…
  • Search boxes that “expand” (width) on click – great idea
  • “Kiosk style” buttons – rather than present 4 radio buttons options, sites opt for the more visual display of text in rounded corner boxes (which actually aids in spatial recall and creates a bigger hit target) – currently revamping an InfoPath form to reflect this,
  • Conversational UIs – rather than a form label and drop down, you see a phrase with the drop down options worked into that phrase. For an extreme example of this (and the “kiosk style” buttons mentioned above). The enterprise can be a dull place, perhaps conversations can change that.

More general patterns:

  • A move away from tabbed navigation (in Web apps). This follows the “focus on content, not chrome” argument put forth by folks like Luke Wroblewski. Not sure about this one – well designed tabs can be great for complex forms.
  • More white space, padding (for reasons of touch, see above)
  • Bauhaus, minimalist design – Google redesign, Microsoft, Amazon redesign (header area); this “minimal” styling uses grays or desaturated colors, so that when a bright color is used, it’s used to draw attention.
  • Single page apps – lots of different “states” on a single page no longer feels like moving through linked “pages”
  • Very open layouts – less boxes and more lines/spacing to visually group areas; boxes still used on core content, but not as much for chrome/layout
  • Single column layouts – less distracting and mobile ready
  • More friendly, conversational language around form elements
  • Content being given proper information design treatment (varying type sizes, caps, shading, etc. to aid in understanding.

When dealing with almost every user-centric project in SharePoint there is some consideration of UX and not just the technical challenges we face. The interactions we design have a great impact on a projects success, and in turn a users satisfaction, and we almost always need to consider how broad the user base is going to be.

This means that employing patterns that are established and proven to be successful must surely help. With that said I think the web community create good trends based upon success so new styles are always evolving and we can help ourselves within the SharePoint platform by being more like the innovators on the wider web.

Hope you find this interesting.

Thanks

Ryan

Office365 and InfoPath – GetUserProfileByName is not available – a solution

Whilst working on client project recently that involved InfoPath within Office365 I immediately wanted to use a commonly employed technique with previous projects – using the GetUserProfileByName web-service to obtain the users first and last name.

There are a number benefits to doing this, especially when the project inevitably involves workflow, custom library views, webparts etc to have a personalized experience for the user. For this specific project we needed to get the user of the form within the document as they were to form official standalone documents (as in out of the SharePoint document library context).

Unfortunately there is a BIG limitation…

“This issue occurs because loopback protection is enabled in the SharePoint Online environment. Loopback protection must be disabled for InfoPath forms to be able to connect to a SharePoint Online web service.

Any time that you make a call to the same server from an InfoPath form, the requests to loop back. This works only when loopback protection is disabled. For security reasons, loopback protection is always enabled in SharePoint Online. This is a known limitation of InfoPath forms in the Office 365 SharePoint Online environment, and there is no workaround for this issue.
Here is the article for your reference: http://support.microsoft.com/kb/2674193

So we need another way to get the user data from within Office 365 and into the InfoPath form and I devised the following solution:

The overview is as follows

  • an InfoPath webpart
  • a query string filter connected to the InfoPath webpart
  • a javascript file to add the query string parameter

Now I had to provision a page with the Infopath webpart and a few other connected webparts

I then needed to get the InfoPath form to react to a query string filter webpart

Passing Parameters to Infopath – By Tomasz Szulczewski

Next I added some JavaScript via a script editor webpart to read the current user name from the user profile service view CSOM

I used some of the script from Kit Menke’s blog here http://kitmenke.com/blog/2013/10/31/pass-user-information-from-sharepoint-2013-to-infopath-2013/

I simplified his script to just read the current user via “get_title()” and then pass this to the “window. location”

This redirects to a url with a query string parameter “CurrentUser” with this value

…aspx?CurrentUser=Username

making sure to redirect only if the string “CurrentUser” is missing from the url. See the “check” statement…


function CustomExecuteFunction() {
var self = this;
self.context = new SP.ClientContext.get_current();
self.web = context.get_web();
self.currentUser = web.get_currentUser();
context.load(self.currentUser);
self.asyncSuccess = function(sender, args) {
var user = this.currentUser;
console.log('asyncSuccess', user);
loc = window.location.href;
check = loc.indexOf('CurrentUser');
if(check <0)
{
// if not the redirect with appended query string
window.location= loc + "?CurrentUser=" + user.get_title();
}
};
self.asyncFailure = function(sender, args) {
alert('Request failed. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
};
// actually fires off the AJAX request
// more info: http://msdn.microsoft.com/en-us/library/dn168907.aspx
context.executeQueryAsync(
Function.createDelegate(self,self.asyncSuccess),
Function.createDelegate(self,self.asyncSuccess)
);
}
ExecuteOrDelayUntilScriptLoaded(CustomExecuteFunction,'sp.js');

So I now had the current user in the url and the query string filter webpart reading the value and passing this to the InfoPath form field – I then had a people picker field read this value and bingo I could interact as if the original query was there.

Hope this helps someone else.

Thanks

Ryan