Tag: Ai
Fast and Predictable Blog Post Summaries with AI
Proofreading blog drafts using Copilot Sidebar
While working on a blog post, I discovered a way to proofread my drafts in an easy way. This might not be very revolutionary, but it was so convenient that I wanted to share it with the world.
I use Hugo for my static website. On my local computer I can preview it in the browser under localhost:1313
. Copilot Sidebar in Edge does the same! This means I can ask it to proofread it.
Prompts and Modelfiles
Prova GPT-SW3
AI Sweden har publicerat den första svenska språkmodellen - GPT-SW3:
I det här inlägget vill jag beskriva hur man kommer igång om man vill testa det. Min setup är följande:
- En MacBook Pro (men det kan vara vilken dator som helst egentligen)
- Python 3.8^ + venv (om det lite senare)
- Visual Studio Code
- Jupyter Notebook Extension till Visual Studio Code
Datoruppsättning
Om inte du har gjort det tidigare, installera Visual Studio Code
Tag: Blog
Fast and Predictable Blog Post Summaries with AI
Proofreading blog drafts using Copilot Sidebar
While working on a blog post, I discovered a way to proofread my drafts in an easy way. This might not be very revolutionary, but it was so convenient that I wanted to share it with the world.
I use Hugo for my static website. On my local computer I can preview it in the browser under localhost:1313
. Copilot Sidebar in Edge does the same! This means I can ask it to proofread it.
Blog Comments are back
I haven’t had comments on my blog since I moved from wordpress. Until now. I just added comments back to my blog and here is how I did it.
The most convinient way is integrating my blog with Github Discussions using giscus.
The giscuss.app page walks you through the setup and authorization process.
I created a new public repository on Github, then I enabled Discussions feature on the repository (Settings -> Features).
New Home for My Blog
Hello World
Now I have moved my blog. chuvash.eu is a static site. I’ll share more details and insights later.
Update 2022-02-10
It has passed a few months since the move from Wordpress to a static site. Now it is time to summarize the insights.
Why I moved
Here are the reasons why I switched from Wordpress.com to a static site
- To be honest, the main reason was that I was curious about static sites.
- It appealed to me to have a fast and secure website (because there is no database that slows down or gets hacked).
- I finally got rid of the annoying ads from Wordpress.com. Don’t get me wrong. I appreciate Wordpress.com, as a matter of fact, I sacrified some really neat functions (such as the comments and the community) when moving to a static, but on that later.
- It finally got free from the vendor lock-in. Now I have all my blog posts as markdown files in a git repository. I can build them to any static website or even consume as they are, no fiddling with a database (if it were a own hosted wordpress site). I find it also easier to collaborate on my blog posts since I can grant access to the git repository to people I want to work together with.
- Speaking of git, now I have real version history of my content, no more accidential deletions.
Well, there might be more reasons, but these are the most important ones.
2012 in review
The WordPress.com stats helper monkeys prepared a 2012 annual report for this blog.
Here’s an excerpt:
4,329 films were submitted to the 2012 Cannes Film Festival. This blog had 54,000 views in 2012. If each view were a film, this blog would power 12 Film Festivals
Click here to see the complete report.
Comments from Wordpress.com
Justin Cooney - Jan 3, 2013
Tag: GPT
Fast and Predictable Blog Post Summaries with AI
Prova GPT-SW3
AI Sweden har publicerat den första svenska språkmodellen - GPT-SW3:
I det här inlägget vill jag beskriva hur man kommer igång om man vill testa det. Min setup är följande:
- En MacBook Pro (men det kan vara vilken dator som helst egentligen)
- Python 3.8^ + venv (om det lite senare)
- Visual Studio Code
- Jupyter Notebook Extension till Visual Studio Code
Datoruppsättning
Om inte du har gjort det tidigare, installera Visual Studio Code
Tag: Auth
How to use ExternalItem.ReadWrite.Ownedby
Automate Creation of Git Repos Using Azure DevOps API
Today I got a question: how can we precreate 50 git repositories in an Azure DevOps Project? I started to learn about the API in Azure DevOps and I found it very interesting. With the API you can script and automate administration of projects, repositores, pull requests etc. To keep this blog post simple and digestable I would like to focus on the intitial request - creating git repositories by code.
Git Merge develop to main in an Azure DevOps Release
This post is a techy one. It’s about running git commands in Azure DevOps Releases in order to finalize a deployment job to production.
Let me first describe our scenario:
We use Azure DevOps for code and for deployment. Our branch strategy a simplified Gitflow model, where all the current work is merged to the “develop” branch. The code from the “develop” branch is then built and released to staging environments and production. After a release to Production and regression tests the develop branch needs to be merged into the “main” branch (or “master”). So simply put, the git merge into main is what we mean by finalizing a production release.
Tag: Config
How to use ExternalItem.ReadWrite.Ownedby
Tag: Graph
How to use ExternalItem.ReadWrite.Ownedby
How to Read SharePoint Storage Capacity with Graph
Tag: Http
How to use ExternalItem.ReadWrite.Ownedby
Using secrets in Logic Apps in a secure way
This is a guide for how to handle secrets in a logic app in a secure way. It combines three resources:
- Accessing Key Vault from Logic App with Managed Identity
- Get Secrets Key Vault API
- Hide your logic apps secrets from prying eyes
First, enable a Managed Identity for your Logic App:
In the KeyVault, add a new Access Policy for the new Managed Identity (from the previous step). Use the least priviliges. In my case it is just enough with GET for secrets.
Tag: M365
How to use ExternalItem.ReadWrite.Ownedby
Monitoring Microsoft 365 using Raspberry Pi and M365 CLI
I would like to show you my recent hobby project with a raspberry pi, a unicorn phat and the powerful cli-microsoft365: A simple monitoring solution of Microsoft 365 Services.
Status of some important services in Microsoft 365
In essence, I put the unicorn phat onto the raspberry pi zero w and wrote this python script:
The python script checks the service status every five minutes and shows it with colors on the unicorn phat.
Is an M365 Group a Yammer Community
Nowadays a Yammer Community gets a corresponding Microsoft 365 Group (Office 365 Group, Unified Group). In your work as an SPO Admin, you might need to differentiate “ordinary” Modern Team Sites from those ones that were created for a Yammer Community.
They both have GROUP#0 as Template. On the actual SPO Site object, there is nothing that you can use to differentiate those. Neither you can use the Office 365 Group information. But there is a way: if you connect to Exchange Online and get the group from there, then there is something useful.
Tag: Patch
How to use ExternalItem.ReadWrite.Ownedby
Tag: Search
How to use ExternalItem.ReadWrite.Ownedby
Add Search Verticals by code
Adding own search verticals is a common task in the Search Configuration in SharePoint. Here I want to share a code sample for achieving this programmatically. I hope, this model can be added to SPMeta2. First of all, Search Verticals are dedicated Search Results Pages and links to them. How to add them manually is described on technet:
There is no API in CSOM for that. Luckily, Mikael Svenson found how to get the Search Navigation and contributed to PnP by writing an Extension: web.LoadSearchNavigation. Here is my sample code for adding new Search Verticals programmatically: [source language=“csharp”] NavigationNode searchNav = context.Web.Navigation.GetNodeById(1040); NavigationNodeCollection nodeCollection = searchNav.Children; NavigationNodeCreationInformation everything = new NavigationNodeCreationInformation { Title = “Everyting”, Url = “/search/Pages/results.aspx”, }; NavigationNodeCreationInformation myresults = new NavigationNodeCreationInformation { Title = “My Results”, Url = “/search/Pages/myresults.aspx”, }; nodeCollection.Add(everything); nodeCollection.Add(myresults); context.ExecuteQuery(); [/source]
Resetting SharePoint Search Configuration Cache
Now it is the second time it happens that the search cannot return any results. This hickup is rare but it happens. To solve it I had to follow these steps:
- Stop the Timer Service
- Clear the configuration cache
- Find in \ProgramData\Microsoft\SharePoint\Config the folder where the file cache.ini exists
- Delete every file from this folder EXCEPT cache.ini
- Open cache.ini, delete the content and put ’1′ (without the quotes) in it and save the file
- Restart the Timer Service
- Index reset
- Full crawl
Source: ITIDea. The linked blog post saved my afternoon today. Thank you, Anita Boerboom.
Create your own search box
It is very simple. Create a new module: SearchArea. Delete Sample.txt and Elements.xml. Create a new file: SearchArea.xml
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Control
Id="ContosoSearchAreaBox"
Sequence="15"
ControlClass="Microsoft.SharePoint.Portal.WebControls.SearchBoxEx"
ControlAssembly="Microsoft.Office.Server.Search, Version=14.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Property Name="GoImageUrl">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="GoImageUrlRTL">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="GoImageActiveUrl">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="GoImageActiveUrlRTL">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="DropDownMode">HideDD\_useDefaultScope</Property>
<Property Name="FrameType">None</Property>
<Property Name="UseSiteDefaults">false</Property>
</Control>
</Elements>
Next add your searcharea module to a site scoped feature.
In the masterpage locate this:
<SharePoint:DelegateControl runat="server"
ControlId="SmallSearchInputBox" Version="4" />
and replace with your brand new search area:
Tag: 3d
Remote video monitoring with Raspberry Pi
My Ender 3 v2 3D Printer does not have a webcam to remotely check 3D prints. Sometimes when I am not at home I need to see how things are going. I thought a simple webcam solution would do the trick.
I grabbed my older Raspberry Pi (RPi 2) and set it up as a remote web camera.
Hardware and Software
So here is the hardware I am using:
Vertical Laptop Holder
I just 3D-printed a laptop holder, a vertical one. It is so pretty and it makes my desktop tidier, so, I thought, it deserves an own blog post. This information might be too little for a blog post. So, as a bonus, I’ll tell you how the process of finding and customizing a 3D model looks like.
.
Thingiverse customizer
I found a nice laptop holder on Thingiverse. Then I just clicked on “Open in customizer” like this:
3D-printa en Super Mario-blomkruka
Jag håller på och lär mig lite om 3D-Print på fritiden. Jag berättar om mina första intryck och hur jag skriver ut en blomkruka som ser ut som ett Super Mario-block - allt detta i en bloggpost.
Montering av 3D-skrivaren
Jag behövde montera min 3D-skrivare (Creality Ender 3 v2) och det gick smidigt även om det tog flera timmar. Jag följde denna fantastiska Youtube video: JustVlad: Creality Ender 3 V2 - 3D Printer - Unbox & Setup . Jag fick justera höjden på plattan flera gånger för att hitta ett lagom avstånd. Svårt att förklara, man måste testa det själv.
Tag: 3d Printer
Remote video monitoring with Raspberry Pi
My Ender 3 v2 3D Printer does not have a webcam to remotely check 3D prints. Sometimes when I am not at home I need to see how things are going. I thought a simple webcam solution would do the trick.
I grabbed my older Raspberry Pi (RPi 2) and set it up as a remote web camera.
Hardware and Software
So here is the hardware I am using:
Tag: Ender
Remote video monitoring with Raspberry Pi
My Ender 3 v2 3D Printer does not have a webcam to remotely check 3D prints. Sometimes when I am not at home I need to see how things are going. I thought a simple webcam solution would do the trick.
I grabbed my older Raspberry Pi (RPi 2) and set it up as a remote web camera.
Hardware and Software
So here is the hardware I am using:
Tag: Motion
Remote video monitoring with Raspberry Pi
My Ender 3 v2 3D Printer does not have a webcam to remotely check 3D prints. Sometimes when I am not at home I need to see how things are going. I thought a simple webcam solution would do the trick.
I grabbed my older Raspberry Pi (RPi 2) and set it up as a remote web camera.
Hardware and Software
So here is the hardware I am using:
Tag: Ngrok
Remote video monitoring with Raspberry Pi
My Ender 3 v2 3D Printer does not have a webcam to remotely check 3D prints. Sometimes when I am not at home I need to see how things are going. I thought a simple webcam solution would do the trick.
I grabbed my older Raspberry Pi (RPi 2) and set it up as a remote web camera.
Hardware and Software
So here is the hardware I am using:
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Tag: Raspberry Pi
Remote video monitoring with Raspberry Pi
My Ender 3 v2 3D Printer does not have a webcam to remotely check 3D prints. Sometimes when I am not at home I need to see how things are going. I thought a simple webcam solution would do the trick.
I grabbed my older Raspberry Pi (RPi 2) and set it up as a remote web camera.
Hardware and Software
So here is the hardware I am using:
Tag: Rpi
Remote video monitoring with Raspberry Pi
My Ender 3 v2 3D Printer does not have a webcam to remotely check 3D prints. Sometimes when I am not at home I need to see how things are going. I thought a simple webcam solution would do the trick.
I grabbed my older Raspberry Pi (RPi 2) and set it up as a remote web camera.
Hardware and Software
So here is the hardware I am using:
Tag: Web Camera
Remote video monitoring with Raspberry Pi
My Ender 3 v2 3D Printer does not have a webcam to remotely check 3D prints. Sometimes when I am not at home I need to see how things are going. I thought a simple webcam solution would do the trick.
I grabbed my older Raspberry Pi (RPi 2) and set it up as a remote web camera.
Hardware and Software
So here is the hardware I am using:
Tag: Webcam
Remote video monitoring with Raspberry Pi
My Ender 3 v2 3D Printer does not have a webcam to remotely check 3D prints. Sometimes when I am not at home I need to see how things are going. I thought a simple webcam solution would do the trick.
I grabbed my older Raspberry Pi (RPi 2) and set it up as a remote web camera.
Hardware and Software
So here is the hardware I am using:
Tag: Wifi
Remote video monitoring with Raspberry Pi
My Ender 3 v2 3D Printer does not have a webcam to remotely check 3D prints. Sometimes when I am not at home I need to see how things are going. I thought a simple webcam solution would do the trick.
I grabbed my older Raspberry Pi (RPi 2) and set it up as a remote web camera.
Hardware and Software
So here is the hardware I am using:
Tag: Export
How to export a Penzu journal
I have used Penzu as my main journal app for many years. Recently when Apple launched its Journal app I have been looking at it and other competitors. Then I realized that I am not able to get my own data from Penzu. There is no reasonable Export function.
So I found my own way to get my journal data. I could name this blog post to something like “How to export the unexportable”, or “How to intercept XHR requests in Puppeteer”, but my case is about Penzu, so I’ll stick to this particular title.
Export AppendOnly Comments
Remember the old comments in SharePoint Lists? I am sure there are tons of lists that use the Append-Only Comments. They are implemented using versioning. The problem is that it is hard to export the comments, unless you know the tricks. The trick I want to share comes from a colleague of mine. The reason why we need export all the comments is that we need to document and save/archive the decision making process that took place in the comments field.
Export any web part from a SharePoint page
The blog post below describes the technical details about how Web Parts can be exported using a hidden tool in OOB SharePoint, though this requires manual assembling of a special url. If you are just interested in a solution for an easy Web Part Export function, just proceed directly to my new blog post where you can download my tool that you can add to your web browser.
Export SharePoint List Data To Xml through PowerShell
Today my colleague Johannes Milling wrote an awesome post: Export SharePoint List Data To XML Directly from the GUI He uses the old and forgotten RPC-based web service owssvr.dll (that has existed since SharePoint 2003). This url pattern is used to get the xml-formatted list data for a specific ListView: [source] http://<site_url>/_vti_bin/owssvr.dll?Cmd=Display&List=&View=&Query=*&XMLDATA=TRUE [/source] To automate this I have written a PowerShell function. All the details are in the comments: [source language=“PowerShell”] function Export-OIPSPListDataAsXml { <# .Synopsis Exports list items as xml .DESCRIPTION This function uses a built-in hidden service owssvr.dll in SharePoint .PARAMETER Web SPWeb or a url for the SPWeb object where the list resides .PARAMETER ListName List Name (List Title) .PARAMETER ViewName Name of the List View to export the data .EXAMPLE Export-OIPSPListView -Web http://myawesomesite -ListName “Teddy Bears” -ViewName “All Items” .EXAMPLE Export-OIPSPListView -Web $webInstance -ListName “Top Links” -ViewName “All Items” .Notes Name: Export-OIPSPListDataAsXml Author: Anatoly Mironov Last Edit: 2014-09-11 Keywords: SPList, SPWeb, SPListView, Xml .Link http://chuvash.eu #> [CmdLetBinding()] param( [Parameter(Mandatory=$true)] [Microsoft.SharePoint.PowerShell.SPWebPipeBind]$Web, [Parameter(Mandatory=$true)] [string]$ListName, [Parameter(Mandatory=$true)] [string]$ViewName) $spWeb = $Web.Read() $list = $spWeb.Lists[$ListName] if (!$list) { throw “List $ListName on web $($spWeb.Url) could not be found” } $view = $list.Views[$ViewName] if (!$view) { throw “View $ViewName on web $ListName could not be found” } $url = “{0}/_vti_bin/owssvr.dll?Cmd=Display&List={1}&View={2}&Query=*&XMLDATA=TRUE” ` -f $spWeb.Url, $list.ID, $view.ID $wc = New-Object Net.WebClient $wc.UseDefaultCredentials = $true $wc.DownloadString($url) } [/source]
Formatera export xml av wordpress
Ville spara min blogg som en dagbok för utskrift. Exporterade hela bloggen som xml. Inga problem. Sedan var det dock nästan omöjligt att enkelt skriva in det i Word / OpenOffice. Jag har skrivit en liten css-fil som formaterar det lite så att man kan skriva ut. Lägg till:
<?xml-stylesheet type = "text/css" href="wordpress.css"?>
direkt efter:
<?xml version="1.0" encoding="UTF-8" ?>
Lägg filen “wordpress.com” i samma mapp. Här är wordpress.css
channel title {
font-size:3em;
}
channel description {
color:green;
margin-bottom:1em;
}
item title {
font-size:2em;
font-family:Arial;
margin-top:1em;
}
creator {
color:green;
}
creator:before {
content:"Skrivet av: ";
color:black;
font-style:italic;
font-size:0.8em;
}
post\_date:before {
content:"Datum: ";
}
comment {
margin-left:3em;
}
comment\_author:before {
content:"Kommentar av: ";
font-style:italic;
color:black;
}
comment\_author {
color:green;
}
comment\_date:before {
content:"(";
}
comment\_date:after {
content:"):";
}
/\* Ska inte visas\*/
link, channel language, pubDate,
guid, author, base\_site\_url,
base\_blog\_url, wxr\_version, generator,
post\_id, is\_sticky, post\_type, post\_name,
status, comment\_status, menu\_order,
post\_parent, ping\_status, post\_date\_gmt,
category, postmeta,
comment\_id, comment\_author\_email,
comment\_author\_IP, comment\_date\_gmt,
comment\_approved, comment\_type,
comment\_user\_id, comment\_parent {
display:none;
}
/\* block style \*/
title, description, post\_date, comment {
display:block;
}
Tag: Journal
How to export a Penzu journal
I have used Penzu as my main journal app for many years. Recently when Apple launched its Journal app I have been looking at it and other competitors. Then I realized that I am not able to get my own data from Penzu. There is no reasonable Export function.
So I found my own way to get my journal data. I could name this blog post to something like “How to export the unexportable”, or “How to intercept XHR requests in Puppeteer”, but my case is about Penzu, so I’ll stick to this particular title.
Tag: Node
How to export a Penzu journal
I have used Penzu as my main journal app for many years. Recently when Apple launched its Journal app I have been looking at it and other competitors. Then I realized that I am not able to get my own data from Penzu. There is no reasonable Export function.
So I found my own way to get my journal data. I could name this blog post to something like “How to export the unexportable”, or “How to intercept XHR requests in Puppeteer”, but my case is about Penzu, so I’ll stick to this particular title.
Tag: Penzu
How to export a Penzu journal
I have used Penzu as my main journal app for many years. Recently when Apple launched its Journal app I have been looking at it and other competitors. Then I realized that I am not able to get my own data from Penzu. There is no reasonable Export function.
So I found my own way to get my journal data. I could name this blog post to something like “How to export the unexportable”, or “How to intercept XHR requests in Puppeteer”, but my case is about Penzu, so I’ll stick to this particular title.
Tag: Puppeteer
How to export a Penzu journal
I have used Penzu as my main journal app for many years. Recently when Apple launched its Journal app I have been looking at it and other competitors. Then I realized that I am not able to get my own data from Penzu. There is no reasonable Export function.
So I found my own way to get my journal data. I could name this blog post to something like “How to export the unexportable”, or “How to intercept XHR requests in Puppeteer”, but my case is about Penzu, so I’ll stick to this particular title.
Tag: Scraping
How to export a Penzu journal
I have used Penzu as my main journal app for many years. Recently when Apple launched its Journal app I have been looking at it and other competitors. Then I realized that I am not able to get my own data from Penzu. There is no reasonable Export function.
So I found my own way to get my journal data. I could name this blog post to something like “How to export the unexportable”, or “How to intercept XHR requests in Puppeteer”, but my case is about Penzu, so I’ll stick to this particular title.
Tag: Xhr
How to export a Penzu journal
I have used Penzu as my main journal app for many years. Recently when Apple launched its Journal app I have been looking at it and other competitors. Then I realized that I am not able to get my own data from Penzu. There is no reasonable Export function.
So I found my own way to get my journal data. I could name this blog post to something like “How to export the unexportable”, or “How to intercept XHR requests in Puppeteer”, but my case is about Penzu, so I’ll stick to this particular title.
XMLHttpRequest the hard way
$.ajax is great, it hides much of the complexity. But sometimes we need to work with “raw” javascript :) So let’s look behind the scenes. The XMLHttpRequest (or just XHR) is used to open a connection to a server without a page reload. Internet Explorer calls it ActiveXObject and it differs in IE versions. Wikipedia article gives a good example how to create one constructor for all browsers: [sourcecode language=“javascript”]if (typeof XMLHttpRequest == “undefined”) XMLHttpRequest = function () { try { return new ActiveXObject(“Msxml2.XMLHTTP.6.0”); } catch (e) {} try { return new ActiveXObject(“Msxml2.XMLHTTP.3.0”); } catch (e) {} try { return new ActiveXObject(“Microsoft.XMLHTTP”); } catch (e) {} //Microsoft.XMLHTTP points to Msxml2.XMLHTTP and is redundant throw new Error(“This browser does not support XMLHttpRequest.”); };[/sourcecode] The remainder is more or less the same among the browsers. We open a connection defining the HTTP verb, URI and async mode (true or false): [sourcecode language=“javascript”]var xhr = new XMLHttpRequest(); xhr.open(“GET”, “/_vti_bin/listdata.svc”, true); xhr.onreadystatechange = onStateChange; xhr.send(null);[/sourcecode] Pay attention to onreadystatechange (only lower case letters). If we choose async=false, the UI waits for the response which is not so kind to users, but maybe it is easier to write a program. Well, there is actually no option but to have async=true. To provide the callback for success and error we can write the responding function onreadystatechange. This function will be called every time the state is changed. There are 5 states:
Update list items with listdata.svc
In one of my previous posts I showed how to retrieve data from listdata.svc with jQuery $.getJSON method. Getting data is very simple, listdata.svc provides a powerful restful interface with filtering, expanding and other features. Read the best and short introduction to listdata.svc by Suneet Sharma or a more detailed and technical article about filters, functions and operators by Mike Flasko at Microsoft with short examples here. Now back to listdata.svc in the SharePoint environment. Corey Roth provides a good images and sample results. For REST the “http verbs” are very important: GET, POST, PUT, DELETE.. SharePoint RESTful interface defines these verbs like that:
Tag: Tips
Proofreading blog drafts using Copilot Sidebar
While working on a blog post, I discovered a way to proofread my drafts in an easy way. This might not be very revolutionary, but it was so convenient that I wanted to share it with the world.
I use Hugo for my static website. On my local computer I can preview it in the browser under localhost:1313
. Copilot Sidebar in Edge does the same! This means I can ask it to proofread it.
Print2SPO - en enkel utskrift till SharePoint
Den här bloggposten är ett (en aning större) användar- (eller verksamhetsutvecklar-)tips om hur man kan sätta upp smarta utskrifter till SharePoint Online - utan några extraappar eller lösningar.
Först och främst, stort tack till min kollega Shahram som har presenterat idén för mig. Tänk dig ett följande scenario:
Du har en mall i Word som du fyller i, skriver ut på papper. Låt säga, det är en plockorder. Du vill digitalisera processen genom att skicka pdf:en till ett gemensamt dokumentbibliotek i SharePoint eller Teams.
Two workarounds for overcoming the listview threshold
These are two workarounds to see documents / list items in a view that exceeds the listview threshold of 5000 items.
Overcoming the listview threshold is as fun as succeeding in the limbo games.
This is changing all the time. When you read this, it might have changed. Today, 2021-01-05, me and my colleague found following two workarounds for listing over 5000 items in a list view in SharePoint Online:
Two site logos?
We have had troubles updating site icons in SharePoint Online. It might be related to one of the following:
- It occures only on hub sites
- The sites have a custom theme
The error message:
We experienced a problem updating the icon. Please try again in a few minutes.
But what I found is that there are two places where you change the site icon. If the first does not work, try the second one, that was what worked for us:
Page Diagnostics for SharePoint
While trying to set up a new Home Site, I discovered that there is a tool (browser extension) called Page Diagnostics for SharePoint.
After running this, I tried that command again and it was smart enough to detect the problem the tool discovered.
Also Network Trace is available.
Network trace
Page Diagnostics Tool is defnitely a tool to have in the troubleshooting toolbelt for SharePoint.
Setting up a Home Site
Here is the script:
Tips and Trick for Azure Functions
These are my favourite tips and tricks. These are only those who me and my colleguages have tried out.
Architecture tips
Keep it slim
Functions should do one thing and they should do it well. When you develop it in C# and Visual Studio, it is so tempting to develop a “microservice” in a good way, you add interfaces, implement good patterns, and all of a sudden you get a monolith packaged in a microservice. If your function grows, stop, rethink. Better to see how it input and output bindings can be used. Also orchestration with Logic Apps or Durable Functions can help.
Switch back to Modern UI
Just a little tip. When you switched to a Classic View of Site Contents, you can switch back by removing a cookie called “splnu”.
Working with resx files in Visual Studio
Today I found a nice Visual Studio Extension for working with localization and resx files: Resx Resource Manager. This extension provides an additional view in your project and scans all the resx files. I would recommend it to all projects where you have to translate your interface. Here is how it looks in my project: It can also assist with some machine translation from Bing and MyMemory: Another good thing is the Export and Import to and from Excel. Wonderful if you need help from Non-developers.
Bypass all custom jslink
Client Side Rendering (CSR) and jslink are great for customizing lists and forms in SharePoint. In my current project we use it a lot of it. A disadvantage of that path, although, is that it might occur javascript errors, during the development phase, but also in production. We do, of course, our best to leverage the best jslink code, but unfortunately we have to live with the fact that errors can occur, especially when we use it for NewForm, EditForm, DisplayForm and View (in list and grid). If an error occurs, it won’t stop the rest of javascript (it is wrapped in try and catch by SharePoint), but the fields will still not function as intended. It can also be some “corrupt” or old data in the field value that will “break” the jslink code. I would like to suggest one little fix, an idea I’ve come up to in my jslink-heavy project:
Improving the web performance of an intranet
[caption id=“attachment_3437” align=“alignnone” width=“480”] All the “small” app parts, web parts, delegate controls, user controls, and other “packages” that “must” be delivered to the users on every page load of the Start Page of your Intranet.[/caption] Recently we made an investment to improve the performance of our intranet. We made many changes in different layers: SQL, Network, Browser upgrade and code. Here I want to tell about what code changes we did to improve the web browser performance. Please leave feedback if you find it useful. You can also share your suggestions. We measured the performance before our code changes and after them. We had amazing results. Unfortunately I can not share any numbers, but we improved the Time to First Byte, time to load event firing in the browser, memory consumption in the clients and, perhaps, the most important, we improved the perceived performance of the Intranet, the way how users experience the speed and UI responsiveness. To do this I got many ideas of my project colleagues and branch colleagues. Here is the list of changes we’ve implemented:
Do not mess with the hive
In our Intranet we got this nasty double encoding error that was introduced in SharePoint April 2014 CU. In July 2014 CU the problem is still there. I often hear the suggestions to update files directly in the hive (the root folder for SharePoint: C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\) In that blog post it is described what the problem is and what files are affected and what code must be altered in order to get it to work (which I like). But it is also suggested to update the Search.ClientControls.js directly on the server (which I don’t like). So my advise is:
Load git into PowerShell
Just a little productivity tip. If you use git on Windows, you probably already have the Github for Windows application. This application adds the Git Shell:
The Git Shell will open a PowerShell window and execute shell.ps1 from the Github directory:
What it won’t do is to load your personal PowerShell profile. I want to use my PowerShell profile that creates some links and adjust the look-and-feel and the promt of the shell. By the way I have published my profile.ps1 as a gist:
Updating hover style in IE8 Developer Tools
In our project we still have to support Internet Explorer 8. The CSS issues in IE8 are most difficult to debug and solve. You can not add a new rule in Developer Tools or toggle the state of an element to hover as in moder web browser dev tools. One solution that I’ve come up to today, is to add a style with javascript or jQuery, open the script pane in IE8 Dev Tools and add this line: [code language=“javascript”] $(’.ms-srch-item:hover {filter:none !important;}’) .appendTo($(‘body’)) [/code] This will fill update the hover effect of the .ms-srch-item directly. That’s it, just a little tip.
Masked Inputs
Just a quick tip today. If you are looking after masked inputs like the old ASP.NET Ajax Control Toolkit MaskedEdit, you can try jQuery plugin called Masked Input from DigitalBush or even better jquery.inputmask.
Toastr.js and SharePoint
Have you used SharePoint javascript Notifications (SP.UI.Notify)? Are you looking for something new and fresh? Well then check out the Toastr.js - a simple, beautiful, fully responsive and light-weight javascript lib for notifications, developed by John Papa and Hans Fjällemark and released under the MIT License. By the way, toastr was one of many things I discovered and learned on John Papa’s online course by pluralsight: Single Page Apps with HTML5, Web API, Knockout and jQuery. It is a really awesome course, where you learn how to create an amazing SPA. Well, how’s about SharePoint. While whatching the course videos about toastr, I thought: Can we use it in SharePoint? Yes we can! Just load the toastr css and js and start using it:
The original Visual Web Part template is missing in Visual Studio 2012
Today I encountered a weird issue, the classic Visual Web Part template was gone in Visual Studio 2012. When I created a Visual WebPart, a webpart was created with a generated .g.cs file, like the sandboxed visual webparts. I am not exactly sure why it happened. According to the MSDN guide Creating Web Parts for SharePoint, the structure of Visual Webparts should be the same as in Visual Studio 2010. It could have happened after I installed the power tools. However, if someone runs into the same issue, here is the solution: Copy this zip file from a computer with VS2010 installed:
javascript: developing for performance
Many words have been said about the importance of performance when working with javascript files. Here I want to summarize what developers can do to increase the performance related to javascript. I found many tips on blogs. Here comes my aggregated list of actions one can do to speed up sharepoint (and not only) sites with focus on javascript:
1. Load only sharepoint stuff you need
Use prefetch option to only load sharepoint javascript files that needed. To see the difference, just add ?prefetch=0
to your sharepoint url in the browser. The downside of this lazy loading is that you wrap all sharepoint related javascript into ExecuteOrDelayUntilScriptLoaded otherwise you maybe invoke some of javascript objects and functions that are not loaded. So the prize of this huge performance improvement is a high awareness by a developer when and which scripts are loaded and run.
Out-Gridview in PowerShell
Did you know that we can pipe the output from PowerShell into a graphical GridView? I have used PowerShell for one year and only now I discovered this nice feature. You can add filter criteria, you can filter by typing in a textbox:
Other useful output cmdlets
- out-file
- out-clip
- out-null
Add Comments column to your sharepoint list
If you have used Issue tracking list template in SharePoint you must have marked that the comments are added and marked with author name and datetime. It is handy to have these micro “discussion boards” on items. The comment-formed communication can help to fine-tune task definitions. By the way, have you seen Trello? So the question is how we can create this column in other lists? Here is a little tutorial how to create “append-only comments”, as they are called:
Powershell scripts for AD
A tip for all who want to administer AD with powershell: Idera Powershell scripts. Just sign up and get the free scripts for AD, SQL, Exchange and Sharepoint. I personally prefer to user modules, so I change the file extension from ps1 to psm1 and then I can use import functions as modules. Here is a simple example for creating for domain users:
import-module .\\New-IADUser1.psm1
function Add-User($name) {
New-IADUser -Name $name
-sAMAccountname $name
-ParentContainer 'CN=Users, DC=contoso, DC=com'
-Password 'SvenskaAkademien1786'
-EnableAccount -PasswordNeverExpires
}
Add-User "user01"
Add-User "user02"
Add-User "user03"
Add-User "user04"
update 2012-03-15: nice script from Ryan
Ryan Dennis has created a very handy script for creating random users. In PowerShell v3.0 there is a cmdlet for creating users: New-ADUser. So the function above can be rewritten like that: [code language=“powershell”] Import-Module ActiveDirectory -ErrorAction SilentlyContinue function Add-User($name) { $password = ConvertTo-SecureString ‘SvenskaAkademien1786’ -AsPlainText -Force New-ADUser -Name $name -sAMAccountname $name -Path ‘CN=Users, DC=contoso, DC=com’ -AccountPassword $password -Enabled $true -PasswordNeverExpires $true } Add-User “user01” Add-User “user02” Add-User “user03” Add-User “user04” [/code]
Check if an html element is hidden using jQuery
Well, sometimes we need to calculate width and so on. In my next post I will write about how to fix auto-resize on fixed sized master pages. But now: a very nice stuff: how to check if an element is hidden or not:
$("#s4-leftpanel").is(":visible")
```It is a pure poetry. It reminds me of the beauty of [symbols in Ruby](http://rubylearning.com/satishtalim/ruby_symbols.html).
Good pattern for javascript files
SP.js exists in two variants in debug mode and in modified. When you develop it is better to use debug mode. When it goes to production it is better to use minified files. The same you can do with your files. Wictor Wilen explains how to do minify your custom javascript files. I think it is a good pattern to create javascript files and call them something-something**.debug.js**. Then when you are done, run the custom tools to minify them.
Todolist in VS
A really nice feature is a task list. Just write //TODO something something in your code and it appears in the task list which can be shown through View - Task List in Visual Studio.
Increase performance while retrieving data with LINQ to SP
If you are just intrested in getting data, not writing to the source like SubmitChange, you can disable ObjectTracking and increase the performance.
context.ObjectTrackingEnabled = false;
```I found this tip on page 248 in the book "[Sharepoint 2010 as a development platform](http://www.apress.com/9781430227069)"
Windows 8 preview
I have tested the Windows 8 developer preview. VMWare player 3 didn’t manage it, so I installed VirtualBox and it ran very well. One thing I did was to enable full screen on VirtualBox. Here is the list of features you get if you install the developer preview:
- Windows SDK for Metro style apps
- Microsoft Visual Studio 11 Express for Windows Developer Preview
- Microsoft Expression Blend 5 Developer Preview
- 28 Metro style apps including the BUILD Conference app
1DayLater.com - the best time tracking
I discovered a great tool for time tracking: 1DayLater. So far I am very pleased. You can add activities, write hash tagged descriptions, get an overview over you consultant hours and much more
powershell.exe -Command
man kan skapa en .bat-fil med olika powershell-anrop:
powershell.exe -Command "& {.\\Script1.ps1}"
Videokurs om Web Content Management
På microsoft.com finns en ny videokurs om web content management. Där kan du lära dig om hur man implementerar cms-funktionalitet med sharepoint, bl.a.: content types, page layouts med mera. Tack för tipset, deutschsprachige Sharepoint-Community.
Autocomplete för sökruta i Sharepoint
Ett mycket trevligt projekt: Search As You Type på Codeplex. Ladda ner textfilen och lägg till javascript och css från den filen till masterpage. Så enkelt är det. Jag har testat det genom att direkt stoppa in koden i Chrome Console.
uls logger
Det finns ett intressant projekt på codeplex: ULS Logger. Är absolut värt att testa.
parametrar i powershell-funktioner
Man kan skapa funktioner med parametrar som påminner mycket om i C#. Så i stället för:
function Just-Test {
Write-Host $args\[0\]
}
```Skriv:
function Just-Test($param) { Write-Host $param }
if($site -ne $null -and $url -ne $null) {“Url OR Site can be given”; return}
Visa i hur länge sedan något hänt
Säg du vill visa när något har skapats. Att visa datum funkar. Ännu bättre är att visa det i stil: “För tre dagar sedan” eller så. Det finns en bra metod i SPUtility:
SPUtility.TimeDeltaAsString(Published, DateTime.Now);
ID på befintliga kolumner
Det finns en fin lista över id på kolumner som man kan lägga till. Här är ett exempel hur man kan använda det. Här är ett exempel på två extra kolumner i contenttype:
<FieldRefs>
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
<!-- Enterprise Keywords-->
<FieldRef ID="{3de94b06-4120-41a5-b907-88773e493458}"/>
<!-- PublishingImage-->
</FieldRefs>
.gitignore for android
.gitignore is very important. This file tells git which files not to care about. I found a good template for android .gitignore: .metadata tmp/** .DS_Store *.tmp *.bak tmp/**/* *.swp *~.nib Thumbs.db Desktop.ini *~ *.apk bin gen local.properties *.jar **.classpath**
The only thing I have added is the last row: .classpath.
Comments from Wordpress.com
J. Pablo Fernández - Apr 2, 2011
Good beginners' tutorial on android, eclipse and git
Smashing magazine has a pretty good tutorial how to start programming for android using git, github, eclipse and datastorage. I recommend: Get Started Developing For Android With Eclipse, Reloaded
New files in Eclipse
If there are new classes or files in the project (say you have got the latest version from github into existing workspace in Eclipse). In order for Eclipse to see them, right click on the package and press “Refresh”.
Get coordinates from Google Maps
To get longitude and latitude can be tricky at the first time. There are many ways to do this, e.g. getlatlon.com. Good enough, but not so practical if you want to collect many coordinates. You can’t search after street names, you only can scroll and drag. Another way is to use javascript to show the longitude and latitude. See this example. This works in all web browsers.Just find your object in Google Maps and paste this javascript in URL bar: javascript:void(prompt('',gApplication.getMap().getCenter()));
You’ll be prompted the coordinates values. Just be sure the map is centered on your object. There is a third, even better way. Use javascript, but don’t be annoyed with prompts. In Chromium (or Google Chrome) navigate to maps.google.com find your object, open the Console in DevTools (press Ctrl-Shift-J). Right click on the object → Center the map here In console write: copy ( gApplication.getMap().getCenter().toString() )
So now you can paste it wherever you need it. But the best with it is: you can do whatever you want and need before copying. In LUSites, I save the coordinates another way, first latitude and then longitude. So I can shift values, trim unnecessary stuff and so on. Look at it: var loc = gApplication.getMap().getCenter().toString(); var locTrimmed = loc.replace(/[() ]/gi,""); var locArray = loc.split(","); var newLoc = locArray[1] + "," + locArray[0]; copy (newLoc)
First I get the string of the coordinates. Then I erase the unnecessary stuff: (), blank space. After splitting I shift the longitude and the latitude and create a new string which is copied. Or, we can shorten this: var coordinates = gApplication .getMap() .getCenter() .toString() .replace(/[() ]/gi,"") .split(","); copy (coordinates[1] + "," + coordinates[0]);
The same in one row (to copy-paste): var coordinates = gApplication.getMap().getCenter().toString().replace(/[() ]/gi,"").split(","); copy (coordinates[1] + "," + coordinates[0]);
To avoid to copy this line of code, just press up arrow in the DevTools console.
Programmers notepad
De flesta känner nog till Notepad++. Det finns en annan väldigt duktig textredigerare: Programmers notepad. Den är väldigt bra. code highlighting, filnavigering direkt i programmet mm. Testa gärna.
Powershell med tysk precision
Master Powershell ebookDe som har missat Powershell, läser nog andra sorts bloggar än denna. Så rak på sak: det finns en lovande ebook om Powershell, skriven av Tobias Weltner. Ska absolut läsa den. Ni som har läst, vad tycker ni om den? Master-PowerShell | With Dr. Tobias Weltner i html
Ändra utseendet på sidan direkt i webbläsaren
I förra inlägget har jag berättat om devtools i Google Chrome. Ett ytterligare tips för att hålla på med klient-delen är att använda Optimizely.com. Det är väldigt smidigt. Gå in på optimizely.com och skriv in adressen till din sharepoint-applikation. Eller se denna video. [youtube http://www.youtube.com/watch?v=0S0IrbwpfzE&rel=0&hl=en_US&feature=player_embedded&version=3]
Felsök på clientsidan med Chrome DevTools
Här är en väldigt bra video som berättar om nya devtools i Google Chrome 10. Den visar 12 tricks hur man kan underlätta felsökning av html, css och javascript. Att kunna ändra html,css och js on-the-fly är faktiskt häftigt. För mig som länge har använt Firebug i Firefox (som nu inte funkar på FF4 RC) känns devtools väldigt bra. [youtube http://www.youtube.com/watch?v=nOEw9iiopwI&w=530&h=335]
Comments from Wordpress.com
Ändra utseendet på sidan direkt i webbläsaren « Sharepoint. Kunskap. Upptäckter på resan. - Mar 1, 2011
Sharepoint Log Viewer
Mycket bra verktyg för att debugga din sharepoint applikation är Sharepoint Log Viewer som är Open Source och finns att hämta på codeplex.com Det går att öppna en logg-fil, det går att köra live monitoring och att exportera. Det sköna är att det är lätt att söka efter correlations-id. Rekommenderar verktyget!
Comments from Wordpress.com
Sharepoint + OpenSource = Sant « Sharepoint. Kunskap. Upptäckter på resan. - Mar 3, 2011
Tag: Ollama
Prompts and Modelfiles
Tag: Automation
How to Read SharePoint Storage Capacity with Graph
Automate Creation of Git Repos Using Azure DevOps API
Today I got a question: how can we precreate 50 git repositories in an Azure DevOps Project? I started to learn about the API in Azure DevOps and I found it very interesting. With the API you can script and automate administration of projects, repositores, pull requests etc. To keep this blog post simple and digestable I would like to focus on the intitial request - creating git repositories by code.
A cost effective way of running legacy scripts in the cloud
Have you also got some old huge scripts that run on a server locally? Have you also considered moving them to the cloud? Here comes an idea of how to do it quickly and easy.
In my case I have some older powershell scripts that are harder to convert to serverless applications:
- They use MSOnline module in PowerShell, hence they require rewriting to AzureAD before using them in an Azure Function
- They take around 15 minutes to complete, Azure Functions Consumption Plan is limited to 10 minutes. Of course I can split them in several parts, but I am looking for an easy way right now, I have to postpone refactoring because I am not sure if there is a real need for this script solution.
- They process a lot of data and consume more that 400 MB memory which makes it crash when I put it in a Azure Automation Runbook.
Well, maybe a Windows Server VM in Azure is the only way? While recently setting up a minecraft server and following a blog post that proposes auto shutdown and logic apps to start the server, I came up with an idea to use exactly the same approach to make it as cost effective as possible.
Tag: Script
How to Read SharePoint Storage Capacity with Graph
Smarter way of loading SharePoint CSOM dll in PowerShell
Have you also got a legacy powershell script that loads SharePoint dlls and runs CSOM code directly? It’s quite easy to convert to PnP PowerShell. But if you run out of time and just need to execute the script, then I have a quick tip for you.
First of all, a CSOM script can be recognized by Add-Type commands (or Import-Module) plus the SharePoint dll paths.
Loading the dll the old way.
A cost effective way of running legacy scripts in the cloud
Have you also got some old huge scripts that run on a server locally? Have you also considered moving them to the cloud? Here comes an idea of how to do it quickly and easy.
In my case I have some older powershell scripts that are harder to convert to serverless applications:
- They use MSOnline module in PowerShell, hence they require rewriting to AzureAD before using them in an Azure Function
- They take around 15 minutes to complete, Azure Functions Consumption Plan is limited to 10 minutes. Of course I can split them in several parts, but I am looking for an easy way right now, I have to postpone refactoring because I am not sure if there is a real need for this script solution.
- They process a lot of data and consume more that 400 MB memory which makes it crash when I put it in a Azure Automation Runbook.
Well, maybe a Windows Server VM in Azure is the only way? While recently setting up a minecraft server and following a blog post that proposes auto shutdown and logic apps to start the server, I came up with an idea to use exactly the same approach to make it as cost effective as possible.
Is Custom Script Dangerous
Allowing custom script has its security implications. But what exactly does it mean? Is it dangerous? My colleauge Daniel and me have done a little experiment. There are two implications stated on MS Docs:
- Scripts have access to everything the user has access to.
- Scripts can access content across several Office 365 services and even beyond with Microsoft Graph integration.
To summarize, we can look at that picture:
So the risk that user 1 (the Blue User) intentionally or unintentionally places a script and lets user 2 (the Red User) run this script by linking to the page that has this script. The page must be in a “common” place.
JavaScript Localization in SharePoint
Yesterday Waldek Mastykarz published a cool post: Globalizing JavaScript in SharePoint 2013. This is a very cool technique to localize your client code in javascript and reuse your resx files in Server Side and Client Side. This is actually not new for SharePoint 2013 despite it has become more needed with the huge client focus in the new SharePoint. I have used this in SharePoint 2010 for a long time. In my blog post: ScriptResx.ashx in SharePoint I told about that technique. What I didn’t know that you can define your javascript namespace directly in the resx file. Waldek wrote in his comment that SP.Publishing.Resources.en-US.resx automatically are SP.Publishing.Resources in javascript. That was not the case for my own localization files. A simple look at SP.Publishing.Resources.en-US.resx helped: [sourcecode language=“xml”] true SP.Publishing.Resources [/sourcecode] This results in: [sourcecode language=“javascript”] _EnsureJSNamespace(‘SP.Publishing’); [/sourcecode] So what we have to do for our custom resx file is to add classFullName resheader: [sourcecode language=“xml”] Takana.Res [/sourcecode]
PowerShell: Copy an entire document library from SharePoint 2007 to disk
For a while ago I needed to copy all files from a document library within a SharePoint 2007 site to the hard drive. So I didn’t need to copy files from SharePoint to SharePoint so I couldn’t use the stsadm -o export command or Chris O’Brien’s nice SharePoint Content Deployment Wizard. I came across the SPIEFolder application which should work with SharePoint 2007 and 2010. It has a site on codeplex: spiefolder.codeplex.com, but neither the binary nor the source code can be downloaded from there. After some searching I found the binary in the author’s skydrive. The fact that the source code was not available seemed as an disanvantage because I could not know what code was run. Nevertheless I tried it out and it didn’t work:
defaultvärde på parametern i powershellfunktioner
Läser ett intressant inlägg om deployskript i powershell. Har upptäckt att man kan stoppa in ett defaultvärde i funktionens parameter. Så i stället för
function hello($name) {
Write-Host $name
}
Kan man köra:
function hello($name = "Gregor") {
Write-Host $name
}
```Mycket smidigt.
PowerShell
PowerShell är ett sätt att manipulera data och struktur i SharePoint-portalen. Samma uppgifter låter göras med konsoll-applikationer. Fördelen med PowerShell är att man kan skapa skript som är flexibla och kan köras med olika parametrar. PowerShell påminner starkt om shell-skript i Linux. För mig som egentligen kommer snarare från bash-världen. Där har Microsoft låtit sig inspireras starkt :). Det finns en bok om PowerShell, skriven av svenskar, som låter intressant. Man behöver inte heller uppfinna hjul på nytt: det finns färdiga skripts som man direkt. Bara man skriver rätt parametrar. Här är ett ställe där man kan hitta skripts. Det finns många sidor som förklarar hur man skriver skript.
Tag: Sharepoint
How to Read SharePoint Storage Capacity with Graph
Show Path Column in SharePoint
PnP.PowerShell is just the tool you need to show the Path column in a SharePoint document library view. Scroll down to see the script, or read on to learn more.
An introduction
Do you still have folders in SharePoint? Well, you are not alone. Remember the old dream of relying on metadata only? Forget it! As a matter of fact, folders are still a popular way of organizing files in SharePoint. When not overused, they provide “metadata” by itself, metadata that works even in synced folders, in archive scenarios, works best with Teams etc.
Lookup Person Field in Power Automate
Hello Citizen Developers!
I get more and more questions about Power Automate.
One of the recent questions is about how to look up a person field from SharePoint using Power Automate.
I’ll give you a bit of the background in a second. Power Automate is really awesome for citizen developers.
There are a lot of triggers and actions that are easy to understand and use, such as send email, create a list item in Sharepoint etc.
But there are also techier, nerdier actions that are less citizen developer friendly. One of them is Send an HTTP Request to SharePoint
. It might be the answer to many challenges, intimidating at first, but powerful and, hopefully, not so complicated once you’ve tried it.
This post is about this very action and how you can use it to simplify your flow.
Automatically Send Email When News Is Published
News in SharePoint are great, it is easy to edit and post news, add pictures and web parts. But you might have thought how you would spread the word better. If your workmates would check the start page on your site or on the SharePoint Home every day, it would be awesome, it might be the case in future. In the meantime though, you probably have considered sending out email notifications to your workmates whenever there is fresh news.
My WSL Setup
This is my installation of Windows WSL and SharePoint Development Environment. The procedure and technology is ever-changing, the details might change, but the process is worth documenting, at least for myself, this is a working guide as of writing (2021-12-20).
Installing Windows Terminal
Installing Windows Terminal is not a prerequisite, but it will make your life much easier. Open Windows Store and search for Windows Terminal and click on Install.
Installing WSL 2
Installing WSL has never been easier than now. For that you only need to run a command in terminal as an Administrator and restart your computer:
Export AppendOnly Comments
Remember the old comments in SharePoint Lists? I am sure there are tons of lists that use the Append-Only Comments. They are implemented using versioning. The problem is that it is hard to export the comments, unless you know the tricks. The trick I want to share comes from a colleague of mine. The reason why we need export all the comments is that we need to document and save/archive the decision making process that took place in the comments field.
Sites.Selected and Governance
The new permission in Graph API - Sites.Selected - is a step in the right direction. Since long we have been looking for ways of scoping the accesses to live up to the least privilege principle. It was either nothing or everything. I have tried out the new Sites.Selected permission and here are my findings.
First of all, if you haven’t heard about Sites.Selected, please visit these pages to find out more. I am skipping the introduction, since there are already good resources on that out there.
Smarter way of loading SharePoint CSOM dll in PowerShell
Have you also got a legacy powershell script that loads SharePoint dlls and runs CSOM code directly? It’s quite easy to convert to PnP PowerShell. But if you run out of time and just need to execute the script, then I have a quick tip for you.
First of all, a CSOM script can be recognized by Add-Type commands (or Import-Module) plus the SharePoint dll paths.
Loading the dll the old way.
Monitoring Microsoft 365 using Raspberry Pi and M365 CLI
I would like to show you my recent hobby project with a raspberry pi, a unicorn phat and the powerful cli-microsoft365: A simple monitoring solution of Microsoft 365 Services.
Status of some important services in Microsoft 365
In essence, I put the unicorn phat onto the raspberry pi zero w and wrote this python script:
The python script checks the service status every five minutes and shows it with colors on the unicorn phat.
1TB=1024GB in SPO Storage
You want to calculate your storage capacity in SharePoint Online? Here is how:
- Every 1TB is 1024GB (it might be confusing, see my previous post, but it’s how it is calculated)
- A tenant gets 1024GB by default
- For every user license of a product that includes the service plan called “SHAREPOINTSTANDARD”/SharePoint Online (Plan 1) you get 10 GB extra
- For every user license of a product that includes the service plan called “SHAREPOINTENTERPRISE”/SharePoint Online (Plan 2) you get 10 GB extra
- For every user license of a product that includes the service called “ONEDRIVEBASIC”/SharePoint Online OneDrive Basic you get 0.5 GB extra
Products vs. Service Plans
A product (a.k.a. SKU) consists of service plans. E.g. Office 365 E3 (product) consists of SharePoint Online Enterprise among others. It is a Service Plan that gives you additional storage, not a product. The information on “SharePoint Limits” page is (over-)simplified. Simplified for a good reason of course - to give a rule of thumb for calculating your storage.
Print2SPO - en enkel utskrift till SharePoint
Den här bloggposten är ett (en aning större) användar- (eller verksamhetsutvecklar-)tips om hur man kan sätta upp smarta utskrifter till SharePoint Online - utan några extraappar eller lösningar.
Först och främst, stort tack till min kollega Shahram som har presenterat idén för mig. Tänk dig ett följande scenario:
Du har en mall i Word som du fyller i, skriver ut på papper. Låt säga, det är en plockorder. Du vill digitalisera processen genom att skicka pdf:en till ett gemensamt dokumentbibliotek i SharePoint eller Teams.
1 TB = 1024 GB in SPO?
There is confusion around how the storage is calculated in SharePoint Online. I believe, in SharePoint Online 1 TB is 1024 GB (based on powers of two), although the SI Prefix is for numbers based on powers of 10 (1TB = 1000GB, Wikipedia). In this post I would like to summarize the results of my investigations and I hope Microsoft or the community can confirm or disconfirm this.
First, let me explain why we care about it. The storage in SharePont is limited and we need to keep an eye on it. Especially in our case, where we need to track storage utilization across different parts of the organization/our tenant. The storage in SharePoint is calculated like so:
Demote News in SharePoint Online
In case you published a news in SharePoint Online and you now want to “downgrade” it to a regular page, I have a solution for you.
The reasons why you would like to demote a News might vary:
- You publish an important message, perhaps a note about an operational disturbance. It might not relevant anymore, but you still want to keep the page in case someone wants to access the information.
- You accidentally create a page as a news.
- …
Kombinera två SharePoint-listor i PowerBI
Det här är en enkel guide på svenska om hur du kan ladda in data från två eller fler listor i SharePoint och lägga ihop dem till en.
Scenariot är följande. Du har två eller fler sajter i SharePoint Online som har var sin lista (med samma kolumner). Du vill ladda in data från båda och se en aggregerad/summerad version. Alternativet är att ha en delad lista, men ibland (av behörighetskäl eller av behovet för smärre anpassningar av enskilda listor), ligger det i separata listor/sajter.
Add a security group as hubbers using PowerShell
Today I needed to add a security group to “People who can associate sites with this hub” through PowerShell. Here is quick how-to. I usually say “hubbers” instead of the long “People who….”. By the way, if you want to know what prerequisites there are for being a hubber, read my other blog post
An example of how to add a security group is missing in the MS Docs:
Two workarounds for overcoming the listview threshold
These are two workarounds to see documents / list items in a view that exceeds the listview threshold of 5000 items.
Overcoming the listview threshold is as fun as succeeding in the limbo games.
This is changing all the time. When you read this, it might have changed. Today, 2021-01-05, me and my colleague found following two workarounds for listing over 5000 items in a list view in SharePoint Online:
Two site logos?
We have had troubles updating site icons in SharePoint Online. It might be related to one of the following:
- It occures only on hub sites
- The sites have a custom theme
The error message:
We experienced a problem updating the icon. Please try again in a few minutes.
But what I found is that there are two places where you change the site icon. If the first does not work, try the second one, that was what worked for us:
Listing all renamed sites in SharePoint Online
When you rename a site, a new site is REDIRECTSITE#0, you can get all the sites of that type by running
Get-SPOSite -Template REDIRECTSITE#0
Please consider some caveats with renaming a site url
Automatically detect new sites in SharePoint Online
Original image by William Warby. https://www.flickr.com/photos/wwarby/16414155179/in/photostream/
Sites in SharePoint are created all the time, not only for SharePoint, but also as storage for Yammer, Teams, Planner and other services in Microsoft 365. There are ways to keep track of them, but the ability to automatically detect a new site creation is quite appealing. Automatic detection means a trigger of a Power Automate (Flow) or a Logic App.
There are a few blog posts that exactly describe how you can detect when a new site is created in SharePoint Online:
Infographics. Who can associate a site with a hub
I found this nice post and a nice decision flowchart.
Low resolution, visit the post to see more.
I also have drawed a simple chart while explaining for my colleagues, you can see it above. I hope this infographics can be useful to more people. By the way, we use the word “Hubber” (sv. Hubbare) for “People who can associate sites to hubs”
Is an M365 Group a Yammer Community
Nowadays a Yammer Community gets a corresponding Microsoft 365 Group (Office 365 Group, Unified Group). In your work as an SPO Admin, you might need to differentiate “ordinary” Modern Team Sites from those ones that were created for a Yammer Community.
They both have GROUP#0 as Template. On the actual SPO Site object, there is nothing that you can use to differentiate those. Neither you can use the Office 365 Group information. But there is a way: if you connect to Exchange Online and get the group from there, then there is something useful.
Estimated Completion in Write-Progress in PowerShell
Have you also got many sites in your tenant? Write-Progress is the bare minimum in a script that goes through all sites. But there is also another nice way to make easier to see the progress - estimated completion time.
Although the idea comes from another blog post (My life is a message), I thought it could be worth sharing it again, especially in the cloud context.
Here is a bit simplified scenario: Getting information for every site. The status message in Write-Progress contains also the estimated completion time.
Optimizing lookups in PowerShell
Have you had a PowerShell script that contains two bigger arrays and you wanted merge the information. It can become quite slow if you need to search for every item from array A through all items in array B. The solution is called a HashTable! It might be not an advanced tip for some, but I was really glad to see a huge improvement, so I decided to share it as a post.
Page Diagnostics for SharePoint
While trying to set up a new Home Site, I discovered that there is a tool (browser extension) called Page Diagnostics for SharePoint.
After running this, I tried that command again and it was smart enough to detect the problem the tool discovered.
Also Network Trace is available.
Network trace
Page Diagnostics Tool is defnitely a tool to have in the troubleshooting toolbelt for SharePoint.
Setting up a Home Site
Here is the script:
Deploying SPFx using Office 365 cli, custom AAD App and Azure Pipelines
In this post I would like to share some findings from setting a deployment of SPFx. In my work:
- I need to deploy SPFx solutions using Azure Pipelines
- I need to use the least privileges/permissions
- I cannot use Legacy Authentication
First of all, big thanks to @waldekm and the whole community of @office365cli and @m365pnp for the quick help, and that outside working hours.
Let’s take a look at the setup piece by piece
Power Automate for a one-time operations
Honestly, Power Automate is great for automating repetetive stuff. But I think there is room for one-time flows as well. I’ll give you an example.
I’ve got an excel file with quite a few rows. And I need to convert it to a SharePoint List. I know there is a couple of options, such as Quick Edit in Classic View, Import an Excel file as a list (it also requires the classic view), there will be Excel import in Modern as well. But I need to also change the column names, maybe adjust something “on-the-go”.
Modern Team Site without an Office 365 Group
These are my findings around Modern Sites without Office 365 Groups. It is, of course, a subject to change.
Today (2020-02-21) when you create a Modern Team Site without a group, you will get a site with the template STS#3. This oldie has been around for a while, hasn’t it?
I would always recommend creating Office 365 Group Connected sites.
How it is created
Through PowerShell/REST or from SharePoint Home, if your account is not allowed to create Office 365 Groups, it will automatically create a site without a group.
Kalendern i SharePoint
Dags för ett svenskt inlägg igen. Idag vill jag titta på kalenderfunktionaliteten i SharePoint Online.
Fortfarande gammalt (classic) utseende
Tyvärr är det gammalt utseende som gäller och det finns inga planer från Microsoft att modernisera kalendern:
Jag förstår att det är väldigt mycket kod för att få till kalendervyn och att det inte är så lätt omvandla till ett modernt utseende, men det ställer till eftersom det upplevs som gammalt och inte användarvänligt ute i verksamheten.
Hiding Teamify Prompt
If you want to remove the Microsoft Teams Banner on your SharePoint Site, the only thing you need is to set a web property on a site: TeamifyHidden=TRUE. I’ll give you some guidance below. But before you do that, consider following:
- If there is already a team created for a group connected site, the prompt won’t show up. Why fix something that is not a problem?
- Only group owners will get the prompt, if they are few and they know what it is, it is better to let them to decide whether to create or not to create a team.
- Only licensed users within your organization will be shown that choice. No external users or users without a license.
- And the most important part: if any site owner selects “Don’t show me again” it will stop popping up for all other site owners. If you happen to have a manual step in the group creation process, then you can just click it away.
Site Collection App Catalog vs. Tenant App Catalog
Site Collection App Catalogs are great for special cases (like developing apps or site unique apps), but using them on scale would be a mess.
I got a question: Why should we use the Tenant App Catalog at all when we could enable a Site Collection App Catalog on every teamsite? So the suggestion here is to install SharePoint Framework Packages on many Site Collection App Catalogs, instead of the Tenant App Catalog. In that way those wouldn’t be visible for all users in the “Add an app” page.
Permissions in SPFx apply to your whole tenant
Once you approve a permission request from an SPFx app, it will grant the same permission to all other apps in the same tenant.
Nothing new, but I want to emphasize that in that blog post only dedicated to that. You can read it here:
A simple sketch over the permissions.
Here is a simple FAQ to explain what it means:
Trust gulp-connect certificate from Visual Studio Online on Mac OS
I have read and followed this awesome post:
Getting SPFx working in Visual Studio Online by SPDavid.
I got my fingers and tried that guide out. This worked good, I spent some time, though, googling (binging) around to get rid of the SSL Warnings for the remote “localhost” on my Mac.
I would like to share this simple instruction on how to trust a self signed certificate from gulp-connect on Mac OS. The implication is that the certificate is on the remote linux machine (on the Visual Studio Environment), that you are connected to through the Visual Studio Code extension.
Is Custom Script Dangerous
Allowing custom script has its security implications. But what exactly does it mean? Is it dangerous? My colleauge Daniel and me have done a little experiment. There are two implications stated on MS Docs:
- Scripts have access to everything the user has access to.
- Scripts can access content across several Office 365 services and even beyond with Microsoft Graph integration.
To summarize, we can look at that picture:
So the risk that user 1 (the Blue User) intentionally or unintentionally places a script and lets user 2 (the Red User) run this script by linking to the page that has this script. The page must be in a “common” place.
The Path Length Limit of 400 chars in SharePoint Online
This post is my summary and my conclusions on the Path Length Limit in SharePoint Online and OneDrive.
How the path length is calculated
Path Length is not the same as the URL length. It is the relative Url.
/sites/site-url/documenlibrary/folder1/folder2/filename.fileextension
Calculations rules
- Only the server relative url part is counted. The “https://[tenant].sharepoin.com” has no impact on that. It starts from the foward slash: “/sites” (or /teams).
- An encoded value such as a blankspace (%20) is treated as one character, not three.
- A unicode character, and an emoji is treated as one character. Good news for Non-English Names.
- Url Parameters, like “?Web=1” are not calculated.
- The site url and the document library url is taken into account
- All slashes are included
- A file extension is also included, and even the dot, e.g. “.docx”
Other related information
- A site url and a group name can only be 64 characters max.
- The path in the “Copy Link” is much shorter than the “real” path
- There is no limit (as of time of writing - 2019-10-30) on the folder name length (other than the bigger limit of 400 characters), I had no issues to add a folder name with 312 characters.
Renaming site urls
I saw a demo of it on the European SharePoint Conference in Copenhagen in 2018. Sebastian Fouillade, who showed this, compared this big change with brain surgery. All the urls, all the connections. But now it is possible. Today I have seen it even in my standard release tenant.
It is really appreciated. Soon it will be possible to rename misspelled sites, like “devlepment” to “development” etc.
To rename you need to go the SharePoint Admin, find your site among Active sites and click on “Edit” in the site url area.
A user can only create 250 groups
A non-admin user can create no more than 250 resources in Azure AD. That is one of the many Azure AD service limits and restrictions. A “resource” can be an app registration, an Office 365 Group etc. But I would like to discuss Groups more in detail.
Imagine the following scenario: Your organization has disabled Office 365 Group Creation. Only IT can create new groups. A service account has been set up for creation of team sites. The application permissions are “binary”, either everything or nothing: Group.ReadWrite.All. This service account will hit the limit very soon.
Snabba diagram i SharePoint Online
Ett nytt tips på svenska: det finns en webpart i SharePoint Online: snabbdiagram.
När du har lagt till ett snabbdiagram, kan du skriva välja mellan stapel och cirkeldiagram
Du kan bara välja mellan stapel- och cirkeldiagram.
Data går att mata in direkt.
Resultatet får du direkt:
Använd data från en lista
Det går att visualisera data från en SharePoint-lista. Det är inte så mycket mer komplicerat, men det öppnar nya möjligheter. Du behöver bara hålla listan uppdaterad.
Troubleshooting Performance in SharePoint Online
This is my personal list of links and thoughts on troubleshooting performance in SharePoint Online.
Resources
- @MSFT365Status, a twitter flow on the incidents and resolutions
- connectivity service
- Service Status (open for all), Service Health (for admins)
Health info in Response Headers
Every response from SharePoint Online contains some health information:
- Diagnosing performance issues with SharePoint Online (MSDocs)
- Troubleshooting SharePoint Performance Issues with F12 (blog post)
Following Response Headers could reveal the health:
Min första kolumnformatering
Jag har precis börjat med kolumnformatering, bara testat. Det är annorlunda, jag är nöjd med första resultatet. Även om det påminner om jslink som jag har jobbat mycket med, så är det mycket lättare att sätta igång:
Det är enklare att ändra, även för en icke-utvecklare. Man får en början:
Med hjälp av dokumentation av List Formatting och Office UI Fabric Icons, har jag skapat en enkel formatering som jag är riktigt nöjd med:
Get totals from a list view using PowerShell
Today I will share a short script for getting totals from a list view in SharePoint. Imagine this scenario: you have set up a list view with totals and you want get the totals every day for statistics or some other reasons. Instead of getting all items, and/or fiddling around with CamlQueries, there is a better and quicker way - List.RenderListData. This combined with a tip from Piyush K Singhs blog post Get Aggregate Values… I came up with an idea to read the ViewXml from an existing view and retrieve the totals (in my case Count and Sum). Enough talking, let’s take a look at the code:
English vs. Non-English
This post is about the default language of a new site in SharePoint Online. There are some pros and cons of using English as the default language for Non-English sites.
In my case I want to know what is better for Swedish users:
- A site with English as default and Swedish as an alternate language (among many other alternate languages)?
- A site with Swedish as default?
Today, when you create a site, English is pre-selected in the form, you have to choose Swedish actively. When you create a team, the underlying SharePoint Site will have English as the default language.
Switch back to Modern UI
Just a little tip. When you switched to a Classic View of Site Contents, you can switch back by removing a cookie called “splnu”.
Tips and tricks for Site Collection App Catalogs
Site Collection App Catalogs (SCAC) are much appreciated, thank you, Office 365 Team. Here is a couple of tips and tricks for SCAC.
Tip #1 You don’t need Tenant Admin rights to add a new Site Collection App Catalog
I have seen many blogs, forum threads etc that state that only Global Tenant Administrators can add new Site Collection App Catalogs. The truth is that a SharePoint Admin rights are enough. The trick is to make that SharePoint Admin Account to a site collection administrator of the app catalog site. To be precise the account that adds a new SCAC must have Manage Web Permissions, as stated in error message:
Just because I can should I use Private Office 365 CDN
This is about a topic brought up by Waldek Mastykarz: Just because you can should you use the Office 365 CDN. In my post I want to take a closer look at the private CDN option in Office 365. Please note, the whole thing is subject to change, and it reflects the circumstances at the time of writing - 2019-08-26.
I’ll skip the introduction of Office 365, let’s jump directly to the Private CDN option. Consider following scenarios.
My list of _layouts pages
There are many resources on the internet that list _layouts/15 urls in SharePoint. Some are outdated, some are too short, some are to long. Here is my list of the urls, that I am going to update when I need. All the urls start with [Your-Tenant].sharepoint.com/sites/[Your-Site]/_layouts/15/ Here we go:
- viewlsts.aspx - Site Contents, Modern View
- viewlsts.aspx?view=14 - Site Contents, Classic View
- appinv.aspx - Grant Permissions to an App
- appregnew.aspx - Register a new SharePoint Application
- appprincipals.aspx - List Registered Add-Ins
- CreateGroup.aspx - Create Site page (Team and Communication)
- TA_AllAppPrincipals.aspx - List all app principals
Update Field.JSLink using JSOM or REST
Today I have just a little code snippet to share. This code snippet shows how to update the JSLink property for an existing field using JSOM and REST. For REST I use sharepoint-utilities. [code language=“javascript”] var updateJsLinkCsom = function(config) { var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(config.listTitle) var fields = list.get_fields(); var field = fields.getByInternalNameOrTitle(config.fieldTitle) field.set_jsLink(config.jsLink) field.update() ctx.executeQueryAsync() }; var updateJsLinkRest = function(config) { SP.SOD.registerSod(‘sputils.js’, ‘/sputils.min.js’) SP.SOD.executeFunc(‘sputils.js’, ‘’, function() { var url = _spPageContextInfo.webAbsoluteUrl + ‘/_api/web/lists/getbytitle(\’’ + config.listTitle + ‘\’)/fields/getbyinternalnameortitle(\’’+ config.fieldTitle + ‘\’)’; var payload = {’__metadata’: {’type’: ‘SP.Field’}, ‘JSLink’: config.jsLink}; var config = {‘headers’ : {‘X-HTTP-Method’: ‘MERGE’ }}; sputils.rest.post(url, payload, config); }); }; var config = { listTitle: ‘’, fieldTitle: ‘’, jsLink: ‘~site/’ }; updateJsLinkCsom(config); updateJsLinkRest(config); [/code] A couple of notes, to update a field we need:
Trigger SP2010 Workflows using JSOM
Today I found out how to start workflows in JSOM (JavaScript Object Model in SharePoint). Nothing special, but since it is not documented, it took me a while to find a solution. Here is the code which I want to keep as simple as possible. What you need to start a SP2010 Workflow for a list item or a document in JSOM, you need to load SP.WorkflowServices.js and you need to create the manager and get the service, then you can trigger a workflow using the workflow name, the list guid and the guid of the list item: [code language=“javascript”] var ctx = SP.ClientContext.get_current(); var workflowServicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web()); var service = workflowServicesManager.getWorkflowInteropService(); service.startWorkflow(workflowName, null, listGuid, plainItem.guid, initiationParams); [/code] Here is the code to trigger a workflow for multiple items: [code language=“javascript”] //fire the workflows function fire2010WorkflowForListItems(ctx, listGuid, plainItems) { var workflowServicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web()); var service = workflowServicesManager.getWorkflowInteropService(); for(var i = 0; i < plainItems.length; i++) { var plainItem = plainItems[i]; console.log(‘scheduling workflow for id: ‘, plainItem.id); service.startWorkflow(options.workflowName, null, listGuid, plainItem.guid, options.initiationParams); } console.log(’now executing…’); ctx.executeQueryAsync(function() { console.info(‘yes, workflows completed for ’ + items.length + ’ items’); }, function() { console.error(‘it didnt go well’); }); } [/code] The code above is inspired from this gist and sharepoint stackexchange. It is a simplified version that only works for list item workflows and SharePoint 2010 workflows. Here is an example how you can get multiple items and batch start a workflow: [code language=“javascript”] //just a couple of variables var options = { workflowName: ‘Behörigheter’, listName: ‘Documents’, initiationParams: {} }; //load list items function startWorfklows() { //Start 2010 Workflow for a List Item var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(options.listName); ctx.load(list); var items = list.getItems(new SP.CamlQuery()); ctx.load(items); ctx.executeQueryAsync(function() { var listGuid = list.get_id() + ‘’; var en = items.getEnumerator(); var plainItems = []; while (en.moveNext()) { var it = en.get_current(); //do not take checked out files, it won’t work if (!it.get_item(‘CheckoutUser’)) { plainItems.push({id: it.get_id(), guid: it.get_item(‘GUID’) + ’’ }); } } fire2010WorkflowForListItems(ctx, listGuid, plainItems); }, function() { alert(‘boom’); }); } //Load Worfklow Js dependency var wfScript = ‘SP.WorkflowServices.js’ SP.SOD.registerSod(wfScript, _spPageContextInfo.webAbsoluteUrl + ‘/_layouts/15/SP.WorkflowServices.js’); SP.SOD.executeFunc(wfScript, ‘’, startWorfklows); [/code]
Minimal Download Strategy. Simple
There are many correct ways (1, 2, 3, 4, 5…) of making scripts work with the Minimal Download Strategy Feature (MDS) in SharePoint 2013 and 2016. But to be honest - every time I need it, I get confused. So now it is time to find a simple solution for that. Who is better at it than the developers of the SharePoint themselves? Look at the MDS code in the built-in Display Templates: Let’s keep it as simple as Item_Default.js, let’s take it as it is and create our own scripts. Here is a skeletton of and MDS-ready script: [code language=“javascript”] function runMyCode() { var time = new Date().toISOString(); console.log(‘runMyCode’, time ); } runMyCode(); if (typeof(RegisterModuleInit) == ‘function’) { var scriptUrl = ‘/Style Library/runMyCode.js’; RegisterModuleInit(scriptUrl, runMyCode); } [/code] Which boils down to this in pseudocode:
Minimal Display Template
We want to use our own Display Templates on Non-publishing sites - our team sites. Without the Publishing Feature activated you have to create an own javascript file. Here is short and concise instructions how to install it: Display Templates on Non-publishing Sites. As described on that blog, you can make copy of an existing Item_Default.js and adjust to your needs. I also asked Elio Struyf and I got the same tip. I did create my starter template. Here I want to share this very minimal javascript based Display Template. The real Minimal Display Template is in the SPCSR github repository: Item_Minimal.js It has been improved by Elio Stuyf himself :) [code language=“javascript”] (function () { // Config contains variables that are defined in one place var config = { propertyMappings: { ‘Path’:null, ‘Title’:[‘Title’] } }; var templateUrl; var register = function () { if (“undefined” !== typeof (Srch) && “undefined” !== typeof (Srch.U) && typeof (Srch.U.registerRenderTemplateByName) === “function”) { Srch.U.registerRenderTemplateByName(templateUrl, render); } }; render = function (ctx) { // Display template data var cachePreviousTemplateData = ctx.DisplayTemplateData; ctx.DisplayTemplateData = { ‘TemplateUrl’: templateUrl, ‘TemplateType’: ‘Item’, ‘TargetControlType’: [‘SearchResults’, ‘Content Web Parts’], ‘ManagedPropertyMapping’: config.propertyMappings }; var cachePreviousItemValuesFunction = ctx.ItemValues; ctx.ItemValues = function(slotOrPropName) { return Srch.ValueInfo.getCachedCtxItemValue(ctx, slotOrPropName); }; // Retrieve managed property data var path = $getItemValue(ctx, ‘Path’); var title = $getItemValue(ctx, ‘Title’); // HTML markup for an item var htmlMarkup = String.format( ‘’ + ‘{1}’ + ‘’, path, title); // Caching ctx.ItemValues = cachePreviousItemValuesFunction; ctx.DisplayTemplateData = cachePreviousTemplateData; // Return the HTML markup return htmlMarkup; }; // Retrieve all the loaded scripts var allScripts = document.getElementsByTagName(“script”); // Get the last script file (this is the current DT file) var scriptUrl = allScripts[allScripts.length - 1].src; if (scriptUrl.indexOf(’/_catalogs/’) > 0) { // Remove the query string if (scriptUrl.indexOf(’?’) > 0) { scriptUrl = scriptUrl.split("?")[0]; } // Insert the site collection token templateUrl = ‘~sitecollection’ + scriptUrl.substr(scriptUrl.indexOf(’/_catalogs/’)) // Register the template to load register(); if (typeof (RegisterModuleInit) === “function” && typeof(Srch.U.replaceUrlTokens) === “function”) { RegisterModuleInit(Srch.U.replaceUrlTokens(templateUrl), register); } } })(); [/code]
SharePoint Utilities - a promising JavaScript Framework
My colleagues at Bool have developed a new JavaScript framework for SharePoint - sharepoint utilities. It started on our DevDay last year - a whole free day when we could learn new things, try out new techniques or build something that was not even requested from a customer. I was not working on sharepoint utilities, so I almost forgot it until… I recently re-discovered sharepoint utilities. It is on Github, it is MIT licensed and contributions are welcome. The core of sharepoint utilities (sputils) is a set of wrappers for Search, TermStore, REST that allow you be more productive as a developer. What I find especially compelling with that it contains some other fundamental stuff that every SharePoint developer needs:
A tiny tool for User Custom Actions
Everybody loves User Custom Actions in SharePoint. That’s the only recommended way of customizing SharePoint. You have heard about it. Unfortunately there is no convinient way of administering them. People have their console applications or powershell scripts to add, update and delete user custom actions. It works but it is hard to open up Visual Studio or PowerShell every time you will try out an idea on a test site. To overcome this, I have created a tiny little tool, packaged as a bookmarklet for your browser. When you click on it, it will show your existing user custom actions and you can add new user custom actions. It is an ongoing little project, available on github, contributions are welcome. What’s left is:
Provisioning Google Maps JSLink with SPMeta2
Among PnP Samples there is a solution for using Google Maps. Great solution where where you can pick a point on a map and define a spacial area on the map. Unfortunately it is a sandbox solution. I rewrote it to a code based template with SPMeta2 Framework. Now it can be installed on any site very easily, without needing UserCode Service and a cumbersome process of uploading a wsp package and activating it. The code is very simple, you can see it on github.
My first Office Add-In
Yesterday I participated in the Hackathon at European SharePoin Conference in Stockholm. The main goal was to learn more about Office Add-Ins. I wanted to create a very very simple app to learn the basics. Here in this post I’ll provide some links and describe the steps needed to start developing your Office Add-Ins. The Add-in I created is an Outlook Add-In, it is called “Joke Inserter” and with it you can insert a random Chuck Norris joke. It is just for fun, but it demonstrated how an add-in can be installed, made available in “New E-mail” and interact with the e-mail you are writing.
Copy SharePoint WebDav Address to Clipboard
While configuring SharePoint sites and helping users I often use File Explorer View for editing pages, resources like css and javascript. In IE there is a dedicated button in the ribbon for that. Sometimes it works, sometimes it doesn’t, because of permissions or other restrictions. Anyway, I use Firefox and Chrome while troubleshooting and developing, so I have created a bookmarklet for copying the webdav address of a site that is open in the browser. [source language=“javascript”] var uri = _spPageContextInfo.webAbsoluteUrl.replace(/https?:\/\//i, “\\\\”).replace(/\//g, “\\”); window.prompt(“Copy to clipboard: Ctrl+C, Enter”, uri); [/source] Unfortunately, there is no copy function in javascript, the prompt solution plus Ctrl-C works fine. The bookmarklet: [source language=“html”] javascript:void%20function(){var%20o=_spPageContextInfo.webAbsoluteUrl.replace(/https%3F:\/\//i,%22\\\\%22).replace(/\//g,%22\\%22);window.prompt(%22Copy%20to%20clipboard:%20Ctrl+C,%20Enter%22,o)}(); [/source] Enjoy
Export Any Web Part using a Bookmarklet
My blog post about exporting any webpart from a SharePoint Page is one of the most read articles on my blog. I use this method a lot. Now what I want to do is to simplify the process. Inspired by my colleague Dan Saedén’s awesome bookmarklet for reading and updating web properties, I decided to make my own bookmarklet. That was easy. Now we can export any web part from any SharePoint page without even looking at any ids in the html markup and assembling the export url manually. Just add the bookmarklet or run the javascript code in the browser console. The code (js and bookmarklet) is on Github. Here is an animated gif that explains how to use it:
Add Search Verticals by code
Adding own search verticals is a common task in the Search Configuration in SharePoint. Here I want to share a code sample for achieving this programmatically. I hope, this model can be added to SPMeta2. First of all, Search Verticals are dedicated Search Results Pages and links to them. How to add them manually is described on technet:
There is no API in CSOM for that. Luckily, Mikael Svenson found how to get the Search Navigation and contributed to PnP by writing an Extension: web.LoadSearchNavigation. Here is my sample code for adding new Search Verticals programmatically: [source language=“csharp”] NavigationNode searchNav = context.Web.Navigation.GetNodeById(1040); NavigationNodeCollection nodeCollection = searchNav.Children; NavigationNodeCreationInformation everything = new NavigationNodeCreationInformation { Title = “Everyting”, Url = “/search/Pages/results.aspx”, }; NavigationNodeCreationInformation myresults = new NavigationNodeCreationInformation { Title = “My Results”, Url = “/search/Pages/myresults.aspx”, }; nodeCollection.Add(everything); nodeCollection.Add(myresults); context.ExecuteQuery(); [/source]
What is a SharePoint application
[caption id=“attachment_3759” align=“alignnone” width=“660”] A meaningful collection of Lego bricks is a toy. A meaningful collection of Lists, Fields, Files and other SharePoint artefacts becomes a SharePoint Application. Private picture.[/caption] App, Add-In, List, Web, Site, Sandbox solution, Workflow. There are too many words flying around in SharePoint that confuse users and Non-SharePoint-Developers. I want to introduce a “new” concept that is so simple and that a company can understand and govern: a SharePoint Application. That is so simple. It can be called a tool, a functionality. That can be a SharePoint list, a document library with a workflow, or a document library with custom jslink. All they can be SharePoint Applications. Let’s use lego as a metaphor. Have you seen this? [caption id=“attachment_3760” align=“alignnone” width=“660”] The same toy car in just brics. SharePoint Artefacts like Webs, Lists, Fields, Content Types, JSLink etc are just lego bricks. Private picture.[/caption] These lego bricks together become a cool toy that you can play with (as you can see in the picture above). So it is with SharePoint Applications, too. SharePoint Applications solve actual business needs. A List, or a JSLink by themselves do not solve a business need. It must be a meaningful collection of SharePoint Artefacts that becomes a SharePoint Application. Example Does the lego metaphor make sense to you? To go back to SharePoint, I’ll give you an example of a SharePoint Application. I would say everybody has done such Applications. In a project we created a document library for product icons that were used for all products in a company. Easy? Yes. But the icons had several states (active, inactive…). Versioning and Approval was required. A workflow for new requests and submits was implemented, too, permissions for different roles, metadata navigation in the document library and so on. Sure, SharePoint provided us with great “lego bricks”. But we created a tool, a functionality - a SharePoint Application, that makes sense to our business. What’s new then? Well, we all have done such applications. The new is to understand SharePoint Applications as an own alternative and quality assurance. See more below. Another example is an “App” for SharePoint Online that I converted into a SharePoint Application by adjusting it for SPO and OnPrem. That’s when I came up with the idea of the SharePoint Application. Definition
Http to Https Redirect in Provider Hosted Apps
It is strongly recommended to use https in SharePoint Provider Hosted Apps. In many provider hosted apps I have seen, only https works. I would recommend to configure a simple http to https redirect in IIS and make solutions better. Many Provider Hosted Apps can be done in that way that they are available without SharePoint Context, e.g. for browsing information. In that case that is important to have an easy url and an automatic http -> https redirect. In this post I’ll give a short manual for doing that. I would recommend this step for all provider hosted apps. 1. In the Provider Hosted Apps Server install the URL Rewrite IIS Module using Web Platform Installer: 2. Next step is to add the http binding to your solution (this is needed for the future redirect): Then you can configure the automatic http to https redirect using the GUI or the web.config update. My instructions originally come from JPPInto.com blog. I suggest updating the web.config file directly in the Provider Hosted App: 3. Add this section to the web.config file: [source language=“xml”] <system.webServer> </system.webServer> [/source] It is important to know that his web.config section will cause failure on the server if URL Rewrite module is not installed. Summary These steps are very easy to accomplish and I recommend it for every Provider Hosted App, especially those ones that are accessible without going through SharePoint (Web Content -> Apps). This also reflects the configurations in Azure Apps (WebSites).
Kom igång med SPMeta2
SPMeta2 (eller bara M2) är ett relativt nytt ramverk för provisionering av SharePoint-artefakter. Bakom ramverket ligger ett gediget arbete. I den här posten vill jag skriva upp mina steg för att sätta upp ett litet projekt. För mig är SPMeta2 nytt och huvudprincipen i den här bloggposten att få en fungerande lösning så snabbt som möjligt. Informationen här kan snabbt bli inaktuell, eftersom SPMeta2 förändras och förbättras väldigt snabbt. Vad är SPMeta2 SPMeta är ett ramverk för att provisionera SharePoint-artefakter, allt från fält, innehållstyper, listor, dokumentbibliotek, user custom actions, ladda upp filer med mera. Klassiskt har vi gjort provisionering med hjälp av XML-baserade moduler och features. SPMeta2 erbjuder ett Fluent API som är kodbaserat. Med hjälp av SPMeta2 definierar man en modell (enkla objekt POCOs) som inte har beroendet till SharePoint. Modellen används sedan av Provision-delen som anropar modellen för specifika versioner: SharePoint 2013, SharePoint 2010, Office 365 med mera. Man kan välja CSOM och SSOM. Provision är också flexibel vad som gäller paketering: det kan vara en konsolapplikation, en SharePoint-app, ett wsp-paket, en PowerShell-modul. Se följande länkar:
Method "GetList" does not exist
I troubleshooted a piece of CSOM code in SharePoint 2013. I got the following error:
Method “GetList” does not exist
The reason was that the method GetList was not imlemented until March 2015 CU (15.0.4701.1001), and the SharePoint farm I had was SharePoint 2013 SP1 (15.0.4569.1000). So the solution is to install the Cumulative Update or use web.Lists.GetByTitle. GetByTitle has one aweful shortcoming: it doesn’t work in multilingual environments. So I have recommended to install the March 2015 CU.
Tillgänglighet i SharePoint
From 1 januari 2015 är bristande tillgänglighet inkluderad i svenska diskrimineringslagen. Detta krav på tillgängligt webbinnehåll ställer högre krav på SharePoint-baserade webbplatser i offentliga sektorn (och helst i alla webbplatser). Regler och riktlinjer för tillgänglighet på webben är definierade av W3C i ett dokument som heter: Web Content Accessibility Guidelines (WCAG) 2.0 vilket finns i en auktoriserad översättning på svenska: Riktlinjer för tillgängligt webbinnehåll (WCAG) 2.0. (Gjort av Funka)
Hur ska vi tänka om Tillgänglighet i SharePoint
Som vilket webbaserat system som helst bör man i SharePointlösningar tänka på tillgänglighet i alla faser av projektet. Liksom säkerhet och prestanda, finns Tillgänglighet med både i Design- och arkiktekturfasen, i utvecklingen, i lanseringen och utbildingen samt i förvaltningen av ett system. Det ska finnas med Governance-modellen. SharePoint är såklart inte ett vanligt webbsystem, utan det är ett stort metasystem. Vi kan dela in det i tre lager för att kunna hantera problem som kan uppstå: [caption id=“attachment_3709” align=“alignnone” width=“454”] ”Sköldpaddor hela vägen ner”: Tre lager av SharePoint som påverkar tillgänglighet: Platform, Egna Lösningar och Använarinnehåll[/caption]
Onpremifying SharePoint apps
We want to make an app available in SharePoint OnPrem, we want to onpremify it. Rethink SharePoint apps and provisioning SharePoint artifacts. It has been a while since I updated my blog – Chuvash.eu. I had my vacation, I visited the sunny and green Chuvashia. Now I am back and I am looking forward to an awesome SharePoint Autumn. One of the first things I had to deal with in this SharePoint Autumn was Onpremifying of a SharePoint Online App. We have an app that has gained popularity and we want to make it available for SharePoint OnPrem. There is no such word Onpremify (yet?), I know, it is a Swenglish happy word making (onpremifiera), but I like the word “onpremify” a lot. There is still uncertainty around the purpose of SharePoint apps. One app type, though, has been used a lot in our company: an app that provisions SharePoint Artifacts – that creates SharePoint Applications. What I mean by SharePoint Applications can be read in my blog post:
Resetting SharePoint Search Configuration Cache
Now it is the second time it happens that the search cannot return any results. This hickup is rare but it happens. To solve it I had to follow these steps:
- Stop the Timer Service
- Clear the configuration cache
- Find in \ProgramData\Microsoft\SharePoint\Config the folder where the file cache.ini exists
- Delete every file from this folder EXCEPT cache.ini
- Open cache.ini, delete the content and put ’1′ (without the quotes) in it and save the file
- Restart the Timer Service
- Index reset
- Full crawl
Source: ITIDea. The linked blog post saved my afternoon today. Thank you, Anita Boerboom.
Why Swedish matters
I Sverige är engelskan är väldigt stark. Speciellt i IT-branschen är vi vana att ha i princip allt på engelska, från kommentarer i koden till stora upphandlingar, rapporter och dokumentation. Trots det ser jag ett stort behov av att kunna prata om IT på svenska. Det gäller både lokala företag och globala företag. Det finns flera anledningar:
- Företag i Sverige följer svenska lagar som är skrivna på svenska, för att leva upp till kraven ska man kunna formulera sig på svenska.
- Modersmål eller det språk som man använder mest i vardagen (gäller mig bland annat) är den snabbaste vägen för kommunikation som ger en högre grad av nyansering. Att kunna nyansera krav och önskemål tidigt i projekt är guld värt (enligt många av mina korrespondenter). Man behöver spendera mindre tid på att formulera och tolka krav.
- En mer ideologisk anledning (men en viktig sådan) är att vi som bor i Sverige har skyldighet att utveckla och hålla svenskan levande, inte minst inom IT-sektorn.
Svenska är en stor möjlighet för att verkligen ge mervärde till våra kunder, möta dem på hemmaplan, prata ett gemensamt språk. Startpunkten till den här diskussionen har varit en ny webinar som jag planerar hålla den 14 april kl 10. Webinarens titel är SharePoint i molnet.Det finns ganska mycket information om SharePoint Online och Office 365 på engelska. Det är dock ganska sparsamt med information på svenska. https://www.eventbrite.com/e/sharepoint-i-molnet-tickets-15976529229 Det här är det som väntar dig som vill delta i webinaren:
Publishing Visio drawings as SVG
In my post yesterday I showed how to publish Visio files as html image maps. That was one of the alternatives. Today I’ll present how to use SVG to achieve the same goal: publish Visio diagrams in SharePoint without having the Enterprise license. There are some alternatives:
- Show Visio diagrams as pdf files on SharePoint Pages
- Embed Visio diagrams as html image maps - Read more in my previous blog post
- Embed Visio diagrams as svg pictures - This blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
SVG
SVG stands for scalable vector graphic, it is a xml-based format for defining images. It is supported in all modern browsers. Because SVG can be part of a page markup, it can be easily embedded into SharePoint.
Publishing Visio diagrams as html image maps
I got a question from a customer: We have our processes defined in Visio, we don’t have SharePoint Enterprise CALs to use the Visio webpart. We have links in process maps. What can we do? Well there are three five ways to solve this business need:
- Find money for SharePoint Enterprise - Very expensive
- Show Visio diagrams as pdf files on SharePoint Pages - Expensive.
- Embed Visio diagrams as html image maps - Least expensive
- Embed Visio diagrams as svg pictures - Separate blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
If the business needs other features available only in Enterprise, just use the solution 1. Stop reading. If you are looking for alternatives, then consider pdf and image maps. I have seen projects where pdf files were embedded in the SharePoint Pages. It required a pdf plugin in IE, a lot of time to make it look the same in different browsers and the scroll and fixed size was still there. It was expensive because of the development and configuration time. In this blog post, I want to show the alternative number 3: embedding Visio diagrams as html image maps. This is only a Proof-of-concept so far.
Struggling with Taxonomy in CSOM
The parts of the CSOM for updating Taxonomy fields are really cumbersome. I mean, look at this code, nicely provided by Vadim Gremyshev (@vgrem). To set a value in a taxonomy field we have to assemble a text representation, and adding a “fake” lookup id. What is needed is a wrapper for handling Taxonomy fields. SPMeta2 and PnP don’t seem to have it yet. Another issue that I have struggled with today was the missing Microsoft.SharePoint.Client.Taxonomy.dll. If you see this error (set customErrors=“Off” in the Web.config), then you have update the reference in the Visual Studio project: Open Properties for the reference called: Microsoft.SharePoint.Client.Taxonomy and ensure that Copy To Local is set to True: For some reason, this reference added through “App for SharePoint Web Toolkit” nuget package adds a reference to an assembly from your computers GAC.
Bypass all custom jslink
Client Side Rendering (CSR) and jslink are great for customizing lists and forms in SharePoint. In my current project we use it a lot of it. A disadvantage of that path, although, is that it might occur javascript errors, during the development phase, but also in production. We do, of course, our best to leverage the best jslink code, but unfortunately we have to live with the fact that errors can occur, especially when we use it for NewForm, EditForm, DisplayForm and View (in list and grid). If an error occurs, it won’t stop the rest of javascript (it is wrapped in try and catch by SharePoint), but the fields will still not function as intended. It can also be some “corrupt” or old data in the field value that will “break” the jslink code. I would like to suggest one little fix, an idea I’ve come up to in my jslink-heavy project:
Client Side Rendering with Async dependencies
Yesterday I asked a question on SharePoint StackExchange:
I also asked Elio Struyf on Twitter: https://twitter.com/eliostruyf/status/540473976255152128 Good idea, Elio Struyf! Now I want to try it out.
Preparations
In this case I’ll be using my example from my blog post yesterday: Drag and Drop Image using Client Side Rendering I have created a new list and added a lookup field to my previous list. What I get is a Title of the lookup item, but not my custom field called DragAndDrop. In my test I will try to load the DragAndDrop Image using an ajax call and rendering it after Client Side Rendering is done with my item. To be complete, I want to show some screenshots for my lookup field: It will result in this OOTB rendering:
Drag and Drop Image using Client Side Rendering
I continue my series about Client Side Rendering (CSR) and jsgrid. Today I want to try a custom field where users can drag and drop images. The inspiration comes from:
- AutoUpload field written by Anton Vishnyakov and
- Base64 Drag and drop written by oroboto
What I want to achieve is:
- A custom field that is rendered with jslink
- Users can drag and drop small pictures (thumbnails) into the field
- A base64 image representation is saved as the field value
- Optionally implement pasting images using Clipboard API
Step 1 Create a field with a custom jslink
Create a field of type Note. I am using the PnP Core Extensions to make it quickier: ’ My jslink file is very simple to begin with: [code language=“javascript”] (function () { ‘use strict’; function view(ctx, field) { return “hello”; } var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘DragAndDropImage’: { ‘View’: view, ‘DisplayForm’: view //‘EditForm’: verySimpleNewAndEdit, //‘NewForm’: verySimpleNewAndEdit } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] This will result in the following display form. Just outputting “hello” indicates that my field is jslink are registered correctly:
Disabling a column in Quick Edit
In my project I have a column called Request Status. This column is not shown in any forms, meaning users should not edit, because it is controlled through the app. Nevertheless it is editable in the Quick Edit. Yesterday I wrote about jsgrid in my blog. Now comes more. Today I’ll share a little practical solution how one can disable editing a field in Quick Edit. The field is edited in jsgrid, but to disable it, we only have set the property called AllowGridEditing to false on our column (not even touching the heavy jsgrid api). We can do in the OnPreRender event in our Client Side Rendering (CSR) registration. Having the context object we have access to the Fields (ContextInfo.ListSchema.Field): [code language=“javascript” highlight=“6,9”] (function () { var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.OnPreRender = function(ctx) { var statusField = ctx.ListSchema.Field.filter(function(f) { return f.Name === ‘Request_x0020_Status’; }); if (statusField) { statusField[0].AllowGridEditing = false; } } SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] Another way is to implement the display form: [code language=“javascript”] (function () { var view = function (ctx, field) { if (ctx.inGridMode) { field.AllowGridEditing = false; } return window.RenderFieldValueDefault(ctx); }; var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘Request_x0020_Status’: { ‘View’: view } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code]
JSGrid Basics
JSGrid is the javascript framework in SharePoint used in Quick Edit View (previously Datasheet View). There are a few very good blog posts on this topic (See below in “Sources”). Nevertheless the fact is that jsgrid and working with quick edit from a developer’s perspective is a huge undiscovered area. Articles I have seen are intended for advanced developers. The goal with my post today is to outline the very basics of working with JSGrid. When you know the basics you will be more comfortable to discover and try out more. The example I want to show is a jsgrid code for a “VerySimpleColumn”. The source code can be found on gist.github.com To focus on jsgrid, I assume you have knowledge and some experience of working with jslink, which is related to jsgrid.
Announcing web based SQL Max Memory calculator
Today I want to announce a tiny web application for calculating max memory in the SQL Server to improve the overall performance in you SharePoint environment: SQL Max Memory Calculator. One of the important actions to improve the performance in SharePoint is fine tuning of the SQL Databases. Regarding the databases one of the crucial settings is the Max Memory Setting. You can read more about database optimizations for SharePoint in a whitepaper written by SharePoint MVP Vlad Catrinescu. The document is available on the SharePoint Community Web Site:
Export any web part from a SharePoint page
The blog post below describes the technical details about how Web Parts can be exported using a hidden tool in OOB SharePoint, though this requires manual assembling of a special url. If you are just interested in a solution for an easy Web Part Export function, just proceed directly to my new blog post where you can download my tool that you can add to your web browser.
Export SharePoint List Data To Xml through PowerShell
Today my colleague Johannes Milling wrote an awesome post: Export SharePoint List Data To XML Directly from the GUI He uses the old and forgotten RPC-based web service owssvr.dll (that has existed since SharePoint 2003). This url pattern is used to get the xml-formatted list data for a specific ListView: [source] http://<site_url>/_vti_bin/owssvr.dll?Cmd=Display&List=&View=&Query=*&XMLDATA=TRUE [/source] To automate this I have written a PowerShell function. All the details are in the comments: [source language=“PowerShell”] function Export-OIPSPListDataAsXml { <# .Synopsis Exports list items as xml .DESCRIPTION This function uses a built-in hidden service owssvr.dll in SharePoint .PARAMETER Web SPWeb or a url for the SPWeb object where the list resides .PARAMETER ListName List Name (List Title) .PARAMETER ViewName Name of the List View to export the data .EXAMPLE Export-OIPSPListView -Web http://myawesomesite -ListName “Teddy Bears” -ViewName “All Items” .EXAMPLE Export-OIPSPListView -Web $webInstance -ListName “Top Links” -ViewName “All Items” .Notes Name: Export-OIPSPListDataAsXml Author: Anatoly Mironov Last Edit: 2014-09-11 Keywords: SPList, SPWeb, SPListView, Xml .Link http://chuvash.eu #> [CmdLetBinding()] param( [Parameter(Mandatory=$true)] [Microsoft.SharePoint.PowerShell.SPWebPipeBind]$Web, [Parameter(Mandatory=$true)] [string]$ListName, [Parameter(Mandatory=$true)] [string]$ViewName) $spWeb = $Web.Read() $list = $spWeb.Lists[$ListName] if (!$list) { throw “List $ListName on web $($spWeb.Url) could not be found” } $view = $list.Views[$ViewName] if (!$view) { throw “View $ViewName on web $ListName could not be found” } $url = “{0}/_vti_bin/owssvr.dll?Cmd=Display&List={1}&View={2}&Query=*&XMLDATA=TRUE” ` -f $spWeb.Url, $list.ID, $view.ID $wc = New-Object Net.WebClient $wc.UseDefaultCredentials = $true $wc.DownloadString($url) } [/source]
Improving the web performance of an intranet
[caption id=“attachment_3437” align=“alignnone” width=“480”] All the “small” app parts, web parts, delegate controls, user controls, and other “packages” that “must” be delivered to the users on every page load of the Start Page of your Intranet.[/caption] Recently we made an investment to improve the performance of our intranet. We made many changes in different layers: SQL, Network, Browser upgrade and code. Here I want to tell about what code changes we did to improve the web browser performance. Please leave feedback if you find it useful. You can also share your suggestions. We measured the performance before our code changes and after them. We had amazing results. Unfortunately I can not share any numbers, but we improved the Time to First Byte, time to load event firing in the browser, memory consumption in the clients and, perhaps, the most important, we improved the perceived performance of the Intranet, the way how users experience the speed and UI responsiveness. To do this I got many ideas of my project colleagues and branch colleagues. Here is the list of changes we’ve implemented:
Do not mess with the hive
In our Intranet we got this nasty double encoding error that was introduced in SharePoint April 2014 CU. In July 2014 CU the problem is still there. I often hear the suggestions to update files directly in the hive (the root folder for SharePoint: C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\) In that blog post it is described what the problem is and what files are affected and what code must be altered in order to get it to work (which I like). But it is also suggested to update the Search.ClientControls.js directly on the server (which I don’t like). So my advise is:
Showing Birthdays and Job Anniversaries in the Newsfeed
In our project we have a requirement to show birthdays and job anniversaries in the Newsfeed. The solution is simple (when you know it) but there has not been any information about it online, until today. I want to share a few lines of PowerShell code to enable Anniversary notifications in the Newsfeed. This desired piece of code was written by my colleague Emma Degerman. Enjoy:
[source language=“PowerShell”] $job = Get-SPTimerJob | ? { $_.TypeName -like “*.UserProfileChangeJob” } $job.GenerateAnniversaries = $true $job.Schedule = [Microsoft.SharePoint.SPSchedule]::FromString(“hourly between 55 and 55”) $job.Update() [/source]
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
A presentation about PowerShell and SharePoint
Yesterday I had a little presentation about PowerShell basics in the SharePoint context. Here you can see the presentation I’ve published on slideshare. The text is in Swedish.
[slideshare id=37316916&doc=sharepoint-140724063012-phpapp01&w=600]
Updating hover style in IE8 Developer Tools
In our project we still have to support Internet Explorer 8. The CSS issues in IE8 are most difficult to debug and solve. You can not add a new rule in Developer Tools or toggle the state of an element to hover as in moder web browser dev tools. One solution that I’ve come up to today, is to add a style with javascript or jQuery, open the script pane in IE8 Dev Tools and add this line: [code language=“javascript”] $(’.ms-srch-item:hover {filter:none !important;}’) .appendTo($(‘body’)) [/code] This will fill update the hover effect of the .ms-srch-item directly. That’s it, just a little tip.
Debugging "What's happening" in Communities
Recently an issue was reported about count mismatches in SharePoint 2013 Communities. The number of replies in category tiles sometimes is different compared to the community stats in the web part called “What’s happening”. The actual number of replies is 1 in the figure below. The user who has reported has tried to add, update and delete discussions and replies. I have invested some time debugging this issue. It would be pity to not share my findings. Well the first thing to do was to determine the type name for the “What’s happening” web part. To do so just edit the page and export the web part. In the exported .webpart file I saw that the type was Microsoft.SharePoint.Portal.WebControls.DashboardWebPart. With that knowledge it is time to open ILSpy, an awesome and free(!) assembly browser and decompiler. Load the “Microsoft.SharePoint.Portal” assembly from GAC into ILSpy. Then use F3 to search for DashboardWebPart: The number of replies is retrieved from SPWeb.AllProperties: If the Property Bag does not contain it, it gets the number of replies from the list. The formula is as follows: [code language=“csharp”] list.ItemCount - list.RootFolder.ItemCount [/code] It means that it gets the number of both discussions and replies: ItemCount of Discusssions List. The number of Discussions is determined by the ItemCount in the RootFolder of the Discussions List. Discussions are List Items in the RootFolder (num2 in the figure below). Replies are saved in the subfolders, every discussion gets an own folder. The number of all replies are num3 in the figure below. After checking the web properties I could see that the number of replies there were wrong: 2. The next step was to determine where and when the Web Properties are updated. The first guess every SharePoint Developer has in such cases is an EventReceiver. Here are all EventReceivers connected to the Discussions List: [code language=“powershell”] $list.EventReceivers | select class, Type, Synchronization | Out-GridView [/code] Allright, CommunityEventReceiver then: Found where the actual update happens: CommunityUtils.UpdateWebIndexedPropertyBag The method is used in DiscussionListCommunityEventHandler.HandleEvent There is a flag, flag5 that is used to determine if the Web Properties should be updated: But the flag5 is not true on Delete operations in some code flows: That’s it. So deleting a reply will not have any effect on “What’s happening”. But adding a new discussion will also update the stats: To summarize the debug session, there is an issue in the OOB code that misses to update community stats when deleting a discussion or a reply. Adding a new discussion, or a reply will synchronize the stats.
Tip: Use the weakest CSS selectors
I am reading Mobile HTML5 written by Estelle Weyle. It is an awesome recap and new knowledge about html, css and javascript. I want to highlight one of tips I got: Use the weakest CSS selectors (can be found on page 204). We all know, that inline CSS and !important are evil. They have a higher level of specifity and override the standard cascade of the CSS rules. If you use !important, then it will be hard to override CSS rules when you really need it. After these two classic “evils” the evil number three is overqualifying of CSS selectors. You should really never add more classes or ids or elements than needed. Consider this: [code language=“css”] .warning { background-color: red; } [/code] It is often enough, you don’t need those: [code language=“css”] html .warning div .warning div.warning, div > .warning body p#myP.blue strong.warning [/code]
Using CAML with SharePoint REST API
Do you prefer REST over CSOM as I do? I’ll skip the whys. Andrew Connell put it already in wrtiting so nicely. Well, if you do prefer REST, then you must have discovered some shortcomings of REST, or its incompleteness compared to CSOM. I think of:
- Inability to filter items based on multivalued taxonomy fields
- Inability to filter items based on user fields where user is added through a group, rather than directly, e.g. AssignedTo=[Me] combined with a SharePoint group.
- …
In such situations I was forced to use CSOM. Until yesterday. Yesterday I learned that we can actually use CAML queries in REST requests. This enables using REST in all situations. The REST API is still developed and many features are added. Maybe a particular operation that needs a CAML query today, can be supported in the core REST API and can be easily refactored then. But until then, we can use CAML queries in REST requests. Here are the important things about it:
What about the SharePoint app domain?
This is an open question about the domains for SharePoint apps. On Technet: Configure an environment for apps for SharePoint (SharePoint 2013) we can read the following:
You must configure a new name in Domain Name Services (DNS) to host the apps. To help improve security, the domain name should not be a subdomain of the domain that hosts the SharePoint sites. For example, if the SharePoint sites are at Contoso.com, consider ContosoApps.com instead of App.Contoso.com as the domain name.
First look at Yammer integration in SharePoint 2013 SP1
I have installed SharePoint SP1 on my development machine. Yammer and OneDrive links have appeared in the Central Administration: If you go ahead and click “Configure Yammer”, you can activate it: Because:
Yammer is Microsoft’s recommended tool for social collaboration.
When you activate Yammer, you’ll get this dialog, and the Yammer link in the SuiteBar: What happens when you click on Yammer, is that you are redirected to Yammer.com and you are prompted a login page. Then you have a usual yammer site with all your networks and stuff (in my case, SPC14 network): Then, if you go to your newsfeed, the following message is shown:
The sessions I attended
My colleagues and friends keep asking me what sessions I went to and what I would recommend to see on channel9 where all of them are publicly available. Here is my prioritized list of sessions:
- #spc325 Real-world examples of FTC to CAM transformations. This was the most exciting developer session. Vesa Juvonen takes the Cloud App Model to its maximum. Wanna know more about the future. See this session.
- #spc404 Build your own REST service with WebAPI 2. You know REST? You like $filter, $top and $select? Good, why not create an own api? You have all the tools in Visual Studio 2013. Just get inspired by Scott Hillier.
- #spc269 Developer audience keynote | What’s new for the Office & SharePoint developer. Get all the developer news presented at #spc14.
- #spc3999 SharePoint Power Hour - New developer APIs and features for Apps for SharePoint.
- #spc371 Developing socially connected apps with Yammer, SharePoint and OpenGraph. Chris Johnson talks about how to use Yammer API to post updates, like and comment from code. What if you wanted to send an update to Yammer from your Line-of-Business application? Very easy.
- #spc303 Advanced Performance Analysis for SharePoint. A real-world case study how performance of a SharePoint site is measured, captured and analyzed. Really interesting.
- #spc391 Deep dive into Mail Compose Apps APIs. Main compose apps are similar to SharePoint apps, they are run as iframes and can be used to update an email while writing it or start a workflow. Good stuff.
- #spc334 Real-world SharePoint architecture decisions. Wictor Wilén talked about his best topic: architecture decisions. He is probably the best in this area in the world, and his presentation becomes better and better every time he presents it.
- #spc3000 Changing the look of Search using Display Templates and CSR. You can do a lot of stuff using the Display Templates and Cliend-Side Rendering. See this session to get inspired and gather a deeper understanding how it works.
- #spc382 Managing Search Relevance in SharePoint 2013 and O365. How does XRANK work? Well it is complicated. This session is a must-see.
- #spc224 The SharePointConference.com Site: From Sketch to Launch to Live! Did you know that SharePointConference.com was built upon SharePoint? See this session to find out what was good in SharePoint for this site, and what workarounds and hacks were necessary to get it to work.
- #spc302 Advanced development patterns for SharePoint Apps. Provider-Hosted Apps are the best type of apps. Let’s see what examples and tips are provided in this session.
- #spc322 SharePoint 2013 Search display templates and query rules. An introduction to Search Display Templates.
- #spc301 Access is back! High-value, ’no code’, functional & flexible business apps with the new Access services. There were a lot of jokes in this session. Access apps are new “no-code” solutions and will replace the InfoPath solutions.
- #spc407 Deep dive into the SharePoint 2013 CSOM API’s. The name is not correct. It is a dive into the CSOM, but it is not deep. See it if you want an introduction, but please keep in mind, the examples don’t follow the javascript coding conventions.
- #spc381 Load testing SharePoint 2013 using Visual Studio 2013. Never used load-testing with Visual Studio? Got a 1.15 hr to kill? Well, see it to learn how to start the Visual Studio and what difference is between a web test and load test.
The sessions I wish I had attended:
My five takeaways from the SharePoint Conference 2014
The SharePoint Conference 2014 was an astounding event. Over 10 000 like-minded SharePointers that met, learned a lot and shared new ideas, couldn’t be better. It was also the first time I was to the U.S. and Las Vegas. What a country, what a city! This place must burn people’s lives faster than anywhere else in the world :) I want to share my five takeaways from this conference. I’ll keep it short:
Custom Error and Access denied pages in Sharepoint
Unfortunately in SharePoint 2013 the custom error pages are not applied: link 1, link 2. Hopefully there will be a hotfix that solves it.
Comments from Wordpress.com
ryan - Mar 5, 2014
I agree, I have seen a few about. Thanks for the post
Jon - Mar 2, 2014
PowerShell: Migrate field choices to a termset
In my current project we are migrating a custom sharepoint solution from SharePoint 2010 to SharePoint 2013. One of the improvements is that we migrate custom field choices to Managed Metadata. Choice Fields were not intended to be so many. So now it is time to convert them to metadata terms. I have written a PowerShell script which copies all the choices from a field to a termset. The script uses Client Side Object Model (CSOM) to get the choice values and it uses Server Object Model to write data to the termset. [sourcecode language=“PowerShell”] <# .Synopsis Use MigrateChoices.ps1 to migrate choices from a field to managed metadata. The source can be a contenttype field from SharePoint 2010 or from SharePoint 2013. .Description This script uses client object model to get the list items from the old environment. Then it uses the Server Object Model to create new terms and termsets (if needed) in the new environment. This script doesn’t override anything. The reason why we use it, is that importing feature isnt easy It creates a new, instead of adding new terms to old ones. It is very hard to create an csv file for that purpose. .Example MigrateChoices.ps1 -Source http://sp2010.contoso.com -Target https://sp2013.contoso.com .Notes Name: MigrateChoices.ps1 Author: Anatoly Mironov Last Edit: 2013-09-04 Keywords: CSOM, Field, FieldChoice, Metadata, Termset .Links http://chuvash.eu .Inputs The script takes Source parameter, it is url for the root web in the Source Site Collection The script takes Target parameter, it is url for the root web in the Target Site Collection .Outputs None #Requires -Version 2.0 #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)][System.String]$Source = $(Read-Host -prompt “Source site Url”), [Parameter(Mandatory=$true)][System.String]$Target = $(Read-Host -prompt “Target site Url”), [Parameter(Mandatory=$false)][System.String]$TermGroupName = “My group”, [Parameter(Mandatory=$false)][System.String]$TermGroupId, [Parameter(Mandatory=$false)][System.String]$TermSetName = “My termset”, [Parameter(Mandatory=$false)][System.String]$TermSetId, [Parameter(Mandatory=$false)][System.String]$FieldName = $(Read-Host -prompt “Field Choice Name”) ) if(-not(gsnp | ? { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { asnp Microsoft.SharePoint.PowerShell } # try to instantiate the target site, if it fails, then it does not run in the right environment $targetSite = get-spsite $Target # predefined termset guids: $guids = @{ “group” = if ($TermGroupId) {New-Object system.guid $TermGroupId } else { [system.guid]::NewGuid() } “termset” = if ($TermSetId) {New-Object system.guid $TermSetId } else { [system.guid]::NewGuid() } } function GetChoices() { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Source) $field = $ctx.Web.Fields.GetByInternalNameOrTitle($FieldName) $ctx.Load($field) $ctx.ExecuteQuery() return ([xml]$field.SchemaXml).Field.Choices.Choice } function New-Term { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermSetItem]$parent, [Parameter(Mandatory=$true)][System.String]$name ) if (!$parent) { throw new-object System.ArgumentException $parent } if (!$name) { throw new-object System.ArgumentException $name } $term = $parent[$name] if (!$term) { $parent.CreateTerm($name, 1033) | out-null } } function CreateTerms() { $taxSession = Get-SPTaxonomySession -Site $targetSite $termStore = $taxSession.DefaultSiteCollectionTermStore $group = $termstore.Groups[$TermGroupName] if (!$group) { $group = $termStore.CreateGroup($TermGroupName, $guids.group) } $termSet = $group.TermSets[$TermsetName] if (!$termset) { $termset = $group.CreateTermSet($SecurityClassificationTermSetName, $guids.termset, 1033) } GetChoices | % { New-Term $termSet $_ } $termStore.CommitAll() $targetSite.Dispose() write-host -ForegroundColor Green “The term sets have been created” } CreateTerms [/sourcecode]
PowerShell: Get version and ProductId from an .app package
In my project I deploy some apps directly through the ObjectModel directly with PowerShell. The apps are built with TFS I have a script that installs or updates apps if there is a new version of the app. Previously I used Import-SPAppPackage to compare the version and productid with an existing app instance, but often I get this error:
The provided App differs from another App with the same version and product ID.
Count lines of code with PowerShell
Today I got a question:
How many lines of code are there in our SharePoint solution?
After a little search, I found that PowerShell is really a nice tool to count lines of code:
I wanted to count lines for different types of code:
- Code Behind written in C#, the files have .cs file extension
- JavaScript code (except jQuery, angular or knockout frameworks)
- PowerShell files (.ps1 and psm1)
- Xml files (all the SharePoint .xml files)
Here is the powershell code that counts lines of code: [code language=“powershell”] # go to the solution folder cd #count lines in .cs files ls -include *.cs -recurse | select-string . | measure | select count #count lines in our .js files ls -include *.js -recurse ` -exclude *min.js, jquery*, _*, jsrender*, CamlBuilder*, knockout* ` | select-string . ` | measure ` | select Count #count lines in our powershell scripts ls -include *.xml -recurse | select-string . | measure | select count #count lines in our powershell scripts ls -include *.ps1, *.psm1 -recurse | select-string . | measure | select count [/code] Just a curious fact, I can’t tell you how many lines of code we have in our solution, but I can reveal the proportions. If I used the flexible box model in css3, it would look like this: There are as many lines of code written in javascript as it is in C#. The main reason that for the big js code base are the SharePoint hosted apps. The PowerShell scripts are as big the javascript code base. Xml files are 4 times bigger than C# code, and it is even bigger than the sum of all lines of code written in C#, JavaScript and PowerShell. It isn’t strange that xml is dominating, almost everything in SharePoint is defined in xml. Fortunately, there are less cases where you have to write raw xml in Visual Studio 2012/2013 and SharePoint 2013. How does it look in your project? What language is dominating in your SharePoint project?
Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)
I have had a strange bug. The comment text box in a OOB SharePoint 2013 blog doesn’t appear. It only says: “There are no comments for this post.” In this blog post I’ll tell you how I found the bug and I’ll show you how you can temporarily bring the commenting to life. I have had luck. While it doesn’t work on the Test Environment, it does actually work on my development machine. The comments text box is rendered as an OnPostRender action in the blog comments display template. After debugging the javascript in hours and comparing the two environments, I just could confirm that displaytemplates are the same. There are two main javascript files that are involved:
Log to ULS using javascript
The more javascript code is produced in SharePoint solutions, the more need we have to log information and possible errors to a central logging place in SharePoint: ULS. This blog post is about logging to ULS from javascript. For a while ago I read a blog post:
The author @avishnyakov mentions the ability log to ULS from javascript. I want to dive deeper. [sourcecode language=“javascript”] ULS.enable = true ULSOnError(“Hello from javascript”, location.href, 0); [/sourcecode] What this function actually does, is that it calls a web service called _vti_bin/diagnostics.asmx
We can follow the function in the init.debug.js [sourcecode language=“javascript”] function ULSOnError(msg, url, line) { return ULSSendExceptionImpl(msg, url, line, ULSOnError.caller); } [/sourcecode] ULSOnError invokes ULSSendExceptionImpl: [sourcecode language=“javascript”] function ULSSendExceptionImpl(msg, url, line, oCaller) { if (Boolean(ULS) && ULS.enable) { ULS.enable = false; window.onerror = ULS.OriginalOnError; ULS.WebServiceNS = “http://schemas.microsoft.com/sharepoint/diagnostics/"; try { ULS.message = msg; if (url.indexOf(’?’) != -1) url = url.substr(0, url.indexOf(’?’)); ULS.file = url.substr(url.lastIndexOf(’/’) + 1); ULS.line = line; ULS.teamName = “”; ULS.originalFile = “”; ULS.callStack = ‘\n’ + ULSGetCallstack(oCaller) + ‘’; ULS.clientInfo = ‘\n’ + ULSGetClientInfo() + ‘’; ULSSendReport(true); } catch (e) { } } if (Boolean(ULS) && Boolean(ULS.OriginalOnError)) return ULS.OriginalOnError(msg, url, String(line)); else return false; } [/sourcecode] ULSSendExceptionImpl invokes ULSSendReport: [sourcecode language=“javascript”] function ULSSendReport(async) { ULS.request = new XMLHttpRequest(); ULS.request.onreadystatechange = ULSHandleWebServiceResponse; ULS.request.open(“POST”, ULSGetWebServiceUrl(), async); ULS.request.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”); ULS.request.setRequestHeader(“SOAPAction”, ULS.WebServiceNS + “SendClientScriptErrorReport”); ULS.request.send(’’ + ‘<soap:Envelope xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=“http://www.w3.org/2001/XMLSchema" xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/">' + ‘soap:Body’ + ‘’ + ‘’ + ULSEncodeXML(ULS.message) + ‘’ + ‘’ + ULSEncodeXML(ULS.file) + ‘’ + ‘’ + String(ULS.line) + ‘’ + ‘’ + ULSEncodeXML(ULS.callStack) + ‘’ + ‘’ + ULSEncodeXML(ULS.clientInfo) + ‘’ + ‘’ + ULSEncodeXML(ULS.teamName) + ‘’ + ‘’ + ULSEncodeXML(ULS.originalFile) + ‘’ + ‘’ + ‘</soap:Body>’ + ‘</soap:Envelope>’); } [/sourcecode]
scriptcs and SharePoint. How SharePoint can benefit?
Last Saturday I attended Leetspeak. Among many awesome speeches and presentations I discovered scriptcs. scriptcs lets you write C# code directly in the console, or execute scripts written with just your favourite editor. Please see more about it on the site. What I thought during Justin Rusbatch’s session at Leetspeak:
Can we use scriptcs in SharePoint?
Technically there is no limitations in SharePoint for scriptcs. Any .NET code can be registered, imported and invoked in a console or in a standalone script. Here is the simple code for instantiating a site collection and disposing it: [code language=“csharp”] #r Microsoft.SharePoint; using Microsoft.SharePoint; var site = new SPSite(“http://dev”); site.Url site.Dispose(); [/code] The code above does not do anything, it is just there to demonstrate how you can register the SharePoint assembly (“Microsoft.SharePoint”) and import it into the script: [code language=“csharp”] using Microsoft.SharePoint; [/code] The example shows even that you in scriptcs no longer need the necessary “boilerplate” (compared to a console application): namespace, Program, Main()… You can just directly write your code. The rest is the same as in a C# application. The code samples for scriptcs can be any code written in C# for SharePoint, code from custom console applications, from feature receivers, you name it. So my next question is:
Apps can only call the OOB CSOM and REST endpoints
As a SharePoint architect or a SharePoint developer, you must have been thinking about the benefits/limitations of SharePoint apps a lot. I want to point out one of them today, which is very important: using custom webservices deployed to SharePoint inside apps. That is impossible and it is designed to be so due to the security architecture in the sharepoint app framework. I have read much about SharePoint apps (books, whitepapers, blog posts) and stumbled over these two contradictive statements:
javascript: Alert Me on a Page
Recently I needed to add an Alert Me link on Pages. Alert Me is a well known SharePoint functionality for notifying users about changes in list or list items. It is availabe in OOB SharePoint as a command in Ribbon if you go to a list view: When you click on this ribbon command, SharePoint opens a modal dialog and takes you to layouts page: SubNew.aspx. To open a modal dialog and load a page is not a rocket science. So a custom “Alert Me” link is doable. As the first step I copied the html markup from the ribbon and adjusted it a little bit. [sourcecode language=“html”] Alert Me [/sourcecode] Then the javascript code which gets the List ID and Page ID is very simple because this information is there in the magic _spPageContextInfo: [sourcecode language=“javascript”] var takana = window.takana || {}; takana.alertMe = function () { var url = String.format("{0}/{1}/SubNew.aspx?List={2}&ID={3}" , _spPageContextInfo.webAbsoluteUrl , _spPageContextInfo.layoutsUrl , encodeURI(_spPageContextInfo.pageListId) , _spPageContextInfo.pageItemId); OpenPopUpPage(url); } [/sourcecode] This code will open a modal dialog in exactly the same way as the ribbon command in OOB SharePoint and let you subscribe to changes on that page. In this code I use String.format which is available on SharePoint pages and _spPageContextInfo which has existed since SharePoint 2010 and has been extended with more useful information about the current context.
javascript: Remove illegal characters in url
Recently I needed to create valid urls for pages using javascript. Also this time I thought it must be some out-of-the-box code for that in SharePoint. The first thing I came up was the “Add page” dialog. I found that the actual dialog was in the _layouts virtual folder:
/\_layouts/15/CreatePublishingPageDialog.aspx
```Bingo, it does the validation in the client side. This is the responsible javascript function that resides directly in the page: \[sourcecode language="javascript"\] function UpdateUrl() { LoadTermContextInfo(); var hiddenPageUrlLabelExtensionClientId = "<%=hiddenPageUrlLabelExtension.ClientID%>"; var hiddenPageUrlLabelExtension = document.getElementById(hiddenPageUrlLabelExtensionClientId); var pageNamePreviewUrlLabelClientId = "<%=pageNamePreviewUrlLabel.ClientID%>"; var pageNamePreviewUrlLabel = document.getElementById(pageNamePreviewUrlLabelClientId); if( pageNamePreviewUrlLabel != null ) { var nameInputTextBoxClientId = "<%=nameInput.ClientID%>"; var nameInputTextBox = document.getElementById(nameInputTextBoxClientId); var allowSpaces = false; if( GetInnerText(hiddenPageUrlLabelExtension) != "" ) { var suggestUrlValue = ""; for (var i=0; i < nameInputTextBox.value.length; i++) { var currentChar = nameInputTextBox.value.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } UpdatePreviewUrl( suggestUrlValue ); } else { if( g\_timerId != 0 ) { window.clearTimeout(g\_timerId); } g\_timerId = window.setTimeout(OnFriendlyUrlNameChanged, 500); } } } \[/sourcecode\] This function iterates through all the characters in the page url and removes the illegal characters. The space, plus sign and the dot become a hyphen. To determine if a character is illegal, it relies on another javascript function called: `IndexOfIllegalCharInUrlLeafName`. This function can be found in the init.js or init.debug.js: \[sourcecode language="javascript"\] function IndexOfIllegalCharInUrlLeafName(strLeafName) { for (var i = 0; i < strLeafName.length; i++) { var ch = strLeafName.charCodeAt(i); if (strLeafName.charAt(i) == '.' && (i == 0 || i == strLeafName.length - 1)) return i; if (ch < 160 && (strLeafName.charAt(i) == '/' || !LegalUrlChars\[ch\])) return i; } return -1; } \[/sourcecode\] This function checks a char against an array of all characters: `LegalUrlChars` from the same file: init.js. [![ill_002](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png)](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png) To use this UpdateUrl function, we have to remove the references to the fields from the Add Page Dialog. Of course, we won't overwrite this original function, we don't want to break the SharePoint OOB functionality. Here is how my new function looks like: \[sourcecode language="javascript"\] var takana = {}; function takana.updateUrl(url) { var allowSpaces = false; if( url ) { var suggestUrlValue = ""; var length = url.length; for (var i=0; i < length; i++) { var currentChar = url.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } } } \[/sourcecode\]
#### Server Side
For those of you who want run this operation on the server, here is the code written in C#: \[sourcecode language="csharp"\] //" # % & \* : < > ? \\ / { } ~ | var illegalChars = @"\[""#%&\\\*:\\<\\>\\?\\\\\\/\\{\\}~\\|\]"; pageName = Regex.Replace(pageName, illegalChars, string.Empty); var punctuation = @"\[\\s\\.;\\+\]"; pageName = Regex.Replace(pageName, punctuation, "-"); //remove "--" pageName = Regex.Replace(pageName, @"\\-{2,}", "-"); pageName = string.Format("{0}.aspx", pageName); //do it like the built-in dialog, lower case pageName = pageName.ToLower(); \[/sourcecode\] Don't forget to leave a comment if you find this post useful.
## Comments from Wordpress.com
####
[Johannes Milling](http://discoveringsharepoint.wordpress.com "johannesmilling@hotmail.com") - <time datetime="2013-08-23 09:53:30">Aug 5, 2013</time>
Good post! :)
<hr />
The CDN concept in SharePoint
How many instances of jquery are there in your SharePoint farm? [sourcecode language=“powershell”] Get-SPWebApplication http://dev ` | Select -Expand Sites ` | Select -Expand AllWebs ` | Select -Expand Lists ` | Select -Expand Items ` | ? { $_.Url -match “jquery.*.js” } ` | select Name, Url [/sourcecode] Have you more than two (jquery and jquery-ui), then you have too much. You can save much place and performance by using Content Delivery Network (CDN) links for the resources like javascript, css, fonts and icons. Consider those Content Delivery Networks:
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
SharePoint Apps: "Provider Hosted First" Approach
Recently I had an exciting mail conversation with Thomas Deutsch. He came up with an idea how to fasten the development of apps. This smart approach is called “Provider Hosted First”. See Thomas’ original blog post. Here are some highlights: What you actually do is a local website which runs in grunt server
:
localhost:9000
```Then a SharePoint-hosted app is created with an SPAppIframe that refers to that local app site. Genious!!! Some key features of this approach:
* This local app contains a livereload script. Your sharepoint app is updated every time you save your css, js, html file in your IDE
* Grunt minifies, bundles your assets
* Grunt runs your tests automatically when your content is modified
* The SharePoint app can be on Premises, on Office 365, wherever you want it.
#### Video
\[caption id="attachment\_2808" align="alignnone" width="630"\][![See the video how it looks like to develop using this approach](https://sharepointkunskap.files.wordpress.com/2013/07/sp-app-002.png?w=630)](http://www.screenr.com/LA8H) See the video how it looks like to develop using this approach\[/caption\]
## Comments from Wordpress.com
####
[Paul Tavares](http://paultavares.wordpress.com "paultavares1@gmail.com") - <time datetime="2013-07-10 02:59:34">Jul 3, 2013</time>
This is pretty cool and very similar to my current setup for developing javascript applications for SharePoint. I use a script to "deploy" updates from my PC to the folder in a document library. I'll try this out when I get around to playing with SP2013.
<hr />
####
[Björn]( "bjorn.roberg@bool.se") - <time datetime="2013-07-02 11:07:08">Jul 2, 2013</time>
Awesome! I'm gonna try that out!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-07-02 15:31:33">Jul 2, 2013</time>
Great! When you go to Thomas Deutsch blog, you can download the source code for the solution.
<hr />
Make javascript code work with Minimal Download Strategy Part 2
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
Minimal Download Strategy (MDS) is an important feature in SharePoint 2013. It lets you download only a page delta, only changes. There is still issues with the MDS and custom scripts and almost no documentation on msdn or technet. In this blog post I want to learn more about adjusting custom scripts for MDS. As in my previous post, I want to take a real problem and try to solve it. The goal is to find a solution, not nececerilly the most optimal solution, at least for now.
Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
Styling suiteBar and IE8
Today I want to share little css tip for styling the suiteBar in SharePoint 2013 and making it work even in IE8. I needed to apply a green color to the suiteBar (#005128). It worked in all browsers except IE8: The reason why is a special css rule (in corev15.css) that only IE8 understands: [sourcecode language=“css”] .ms-core-needIEFilter #suiteBarLeft { filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=#ff0072c6,endColorstr=#ff0072c6); } [/sourcecode] I found this answer in an blog post written by Trace Armstrong: SharePoint 2013 – Branding the Top Bar and the Importance of Browser Testing. You could override this css rule with your colors, just dig into the msdn documentation. What I needed though, was just a plain color, so I didn’t want to dig into that old progid-definitions. There is actually a simpler solution on social.msdn.microsoft.com. A guy called avshinnikov just overrides the “filter” rule by setting it to none. If you apply it only with id selector (#suiteBarLeft) then you have to put “!important” after that. Fortunately I allready had my own css class on html tag which is a sort of a “namespace” for my selectors: [sourcecode language=“css”] .takana-html #suiteBarLeft { background-color: #005128; filter: none; } [/sourcecode] The class .takana-html can have any name, of course, and it can be a class on a closer parent element to the suiteBar. The only goal for that is to make your css rules more important in your design in a natural way (and avoiding the “!important”). Eventhough many people use this principle without thinking about it, I’ve not found any info regarding this principle. I only heard Jeremy Foster and Michael Palermo talking about it and referring to it as “css namespaces” in a video course: Developing in HTML5 with JavaScript and CSS3 Jump Start. Of course, the name isn’t unique, there is another thing called css namespaces. But the concept is really good.
AutoSPInstaller: error while stopping the default web site in IIS
During an installation with AutoSPInstaller on my development machine I ran into a strange issue. I got the following error:
System.IO.FileNotFoundException: Could not load file or assembly ‘Microsoft.IIS.PowerShell.Framework’ or one of its dependencies
I haven’t found any other people having the same problem with the AutoSPInstaller, but I found a similar report on another forum: help.octopusdeploy.com. Maybe I am the only one who gets this error in AutoSPInstaller, if not it can be useful to write the solution down. The error occurs when the default web site in IIS is stopped. For some reason Get-WebSite cmdlet throws an exception the first time you invoke it, but not the second time. To get it working I followed the tip from the help.octopusdeploy.com and wrapped the Get-Website code in a try-and-catch, where the same cmdlet was in try and in catch. This line: [sourcecode language=“powershell”] $defaultWebsite = Get-Website | Where-Object {$_.Name -eq “Default Web Site” -or $_.ID -eq 1 -or $_.physicalPath -eq “%SystemDrive%\inetpub\wwwroot”} # Try different ways of identifying the Default Web Site, in case it has a different name (e.g. localized installs)[/sourcecode] becomes this code (the lines in try and catch are identical): [sourcecode language=“powershell”] Try{ $defaultWebsite = Get-Website | Where-Object {$_.Name -eq “Default Web Site” -or $_.ID -eq 1 -or $_.physicalPath -eq “%SystemDrive%\inetpub\wwwroot”} # Try different ways of identifying the Default Web Site, in case it has a different name (e.g. localized installs) } Catch [System.IO.FileNotFoundException]{ $defaultWebsite = Get-Website | Where-Object {$_.Name -eq “Default Web Site” -or $_.ID -eq 1 -or $_.physicalPath -eq “%SystemDrive%\inetpub\wwwroot”} Break }[/sourcecode] With this fix I was able to run the whole AutoSPInstaller script. My development machine was a fresh installed Windows Server 2008 R2 SP1 (without any updates). Leave a comment if you run into the same issue. If so, I’ll try to send a patch to the AutoSPInstaller code.
Multi-lingual "Last Modified" footer
You want to show when a page is last modified? The label should, of course, work in multi-language environment. For MOSS, there is a great article about how to achieve this: Jamie McAllister. Building a multi-lingual ‘Last Modified’ Footer for MOSS. Here is a simple example for doing the same in SharePoint 2013: [sourcecode language=“html”] <%@ Register TagPrefix=‘SharePointWebControls’ Namespace=‘Microsoft.SharePoint.WebControls’ Assembly=‘Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c’ %> <SharePointWebControls:EncodedLiteral runat=‘server’ Text=’<%$Resources:cms,pagesettings_modifieddate_label%>’ EncodeMethod=‘HtmlEncode’/>: <SharePointWebControls:DateTimeField runat=“server” FieldName=“Modified” ControlMode=“Display”/> [/sourcecode] It fetches the localized value from cms.resx and puts it into your page as html.
REST API: Add a plain text file as an attachment to a list item
SharePoint 2013 REST API has been enhanced and extended. The old _vti_bin/listdata.svc is still there, but the new api for working with lists and list items is much more and obviously a part of a bigger api: _api/web/lists Yesterday I saw an interesting question on SharePoint StackExchange:
The instructions in the MSDN resource are not so detailed, the cannot be. The guy who asked the question did as it stood in the examples. But sometimes solutions for SharePoint need some small adjustments :) Here is the simplest code to create an attachment in plain text for a list item 1 in the list called List1 in the root web. That’s it. But it works: [sourcecode language=“javascript”] var content = “Hello, this text is inside the file created with REST API”; var digest = $("#__REQUESTDIGEST").val(); var composedUrl = “/_api/web/lists/GetByTitle(‘List1’)/items(1)/AttachmentFiles/add(FileName=‘readme.txt’)”; $.ajax({ url: composedUrl, type: “POST”, data: content, headers: { “X-RequestDigest”: digest } }) [/sourcecode] This example is of course just for demonstration. It uses only hard-coded values. But it shows how simple it is to create a list item attachment using SharePoint 2013 REST API and “upload” plain text asynchronously to the server.
Error: Sorry, we're having trouble reaching the server
I ran into a an issue today. When I tried to add a user to a site in my SharePoint 2013 site, I got this error:
Sorry, we’re having trouble reaching the server
A google search gave these two possible solutions:
I know it can almost everything that can cause this error. Here are my two öre :) I found that when I tried to add a user, an ajax call was made. And this was the error:
SharePoint Modal Dialog as AngularJS directive
It has already become a series of posts in my blog about the combination of AngularJS and SharePoint:
- AngularJS: prevent form validation in Page Edit Mode
- angular jQuery UI autocomplete
- AngularJS: sync $location.search with an input value
And it will be more. Some of them are a pure angular stuff, some of them are really for SharePoint. In this post post I’ll show how to create a directive for a sharepoint modal dialog (SP.UI.ModalDialog). There is already a modal dialog implementation in the Angular UI project, but it uses the bootstrap modal dialog. But it custom attributes for angular">is not that hard to create an own directive for showing sharepoint modal dialogs. I’ve called the new directive ng-sp-modal
(ngSpModal). Here is this: [sourcecode language=“javascript”] var ngSpModal = function() { link: function (scope, element, attrs, controller) { var dialog, defaults = { html: element.get(0), showClose: false }, getOptions = function () { var options = scope.$eval(attrs.ngSpModal); return angular.extend(defaults, options); }; fireSpModal: function (value) { if (value) { var opts = getOptions(); dialog = SP.UI.ModalDialog.showModalDialog(opts); } else { dialog && dialog.close(); } }; // Watch for changes to the directives options scope.$watch(attrs.ngShow, fireSpModal, true); } return { require: ‘?ngShow’, link: link }; }; window.myApp = angular.module(‘myApp’, [‘ui.directives’]); myApp.directive(’ngSpModal’, [ngSpModal]); [/sourcecode] The new ng-sp-modal directive depends on ng-show. When your expression or value for ng-show for your html area is true, then a sharepoint modal dialog will open. This is achieved through a $watch command. The html area which is used to create will be copied to the modal dialog. I have used it for forms. To use it, just place this directive into your html element that you want be shown in a modal dialog. Here is a simple example to achieve what it is shown in the screenshot pasted above. [sourcecode language=“html”] Here is the html markup for your modal dialog [/sourcecode] Here is the very simple angular controller to let it work: [sourcecode language=“javascript”] function someCtrl($scope) { $scope.modalOptions = { height: 100, width: 300, title: “Yeah” }; } [/sourcecode]
JavaScript Localization in SharePoint
Yesterday Waldek Mastykarz published a cool post: Globalizing JavaScript in SharePoint 2013. This is a very cool technique to localize your client code in javascript and reuse your resx files in Server Side and Client Side. This is actually not new for SharePoint 2013 despite it has become more needed with the huge client focus in the new SharePoint. I have used this in SharePoint 2010 for a long time. In my blog post: ScriptResx.ashx in SharePoint I told about that technique. What I didn’t know that you can define your javascript namespace directly in the resx file. Waldek wrote in his comment that SP.Publishing.Resources.en-US.resx automatically are SP.Publishing.Resources in javascript. That was not the case for my own localization files. A simple look at SP.Publishing.Resources.en-US.resx helped: [sourcecode language=“xml”] true SP.Publishing.Resources [/sourcecode] This results in: [sourcecode language=“javascript”] _EnsureJSNamespace(‘SP.Publishing’); [/sourcecode] So what we have to do for our custom resx file is to add classFullName resheader: [sourcecode language=“xml”] Takana.Res [/sourcecode]
AngularJS: prevent form validation in Page Edit Mode
I work on a cool project where AngularJS is used for rendering of business data in a SharePoint portal. One of the beautiful parts of AngularJS is the client validation. AngularJS understands the new html5 attributes like “required” and pattern, which makes the markup and javascript concise and semantic. Recently I ran into a problem: The SharePoint webparts which had html forms with required fields were impossible to add to a page in the web browser, neither was it possible to edit the pages with these webparts. When I clicked on “Save”, the page tried to validate and failed. The solution for this is very elegant, like much of the AngularJS. If you don’t show your angular form, it won’t validate. So just use any method to detect the edit mode on a SharePoint page. I created a helper function for that. [sourcecode language=“javascript”] function isEditMode() { var publishingEdit = window.g_disableCheckoutInEditMode, form = document.forms[MSOWebPartPageFormName], input = form.MSOLayout_InDesignMode || form._wikiPageMode; return !!(publishingEdit || (input && input.value)); } [/sourcecode] In the angular controller, just define the part of it which shouldn’t be there when you are editing a page, by using ng-hide="editMode"
: [sourcecode language=“html”] [/sourcecode] editMode
is a $scope variable in your controller. So the last thing to do is to get the editMode value by invoking the previously defined isEditMode
function: [sourcecode language=“javascript”] function PhoneCallCtrl($scope, $http) { $scope.editMode = isEditMode(); } [/sourcecode]
PowerShell: Copy an entire document library from SharePoint 2007 to disk
For a while ago I needed to copy all files from a document library within a SharePoint 2007 site to the hard drive. So I didn’t need to copy files from SharePoint to SharePoint so I couldn’t use the stsadm -o export command or Chris O’Brien’s nice SharePoint Content Deployment Wizard. I came across the SPIEFolder application which should work with SharePoint 2007 and 2010. It has a site on codeplex: spiefolder.codeplex.com, but neither the binary nor the source code can be downloaded from there. After some searching I found the binary in the author’s skydrive. The fact that the source code was not available seemed as an disanvantage because I could not know what code was run. Nevertheless I tried it out and it didn’t work:
Run web.config-dependant code in PowerShell
PowerShell is a great tool. It helps in SharePoint administration and tasks automation. Today I needed to provision a webpart on many similar pages. This third-party webpart’s constructor instantiates a dataaccess service and uses a connectionstring which is stored in the web.config file. So the webpart creation failed until I found a way to load the configuration into powershell. First you can create a simple file powershell.exe.config
, put it into $pshome
(C:\Windows\System32\WindowsPowerShell\v1.0). In that file you can specify the connectionstring in the same way like in the web.config (or app.config). But it is not secure: the connectionstring can be changed in the future, and you really don’t want to copy your connectionstrings around. So there is a better way: Check out Ohad Israeli’s blog post about how a configuration file can be bound dynamically in a .net assembly: Binding to a custom App.Config file. In PowerShell you can do the same, all we need is to modify the syntax: StackOverflow: Powershell Calling .NET Assembly that uses App.config:
Create SPGroup in PowerShell
Thanks to Ryan for sharing powershell functions. I used New-SPGroup which I altered. Now You can define which permissions will be given to the new group. You can even create groups without default users. Here it comes:
function New-SPGroup {
<#
.Synopsis
Use New-SPGroup to create a SharePoint Group.
.Description
This function uses the Add() method of a SharePoint RoleAssignments property in an SPWeb to create a SharePoint Group.
.Example
New-SPGroup -Web http://intranet -GroupName "Test Group" -OwnerName DOMAIN\\User -MemberName DOMAIN\\User2 -Description "My Group" -Role "Read"
This example creates a group called "Test Group" in the http://intranet site, with a description of "My Group". The owner is DOMAIN\\User and the first member of the group is DOMAIN\\User2 and adds "Limited Access".
C:\\PS>New-SPGroup -Web http://intranet -GroupName "Test Group" -OwnerName DOMAIN\\User -MemberName DOMAIN\\User2 -Description "My Group" -Role "Read"
This example creates a group called "Test Group" in the http://intranet site, with a description of "My Group". The owner is DOMAIN\\User and the first member of the group is DOMAIN\\User2 and adds "Read" access.
Pay attention to the role definition names. They must be provided in the language of your site.
.Notes
Name: New-SPGroup
Author: Ryan Dennis, Anatoly Mironov
Last Edit: 2012-11-05
Keywords: New-SPGroup, spgroup, permissions
.Link
http://www.sharepointryan.com
http://twitter.com/SharePointRyan
https://sharepointkunskap.wordpress.com
.Inputs
None
.Outputs
None
#Requires -Version 2.0
#>
\[CmdletBinding()\]
Param(
\[Microsoft.SharePoint.PowerShell.SPWebPipeBind\]$Web,
\[string\]$GroupName,
\[string\]$OwnerName,
\[string\]$MemberName,
\[string\]$Role,
\[string\]$Description
)
$SPWeb = $Web.Read()
if ($SPWeb.SiteGroups\[$GroupName\] -ne $null){
throw "Group $GroupName already exists!"
}
if ($Role) {
$roleDefinition = $SPWeb.RoleDefinitions\[$Role\]
if (!$roleDefinition) {
throw "Role Definition $Role doesn't exist!"
}
}
if ($SPWeb.Site.WebApplication.UseClaimsAuthentication){
$op = New-SPClaimsPrincipal $OwnerName -IdentityType WindowsSamAccountName
$owner = $SPWeb | Get-SPUser $op
if ($MemberName) {
$mp = New-SPClaimsPrincipal $MemberName -IdentityType WindowsSamAccountName
$member = $SPWeb | Get-SPUser $mp
}
}
else {
$owner = $SPWeb | Get-SPUser $OwnerName
if ($MemberName) {
$member = $SPWeb | Get-SPUser $MemberName
}
}
$SPWeb.SiteGroups.Add($GroupName, $owner, $member, $Description)
$SPGroup = $SPWeb.SiteGroups\[$GroupName\]
$roleAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($SPGroup)
if ($Role) {
$roleAssignment.RoleDefinitionBindings.Add($roleDefinition)
}
$SPWeb.RoleAssignments.Add($roleAssignment)
$SPWeb.Dispose()
return $SPGroup
}
JSOM: Alter a column's DisplayName
Here is another article in my JSOM series. For one month ago I showed how to alter a column’s ShowInDisplayForm property with JSOM. This time I’ll show a code sample for changing a column’s (field’s) display name. If you want to alter the displayname with Server Object Model, grab the code in the sharepoint.stackexchange.com: Change Field’s DisplayName in a List. [sourcecode language=“javascript”]var ctx = SP.ClientContext.get_current(), //SP.ClientContext field = ctx.get_web() //SP.Web .get_lists() //SP.ListCollection .getByTitle(‘MyList’) //SP.List .get_fields() //SP.FieldCollection .getByInternalNameOrTitle(“Body”); //SP.Field ctx.load(field, “Title”); //load only Title ctx.executeQueryAsync(function() { field.set_title(“Beskrivning”); field.update(); ctx.executeQueryAsync(); });[/sourcecode]
Delete all list items with jsom
Today I needed to “clean” a list, meaning to remove all list items. For some time ago I wrote a post about different ways of removing list items in bulk: Server Object Model, SPLinq and RPC. This time I had only the web browser. So I tried the jsom way. By the way, the javascript documentation for jsom on msdn is getting really good. Don’t miss that: How to: Complete basic operations using JavaScript library code in SharePoint 2013. Now here comes theworking code I used to remove all items in my list:
TypeScript in SharePoint
By now TypeScript shouldn’t be something one has to introduce.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
If you haven’t already done it, go and see the intro video for TypeScript, check out a tutorial and visit the typescript playground. There are other javascript libraries which extend javascript and are compatible/compile to javascript: Dart and CoffeeScript. To be honest I had never time to try those. The fact that TypeScript is well integrated into Visual Studio which I happen to work within all the days (intellisense, compilation checks and more) did me curious. This post is actually not about TypeScript itself, but a test to use it in SharePoint. In this short “lab” I even had Web Essentials 2012 which automatically compile typescript files into plain javascript files on save. This is what I did: Install TypeScript and Web Essentials 2012 Create a SharePoint-hosted app: Create a new TypeScript file in the autogenerated “Scripts”-module and call it “Greeter.ts” Just save the file as it is. The new file is created: Greeter.js Now we don’t need to copy this file to the app, so remove Greeter.ts from the Elements.xml file (or comment it out): Open the Default.aspx from the Pages module and add the reference to the new javascript file:
GeoLocation Field in SharePoint 2013
In SharePoint 2013 Preview there is a new type of field: GeoLocation which is, like the old SPUrlField, a pair of values. The geolocation is described as longitude and latitude. Unfortunately you can’t add this field in list settings. You have to create this in code. In the provided link you can find the code C# code which uses the Client Object Model. In another link you can find an example how to create the geolocation file using Server Object Model (in FeatureActivated EventReceiver). If you know me, you might already know that I will propose a JavaScript solution. Here is the code to create a geolocation field in an existing list using JSOM:
Callouts in SharePoint 2013 Preview
While ModalDialog is not default for editing list items in SharePoint 2013 Preview, there is a new “popup” element in SharePoint - callout or popover. I would like to recommend these two blogs when you want discover more: Andrey Markeev: Callouts (popovers) в SharePoint 2013 Preview (in Russian) Alex Boev: a three part series: 1. Custom Callouts in the SharePoint 2013 Metro UI: Part 1: Basics 2. Custom Callouts in the SharePoint 2013 Metro UI, Part 2: Actions 3. Custom Callouts in the SharePoint 2013 Metro UI, Part 3: CalloutManager To get introduced with callouts in SharePoint 2013, you can run this code (from Andrey Markeev’s blog):
.tfignore - ".gitignore" for TFS
I haven’t used TFS so much. But I like it so far. It works smoothly, both TFS 2012 (on premises) and TFS Preview (online). I really appreciate that Microsoft has been inspired from git - the world’s best VCS :). For example .tfignore which works exactly like the .gitignore file. It is nice that the non-classic Microsoft dot notation convention for naming the hidden files is chosen. So if you have any files to ignore just do it like you did in your git projects. Here is a .tfignore which I use in my SharePoint project for now. I suppose it will be extended soon:
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
Simplify js and css development with Web Essentials (Visual Studio Extension)
If you develop much javascript and css, this is the exension to Visual Studio you just can’t live without: Web Essentials (It is even released for VS2012). You can do many things with it. Here are two examples for simple but very useful functions: 1. Show which browsers support a css attribute: 2. Collapse javascript functions and create #region areas like in C# code: There is much more, like less and coffeescript parsing. Just check the documentation. And it is fully appliable in SharePoint development.
Toastr.js and SharePoint
Have you used SharePoint javascript Notifications (SP.UI.Notify)? Are you looking for something new and fresh? Well then check out the Toastr.js - a simple, beautiful, fully responsive and light-weight javascript lib for notifications, developed by John Papa and Hans Fjällemark and released under the MIT License. By the way, toastr was one of many things I discovered and learned on John Papa’s online course by pluralsight: Single Page Apps with HTML5, Web API, Knockout and jQuery. It is a really awesome course, where you learn how to create an amazing SPA. Well, how’s about SharePoint. While whatching the course videos about toastr, I thought: Can we use it in SharePoint? Yes we can! Just load the toastr css and js and start using it:
JSOM: Alter a column's ShowInDisplayForm property
When you create a content type, you can define if your fields will be shown in DisplayForm, EditForm, NewForm. You can hide or show them, just as Yaroslav Pentsarsky says. If your list is already provisioned, you can change them with Server Object Model, why not in PowerShell: Technet: Setting ShowInDisplayForm, ShowInEditForm, ShowInNewForm properties with powershell. If you don’t have access to the server, then the same can be done with JSOM. Here is the code:
JSOM: Last Modified Date of a List
The data transfer between server and client can heavily affect the performance. One of the measures to reduce the amount data transferred from the server to the client is storing data on the client. In many modern browsers we can use html5 localStorage. Even in older browsers there are ways to store data. I would recommend a nice js lib called amplify.js. The interface is much easier, then:
amplify.store("key", { title: "value" });
```It comes in nicely, if we have much data which we get with JSOM. But we have to care about eventual changes to list items done after we got them the last time. So we have to store the [last modified date](http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.lastitemmodifieddate.aspx). This property is also available in JSOM:
var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(“Tasks”); ctx.load(list, “LastItemModifiedDate”); ctx.executeQueryAsync( function() { var lastmodified = list.get_lastItemModifiedDate(); }, function() {} );
The original Visual Web Part template is missing in Visual Studio 2012
Today I encountered a weird issue, the classic Visual Web Part template was gone in Visual Studio 2012. When I created a Visual WebPart, a webpart was created with a generated .g.cs file, like the sandboxed visual webparts. I am not exactly sure why it happened. According to the MSDN guide Creating Web Parts for SharePoint, the structure of Visual Webparts should be the same as in Visual Studio 2010. It could have happened after I installed the power tools. However, if someone runs into the same issue, here is the solution: Copy this zip file from a computer with VS2010 installed:
The right URL regardless AAM zone
For a while ago my colleague gave me a nice tip of getting the right absolute url regardless sharepoint zone in Alternate Access Mappings. I want to share it, because it is brilliant:
var url = SPUtility.AlternateServerUrlFromHttpRequestUrl(new Uri(value)).AbsoluteUri;
Using SharePoint tooltips
I found a great post about using sharepoint tooltips on Andrey Markeev’s (@amarkeev, omlin) blog: JavaScript ToolTip’ы для SharePoint. He describes how he found the standard sharepoint tooltips and how they can be reused. The best part of it his “research”. Andrey’s conclusion is to create an own, simplified javascript class which enables “sharepoint” tooltips. I modified it somewhat. I think there is no need to instantiate a TooltipManager…
var Takana = window.Takana || {};
Takana.ToolTipManager = function () {
var \_divId = "my\_tooltip";
var \_innerDivId = "my\_tooltip\_inner";
function createTitleAndDescriptionHtml(title, description) {
return String.format(
'<div>{0}</div><div>{1}</div>',
title,
description);
}
function showTooltip(element, rawHtml) {
var tooltipDiv = $get(\_divId);
if (tooltipDiv == null)
tooltipDiv = createTooltip();
$get(\_innerDivId).innerHTML = rawHtml;
displayTooltipNextToElement(tooltipDiv, element);
}
function displayTooltipNextToElement(tooltipDiv, element) {
tooltipDiv.style.display = '';
var loc = Sys.UI.DomElement.getLocation(element);
tooltipDiv.style.left = loc.x + 'px';
tooltipDiv.style.top = loc.y + element.offsetHeight + 2 + 'px';
if (tooltipDiv.curTimeout != null)
clearTimeout(tooltipDiv.curTimeout);
}
function createTooltip() {
var mainDiv = document.createElement('span')
mainDiv.id = \_divId;
mainDiv.className = 'ms-cui-tooltip';
mainDiv.style.width = 'auto';
mainDiv.style.position = 'absolute';
var bodyDiv = document.createElement('div');
bodyDiv.className = 'ms-cui-tooltip-body';
bodyDiv.style.width = 'auto';
var innerDiv = document.createElement('div');
innerDiv.id = \_innerDivId;
innerDiv.className = 'ms-cui-tooltip-glow';
innerDiv.style.width = 'auto';
bodyDiv.appendChild(innerDiv);
mainDiv.appendChild(bodyDiv);
document.body.appendChild(mainDiv);
return mainDiv;
}
function hideDiv() {
$get(\_divId).style.display = 'none';
}
var manager = {};
manager.attachToolTip = function (element, title, description) {
$addHandler(element, 'mouseover', function (e) {
showTooltip(element, createTitleAndDescriptionHtml(title, description));
});
$addHandler(element, 'mouseout', hideDiv);
}
manager.attachToolTipRaw = function (element, rawHtml) {
$addHandler(element, 'mouseover', function (e) {
showTooltip(element, rawHtml);
});
$addHandler(element, 'mouseout', hideDiv);
}
return manager;
}();
Now a manager is created on a page per default. To add a tooltip, just use the TooltipManager:
Multiple instances of javascript webparts on the same page
Javascript has become popular among many SharePoint developers thanks to easy and fast jQuery, CSOM, SPServices and many other javascript libraries. That can make solutions modern and fast. On the other hand developers should be aware of more things (some of them at Bamboo Team Blog). One of those is scoping of javascript webparts. The problem a developer has to consider: what happens if a user creates two or more instances of the same beautiful webpart on the page? Let’s go and lab :) I’ll create a solution for this lab: sp-lend-id.ikkelen. This time it will be a sandboxed solution. This solution contains a webpart:
Three ways to get the id of last created SPListItem
An interesting question came on SharePoint StackExchange: How to retrieve the guid of the last uploaded file. It is only possible in CSOM as far as I know. But if we simplify the task, how to get the id of the last item, the we can compare three ways of getting them: SPServices, jQuery + listdata.svc and CSOM.
SPServices
The most easiest way, but not available in async:
$().SPServices.SPGetLastItemId({
listName: "Documents"
});
listdata.svc
Just combine some query strings and try in the browsers address bar:
Web Application Properties as JSON
I saw an interesting question on sharepoint.stackexchange: How to access a Web application/Farm level property bag via jQuery/Javascript/ClientContext. Some time ago I tested a custom http handler, so I wanted to try a custom httphandler for this as well. It worked. Here more details: Just deploy sp-lend-id.tupsam from the solution. If you don’t have any properties in your web application, just add some:
asnp microsoft.sharepoint.powershell
$app = get-spwebapplication http://dev
$app.Properties.Add("Santa", "Claus")
$app.Properties.Add("Ded", "Moroz")
$app.Properties.Add("Hel", "Muci")
$app.Update()
Then just to test open the httphandler directly in the browser:
Using javascript objects passed from closed popup
It is not a rocket science to pass objects from child window (popup) to main window. The problem I encountered today was IE and passing complex objects. So it is just an IE issue as far as I know. The problem occurs when you pass some object (not a simple String or Number) to main window:
window.opener.takeAnObjectFromChild = {
title: "Should even be available when I close the child"
};
and you then close the child window, next time the main window tries to access the passed object:
javascript: developing for performance
Many words have been said about the importance of performance when working with javascript files. Here I want to summarize what developers can do to increase the performance related to javascript. I found many tips on blogs. Here comes my aggregated list of actions one can do to speed up sharepoint (and not only) sites with focus on javascript:
1. Load only sharepoint stuff you need
Use prefetch option to only load sharepoint javascript files that needed. To see the difference, just add ?prefetch=0
to your sharepoint url in the browser. The downside of this lazy loading is that you wrap all sharepoint related javascript into ExecuteOrDelayUntilScriptLoaded otherwise you maybe invoke some of javascript objects and functions that are not loaded. So the prize of this huge performance improvement is a high awareness by a developer when and which scripts are loaded and run.
nodeunit and SharePoint: unit tests in javascript
nodeunit is a (relatively) new test framework for javascript, mainly for node, but it can be run in a browser as well. The most popular framework for testing javascript is Qunit, but I’ll lab with it another time. I found nodeunit tests in moment.js - the best date handling framework for javascript and it worked very well. So first of all, why should we test? The best answer is actually: Life is to short for manual testing (it was actually the slogan at the Google London Test Automation Conference 2007.
Develop for SharePoint on Windows 8
Do you like Windows 8 user expirience, as me? Well than you want to try developing sharepoint solutions in Windows 8. Here I will show what I found out.
Environment
I installed Windows 8 Release Preview as a VMWare machine. Then I installed Visual Studio 2012 RC. Then I followed the steps for installing SharePoint on Windows 8 which are more or less the same as for Windows 7 client install. But then I encountered an error I haven’t found solution for yet. In my standalone sharepoint installation there were some permission problems:
$ in cmssitemanager.js conflicts with $ in jQuery
In SharePoint 2010 if CMSSiteManager.js library is loaded besides jQuery, then much of stuff stops working. The reason is that the dollar sign ($) is used in cmssitemanager.js as well which conflicts with jQuery. Mostly it appears on pages where you load jQuery and have an image library with thumbnails. To avoid this, just replace all $ with jQuery in your custom scripts. A more crazy situation is when avoiding $ isn’t enough. It is when you load jQuery to page head automatically on all pages. The Asset picker (AssetPortalBrowser.aspx) invokes $ itself and gets with jQuery in conflict without you write a single line of custom javascript code. You usually get the following error:
javascript toolkit on text file
Referencing javascript libraries from Content Delivery Networks (CDN) like jQuery can have many benefits. The self-hosted javascript files are on the other hand give you more control. But in one situation it is much better with cdns: the development. Like Marc D Anderson pointed:
I didn’t realize it at the time, but this txt file has become a standard part of my toolkit already. I’ve added it to three client environments just since last week. It’s the A #1 fastest way to get something up and running, even if you know you’re going to host the files locally later.
jQuery mobile and SharePoint
In this post I want to explore how to build a mobile app using jQuery mobile. Recently I discovered two great blog posts about this:
- Building SharePoint web apps using Sencha Touch by Luc Stakenborg
- jQuery mobile and SharePoint by Chris Quick
In my post I’ll use their findings and share some of mine thougts. I’ll focus mostly on how to get started with jQuery mobile and SharePoint. So go ahead and create your jQuery mobile app, just drag’n’drop some controls: Download it and yout get an “app.html” file and “my.css”. For now ignore my.css. app.html is something like that:
Implement public wcf service in SharePoint
If you have an external web service reference in your sharepoint solution, you can use web.config configuration like:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding\_ISuperService" >
<security mode="None">
<message clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://super.domain/SuperService.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding\_ISuperService"
contract="ISuperService"
name="SuperServiceEndpoint">
</endpoint>
</client>
</system.serviceModel>
```security mode is set to "None". Then in code just get this configuration:
var proxy = new SuperServiceClient(“SuperServiceEndpoint”); var result = proxy.GetSomething();
var binding = new WSHttpBinding(); binding.Security.Mode = SecurityMode.None; var endpoint = new EndpointAddress(“http://super.domain/SuperService.svc"); var proxy = new ExternalServices.DreamServiceClient(binding, endpoint); var result = proxy.GetSomething();
Creating custom powershell cmdlet
Why
I need to to activate a feature in PowerShell and specify some properties. Simple? Yes. Possible? No. In the default Enable-SPFeature cmdlet you can’t specify any properties:
Enable-SPFeature –Identity "b5eef7d1-f46f-44d1-b53e-410f62032846" -URL http://dev
We can of course easily add properties when activating features in onet.xml:
<!-- Publishing Resources -->
<Feature ID="AEBC918D-B20F-4a11-A1DB-9ED84D79C87E">
<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<Property Key="AllowRss" Value="false" />
<Property Key="SimplePublishing" Value="false" />
</Properties>
</Feature>
So I went to SharePoint StackExchange and asked the question. Then I realized: the standard Sharepoin API doesn’t support this neither. The methods of SPFeatureCollection which have SPFeatureProperties as parameter are internal. So the only way is to use Reflection like Hristo Pavlov (2008) and Yaroslav Pentsarsky (2010) suggest. So why not to try to create a cmdlet?
Out-Gridview in PowerShell
Did you know that we can pipe the output from PowerShell into a graphical GridView? I have used PowerShell for one year and only now I discovered this nice feature. You can add filter criteria, you can filter by typing in a textbox:
Other useful output cmdlets
- out-file
- out-clip
- out-null
ResxCrunch: Localization tool
If your solution has two or more languages to support, I can recommend an open source tool ResxCrunch. Btw, you can even use ResxCrunch for localization of Android applications.
Access User Profile Properties from Powershell
To use only SPUser objects isn’t always sufficient. To get other properties we have to retrieve user profiles. Giles Hamson gives an example how to get and how to update user profile properties with powershell. Here is an example how to get all work phones:
$url = "http://intranet/"
$site = Get-SPSite $url
$context = Get-SPServiceContext $site
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$profiles = $profileManager.GetEnumerator()
while ($profiles.MoveNext()) {
$userProfile = $profiles.Current
$name = $userProfile.DisplayName
$phone = $userProfile\["WorkPhone"\]
$line = '{0};{1}' -f $name, $phone
write $line
}
If you are not sure what properties are called, see the whole list by typing:
Add Comments column to your sharepoint list
If you have used Issue tracking list template in SharePoint you must have marked that the comments are added and marked with author name and datetime. It is handy to have these micro “discussion boards” on items. The comment-formed communication can help to fine-tune task definitions. By the way, have you seen Trello? So the question is how we can create this column in other lists? Here is a little tutorial how to create “append-only comments”, as they are called:
fallback for html5 placeholders
Placeholders are very handy in html5, we don’t need to fool with input values. But in SharePoint and IE we must provide fallback for placeholders if we want use them in other browsers. Here is an jQuery extension to do that:
(function ($) {
$.fn.extend({
ensurePlaceholders: function () {
var input = document.createElement('input');
var placeholderSupported = ('placeholder' in input);
if (placeholderSupported) {
return;
}
function setHints(elem) {
var $elem = $(elem);
var value = $elem.val();
if (value == "") {
var placeholder = $elem.attr("placeholder");
$elem.val(placeholder);
$elem.addClass("empty-text");
}
}
function removeHints(elem) {
var $elem = $(elem);
$elem.removeClass("empty-text");
var value = $elem.val();
var placeholder = $elem.attr("placeholder");
if (value == placeholder) {
$elem.val("");
}
}
this.find("\[placeholder\]").each(function() {
setHints(this);
});
this.on("focus", "\[placeholder\]", function(e) {
removeHints(this);
});
this.on("blur", "\[placeholder\]", function(e) {
setHints(this);
});
}
});
})(jQuery);
```Then "ensure placeholders" by running this function on a wrapper element which contains fields with the placeholder attribute:
jQuery("#form-wrapper").ensurePlaceholders();
SP.UI.Notify in Modal Dialog
If you open a custom page (not a list item form) in a modal dialog, your notification won’t be shown. The reason is that the notification area (#notificationArea) is inside a hidden div (#s4-ribbonrow). To show this notificationArea we must display the notification area:
var $ribbon = jQuery("#s4-ribbonrow");
if ($ribbon.is(":hidden")) {
$ribbon.css({"min-height": 0, "height": "0px"})
.show().children().hide()
.filter("#notificationArea").show()
}
Comments from Wordpress.com
Jens Malmberg - Jan 3, 2013
cross browser console.log
console.log
is the best tool for debugging javascript. In Firefox Firebug and Chrome Dev Tools you can even log objects which are represented as tree nodes of properties. If Firebug or Dev Tools in Chrome and IE9 are not opened, all these messages are ignored. But IE8 doesn’t understand console (if Dev Tools are closed) and raises an error: To avoid these errors, just declare an empty function just for IE8–:
Enable Save in IE9 mode
Wouldn’t it be nice to use html5 and css3 in SharePoint? No problems, there is actually v5 master out there, created by Kyle Schaefer. Or just use h5ml5 and css3 right away in your webparts and pages. But there is a big problem. It doesn’t work in IE9–. One of the issues (even listed by Kyle) is that “save” doesn’t work in modal dialogs where Rich Text Editor is used. Especialy it is for modal dialogs. The problem is not IE9, neither html5 and css3. After some digging in javascript code which is shipped with SharePoint I found out that the problem is some legacy javascript code which is not supported by IE9 but in IE8– (and compatibility mode). When we set IE9 mode in IE9 Dev Tools (F12) and go to Tasks list and try to create a task, we’ll get an error: It is RTE_GetEditorIFrame from init.js:
$().SPServices is best for SOAP
SPServices is a great tool, really nice work, Marc Anderson (@sympmarc). It has been there all the time I have developed for SharePoint. But the fact that you work with XML and you must parse the attributes (!) was the reason why I prefered listdata.svc and Client Object Model, where you get objects in JSON or you have a nice API to get objects and their properties. But there is an area where SPServices are really the best tool: SharePoint Web Services which only understand SOAP like SocialDataService.asmx.
$ and jQuery in SharePoint
Do you still use $ for jQuery? Well, don’t. If your code with $ resides with a SharePoint Images webpart, it will stop working. You’ll get errors like
Uncaught TypeError: Cannot call method 'empty' of null
The reason is that SharePoint uses $ in its own javascript code: CMSSiteManager.js
function $()
{ULSjlC:;
var elements=new Array();
for (var i=0; i < arguments.length; i++)
{
var element=arguments\[i\];
if (typeof element=='string')
element=document.getElementById(element);
if (arguments.length==1) return element;
elements.push(element);
}
return elements;
}
ScriptResx.ashx in SharePoint
In my previous post I showed a little proof-of-concept for an httphandler which I want to use to dynamically get the localization resources from SharePoint as javascript object. But wait a moment. How does SharePoint handle localization on client? When you look in Script tab in Chrome dev tools, you’ll find:
ScriptResource.axd
It is added to the server when deployed. See a good introduction to WebResource.axd and ScriptResource.axd by Brian Chavez.
Custom HttpHandler in SharePoint for getting dynamic javascript code
Sometimes I want to add some dynamic javascript code. E.g. I had an idea to get javascript code for localization dynamically. Kirk Evan provides a very clean approach to add ASP.NET HttpHandler to SharePoint. This is just a little lab: Create a SharePoint empty project. I call it Jerkelle. Create a class called Resx2JsHandler and implement the IHttpHandler interface Add the mapped folder Layouts and create Jerkelle.ashx file Here is the project. I probably will publish it on my github account: The Jerkelle.ashx file is very simple, it references to the code file (Resx2JsHandler.cs):
XMLHttpRequest the hard way
$.ajax is great, it hides much of the complexity. But sometimes we need to work with “raw” javascript :) So let’s look behind the scenes. The XMLHttpRequest (or just XHR) is used to open a connection to a server without a page reload. Internet Explorer calls it ActiveXObject and it differs in IE versions. Wikipedia article gives a good example how to create one constructor for all browsers: [sourcecode language=“javascript”]if (typeof XMLHttpRequest == “undefined”) XMLHttpRequest = function () { try { return new ActiveXObject(“Msxml2.XMLHTTP.6.0”); } catch (e) {} try { return new ActiveXObject(“Msxml2.XMLHTTP.3.0”); } catch (e) {} try { return new ActiveXObject(“Microsoft.XMLHTTP”); } catch (e) {} //Microsoft.XMLHTTP points to Msxml2.XMLHTTP and is redundant throw new Error(“This browser does not support XMLHttpRequest.”); };[/sourcecode] The remainder is more or less the same among the browsers. We open a connection defining the HTTP verb, URI and async mode (true or false): [sourcecode language=“javascript”]var xhr = new XMLHttpRequest(); xhr.open(“GET”, “/_vti_bin/listdata.svc”, true); xhr.onreadystatechange = onStateChange; xhr.send(null);[/sourcecode] Pay attention to onreadystatechange (only lower case letters). If we choose async=false, the UI waits for the response which is not so kind to users, but maybe it is easier to write a program. Well, there is actually no option but to have async=true. To provide the callback for success and error we can write the responding function onreadystatechange. This function will be called every time the state is changed. There are 5 states:
Push a copy of Resources to client in javascript
In one of my previous posts I told about pushing a copy of an object into client. Now I’ll try to copy my resource values into client. The problem is often that we must create multiple localization resources: first as resx-file. If we use much ajax and client side rendering, we must provide some localization there, too. If they are different subsets of localization resources, it isn’t a problem. But when you get overlapping, it becomes more difficult to manage and sync them. See how Microsoft Ajax Library provides some strings: What if we just copy the values from resx file into client? If there are not business constraint it can make the development much easier. Let’s try it. For that we need Reflection. We start with changing the access modifiers on resx file to public: Then we must get all static properties of the auto-generated class (ResXFileCodeGenerator):
Add links to Global Navigation in My Sites
Oliver Wirkus shows how to add links to Global Navigation in My Sites. Just go to: Central Administration Applicaiton Management Manage Service Applications User Profile Service Application Configure Personalization Site
Comments from Wordpress.com
Lroth - Feb 4, 2015
There is no “configure personalization site” link. What is in the tea you are drinking?
It is actually coffee…Just kidding. This is an instruction for SharePoint 2010.
Parameterize a javascript object and create url
If you want to add some parameters to an url which you want to open, you can use jQuery.param function:
var url = "some\_url";
var params = {
name: "Setner",
email: "setner@narspi.name",
mobile: "123456789"
};
var search = "?" + $.param(p);
url += search;
```It is handy, indeed. In an environment without jQuery (are there some?:) ) you can just iterate an object and join properties:
var url = “some_url”; var params = { name: “Setner”, email: “setner@narspi.name”, mobile: “123456789” }; if (url.match("/\?/g") == null) { url += “?”; } else { url += “&”; } var search = “”; for(var p in params) { search += [p, params[p]].join("="); } url += search;
Erik Swensson's book about Sharepoint Branding
Today Erik Swensson’s book Practical SharePoint 2010 Branding and Customization came to our company. I am looking forward to read it. It’s about time to see alternatives to Randy’s starters.
OOTB permission levels in SharePoint
There are much info about standard permission levels in SharePoint. Here is my visualization for that. Just a little bit easier to find out the right permission level. Enjoy:
Full Control (FullMask)
Design
Contribute
Read
Limited Access
Restricted Reader
Manage Hierarchy
Approve
ViewListItems
x
x
x
x
x
x
AddListItems
x
x
x
x
EditListItems
x
x
x
x
DeleteListItems
x
x
x
x
ApproveItems
x
x
OpenItems
x
x
x
x
x
x
ViewVersions
x
x
x
x
x
DeleteVersions
x
x
x
x
CancelCheckout
x
x
x
ManagePersonalViews
x
x
x
x
ManageLists
x
x
ViewFormPages
x
x
x
x
x
x
Open
x
x
x
x
x
x
x
ViewPages
x
x
x
x
x
x
AddAndCustomizePages
x
x
ApplyThemeAndBorder
x
ApplyStyleSheets
x
ViewUsageData
x
CreateSSCSite
x
x
x
x
x
ManageSubWebs
x
CreateGroups
ManagePermissions
x
BrowseDirectories
x
x
x
x
BrowseUserInfo
x
x
x
x
x
x
AddDelPrivateWebParts
x
x
x
x
UpdatePersonalWebParts
x
x
x
x
ManageWeb
x
UseClientIntegration
Remove protected Organizational Units from AD
To remove a protected OU, go to ADUC (Active Directory Users and Computers), select the domain and enable “Advanced Features” in View. When Advanced Features are enabled, just right click you OU go to Properties -> Object and uncheck “Protect against accidential deletion”. Disable Advanced Features after that. By the way. When Advanced Features are enabled you can even see the distinguished Name of objects directly in ADUC UI.
Settings in Sharepoint_config database instead of appSettings
An alternative to store key-value paired properties in appSettings in web.config we can use Sharepoint_config database by creating our own SPPersistedObject. First we have to create a class which inherits from SPPersistedObject and decorate its properties with [Persisted]:
namespace Takana.SharePoint
{
public class Settings: SPPersistedObject
{
\[Persisted\]
public string DbConString;
public LinkCheckerPersistedSettings() { }
public LinkCheckerPersistedSettings(string name, SPPersistedObject parent) : base(name, parent) { }
}
}
```Then we must create such an object. Let's do it in Powershell:
if(-not(Get-PSSnapin | Where { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { Add-PSSnapin Microsoft.SharePoint.PowerShell }
Adding organizational units to AD through powershell
Want to create some organizational structure in AD, I suppose it is specifically useful in a development environment, well the best solution is powershell then. Mastering Powershell by and Powershell.nu by Niklas Goude provide examples how to do this.
$domain = \[ADSI\]""
$ou = $domain.Create("organizationalUnit", "OU=Administration")
$ou.SetInfo()
```Be sure you write "organizationalUnit" in lower case. Otherwise you'll get "Exception calling "SetInfo" with "0" argument(s): "The specified directory service attribute or value does not exist" when you invoke **$ou.setinfo()**. If you want to create an OU under another OU, just create $domain and specify the location: \[code language="powershell"\] $domain = \[ADSI\]"OU=Administration, dc=takana, dc=local" $company = $domain.Create("organizationalUnit", "OU=Accounting") $company.SetInfo()</pre> To save some other properties: <pre>$ou.put("Description", "this is a dummy ou") $ou.SetInfo() \[/code\]
#### Update 2013-12-10
In PowerShell V3 you have a built-in cmdlet for doing that once you add the Active Directory role in your server. It simple as that: \[code language="powershell"\] New-ADOrganizationalUnit "Accounting" -Path "dc=takana, dc=local" \[/code\]
Install a custom timer job in Powershell
First we have to create a class for our timer job which inherits SPTimerJobDefinition, build it and deploy it.
public class TakanaTimer : SPJobDefinition
{
public TakanaTimer(){}
public TakanaTimer(string jobName, SPService service,
SPServer server, SPJobLockType targetType)
: base(jobName, service, server, targetType) { }
public TakanaTimer(string jobName, SPWebApplication webapp)
: base(jobName, webapp, null, SPJobLockType.ContentDatabase)
{
Title = jobName;
}
public override void Execute(Guid contentDbId)
{
Log.Info("Running Takana Timer");
}
}
There is a powershell example for this, but it has not been updated since MOSS.
Shrink sharepoint database
A Sharepoint Database can become big and have unused spaces. To shrink database go to CA-> Health Analyzer: http://takana:1337/Lists/HealthReports/AllItems.aspx See if there is a list item about unused space in db under the Availability. Click on Repair Automatically in the opened Modal Dialog:
Set ObjectTrackingEnabled = false when reading
In LINQ 2 SP we work with a data context. By default a data context has the property ObjectTrackingEnabled = true. This property is crucial for all other operations in CRUD except Read. I performed a mini experiment. I created 20 000 items in my task list. Every seventh item contains “pärla”. Allright, here is what I found out:
2857 / 20 000 items
ObjectTrackingEnabled = true
Find the current Active Directory Domain
While working with Active Directory within SharePoint we probably don’t need to specify the domain or the root container. We can the current values. Here is a simple method from a console application just to demonstrate:
internal static void GetDomain()
{
var context = new DirectoryContext(DirectoryContextType.Domain);
var domain = Domain.GetDomain(context);
Console.WriteLine("Full domain:");
Console.WriteLine(domain.Name); //takana.local
Console.WriteLine();
Console.WriteLine("root container");
var parts = domain.Name.Split(new\[\] {"."}, StringSplitOptions.RemoveEmptyEntries);
var dcParts = parts.Select(n => "dc=" + n).ToArray();
var d = string.Join(",", dcParts); //dc=takana, dc=local
Console.WriteLine(d);
}
First we get get the full domain, then we split and join them again.
Two interesting html5-in-sharepoint presentations
[slideshare id=11031050&doc=sharepointhtml5-120113215236-phpapp02] HTML5-and-CSS3-What-About-SharePoint.pdf (968 KB) by Kyle Schaefer
Datetime in ASP.NET javascript and $.ajax
In one of my previous blogs I wrote about serializing of javascript objects. You can do it with JSON.stringify or Sys.Serialization.JavaScriptSerializer.serialize. Both methods work fine… almost. There is a big difference when it comes to datetime objects. MS treats dates a little bit different (like RegEx and much more). Let’s try this one:
var writer = { name: "Ajgi", birthdate: new Date(1934, 8-1, 21) };
var json = JSON.stringify(writer);
var msjson = Sys.Serialization.JavaScriptSerializer.serialize(writer);
What happens if we try to parse back msjson with JSON.parse: Well, the date isn’t a valid date anymore. How can we improve it. Rick Strahl gives a solution with custom functions for serializing and deserializing of ms date. But the thing is: we don’t need any custom functions for this, not if you run ASP.NET. The only thing we need is to use serialize and deserialize functions from Sys.Serialization.JavascriptSerializer namespace which you get automatically when you add ScriptManager in ASP.NET (and you get it even automagically in SharePoint). But what about $.ajax and functions I wrote about for retrieving list items and populating them, and updating list items with listdata.svc? Well, there comes the really nice tip from Rick Strahl: not to force $.ajax to parse the response. So instead of dataType: “json”, use the plain dataType: “text”. As the result we’ll get just a text, which we, of course, will deserialize with the native code for Microsoft:…. Use text when possible. When you define json as response format:
SPWebConfigModification
SPWebConfigModification. Some links to start with: http://panvega.wordpress.com/2009/09/02/using-spwebconfigmodification-within-a-feature-receiver/ http://www.onedotnetway.com/get-name-of-current-executing-assembly-in-c/ http://blogs.devhorizon.com/reza/?p=459 http://ikarstein.wordpress.com/2010/09/02/add-web-config-modification-with-powershell-spwebconfigmodification/ http://msdn.microsoft.com/en-us/library/bb861909.aspx
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
var webapp = parent as SPWebApplication;
if (webapp != null)
{
var mod1 = GetWebControlsConfigMod();
webapp.WebConfigModifications.Add(mod1);
var mod2 = GetConStringConfigMod();
webapp.WebConfigModifications.Add(mod2);
SaveChanges(webapp);
}
else
{
Log.Warning("no modifications to webapp are done");
}
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
var webapp = parent as SPWebApplication;
if (webapp != null)
{
var mod = GetWebControlsConfigMod();
var modsCollection = webapp.WebConfigModifications;
var modToDelete =
(from m in modsCollection
where m.Value.Equals(mod.Value, StringComparison.InvariantCultureIgnoreCase)
select m).FirstOrDefault();
if (modToDelete != null)
{
modsCollection.Remove(modToDelete);
SaveChanges(webapp);
}
}
}
private static void SaveChanges(SPPersistedObject webapp)
{
var service = webapp.Farm.Services.GetValue();
service.ApplyWebConfigModifications();
webapp.Update();
}
private static SPWebConfigModification GetWebControlsConfigMod()
{
var assembly = System.Reflection.Assembly.GetAssembly(typeof(WebControls.OfficeEditor));
var ass = assembly.FullName;
var @namespace = assembly.GetName().Name + ".WebControls";
var value = string.Format("", ass,
@namespace);
const string path = "configuration/SharePoint/SafeControls";
var mod = new SPWebConfigModification
{
Path = path,
Name = "JustaName1",
Sequence = 0,
Owner = @namespace,
Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
Value = value
};
return mod;
}
private static SPWebConfigModification GetConStringConfigMod()
{
const string name = "ContosoConString";
const string conString =
"Data Source=db.contoso.com;Initial Catalog=contoso\_db;Persist Security Info=True;User ID=contoso\_Contributor;Password=contoso";
var mod = new SPWebConfigModification
{
Name = "JustaName2",
Path = "configuration/connectionStrings",
Owner = "contoso\_connectionstrings",
Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
Value = String.Format("", name, conString)
};
return mod;
}
```Powershell:
#ADDING asnp microsoft.sharepoint.powershell $url = “http://contoso” $app = Get-SPWebApplication $url $name = “ContosoConString”; $conString = “Data Source=db.contoso.com;Initial Catalog=contoso_db;Persist Security Info=True;User ID=contoso_Contributor;Password=contoso”; $mod = new-object Microsoft.SharePoint.Administration.SPWebConfigModification $mod.Name = “JustName2” $mod.Path = “configuration/connectionStrings” $mod.Owner = “User Name” $mod.Type = 0 #for the enum value “SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode” $mod.Value = ‘’ -f $name, $conString $app.WebConfigModifications.Add($mod) $service = [Microsoft.SharePoint.Administration.SPWebService]::ContentService $service.ApplyWebConfigModifications() $app.Update() #ADDING snapin asnp microsoft.sharepoint.powershell
Check if a user is in a OU
To get all users from an AD group is very simple:
groupName = "an\_ad\_group";
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName);
var principals = grp.GetMembers(true);
```But what about an OU? There is no OrganizationUnitPrincipal... [Well, there is a solution: to instantiate a context for your OU](http://stackoverflow.com/a/1927476/632117 "See the solution on Stack Overflow"): So if you want to check if a user in a OU:
internal static bool IsUserInOu(string ou, string name) { var domain = “takana.local”; var container = string.Format(“OU={0}, DC=takana, DC=local”, ou); var ctx = new PrincipalContext(ContextType.Domain, domain, container); var up = new UserPrincipal(ctx); var ps = new PrincipalSearcher(up);
\n and \t in powershell
Want to add some tabs and new lines to your output in Powershell. Well, it works like \n and \t. But there is a little different syntax: `t and `n. Just a tip. An alternative way to add new line is to use [Environment]::NewLine:
$nl = \[Environment\]::NewLine
$var = "hej" + $nl
Write $var
Add Sharepoint Snap-in if needed
Just include it in your script or function:
if(-not(Get-PSSnapin |
Where { $_.Name -eq "Microsoft.SharePoint.PowerShell"})) {
Add-PSSnapin Microsoft.SharePoint.PowerShell}
By the way, I found it in PowerShell for Microsoft SharePoint 2010 Administrators by Niklas Goude and Mattias Karlsson. Powershell for Sharepoint Administrators. UPDATE: I found a better way to check a variable for null: Thomas Maurer. Powershell: check variable for null. It is like in javascript, just put it in the if-statement to test if it exists or not:
Get url parameters with javascript
There is a question in Stackoverflow and this one, too. There is a fine solution for jQuery. The only thing we need is window.location.search. Say we have http://domain.com?q=hello&a=good#home, then it takes only ?q=hello&a=good, and leaves #home and the main url. Anchors can be retrieved with hash. Here are all properties of window.location: Google Chrome provides a fine function: window.location.getParameter: I like the name of this function. So why not to use it or create this one if a browser doesn’t have it? Well here we go:
Reload page in js: RefreshPage
There are many ways to reload / refresh a page in javascript. One of them is as in discoveringsharepoint.wordpress.com describes:
window.location.reload()
```Today I found some tools which are shipped with ASP.NET/SharePoint to reload a page. The big advantage of them they are designed to work with SharePoint and take all possible aspects of page life cycle into account. The javascript function to refresh a page is just called, guess..: **RefreshPage** and it resides in init.js:
//init.js: function RefreshPageTo(evt, url, bForceSubmit) {ULSA13:; CoreInvoke(’_RefreshPageTo’, evt, url, bForceSubmit); }
Run javascript code except it is inside a modal dialog
Want to run some javascript code everywhere, but not in a modal dialog. Because errors are occured, or this code is unnecessary i dialogs. Well here is a solution I have found after some experiments:
$(document).ready(function() {
if (!window.location.href.match(/isdlg=1/i)) {
onDocumentReadyExceptItIsInDialog();
}
});
function onDocumentReadyExceptItIsInDialog() {}
```This code checks with Regular Expressions if the url of the parent window contains IsDlg=1, if so nothing happens. In the usual case (not inside a dialog), the javascript code runs. EDIT: after I wrote this I actually found that this is the way SharePoint itself does: [![](https://sharepointkunskap.files.wordpress.com/2012/01/isdlg.png "isdlg")](https://sharepointkunskap.files.wordpress.com/2012/01/isdlg.png) So now I update the previous function to this:
$(document).ready(function() { if (window.location.search.match(/[?&]isdlg=1/i)) { return; } onDocumentReadyExceptItIsInDialog(); });
listdata.svc vs CSOM for retrieving and manipulation of list items
What is better and where and when… I’ll try to find out.. This post will be updated soon. Take a look at this so far: http://sharepoint.stackexchange.com/questions/23209/sharepoint-2010-javascript-client-object-model-cross-site-collections
String.format for javascript
sprintf is actually the best javascript implementation of sprintf (string.format). But wait, shouldn’t it be some more .NET-like stuff in SharePoint environment? Indeed there is! (Well, not only in SP, but ASP.NET) String.format(“Hello {0}”, “world”) does exactly the same thing as on server side. Wow, it opens for many opportunities, e.g. in jQuery tmpl: String.format validates arguments, and if all is OK, it invokes another function String._toFormattedString:
function String$\_toFormattedString(useLocale, args) {
var result = '';
var format = args\[0\];
for (var i=0;;) {
var open = format.indexOf('{', i);
var close = format.indexOf('}', i);
if ((open < 0) && (close < 0)) {
result += format.slice(i);
break;
}
if ((close > 0) && ((close < open) || (open < 0))) {
if (format.charAt(close + 1) !== '}') {
throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
}
result += format.slice(i, close + 1);
i = close + 2;
continue;
}
result += format.slice(i, open);
i = open + 1;
if (format.charAt(i) === '{') {
result += '{';
i++;
continue;
}
if (close < 0) throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
var brace = format.substring(i, close);
var colonIndex = brace.indexOf(':');
var argNumber = parseInt((colonIndex < 0)? brace : brace.substring(0, colonIndex), 10) + 1;
if (isNaN(argNumber)) throw Error.argument('format', Sys.Res.stringFormatInvalid);
var argFormat = (colonIndex < 0)? '' : brace.substring(colonIndex + 1);
var arg = args\[argNumber\];
if (typeof(arg) === "undefined" || arg === null) {
arg = '';
}
if (arg.toFormattedString) {
result += arg.toFormattedString(argFormat);
}
else if (useLocale && arg.localeFormat) {
result += arg.localeFormat(argFormat);
}
else if (arg.format) {
result += arg.format(argFormat);
}
else
result += arg.toString();
i = close + 1;
}
return result;
}
```By the way, take a look at summary part of String.format:
/// /// /// ///
$select in listdata.svc
Sure you don’t want to load all the properties of listitems, like ContenTypeId and so on. We cannot avoid __metadata property :), but we can let listdata.svc to send only properties we want. By the way, the best tool for building listdata.svc queries is linqpad. Just write a usual Linq and linqpad converts it to web service url query: Another great stuff is $count, just add ?$count and you get only the count of items, no other junk.
Add global navigation links in Powershell and Feature Receiver
I think, powershell is the best way to do configurations you have to do once. Adding some links to global (top) navigation is one of them:
asnp microsoft.sharepoint.powershell
$w = get-spweb http://takana
$l = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Smells like team spirit", "/pages/teamspirit.aspx")
$w.Navigation.TopNavigationBar.AddAsLast($l)
Feature receiver
The alternative is to create a web scoped feature and provide properties:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
var web = properties.Feature.Parent as SPWeb;
var prop = properties.Feature.Properties\["MyGlobalLinks"\];
var links = prop.Value.Split(new\[\] { ";#" },
StringSplitOptions.RemoveEmptyEntries);
foreach (var item in links)
{
var newLink = item.Split(new\[\] { ";" },
StringSplitOptions.RemoveEmptyEntries);
var newMenuItem =
new SPNavigationNode(newLink\[0\], newLink\[1\]);
web.Navigation.TopNavigationBar.AddAsLast(newMenuItem);
}
}
```This feature can be prefereably hidden. The properties are passed in onet:
NavBarLink
I found even a third way to add links to global navigation: NavBarLink
Can't add a global site navigation link
If you encounter problems while customizing global site navigation in a custom site definition for SharePoint 2010, you probably can solve it by adding the necessary navbar element in navbars section of the onet.xml:
<NavBar Name="$Resources:core,category\_Top;"
Separator="&nbsp;&nbsp;&nbsp;"
Body="<a ID='onettopnavbar#LABEL\_ID#' href='#URL#' accesskey='J'>#LABEL#</a>"
ID="1002" />
It solved the problems for me :).
Comments from Wordpress.com
Chilly - Nov 3, 2012
How did you edit the Onet.XML file? What if this is only happening on one site in a whole site colleciton will this help this site as well. Thanks for any help you can give. This problem is bugging me on one of my sites.
Retention policies
Ziegler provides a cool intro, implementation sample and much more. When deployed we can apply this policy to a contenttype in the UI, or in code. To create our own expiration logic we have to implement IExpirationFormula and its ComputeExpireDate:
public class TaskExpiration : IExpirationFormula
{
public DateTime? ComputeExpireDate(SPListItem item,
XmlNode parametersData)
{
if (!item\["Status"\].Equals("Completed"))
{
return null;
}
var dt = (DateTime) item\["Modified"\];
return dt.AddDays(30);
}
}
```In order to see IExpirationFormula, add a reference to Microsoft.Office.Policy (and maybe Microsoft.Office.DocumentManagement): [![](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png "policy-dll")](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png) To see our custom retention policy, we have to register it in xml, we can do it in Feature Receiver like [Yaroslav](http://www.sharemuch.com/2011/01/10/creation-custom-retention-policies-for-sharepoint-2010-libraries/):
public override void FeatureActivated(SPFeatureReceiverProperties properties) { const string xmlManifest = “<PolicyResource xmlns=‘urn:schemas-microsoft-com:office:server:policy’” + " id = ‘Takana.TaskRetentionPolicy’" + " featureId=‘Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration’" + " type = ‘DateCalculator’>" + " Takana Task Retention Policy" + “Tasks expire 30 days after they have been completed” + “Takana.SharePoint, Version=1.0.0.0, Culture=neutral, " + “PublicKeyToken=920c0327f8b01d97” + “Takana.SharePoint.Policies.TaskExpiration” + “”; PolicyResourceCollection.Add(xmlManifest); }
Batch remove
To add items to a list in bulk, or remove them in bulk. Well to do that you can use SPLinq, Server Object Model and … web.ProcessBatchData, which is the most effective. I did an experiment today. I created 1000 tasks in my task list three times and removed all items in three different ways and took time. First I put 1000 items with ajax and listdata.svc:
function pad(n) {
if (n >= 10000) return n;
if (n >= 1000) return '0' + n;
if (n >= 100) return '00' + n;
if (n >= 10) return '000' + n;
return '0000' + n;
}
var s;
var counter = 0;
var title = "task "
function foo() {
counter++;
if (counter > 10000) {
window.clearInterval(s);
}
else {
var value = {};
value.title = title + pad(counter);
createNewTask(value);
}
}
s = setInterval(foo, 200);
Then I ran three different scenarios. Here is the resut for VMWare machine Windows Server 2008 R2, 4GB RAM, SharePoint 2010 SP1:
Add stsadm folder to PATH in cmd
Tired to see C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN\stsadm.exe? Wouldn’t be nice to run stsadm directly without going the 14 bin folder, or permanently changing %PATH%, well add this line to your script:
PATH=%PATH%;C:\\Program Files\\Common Files\\Microsoft Shared\\Web Server Extensions\\14\\BIN\\
format javascript date in ISO 8601
There is a solution in StackOverflow:
/\* use a function for the exact format desired... \*/
function ISODateString(d){
function pad(n){return n<10 ? '0'+n : n}
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'}
var d = new Date();
print(ISODateString(d)); // prints something like 2009-09-28T19:03:12Z
```But there is already a function for this: toISOString, it came with ecmascript 5. [Unfortunately, not all browsers support this](http://kangax.github.com/es5-compat-table/ "See the best comparision for ecmascript 5 support"), to solve this problem, we can provide our own prototype function for Date if it doesn't exist:
if (!Date.prototype.toISOString) { Date.prototype.toISOString = function() { function pad(n) { return n < 10 ? ‘0’ + n : n } return this.getUTCFullYear() + ‘-’ + pad(this.getUTCMonth() + 1) + ‘-’ + pad(this.getUTCDate()) + ‘T’ + pad(this.getUTCHours()) + ‘:’ + pad(this.getUTCMinutes()) + ‘:’ + pad(this.getUTCSeconds()) + ‘Z’; }; }
Pass arguments from/to Modal Dialog
To pass arguments from a ModalDialog is easy. Provide some buttons and invoke close function:
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, someValue);
```The first argument is result, [it is a enumeration with three alternatives](http://msdn.microsoft.com/en-us/library/ff409060.aspx): cancel, invalid and OK. The value you pass back to the main window can be a simple string, or a complex javascript object. In this example I'll create a html element which is hidden (id="modal-form" [class="s4-die"](/2011/10/14/s4-die/)):
Pass arguments to Modal Dialog and use it
In options you pass to SP.UI.ModalDialog.showModalDialog you can define args property. It can be any object with any complexity.
Get current user and handle a success callback
In my previous post I needed the accound id of the current user for posting new list items. To retrieve the id, we can push this to the client from the code behind, or get the current user using Client Object Model. To provide a more generic way we can write a js function which get the current user. But we must even provide some callback functionality, otherwise we don’t know if the operation was successful or not. Let’s be inspired by success and error properties in $.ajax:
Update list items with listdata.svc
In one of my previous posts I showed how to retrieve data from listdata.svc with jQuery $.getJSON method. Getting data is very simple, listdata.svc provides a powerful restful interface with filtering, expanding and other features. Read the best and short introduction to listdata.svc by Suneet Sharma or a more detailed and technical article about filters, functions and operators by Mike Flasko at Microsoft with short examples here. Now back to listdata.svc in the SharePoint environment. Corey Roth provides a good images and sample results. For REST the “http verbs” are very important: GET, POST, PUT, DELETE.. SharePoint RESTful interface defines these verbs like that:
Add content to a provisioned publishing page
We can use PublishingPageContent Property to write content to a page:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="Pages" Url="$Resources:cmscore,List\_Pages\_UrlName;" >
<File Path="Pages\\Help.aspx" Url="Help.aspx" Type="GhostableInLibrary">
<Property Name="Title" Value="Contoso Help Page" />
<Property Name="PublishingPageLayout" Value="~SiteCollection/\_catalogs/masterpage/ContosoPageLayout.aspx, Text page" />
<Property Name="ContentType" Value="$Resources:cmscore,contenttype\_welcomepage\_name;" />
<Property Name="PublishingPageContent" Value="hello world"/>
</File>
</Module>
</Elements>
javascript load callback for UpdatePanel
Using asp:UpdatePanel isn’t so easy with jQuery(document).ready() or jQuery(window).load(). The jQuery selectors can’t find elements which are not shown in the beginning. All other elements which are loaded dynamically are difficult to catch. I found a solution in forums.asp.net. A user called germanz creates an jQuery event listener AjaxReady, he uses the ASP.NET built-in PageRequestManager. If there only few usages of it it can be invoked directly from a PageRequestManager instance:
jQuery UI Datepicker
As an alternative to asp:Calendar we can use the fancy jQuery UI Datepicker:
$(document).ready(function () {
$.datepicker.setDefaults($.datepicker.regional\["sv"\]);
$("#").datepicker({
changeMonth: true,
changeYear: true,
yearRange: "-120:+0"
});
});
```I found this a much simple and best solution for an [birthdate input](http://stackoverflow.com/questions/339956/whats-the-best-ui-for-entering-date-of-birth). We can set [international options](http://stackoverflow.com/questions/1865091/jquery-datepicker-language-problem), [year range](http://stackoverflow.com/questions/269545/jquery-datepicker-years-shown), [year](http://stackoverflow.com/questions/3164898/jquery-ui-datepicker-next-and-previous-year) and [month navigation](http://jqueryui.com/demos/datepicker/dropdown-month-year.html). Other options I have tried are asp:Calendar, ajaxtoolkit:CalendarExtender and DateJs. jQuery UI is the most simple much more than datepicker and works smoothily with SharePoint.
ASP.NET Ajax Toolkit
To integrate ASP.NET Ajax Toolkit is not the most straight forward task in SharePoint. If you want to take the risk, “Inspired by Technology” provides the best guide so far.
Sort a lib when column headers are hidden
Just add this to the url in the browser address bar:
?SortField=Modified&SortDir=Asc
Push a copy of an object to client
To reduce postbacks and database calls, a copy of the current object(s) can be pushed down to the client in JSON format. Say a webpart renders information about a person, another webpart shows related information which is retrieved dynamically (like web services). Instead of getting the current person from the database in the second webpart again, we can reuse the same person object from the first webpart. To do so we must provide a DataContract for the Person class:
Custom Picker in Sharepoint
PeopleEditor is a nice webcontrol for picking people. To add it to your webpart or page is easy: But there is more we can do with pickers in Sharepoin. We can define our own pickers. Jeremy Luerkens gives one such example and a code sample (!). Another example can be found in Sharepoint as a Development Platform (p. 661), even though it misses the important class BookQueryControl. Just to start I made a book picker (I simplified and changed the idea provided in the book). Here is the working result, for simplicity the whole code is in one file: [sourcecode language=“csharp”] public partial class WPBookPickerUserControl : UserControl { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { pnlBook.Controls.Add(new BookEditor() { Width = Unit.Pixel(200), MultiSelect = false}); } } } public class Book { public string Title { get; set; } public string Author { get; set; } public string Price { get; set; } public string Publisher { get; set; } } public class BookDataManager { private static Book[] _books = { new Book {Title = “SP”, Author = “John”, Price = “2€”, Publisher = “Amazon”}, new Book {Title = “JS”, Author = “David”, Price = “3€”, Publisher = “Amazon”} }; private static DataTable GetDataTable(IEnumerable books) { var table = new DataTable(); table.Columns.Add(“Title”, typeof(string)); table.Columns.Add(“Author”, typeof(string)); table.Columns.Add(“Price”, typeof(string)); table.Columns.Add(“Publisher”, typeof(string)); foreach (var b in books) { table.LoadDataRow(new string[] { b.Title, b.Author, b.Price, b.Publisher }, true); } return table; } public static DataTable ValidateBook(string key) { var books = _books.Where(c => c.Title == key).ToArray(); return GetDataTable(books); } public static DataTable SearchForBooks(string keyword) { var books = _books.Where(c => c.Title.Contains(keyword)).ToArray(); return GetDataTable(books); } public static PickerEntity ConvertFromDataRow(DataRow dr, PickerEntity pi) { pi = pi ?? new PickerEntity(); var t = dr[“Title”].ToString(); var a = dr[“Author”].ToString(); var p = dr[“Price”].ToString(); var l = dr[“Publisher”].ToString(); pi.Key = t; pi.DisplayText = string.Format("{0} ({1}), {2}", t, a, p); pi.EntityData = new Hashtable(); foreach(DataColumn col in dr.Table.Columns) { pi.EntityData[col.ColumnName] = dr[col.ColumnName]; } return pi; } } public class BookEditor : EntityEditorWithPicker { public BookEditor() { PickerDialogType = typeof (BookPickerDialog); ValidatorEnabled = true; } public override PickerEntity ValidateEntity(PickerEntity needsValidation) { var tblItem = BookDataManager.ValidateBook(needsValidation.Key); needsValidation.IsResolved = false; if (tblItem != null && tblItem.Rows.Count > 0) { needsValidation = BookDataManager.ConvertFromDataRow(tblItem.Rows[0], needsValidation); needsValidation.IsResolved = true; } return needsValidation; } } public class BookQueryControl : PickerQueryControlBase { public TableResultControl ResultControl { get { return (TableResultControl)base.PickerDialog.ResultControl; } } public BookEditor EditorControl { get { return (BookEditor)base.PickerDialog.EditorControl; } } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); base.ColumnList.Visible = false; } private DataTable CreateDataTable() { // Method variables DataColumn column; // Init data table DataTable table = new DataTable(); table.Locale = CultureInfo.InvariantCulture; // Loop visible column names foreach (string columnName in ResultControl.ColumnNames) { column = new DataColumn {DataType = typeof (string), ColumnName = columnName}; table.Columns.Add(column); } // Return table return table; } public override PickerEntity GetEntity(DataRow dr) { // No datarow provided if (dr == null) return null; var pi = new PickerEntity(); var t = dr[“Title”].ToString(); var a = dr[“Author”].ToString(); var p = dr[“Price”].ToString(); var l = dr[“Publisher”].ToString(); pi.Key = t; pi.DisplayText = string.Format("{0} ({1}), {2}", t, a, p); pi.IsResolved = true; pi.EntityData = new Hashtable(); foreach (DataColumn col in dr.Table.Columns) { pi.EntityData[col.ColumnName] = dr[col.ColumnName]; } return pi; } protected override int IssueQuery(string search, string group, int pageIndex, int pageSize) { search = (search != null) ? search.Trim() : null; if (string.IsNullOrEmpty(search)) { PickerDialog.ErrorMessage = “No search provided”; return 0; } var table = BookDataManager.SearchForBooks(search); if (table == null || table.Rows.Count == 0) { PickerDialog.ErrorMessage = “No matching books found.”; return 0; } PickerDialog.Results = table; PickerDialog.ResultControl.PageSize = table.Rows.Count; return table.Rows.Count; } } public class BookPickerDialog : PickerDialog { public BookPickerDialog() : base(new BookQueryControl(), new TableResultControl(), new BookEditor()) { DialogTitle = “Custom Book Picker Dialog”; Description = “Please select one or more books”; MultiSelect = false; } protected override void OnPreRender(EventArgs e) { var resultControl = (TableResultControl) ResultControl; var columnDisplayNames = resultControl.ColumnDisplayNames; var columnNames = resultControl.ColumnNames; var columnWidths = resultControl.ColumnWidths; columnDisplayNames.Clear(); columnNames.Clear(); columnWidths.Clear(); var cols = new string[] {“Title”, “Author”, “Price”, “Publisher”}; columnDisplayNames.AddRange(cols); columnNames.AddRange(cols); columnWidths.AddRange(new string[] { “40%”, “20%”, “10%”, “30%”}); base.OnPreRender(e); } } [/sourcecode] Of course the best way is to create separate files for each class, but don’t forget to add Safecontrol to web.config.
Powershell scripts for AD
A tip for all who want to administer AD with powershell: Idera Powershell scripts. Just sign up and get the free scripts for AD, SQL, Exchange and Sharepoint. I personally prefer to user modules, so I change the file extension from ps1 to psm1 and then I can use import functions as modules. Here is a simple example for creating for domain users:
import-module .\\New-IADUser1.psm1
function Add-User($name) {
New-IADUser -Name $name
-sAMAccountname $name
-ParentContainer 'CN=Users, DC=contoso, DC=com'
-Password 'SvenskaAkademien1786'
-EnableAccount -PasswordNeverExpires
}
Add-User "user01"
Add-User "user02"
Add-User "user03"
Add-User "user04"
update 2012-03-15: nice script from Ryan
Ryan Dennis has created a very handy script for creating random users. In PowerShell v3.0 there is a cmdlet for creating users: New-ADUser. So the function above can be rewritten like that: [code language=“powershell”] Import-Module ActiveDirectory -ErrorAction SilentlyContinue function Add-User($name) { $password = ConvertTo-SecureString ‘SvenskaAkademien1786’ -AsPlainText -Force New-ADUser -Name $name -sAMAccountname $name -Path ‘CN=Users, DC=contoso, DC=com’ -AccountPassword $password -Enabled $true -PasswordNeverExpires $true } Add-User “user01” Add-User “user02” Add-User “user03” Add-User “user04” [/code]
json serializer in Sharepoint
There is a very handy JSON lib for serializing javascript objects. It is hosted on github under douglas crockford. Download json2.js and serialize with JSON.stringify function: EDIT: There is actually this function in core javascript. It exists since javascript 1.7 and ecmascript 5. So you don’t have to add anything to get this functionality:
var t = { name: "dev", city: "new york" };
JSON.stringify(t);
```There are actually built-in goodies for serializing javascript objects in [ASP.NET](http://msdn.microsoft.com/en-us/library/bb310857.aspx): Sys.Serialization.JavaScriptSerializer.serialize
var t = { name: “dev”, city: “new york” }; Sys.Serialization.JavaScriptSerializer.serialize(t);
Load Profile Image with javascript
See a great post in “Learning Sharepoint” with an example how to get a picture of user with Client Object Model and javascript.
Get Distinguished Name for a user
To get the distinguished name for a user, it isn’t enough to get an SPUser object. The distinguished name is the unique string for identifying a user in Active Directory (eg. CN=BeforeDAfter,OU=Test,DC=North America,DC=Fabrikam,DC=COM) Even using UserProfile object is not that clear. The distinguished name can be found in a property which can be retrieved with brackets: up[PropertyConstants.DistinguishedName]
public static string GetDistinguishedName(string login)
{
var dn = "";
UserProfile up;
using (var site = new SPSite("http://dev"))
{
var serviceContext = SPServiceContext.GetContext(site);
var upm = new UserProfileManager(serviceContext);
var exists = upm.UserExists(login);
if (!exists)
upm.CreateUserProfile(login);
if (exists)
{
up = upm.GetUserProfile(login);
dn = up\[PropertyConstants.DistinguishedName\].Value.ToString();
}
}
return dn;
}
```The code is simplified and doesn't contain any error handling. And a better handling of upm.UserExists must be implemented: If upm.CreateUserProfile(login) runs, it doesn't make it so quickly and the next step won't run (upm.GetUserProfile). If you are not working in SP Context, you can see the distinguished name for a user in Powershell:
import-module activedirectory $u = get-aduser administrator $u.DistinguishedName
jQuery timeago and the localization
If you have used SPUtility.TimeDeltaAsString you must know how useful it is. There is also the jQuery plugin that can perform counting of time deltas and (!) translate it. jQuery timeago is available for many languages, Swedish among others:
// Swedish
jQuery.timeago.settings.strings = {
prefixAgo: "för",
prefixFromNow: "om",
suffixAgo: "sedan",
suffixFromNow: "",
seconds: "mindre än en minut",
minute: "ungefär en minut",
minutes: "%d minuter",
hour: "ungefär en timme",
hours: "ungefär %d timmar",
day: "en dag",
days: "%d dagar",
month: "ungefär en månad",
months: "%d månader",
year: "ungefär ett år",
years: "%d år"
};
```The code is hosted on [Github](https://github.com/rmm5t/jquery-timeago). In order the time deltas to be localized in SharePoint a ScriptLink has to be used:
<SharePoint:ScriptLink ID=“timeagoLanguage” runat=“server” Language=“javascript” Name=“jquery.timeago.lang.js” Localizable=“True” LoadAfterUI=“True” OnDemand=“False” ></SharePoint:ScriptLink>
Google Analytics in Sharepoint
Google Analytics is a popular and mature tool for monitoring network activities on your site. Why not use it in Sharepoint? Dave Coleman and Mike Knowles provide good guides for doing that. There is a promising plugin to SP SPGoogleAnalytics which integrates both and provides an easy interface to put GA to your SharePoint installation and see the data directly on your intranet. It comes from codeplex: What do you think about spgoogleanalytics.codeplex? When I recently had to turn on Google Analytics on an intranet, I had no time for evaluating SPGoogleAnalytics, so I did the harder way: just put ga script in the end of a master page, just before ending tag. But what if one has multiple masterpages? Is there a way to put GA in one step? Maybe a user control like Knowles suggests?
Subdomains for site collections
In order to be able to use subdomains for different sitecollections, we have to use hostheaders. Sharad Kumar provides a good example:
$w = Get-SPWebApplication http://sitename
New-SPSite http://www.contoso.com
-OwnerAlias "DOMAIN\\jdoe" -HostHeaderWebApplication $w
-Name "Contoso" -Template "STS#0"
```If we want to create, say http://rockets.contoso.com, we can run:
New-SPSite http://rockets.contoso.com -OwnerAlias “DOMAIN\jdoe” -HostHeaderWebApplication “http://sitename” -Name “Rockets” -Template “STS#0” -Language 1053
restart-service iisadmin
Working with web.Properties
Sometimes one may need more properties to track on a SPWeb beside Title and Description. One of the possibilities is to create a custom list (maybe a hidden one) with keys and values (Title and Value). It works fine. The good thing with it is also the possibility to change the key-value pair directly in the web interface. Another approach is to use web.Properties which is a Dictionary with key-values pairs. A simpler and neater solution: Here is a good motivation from the best sharepoint book Sharepoint as a Development Platform (p. 1043):
$.getJSON, jQuery.tmpl and _vti_bin
Javascript is very fast, responsive and unburdens the cpu at the server. Here I show a little example how to use jQuery.getJSON, jQuery.tmpl (wonderful plugin for rendering repeating data, repo hosted on Github) and REST-based service listdata.svc from /_layouts/_vti_bin/ folder. For this example I created a generic list “Contacts”, added two text fields Name and Phone. Add some phone numbers and try to go to /_vti_bin/ListData.svc/Contacts If you get 404-error, install a ADO.NET Data Services v1.5 CTP2, as described at dotnetmafia. If you want to know more about how to sort and filter, skip and limit results, read more at nothingbutsharepoint. If you encounter problems, follow Michaël’s blog post and download and install Windows6.1-KB976127-v6-x64.msu (if you have Windows Server 2008 R2), or NDP35SP1-KB976126-v2-x64.exe (if you have Windows Server 2008). After installing the version of the System.Data.Services.dll file is 3.5.30729.5004 (Windows Server 2008 R2), and 3.5.30729.4466 (Windows Server 2008). Allright, the remainder is pure javascript. In order to get it working you have to run the script from the same domain, meaning you can’t run javascript to retrieve the data from a html-file from your home folder. Create a webpart and add it to your page.
Remove links to user profiles on list with javascript
Well, if you need remove links to user profiles, you can iterate all td-elements with class ms-vb-user using jQuery each function and remove a elements. Here is a little script:
$(document).ready(function() {
$(".ms-vb-user a").each(function() {
var text = $(this).text();
var span = document.createElement("span");
var user = document.createTextNode(text);
span.appendChild(user);
var parent = $(this).parent()\[0\];
parent.removeChild(this);
parent.appendChild(span);
});
});
```EDIT 2012-02-05 A much more better way to do it is [to use replaceWith in jQuery](http://stackoverflow.com/a/2409163/632117 "See a similar question and an answer on StackOverflow"):
$(".ms-vb-user a").each(function() { $(this).replaceWith(this.childNodes); });
Reset favicon cache
Favicon is one of the hardest. Ctrl-F5 doesn’t help. You can of course see the source, find the location of the favicon, click on it (if you use Firefox or Chrome), otherwise copy the url and paste it in the address bar. When you load it separately, the favicon cache is renewed. It works. But if you want to make it easier for your users, set a version to your favicon file in the masterpage:
Show files first in view
When you create an own view in schema.xml it is easy to show files first (Scope). It is quite useful if you want to show only few items on start page in xsltlistviewwebpart:
Scope="Recursive"
```Though there is a problem when you provision this list instance. Thanks to [a great post of Koen van der Linden about how to show files recursively](http://kvdlinden.blogspot.com/2010/04/schemaxml-onetxml-and-baseview-doesnt.html) it is no big deal to solve it. Just add the same scope to View element in the module in onet, which provisions your site:
<View List="$Resources:core,shareddocuments_Folder;" BaseViewID=“41” WebPartZoneID=“Middle” WebPartOrder=“2” Scope=“Recursive” />
Hide my site link with css
Want to hide my site link without disabling social features. Well, the simplest way to do it is to use css:
#mp1\_0\_0\_Anchor { display: none; }
```If you want to hide my profile instead, just hide #mp1\_0\_1\_Anchor:
#mp1_0_1_Anchor { display: none; }
.ms-MenuUIUL li[text=‘My Site’] { display: none;}
##### Disable the my profile feature An even better solution is maybe to disable the ability to change the profiles. [Just remove the permission to "user personalization..." for All authenticated users in User Profile Service](http://blog.libinuko.com/2010/10/10/sharepoint-2010-howto-disable-my-site-and-my-profile-link/).
## Comments from Wordpress.com
####
[John]( "johnandrewdavies@hotmail.com") - <time datetime="2012-03-07 00:15:32">Mar 3, 2012</time>
Be careful this cannot be used, the classes for pop up menus are generated dynamically on the page, and that class can be applied to a number of menus I assume depending on the order which they load on the page, which isnt the same every time, so for instance this hides something in the site actions menu, or the new button on a library sometimes.
<hr />
####
[Brett Anderson](http://sharepoint2020.wordpress.com "brettando@live.com.au") - <time datetime="2012-05-02 06:13:05">May 3, 2012</time>
Hi, The amended solution does not work in IE7.
<hr />
####
[Fredrik]( "fredrik.eriksson234@gmail.com") - <time datetime="2012-03-09 15:27:24">Mar 5, 2012</time>
Thank you Anatoly, that worked perfectly in all browsers! I had problems with the first suggested solution, because it would hide other menu items, like "edit this page" from the site settings dropdown!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:10:36">Mar 3, 2012</time>
You are totally right, John! I realized that too. Fortunately, I didn't need that then. But while using that I saw that sometimes Site Actions -Edit Page disappeared. These IDs are really generated dynamically. Thanks for your comment. I'll update my post.
<hr />
####
[vishal]( "vishals.shivan@gmail.com") - <time datetime="2012-03-07 07:27:54">Mar 3, 2012</time>
Hi Anatoly. Thanks for the solution. but the problem we are facing one problem after implementing this. Once we make this change and when login to the portal next time, the "Edit Page" link under site action menu is not getting displayed and the My Site Link is getting displyed. any suggestion?
<hr />
####
[Material SharePoint » Hide ‘My Site’ Link from Welcome User Dropdown Control](http://sharepoint.jsturges.com/2012/05/hide-my-site-link-from-welcome-user-dropdown-control/ "") - <time datetime="2012-05-12 17:45:13">May 6, 2012</time>
\[...\] of my enterprise level clients that we usually hide it all together! To do this, you can use an awesome CSS trick I learned from Anatoly \[...\]
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:24:39">Mar 3, 2012</time>
Hi Vishal. Unfortunately we cannot rely on these IDs, as John in previous comment mentioned, because these IDs are generated dynamically. I'll update my post. One possible solution would be use attribute selectors... Something like .ms-MenuUIUL li\[text='My Site'\] { display: none;}
<hr />
####
[jim]( "jim.omara@gmail.com") - <time datetime="2014-02-12 17:38:05">Feb 3, 2014</time>
.ms-welcomeMenu #mp1\_0\_0{ display:none; } .ms-welcomeMenu #mp1\_0\_1{ display:none; } .ms-welcomeMenu #mp1\_0\_2{ display:none; } .ms-welcomeMenu #mp1\_0\_3{ display:none; } .ms-welcomeMenu #mp1\_0\_4{ display:none; } .ms-welcomeMenu #mp1\_0\_8{ display:none; } .ms-welcomeMenu #mp1\_0\_9{ display:none; } these work for me.
<hr />
####
[Anatoly Mironov](http://chuvash.eu "mirontoli@gmail.com") - <time datetime="2014-02-12 23:20:59">Feb 3, 2014</time>
Thank you for sharing your solution. Appreciate.
<hr />
Go back in javascript
Add link for “Go Back” in javascript (inspired by Webmasters tips):
<a href="javascript:location.href=document.referrer;">Back</a>
```If you have access to the code behind you can [do the same](http://www.beansoftware.com/ASP.NET-FAQ/Referrer-URL.aspx) with:
Request.UrlReferrer.ToString()
```If you want to go to site collection root, it is simple, too: <SharePoint:SPLinkButton runat="server" NavigateUrl="<% $SPUrl:~SiteCollection/%>">Start</SharePoint:SPLinkButton>
Uninstall custom features in a batch
A funny powershell command I came upon today together with my colleague. Remove all your custom features (which start with something, say contoso):
Get-SPFeature
| Where { $\_.DisplayName.StartsWith("Contoso.") }
| ForEach { Uninstall-SPFeature $\_.Id -confirm:0 -force }
Have fun!
Configure User Profile Service Application
Today I have struggled with User Profile Service Application. I should have followed this awesome tutorial by ShareponitGeorge. And many thanks to my friend David for the great assistance! One important thing to beware about: Forefront Identity Manager Service must be running. Otherwise you don’t see the existing synchronization connections and you can’t add new connections. You can ensure that this service is running by running services.msc (just press Windows button and write services). Or you can do in powershell:
Sense of case
Sometimes one must have much sense of humour. Take a look at this:
<Field ID="{0F0BC0C4-2478-4CB5-85B0-A01B79956061}"
Name="TargetUrl"
DisplayName="MyUrl"
StaticName="TargetUrl"
Type="URL"
Sealed="TRUE"/>
```How many erros can arise in this custom field? Hmpf, everything is clear. But when I tried this (with Type="Url") many unexpected errors occured. Sometimes it is a tumbleweed with case-sensitive stuff in the case-insensitive Windows environment.
Auto-resize the main container in master page
If you have a master page with fixed size (perhaps in a centered layout). Here is a simplistic js-script to auto-resize:
$(window).load(function(){
$wider = false;
$pagecontainer = $("#pagecontainer");
$elementsToCareAbout = $("#ctl00\_MSO\_ContentDiv > \*, #ctl00\_MSO\_ContentDiv table")
$elementsToCareAbout.each(function(){
if($(this).width() > $pagecontainer.width())
{
$wider = true;
}
});
if ($wider) $pagecontainer.width(1200);
});
Any improvement ideas and suggestions are more than welcome.
Check if an html element is hidden using jQuery
Well, sometimes we need to calculate width and so on. In my next post I will write about how to fix auto-resize on fixed sized master pages. But now: a very nice stuff: how to check if an element is hidden or not:
$("#s4-leftpanel").is(":visible")
```It is a pure poetry. It reminds me of the beauty of [symbols in Ruby](http://rubylearning.com/satishtalim/ruby_symbols.html).
Add article content and editing to your Page Layout
If you work with Sharepoint Designer, use your own page layouts and want to have them for a page in a publishing site, you have to put in some controls in order to see th page content in you custom page layout. Put in a appropriate place in you page layout ( taken from ArticleLeft.aspx):
<div>
<PublishingWebControls:EditModePanel runat="server" CssClass="edit-mode-panel">
<SharePoint:TextField runat="server" FieldName="Title"/>
</PublishingWebControls:EditModePanel>
<div class="captioned-image">
<div class="image">
<PublishingWebControls:RichImageField FieldName="PublishingPageImage" runat="server"/>
</div>
<div class="caption">
<PublishingWebControls:RichHtmlField FieldName="PublishingImageCaption"
AllowTextMarkup="false" AllowTables="false" AllowLists="false"
AllowHeadings="false" AllowStyles="false" AllowFontColorsMenu="false"
AllowParagraphFormatting="false" AllowFonts="false" PreviewValueSize="Small"
AllowInsert="false" runat="server"/>
</div>
</div>
<div class="article-header">
<div class="date-line">
<SharePoint:DateTimeField FieldName="ArticleStartDate" runat="server"/>
</div>
<div class="by-line">
<SharePoint:TextField FieldName="ArticleByLine" runat="server"/>
</div>
</div>
<div class="article-content">
<PublishingWebControls:RichHtmlField FieldName="PublishingPageContent"
HasInitialFocus="True" MinimumEditHeight="400px" runat="server"/>
</div>
<PublishingWebControls:EditModePanel runat="server" CssClass="edit-mode-panel roll-up">
<PublishingWebControls:RichImageField FieldName="PublishingRollupImage"
AllowHyperLinks="false" runat="server" />
<asp:Label text="<%$Resources:cms,Article\_rollup\_image\_text%>" runat="server" />
</PublishingWebControls:EditModePanel>
</div>
Comments from Wordpress.com
Renate - May 1, 2014
Add TreeView to Site
For all of who use Randy Drisgill’s starter masters, it won’t help if you go to Site Actions TreView and just enable it, because the DelegateControl is in a hidden panel. To really restore the original treeview you have to copy this xml from v4.master:
<Sharepoint:UIVersionedContent runat="server" UIVersion="4">
<ContentTemplate>
<Sharepoint:SPNavigationManager
id="TreeViewNavigationManagerV4"
runat="server"
ContainedControl="TreeView"
CssClass="s4-treeView"
>
<SharePoint:SPLinkButton runat="server"
NavigateUrl="~site/\_layouts/viewlsts.aspx"
id="idNavLinkSiteHierarchyV4"
Text="<%$Resources:wss,treeview\_header%>"
accesskey="<%$Resources:wss,quiklnch\_allcontent\_AK%>"
CssClass="s4-qlheader" />
<div class="ms-treeviewouter">
<SharePoint:DelegateControl runat="server" ControlId="TreeViewAndDataSource">
<Template\_Controls>
<SharePoint:SPHierarchyDataSourceControl
runat="server"
id="TreeViewDataSourceV4"
RootContextObject="Web"
IncludeDiscussionFolders="true"
/>
<SharePoint:SPRememberScroll runat="server"
id="TreeViewRememberScrollV4"
onscroll="javascript:_spRecordScrollPositions(this);"
style="overflow: auto;height: 400px;width: 155px; ">
<Sharepoint:SPTreeView
id="WebTreeViewV4"
runat="server"
ShowLines="false"
DataSourceId="TreeViewDataSourceV4"
ExpandDepth="0"
SelectedNodeStyle-CssClass="ms-tvselected"
NodeStyle-CssClass="ms-navitem"
SkipLinkText=""
NodeIndent="12"
ExpandImageUrl="/_layouts/images/tvclosed.png"
ExpandImageUrlRtl="/_layouts/images/tvclosedrtl.png"
CollapseImageUrl="/_layouts/images/tvopen.png"
CollapseImageUrlRtl="/_layouts/images/tvopenrtl.png"
NoExpandImageUrl="/_layouts/images/tvblank.gif"
>
</Sharepoint:SPTreeView>
</Sharepoint:SPRememberScroll>
</Template_Controls>
</SharePoint:DelegateControl>
</div>
</Sharepoint:SPNavigationManager>
</ContentTemplate>
</SharePoint:UIVersionedContent>
and paste it before:
Creating custom my site template
Here are some links to start creating a custom my site template:
If you want to take the default templates take a look at **{SharepointRoot}\TEMPLATE\SiteTempates\SPMSITE **(the site template for “my content” - an individual site collection rootweb template, and first of all {SharepointRoot}\TEMPLATE\SiteTempates\SPMSITEHOST, the host site template for my sites. They include pages and onet.xml. Both use mysite.master which can be found at:
master page for html5 and css3
A great work: v5.master. I am recommending to try it. The problem are some javascript bugs in the IE 9 when you run IE mode 9 that are necessary to enable html5 and css3 support. You can’t “save” a list item: The reason why it doesn’t work in IE, but in Chrome, Firefox, is that IE invokes some functionality that it doesn’t invoke in other browsers. Next: Enable Save button in IE9
Determine the build version of Sharepoint
Sometimes you need to know what version of Sharepoint is installed on your machine. Perhaps when you want to restore a .bak-file (a backup done on another machine and you get error message like:
Restore-SPSite : Your backup is from a different version of Microsoft SharePoint Foundation and cannot be restored to a
server running the current version. The backup file should be restored to a server with version '14.0.0.6109' or later
To find out your build version you can do it in UI: go to Central Administration -> System Settings -> Manage servers in this farm -> Configuration database version. Or you can do in Powershell running:
Sharepoint Warmup Script
It is useful to warm up a site after app pool recycling or after a site creation in development environments. I found a very simple script which I made even simpler:
$url = "http://takana"
$wc = new-object net.webclient
$wc.credentials = \[System.Net.CredentialCache\]::DefaultCredentials
$wc.DownloadString($url) | out-null
$wc.Dispose()
For more sophisticated warmups Wahid Salemi provided an interisting script to warm up your Sharepoint. By the way. Let us save it as a powershell function. Take a look at sharepointryan’s functions. Let’s create a proper function of that:
A simple Log for ULS
Do an unsafe update in a unified manner « Sharepoint. Kunskap. Upptäckter på resan. - Sep 3, 2011
[…] Log class is my own class which I presented in my previous post. Like this:GillaBli först att gilla denna […]
A simple Log for ULS
Here is a simple log which has been inspired of Android Log. It logs to ULS which you can open with ULSViewer, SharePoint Log Viewer.
using System;
using Microsoft.SharePoint.Administration;
namespace Contoso.Intranet.Portal.Utilities
{
public class Log
{
private static readonly string \_CATEGORYNAME = "CONTOSO";
private static readonly SPDiagnosticsCategory \_ERROR\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Unexpected, EventSeverity.Error);
private static readonly SPDiagnosticsCategory \_WARNING\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.High, EventSeverity.Warning);
private static readonly SPDiagnosticsCategory \_VERBOSE\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Verbose, EventSeverity.Verbose);
private static readonly SPDiagnosticsCategory \_INFO\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Medium, EventSeverity.Information);
private static void WriteTrace(SPDiagnosticsCategory category, string message, string trace)
{
SPDiagnosticsService.Local.WriteTrace(0, category, category.DefaultTraceSeverity, message, trace);
}
public static void Error(Exception ex)
{
WriteTrace(\_ERROR\_CATEGORY, ex.Message, ex.StackTrace);
}
public static void Warning(string message)
{
WriteTrace(\_WARNING\_CATEGORY, message, "");
}
public static void Verbose(string message)
{
WriteTrace(\_VERBOSE\_CATEGORY, message, "");
}
public static void Info(string message)
{
WriteTrace(\_INFO\_CATEGORY, message, "");
}
}
}
A possible improvement can be a custom Area. See an example of ThorstenHans on Github: CustomLogger.cs EDIT: I found an interesting article: How to log to the SharePoint ULS Logs: Clean Debugging and Error Logging broken down into steps written by Philip Stathis.
Custom Title on built-in webpart
What to do if you want to change the title in the built-in webpart like Tasks or so. Your own title or just to avoid tasks (1) and tasks (2) if you add two views of them to a page. In onet.xml you add them as view:
<View
List="$Resources:core,lists\_Folder;/$Resources:core,tasks\_Folder;"
BaseViewID="7" WebPartZoneID="Middle"
WebPartOrder="6"/>
```The solution is to add [cdata element and webpart tag within it](http://www.novolocus.com/2011/06/14/set-the-title-of-a-listviewwebpart/). So now replace this with:
<![CDATA[ Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c Microsoft.SharePoint.WebPartPages.XsltListViewWebPart Task Title as I want it ]]>
Aktivera intellisense för javascript i VS
Det finns ett sätt att aktivera intellisense för javascript i VS: Klistra in det i ditt js-fil eller aspx:
/// <reference name="MicrosoftAjax.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.core.debug.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.debug.js" />
```Men tyvärr [kommer det inte funka om du har installerat Resharper](http://devnet.jetbrains.net/thread/297493). Eller lägg till vanliga script-taggar som beskrivet i boken Sharepoint As Developer Platform:
<asp:PlaceHolder ID=“PlaceHolder1” runat=“server” Visible=“false”> </asp:PlaceHolder>
SocialCommentWebPart
Lägg till en kommentarruta i din sida. Gör det lite till webb2.0. Här finns lite info. På denna sida står det hur man kan lägga till webparten mha xml. You can even provision a social comment webpart like it is done in my site:
<File Url="person.aspx" Type="Ghostable">
<AllUsersWebPart WebPartZoneID="MiddleLeftZone" WebPartOrder="3">
<!\[CDATA\[
<WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">
<Assembly>Microsoft.SharePoint.Portal, Version=14.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<TypeName>Microsoft.SharePoint.Portal.WebControls.SocialCommentWebPart</TypeName>
<Title>$Resources:spscore,SocialComment\_WebPart\_Title</Title>
<Description>$Resources:spscore,SocialComment\_WebPart\_Description</Description>
<PartOrder>3</PartOrder>
<FrameType>TitleBarOnly</FrameType>
<AllowMinimize>true</AllowMinimize>
<AllowRemove>true</AllowRemove>
<IsVisible>true</IsVisible>
</WebPart>
\]\]>
</AllUsersWebPart>
</File>
Sharepoint + OpenSource = Sant
Om man söker på Sharepoint i codeplex.com får man 729 projekt som är alltså öppna. Det är inte illa. Bland dem finns till exempel Sharepoint Log Viewer. Till det kommer 713 öppna projekt som är taggade ASP.NET som kan användas väldigt mycket i Sharepoint-utveckling. Bland ASP.NET-taggade finns smidiga Telerik Extensions. Powershell är också absolut en tag som man ska söka på i codeplex. codeplex.com är Microsofts officiella OpenSource-portal. Det måste finnas andra sidor där öppna projekt inom Sharepoint och ASP.NET samlas. Tipsa gärna i kommentarer.
Retrieve information from AD
Here is a a link you can start with. To test AD, install AD. Then we canplay with it. Take a look those examples, too.
PrincipalSearcher vs. DirectorySearcher
What is the difference?
OU
Here are two examples (one for PrincipalSearcher and the other for DirectorySearcher) to retrieve users from an OU:
//PrincipalSearcher
internal static void ListPrincipalsFromOu()
{
using(var ctx = new PrincipalContext(ContextType.Domain, "takana.local", "OU=SOME\_OU ,DC=takana, DC=local"))
{
using (var up = new UserPrincipal(ctx))
{
using (var ps = new PrincipalSearcher(up))
{
using (var res = ps.FindAll())
{
foreach (var p in res)
{
Console.WriteLine(p.SamAccountName);
}
}
}
}
}
}
//DirectorySearcher
internal static void ListAdEntriesFromOu()
{
const string property = "sAMAccountName";
var ldapcon = new DirectoryEntry("takana.local") {
Path = "LDAP://OU=SOME\_OU,DC=takana,DC=local"
};
var search = new DirectorySearcher(ldapcon);
search.PropertiesToLoad.Add(property);
using (var results = search.FindAll())
{
foreach (System.DirectoryServices.SearchResult result in results)
{
using (var entry = result.GetDirectoryEntry())
{
if (entry.Properties\[property\].Count > 0)
{
Console.WriteLine(entry.Properties\[property\]\[0\]);
}
}
}
}
}
Tag: Storage
How to Read SharePoint Storage Capacity with Graph
1 TB = 1024 GB in SPO?
There is confusion around how the storage is calculated in SharePoint Online. I believe, in SharePoint Online 1 TB is 1024 GB (based on powers of two), although the SI Prefix is for numbers based on powers of 10 (1TB = 1000GB, Wikipedia). In this post I would like to summarize the results of my investigations and I hope Microsoft or the community can confirm or disconfirm this.
First, let me explain why we care about it. The storage in SharePont is limited and we need to keep an eye on it. Especially in our case, where we need to track storage utilization across different parts of the organization/our tenant. The storage in SharePoint is calculated like so:
Tag: Tenant
How to Read SharePoint Storage Capacity with Graph
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Tag: Comments
Blog Comments are back
I haven’t had comments on my blog since I moved from wordpress. Until now. I just added comments back to my blog and here is how I did it.
The most convinient way is integrating my blog with Github Discussions using giscus.
The giscuss.app page walks you through the setup and authorization process.
I created a new public repository on Github, then I enabled Discussions feature on the repository (Settings -> Features).
Export AppendOnly Comments
Remember the old comments in SharePoint Lists? I am sure there are tons of lists that use the Append-Only Comments. They are implemented using versioning. The problem is that it is hard to export the comments, unless you know the tricks. The trick I want to share comes from a colleague of mine. The reason why we need export all the comments is that we need to document and save/archive the decision making process that took place in the comments field.
Add Comments column to your sharepoint list
If you have used Issue tracking list template in SharePoint you must have marked that the comments are added and marked with author name and datetime. It is handy to have these micro “discussion boards” on items. The comment-formed communication can help to fine-tune task definitions. By the way, have you seen Trello? So the question is how we can create this column in other lists? Here is a little tutorial how to create “append-only comments”, as they are called:
Tag: Github
Blog Comments are back
I haven’t had comments on my blog since I moved from wordpress. Until now. I just added comments back to my blog and here is how I did it.
The most convinient way is integrating my blog with Github Discussions using giscus.
The giscuss.app page walks you through the setup and authorization process.
I created a new public repository on Github, then I enabled Discussions feature on the repository (Settings -> Features).
Discord Bot From Hello World to Container Apps
Recently I Became Curious About Discord Bots and How They Work.
In this blog post, I am going to write about my learnings. While some parts might be familiar to you, I found it very amusing to start with a simple “Hello, World!” bot, run it locally, deploy it to the cloud, and integrate it with ChatGPT. Along the way, I learned a lot. I hope this post can inspire other people or at least serve as a reference to refresh my memory when I revisit this topic in the future.
New Home for My Blog
Hello World
Now I have moved my blog. chuvash.eu is a static site. I’ll share more details and insights later.
Update 2022-02-10
It has passed a few months since the move from Wordpress to a static site. Now it is time to summarize the insights.
Why I moved
Here are the reasons why I switched from Wordpress.com to a static site
- To be honest, the main reason was that I was curious about static sites.
- It appealed to me to have a fast and secure website (because there is no database that slows down or gets hacked).
- I finally got rid of the annoying ads from Wordpress.com. Don’t get me wrong. I appreciate Wordpress.com, as a matter of fact, I sacrified some really neat functions (such as the comments and the community) when moving to a static, but on that later.
- It finally got free from the vendor lock-in. Now I have all my blog posts as markdown files in a git repository. I can build them to any static website or even consume as they are, no fiddling with a database (if it were a own hosted wordpress site). I find it also easier to collaborate on my blog posts since I can grant access to the git repository to people I want to work together with.
- Speaking of git, now I have real version history of my content, no more accidential deletions.
Well, there might be more reasons, but these are the most important ones.
Re-discovering Github
Github has changed a lot. While working mostly in Azure DevOps I haven’t followed all the development on Github. Now when I look at that, I am really amazed.
Private Repos for Free accounts
Well, for me it is not as interesting, because with my free account, I don’t see any harm having my labs public. But I know, some people used bitbucket for their smaller private repos.
Github Project
I suppose it is the Azure DevOps Project concept that was copied to Github, a place for planning and having multiple connected repos.
SharePoint Utilities - a promising JavaScript Framework
My colleagues at Bool have developed a new JavaScript framework for SharePoint - sharepoint utilities. It started on our DevDay last year - a whole free day when we could learn new things, try out new techniques or build something that was not even requested from a customer. I was not working on sharepoint utilities, so I almost forgot it until… I recently re-discovered sharepoint utilities. It is on Github, it is MIT licensed and contributions are welcome. The core of sharepoint utilities (sputils) is a set of wrappers for Search, TermStore, REST that allow you be more productive as a developer. What I find especially compelling with that it contains some other fundamental stuff that every SharePoint developer needs:
JSGrid Basics
JSGrid is the javascript framework in SharePoint used in Quick Edit View (previously Datasheet View). There are a few very good blog posts on this topic (See below in “Sources”). Nevertheless the fact is that jsgrid and working with quick edit from a developer’s perspective is a huge undiscovered area. Articles I have seen are intended for advanced developers. The goal with my post today is to outline the very basics of working with JSGrid. When you know the basics you will be more comfortable to discover and try out more. The example I want to show is a jsgrid code for a “VerySimpleColumn”. The source code can be found on gist.github.com To focus on jsgrid, I assume you have knowledge and some experience of working with jslink, which is related to jsgrid.
Load git into PowerShell
Just a little productivity tip. If you use git on Windows, you probably already have the Github for Windows application. This application adds the Git Shell:
The Git Shell will open a PowerShell window and execute shell.ps1 from the Github directory:
What it won’t do is to load your personal PowerShell profile. I want to use my PowerShell profile that creates some links and adjust the look-and-feel and the promt of the shell. By the way I have published my profile.ps1 as a gist:
Toastr.js and SharePoint
Have you used SharePoint javascript Notifications (SP.UI.Notify)? Are you looking for something new and fresh? Well then check out the Toastr.js - a simple, beautiful, fully responsive and light-weight javascript lib for notifications, developed by John Papa and Hans Fjällemark and released under the MIT License. By the way, toastr was one of many things I discovered and learned on John Papa’s online course by pluralsight: Single Page Apps with HTML5, Web API, Knockout and jQuery. It is a really awesome course, where you learn how to create an amazing SPA. Well, how’s about SharePoint. While whatching the course videos about toastr, I thought: Can we use it in SharePoint? Yes we can! Just load the toastr css and js and start using it:
css3 transform
See Richards Bradshaw’s page with explanations and examples of css3 transform and transitions. His code is also available for forking on Github.
Sharepoint repos on github
You may think all interesting open source Sharepoint projects on codeplex. Well it is true, but there are some interesting projects on github as well. There are 17 projects for now. From a matrix to RichControls.
cloud9 web ide
Skapa javascript-appar i din webbläsare. Mycket smidigt. Direkt kontakt till github.
Improvement ideas
Now, to organize it a little bit, all improvement ideas will be placed in project issues on the github and tagged as “improvement ideas”. It is much better to collaborate this way. You can track the status of a improvement idea, comment it. Every time it is changed, all the involved developers will be announced.
Good beginners' tutorial on android, eclipse and git
Smashing magazine has a pretty good tutorial how to start programming for android using git, github, eclipse and datastorage. I recommend: Get Started Developing For Android With Eclipse, Reloaded
New files in Eclipse
If there are new classes or files in the project (say you have got the latest version from github into existing workspace in Eclipse). In order for Eclipse to see them, right click on the package and press “Refresh”.
Lusites wiki created
Now there is a wiki on github for LUSites to be able to collaborate.
migrera svn till git
Ja, hur gör man om man vill migrera till git? Låt oss säga, man vill använda github. Jag ska berätta hur man kan göra det. Jag gör det i Linux, förmodar samma gäller Mac. Det finns en bra manual om hur man migrerar svn till git. Vi ska gå igenom steg för steg. Skapa en fil som heter users.txt på ditt Skrivbord:
jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>
VisualSVN Server = server <server@server.com>
Det sista är nödvändigt. Eftersom om du har skapat en repository från VisualSVN, kommer det krävas en användarmappning för det med. Installera git-svn:
Tag: Azdo
Workload Identity Federation
There is no reason not to switch to Workload Identity Federation for Service Connections in Azure DevOps. Compared to secret-based connections, it offers several compelling benefits:
- Firstly, you eliminate the need for secrets. This means no more manual or automatic rotation of secrets, or worse, being caught off guard when secrets expire unnoticed.
- Secondly, it’s more secure. Secrets used across multiple projects and stored in key vaults or, even worse, in tools like OneNote, are far more susceptible to compromise than the new identity federation approach.
Here is my step-by-step guide on setting up Workload Identity Federation in Azure DevOps. I recommend the manual setup over the automatic one for these reasons:
Azure Key Vault vs. Pipeline Variables
Using Azure Key Vault in a Pipeline is cool, but it is less secure.
The Key Vault setup
Have you tried the Key Vault Step in an Azure DevOps Pipeline? If you haven’t, please follow these awesome guides:
- Azure DevOps Labs. Using secrets from Azure Key Vault in a pipeline
- Tobias Zimmergren. Using Azure Key Vault Secrets in Azure DevOps pipelines
The steps described in these guides are easy, but that effort made me think about the first pair of pros and cons.
Tag: Azure Devops
Workload Identity Federation
There is no reason not to switch to Workload Identity Federation for Service Connections in Azure DevOps. Compared to secret-based connections, it offers several compelling benefits:
- Firstly, you eliminate the need for secrets. This means no more manual or automatic rotation of secrets, or worse, being caught off guard when secrets expire unnoticed.
- Secondly, it’s more secure. Secrets used across multiple projects and stored in key vaults or, even worse, in tools like OneNote, are far more susceptible to compromise than the new identity federation approach.
Here is my step-by-step guide on setting up Workload Identity Federation in Azure DevOps. I recommend the manual setup over the automatic one for these reasons:
Azure Key Vault vs. Pipeline Variables
Using Azure Key Vault in a Pipeline is cool, but it is less secure.
The Key Vault setup
Have you tried the Key Vault Step in an Azure DevOps Pipeline? If you haven’t, please follow these awesome guides:
- Azure DevOps Labs. Using secrets from Azure Key Vault in a pipeline
- Tobias Zimmergren. Using Azure Key Vault Secrets in Azure DevOps pipelines
The steps described in these guides are easy, but that effort made me think about the first pair of pros and cons.
Tag: Deployment
Workload Identity Federation
There is no reason not to switch to Workload Identity Federation for Service Connections in Azure DevOps. Compared to secret-based connections, it offers several compelling benefits:
- Firstly, you eliminate the need for secrets. This means no more manual or automatic rotation of secrets, or worse, being caught off guard when secrets expire unnoticed.
- Secondly, it’s more secure. Secrets used across multiple projects and stored in key vaults or, even worse, in tools like OneNote, are far more susceptible to compromise than the new identity federation approach.
Here is my step-by-step guide on setting up Workload Identity Federation in Azure DevOps. I recommend the manual setup over the automatic one for these reasons:
Git Merge develop to main in an Azure DevOps Release
This post is a techy one. It’s about running git commands in Azure DevOps Releases in order to finalize a deployment job to production.
Let me first describe our scenario:
We use Azure DevOps for code and for deployment. Our branch strategy a simplified Gitflow model, where all the current work is merged to the “develop” branch. The code from the “develop” branch is then built and released to staging environments and production. After a release to Production and regression tests the develop branch needs to be merged into the “main” branch (or “master”). So simply put, the git merge into main is what we mean by finalizing a production release.
Tag: Pipelines
Workload Identity Federation
There is no reason not to switch to Workload Identity Federation for Service Connections in Azure DevOps. Compared to secret-based connections, it offers several compelling benefits:
- Firstly, you eliminate the need for secrets. This means no more manual or automatic rotation of secrets, or worse, being caught off guard when secrets expire unnoticed.
- Secondly, it’s more secure. Secrets used across multiple projects and stored in key vaults or, even worse, in tools like OneNote, are far more susceptible to compromise than the new identity federation approach.
Here is my step-by-step guide on setting up Workload Identity Federation in Azure DevOps. I recommend the manual setup over the automatic one for these reasons:
Azure Key Vault vs. Pipeline Variables
Using Azure Key Vault in a Pipeline is cool, but it is less secure.
The Key Vault setup
Have you tried the Key Vault Step in an Azure DevOps Pipeline? If you haven’t, please follow these awesome guides:
- Azure DevOps Labs. Using secrets from Azure Key Vault in a pipeline
- Tobias Zimmergren. Using Azure Key Vault Secrets in Azure DevOps pipelines
The steps described in these guides are easy, but that effort made me think about the first pair of pros and cons.
Tag: Security
Workload Identity Federation
There is no reason not to switch to Workload Identity Federation for Service Connections in Azure DevOps. Compared to secret-based connections, it offers several compelling benefits:
- Firstly, you eliminate the need for secrets. This means no more manual or automatic rotation of secrets, or worse, being caught off guard when secrets expire unnoticed.
- Secondly, it’s more secure. Secrets used across multiple projects and stored in key vaults or, even worse, in tools like OneNote, are far more susceptible to compromise than the new identity federation approach.
Here is my step-by-step guide on setting up Workload Identity Federation in Azure DevOps. I recommend the manual setup over the automatic one for these reasons:
Sites.Selected and Governance
The new permission in Graph API - Sites.Selected - is a step in the right direction. Since long we have been looking for ways of scoping the accesses to live up to the least privilege principle. It was either nothing or everything. I have tried out the new Sites.Selected permission and here are my findings.
First of all, if you haven’t heard about Sites.Selected, please visit these pages to find out more. I am skipping the introduction, since there are already good resources on that out there.
Tag: Svenska
Prova GPT-SW3
AI Sweden har publicerat den första svenska språkmodellen - GPT-SW3:
I det här inlägget vill jag beskriva hur man kommer igång om man vill testa det. Min setup är följande:
- En MacBook Pro (men det kan vara vilken dator som helst egentligen)
- Python 3.8^ + venv (om det lite senare)
- Visual Studio Code
- Jupyter Notebook Extension till Visual Studio Code
Datoruppsättning
Om inte du har gjort det tidigare, installera Visual Studio Code
Print2SPO - en enkel utskrift till SharePoint
Den här bloggposten är ett (en aning större) användar- (eller verksamhetsutvecklar-)tips om hur man kan sätta upp smarta utskrifter till SharePoint Online - utan några extraappar eller lösningar.
Först och främst, stort tack till min kollega Shahram som har presenterat idén för mig. Tänk dig ett följande scenario:
Du har en mall i Word som du fyller i, skriver ut på papper. Låt säga, det är en plockorder. Du vill digitalisera processen genom att skicka pdf:en till ett gemensamt dokumentbibliotek i SharePoint eller Teams.
Vår robot Stefan
Roboten Stefan
Här är historian om Stefan, en robot jag och barnen har jobbat på under den senaste månaden. I en sann DIY-anda vill jag skriva om vårt projekt på bloggen och förhoppningsvis inspirera andra att utforska det. I och med projektet innebär en hel del pyssel, så är det lämpat i princip för alla åldrar.
Även om allting togs fram parallellt och stegvis (“i iterationer”), kommer projektet presenteras det i förenklad ordning
Kombinera två SharePoint-listor i PowerBI
Det här är en enkel guide på svenska om hur du kan ladda in data från två eller fler listor i SharePoint och lägga ihop dem till en.
Scenariot är följande. Du har två eller fler sajter i SharePoint Online som har var sin lista (med samma kolumner). Du vill ladda in data från båda och se en aggregerad/summerad version. Alternativet är att ha en delad lista, men ibland (av behörighetskäl eller av behovet för smärre anpassningar av enskilda listor), ligger det i separata listor/sajter.
Snabba diagram i SharePoint Online
Ett nytt tips på svenska: det finns en webpart i SharePoint Online: snabbdiagram.
När du har lagt till ett snabbdiagram, kan du skriva välja mellan stapel och cirkeldiagram
Du kan bara välja mellan stapel- och cirkeldiagram.
Data går att mata in direkt.
Resultatet får du direkt:
Använd data från en lista
Det går att visualisera data från en SharePoint-lista. Det är inte så mycket mer komplicerat, men det öppnar nya möjligheter. Du behöver bara hålla listan uppdaterad.
Tag: Azure
Discord Bot From Hello World to Container Apps
Recently I Became Curious About Discord Bots and How They Work.
In this blog post, I am going to write about my learnings. While some parts might be familiar to you, I found it very amusing to start with a simple “Hello, World!” bot, run it locally, deploy it to the cloud, and integrate it with ChatGPT. Along the way, I learned a lot. I hope this post can inspire other people or at least serve as a reference to refresh my memory when I revisit this topic in the future.
A powershell script for activating an eligible role assignment in Azure AD
Recently my role assignments in Azure AD were switched from permanent to eligible ones. This is part of PIM - Privileged Identity Management, you can read more about it on MS Docs:
To activate your eligible assignment you can use Azure Portal, Graph API, and PowerShell. The activation in the portal and Graph API is described on MS Docs:
Sites.Selected and Governance
The new permission in Graph API - Sites.Selected - is a step in the right direction. Since long we have been looking for ways of scoping the accesses to live up to the least privilege principle. It was either nothing or everything. I have tried out the new Sites.Selected permission and here are my findings.
First of all, if you haven’t heard about Sites.Selected, please visit these pages to find out more. I am skipping the introduction, since there are already good resources on that out there.
A cost effective way of running legacy scripts in the cloud
Have you also got some old huge scripts that run on a server locally? Have you also considered moving them to the cloud? Here comes an idea of how to do it quickly and easy.
In my case I have some older powershell scripts that are harder to convert to serverless applications:
- They use MSOnline module in PowerShell, hence they require rewriting to AzureAD before using them in an Azure Function
- They take around 15 minutes to complete, Azure Functions Consumption Plan is limited to 10 minutes. Of course I can split them in several parts, but I am looking for an easy way right now, I have to postpone refactoring because I am not sure if there is a real need for this script solution.
- They process a lot of data and consume more that 400 MB memory which makes it crash when I put it in a Azure Automation Runbook.
Well, maybe a Windows Server VM in Azure is the only way? While recently setting up a minecraft server and following a blog post that proposes auto shutdown and logic apps to start the server, I came up with an idea to use exactly the same approach to make it as cost effective as possible.
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Setting up a HelloWorld Azure Alert
Azure Alerts are awesome for monitoring of solutions in Azure. If you are about to set up your first Alert Rules in Azure, then it’s a guide for you. Configuring alert rules can be quite intimidating at first, with all the options, metrics, evaluation times, etc.
Here is a very very simple setup that can serve as a teaser and help you get started with the Azure Alerts.
Using secrets in Logic Apps in a secure way
This is a guide for how to handle secrets in a logic app in a secure way. It combines three resources:
- Accessing Key Vault from Logic App with Managed Identity
- Get Secrets Key Vault API
- Hide your logic apps secrets from prying eyes
First, enable a Managed Identity for your Logic App:
In the KeyVault, add a new Access Policy for the new Managed Identity (from the previous step). Use the least priviliges. In my case it is just enough with GET for secrets.
Filtering Azure Table Data directly in the Azure Function Binding
Instead of filtering values from an Azure Storage Table, you can do it directly in the bindings. It might not be a solution for everything, but in the right place, it is fantastic. I was very surprised to see how little code was needed after this binding change:
For that to work, define the filter attribute in the bindings: “filter”: “(PartitionKey eq ‘{package}’)”
To try it out, add a new row in a table defined in the bindings (“metadata” in my case):
Trust gulp-connect certificate from Visual Studio Online on Mac OS
I have read and followed this awesome post:
Getting SPFx working in Visual Studio Online by SPDavid.
I got my fingers and tried that guide out. This worked good, I spent some time, though, googling (binging) around to get rid of the SSL Warnings for the remote “localhost” on my Mac.
I would like to share this simple instruction on how to trust a self signed certificate from gulp-connect on Mac OS. The implication is that the certificate is on the remote linux machine (on the Visual Studio Environment), that you are connected to through the Visual Studio Code extension.
Tips and Trick for Azure Functions
These are my favourite tips and tricks. These are only those who me and my colleguages have tried out.
Architecture tips
Keep it slim
Functions should do one thing and they should do it well. When you develop it in C# and Visual Studio, it is so tempting to develop a “microservice” in a good way, you add interfaces, implement good patterns, and all of a sudden you get a monolith packaged in a microservice. If your function grows, stop, rethink. Better to see how it input and output bindings can be used. Also orchestration with Logic Apps or Durable Functions can help.
Simple Build for dotnet new react
I created a sample ASP.NET Core app with React.
dotnet new react
Then it took a couple of hours to get the build to work. Here is my working azure-pipelines.yml:
Resources:
S01E01 IoT: Posting Temperature from Raspberry Pi to Azure
Recently I have looked more at IoT, Raspberry Pi in my spare time. In my blog post I want to share my experience in a series of posts. This post is about measuring temperature, humidity and pressure with Raspberry Pi 2 Model B and Sense Hat and posting this data to Azure Table Storage. I followed this tutorial for connecting to azure with python and these instructions for reading data from Sense Hat. The python script is on github. Along the way I learned that only python 2.x can be used with azure and table names cannot contain underscore (I got Bad Request error when I tried to create a table with the name “climate_data”). But overall, the process was straightforward. The temperature is not correct, maybe because the sensor is inbetween Raspberry Pi and Sense Hat where it gets warm. But it is just a Proof-of-Concept. I have used Visual Studio 2015 to see the data in Azure Table Storage. For that I needed to install Azure SDK 2.7. There are many other “explorers” for Azure Storage. Other resources Accessing Azure from Linux and Mac Improvement #1 Corrected Temperature I found a formula for calculating more correct temperature on the raspberry pi forum.
Tag: Bot
Discord Bot From Hello World to Container Apps
Recently I Became Curious About Discord Bots and How They Work.
In this blog post, I am going to write about my learnings. While some parts might be familiar to you, I found it very amusing to start with a simple “Hello, World!” bot, run it locally, deploy it to the cloud, and integrate it with ChatGPT. Along the way, I learned a lot. I hope this post can inspire other people or at least serve as a reference to refresh my memory when I revisit this topic in the future.
11 Things I learned about chat bots in Teams
Recently we developed and published a chat bot in Power Virtual Agents for Teams (PVAforTeams). I would like to share my takes and lessons learned with you.
#1 Easy to edit, fun to work with
Bots in PVAforTeams are no-code solutions and provide a comprehensive graphical interface. Developers, analysts, business representatives can work together on defining topics, user flows. It has been really fun to shape the bot in a group - with a lot of laughter and interesting discussions about users’ work habits and how users search and find information. This is how the simplest topic looks like: Greeting:
Tag: Chatgpt
Discord Bot From Hello World to Container Apps
Recently I Became Curious About Discord Bots and How They Work.
In this blog post, I am going to write about my learnings. While some parts might be familiar to you, I found it very amusing to start with a simple “Hello, World!” bot, run it locally, deploy it to the cloud, and integrate it with ChatGPT. Along the way, I learned a lot. I hope this post can inspire other people or at least serve as a reference to refresh my memory when I revisit this topic in the future.
Tag: Cloud
Discord Bot From Hello World to Container Apps
Recently I Became Curious About Discord Bots and How They Work.
In this blog post, I am going to write about my learnings. While some parts might be familiar to you, I found it very amusing to start with a simple “Hello, World!” bot, run it locally, deploy it to the cloud, and integrate it with ChatGPT. Along the way, I learned a lot. I hope this post can inspire other people or at least serve as a reference to refresh my memory when I revisit this topic in the future.
First look at Yammer integration in SharePoint 2013 SP1
I have installed SharePoint SP1 on my development machine. Yammer and OneDrive links have appeared in the Central Administration: If you go ahead and click “Configure Yammer”, you can activate it: Because:
Yammer is Microsoft’s recommended tool for social collaboration.
When you activate Yammer, you’ll get this dialog, and the Yammer link in the SuiteBar: What happens when you click on Yammer, is that you are redirected to Yammer.com and you are prompted a login page. Then you have a usual yammer site with all your networks and stuff (in my case, SPC14 network): Then, if you go to your newsfeed, the following message is shown:
Hello world in node.js
I know, node.js has been present for a while. But I actually had no time to try it. I was surprised that now it is very straight forward to start with node.js. Allright, everything begins with Hello world. Eventhough it is available for allmost all combinations of operating systems and servers, the easiest way to test it was actually Ubuntu. To install just run:
sudo apt-get install nodejs
```Then make a new directory and create the hello.js:
mkdir hello cd hello vi hello.js
Tag: Containerapp
Discord Bot From Hello World to Container Apps
Recently I Became Curious About Discord Bots and How They Work.
In this blog post, I am going to write about my learnings. While some parts might be familiar to you, I found it very amusing to start with a simple “Hello, World!” bot, run it locally, deploy it to the cloud, and integrate it with ChatGPT. Along the way, I learned a lot. I hope this post can inspire other people or at least serve as a reference to refresh my memory when I revisit this topic in the future.
Tag: Discord
Discord Bot From Hello World to Container Apps
Recently I Became Curious About Discord Bots and How They Work.
In this blog post, I am going to write about my learnings. While some parts might be familiar to you, I found it very amusing to start with a simple “Hello, World!” bot, run it locally, deploy it to the cloud, and integrate it with ChatGPT. Along the way, I learned a lot. I hope this post can inspire other people or at least serve as a reference to refresh my memory when I revisit this topic in the future.
Tag: Docker
Discord Bot From Hello World to Container Apps
Recently I Became Curious About Discord Bots and How They Work.
In this blog post, I am going to write about my learnings. While some parts might be familiar to you, I found it very amusing to start with a simple “Hello, World!” bot, run it locally, deploy it to the cloud, and integrate it with ChatGPT. Along the way, I learned a lot. I hope this post can inspire other people or at least serve as a reference to refresh my memory when I revisit this topic in the future.
Tag: Doclib
Show Path Column in SharePoint
PnP.PowerShell is just the tool you need to show the Path column in a SharePoint document library view. Scroll down to see the script, or read on to learn more.
An introduction
Do you still have folders in SharePoint? Well, you are not alone. Remember the old dream of relying on metadata only? Forget it! As a matter of fact, folders are still a popular way of organizing files in SharePoint. When not overused, they provide “metadata” by itself, metadata that works even in synced folders, in archive scenarios, works best with Teams etc.
Tag: List
Show Path Column in SharePoint
PnP.PowerShell is just the tool you need to show the Path column in a SharePoint document library view. Scroll down to see the script, or read on to learn more.
An introduction
Do you still have folders in SharePoint? Well, you are not alone. Remember the old dream of relying on metadata only? Forget it! As a matter of fact, folders are still a popular way of organizing files in SharePoint. When not overused, they provide “metadata” by itself, metadata that works even in synced folders, in archive scenarios, works best with Teams etc.
Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
ForEach-metod i List
En intressant variant av foreach är ForEach-metoden i List. Titta på det lilla exemplet:
private static void SavePlacesToDB(SQLiteConnection cnn,
List<dynamic> places)
{
places.ForEach(obj => SavePlaceToDB(obj, cnn));
}
```Här används även det nya objektet [dynamic](http://msdn.microsoft.com/en-us/library/dd264736.aspx) som har kommit i Visual Studio 2010, samt en [lambda expression (=>)](http://msdn.microsoft.com/en-us/library/bb397687.aspx).
Tag: Pnp
Show Path Column in SharePoint
PnP.PowerShell is just the tool you need to show the Path column in a SharePoint document library view. Scroll down to see the script, or read on to learn more.
An introduction
Do you still have folders in SharePoint? Well, you are not alone. Remember the old dream of relying on metadata only? Forget it! As a matter of fact, folders are still a popular way of organizing files in SharePoint. When not overused, they provide “metadata” by itself, metadata that works even in synced folders, in archive scenarios, works best with Teams etc.
Sites.Selected and Governance
The new permission in Graph API - Sites.Selected - is a step in the right direction. Since long we have been looking for ways of scoping the accesses to live up to the least privilege principle. It was either nothing or everything. I have tried out the new Sites.Selected permission and here are my findings.
First of all, if you haven’t heard about Sites.Selected, please visit these pages to find out more. I am skipping the introduction, since there are already good resources on that out there.
Smarter way of loading SharePoint CSOM dll in PowerShell
Have you also got a legacy powershell script that loads SharePoint dlls and runs CSOM code directly? It’s quite easy to convert to PnP PowerShell. But if you run out of time and just need to execute the script, then I have a quick tip for you.
First of all, a CSOM script can be recognized by Add-Type commands (or Import-Module) plus the SharePoint dll paths.
Loading the dll the old way.
Demote News in SharePoint Online
In case you published a news in SharePoint Online and you now want to “downgrade” it to a regular page, I have a solution for you.
The reasons why you would like to demote a News might vary:
- You publish an important message, perhaps a note about an operational disturbance. It might not relevant anymore, but you still want to keep the page in case someone wants to access the information.
- You accidentally create a page as a news.
- …
Hiding Teamify Prompt
If you want to remove the Microsoft Teams Banner on your SharePoint Site, the only thing you need is to set a web property on a site: TeamifyHidden=TRUE. I’ll give you some guidance below. But before you do that, consider following:
- If there is already a team created for a group connected site, the prompt won’t show up. Why fix something that is not a problem?
- Only group owners will get the prompt, if they are few and they know what it is, it is better to let them to decide whether to create or not to create a team.
- Only licensed users within your organization will be shown that choice. No external users or users without a license.
- And the most important part: if any site owner selects “Don’t show me again” it will stop popping up for all other site owners. If you happen to have a manual step in the group creation process, then you can just click it away.
Tag: Powershell
Show Path Column in SharePoint
PnP.PowerShell is just the tool you need to show the Path column in a SharePoint document library view. Scroll down to see the script, or read on to learn more.
An introduction
Do you still have folders in SharePoint? Well, you are not alone. Remember the old dream of relying on metadata only? Forget it! As a matter of fact, folders are still a popular way of organizing files in SharePoint. When not overused, they provide “metadata” by itself, metadata that works even in synced folders, in archive scenarios, works best with Teams etc.
Automate Creation of Git Repos Using Azure DevOps API
Today I got a question: how can we precreate 50 git repositories in an Azure DevOps Project? I started to learn about the API in Azure DevOps and I found it very interesting. With the API you can script and automate administration of projects, repositores, pull requests etc. To keep this blog post simple and digestable I would like to focus on the intitial request - creating git repositories by code.
A powershell script for activating an eligible role assignment in Azure AD
Recently my role assignments in Azure AD were switched from permanent to eligible ones. This is part of PIM - Privileged Identity Management, you can read more about it on MS Docs:
To activate your eligible assignment you can use Azure Portal, Graph API, and PowerShell. The activation in the portal and Graph API is described on MS Docs:
Sites.Selected and Governance
The new permission in Graph API - Sites.Selected - is a step in the right direction. Since long we have been looking for ways of scoping the accesses to live up to the least privilege principle. It was either nothing or everything. I have tried out the new Sites.Selected permission and here are my findings.
First of all, if you haven’t heard about Sites.Selected, please visit these pages to find out more. I am skipping the introduction, since there are already good resources on that out there.
Smarter way of loading SharePoint CSOM dll in PowerShell
Have you also got a legacy powershell script that loads SharePoint dlls and runs CSOM code directly? It’s quite easy to convert to PnP PowerShell. But if you run out of time and just need to execute the script, then I have a quick tip for you.
First of all, a CSOM script can be recognized by Add-Type commands (or Import-Module) plus the SharePoint dll paths.
Loading the dll the old way.
A cost effective way of running legacy scripts in the cloud
Have you also got some old huge scripts that run on a server locally? Have you also considered moving them to the cloud? Here comes an idea of how to do it quickly and easy.
In my case I have some older powershell scripts that are harder to convert to serverless applications:
- They use MSOnline module in PowerShell, hence they require rewriting to AzureAD before using them in an Azure Function
- They take around 15 minutes to complete, Azure Functions Consumption Plan is limited to 10 minutes. Of course I can split them in several parts, but I am looking for an easy way right now, I have to postpone refactoring because I am not sure if there is a real need for this script solution.
- They process a lot of data and consume more that 400 MB memory which makes it crash when I put it in a Azure Automation Runbook.
Well, maybe a Windows Server VM in Azure is the only way? While recently setting up a minecraft server and following a blog post that proposes auto shutdown and logic apps to start the server, I came up with an idea to use exactly the same approach to make it as cost effective as possible.
Demote News in SharePoint Online
In case you published a news in SharePoint Online and you now want to “downgrade” it to a regular page, I have a solution for you.
The reasons why you would like to demote a News might vary:
- You publish an important message, perhaps a note about an operational disturbance. It might not relevant anymore, but you still want to keep the page in case someone wants to access the information.
- You accidentally create a page as a news.
- …
Add a security group as hubbers using PowerShell
Today I needed to add a security group to “People who can associate sites with this hub” through PowerShell. Here is quick how-to. I usually say “hubbers” instead of the long “People who….”. By the way, if you want to know what prerequisites there are for being a hubber, read my other blog post
An example of how to add a security group is missing in the MS Docs:
Setting up a HelloWorld Azure Alert
Azure Alerts are awesome for monitoring of solutions in Azure. If you are about to set up your first Alert Rules in Azure, then it’s a guide for you. Configuring alert rules can be quite intimidating at first, with all the options, metrics, evaluation times, etc.
Here is a very very simple setup that can serve as a teaser and help you get started with the Azure Alerts.
Is an M365 Group a Yammer Community
Nowadays a Yammer Community gets a corresponding Microsoft 365 Group (Office 365 Group, Unified Group). In your work as an SPO Admin, you might need to differentiate “ordinary” Modern Team Sites from those ones that were created for a Yammer Community.
They both have GROUP#0 as Template. On the actual SPO Site object, there is nothing that you can use to differentiate those. Neither you can use the Office 365 Group information. But there is a way: if you connect to Exchange Online and get the group from there, then there is something useful.
Estimated Completion in Write-Progress in PowerShell
Have you also got many sites in your tenant? Write-Progress is the bare minimum in a script that goes through all sites. But there is also another nice way to make easier to see the progress - estimated completion time.
Although the idea comes from another blog post (My life is a message), I thought it could be worth sharing it again, especially in the cloud context.
Here is a bit simplified scenario: Getting information for every site. The status message in Write-Progress contains also the estimated completion time.
Optimizing lookups in PowerShell
Have you had a PowerShell script that contains two bigger arrays and you wanted merge the information. It can become quite slow if you need to search for every item from array A through all items in array B. The solution is called a HashTable! It might be not an advanced tip for some, but I was really glad to see a huge improvement, so I decided to share it as a post.
Get totals from a list view using PowerShell
Today I will share a short script for getting totals from a list view in SharePoint. Imagine this scenario: you have set up a list view with totals and you want get the totals every day for statistics or some other reasons. Instead of getting all items, and/or fiddling around with CamlQueries, there is a better and quicker way - List.RenderListData. This combined with a tip from Piyush K Singhs blog post Get Aggregate Values… I came up with an idea to read the ViewXml from an existing view and retrieve the totals (in my case Count and Sum). Enough talking, let’s take a look at the code:
My PowerShell Profile
It has been a while I last worked with PowerShell. I had my custom profile where I had my own prompt and some other customizations. Now I cannot find it anymore. I’ll start with the new one and I am saving it on my blog, so it will be easier to find in future: [code language=“powershell”] Function Prompt { $PromptData=“PS $($executionContext.SessionState.Path.CurrentLocation)$(’>’ * ($nestedPromptLevel + 1)) " $host.ui.RawUI.WindowTitle=$PromptData +’-’+(Get-Date).tostring() # .Link# http://go.microsoft.com/fwlink/?LinkID=225750 # .ExternalHelp System.Management.Automation.dll-help.xml } [/code] The prompt function comes from the scripting guy blog. To customize your profile, just open it in a text editor (in my case: code) [code language=“powershell”] code $profile [/code] Update 2018-04-10 You can also include these lines: [code language=“powershell”] $path1 = “C:\Program Files\Common Files\microsoft shared\Web Server Extensions\” $path2 = “15” Add-Type -Path “$path1\$path2\ISAPI\Microsoft.SharePoint.Client.dll” Add-Type -Path “$path1\$path2\ISAPI\Microsoft.SharePoint.Client.Runtime.dll” [/code] VS Code Now we can run VS Code to create ps1 scripts and run selections as we did it in PowerShell ISE.
Export SharePoint List Data To Xml through PowerShell
Today my colleague Johannes Milling wrote an awesome post: Export SharePoint List Data To XML Directly from the GUI He uses the old and forgotten RPC-based web service owssvr.dll (that has existed since SharePoint 2003). This url pattern is used to get the xml-formatted list data for a specific ListView: [source] http://<site_url>/_vti_bin/owssvr.dll?Cmd=Display&List=&View=&Query=*&XMLDATA=TRUE [/source] To automate this I have written a PowerShell function. All the details are in the comments: [source language=“PowerShell”] function Export-OIPSPListDataAsXml { <# .Synopsis Exports list items as xml .DESCRIPTION This function uses a built-in hidden service owssvr.dll in SharePoint .PARAMETER Web SPWeb or a url for the SPWeb object where the list resides .PARAMETER ListName List Name (List Title) .PARAMETER ViewName Name of the List View to export the data .EXAMPLE Export-OIPSPListView -Web http://myawesomesite -ListName “Teddy Bears” -ViewName “All Items” .EXAMPLE Export-OIPSPListView -Web $webInstance -ListName “Top Links” -ViewName “All Items” .Notes Name: Export-OIPSPListDataAsXml Author: Anatoly Mironov Last Edit: 2014-09-11 Keywords: SPList, SPWeb, SPListView, Xml .Link http://chuvash.eu #> [CmdLetBinding()] param( [Parameter(Mandatory=$true)] [Microsoft.SharePoint.PowerShell.SPWebPipeBind]$Web, [Parameter(Mandatory=$true)] [string]$ListName, [Parameter(Mandatory=$true)] [string]$ViewName) $spWeb = $Web.Read() $list = $spWeb.Lists[$ListName] if (!$list) { throw “List $ListName on web $($spWeb.Url) could not be found” } $view = $list.Views[$ViewName] if (!$view) { throw “View $ViewName on web $ListName could not be found” } $url = “{0}/_vti_bin/owssvr.dll?Cmd=Display&List={1}&View={2}&Query=*&XMLDATA=TRUE” ` -f $spWeb.Url, $list.ID, $view.ID $wc = New-Object Net.WebClient $wc.UseDefaultCredentials = $true $wc.DownloadString($url) } [/source]
Showing Birthdays and Job Anniversaries in the Newsfeed
In our project we have a requirement to show birthdays and job anniversaries in the Newsfeed. The solution is simple (when you know it) but there has not been any information about it online, until today. I want to share a few lines of PowerShell code to enable Anniversary notifications in the Newsfeed. This desired piece of code was written by my colleague Emma Degerman. Enjoy:
[source language=“PowerShell”] $job = Get-SPTimerJob | ? { $_.TypeName -like “*.UserProfileChangeJob” } $job.GenerateAnniversaries = $true $job.Schedule = [Microsoft.SharePoint.SPSchedule]::FromString(“hourly between 55 and 55”) $job.Update() [/source]
Load git into PowerShell
Just a little productivity tip. If you use git on Windows, you probably already have the Github for Windows application. This application adds the Git Shell:
The Git Shell will open a PowerShell window and execute shell.ps1 from the Github directory:
What it won’t do is to load your personal PowerShell profile. I want to use my PowerShell profile that creates some links and adjust the look-and-feel and the promt of the shell. By the way I have published my profile.ps1 as a gist:
A presentation about PowerShell and SharePoint
Yesterday I had a little presentation about PowerShell basics in the SharePoint context. Here you can see the presentation I’ve published on slideshare. The text is in Swedish.
[slideshare id=37316916&doc=sharepoint-140724063012-phpapp01&w=600]
A PowerShell one liner
PowerShell is powerful. You can write concise, well formulated, functional-style code. Recently I got the following quiz:
You’ve got $100. You have to buy exactly 100 animal, at least 1 dog, 1 cat and 1 mouse. 1 dog costs $15, 1 cat costs $1, 1 mouse costs $0.25.
There can be many ways to solve it. But look at this one line solution. It is quite impressive what you can do with PowerShell [code language=“powershell”] 1..98 | % { $dog = $_ 1..98 | % { $cat = $_ @{ “Dog” = $dog “Cat” = $cat “Mouse” = 100 - $dog -$cat } } } | ? { $_.Mouse -gt 0 } | ? { $_.Dog * 15 + $_.Cat * 1 + $_.Mouse * 0.25 -eq 100 } [/code] This solution uses ranges, dynamic objects (PSObject), nested for loops, implicit returns and advanced filtering. All that is is out-of-the-box PowerShell.
Debugging "What's happening" in Communities
Recently an issue was reported about count mismatches in SharePoint 2013 Communities. The number of replies in category tiles sometimes is different compared to the community stats in the web part called “What’s happening”. The actual number of replies is 1 in the figure below. The user who has reported has tried to add, update and delete discussions and replies. I have invested some time debugging this issue. It would be pity to not share my findings. Well the first thing to do was to determine the type name for the “What’s happening” web part. To do so just edit the page and export the web part. In the exported .webpart file I saw that the type was Microsoft.SharePoint.Portal.WebControls.DashboardWebPart. With that knowledge it is time to open ILSpy, an awesome and free(!) assembly browser and decompiler. Load the “Microsoft.SharePoint.Portal” assembly from GAC into ILSpy. Then use F3 to search for DashboardWebPart: The number of replies is retrieved from SPWeb.AllProperties: If the Property Bag does not contain it, it gets the number of replies from the list. The formula is as follows: [code language=“csharp”] list.ItemCount - list.RootFolder.ItemCount [/code] It means that it gets the number of both discussions and replies: ItemCount of Discusssions List. The number of Discussions is determined by the ItemCount in the RootFolder of the Discussions List. Discussions are List Items in the RootFolder (num2 in the figure below). Replies are saved in the subfolders, every discussion gets an own folder. The number of all replies are num3 in the figure below. After checking the web properties I could see that the number of replies there were wrong: 2. The next step was to determine where and when the Web Properties are updated. The first guess every SharePoint Developer has in such cases is an EventReceiver. Here are all EventReceivers connected to the Discussions List: [code language=“powershell”] $list.EventReceivers | select class, Type, Synchronization | Out-GridView [/code] Allright, CommunityEventReceiver then: Found where the actual update happens: CommunityUtils.UpdateWebIndexedPropertyBag The method is used in DiscussionListCommunityEventHandler.HandleEvent There is a flag, flag5 that is used to determine if the Web Properties should be updated: But the flag5 is not true on Delete operations in some code flows: That’s it. So deleting a reply will not have any effect on “What’s happening”. But adding a new discussion will also update the stats: To summarize the debug session, there is an issue in the OOB code that misses to update community stats when deleting a discussion or a reply. Adding a new discussion, or a reply will synchronize the stats.
PowerShell: Migrate field choices to a termset
In my current project we are migrating a custom sharepoint solution from SharePoint 2010 to SharePoint 2013. One of the improvements is that we migrate custom field choices to Managed Metadata. Choice Fields were not intended to be so many. So now it is time to convert them to metadata terms. I have written a PowerShell script which copies all the choices from a field to a termset. The script uses Client Side Object Model (CSOM) to get the choice values and it uses Server Object Model to write data to the termset. [sourcecode language=“PowerShell”] <# .Synopsis Use MigrateChoices.ps1 to migrate choices from a field to managed metadata. The source can be a contenttype field from SharePoint 2010 or from SharePoint 2013. .Description This script uses client object model to get the list items from the old environment. Then it uses the Server Object Model to create new terms and termsets (if needed) in the new environment. This script doesn’t override anything. The reason why we use it, is that importing feature isnt easy It creates a new, instead of adding new terms to old ones. It is very hard to create an csv file for that purpose. .Example MigrateChoices.ps1 -Source http://sp2010.contoso.com -Target https://sp2013.contoso.com .Notes Name: MigrateChoices.ps1 Author: Anatoly Mironov Last Edit: 2013-09-04 Keywords: CSOM, Field, FieldChoice, Metadata, Termset .Links http://chuvash.eu .Inputs The script takes Source parameter, it is url for the root web in the Source Site Collection The script takes Target parameter, it is url for the root web in the Target Site Collection .Outputs None #Requires -Version 2.0 #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)][System.String]$Source = $(Read-Host -prompt “Source site Url”), [Parameter(Mandatory=$true)][System.String]$Target = $(Read-Host -prompt “Target site Url”), [Parameter(Mandatory=$false)][System.String]$TermGroupName = “My group”, [Parameter(Mandatory=$false)][System.String]$TermGroupId, [Parameter(Mandatory=$false)][System.String]$TermSetName = “My termset”, [Parameter(Mandatory=$false)][System.String]$TermSetId, [Parameter(Mandatory=$false)][System.String]$FieldName = $(Read-Host -prompt “Field Choice Name”) ) if(-not(gsnp | ? { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { asnp Microsoft.SharePoint.PowerShell } # try to instantiate the target site, if it fails, then it does not run in the right environment $targetSite = get-spsite $Target # predefined termset guids: $guids = @{ “group” = if ($TermGroupId) {New-Object system.guid $TermGroupId } else { [system.guid]::NewGuid() } “termset” = if ($TermSetId) {New-Object system.guid $TermSetId } else { [system.guid]::NewGuid() } } function GetChoices() { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Source) $field = $ctx.Web.Fields.GetByInternalNameOrTitle($FieldName) $ctx.Load($field) $ctx.ExecuteQuery() return ([xml]$field.SchemaXml).Field.Choices.Choice } function New-Term { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermSetItem]$parent, [Parameter(Mandatory=$true)][System.String]$name ) if (!$parent) { throw new-object System.ArgumentException $parent } if (!$name) { throw new-object System.ArgumentException $name } $term = $parent[$name] if (!$term) { $parent.CreateTerm($name, 1033) | out-null } } function CreateTerms() { $taxSession = Get-SPTaxonomySession -Site $targetSite $termStore = $taxSession.DefaultSiteCollectionTermStore $group = $termstore.Groups[$TermGroupName] if (!$group) { $group = $termStore.CreateGroup($TermGroupName, $guids.group) } $termSet = $group.TermSets[$TermsetName] if (!$termset) { $termset = $group.CreateTermSet($SecurityClassificationTermSetName, $guids.termset, 1033) } GetChoices | % { New-Term $termSet $_ } $termStore.CommitAll() $targetSite.Dispose() write-host -ForegroundColor Green “The term sets have been created” } CreateTerms [/sourcecode]
PowerShell: Get version and ProductId from an .app package
In my project I deploy some apps directly through the ObjectModel directly with PowerShell. The apps are built with TFS I have a script that installs or updates apps if there is a new version of the app. Previously I used Import-SPAppPackage to compare the version and productid with an existing app instance, but often I get this error:
The provided App differs from another App with the same version and product ID.
Count lines of code with PowerShell
Today I got a question:
How many lines of code are there in our SharePoint solution?
After a little search, I found that PowerShell is really a nice tool to count lines of code:
I wanted to count lines for different types of code:
- Code Behind written in C#, the files have .cs file extension
- JavaScript code (except jQuery, angular or knockout frameworks)
- PowerShell files (.ps1 and psm1)
- Xml files (all the SharePoint .xml files)
Here is the powershell code that counts lines of code: [code language=“powershell”] # go to the solution folder cd #count lines in .cs files ls -include *.cs -recurse | select-string . | measure | select count #count lines in our .js files ls -include *.js -recurse ` -exclude *min.js, jquery*, _*, jsrender*, CamlBuilder*, knockout* ` | select-string . ` | measure ` | select Count #count lines in our powershell scripts ls -include *.xml -recurse | select-string . | measure | select count #count lines in our powershell scripts ls -include *.ps1, *.psm1 -recurse | select-string . | measure | select count [/code] Just a curious fact, I can’t tell you how many lines of code we have in our solution, but I can reveal the proportions. If I used the flexible box model in css3, it would look like this: There are as many lines of code written in javascript as it is in C#. The main reason that for the big js code base are the SharePoint hosted apps. The PowerShell scripts are as big the javascript code base. Xml files are 4 times bigger than C# code, and it is even bigger than the sum of all lines of code written in C#, JavaScript and PowerShell. It isn’t strange that xml is dominating, almost everything in SharePoint is defined in xml. Fortunately, there are less cases where you have to write raw xml in Visual Studio 2012/2013 and SharePoint 2013. How does it look in your project? What language is dominating in your SharePoint project?
scriptcs and SharePoint. How SharePoint can benefit?
Last Saturday I attended Leetspeak. Among many awesome speeches and presentations I discovered scriptcs. scriptcs lets you write C# code directly in the console, or execute scripts written with just your favourite editor. Please see more about it on the site. What I thought during Justin Rusbatch’s session at Leetspeak:
Can we use scriptcs in SharePoint?
Technically there is no limitations in SharePoint for scriptcs. Any .NET code can be registered, imported and invoked in a console or in a standalone script. Here is the simple code for instantiating a site collection and disposing it: [code language=“csharp”] #r Microsoft.SharePoint; using Microsoft.SharePoint; var site = new SPSite(“http://dev”); site.Url site.Dispose(); [/code] The code above does not do anything, it is just there to demonstrate how you can register the SharePoint assembly (“Microsoft.SharePoint”) and import it into the script: [code language=“csharp”] using Microsoft.SharePoint; [/code] The example shows even that you in scriptcs no longer need the necessary “boilerplate” (compared to a console application): namespace, Program, Main()… You can just directly write your code. The rest is the same as in a C# application. The code samples for scriptcs can be any code written in C# for SharePoint, code from custom console applications, from feature receivers, you name it. So my next question is:
The CDN concept in SharePoint
How many instances of jquery are there in your SharePoint farm? [sourcecode language=“powershell”] Get-SPWebApplication http://dev ` | Select -Expand Sites ` | Select -Expand AllWebs ` | Select -Expand Lists ` | Select -Expand Items ` | ? { $_.Url -match “jquery.*.js” } ` | select Name, Url [/sourcecode] Have you more than two (jquery and jquery-ui), then you have too much. You can save much place and performance by using Content Delivery Network (CDN) links for the resources like javascript, css, fonts and icons. Consider those Content Delivery Networks:
Set IE Proxy Server with PowerShell
Today just a quick one-liner tip for PowerShell. Use this script to set a proxy server in IE Settings. I got the inspiration from Aymeric’s blog: Scripting : Toggle proxy server in IE settings with PowerShell: [sourcecode language=“PowerShell”] sp AutoConfigUrl “http://proxy.contoso.com” ` -Path “HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings” [/sourcecode] By the way sp
is just alias for Set-ItemProperty cmdlet: This corresponds these settings in IE (Tools - Internet Options - Connections - Lan Settings): It can be useful if you have want to automate this.
A quick guide to configuring the Loopback check
Great tutorial how to configure the loopback check on a dev machine. Exactly what I needed for a month ago. Pity that this article came after that. :-) Here is the command to disable it completeley:
\# Disable Loopback check http://support.microsoft.com/kb/896861 #
New-ItemProperty HKLM:\\System\\CurrentControlSet\\Control\\Lsa -Name "DisableLoopbackCheck" -Value "1" -PropertyType dword
AutoSPInstaller: error while stopping the default web site in IIS
During an installation with AutoSPInstaller on my development machine I ran into a strange issue. I got the following error:
System.IO.FileNotFoundException: Could not load file or assembly ‘Microsoft.IIS.PowerShell.Framework’ or one of its dependencies
I haven’t found any other people having the same problem with the AutoSPInstaller, but I found a similar report on another forum: help.octopusdeploy.com. Maybe I am the only one who gets this error in AutoSPInstaller, if not it can be useful to write the solution down. The error occurs when the default web site in IIS is stopped. For some reason Get-WebSite cmdlet throws an exception the first time you invoke it, but not the second time. To get it working I followed the tip from the help.octopusdeploy.com and wrapped the Get-Website code in a try-and-catch, where the same cmdlet was in try and in catch. This line: [sourcecode language=“powershell”] $defaultWebsite = Get-Website | Where-Object {$_.Name -eq “Default Web Site” -or $_.ID -eq 1 -or $_.physicalPath -eq “%SystemDrive%\inetpub\wwwroot”} # Try different ways of identifying the Default Web Site, in case it has a different name (e.g. localized installs)[/sourcecode] becomes this code (the lines in try and catch are identical): [sourcecode language=“powershell”] Try{ $defaultWebsite = Get-Website | Where-Object {$_.Name -eq “Default Web Site” -or $_.ID -eq 1 -or $_.physicalPath -eq “%SystemDrive%\inetpub\wwwroot”} # Try different ways of identifying the Default Web Site, in case it has a different name (e.g. localized installs) } Catch [System.IO.FileNotFoundException]{ $defaultWebsite = Get-Website | Where-Object {$_.Name -eq “Default Web Site” -or $_.ID -eq 1 -or $_.physicalPath -eq “%SystemDrive%\inetpub\wwwroot”} Break }[/sourcecode] With this fix I was able to run the whole AutoSPInstaller script. My development machine was a fresh installed Windows Server 2008 R2 SP1 (without any updates). Leave a comment if you run into the same issue. If so, I’ll try to send a patch to the AutoSPInstaller code.
PowerShell: Copy an entire document library from SharePoint 2007 to disk
For a while ago I needed to copy all files from a document library within a SharePoint 2007 site to the hard drive. So I didn’t need to copy files from SharePoint to SharePoint so I couldn’t use the stsadm -o export command or Chris O’Brien’s nice SharePoint Content Deployment Wizard. I came across the SPIEFolder application which should work with SharePoint 2007 and 2010. It has a site on codeplex: spiefolder.codeplex.com, but neither the binary nor the source code can be downloaded from there. After some searching I found the binary in the author’s skydrive. The fact that the source code was not available seemed as an disanvantage because I could not know what code was run. Nevertheless I tried it out and it didn’t work:
Run web.config-dependant code in PowerShell
PowerShell is a great tool. It helps in SharePoint administration and tasks automation. Today I needed to provision a webpart on many similar pages. This third-party webpart’s constructor instantiates a dataaccess service and uses a connectionstring which is stored in the web.config file. So the webpart creation failed until I found a way to load the configuration into powershell. First you can create a simple file powershell.exe.config
, put it into $pshome
(C:\Windows\System32\WindowsPowerShell\v1.0). In that file you can specify the connectionstring in the same way like in the web.config (or app.config). But it is not secure: the connectionstring can be changed in the future, and you really don’t want to copy your connectionstrings around. So there is a better way: Check out Ohad Israeli’s blog post about how a configuration file can be bound dynamically in a .net assembly: Binding to a custom App.Config file. In PowerShell you can do the same, all we need is to modify the syntax: StackOverflow: Powershell Calling .NET Assembly that uses App.config:
Create SPGroup in PowerShell
Thanks to Ryan for sharing powershell functions. I used New-SPGroup which I altered. Now You can define which permissions will be given to the new group. You can even create groups without default users. Here it comes:
function New-SPGroup {
<#
.Synopsis
Use New-SPGroup to create a SharePoint Group.
.Description
This function uses the Add() method of a SharePoint RoleAssignments property in an SPWeb to create a SharePoint Group.
.Example
New-SPGroup -Web http://intranet -GroupName "Test Group" -OwnerName DOMAIN\\User -MemberName DOMAIN\\User2 -Description "My Group" -Role "Read"
This example creates a group called "Test Group" in the http://intranet site, with a description of "My Group". The owner is DOMAIN\\User and the first member of the group is DOMAIN\\User2 and adds "Limited Access".
C:\\PS>New-SPGroup -Web http://intranet -GroupName "Test Group" -OwnerName DOMAIN\\User -MemberName DOMAIN\\User2 -Description "My Group" -Role "Read"
This example creates a group called "Test Group" in the http://intranet site, with a description of "My Group". The owner is DOMAIN\\User and the first member of the group is DOMAIN\\User2 and adds "Read" access.
Pay attention to the role definition names. They must be provided in the language of your site.
.Notes
Name: New-SPGroup
Author: Ryan Dennis, Anatoly Mironov
Last Edit: 2012-11-05
Keywords: New-SPGroup, spgroup, permissions
.Link
http://www.sharepointryan.com
http://twitter.com/SharePointRyan
https://sharepointkunskap.wordpress.com
.Inputs
None
.Outputs
None
#Requires -Version 2.0
#>
\[CmdletBinding()\]
Param(
\[Microsoft.SharePoint.PowerShell.SPWebPipeBind\]$Web,
\[string\]$GroupName,
\[string\]$OwnerName,
\[string\]$MemberName,
\[string\]$Role,
\[string\]$Description
)
$SPWeb = $Web.Read()
if ($SPWeb.SiteGroups\[$GroupName\] -ne $null){
throw "Group $GroupName already exists!"
}
if ($Role) {
$roleDefinition = $SPWeb.RoleDefinitions\[$Role\]
if (!$roleDefinition) {
throw "Role Definition $Role doesn't exist!"
}
}
if ($SPWeb.Site.WebApplication.UseClaimsAuthentication){
$op = New-SPClaimsPrincipal $OwnerName -IdentityType WindowsSamAccountName
$owner = $SPWeb | Get-SPUser $op
if ($MemberName) {
$mp = New-SPClaimsPrincipal $MemberName -IdentityType WindowsSamAccountName
$member = $SPWeb | Get-SPUser $mp
}
}
else {
$owner = $SPWeb | Get-SPUser $OwnerName
if ($MemberName) {
$member = $SPWeb | Get-SPUser $MemberName
}
}
$SPWeb.SiteGroups.Add($GroupName, $owner, $member, $Description)
$SPGroup = $SPWeb.SiteGroups\[$GroupName\]
$roleAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($SPGroup)
if ($Role) {
$roleAssignment.RoleDefinitionBindings.Add($roleDefinition)
}
$SPWeb.RoleAssignments.Add($roleAssignment)
$SPWeb.Dispose()
return $SPGroup
}
Creating custom powershell cmdlet
Why
I need to to activate a feature in PowerShell and specify some properties. Simple? Yes. Possible? No. In the default Enable-SPFeature cmdlet you can’t specify any properties:
Enable-SPFeature –Identity "b5eef7d1-f46f-44d1-b53e-410f62032846" -URL http://dev
We can of course easily add properties when activating features in onet.xml:
<!-- Publishing Resources -->
<Feature ID="AEBC918D-B20F-4a11-A1DB-9ED84D79C87E">
<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<Property Key="AllowRss" Value="false" />
<Property Key="SimplePublishing" Value="false" />
</Properties>
</Feature>
So I went to SharePoint StackExchange and asked the question. Then I realized: the standard Sharepoin API doesn’t support this neither. The methods of SPFeatureCollection which have SPFeatureProperties as parameter are internal. So the only way is to use Reflection like Hristo Pavlov (2008) and Yaroslav Pentsarsky (2010) suggest. So why not to try to create a cmdlet?
Out-Gridview in PowerShell
Did you know that we can pipe the output from PowerShell into a graphical GridView? I have used PowerShell for one year and only now I discovered this nice feature. You can add filter criteria, you can filter by typing in a textbox:
Other useful output cmdlets
- out-file
- out-clip
- out-null
Run powershell remotely
To run powershell remotely is really easy. First enable it on the machine which will receive the remote commands:
Enable-PSRemoting
Then go to another machine and connect to your host:
$cred = Get-Credential
Enter-PSSession -Computername dev -Credential $cred
If you want to know more about powershell remoting, I recommend “A layman’s guide…”. See even a detailed example on poshcode.
Access User Profile Properties from Powershell
To use only SPUser objects isn’t always sufficient. To get other properties we have to retrieve user profiles. Giles Hamson gives an example how to get and how to update user profile properties with powershell. Here is an example how to get all work phones:
$url = "http://intranet/"
$site = Get-SPSite $url
$context = Get-SPServiceContext $site
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$profiles = $profileManager.GetEnumerator()
while ($profiles.MoveNext()) {
$userProfile = $profiles.Current
$name = $userProfile.DisplayName
$phone = $userProfile\["WorkPhone"\]
$line = '{0};{1}' -f $name, $phone
write $line
}
If you are not sure what properties are called, see the whole list by typing:
Adding organizational units to AD through powershell
Want to create some organizational structure in AD, I suppose it is specifically useful in a development environment, well the best solution is powershell then. Mastering Powershell by and Powershell.nu by Niklas Goude provide examples how to do this.
$domain = \[ADSI\]""
$ou = $domain.Create("organizationalUnit", "OU=Administration")
$ou.SetInfo()
```Be sure you write "organizationalUnit" in lower case. Otherwise you'll get "Exception calling "SetInfo" with "0" argument(s): "The specified directory service attribute or value does not exist" when you invoke **$ou.setinfo()**. If you want to create an OU under another OU, just create $domain and specify the location: \[code language="powershell"\] $domain = \[ADSI\]"OU=Administration, dc=takana, dc=local" $company = $domain.Create("organizationalUnit", "OU=Accounting") $company.SetInfo()</pre> To save some other properties: <pre>$ou.put("Description", "this is a dummy ou") $ou.SetInfo() \[/code\]
#### Update 2013-12-10
In PowerShell V3 you have a built-in cmdlet for doing that once you add the Active Directory role in your server. It simple as that: \[code language="powershell"\] New-ADOrganizationalUnit "Accounting" -Path "dc=takana, dc=local" \[/code\]
Install a custom timer job in Powershell
First we have to create a class for our timer job which inherits SPTimerJobDefinition, build it and deploy it.
public class TakanaTimer : SPJobDefinition
{
public TakanaTimer(){}
public TakanaTimer(string jobName, SPService service,
SPServer server, SPJobLockType targetType)
: base(jobName, service, server, targetType) { }
public TakanaTimer(string jobName, SPWebApplication webapp)
: base(jobName, webapp, null, SPJobLockType.ContentDatabase)
{
Title = jobName;
}
public override void Execute(Guid contentDbId)
{
Log.Info("Running Takana Timer");
}
}
There is a powershell example for this, but it has not been updated since MOSS.
SPWebConfigModification
SPWebConfigModification. Some links to start with: http://panvega.wordpress.com/2009/09/02/using-spwebconfigmodification-within-a-feature-receiver/ http://www.onedotnetway.com/get-name-of-current-executing-assembly-in-c/ http://blogs.devhorizon.com/reza/?p=459 http://ikarstein.wordpress.com/2010/09/02/add-web-config-modification-with-powershell-spwebconfigmodification/ http://msdn.microsoft.com/en-us/library/bb861909.aspx
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
var webapp = parent as SPWebApplication;
if (webapp != null)
{
var mod1 = GetWebControlsConfigMod();
webapp.WebConfigModifications.Add(mod1);
var mod2 = GetConStringConfigMod();
webapp.WebConfigModifications.Add(mod2);
SaveChanges(webapp);
}
else
{
Log.Warning("no modifications to webapp are done");
}
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
var webapp = parent as SPWebApplication;
if (webapp != null)
{
var mod = GetWebControlsConfigMod();
var modsCollection = webapp.WebConfigModifications;
var modToDelete =
(from m in modsCollection
where m.Value.Equals(mod.Value, StringComparison.InvariantCultureIgnoreCase)
select m).FirstOrDefault();
if (modToDelete != null)
{
modsCollection.Remove(modToDelete);
SaveChanges(webapp);
}
}
}
private static void SaveChanges(SPPersistedObject webapp)
{
var service = webapp.Farm.Services.GetValue();
service.ApplyWebConfigModifications();
webapp.Update();
}
private static SPWebConfigModification GetWebControlsConfigMod()
{
var assembly = System.Reflection.Assembly.GetAssembly(typeof(WebControls.OfficeEditor));
var ass = assembly.FullName;
var @namespace = assembly.GetName().Name + ".WebControls";
var value = string.Format("", ass,
@namespace);
const string path = "configuration/SharePoint/SafeControls";
var mod = new SPWebConfigModification
{
Path = path,
Name = "JustaName1",
Sequence = 0,
Owner = @namespace,
Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
Value = value
};
return mod;
}
private static SPWebConfigModification GetConStringConfigMod()
{
const string name = "ContosoConString";
const string conString =
"Data Source=db.contoso.com;Initial Catalog=contoso\_db;Persist Security Info=True;User ID=contoso\_Contributor;Password=contoso";
var mod = new SPWebConfigModification
{
Name = "JustaName2",
Path = "configuration/connectionStrings",
Owner = "contoso\_connectionstrings",
Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
Value = String.Format("", name, conString)
};
return mod;
}
```Powershell:
#ADDING asnp microsoft.sharepoint.powershell $url = “http://contoso” $app = Get-SPWebApplication $url $name = “ContosoConString”; $conString = “Data Source=db.contoso.com;Initial Catalog=contoso_db;Persist Security Info=True;User ID=contoso_Contributor;Password=contoso”; $mod = new-object Microsoft.SharePoint.Administration.SPWebConfigModification $mod.Name = “JustName2” $mod.Path = “configuration/connectionStrings” $mod.Owner = “User Name” $mod.Type = 0 #for the enum value “SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode” $mod.Value = ‘’ -f $name, $conString $app.WebConfigModifications.Add($mod) $service = [Microsoft.SharePoint.Administration.SPWebService]::ContentService $service.ApplyWebConfigModifications() $app.Update() #ADDING snapin asnp microsoft.sharepoint.powershell
\n and \t in powershell
Want to add some tabs and new lines to your output in Powershell. Well, it works like \n and \t. But there is a little different syntax: `t and `n. Just a tip. An alternative way to add new line is to use [Environment]::NewLine:
$nl = \[Environment\]::NewLine
$var = "hej" + $nl
Write $var
Add Sharepoint Snap-in if needed
Just include it in your script or function:
if(-not(Get-PSSnapin |
Where { $_.Name -eq "Microsoft.SharePoint.PowerShell"})) {
Add-PSSnapin Microsoft.SharePoint.PowerShell}
By the way, I found it in PowerShell for Microsoft SharePoint 2010 Administrators by Niklas Goude and Mattias Karlsson. Powershell for Sharepoint Administrators. UPDATE: I found a better way to check a variable for null: Thomas Maurer. Powershell: check variable for null. It is like in javascript, just put it in the if-statement to test if it exists or not:
Add global navigation links in Powershell and Feature Receiver
I think, powershell is the best way to do configurations you have to do once. Adding some links to global (top) navigation is one of them:
asnp microsoft.sharepoint.powershell
$w = get-spweb http://takana
$l = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Smells like team spirit", "/pages/teamspirit.aspx")
$w.Navigation.TopNavigationBar.AddAsLast($l)
Feature receiver
The alternative is to create a web scoped feature and provide properties:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
var web = properties.Feature.Parent as SPWeb;
var prop = properties.Feature.Properties\["MyGlobalLinks"\];
var links = prop.Value.Split(new\[\] { ";#" },
StringSplitOptions.RemoveEmptyEntries);
foreach (var item in links)
{
var newLink = item.Split(new\[\] { ";" },
StringSplitOptions.RemoveEmptyEntries);
var newMenuItem =
new SPNavigationNode(newLink\[0\], newLink\[1\]);
web.Navigation.TopNavigationBar.AddAsLast(newMenuItem);
}
}
```This feature can be prefereably hidden. The properties are passed in onet:
NavBarLink
I found even a third way to add links to global navigation: NavBarLink
Batch remove
To add items to a list in bulk, or remove them in bulk. Well to do that you can use SPLinq, Server Object Model and … web.ProcessBatchData, which is the most effective. I did an experiment today. I created 1000 tasks in my task list three times and removed all items in three different ways and took time. First I put 1000 items with ajax and listdata.svc:
function pad(n) {
if (n >= 10000) return n;
if (n >= 1000) return '0' + n;
if (n >= 100) return '00' + n;
if (n >= 10) return '000' + n;
return '0000' + n;
}
var s;
var counter = 0;
var title = "task "
function foo() {
counter++;
if (counter > 10000) {
window.clearInterval(s);
}
else {
var value = {};
value.title = title + pad(counter);
createNewTask(value);
}
}
s = setInterval(foo, 200);
Then I ran three different scenarios. Here is the resut for VMWare machine Windows Server 2008 R2, 4GB RAM, SharePoint 2010 SP1:
Powershell scripts for AD
A tip for all who want to administer AD with powershell: Idera Powershell scripts. Just sign up and get the free scripts for AD, SQL, Exchange and Sharepoint. I personally prefer to user modules, so I change the file extension from ps1 to psm1 and then I can use import functions as modules. Here is a simple example for creating for domain users:
import-module .\\New-IADUser1.psm1
function Add-User($name) {
New-IADUser -Name $name
-sAMAccountname $name
-ParentContainer 'CN=Users, DC=contoso, DC=com'
-Password 'SvenskaAkademien1786'
-EnableAccount -PasswordNeverExpires
}
Add-User "user01"
Add-User "user02"
Add-User "user03"
Add-User "user04"
update 2012-03-15: nice script from Ryan
Ryan Dennis has created a very handy script for creating random users. In PowerShell v3.0 there is a cmdlet for creating users: New-ADUser. So the function above can be rewritten like that: [code language=“powershell”] Import-Module ActiveDirectory -ErrorAction SilentlyContinue function Add-User($name) { $password = ConvertTo-SecureString ‘SvenskaAkademien1786’ -AsPlainText -Force New-ADUser -Name $name -sAMAccountname $name -Path ‘CN=Users, DC=contoso, DC=com’ -AccountPassword $password -Enabled $true -PasswordNeverExpires $true } Add-User “user01” Add-User “user02” Add-User “user03” Add-User “user04” [/code]
Uninstall custom features in a batch
A funny powershell command I came upon today together with my colleague. Remove all your custom features (which start with something, say contoso):
Get-SPFeature
| Where { $\_.DisplayName.StartsWith("Contoso.") }
| ForEach { Uninstall-SPFeature $\_.Id -confirm:0 -force }
Have fun!
Configure User Profile Service Application
Today I have struggled with User Profile Service Application. I should have followed this awesome tutorial by ShareponitGeorge. And many thanks to my friend David for the great assistance! One important thing to beware about: Forefront Identity Manager Service must be running. Otherwise you don’t see the existing synchronization connections and you can’t add new connections. You can ensure that this service is running by running services.msc (just press Windows button and write services). Or you can do in powershell:
Sharepoint Warmup Script
It is useful to warm up a site after app pool recycling or after a site creation in development environments. I found a very simple script which I made even simpler:
$url = "http://takana"
$wc = new-object net.webclient
$wc.credentials = \[System.Net.CredentialCache\]::DefaultCredentials
$wc.DownloadString($url) | out-null
$wc.Dispose()
For more sophisticated warmups Wahid Salemi provided an interisting script to warm up your Sharepoint. By the way. Let us save it as a powershell function. Take a look at sharepointryan’s functions. Let’s create a proper function of that:
Change CA port number
In order to change port number for the Central Administration site, run this cmdlet:
Set-SPCentralAdministration -Port 1337
You can set any number between 1023 and 32767 except 443.
Get role assignments of a web or a list
In Powershell you can easily get the permissions in a web or in a list:
$web = get-spweb http://contoso.com
$web.Groups | select Name, Roles > .\\Desktop\\webgroups.txt
$list = $web.Lists.TryGetList("Assets");
$list.RoleAssignments | select Member, RoleDefinitionBindings > .\\Desktop\\assets-roleassignements.txt
```To get all users in all groups run:
$web.Groups | Foreach { Write $_.Name; Write “————-”; $_.Users | Select Name; Write “”; Write "" }
pause in Powershell
Om man högerklickar och väljer “Run With Powershell”, är det bra om fönstret inte försvinner… Det hade varit bra med en funktion som pause… Här kommer väl till pass en egen pause.:
function Pause ($Message="Press any key to continue...")
{
Write-Host -NoNewLine $Message
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Write-Host ""
}
powershell.exe -Command
man kan skapa en .bat-fil med olika powershell-anrop:
powershell.exe -Command "& {.\\Script1.ps1}"
Flaggor i powershellfunktioner
Har länge letat efter möjligheten att skriva funktioner med egna flaggor på ett enkelt sätt. “Flaggor” (flags) är namngivna parametrar. Följande kommando har flaggor: -Identity, -WebApplication och -GACDeployment.
Install-SPSolution -Identity contoso.portal.wsp -WebApplication http://contoso -GACDeployment
```Låt oss titta på ett gammalt exempel:
function hello($firstname, $lastname) { Write “Hello $firstname $lastname” }
hello -firstname Gregor -lastname Samsa
hello -lastname Samsa -firstname Gregor
function helloInColor($firstname, $lastname, [switch]$red = $false, [switch]$green = $false) { $greeting = “Hello, $firstname $lastname” if($red) { Write-Host -ForegroundColor Red $greeting } if($green) { Write-Host -ForegroundColor Green $greeting } }
Lägg till en annan administrator på site collection
Man kan göra det i CA (Application Mgmnt - Change Site Cltn Admins). Det kan man också snabbt göra med powershell:
Set-SPSite http://contoso -SecondaryOwnerAlias contoso\\admin2
defaultvärde på parametern i powershellfunktioner
Läser ett intressant inlägg om deployskript i powershell. Har upptäckt att man kan stoppa in ett defaultvärde i funktionens parameter. Så i stället för
function hello($name) {
Write-Host $name
}
Kan man köra:
function hello($name = "Gregor") {
Write-Host $name
}
```Mycket smidigt.
parametrar i powershell-funktioner
Man kan skapa funktioner med parametrar som påminner mycket om i C#. Så i stället för:
function Just-Test {
Write-Host $args\[0\]
}
```Skriv:
function Just-Test($param) { Write-Host $param }
if($site -ne $null -and $url -ne $null) {“Url OR Site can be given”; return}
powershell_ise
Powershell ISE (Integrated Scripting Environment) är ett bra verktyg för att skriva powershell-skript med färgmarkering och möjligheten att testköra det. Synd bara att det inte är aktiverat ifrån början i Server 2008. För att [aktivera](Import-Module ServerManager 2 Add-Windowsfeature PowerShell-ISE ) kör följande kommandon i powershell:
Import-Module ServerManager
Add-Windowsfeature PowerShell-ISE
För att sedan starta powershell kör:
powershell\_ise
Förenkla skapandet av utvecklingsmiljön till SharePoint 2010
Jag är fortfarande i mitt sökande efter den perfekta (för mig) utvecklingsmiljön för SharePoint 2010. Fram tills nu har jag arbetat med en virtuell (VMware) maskin som kollegor till mig har konfigurerat. Men jag vill ha kunskapen att göra det själv. Än så länge har jag bara stött på procedurer som är relativt långdragna, fram tills idag. Se på videon på sidan jag länkat nedan. Jag ska testa det och sen förhoppningsvis komma med resultat här. Mitt mål är att lätt komma igång med en maskin som körs som VHD eller native dualboot. Men jag börjar med en virtuell VMware maskin. Ett dygn senare: Igår lät jag skriptet köra (utan config ändringar) och efter många timmar är allt installerat och klart. Dock trailversioner. Men gör man det en natt efter 2 veckor eller när trailen är slut, då kan man börja på en ny maskin igen. Jag gillar skarpt detta skript! Ännu bättre blir det nog när man konfigurerar det att fixa en VHD. Kommer mer om det när det är testat! Länksamling Film från Channel 9 Ladda ner Scriptet här Skriptskaparnas bloggar http://blogs.msdn.com/b/cjohnson/archive/2010/10/28/announcing-sharepoint-easy-setup-for-developers.aspx http://blogs.msdn.com/b/pstubbs/archive/2010/10/27/sharepoint-2010-easy-setup-script.aspx
Powershell med tysk precision
Master Powershell ebookDe som har missat Powershell, läser nog andra sorts bloggar än denna. Så rak på sak: det finns en lovande ebook om Powershell, skriven av Tobias Weltner. Ska absolut läsa den. Ni som har läst, vad tycker ni om den? Master-PowerShell | With Dr. Tobias Weltner i html
Sharepoint + OpenSource = Sant
Om man söker på Sharepoint i codeplex.com får man 729 projekt som är alltså öppna. Det är inte illa. Bland dem finns till exempel Sharepoint Log Viewer. Till det kommer 713 öppna projekt som är taggade ASP.NET som kan användas väldigt mycket i Sharepoint-utveckling. Bland ASP.NET-taggade finns smidiga Telerik Extensions. Powershell är också absolut en tag som man ska söka på i codeplex. codeplex.com är Microsofts officiella OpenSource-portal. Det måste finnas andra sidor där öppna projekt inom Sharepoint och ASP.NET samlas. Tipsa gärna i kommentarer.
Radera en sajt ifrån Powershell
Att radera en sajt ifrån Powershell är väldigt enkelt. Skriv bara:
Remove-SPWeb [http://sharepoint/test](http://sharepoint/test)
Aktivera PowerShell för Sharepoint
Som standard så är snap-in i Powershell för Sharepoint inte aktiverat. Gå in på Powershell och aktivera det genom att skriva in: Enable PowerShell Sharepoint:
Add-PSSnapin Microsoft.SharePoint.Powershell
```Se mer på [social.technet.microsoft](http://social.technet.microsoft.com/Forums/en/sharepoint2010setup/thread/81392f4c-549c-4c4b-a158-99ab8ef8e114).
Retrieve information from AD
Here is a a link you can start with. To test AD, install AD. Then we canplay with it. Take a look those examples, too.
PrincipalSearcher vs. DirectorySearcher
What is the difference?
OU
Here are two examples (one for PrincipalSearcher and the other for DirectorySearcher) to retrieve users from an OU:
//PrincipalSearcher
internal static void ListPrincipalsFromOu()
{
using(var ctx = new PrincipalContext(ContextType.Domain, "takana.local", "OU=SOME\_OU ,DC=takana, DC=local"))
{
using (var up = new UserPrincipal(ctx))
{
using (var ps = new PrincipalSearcher(up))
{
using (var res = ps.FindAll())
{
foreach (var p in res)
{
Console.WriteLine(p.SamAccountName);
}
}
}
}
}
}
//DirectorySearcher
internal static void ListAdEntriesFromOu()
{
const string property = "sAMAccountName";
var ldapcon = new DirectoryEntry("takana.local") {
Path = "LDAP://OU=SOME\_OU,DC=takana,DC=local"
};
var search = new DirectorySearcher(ldapcon);
search.PropertiesToLoad.Add(property);
using (var results = search.FindAll())
{
foreach (System.DirectoryServices.SearchResult result in results)
{
using (var entry = result.GetDirectoryEntry())
{
if (entry.Properties\[property\].Count > 0)
{
Console.WriteLine(entry.Properties\[property\]\[0\]);
}
}
}
}
}
PowerShell
PowerShell är ett sätt att manipulera data och struktur i SharePoint-portalen. Samma uppgifter låter göras med konsoll-applikationer. Fördelen med PowerShell är att man kan skapa skript som är flexibla och kan köras med olika parametrar. PowerShell påminner starkt om shell-skript i Linux. För mig som egentligen kommer snarare från bash-världen. Där har Microsoft låtit sig inspireras starkt :). Det finns en bok om PowerShell, skriven av svenskar, som låter intressant. Man behöver inte heller uppfinna hjul på nytt: det finns färdiga skripts som man direkt. Bara man skriver rätt parametrar. Här är ett ställe där man kan hitta skripts. Det finns många sidor som förklarar hur man skriver skript.
Tag: View
Show Path Column in SharePoint
PnP.PowerShell is just the tool you need to show the Path column in a SharePoint document library view. Scroll down to see the script, or read on to learn more.
An introduction
Do you still have folders in SharePoint? Well, you are not alone. Remember the old dream of relying on metadata only? Forget it! As a matter of fact, folders are still a popular way of organizing files in SharePoint. When not overused, they provide “metadata” by itself, metadata that works even in synced folders, in archive scenarios, works best with Teams etc.
Tag: Hobby
Vertical Laptop Holder
I just 3D-printed a laptop holder, a vertical one. It is so pretty and it makes my desktop tidier, so, I thought, it deserves an own blog post. This information might be too little for a blog post. So, as a bonus, I’ll tell you how the process of finding and customizing a 3D model looks like.
.
Thingiverse customizer
I found a nice laptop holder on Thingiverse. Then I just clicked on “Open in customizer” like this:
3D-printa en Super Mario-blomkruka
Jag håller på och lär mig lite om 3D-Print på fritiden. Jag berättar om mina första intryck och hur jag skriver ut en blomkruka som ser ut som ett Super Mario-block - allt detta i en bloggpost.
Montering av 3D-skrivaren
Jag behövde montera min 3D-skrivare (Creality Ender 3 v2) och det gick smidigt även om det tog flera timmar. Jag följde denna fantastiska Youtube video: JustVlad: Creality Ender 3 V2 - 3D Printer - Unbox & Setup . Jag fick justera höjden på plattan flera gånger för att hitta ett lagom avstånd. Svårt att förklara, man måste testa det själv.
Tag: Diy
Microbit Mouse Jiggler
Do you want to be always green in Teams? This fun diy project will help you - a mouse jiggler that keeps your screen and Zoom and Teams awake.
The idea came when I had a fun conversation with a friend of mine about presence status tracking and how ineffecient it is. As a matter of fact I found a whole lot of products and diy projects just for faking your presence status. So it sounded like a fun challenge to me. Eventhough I don’t need it. If you think you need it, I’d say talk to your boss instead and make sure you are not measured on time being green in Teams, but your real effort. But it is fun to tinker with electronics anyway :)
Vår robot Stefan
Roboten Stefan
Här är historian om Stefan, en robot jag och barnen har jobbat på under den senaste månaden. I en sann DIY-anda vill jag skriva om vårt projekt på bloggen och förhoppningsvis inspirera andra att utforska det. I och med projektet innebär en hel del pyssel, så är det lämpat i princip för alla åldrar.
Även om allting togs fram parallellt och stegvis (“i iterationer”), kommer projektet presenteras det i förenklad ordning
Tag: Electronics
Microbit Mouse Jiggler
Do you want to be always green in Teams? This fun diy project will help you - a mouse jiggler that keeps your screen and Zoom and Teams awake.
The idea came when I had a fun conversation with a friend of mine about presence status tracking and how ineffecient it is. As a matter of fact I found a whole lot of products and diy projects just for faking your presence status. So it sounded like a fun challenge to me. Eventhough I don’t need it. If you think you need it, I’d say talk to your boss instead and make sure you are not measured on time being green in Teams, but your real effort. But it is fun to tinker with electronics anyway :)
Tag: Jiggle
Microbit Mouse Jiggler
Do you want to be always green in Teams? This fun diy project will help you - a mouse jiggler that keeps your screen and Zoom and Teams awake.
The idea came when I had a fun conversation with a friend of mine about presence status tracking and how ineffecient it is. As a matter of fact I found a whole lot of products and diy projects just for faking your presence status. So it sounded like a fun challenge to me. Eventhough I don’t need it. If you think you need it, I’d say talk to your boss instead and make sure you are not measured on time being green in Teams, but your real effort. But it is fun to tinker with electronics anyway :)
Tag: Microbit
Microbit Mouse Jiggler
Do you want to be always green in Teams? This fun diy project will help you - a mouse jiggler that keeps your screen and Zoom and Teams awake.
The idea came when I had a fun conversation with a friend of mine about presence status tracking and how ineffecient it is. As a matter of fact I found a whole lot of products and diy projects just for faking your presence status. So it sounded like a fun challenge to me. Eventhough I don’t need it. If you think you need it, I’d say talk to your boss instead and make sure you are not measured on time being green in Teams, but your real effort. But it is fun to tinker with electronics anyway :)
Tag: Mouse
Microbit Mouse Jiggler
Do you want to be always green in Teams? This fun diy project will help you - a mouse jiggler that keeps your screen and Zoom and Teams awake.
The idea came when I had a fun conversation with a friend of mine about presence status tracking and how ineffecient it is. As a matter of fact I found a whole lot of products and diy projects just for faking your presence status. So it sounded like a fun challenge to me. Eventhough I don’t need it. If you think you need it, I’d say talk to your boss instead and make sure you are not measured on time being green in Teams, but your real effort. But it is fun to tinker with electronics anyway :)
Tag: Email
Lookup Person Field in Power Automate
Hello Citizen Developers!
I get more and more questions about Power Automate.
One of the recent questions is about how to look up a person field from SharePoint using Power Automate.
I’ll give you a bit of the background in a second. Power Automate is really awesome for citizen developers.
There are a lot of triggers and actions that are easy to understand and use, such as send email, create a list item in Sharepoint etc.
But there are also techier, nerdier actions that are less citizen developer friendly. One of them is Send an HTTP Request to SharePoint
. It might be the answer to many challenges, intimidating at first, but powerful and, hopefully, not so complicated once you’ve tried it.
This post is about this very action and how you can use it to simplify your flow.
Automatically Send Email When News Is Published
News in SharePoint are great, it is easy to edit and post news, add pictures and web parts. But you might have thought how you would spread the word better. If your workmates would check the start page on your site or on the SharePoint Home every day, it would be awesome, it might be the case in future. In the meantime though, you probably have considered sending out email notifications to your workmates whenever there is fresh news.
Tag: Flow
Lookup Person Field in Power Automate
Hello Citizen Developers!
I get more and more questions about Power Automate.
One of the recent questions is about how to look up a person field from SharePoint using Power Automate.
I’ll give you a bit of the background in a second. Power Automate is really awesome for citizen developers.
There are a lot of triggers and actions that are easy to understand and use, such as send email, create a list item in Sharepoint etc.
But there are also techier, nerdier actions that are less citizen developer friendly. One of them is Send an HTTP Request to SharePoint
. It might be the answer to many challenges, intimidating at first, but powerful and, hopefully, not so complicated once you’ve tried it.
This post is about this very action and how you can use it to simplify your flow.
Automatically Send Email When News Is Published
News in SharePoint are great, it is easy to edit and post news, add pictures and web parts. But you might have thought how you would spread the word better. If your workmates would check the start page on your site or on the SharePoint Home every day, it would be awesome, it might be the case in future. In the meantime though, you probably have considered sending out email notifications to your workmates whenever there is fresh news.
Power Automate for a one-time operations
Honestly, Power Automate is great for automating repetetive stuff. But I think there is room for one-time flows as well. I’ll give you an example.
I’ve got an excel file with quite a few rows. And I need to convert it to a SharePoint List. I know there is a couple of options, such as Quick Edit in Classic View, Import an Excel file as a list (it also requires the classic view), there will be Excel import in Modern as well. But I need to also change the column names, maybe adjust something “on-the-go”.
Tag: Lookup
Lookup Person Field in Power Automate
Hello Citizen Developers!
I get more and more questions about Power Automate.
One of the recent questions is about how to look up a person field from SharePoint using Power Automate.
I’ll give you a bit of the background in a second. Power Automate is really awesome for citizen developers.
There are a lot of triggers and actions that are easy to understand and use, such as send email, create a list item in Sharepoint etc.
But there are also techier, nerdier actions that are less citizen developer friendly. One of them is Send an HTTP Request to SharePoint
. It might be the answer to many challenges, intimidating at first, but powerful and, hopefully, not so complicated once you’ve tried it.
This post is about this very action and how you can use it to simplify your flow.
Tag: Powerautomate
Lookup Person Field in Power Automate
Hello Citizen Developers!
I get more and more questions about Power Automate.
One of the recent questions is about how to look up a person field from SharePoint using Power Automate.
I’ll give you a bit of the background in a second. Power Automate is really awesome for citizen developers.
There are a lot of triggers and actions that are easy to understand and use, such as send email, create a list item in Sharepoint etc.
But there are also techier, nerdier actions that are less citizen developer friendly. One of them is Send an HTTP Request to SharePoint
. It might be the answer to many challenges, intimidating at first, but powerful and, hopefully, not so complicated once you’ve tried it.
This post is about this very action and how you can use it to simplify your flow.
Automatically Send Email When News Is Published
News in SharePoint are great, it is easy to edit and post news, add pictures and web parts. But you might have thought how you would spread the word better. If your workmates would check the start page on your site or on the SharePoint Home every day, it would be awesome, it might be the case in future. In the meantime though, you probably have considered sending out email notifications to your workmates whenever there is fresh news.
Automatically detect new sites in SharePoint Online
Original image by William Warby. https://www.flickr.com/photos/wwarby/16414155179/in/photostream/
Sites in SharePoint are created all the time, not only for SharePoint, but also as storage for Yammer, Teams, Planner and other services in Microsoft 365. There are ways to keep track of them, but the ability to automatically detect a new site creation is quite appealing. Automatic detection means a trigger of a Power Automate (Flow) or a Logic App.
There are a few blog posts that exactly describe how you can detect when a new site is created in SharePoint Online:
Tag: News
Automatically Send Email When News Is Published
News in SharePoint are great, it is easy to edit and post news, add pictures and web parts. But you might have thought how you would spread the word better. If your workmates would check the start page on your site or on the SharePoint Home every day, it would be awesome, it might be the case in future. In the meantime though, you probably have considered sending out email notifications to your workmates whenever there is fresh news.
Demote News in SharePoint Online
In case you published a news in SharePoint Online and you now want to “downgrade” it to a regular page, I have a solution for you.
The reasons why you would like to demote a News might vary:
- You publish an important message, perhaps a note about an operational disturbance. It might not relevant anymore, but you still want to keep the page in case someone wants to access the information.
- You accidentally create a page as a news.
- …
Tag: Api
Automate Creation of Git Repos Using Azure DevOps API
Today I got a question: how can we precreate 50 git repositories in an Azure DevOps Project? I started to learn about the API in Azure DevOps and I found it very interesting. With the API you can script and automate administration of projects, repositores, pull requests etc. To keep this blog post simple and digestable I would like to focus on the intitial request - creating git repositories by code.
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Hiding Teamify Prompt
If you want to remove the Microsoft Teams Banner on your SharePoint Site, the only thing you need is to set a web property on a site: TeamifyHidden=TRUE. I’ll give you some guidance below. But before you do that, consider following:
- If there is already a team created for a group connected site, the prompt won’t show up. Why fix something that is not a problem?
- Only group owners will get the prompt, if they are few and they know what it is, it is better to let them to decide whether to create or not to create a team.
- Only licensed users within your organization will be shown that choice. No external users or users without a license.
- And the most important part: if any site owner selects “Don’t show me again” it will stop popping up for all other site owners. If you happen to have a manual step in the group creation process, then you can just click it away.
Using CAML with SharePoint REST API
Do you prefer REST over CSOM as I do? I’ll skip the whys. Andrew Connell put it already in wrtiting so nicely. Well, if you do prefer REST, then you must have discovered some shortcomings of REST, or its incompleteness compared to CSOM. I think of:
- Inability to filter items based on multivalued taxonomy fields
- Inability to filter items based on user fields where user is added through a group, rather than directly, e.g. AssignedTo=[Me] combined with a SharePoint group.
- …
In such situations I was forced to use CSOM. Until yesterday. Yesterday I learned that we can actually use CAML queries in REST requests. This enables using REST in all situations. The REST API is still developed and many features are added. Maybe a particular operation that needs a CAML query today, can be supported in the core REST API and can be easily refactored then. But until then, we can use CAML queries in REST requests. Here are the important things about it:
REST API: Add a plain text file as an attachment to a list item
SharePoint 2013 REST API has been enhanced and extended. The old _vti_bin/listdata.svc is still there, but the new api for working with lists and list items is much more and obviously a part of a bigger api: _api/web/lists Yesterday I saw an interesting question on SharePoint StackExchange:
The instructions in the MSDN resource are not so detailed, the cannot be. The guy who asked the question did as it stood in the examples. But sometimes solutions for SharePoint need some small adjustments :) Here is the simplest code to create an attachment in plain text for a list item 1 in the list called List1 in the root web. That’s it. But it works: [sourcecode language=“javascript”] var content = “Hello, this text is inside the file created with REST API”; var digest = $("#__REQUESTDIGEST").val(); var composedUrl = “/_api/web/lists/GetByTitle(‘List1’)/items(1)/AttachmentFiles/add(FileName=‘readme.txt’)”; $.ajax({ url: composedUrl, type: “POST”, data: content, headers: { “X-RequestDigest”: digest } }) [/sourcecode] This example is of course just for demonstration. It uses only hard-coded values. But it shows how simple it is to create a list item attachment using SharePoint 2013 REST API and “upload” plain text asynchronously to the server.
javascript API i Sharepoint
Det är supersmidigt. Här är ett exempel:
function createAnnouncement(title, body) {
var ctx = new SP.ClientContext.get\_current();
var list = ctx.get\_web().get\_lists().getByTitle('Meddelanden');
var itemCreationInfo = new SP.ListItemCreationInformation();
this.newListItem = list.addItem(itemCreationInfo);
this.newListItem.set\_item("Title", title);
this.newListItem.set\_item("Body", body);
this.newListItem.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onSucceededCallback), Function.createDelegate(this, this.onFailedCallback));
}
function onSucceededCallback(sender, args) {
SP.UI.Status.addStatus("Info", "It worked!",true);
}
function onFailedCallback(sender, args) {
SP.UI.Status.addStatus("Info", "It didn't work!",true);
}
Comments from Wordpress.com
westerdaled - Feb 0, 2013
Tag: Azuredevops
Automate Creation of Git Repos Using Azure DevOps API
Today I got a question: how can we precreate 50 git repositories in an Azure DevOps Project? I started to learn about the API in Azure DevOps and I found it very interesting. With the API you can script and automate administration of projects, repositores, pull requests etc. To keep this blog post simple and digestable I would like to focus on the intitial request - creating git repositories by code.
Git Merge develop to main in an Azure DevOps Release
This post is a techy one. It’s about running git commands in Azure DevOps Releases in order to finalize a deployment job to production.
Let me first describe our scenario:
We use Azure DevOps for code and for deployment. Our branch strategy a simplified Gitflow model, where all the current work is merged to the “develop” branch. The code from the “develop” branch is then built and released to staging environments and production. After a release to Production and regression tests the develop branch needs to be merged into the “main” branch (or “master”). So simply put, the git merge into main is what we mean by finalizing a production release.
Tag: Git
Automate Creation of Git Repos Using Azure DevOps API
Today I got a question: how can we precreate 50 git repositories in an Azure DevOps Project? I started to learn about the API in Azure DevOps and I found it very interesting. With the API you can script and automate administration of projects, repositores, pull requests etc. To keep this blog post simple and digestable I would like to focus on the intitial request - creating git repositories by code.
Git Merge develop to main in an Azure DevOps Release
This post is a techy one. It’s about running git commands in Azure DevOps Releases in order to finalize a deployment job to production.
Let me first describe our scenario:
We use Azure DevOps for code and for deployment. Our branch strategy a simplified Gitflow model, where all the current work is merged to the “develop” branch. The code from the “develop” branch is then built and released to staging environments and production. After a release to Production and regression tests the develop branch needs to be merged into the “main” branch (or “master”). So simply put, the git merge into main is what we mean by finalizing a production release.
Re-discovering Github
Github has changed a lot. While working mostly in Azure DevOps I haven’t followed all the development on Github. Now when I look at that, I am really amazed.
Private Repos for Free accounts
Well, for me it is not as interesting, because with my free account, I don’t see any harm having my labs public. But I know, some people used bitbucket for their smaller private repos.
Github Project
I suppose it is the Azure DevOps Project concept that was copied to Github, a place for planning and having multiple connected repos.
Load git into PowerShell
Just a little productivity tip. If you use git on Windows, you probably already have the Github for Windows application. This application adds the Git Shell:
The Git Shell will open a PowerShell window and execute shell.ps1 from the Github directory:
What it won’t do is to load your personal PowerShell profile. I want to use my PowerShell profile that creates some links and adjust the look-and-feel and the promt of the shell. By the way I have published my profile.ps1 as a gist:
.tfignore - ".gitignore" for TFS
I haven’t used TFS so much. But I like it so far. It works smoothly, both TFS 2012 (on premises) and TFS Preview (online). I really appreciate that Microsoft has been inspired from git - the world’s best VCS :). For example .tfignore which works exactly like the .gitignore file. It is nice that the non-classic Microsoft dot notation convention for naming the hidden files is chosen. So if you have any files to ignore just do it like you did in your git projects. Here is a .tfignore which I use in my SharePoint project for now. I suppose it will be extended soon:
.gitignore for .net
At appharbor there is a simple .gitignore file for .net applications. If you use Resharper, you may find the extended version of .gitignore useful. A most comprehensive .gitignore can be found on gitextensions website. (Thanks to Vasiliy Aksyonov for the comment):
#ignore thumbnails created by windows
Thumbs.db
#Ignore files build by Visual Studio
\*.obj
\*.exe
\*.pdb
\*.user
\*.aps
\*.pch
\*.vspscc
\*\_i.c
\*\_p.c
\*.ncb
\*.suo
\*.tlb
\*.tlh
\*.bak
\*.cache
\*.ilk
\*.log
\[Bb\]in
\[Dd\]ebug\*/
\*.lib
\*.sbr
obj/
\[Rr\]elease\*/
\_ReSharper\*/
\[Tt\]est\[Rr\]esult\*
```If git tracks some files you don't want it to track, [just remove these files from the git repo](http://stackoverflow.com/questions/1273108/how-do-i-git-rm-a-file-without-deleting-it-from-disk "See the answer at Stackoverflow"):
git rm –cached file
Team Explorer
Until now I have only worked with svn and git. So I am very curious about the Team Foundation Server and Team Explorer which all talk much about. The best thing is the integration with the issue tracking. I can see all work item, or just my work items. Another fine feature, at leat if you use codeplex, is the Team Explorer Everywhere.
The Team Explorer Everywhere client works on Windows, Linux, Mac, or Solaris. It provides a command line client and plug-in for Eclipse to access Team Foundation Server. For information on obtaining the client and connecting to the Team Foundation Server please read the Team Explorer Everywhere Client wiki page. You will need the information on the right to connect to the Team Foundation Server in Team Explorer Everywhere.
.gitignore for android
.gitignore is very important. This file tells git which files not to care about. I found a good template for android .gitignore: .metadata tmp/** .DS_Store *.tmp *.bak tmp/**/* *.swp *~.nib Thumbs.db Desktop.ini *~ *.apk bin gen local.properties *.jar **.classpath**
The only thing I have added is the last row: .classpath.
Comments from Wordpress.com
J. Pablo Fernández - Apr 2, 2011
Good beginners' tutorial on android, eclipse and git
Smashing magazine has a pretty good tutorial how to start programming for android using git, github, eclipse and datastorage. I recommend: Get Started Developing For Android With Eclipse, Reloaded
Set up the Lusites development environment
There is a very good wiki page which describes how to set up the environment. If you think something is missing there, just leave a comment here. Much of that was inspired by a useful tutorial from doityourselfandroid.com
Update from git
So if you have an existing copy of the project, just type: git pull origin master
Or in Egit in Eclipse, right-click on repo and run “Fetch from upstream”.
New files in Eclipse
If there are new classes or files in the project (say you have got the latest version from github into existing workspace in Eclipse). In order for Eclipse to see them, right click on the package and press “Refresh”.
migrera svn till git
Ja, hur gör man om man vill migrera till git? Låt oss säga, man vill använda github. Jag ska berätta hur man kan göra det. Jag gör det i Linux, förmodar samma gäller Mac. Det finns en bra manual om hur man migrerar svn till git. Vi ska gå igenom steg för steg. Skapa en fil som heter users.txt på ditt Skrivbord:
jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>
VisualSVN Server = server <server@server.com>
Det sista är nödvändigt. Eftersom om du har skapat en repository från VisualSVN, kommer det krävas en användarmappning för det med. Installera git-svn:
Tag: App
11 Things I learned about chat bots in Teams
Recently we developed and published a chat bot in Power Virtual Agents for Teams (PVAforTeams). I would like to share my takes and lessons learned with you.
#1 Easy to edit, fun to work with
Bots in PVAforTeams are no-code solutions and provide a comprehensive graphical interface. Developers, analysts, business representatives can work together on defining topics, user flows. It has been really fun to shape the bot in a group - with a lot of laughter and interesting discussions about users’ work habits and how users search and find information. This is how the simplest topic looks like: Greeting:
Tips and tricks for Site Collection App Catalogs
Site Collection App Catalogs (SCAC) are much appreciated, thank you, Office 365 Team. Here is a couple of tips and tricks for SCAC.
Tip #1 You don’t need Tenant Admin rights to add a new Site Collection App Catalog
I have seen many blogs, forum threads etc that state that only Global Tenant Administrators can add new Site Collection App Catalogs. The truth is that a SharePoint Admin rights are enough. The trick is to make that SharePoint Admin Account to a site collection administrator of the app catalog site. To be precise the account that adds a new SCAC must have Manage Web Permissions, as stated in error message:
My first Office Add-In
Yesterday I participated in the Hackathon at European SharePoin Conference in Stockholm. The main goal was to learn more about Office Add-Ins. I wanted to create a very very simple app to learn the basics. Here in this post I’ll provide some links and describe the steps needed to start developing your Office Add-Ins. The Add-in I created is an Outlook Add-In, it is called “Joke Inserter” and with it you can insert a random Chuck Norris joke. It is just for fun, but it demonstrated how an add-in can be installed, made available in “New E-mail” and interact with the e-mail you are writing.
What is a SharePoint application
[caption id=“attachment_3759” align=“alignnone” width=“660”] A meaningful collection of Lego bricks is a toy. A meaningful collection of Lists, Fields, Files and other SharePoint artefacts becomes a SharePoint Application. Private picture.[/caption] App, Add-In, List, Web, Site, Sandbox solution, Workflow. There are too many words flying around in SharePoint that confuse users and Non-SharePoint-Developers. I want to introduce a “new” concept that is so simple and that a company can understand and govern: a SharePoint Application. That is so simple. It can be called a tool, a functionality. That can be a SharePoint list, a document library with a workflow, or a document library with custom jslink. All they can be SharePoint Applications. Let’s use lego as a metaphor. Have you seen this? [caption id=“attachment_3760” align=“alignnone” width=“660”] The same toy car in just brics. SharePoint Artefacts like Webs, Lists, Fields, Content Types, JSLink etc are just lego bricks. Private picture.[/caption] These lego bricks together become a cool toy that you can play with (as you can see in the picture above). So it is with SharePoint Applications, too. SharePoint Applications solve actual business needs. A List, or a JSLink by themselves do not solve a business need. It must be a meaningful collection of SharePoint Artefacts that becomes a SharePoint Application. Example Does the lego metaphor make sense to you? To go back to SharePoint, I’ll give you an example of a SharePoint Application. I would say everybody has done such Applications. In a project we created a document library for product icons that were used for all products in a company. Easy? Yes. But the icons had several states (active, inactive…). Versioning and Approval was required. A workflow for new requests and submits was implemented, too, permissions for different roles, metadata navigation in the document library and so on. Sure, SharePoint provided us with great “lego bricks”. But we created a tool, a functionality - a SharePoint Application, that makes sense to our business. What’s new then? Well, we all have done such applications. The new is to understand SharePoint Applications as an own alternative and quality assurance. See more below. Another example is an “App” for SharePoint Online that I converted into a SharePoint Application by adjusting it for SPO and OnPrem. That’s when I came up with the idea of the SharePoint Application. Definition
Http to Https Redirect in Provider Hosted Apps
It is strongly recommended to use https in SharePoint Provider Hosted Apps. In many provider hosted apps I have seen, only https works. I would recommend to configure a simple http to https redirect in IIS and make solutions better. Many Provider Hosted Apps can be done in that way that they are available without SharePoint Context, e.g. for browsing information. In that case that is important to have an easy url and an automatic http -> https redirect. In this post I’ll give a short manual for doing that. I would recommend this step for all provider hosted apps. 1. In the Provider Hosted Apps Server install the URL Rewrite IIS Module using Web Platform Installer: 2. Next step is to add the http binding to your solution (this is needed for the future redirect): Then you can configure the automatic http to https redirect using the GUI or the web.config update. My instructions originally come from JPPInto.com blog. I suggest updating the web.config file directly in the Provider Hosted App: 3. Add this section to the web.config file: [source language=“xml”] <system.webServer> </system.webServer> [/source] It is important to know that his web.config section will cause failure on the server if URL Rewrite module is not installed. Summary These steps are very easy to accomplish and I recommend it for every Provider Hosted App, especially those ones that are accessible without going through SharePoint (Web Content -> Apps). This also reflects the configurations in Azure Apps (WebSites).
Kom igång med SPMeta2
SPMeta2 (eller bara M2) är ett relativt nytt ramverk för provisionering av SharePoint-artefakter. Bakom ramverket ligger ett gediget arbete. I den här posten vill jag skriva upp mina steg för att sätta upp ett litet projekt. För mig är SPMeta2 nytt och huvudprincipen i den här bloggposten att få en fungerande lösning så snabbt som möjligt. Informationen här kan snabbt bli inaktuell, eftersom SPMeta2 förändras och förbättras väldigt snabbt. Vad är SPMeta2 SPMeta är ett ramverk för att provisionera SharePoint-artefakter, allt från fält, innehållstyper, listor, dokumentbibliotek, user custom actions, ladda upp filer med mera. Klassiskt har vi gjort provisionering med hjälp av XML-baserade moduler och features. SPMeta2 erbjuder ett Fluent API som är kodbaserat. Med hjälp av SPMeta2 definierar man en modell (enkla objekt POCOs) som inte har beroendet till SharePoint. Modellen används sedan av Provision-delen som anropar modellen för specifika versioner: SharePoint 2013, SharePoint 2010, Office 365 med mera. Man kan välja CSOM och SSOM. Provision är också flexibel vad som gäller paketering: det kan vara en konsolapplikation, en SharePoint-app, ett wsp-paket, en PowerShell-modul. Se följande länkar:
Onpremifying SharePoint apps
We want to make an app available in SharePoint OnPrem, we want to onpremify it. Rethink SharePoint apps and provisioning SharePoint artifacts. It has been a while since I updated my blog – Chuvash.eu. I had my vacation, I visited the sunny and green Chuvashia. Now I am back and I am looking forward to an awesome SharePoint Autumn. One of the first things I had to deal with in this SharePoint Autumn was Onpremifying of a SharePoint Online App. We have an app that has gained popularity and we want to make it available for SharePoint OnPrem. There is no such word Onpremify (yet?), I know, it is a Swenglish happy word making (onpremifiera), but I like the word “onpremify” a lot. There is still uncertainty around the purpose of SharePoint apps. One app type, though, has been used a lot in our company: an app that provisions SharePoint Artifacts – that creates SharePoint Applications. What I mean by SharePoint Applications can be read in my blog post:
Announcing web based SQL Max Memory calculator
Today I want to announce a tiny web application for calculating max memory in the SQL Server to improve the overall performance in you SharePoint environment: SQL Max Memory Calculator. One of the important actions to improve the performance in SharePoint is fine tuning of the SQL Databases. Regarding the databases one of the crucial settings is the Max Memory Setting. You can read more about database optimizations for SharePoint in a whitepaper written by SharePoint MVP Vlad Catrinescu. The document is available on the SharePoint Community Web Site:
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
What about the SharePoint app domain?
This is an open question about the domains for SharePoint apps. On Technet: Configure an environment for apps for SharePoint (SharePoint 2013) we can read the following:
You must configure a new name in Domain Name Services (DNS) to host the apps. To help improve security, the domain name should not be a subdomain of the domain that hosts the SharePoint sites. For example, if the SharePoint sites are at Contoso.com, consider ContosoApps.com instead of App.Contoso.com as the domain name.
My five takeaways from the SharePoint Conference 2014
The SharePoint Conference 2014 was an astounding event. Over 10 000 like-minded SharePointers that met, learned a lot and shared new ideas, couldn’t be better. It was also the first time I was to the U.S. and Las Vegas. What a country, what a city! This place must burn people’s lives faster than anywhere else in the world :) I want to share my five takeaways from this conference. I’ll keep it short:
PowerShell: Get version and ProductId from an .app package
In my project I deploy some apps directly through the ObjectModel directly with PowerShell. The apps are built with TFS I have a script that installs or updates apps if there is a new version of the app. Previously I used Import-SPAppPackage to compare the version and productid with an existing app instance, but often I get this error:
The provided App differs from another App with the same version and product ID.
Apps can only call the OOB CSOM and REST endpoints
As a SharePoint architect or a SharePoint developer, you must have been thinking about the benefits/limitations of SharePoint apps a lot. I want to point out one of them today, which is very important: using custom webservices deployed to SharePoint inside apps. That is impossible and it is designed to be so due to the security architecture in the sharepoint app framework. I have read much about SharePoint apps (books, whitepapers, blog posts) and stumbled over these two contradictive statements:
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
SharePoint Apps: "Provider Hosted First" Approach
Recently I had an exciting mail conversation with Thomas Deutsch. He came up with an idea how to fasten the development of apps. This smart approach is called “Provider Hosted First”. See Thomas’ original blog post. Here are some highlights: What you actually do is a local website which runs in grunt server
:
localhost:9000
```Then a SharePoint-hosted app is created with an SPAppIframe that refers to that local app site. Genious!!! Some key features of this approach:
* This local app contains a livereload script. Your sharepoint app is updated every time you save your css, js, html file in your IDE
* Grunt minifies, bundles your assets
* Grunt runs your tests automatically when your content is modified
* The SharePoint app can be on Premises, on Office 365, wherever you want it.
#### Video
\[caption id="attachment\_2808" align="alignnone" width="630"\][![See the video how it looks like to develop using this approach](https://sharepointkunskap.files.wordpress.com/2013/07/sp-app-002.png?w=630)](http://www.screenr.com/LA8H) See the video how it looks like to develop using this approach\[/caption\]
## Comments from Wordpress.com
####
[Paul Tavares](http://paultavares.wordpress.com "paultavares1@gmail.com") - <time datetime="2013-07-10 02:59:34">Jul 3, 2013</time>
This is pretty cool and very similar to my current setup for developing javascript applications for SharePoint. I use a script to "deploy" updates from my PC to the folder in a document library. I'll try this out when I get around to playing with SP2013.
<hr />
####
[Björn]( "bjorn.roberg@bool.se") - <time datetime="2013-07-02 11:07:08">Jul 2, 2013</time>
Awesome! I'm gonna try that out!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-07-02 15:31:33">Jul 2, 2013</time>
Great! When you go to Thomas Deutsch blog, you can download the source code for the solution.
<hr />
jQuery mobile and SharePoint
In this post I want to explore how to build a mobile app using jQuery mobile. Recently I discovered two great blog posts about this:
- Building SharePoint web apps using Sencha Touch by Luc Stakenborg
- jQuery mobile and SharePoint by Chris Quick
In my post I’ll use their findings and share some of mine thougts. I’ll focus mostly on how to get started with jQuery mobile and SharePoint. So go ahead and create your jQuery mobile app, just drag’n’drop some controls: Download it and yout get an “app.html” file and “my.css”. For now ignore my.css. app.html is something like that:
Bobusos. Rövarspråk translator
I have published my old app “Rövarspråksöversättare”, an assignment on the android course. Rövarspråket is the Swedish language game. Of course Bobusos (“bus” - en:prank in Rövarspråket) is open source and can be found on Github.
Tag: Chatbot
11 Things I learned about chat bots in Teams
Recently we developed and published a chat bot in Power Virtual Agents for Teams (PVAforTeams). I would like to share my takes and lessons learned with you.
#1 Easy to edit, fun to work with
Bots in PVAforTeams are no-code solutions and provide a comprehensive graphical interface. Developers, analysts, business representatives can work together on defining topics, user flows. It has been really fun to shape the bot in a group - with a lot of laughter and interesting discussions about users’ work habits and how users search and find information. This is how the simplest topic looks like: Greeting:
Tag: Low-Code
11 Things I learned about chat bots in Teams
Recently we developed and published a chat bot in Power Virtual Agents for Teams (PVAforTeams). I would like to share my takes and lessons learned with you.
#1 Easy to edit, fun to work with
Bots in PVAforTeams are no-code solutions and provide a comprehensive graphical interface. Developers, analysts, business representatives can work together on defining topics, user flows. It has been really fun to shape the bot in a group - with a lot of laughter and interesting discussions about users’ work habits and how users search and find information. This is how the simplest topic looks like: Greeting:
Tag: No-Code
11 Things I learned about chat bots in Teams
Recently we developed and published a chat bot in Power Virtual Agents for Teams (PVAforTeams). I would like to share my takes and lessons learned with you.
#1 Easy to edit, fun to work with
Bots in PVAforTeams are no-code solutions and provide a comprehensive graphical interface. Developers, analysts, business representatives can work together on defining topics, user flows. It has been really fun to shape the bot in a group - with a lot of laughter and interesting discussions about users’ work habits and how users search and find information. This is how the simplest topic looks like: Greeting:
Tag: Pvaforteams
11 Things I learned about chat bots in Teams
Recently we developed and published a chat bot in Power Virtual Agents for Teams (PVAforTeams). I would like to share my takes and lessons learned with you.
#1 Easy to edit, fun to work with
Bots in PVAforTeams are no-code solutions and provide a comprehensive graphical interface. Developers, analysts, business representatives can work together on defining topics, user flows. It has been really fun to shape the bot in a group - with a lot of laughter and interesting discussions about users’ work habits and how users search and find information. This is how the simplest topic looks like: Greeting:
Tag: Swedish
11 Things I learned about chat bots in Teams
Recently we developed and published a chat bot in Power Virtual Agents for Teams (PVAforTeams). I would like to share my takes and lessons learned with you.
#1 Easy to edit, fun to work with
Bots in PVAforTeams are no-code solutions and provide a comprehensive graphical interface. Developers, analysts, business representatives can work together on defining topics, user flows. It has been really fun to shape the bot in a group - with a lot of laughter and interesting discussions about users’ work habits and how users search and find information. This is how the simplest topic looks like: Greeting:
Why Swedish matters
I Sverige är engelskan är väldigt stark. Speciellt i IT-branschen är vi vana att ha i princip allt på engelska, från kommentarer i koden till stora upphandlingar, rapporter och dokumentation. Trots det ser jag ett stort behov av att kunna prata om IT på svenska. Det gäller både lokala företag och globala företag. Det finns flera anledningar:
- Företag i Sverige följer svenska lagar som är skrivna på svenska, för att leva upp till kraven ska man kunna formulera sig på svenska.
- Modersmål eller det språk som man använder mest i vardagen (gäller mig bland annat) är den snabbaste vägen för kommunikation som ger en högre grad av nyansering. Att kunna nyansera krav och önskemål tidigt i projekt är guld värt (enligt många av mina korrespondenter). Man behöver spendera mindre tid på att formulera och tolka krav.
- En mer ideologisk anledning (men en viktig sådan) är att vi som bor i Sverige har skyldighet att utveckla och hålla svenskan levande, inte minst inom IT-sektorn.
Svenska är en stor möjlighet för att verkligen ge mervärde till våra kunder, möta dem på hemmaplan, prata ett gemensamt språk. Startpunkten till den här diskussionen har varit en ny webinar som jag planerar hålla den 14 april kl 10. Webinarens titel är SharePoint i molnet.Det finns ganska mycket information om SharePoint Online och Office 365 på engelska. Det är dock ganska sparsamt med information på svenska. https://www.eventbrite.com/e/sharepoint-i-molnet-tickets-15976529229 Det här är det som väntar dig som vill delta i webinaren:
Version 0.2.0: Swedish localization
Well, it is time to localize. The first language has been added: Swedish, of course. To localize is pretty simple in Android. All you have to do is to create a new folder /res/values-xx
where xx is the language code. sv is Swedish. In this folder create an xml file called strings.xml and copy all the content from /res/values/strings.xml
. Replace all the strings from your default language into the language you want to localize to. There is a graphical wizzard in Eclipse+Android for creating the right folder: Right click on your project → Android tools → Create a new Resource file → Choose Language → Follow your intution.
Tag: Teams
11 Things I learned about chat bots in Teams
Recently we developed and published a chat bot in Power Virtual Agents for Teams (PVAforTeams). I would like to share my takes and lessons learned with you.
#1 Easy to edit, fun to work with
Bots in PVAforTeams are no-code solutions and provide a comprehensive graphical interface. Developers, analysts, business representatives can work together on defining topics, user flows. It has been really fun to shape the bot in a group - with a lot of laughter and interesting discussions about users’ work habits and how users search and find information. This is how the simplest topic looks like: Greeting:
Own praise badges in Teams
While reading the Teams News recap from December 2020, I found one thing that caught my attention particularly: Custom Praise Badges in Teams. Let’s try this. But first, those badges are the default ones:
They are good starting point. But to take it a step further, to really engage people and praise, you need some specific badges that mean something for your company.
To add a new badge all you have to do is to go to Teams Admin (obviously it requires you having the Teams Administrator Role):
Teams incoming webhooks for performance monitoring
Incoming webhooks in Teams are great, indeed. Last week I saw this tweet, which inspired me to share one of our webhooks.
There are many scenarios where it can be used, I would also like to share one of our scenarios: notifying our DevOps team about performance issues in SharePoint Online, detected through Exoprise.
This adaptive card (in Swedish) shows an alarm from Exoprise about login problems.
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Setting up a HelloWorld Azure Alert
Azure Alerts are awesome for monitoring of solutions in Azure. If you are about to set up your first Alert Rules in Azure, then it’s a guide for you. Configuring alert rules can be quite intimidating at first, with all the options, metrics, evaluation times, etc.
Here is a very very simple setup that can serve as a teaser and help you get started with the Azure Alerts.
Tag: Linux
My WSL Setup
This is my installation of Windows WSL and SharePoint Development Environment. The procedure and technology is ever-changing, the details might change, but the process is worth documenting, at least for myself, this is a working guide as of writing (2021-12-20).
Installing Windows Terminal
Installing Windows Terminal is not a prerequisite, but it will make your life much easier. Open Windows Store and search for Windows Terminal and click on Install.
Installing WSL 2
Installing WSL has never been easier than now. For that you only need to run a command in terminal as an Administrator and restart your computer:
Setting up Raspberry Pi2 for a Dashboard Monitor
I have set up Raspberry Pi as a Dashboard Monitor a couple of times. Here I want to summarize my steps. In fact, it is nothing special, a raspberry pi that is used as a browser showing a web based dashboard in full screen, but there are some important configuration steps needed to make it as good as possible.
Install Raspbian
Raspbian is the best operating system for Raspberry Pi. Just stick with that.
Trying out Visual Studio Code on Ubuntu
I am very curious about the new .NET Core, ASP.NET 5, EF 7 and Visual Studio Code for Linux, Mac and Windows. I have tried it out on an Ubuntu 15.04 machine. The installation and configuration required a few steps, so it is not an usual “Next-next-next”-installation. But, hey, it is just a beta, a preview so far, and first of all: It worked. I am sharing a couple of screenshots and the commands I ran in the terminal, mixed with comments and links: [source language=“bash”] #install latest node and npm #https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs sudo npm install -g yo sudo npm install -g generator-aspnet # download VS Code and make a link # make a folder mkdir workspace/tryvs cd workspace/tryvs # create “src/global.json” file: # http://docs.asp.net/en/latest/tutorials/your-first-mac-aspnet.html { “sdk”: { “version”: “1.0.0-beta7” } } nano src/global.json # start VS Code # create # install omnisharp: # http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#installing-on-debian-ubuntu-and-derivatives curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh dnvm #install dnx sudo apt-get install -y libunwind8 gettext libssl-dev libcurl3-dev zlib1g libicu-dev dnvm upgrade -r coreclr cd EmptyApplication dnu restore #install libuv #http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#using-docker sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/ sudo ldconfig #build, I got an error here dnu build #start the web server dnx web [/source]
A new Chuvash keyboard layout
The Chuvash keyboard layout has been the Russian keyboard layout with 4 Chuvash letters that are typed by pressing the right Alt button plus the base letter. Some of the arguments have been
- Users don’t need to switch or learn a new keyboard layout. They can keep on typing Russian texts and sometimes Chuvash texts
- It is easy to communicate about how the right Alt button works. The Right-Alt-technique is also used in Esperanto, Polish and other languages.
- The letters are placed according the labels
Recently two major events happened that made the question about the Chuvash keyboard layout important:
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
It is time to standardize the Chuvash Keyboard Layout
[caption id=“attachment_3165” align=“alignnone” width=“630”] Proto-Bulgarian Runes (Chuvash language is the closest language to the Proto-Bulgar language). Wonder if they are supported in Unicode :)[/caption] The Chuvash Computer Keyboard layouts have existed since 2001, but due to the lack for Unicode support we were forced to use the look-alike letters from other latin-based keyboard layouts. On Linux The Chuvash keyboard layout was added in [2007](https://bugs.freedesktop.org/show_bug.cgi?id=11246 “The original “bug” in FreeDesktop bugzilla”) and Linux is still the only operating system that has a native keyboard layout for Chuvash language. On Windows we have used the Keyboard Layout Creator and distributed it as an executable file. Today, when Windows XP is not supported anymore, the majority of users now have full support for the correct Chuvash letters from the Extended Cyrillic table. These four Chuvash letters are “additional” to the Russian alphabet: Ӑ, Ӗ, Ҫ and Ӳ. Now when new “keyboards” appear on Android, in web browser (they use the standardized letters) and hopefully in Windows and iOS, we have to consider put the correct letters into the keyboard layouts. For Linux the /usr/share/X11/xkb/symbols/ru
file has to be updated: [code] // Chuvash language layout // Anatoly Mironov @mirontoli partial alphanumeric_keys xkb_symbols “cv” { include “ru(winkeys)” name[Group1]= “Chuvash”; key.type[group1]=“FOUR_LEVEL”; key { [ Cyrillic_u, Cyrillic_U, 0x010004f3, 0x010004f2 ] }; key { [ Cyrillic_ie, Cyrillic_IE, 0x010004d7, 0x010004d6 ] }; key { [ Cyrillic_a, Cyrillic_A, 0x010004d1, 0x010004d0 ] }; key { [ Cyrillic_es, Cyrillic_ES, 0x010004ab, 0x010004aa ] }; include “level3(ralt_switch)” }; [/code]
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Hello world in node.js
I know, node.js has been present for a while. But I actually had no time to try it. I was surprised that now it is very straight forward to start with node.js. Allright, everything begins with Hello world. Eventhough it is available for allmost all combinations of operating systems and servers, the easiest way to test it was actually Ubuntu. To install just run:
sudo apt-get install nodejs
```Then make a new directory and create the hello.js:
mkdir hello cd hello vi hello.js
Tag: Nodejs
My WSL Setup
This is my installation of Windows WSL and SharePoint Development Environment. The procedure and technology is ever-changing, the details might change, but the process is worth documenting, at least for myself, this is a working guide as of writing (2021-12-20).
Installing Windows Terminal
Installing Windows Terminal is not a prerequisite, but it will make your life much easier. Open Windows Store and search for Windows Terminal and click on Install.
Installing WSL 2
Installing WSL has never been easier than now. For that you only need to run a command in terminal as an Administrator and restart your computer:
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
SharePoint Apps: "Provider Hosted First" Approach
Recently I had an exciting mail conversation with Thomas Deutsch. He came up with an idea how to fasten the development of apps. This smart approach is called “Provider Hosted First”. See Thomas’ original blog post. Here are some highlights: What you actually do is a local website which runs in grunt server
:
localhost:9000
```Then a SharePoint-hosted app is created with an SPAppIframe that refers to that local app site. Genious!!! Some key features of this approach:
* This local app contains a livereload script. Your sharepoint app is updated every time you save your css, js, html file in your IDE
* Grunt minifies, bundles your assets
* Grunt runs your tests automatically when your content is modified
* The SharePoint app can be on Premises, on Office 365, wherever you want it.
#### Video
\[caption id="attachment\_2808" align="alignnone" width="630"\][![See the video how it looks like to develop using this approach](https://sharepointkunskap.files.wordpress.com/2013/07/sp-app-002.png?w=630)](http://www.screenr.com/LA8H) See the video how it looks like to develop using this approach\[/caption\]
## Comments from Wordpress.com
####
[Paul Tavares](http://paultavares.wordpress.com "paultavares1@gmail.com") - <time datetime="2013-07-10 02:59:34">Jul 3, 2013</time>
This is pretty cool and very similar to my current setup for developing javascript applications for SharePoint. I use a script to "deploy" updates from my PC to the folder in a document library. I'll try this out when I get around to playing with SP2013.
<hr />
####
[Björn]( "bjorn.roberg@bool.se") - <time datetime="2013-07-02 11:07:08">Jul 2, 2013</time>
Awesome! I'm gonna try that out!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-07-02 15:31:33">Jul 2, 2013</time>
Great! When you go to Thomas Deutsch blog, you can download the source code for the solution.
<hr />
Tag: Nvm
My WSL Setup
This is my installation of Windows WSL and SharePoint Development Environment. The procedure and technology is ever-changing, the details might change, but the process is worth documenting, at least for myself, this is a working guide as of writing (2021-12-20).
Installing Windows Terminal
Installing Windows Terminal is not a prerequisite, but it will make your life much easier. Open Windows Store and search for Windows Terminal and click on Install.
Installing WSL 2
Installing WSL has never been easier than now. For that you only need to run a command in terminal as an Administrator and restart your computer:
Tag: Spfx
My WSL Setup
This is my installation of Windows WSL and SharePoint Development Environment. The procedure and technology is ever-changing, the details might change, but the process is worth documenting, at least for myself, this is a working guide as of writing (2021-12-20).
Installing Windows Terminal
Installing Windows Terminal is not a prerequisite, but it will make your life much easier. Open Windows Store and search for Windows Terminal and click on Install.
Installing WSL 2
Installing WSL has never been easier than now. For that you only need to run a command in terminal as an Administrator and restart your computer:
Deploying SPFx using Office 365 cli, custom AAD App and Azure Pipelines
In this post I would like to share some findings from setting a deployment of SPFx. In my work:
- I need to deploy SPFx solutions using Azure Pipelines
- I need to use the least privileges/permissions
- I cannot use Legacy Authentication
First of all, big thanks to @waldekm and the whole community of @office365cli and @m365pnp for the quick help, and that outside working hours.
Let’s take a look at the setup piece by piece
Site Collection App Catalog vs. Tenant App Catalog
Site Collection App Catalogs are great for special cases (like developing apps or site unique apps), but using them on scale would be a mess.
I got a question: Why should we use the Tenant App Catalog at all when we could enable a Site Collection App Catalog on every teamsite? So the suggestion here is to install SharePoint Framework Packages on many Site Collection App Catalogs, instead of the Tenant App Catalog. In that way those wouldn’t be visible for all users in the “Add an app” page.
Permissions in SPFx apply to your whole tenant
Once you approve a permission request from an SPFx app, it will grant the same permission to all other apps in the same tenant.
Nothing new, but I want to emphasize that in that blog post only dedicated to that. You can read it here:
A simple sketch over the permissions.
Here is a simple FAQ to explain what it means:
Tag: Wsl
My WSL Setup
This is my installation of Windows WSL and SharePoint Development Environment. The procedure and technology is ever-changing, the details might change, but the process is worth documenting, at least for myself, this is a working guide as of writing (2021-12-20).
Installing Windows Terminal
Installing Windows Terminal is not a prerequisite, but it will make your life much easier. Open Windows Store and search for Windows Terminal and click on Install.
Installing WSL 2
Installing WSL has never been easier than now. For that you only need to run a command in terminal as an Administrator and restart your computer:
Tag: Excel
Export AppendOnly Comments
Remember the old comments in SharePoint Lists? I am sure there are tons of lists that use the Append-Only Comments. They are implemented using versioning. The problem is that it is hard to export the comments, unless you know the tricks. The trick I want to share comes from a colleague of mine. The reason why we need export all the comments is that we need to document and save/archive the decision making process that took place in the comments field.
Power Automate for a one-time operations
Honestly, Power Automate is great for automating repetetive stuff. But I think there is room for one-time flows as well. I’ll give you an example.
I’ve got an excel file with quite a few rows. And I need to convert it to a SharePoint List. I know there is a couple of options, such as Quick Edit in Classic View, Import an Excel file as a list (it also requires the classic view), there will be Excel import in Modern as well. But I need to also change the column names, maybe adjust something “on-the-go”.
JSGrid Basics
JSGrid is the javascript framework in SharePoint used in Quick Edit View (previously Datasheet View). There are a few very good blog posts on this topic (See below in “Sources”). Nevertheless the fact is that jsgrid and working with quick edit from a developer’s perspective is a huge undiscovered area. Articles I have seen are intended for advanced developers. The goal with my post today is to outline the very basics of working with JSGrid. When you know the basics you will be more comfortable to discover and try out more. The example I want to show is a jsgrid code for a “VerySimpleColumn”. The source code can be found on gist.github.com To focus on jsgrid, I assume you have knowledge and some experience of working with jslink, which is related to jsgrid.
Save an excel sheet as a clean table
To save an excel sheet as a html table is very easy. Just select the needed area, then go to Save as and check the selection and choose html as output format. It works fine. It even looks like it did in Excel. But what if you don’t want all this junk, you want only the plain html table (e.g. for pasting into WP). When I saved my permission levels to html, I used this javascript code. First open the html page which Excel has created in Chrome, open the Dev Tools console, load the latest jQuery into the page, and remove all unnecessary attributes and styling, remove the comments, after that you can just copy the outerHTML of the table and paste into a text editor:
Tag: Guide
Export AppendOnly Comments
Remember the old comments in SharePoint Lists? I am sure there are tons of lists that use the Append-Only Comments. They are implemented using versioning. The problem is that it is hard to export the comments, unless you know the tricks. The trick I want to share comes from a colleague of mine. The reason why we need export all the comments is that we need to document and save/archive the decision making process that took place in the comments field.
Print2SPO - en enkel utskrift till SharePoint
Den här bloggposten är ett (en aning större) användar- (eller verksamhetsutvecklar-)tips om hur man kan sätta upp smarta utskrifter till SharePoint Online - utan några extraappar eller lösningar.
Först och främst, stort tack till min kollega Shahram som har presenterat idén för mig. Tänk dig ett följande scenario:
Du har en mall i Word som du fyller i, skriver ut på papper. Låt säga, det är en plockorder. Du vill digitalisera processen genom att skicka pdf:en till ett gemensamt dokumentbibliotek i SharePoint eller Teams.
Kombinera två SharePoint-listor i PowerBI
Det här är en enkel guide på svenska om hur du kan ladda in data från två eller fler listor i SharePoint och lägga ihop dem till en.
Scenariot är följande. Du har två eller fler sajter i SharePoint Online som har var sin lista (med samma kolumner). Du vill ladda in data från båda och se en aggregerad/summerad version. Alternativet är att ha en delad lista, men ibland (av behörighetskäl eller av behovet för smärre anpassningar av enskilda listor), ligger det i separata listor/sajter.
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
Windows 8: shutdown button on your start and desktop
If you think that “Go to corner” -> Settings -> Power -> Shut down are three steps to much if you just want to shutdown your Windows 8 machine, than do as I did: create a shortcut on you desktop and a tile on your start screen. Create a shortcut as usual: Write in the location field:
shutdown /s /t 0
Name it something, why not “shutdown”? Change the default icon: There it is. Now we can pin it to Start: Done. Now, if you want to shutdown, you have to click only once: Enjoy!
Tag: Versioning
Export AppendOnly Comments
Remember the old comments in SharePoint Lists? I am sure there are tons of lists that use the Append-Only Comments. They are implemented using versioning. The problem is that it is hard to export the comments, unless you know the tricks. The trick I want to share comes from a colleague of mine. The reason why we need export all the comments is that we need to document and save/archive the decision making process that took place in the comments field.
Team Explorer
Until now I have only worked with svn and git. So I am very curious about the Team Foundation Server and Team Explorer which all talk much about. The best thing is the integration with the issue tracking. I can see all work item, or just my work items. Another fine feature, at leat if you use codeplex, is the Team Explorer Everywhere.
The Team Explorer Everywhere client works on Windows, Linux, Mac, or Solaris. It provides a command line client and plug-in for Eclipse to access Team Foundation Server. For information on obtaining the client and connecting to the Team Foundation Server please read the Team Explorer Everywhere Client wiki page. You will need the information on the right to connect to the Team Foundation Server in Team Explorer Everywhere.
Tag: Hugo
New Home for My Blog
Hello World
Now I have moved my blog. chuvash.eu is a static site. I’ll share more details and insights later.
Update 2022-02-10
It has passed a few months since the move from Wordpress to a static site. Now it is time to summarize the insights.
Why I moved
Here are the reasons why I switched from Wordpress.com to a static site
- To be honest, the main reason was that I was curious about static sites.
- It appealed to me to have a fast and secure website (because there is no database that slows down or gets hacked).
- I finally got rid of the annoying ads from Wordpress.com. Don’t get me wrong. I appreciate Wordpress.com, as a matter of fact, I sacrified some really neat functions (such as the comments and the community) when moving to a static, but on that later.
- It finally got free from the vendor lock-in. Now I have all my blog posts as markdown files in a git repository. I can build them to any static website or even consume as they are, no fiddling with a database (if it were a own hosted wordpress site). I find it also easier to collaborate on my blog posts since I can grant access to the git repository to people I want to work together with.
- Speaking of git, now I have real version history of my content, no more accidential deletions.
Well, there might be more reasons, but these are the most important ones.
Tag: Netlify
New Home for My Blog
Hello World
Now I have moved my blog. chuvash.eu is a static site. I’ll share more details and insights later.
Update 2022-02-10
It has passed a few months since the move from Wordpress to a static site. Now it is time to summarize the insights.
Why I moved
Here are the reasons why I switched from Wordpress.com to a static site
- To be honest, the main reason was that I was curious about static sites.
- It appealed to me to have a fast and secure website (because there is no database that slows down or gets hacked).
- I finally got rid of the annoying ads from Wordpress.com. Don’t get me wrong. I appreciate Wordpress.com, as a matter of fact, I sacrified some really neat functions (such as the comments and the community) when moving to a static, but on that later.
- It finally got free from the vendor lock-in. Now I have all my blog posts as markdown files in a git repository. I can build them to any static website or even consume as they are, no fiddling with a database (if it were a own hosted wordpress site). I find it also easier to collaborate on my blog posts since I can grant access to the git repository to people I want to work together with.
- Speaking of git, now I have real version history of my content, no more accidential deletions.
Well, there might be more reasons, but these are the most important ones.
Tag: Static
New Home for My Blog
Hello World
Now I have moved my blog. chuvash.eu is a static site. I’ll share more details and insights later.
Update 2022-02-10
It has passed a few months since the move from Wordpress to a static site. Now it is time to summarize the insights.
Why I moved
Here are the reasons why I switched from Wordpress.com to a static site
- To be honest, the main reason was that I was curious about static sites.
- It appealed to me to have a fast and secure website (because there is no database that slows down or gets hacked).
- I finally got rid of the annoying ads from Wordpress.com. Don’t get me wrong. I appreciate Wordpress.com, as a matter of fact, I sacrified some really neat functions (such as the comments and the community) when moving to a static, but on that later.
- It finally got free from the vendor lock-in. Now I have all my blog posts as markdown files in a git repository. I can build them to any static website or even consume as they are, no fiddling with a database (if it were a own hosted wordpress site). I find it also easier to collaborate on my blog posts since I can grant access to the git repository to people I want to work together with.
- Speaking of git, now I have real version history of my content, no more accidential deletions.
Well, there might be more reasons, but these are the most important ones.
Tag: Website
New Home for My Blog
Hello World
Now I have moved my blog. chuvash.eu is a static site. I’ll share more details and insights later.
Update 2022-02-10
It has passed a few months since the move from Wordpress to a static site. Now it is time to summarize the insights.
Why I moved
Here are the reasons why I switched from Wordpress.com to a static site
- To be honest, the main reason was that I was curious about static sites.
- It appealed to me to have a fast and secure website (because there is no database that slows down or gets hacked).
- I finally got rid of the annoying ads from Wordpress.com. Don’t get me wrong. I appreciate Wordpress.com, as a matter of fact, I sacrified some really neat functions (such as the comments and the community) when moving to a static, but on that later.
- It finally got free from the vendor lock-in. Now I have all my blog posts as markdown files in a git repository. I can build them to any static website or even consume as they are, no fiddling with a database (if it were a own hosted wordpress site). I find it also easier to collaborate on my blog posts since I can grant access to the git repository to people I want to work together with.
- Speaking of git, now I have real version history of my content, no more accidential deletions.
Well, there might be more reasons, but these are the most important ones.
Tag: Admin
A powershell script for activating an eligible role assignment in Azure AD
Recently my role assignments in Azure AD were switched from permanent to eligible ones. This is part of PIM - Privileged Identity Management, you can read more about it on MS Docs:
To activate your eligible assignment you can use Azure Portal, Graph API, and PowerShell. The activation in the portal and Graph API is described on MS Docs:
Tag: Administrator
A powershell script for activating an eligible role assignment in Azure AD
Recently my role assignments in Azure AD were switched from permanent to eligible ones. This is part of PIM - Privileged Identity Management, you can read more about it on MS Docs:
To activate your eligible assignment you can use Azure Portal, Graph API, and PowerShell. The activation in the portal and Graph API is described on MS Docs:
Tag: Azuread
A powershell script for activating an eligible role assignment in Azure AD
Recently my role assignments in Azure AD were switched from permanent to eligible ones. This is part of PIM - Privileged Identity Management, you can read more about it on MS Docs:
To activate your eligible assignment you can use Azure Portal, Graph API, and PowerShell. The activation in the portal and Graph API is described on MS Docs:
Tag: Identity
A powershell script for activating an eligible role assignment in Azure AD
Recently my role assignments in Azure AD were switched from permanent to eligible ones. This is part of PIM - Privileged Identity Management, you can read more about it on MS Docs:
To activate your eligible assignment you can use Azure Portal, Graph API, and PowerShell. The activation in the portal and Graph API is described on MS Docs:
Using secrets in Logic Apps in a secure way
This is a guide for how to handle secrets in a logic app in a secure way. It combines three resources:
- Accessing Key Vault from Logic App with Managed Identity
- Get Secrets Key Vault API
- Hide your logic apps secrets from prying eyes
First, enable a Managed Identity for your Logic App:
In the KeyVault, add a new Access Policy for the new Managed Identity (from the previous step). Use the least priviliges. In my case it is just enough with GET for secrets.
Tag: Office 365
A powershell script for activating an eligible role assignment in Azure AD
Recently my role assignments in Azure AD were switched from permanent to eligible ones. This is part of PIM - Privileged Identity Management, you can read more about it on MS Docs:
To activate your eligible assignment you can use Azure Portal, Graph API, and PowerShell. The activation in the portal and Graph API is described on MS Docs:
Sites.Selected and Governance
The new permission in Graph API - Sites.Selected - is a step in the right direction. Since long we have been looking for ways of scoping the accesses to live up to the least privilege principle. It was either nothing or everything. I have tried out the new Sites.Selected permission and here are my findings.
First of all, if you haven’t heard about Sites.Selected, please visit these pages to find out more. I am skipping the introduction, since there are already good resources on that out there.
Monitoring Microsoft 365 using Raspberry Pi and M365 CLI
I would like to show you my recent hobby project with a raspberry pi, a unicorn phat and the powerful cli-microsoft365: A simple monitoring solution of Microsoft 365 Services.
Status of some important services in Microsoft 365
In essence, I put the unicorn phat onto the raspberry pi zero w and wrote this python script:
The python script checks the service status every five minutes and shows it with colors on the unicorn phat.
1TB=1024GB in SPO Storage
You want to calculate your storage capacity in SharePoint Online? Here is how:
- Every 1TB is 1024GB (it might be confusing, see my previous post, but it’s how it is calculated)
- A tenant gets 1024GB by default
- For every user license of a product that includes the service plan called “SHAREPOINTSTANDARD”/SharePoint Online (Plan 1) you get 10 GB extra
- For every user license of a product that includes the service plan called “SHAREPOINTENTERPRISE”/SharePoint Online (Plan 2) you get 10 GB extra
- For every user license of a product that includes the service called “ONEDRIVEBASIC”/SharePoint Online OneDrive Basic you get 0.5 GB extra
Products vs. Service Plans
A product (a.k.a. SKU) consists of service plans. E.g. Office 365 E3 (product) consists of SharePoint Online Enterprise among others. It is a Service Plan that gives you additional storage, not a product. The information on “SharePoint Limits” page is (over-)simplified. Simplified for a good reason of course - to give a rule of thumb for calculating your storage.
Print2SPO - en enkel utskrift till SharePoint
Den här bloggposten är ett (en aning större) användar- (eller verksamhetsutvecklar-)tips om hur man kan sätta upp smarta utskrifter till SharePoint Online - utan några extraappar eller lösningar.
Först och främst, stort tack till min kollega Shahram som har presenterat idén för mig. Tänk dig ett följande scenario:
Du har en mall i Word som du fyller i, skriver ut på papper. Låt säga, det är en plockorder. Du vill digitalisera processen genom att skicka pdf:en till ett gemensamt dokumentbibliotek i SharePoint eller Teams.
1 TB = 1024 GB in SPO?
There is confusion around how the storage is calculated in SharePoint Online. I believe, in SharePoint Online 1 TB is 1024 GB (based on powers of two), although the SI Prefix is for numbers based on powers of 10 (1TB = 1000GB, Wikipedia). In this post I would like to summarize the results of my investigations and I hope Microsoft or the community can confirm or disconfirm this.
First, let me explain why we care about it. The storage in SharePont is limited and we need to keep an eye on it. Especially in our case, where we need to track storage utilization across different parts of the organization/our tenant. The storage in SharePoint is calculated like so:
Demote News in SharePoint Online
In case you published a news in SharePoint Online and you now want to “downgrade” it to a regular page, I have a solution for you.
The reasons why you would like to demote a News might vary:
- You publish an important message, perhaps a note about an operational disturbance. It might not relevant anymore, but you still want to keep the page in case someone wants to access the information.
- You accidentally create a page as a news.
- …
Kombinera två SharePoint-listor i PowerBI
Det här är en enkel guide på svenska om hur du kan ladda in data från två eller fler listor i SharePoint och lägga ihop dem till en.
Scenariot är följande. Du har två eller fler sajter i SharePoint Online som har var sin lista (med samma kolumner). Du vill ladda in data från båda och se en aggregerad/summerad version. Alternativet är att ha en delad lista, men ibland (av behörighetskäl eller av behovet för smärre anpassningar av enskilda listor), ligger det i separata listor/sajter.
Add a security group as hubbers using PowerShell
Today I needed to add a security group to “People who can associate sites with this hub” through PowerShell. Here is quick how-to. I usually say “hubbers” instead of the long “People who….”. By the way, if you want to know what prerequisites there are for being a hubber, read my other blog post
An example of how to add a security group is missing in the MS Docs:
Own praise badges in Teams
While reading the Teams News recap from December 2020, I found one thing that caught my attention particularly: Custom Praise Badges in Teams. Let’s try this. But first, those badges are the default ones:
They are good starting point. But to take it a step further, to really engage people and praise, you need some specific badges that mean something for your company.
To add a new badge all you have to do is to go to Teams Admin (obviously it requires you having the Teams Administrator Role):
Two workarounds for overcoming the listview threshold
These are two workarounds to see documents / list items in a view that exceeds the listview threshold of 5000 items.
Overcoming the listview threshold is as fun as succeeding in the limbo games.
This is changing all the time. When you read this, it might have changed. Today, 2021-01-05, me and my colleague found following two workarounds for listing over 5000 items in a list view in SharePoint Online:
Teams incoming webhooks for performance monitoring
Incoming webhooks in Teams are great, indeed. Last week I saw this tweet, which inspired me to share one of our webhooks.
There are many scenarios where it can be used, I would also like to share one of our scenarios: notifying our DevOps team about performance issues in SharePoint Online, detected through Exoprise.
This adaptive card (in Swedish) shows an alarm from Exoprise about login problems.
Two site logos?
We have had troubles updating site icons in SharePoint Online. It might be related to one of the following:
- It occures only on hub sites
- The sites have a custom theme
The error message:
We experienced a problem updating the icon. Please try again in a few minutes.
But what I found is that there are two places where you change the site icon. If the first does not work, try the second one, that was what worked for us:
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Automatically detect new sites in SharePoint Online
Original image by William Warby. https://www.flickr.com/photos/wwarby/16414155179/in/photostream/
Sites in SharePoint are created all the time, not only for SharePoint, but also as storage for Yammer, Teams, Planner and other services in Microsoft 365. There are ways to keep track of them, but the ability to automatically detect a new site creation is quite appealing. Automatic detection means a trigger of a Power Automate (Flow) or a Logic App.
There are a few blog posts that exactly describe how you can detect when a new site is created in SharePoint Online:
Is an M365 Group a Yammer Community
Nowadays a Yammer Community gets a corresponding Microsoft 365 Group (Office 365 Group, Unified Group). In your work as an SPO Admin, you might need to differentiate “ordinary” Modern Team Sites from those ones that were created for a Yammer Community.
They both have GROUP#0 as Template. On the actual SPO Site object, there is nothing that you can use to differentiate those. Neither you can use the Office 365 Group information. But there is a way: if you connect to Exchange Online and get the group from there, then there is something useful.
Estimated Completion in Write-Progress in PowerShell
Have you also got many sites in your tenant? Write-Progress is the bare minimum in a script that goes through all sites. But there is also another nice way to make easier to see the progress - estimated completion time.
Although the idea comes from another blog post (My life is a message), I thought it could be worth sharing it again, especially in the cloud context.
Here is a bit simplified scenario: Getting information for every site. The status message in Write-Progress contains also the estimated completion time.
Optimizing lookups in PowerShell
Have you had a PowerShell script that contains two bigger arrays and you wanted merge the information. It can become quite slow if you need to search for every item from array A through all items in array B. The solution is called a HashTable! It might be not an advanced tip for some, but I was really glad to see a huge improvement, so I decided to share it as a post.
Page Diagnostics for SharePoint
While trying to set up a new Home Site, I discovered that there is a tool (browser extension) called Page Diagnostics for SharePoint.
After running this, I tried that command again and it was smart enough to detect the problem the tool discovered.
Also Network Trace is available.
Network trace
Page Diagnostics Tool is defnitely a tool to have in the troubleshooting toolbelt for SharePoint.
Setting up a Home Site
Here is the script:
Deploying SPFx using Office 365 cli, custom AAD App and Azure Pipelines
In this post I would like to share some findings from setting a deployment of SPFx. In my work:
- I need to deploy SPFx solutions using Azure Pipelines
- I need to use the least privileges/permissions
- I cannot use Legacy Authentication
First of all, big thanks to @waldekm and the whole community of @office365cli and @m365pnp for the quick help, and that outside working hours.
Let’s take a look at the setup piece by piece
Power Automate for a one-time operations
Honestly, Power Automate is great for automating repetetive stuff. But I think there is room for one-time flows as well. I’ll give you an example.
I’ve got an excel file with quite a few rows. And I need to convert it to a SharePoint List. I know there is a couple of options, such as Quick Edit in Classic View, Import an Excel file as a list (it also requires the classic view), there will be Excel import in Modern as well. But I need to also change the column names, maybe adjust something “on-the-go”.
Modern Team Site without an Office 365 Group
These are my findings around Modern Sites without Office 365 Groups. It is, of course, a subject to change.
Today (2020-02-21) when you create a Modern Team Site without a group, you will get a site with the template STS#3. This oldie has been around for a while, hasn’t it?
I would always recommend creating Office 365 Group Connected sites.
How it is created
Through PowerShell/REST or from SharePoint Home, if your account is not allowed to create Office 365 Groups, it will automatically create a site without a group.
Multilingual MS Forms
Want to translate your MS Forms into other languages? Create a form, not a quiz. It is available in both Forms and Forms Pro licenses.
Today I want to share one of my findings. One of those that seem obvious once you know, but that take time to find out.
Unfortunately, there is no official comparison of what is included in MS Forms vs. MS Forms Pro. So I thought that the ability to have forms in multiple languages was connected to the license.
Using Sway as a simple static site builder
Sometimes all you need is just a simple static web page: instructions, a landing page, a collection of links. I think I have a perfect use case for Sway. Consider a scenario similar to what Laura Kokkarinen writes in her blog post:
An external user invitation needs an inviteRedirectUrl. Usually it is myapps.microsoft.com. In Laura’s case it was a given extranet url.
Site Collection App Catalog vs. Tenant App Catalog
Site Collection App Catalogs are great for special cases (like developing apps or site unique apps), but using them on scale would be a mess.
I got a question: Why should we use the Tenant App Catalog at all when we could enable a Site Collection App Catalog on every teamsite? So the suggestion here is to install SharePoint Framework Packages on many Site Collection App Catalogs, instead of the Tenant App Catalog. In that way those wouldn’t be visible for all users in the “Add an app” page.
The Path Length Limit of 400 chars in SharePoint Online
This post is my summary and my conclusions on the Path Length Limit in SharePoint Online and OneDrive.
How the path length is calculated
Path Length is not the same as the URL length. It is the relative Url.
/sites/site-url/documenlibrary/folder1/folder2/filename.fileextension
Calculations rules
- Only the server relative url part is counted. The “https://[tenant].sharepoin.com” has no impact on that. It starts from the foward slash: “/sites” (or /teams).
- An encoded value such as a blankspace (%20) is treated as one character, not three.
- A unicode character, and an emoji is treated as one character. Good news for Non-English Names.
- Url Parameters, like “?Web=1” are not calculated.
- The site url and the document library url is taken into account
- All slashes are included
- A file extension is also included, and even the dot, e.g. “.docx”
Other related information
- A site url and a group name can only be 64 characters max.
- The path in the “Copy Link” is much shorter than the “real” path
- There is no limit (as of time of writing - 2019-10-30) on the folder name length (other than the bigger limit of 400 characters), I had no issues to add a folder name with 312 characters.
A user can only create 250 groups
A non-admin user can create no more than 250 resources in Azure AD. That is one of the many Azure AD service limits and restrictions. A “resource” can be an app registration, an Office 365 Group etc. But I would like to discuss Groups more in detail.
Imagine the following scenario: Your organization has disabled Office 365 Group Creation. Only IT can create new groups. A service account has been set up for creation of team sites. The application permissions are “binary”, either everything or nothing: Group.ReadWrite.All. This service account will hit the limit very soon.
Tag: Pim
A powershell script for activating an eligible role assignment in Azure AD
Recently my role assignments in Azure AD were switched from permanent to eligible ones. This is part of PIM - Privileged Identity Management, you can read more about it on MS Docs:
To activate your eligible assignment you can use Azure Portal, Graph API, and PowerShell. The activation in the portal and Graph API is described on MS Docs:
Tag: Aad
Sites.Selected and Governance
The new permission in Graph API - Sites.Selected - is a step in the right direction. Since long we have been looking for ways of scoping the accesses to live up to the least privilege principle. It was either nothing or everything. I have tried out the new Sites.Selected permission and here are my findings.
First of all, if you haven’t heard about Sites.Selected, please visit these pages to find out more. I am skipping the introduction, since there are already good resources on that out there.
Deploying SPFx using Office 365 cli, custom AAD App and Azure Pipelines
In this post I would like to share some findings from setting a deployment of SPFx. In my work:
- I need to deploy SPFx solutions using Azure Pipelines
- I need to use the least privileges/permissions
- I cannot use Legacy Authentication
First of all, big thanks to @waldekm and the whole community of @office365cli and @m365pnp for the quick help, and that outside working hours.
Let’s take a look at the setup piece by piece
Tag: Application
Sites.Selected and Governance
The new permission in Graph API - Sites.Selected - is a step in the right direction. Since long we have been looking for ways of scoping the accesses to live up to the least privilege principle. It was either nothing or everything. I have tried out the new Sites.Selected permission and here are my findings.
First of all, if you haven’t heard about Sites.Selected, please visit these pages to find out more. I am skipping the introduction, since there are already good resources on that out there.
What is a SharePoint application
[caption id=“attachment_3759” align=“alignnone” width=“660”] A meaningful collection of Lego bricks is a toy. A meaningful collection of Lists, Fields, Files and other SharePoint artefacts becomes a SharePoint Application. Private picture.[/caption] App, Add-In, List, Web, Site, Sandbox solution, Workflow. There are too many words flying around in SharePoint that confuse users and Non-SharePoint-Developers. I want to introduce a “new” concept that is so simple and that a company can understand and govern: a SharePoint Application. That is so simple. It can be called a tool, a functionality. That can be a SharePoint list, a document library with a workflow, or a document library with custom jslink. All they can be SharePoint Applications. Let’s use lego as a metaphor. Have you seen this? [caption id=“attachment_3760” align=“alignnone” width=“660”] The same toy car in just brics. SharePoint Artefacts like Webs, Lists, Fields, Content Types, JSLink etc are just lego bricks. Private picture.[/caption] These lego bricks together become a cool toy that you can play with (as you can see in the picture above). So it is with SharePoint Applications, too. SharePoint Applications solve actual business needs. A List, or a JSLink by themselves do not solve a business need. It must be a meaningful collection of SharePoint Artefacts that becomes a SharePoint Application. Example Does the lego metaphor make sense to you? To go back to SharePoint, I’ll give you an example of a SharePoint Application. I would say everybody has done such Applications. In a project we created a document library for product icons that were used for all products in a company. Easy? Yes. But the icons had several states (active, inactive…). Versioning and Approval was required. A workflow for new requests and submits was implemented, too, permissions for different roles, metadata navigation in the document library and so on. Sure, SharePoint provided us with great “lego bricks”. But we created a tool, a functionality - a SharePoint Application, that makes sense to our business. What’s new then? Well, we all have done such applications. The new is to understand SharePoint Applications as an own alternative and quality assurance. See more below. Another example is an “App” for SharePoint Online that I converted into a SharePoint Application by adjusting it for SPO and OnPrem. That’s when I came up with the idea of the SharePoint Application. Definition
Tag: Spo
Sites.Selected and Governance
The new permission in Graph API - Sites.Selected - is a step in the right direction. Since long we have been looking for ways of scoping the accesses to live up to the least privilege principle. It was either nothing or everything. I have tried out the new Sites.Selected permission and here are my findings.
First of all, if you haven’t heard about Sites.Selected, please visit these pages to find out more. I am skipping the introduction, since there are already good resources on that out there.
Monitoring Microsoft 365 using Raspberry Pi and M365 CLI
I would like to show you my recent hobby project with a raspberry pi, a unicorn phat and the powerful cli-microsoft365: A simple monitoring solution of Microsoft 365 Services.
Status of some important services in Microsoft 365
In essence, I put the unicorn phat onto the raspberry pi zero w and wrote this python script:
The python script checks the service status every five minutes and shows it with colors on the unicorn phat.
Print2SPO - en enkel utskrift till SharePoint
Den här bloggposten är ett (en aning större) användar- (eller verksamhetsutvecklar-)tips om hur man kan sätta upp smarta utskrifter till SharePoint Online - utan några extraappar eller lösningar.
Först och främst, stort tack till min kollega Shahram som har presenterat idén för mig. Tänk dig ett följande scenario:
Du har en mall i Word som du fyller i, skriver ut på papper. Låt säga, det är en plockorder. Du vill digitalisera processen genom att skicka pdf:en till ett gemensamt dokumentbibliotek i SharePoint eller Teams.
Two site logos?
We have had troubles updating site icons in SharePoint Online. It might be related to one of the following:
- It occures only on hub sites
- The sites have a custom theme
The error message:
We experienced a problem updating the icon. Please try again in a few minutes.
But what I found is that there are two places where you change the site icon. If the first does not work, try the second one, that was what worked for us:
Listing all renamed sites in SharePoint Online
When you rename a site, a new site is REDIRECTSITE#0, you can get all the sites of that type by running
Get-SPOSite -Template REDIRECTSITE#0
Please consider some caveats with renaming a site url
Automatically detect new sites in SharePoint Online
Original image by William Warby. https://www.flickr.com/photos/wwarby/16414155179/in/photostream/
Sites in SharePoint are created all the time, not only for SharePoint, but also as storage for Yammer, Teams, Planner and other services in Microsoft 365. There are ways to keep track of them, but the ability to automatically detect a new site creation is quite appealing. Automatic detection means a trigger of a Power Automate (Flow) or a Logic App.
There are a few blog posts that exactly describe how you can detect when a new site is created in SharePoint Online:
Is an M365 Group a Yammer Community
Nowadays a Yammer Community gets a corresponding Microsoft 365 Group (Office 365 Group, Unified Group). In your work as an SPO Admin, you might need to differentiate “ordinary” Modern Team Sites from those ones that were created for a Yammer Community.
They both have GROUP#0 as Template. On the actual SPO Site object, there is nothing that you can use to differentiate those. Neither you can use the Office 365 Group information. But there is a way: if you connect to Exchange Online and get the group from there, then there is something useful.
Page Diagnostics for SharePoint
While trying to set up a new Home Site, I discovered that there is a tool (browser extension) called Page Diagnostics for SharePoint.
After running this, I tried that command again and it was smart enough to detect the problem the tool discovered.
Also Network Trace is available.
Network trace
Page Diagnostics Tool is defnitely a tool to have in the troubleshooting toolbelt for SharePoint.
Setting up a Home Site
Here is the script:
Deploying SPFx using Office 365 cli, custom AAD App and Azure Pipelines
In this post I would like to share some findings from setting a deployment of SPFx. In my work:
- I need to deploy SPFx solutions using Azure Pipelines
- I need to use the least privileges/permissions
- I cannot use Legacy Authentication
First of all, big thanks to @waldekm and the whole community of @office365cli and @m365pnp for the quick help, and that outside working hours.
Let’s take a look at the setup piece by piece
Kalendern i SharePoint
Dags för ett svenskt inlägg igen. Idag vill jag titta på kalenderfunktionaliteten i SharePoint Online.
Fortfarande gammalt (classic) utseende
Tyvärr är det gammalt utseende som gäller och det finns inga planer från Microsoft att modernisera kalendern:
Jag förstår att det är väldigt mycket kod för att få till kalendervyn och att det inte är så lätt omvandla till ett modernt utseende, men det ställer till eftersom det upplevs som gammalt och inte användarvänligt ute i verksamheten.
Snabba diagram i SharePoint Online
Ett nytt tips på svenska: det finns en webpart i SharePoint Online: snabbdiagram.
När du har lagt till ett snabbdiagram, kan du skriva välja mellan stapel och cirkeldiagram
Du kan bara välja mellan stapel- och cirkeldiagram.
Data går att mata in direkt.
Resultatet får du direkt:
Använd data från en lista
Det går att visualisera data från en SharePoint-lista. Det är inte så mycket mer komplicerat, men det öppnar nya möjligheter. Du behöver bara hålla listan uppdaterad.
Troubleshooting Performance in SharePoint Online
This is my personal list of links and thoughts on troubleshooting performance in SharePoint Online.
Resources
- @MSFT365Status, a twitter flow on the incidents and resolutions
- connectivity service
- Service Status (open for all), Service Health (for admins)
Health info in Response Headers
Every response from SharePoint Online contains some health information:
- Diagnosing performance issues with SharePoint Online (MSDocs)
- Troubleshooting SharePoint Performance Issues with F12 (blog post)
Following Response Headers could reveal the health:
Switch back to Modern UI
Just a little tip. When you switched to a Classic View of Site Contents, you can switch back by removing a cookie called “splnu”.
My list of _layouts pages
There are many resources on the internet that list _layouts/15 urls in SharePoint. Some are outdated, some are too short, some are to long. Here is my list of the urls, that I am going to update when I need. All the urls start with [Your-Tenant].sharepoint.com/sites/[Your-Site]/_layouts/15/ Here we go:
- viewlsts.aspx - Site Contents, Modern View
- viewlsts.aspx?view=14 - Site Contents, Classic View
- appinv.aspx - Grant Permissions to an App
- appregnew.aspx - Register a new SharePoint Application
- appprincipals.aspx - List Registered Add-Ins
- CreateGroup.aspx - Create Site page (Team and Communication)
- TA_AllAppPrincipals.aspx - List all app principals
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Tag: Core
Smarter way of loading SharePoint CSOM dll in PowerShell
Have you also got a legacy powershell script that loads SharePoint dlls and runs CSOM code directly? It’s quite easy to convert to PnP PowerShell. But if you run out of time and just need to execute the script, then I have a quick tip for you.
First of all, a CSOM script can be recognized by Add-Type commands (or Import-Module) plus the SharePoint dll paths.
Loading the dll the old way.
Tag: Csom
Smarter way of loading SharePoint CSOM dll in PowerShell
Have you also got a legacy powershell script that loads SharePoint dlls and runs CSOM code directly? It’s quite easy to convert to PnP PowerShell. But if you run out of time and just need to execute the script, then I have a quick tip for you.
First of all, a CSOM script can be recognized by Add-Type commands (or Import-Module) plus the SharePoint dll paths.
Loading the dll the old way.
Add Search Verticals by code
Adding own search verticals is a common task in the Search Configuration in SharePoint. Here I want to share a code sample for achieving this programmatically. I hope, this model can be added to SPMeta2. First of all, Search Verticals are dedicated Search Results Pages and links to them. How to add them manually is described on technet:
There is no API in CSOM for that. Luckily, Mikael Svenson found how to get the Search Navigation and contributed to PnP by writing an Extension: web.LoadSearchNavigation. Here is my sample code for adding new Search Verticals programmatically: [source language=“csharp”] NavigationNode searchNav = context.Web.Navigation.GetNodeById(1040); NavigationNodeCollection nodeCollection = searchNav.Children; NavigationNodeCreationInformation everything = new NavigationNodeCreationInformation { Title = “Everyting”, Url = “/search/Pages/results.aspx”, }; NavigationNodeCreationInformation myresults = new NavigationNodeCreationInformation { Title = “My Results”, Url = “/search/Pages/myresults.aspx”, }; nodeCollection.Add(everything); nodeCollection.Add(myresults); context.ExecuteQuery(); [/source]
Method "GetList" does not exist
I troubleshooted a piece of CSOM code in SharePoint 2013. I got the following error:
Method “GetList” does not exist
The reason was that the method GetList was not imlemented until March 2015 CU (15.0.4701.1001), and the SharePoint farm I had was SharePoint 2013 SP1 (15.0.4569.1000). So the solution is to install the Cumulative Update or use web.Lists.GetByTitle. GetByTitle has one aweful shortcoming: it doesn’t work in multilingual environments. So I have recommended to install the March 2015 CU.
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
PowerShell: Migrate field choices to a termset
In my current project we are migrating a custom sharepoint solution from SharePoint 2010 to SharePoint 2013. One of the improvements is that we migrate custom field choices to Managed Metadata. Choice Fields were not intended to be so many. So now it is time to convert them to metadata terms. I have written a PowerShell script which copies all the choices from a field to a termset. The script uses Client Side Object Model (CSOM) to get the choice values and it uses Server Object Model to write data to the termset. [sourcecode language=“PowerShell”] <# .Synopsis Use MigrateChoices.ps1 to migrate choices from a field to managed metadata. The source can be a contenttype field from SharePoint 2010 or from SharePoint 2013. .Description This script uses client object model to get the list items from the old environment. Then it uses the Server Object Model to create new terms and termsets (if needed) in the new environment. This script doesn’t override anything. The reason why we use it, is that importing feature isnt easy It creates a new, instead of adding new terms to old ones. It is very hard to create an csv file for that purpose. .Example MigrateChoices.ps1 -Source http://sp2010.contoso.com -Target https://sp2013.contoso.com .Notes Name: MigrateChoices.ps1 Author: Anatoly Mironov Last Edit: 2013-09-04 Keywords: CSOM, Field, FieldChoice, Metadata, Termset .Links http://chuvash.eu .Inputs The script takes Source parameter, it is url for the root web in the Source Site Collection The script takes Target parameter, it is url for the root web in the Target Site Collection .Outputs None #Requires -Version 2.0 #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)][System.String]$Source = $(Read-Host -prompt “Source site Url”), [Parameter(Mandatory=$true)][System.String]$Target = $(Read-Host -prompt “Target site Url”), [Parameter(Mandatory=$false)][System.String]$TermGroupName = “My group”, [Parameter(Mandatory=$false)][System.String]$TermGroupId, [Parameter(Mandatory=$false)][System.String]$TermSetName = “My termset”, [Parameter(Mandatory=$false)][System.String]$TermSetId, [Parameter(Mandatory=$false)][System.String]$FieldName = $(Read-Host -prompt “Field Choice Name”) ) if(-not(gsnp | ? { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { asnp Microsoft.SharePoint.PowerShell } # try to instantiate the target site, if it fails, then it does not run in the right environment $targetSite = get-spsite $Target # predefined termset guids: $guids = @{ “group” = if ($TermGroupId) {New-Object system.guid $TermGroupId } else { [system.guid]::NewGuid() } “termset” = if ($TermSetId) {New-Object system.guid $TermSetId } else { [system.guid]::NewGuid() } } function GetChoices() { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Source) $field = $ctx.Web.Fields.GetByInternalNameOrTitle($FieldName) $ctx.Load($field) $ctx.ExecuteQuery() return ([xml]$field.SchemaXml).Field.Choices.Choice } function New-Term { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermSetItem]$parent, [Parameter(Mandatory=$true)][System.String]$name ) if (!$parent) { throw new-object System.ArgumentException $parent } if (!$name) { throw new-object System.ArgumentException $name } $term = $parent[$name] if (!$term) { $parent.CreateTerm($name, 1033) | out-null } } function CreateTerms() { $taxSession = Get-SPTaxonomySession -Site $targetSite $termStore = $taxSession.DefaultSiteCollectionTermStore $group = $termstore.Groups[$TermGroupName] if (!$group) { $group = $termStore.CreateGroup($TermGroupName, $guids.group) } $termSet = $group.TermSets[$TermsetName] if (!$termset) { $termset = $group.CreateTermSet($SecurityClassificationTermSetName, $guids.termset, 1033) } GetChoices | % { New-Term $termSet $_ } $termStore.CommitAll() $targetSite.Dispose() write-host -ForegroundColor Green “The term sets have been created” } CreateTerms [/sourcecode]
Apps can only call the OOB CSOM and REST endpoints
As a SharePoint architect or a SharePoint developer, you must have been thinking about the benefits/limitations of SharePoint apps a lot. I want to point out one of them today, which is very important: using custom webservices deployed to SharePoint inside apps. That is impossible and it is designed to be so due to the security architecture in the sharepoint app framework. I have read much about SharePoint apps (books, whitepapers, blog posts) and stumbled over these two contradictive statements:
JSOM: Alter a column's DisplayName
Here is another article in my JSOM series. For one month ago I showed how to alter a column’s ShowInDisplayForm property with JSOM. This time I’ll show a code sample for changing a column’s (field’s) display name. If you want to alter the displayname with Server Object Model, grab the code in the sharepoint.stackexchange.com: Change Field’s DisplayName in a List. [sourcecode language=“javascript”]var ctx = SP.ClientContext.get_current(), //SP.ClientContext field = ctx.get_web() //SP.Web .get_lists() //SP.ListCollection .getByTitle(‘MyList’) //SP.List .get_fields() //SP.FieldCollection .getByInternalNameOrTitle(“Body”); //SP.Field ctx.load(field, “Title”); //load only Title ctx.executeQueryAsync(function() { field.set_title(“Beskrivning”); field.update(); ctx.executeQueryAsync(); });[/sourcecode]
Delete all list items with jsom
Today I needed to “clean” a list, meaning to remove all list items. For some time ago I wrote a post about different ways of removing list items in bulk: Server Object Model, SPLinq and RPC. This time I had only the web browser. So I tried the jsom way. By the way, the javascript documentation for jsom on msdn is getting really good. Don’t miss that: How to: Complete basic operations using JavaScript library code in SharePoint 2013. Now here comes theworking code I used to remove all items in my list:
JSOM: Last Modified Date of a List
The data transfer between server and client can heavily affect the performance. One of the measures to reduce the amount data transferred from the server to the client is storing data on the client. In many modern browsers we can use html5 localStorage. Even in older browsers there are ways to store data. I would recommend a nice js lib called amplify.js. The interface is much easier, then:
amplify.store("key", { title: "value" });
```It comes in nicely, if we have much data which we get with JSOM. But we have to care about eventual changes to list items done after we got them the last time. So we have to store the [last modified date](http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.lastitemmodifieddate.aspx). This property is also available in JSOM:
var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(“Tasks”); ctx.load(list, “LastItemModifiedDate”); ctx.executeQueryAsync( function() { var lastmodified = list.get_lastItemModifiedDate(); }, function() {} );
Three ways to get the id of last created SPListItem
An interesting question came on SharePoint StackExchange: How to retrieve the guid of the last uploaded file. It is only possible in CSOM as far as I know. But if we simplify the task, how to get the id of the last item, the we can compare three ways of getting them: SPServices, jQuery + listdata.svc and CSOM.
SPServices
The most easiest way, but not available in async:
$().SPServices.SPGetLastItemId({
listName: "Documents"
});
listdata.svc
Just combine some query strings and try in the browsers address bar:
Tag: Dll
Smarter way of loading SharePoint CSOM dll in PowerShell
Have you also got a legacy powershell script that loads SharePoint dlls and runs CSOM code directly? It’s quite easy to convert to PnP PowerShell. But if you run out of time and just need to execute the script, then I have a quick tip for you.
First of all, a CSOM script can be recognized by Add-Type commands (or Import-Module) plus the SharePoint dll paths.
Loading the dll the old way.
Tag: Mac
Smarter way of loading SharePoint CSOM dll in PowerShell
Have you also got a legacy powershell script that loads SharePoint dlls and runs CSOM code directly? It’s quite easy to convert to PnP PowerShell. But if you run out of time and just need to execute the script, then I have a quick tip for you.
First of all, a CSOM script can be recognized by Add-Type commands (or Import-Module) plus the SharePoint dll paths.
Loading the dll the old way.
Mass remove live photo videos
While importing images from my iPhone using Image Capture on my mac, I discovered that almost all pictures had corresponding videos. They had the same name, only the file extension was different:
- IMG_2829.JPG
- IMG_2829.MOV
For archiving I don’t to have live photo videos, that’s why I needed a script for that. I found a good start in an answer on SuperUser.stackexchange.com:
I altered it a bit to remove the corresponding .MOV-file (rm):
Trust gulp-connect certificate from Visual Studio Online on Mac OS
I have read and followed this awesome post:
Getting SPFx working in Visual Studio Online by SPDavid.
I got my fingers and tried that guide out. This worked good, I spent some time, though, googling (binging) around to get rid of the SSL Warnings for the remote “localhost” on my Mac.
I would like to share this simple instruction on how to trust a self signed certificate from gulp-connect on Mac OS. The implication is that the certificate is on the remote linux machine (on the Visual Studio Environment), that you are connected to through the Visual Studio Code extension.
Chuvash Keyboard Layout for Mac
I’ve got a Mac and one of my first questions was: How can I write in Chuvash on my Mac, obviously :) In this post I am going to tell how I created Chuvash Keyboard Layout. The solution and installation instructions are on Github: Chuvash Keyboard Layout for Mac
What the heck is Chuvash?
For those who don’t know yet: Chuvash are people who live in Chuvash Republic in Russian Federation, and abroad, as me. We are 1.5 million. Chuvash is also a language, an official language of the Republic, a minority language, that is completely different from the second official language Russian. Chuvash uses Cyrillic letters, all 33 Russian letters plus 4 additional letters: A breve (Ӑ), E breve (Ӗ), C cedilla (Ҫ) and U with double acute (Ӳ).
Trying out Visual Studio Code on Ubuntu
I am very curious about the new .NET Core, ASP.NET 5, EF 7 and Visual Studio Code for Linux, Mac and Windows. I have tried it out on an Ubuntu 15.04 machine. The installation and configuration required a few steps, so it is not an usual “Next-next-next”-installation. But, hey, it is just a beta, a preview so far, and first of all: It worked. I am sharing a couple of screenshots and the commands I ran in the terminal, mixed with comments and links: [source language=“bash”] #install latest node and npm #https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs sudo npm install -g yo sudo npm install -g generator-aspnet # download VS Code and make a link # make a folder mkdir workspace/tryvs cd workspace/tryvs # create “src/global.json” file: # http://docs.asp.net/en/latest/tutorials/your-first-mac-aspnet.html { “sdk”: { “version”: “1.0.0-beta7” } } nano src/global.json # start VS Code # create # install omnisharp: # http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#installing-on-debian-ubuntu-and-derivatives curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh dnvm #install dnx sudo apt-get install -y libunwind8 gettext libssl-dev libcurl3-dev zlib1g libicu-dev dnvm upgrade -r coreclr cd EmptyApplication dnu restore #install libuv #http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#using-docker sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/ sudo ldconfig #build, I got an error here dnu build #start the web server dnx web [/source]
Tag: Terminal
Smarter way of loading SharePoint CSOM dll in PowerShell
Have you also got a legacy powershell script that loads SharePoint dlls and runs CSOM code directly? It’s quite easy to convert to PnP PowerShell. But if you run out of time and just need to execute the script, then I have a quick tip for you.
First of all, a CSOM script can be recognized by Add-Type commands (or Import-Module) plus the SharePoint dll paths.
Loading the dll the old way.
Tag: Tip
Smarter way of loading SharePoint CSOM dll in PowerShell
Have you also got a legacy powershell script that loads SharePoint dlls and runs CSOM code directly? It’s quite easy to convert to PnP PowerShell. But if you run out of time and just need to execute the script, then I have a quick tip for you.
First of all, a CSOM script can be recognized by Add-Type commands (or Import-Module) plus the SharePoint dll paths.
Loading the dll the old way.
Tag: Job
A cost effective way of running legacy scripts in the cloud
Have you also got some old huge scripts that run on a server locally? Have you also considered moving them to the cloud? Here comes an idea of how to do it quickly and easy.
In my case I have some older powershell scripts that are harder to convert to serverless applications:
- They use MSOnline module in PowerShell, hence they require rewriting to AzureAD before using them in an Azure Function
- They take around 15 minutes to complete, Azure Functions Consumption Plan is limited to 10 minutes. Of course I can split them in several parts, but I am looking for an easy way right now, I have to postpone refactoring because I am not sure if there is a real need for this script solution.
- They process a lot of data and consume more that 400 MB memory which makes it crash when I put it in a Azure Automation Runbook.
Well, maybe a Windows Server VM in Azure is the only way? While recently setting up a minecraft server and following a blog post that proposes auto shutdown and logic apps to start the server, I came up with an idea to use exactly the same approach to make it as cost effective as possible.
Tag: Legacy
A cost effective way of running legacy scripts in the cloud
Have you also got some old huge scripts that run on a server locally? Have you also considered moving them to the cloud? Here comes an idea of how to do it quickly and easy.
In my case I have some older powershell scripts that are harder to convert to serverless applications:
- They use MSOnline module in PowerShell, hence they require rewriting to AzureAD before using them in an Azure Function
- They take around 15 minutes to complete, Azure Functions Consumption Plan is limited to 10 minutes. Of course I can split them in several parts, but I am looking for an easy way right now, I have to postpone refactoring because I am not sure if there is a real need for this script solution.
- They process a lot of data and consume more that 400 MB memory which makes it crash when I put it in a Azure Automation Runbook.
Well, maybe a Windows Server VM in Azure is the only way? While recently setting up a minecraft server and following a blog post that proposes auto shutdown and logic apps to start the server, I came up with an idea to use exactly the same approach to make it as cost effective as possible.
Tag: Logicapp
A cost effective way of running legacy scripts in the cloud
Have you also got some old huge scripts that run on a server locally? Have you also considered moving them to the cloud? Here comes an idea of how to do it quickly and easy.
In my case I have some older powershell scripts that are harder to convert to serverless applications:
- They use MSOnline module in PowerShell, hence they require rewriting to AzureAD before using them in an Azure Function
- They take around 15 minutes to complete, Azure Functions Consumption Plan is limited to 10 minutes. Of course I can split them in several parts, but I am looking for an easy way right now, I have to postpone refactoring because I am not sure if there is a real need for this script solution.
- They process a lot of data and consume more that 400 MB memory which makes it crash when I put it in a Azure Automation Runbook.
Well, maybe a Windows Server VM in Azure is the only way? While recently setting up a minecraft server and following a blog post that proposes auto shutdown and logic apps to start the server, I came up with an idea to use exactly the same approach to make it as cost effective as possible.
Using secrets in Logic Apps in a secure way
This is a guide for how to handle secrets in a logic app in a secure way. It combines three resources:
- Accessing Key Vault from Logic App with Managed Identity
- Get Secrets Key Vault API
- Hide your logic apps secrets from prying eyes
First, enable a Managed Identity for your Logic App:
In the KeyVault, add a new Access Policy for the new Managed Identity (from the previous step). Use the least priviliges. In my case it is just enough with GET for secrets.
Tag: Msonline
A cost effective way of running legacy scripts in the cloud
Have you also got some old huge scripts that run on a server locally? Have you also considered moving them to the cloud? Here comes an idea of how to do it quickly and easy.
In my case I have some older powershell scripts that are harder to convert to serverless applications:
- They use MSOnline module in PowerShell, hence they require rewriting to AzureAD before using them in an Azure Function
- They take around 15 minutes to complete, Azure Functions Consumption Plan is limited to 10 minutes. Of course I can split them in several parts, but I am looking for an easy way right now, I have to postpone refactoring because I am not sure if there is a real need for this script solution.
- They process a lot of data and consume more that 400 MB memory which makes it crash when I put it in a Azure Automation Runbook.
Well, maybe a Windows Server VM in Azure is the only way? While recently setting up a minecraft server and following a blog post that proposes auto shutdown and logic apps to start the server, I came up with an idea to use exactly the same approach to make it as cost effective as possible.
Tag: Runbook
A cost effective way of running legacy scripts in the cloud
Have you also got some old huge scripts that run on a server locally? Have you also considered moving them to the cloud? Here comes an idea of how to do it quickly and easy.
In my case I have some older powershell scripts that are harder to convert to serverless applications:
- They use MSOnline module in PowerShell, hence they require rewriting to AzureAD before using them in an Azure Function
- They take around 15 minutes to complete, Azure Functions Consumption Plan is limited to 10 minutes. Of course I can split them in several parts, but I am looking for an easy way right now, I have to postpone refactoring because I am not sure if there is a real need for this script solution.
- They process a lot of data and consume more that 400 MB memory which makes it crash when I put it in a Azure Automation Runbook.
Well, maybe a Windows Server VM in Azure is the only way? While recently setting up a minecraft server and following a blog post that proposes auto shutdown and logic apps to start the server, I came up with an idea to use exactly the same approach to make it as cost effective as possible.
Tag: Schedule
A cost effective way of running legacy scripts in the cloud
Have you also got some old huge scripts that run on a server locally? Have you also considered moving them to the cloud? Here comes an idea of how to do it quickly and easy.
In my case I have some older powershell scripts that are harder to convert to serverless applications:
- They use MSOnline module in PowerShell, hence they require rewriting to AzureAD before using them in an Azure Function
- They take around 15 minutes to complete, Azure Functions Consumption Plan is limited to 10 minutes. Of course I can split them in several parts, but I am looking for an easy way right now, I have to postpone refactoring because I am not sure if there is a real need for this script solution.
- They process a lot of data and consume more that 400 MB memory which makes it crash when I put it in a Azure Automation Runbook.
Well, maybe a Windows Server VM in Azure is the only way? While recently setting up a minecraft server and following a blog post that proposes auto shutdown and logic apps to start the server, I came up with an idea to use exactly the same approach to make it as cost effective as possible.
Tag: Cli-Microsoft365
Monitoring Microsoft 365 using Raspberry Pi and M365 CLI
I would like to show you my recent hobby project with a raspberry pi, a unicorn phat and the powerful cli-microsoft365: A simple monitoring solution of Microsoft 365 Services.
Status of some important services in Microsoft 365
In essence, I put the unicorn phat onto the raspberry pi zero w and wrote this python script:
The python script checks the service status every five minutes and shows it with colors on the unicorn phat.
Tag: Office365
Monitoring Microsoft 365 using Raspberry Pi and M365 CLI
I would like to show you my recent hobby project with a raspberry pi, a unicorn phat and the powerful cli-microsoft365: A simple monitoring solution of Microsoft 365 Services.
Status of some important services in Microsoft 365
In essence, I put the unicorn phat onto the raspberry pi zero w and wrote this python script:
The python script checks the service status every five minutes and shows it with colors on the unicorn phat.
Teams incoming webhooks for performance monitoring
Incoming webhooks in Teams are great, indeed. Last week I saw this tweet, which inspired me to share one of our webhooks.
There are many scenarios where it can be used, I would also like to share one of our scenarios: notifying our DevOps team about performance issues in SharePoint Online, detected through Exoprise.
This adaptive card (in Swedish) shows an alarm from Exoprise about login problems.
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Is an M365 Group a Yammer Community
Nowadays a Yammer Community gets a corresponding Microsoft 365 Group (Office 365 Group, Unified Group). In your work as an SPO Admin, you might need to differentiate “ordinary” Modern Team Sites from those ones that were created for a Yammer Community.
They both have GROUP#0 as Template. On the actual SPO Site object, there is nothing that you can use to differentiate those. Neither you can use the Office 365 Group information. But there is a way: if you connect to Exchange Online and get the group from there, then there is something useful.
Deploying SPFx using Office 365 cli, custom AAD App and Azure Pipelines
In this post I would like to share some findings from setting a deployment of SPFx. In my work:
- I need to deploy SPFx solutions using Azure Pipelines
- I need to use the least privileges/permissions
- I cannot use Legacy Authentication
First of all, big thanks to @waldekm and the whole community of @office365cli and @m365pnp for the quick help, and that outside working hours.
Let’s take a look at the setup piece by piece
Modern Team Site without an Office 365 Group
These are my findings around Modern Sites without Office 365 Groups. It is, of course, a subject to change.
Today (2020-02-21) when you create a Modern Team Site without a group, you will get a site with the template STS#3. This oldie has been around for a while, hasn’t it?
I would always recommend creating Office 365 Group Connected sites.
How it is created
Through PowerShell/REST or from SharePoint Home, if your account is not allowed to create Office 365 Groups, it will automatically create a site without a group.
Multilingual MS Forms
Want to translate your MS Forms into other languages? Create a form, not a quiz. It is available in both Forms and Forms Pro licenses.
Today I want to share one of my findings. One of those that seem obvious once you know, but that take time to find out.
Unfortunately, there is no official comparison of what is included in MS Forms vs. MS Forms Pro. So I thought that the ability to have forms in multiple languages was connected to the license.
Using Sway as a simple static site builder
Sometimes all you need is just a simple static web page: instructions, a landing page, a collection of links. I think I have a perfect use case for Sway. Consider a scenario similar to what Laura Kokkarinen writes in her blog post:
An external user invitation needs an inviteRedirectUrl. Usually it is myapps.microsoft.com. In Laura’s case it was a given extranet url.
Permissions in SPFx apply to your whole tenant
Once you approve a permission request from an SPFx app, it will grant the same permission to all other apps in the same tenant.
Nothing new, but I want to emphasize that in that blog post only dedicated to that. You can read it here:
A simple sketch over the permissions.
Here is a simple FAQ to explain what it means:
The Path Length Limit of 400 chars in SharePoint Online
This post is my summary and my conclusions on the Path Length Limit in SharePoint Online and OneDrive.
How the path length is calculated
Path Length is not the same as the URL length. It is the relative Url.
/sites/site-url/documenlibrary/folder1/folder2/filename.fileextension
Calculations rules
- Only the server relative url part is counted. The “https://[tenant].sharepoin.com” has no impact on that. It starts from the foward slash: “/sites” (or /teams).
- An encoded value such as a blankspace (%20) is treated as one character, not three.
- A unicode character, and an emoji is treated as one character. Good news for Non-English Names.
- Url Parameters, like “?Web=1” are not calculated.
- The site url and the document library url is taken into account
- All slashes are included
- A file extension is also included, and even the dot, e.g. “.docx”
Other related information
- A site url and a group name can only be 64 characters max.
- The path in the “Copy Link” is much shorter than the “real” path
- There is no limit (as of time of writing - 2019-10-30) on the folder name length (other than the bigger limit of 400 characters), I had no issues to add a folder name with 312 characters.
Renaming site urls
I saw a demo of it on the European SharePoint Conference in Copenhagen in 2018. Sebastian Fouillade, who showed this, compared this big change with brain surgery. All the urls, all the connections. But now it is possible. Today I have seen it even in my standard release tenant.
It is really appreciated. Soon it will be possible to rename misspelled sites, like “devlepment” to “development” etc.
To rename you need to go the SharePoint Admin, find your site among Active sites and click on “Edit” in the site url area.
A user can only create 250 groups
A non-admin user can create no more than 250 resources in Azure AD. That is one of the many Azure AD service limits and restrictions. A “resource” can be an app registration, an Office 365 Group etc. But I would like to discuss Groups more in detail.
Imagine the following scenario: Your organization has disabled Office 365 Group Creation. Only IT can create new groups. A service account has been set up for creation of team sites. The application permissions are “binary”, either everything or nothing: Group.ReadWrite.All. This service account will hit the limit very soon.
Tips and tricks for Site Collection App Catalogs
Site Collection App Catalogs (SCAC) are much appreciated, thank you, Office 365 Team. Here is a couple of tips and tricks for SCAC.
Tip #1 You don’t need Tenant Admin rights to add a new Site Collection App Catalog
I have seen many blogs, forum threads etc that state that only Global Tenant Administrators can add new Site Collection App Catalogs. The truth is that a SharePoint Admin rights are enough. The trick is to make that SharePoint Admin Account to a site collection administrator of the app catalog site. To be precise the account that adds a new SCAC must have Manage Web Permissions, as stated in error message:
Just because I can should I use Private Office 365 CDN
This is about a topic brought up by Waldek Mastykarz: Just because you can should you use the Office 365 CDN. In my post I want to take a closer look at the private CDN option in Office 365. Please note, the whole thing is subject to change, and it reflects the circumstances at the time of writing - 2019-08-26.
I’ll skip the introduction of Office 365, let’s jump directly to the Private CDN option. Consider following scenarios.
My first Office Add-In
Yesterday I participated in the Hackathon at European SharePoin Conference in Stockholm. The main goal was to learn more about Office Add-Ins. I wanted to create a very very simple app to learn the basics. Here in this post I’ll provide some links and describe the steps needed to start developing your Office Add-Ins. The Add-in I created is an Outlook Add-In, it is called “Joke Inserter” and with it you can insert a random Chuck Norris joke. It is just for fun, but it demonstrated how an add-in can be installed, made available in “New E-mail” and interact with the e-mail you are writing.
Onpremifying SharePoint apps
We want to make an app available in SharePoint OnPrem, we want to onpremify it. Rethink SharePoint apps and provisioning SharePoint artifacts. It has been a while since I updated my blog – Chuvash.eu. I had my vacation, I visited the sunny and green Chuvashia. Now I am back and I am looking forward to an awesome SharePoint Autumn. One of the first things I had to deal with in this SharePoint Autumn was Onpremifying of a SharePoint Online App. We have an app that has gained popularity and we want to make it available for SharePoint OnPrem. There is no such word Onpremify (yet?), I know, it is a Swenglish happy word making (onpremifiera), but I like the word “onpremify” a lot. There is still uncertainty around the purpose of SharePoint apps. One app type, though, has been used a lot in our company: an app that provisions SharePoint Artifacts – that creates SharePoint Applications. What I mean by SharePoint Applications can be read in my blog post:
Export any web part from a SharePoint page
The blog post below describes the technical details about how Web Parts can be exported using a hidden tool in OOB SharePoint, though this requires manual assembling of a special url. If you are just interested in a solution for an easy Web Part Export function, just proceed directly to my new blog post where you can download my tool that you can add to your web browser.
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
What about the SharePoint app domain?
This is an open question about the domains for SharePoint apps. On Technet: Configure an environment for apps for SharePoint (SharePoint 2013) we can read the following:
You must configure a new name in Domain Name Services (DNS) to host the apps. To help improve security, the domain name should not be a subdomain of the domain that hosts the SharePoint sites. For example, if the SharePoint sites are at Contoso.com, consider ContosoApps.com instead of App.Contoso.com as the domain name.
The CDN concept in SharePoint
How many instances of jquery are there in your SharePoint farm? [sourcecode language=“powershell”] Get-SPWebApplication http://dev ` | Select -Expand Sites ` | Select -Expand AllWebs ` | Select -Expand Lists ` | Select -Expand Items ` | ? { $_.Url -match “jquery.*.js” } ` | select Name, Url [/sourcecode] Have you more than two (jquery and jquery-ui), then you have too much. You can save much place and performance by using Content Delivery Network (CDN) links for the resources like javascript, css, fonts and icons. Consider those Content Delivery Networks:
SharePoint Apps: "Provider Hosted First" Approach
Recently I had an exciting mail conversation with Thomas Deutsch. He came up with an idea how to fasten the development of apps. This smart approach is called “Provider Hosted First”. See Thomas’ original blog post. Here are some highlights: What you actually do is a local website which runs in grunt server
:
localhost:9000
```Then a SharePoint-hosted app is created with an SPAppIframe that refers to that local app site. Genious!!! Some key features of this approach:
* This local app contains a livereload script. Your sharepoint app is updated every time you save your css, js, html file in your IDE
* Grunt minifies, bundles your assets
* Grunt runs your tests automatically when your content is modified
* The SharePoint app can be on Premises, on Office 365, wherever you want it.
#### Video
\[caption id="attachment\_2808" align="alignnone" width="630"\][![See the video how it looks like to develop using this approach](https://sharepointkunskap.files.wordpress.com/2013/07/sp-app-002.png?w=630)](http://www.screenr.com/LA8H) See the video how it looks like to develop using this approach\[/caption\]
## Comments from Wordpress.com
####
[Paul Tavares](http://paultavares.wordpress.com "paultavares1@gmail.com") - <time datetime="2013-07-10 02:59:34">Jul 3, 2013</time>
This is pretty cool and very similar to my current setup for developing javascript applications for SharePoint. I use a script to "deploy" updates from my PC to the folder in a document library. I'll try this out when I get around to playing with SP2013.
<hr />
####
[Björn]( "bjorn.roberg@bool.se") - <time datetime="2013-07-02 11:07:08">Jul 2, 2013</time>
Awesome! I'm gonna try that out!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-07-02 15:31:33">Jul 2, 2013</time>
Great! When you go to Thomas Deutsch blog, you can download the source code for the solution.
<hr />
Develop for SharePoint on Windows 8
Do you like Windows 8 user expirience, as me? Well than you want to try developing sharepoint solutions in Windows 8. Here I will show what I found out.
Environment
I installed Windows 8 Release Preview as a VMWare machine. Then I installed Visual Studio 2012 RC. Then I followed the steps for installing SharePoint on Windows 8 which are more or less the same as for Windows 7 client install. But then I encountered an error I haven’t found solution for yet. In my standalone sharepoint installation there were some permission problems:
Tag: Python
Monitoring Microsoft 365 using Raspberry Pi and M365 CLI
I would like to show you my recent hobby project with a raspberry pi, a unicorn phat and the powerful cli-microsoft365: A simple monitoring solution of Microsoft 365 Services.
Status of some important services in Microsoft 365
In essence, I put the unicorn phat onto the raspberry pi zero w and wrote this python script:
The python script checks the service status every five minutes and shows it with colors on the unicorn phat.
Vår robot Stefan
Roboten Stefan
Här är historian om Stefan, en robot jag och barnen har jobbat på under den senaste månaden. I en sann DIY-anda vill jag skriva om vårt projekt på bloggen och förhoppningsvis inspirera andra att utforska det. I och med projektet innebär en hel del pyssel, så är det lämpat i princip för alla åldrar.
Även om allting togs fram parallellt och stegvis (“i iterationer”), kommer projektet presenteras det i förenklad ordning
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Tag: Raspberrypi
Monitoring Microsoft 365 using Raspberry Pi and M365 CLI
I would like to show you my recent hobby project with a raspberry pi, a unicorn phat and the powerful cli-microsoft365: A simple monitoring solution of Microsoft 365 Services.
Status of some important services in Microsoft 365
In essence, I put the unicorn phat onto the raspberry pi zero w and wrote this python script:
The python script checks the service status every five minutes and shows it with colors on the unicorn phat.
MagicMirror2 and Chuvash
This post is about my setup of the popular MagicMirror2 application. I show the steps needed to set it up on a Raspberry Pi Zero W and connect it to a TV set. As a bonus, I share my thoughts on the Chuvash localization work.
MagicMirror2 is a DIY project and an open-source application, voted to number one of the best Raspberry Pi Projects. In essence, it shows information of your choice (weather, calendar, news) on a screen that is embedded in a mirror.
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Setting up Raspberry Pi2 for a Dashboard Monitor
I have set up Raspberry Pi as a Dashboard Monitor a couple of times. Here I want to summarize my steps. In fact, it is nothing special, a raspberry pi that is used as a browser showing a web based dashboard in full screen, but there are some important configuration steps needed to make it as good as possible.
Install Raspbian
Raspbian is the best operating system for Raspberry Pi. Just stick with that.
S01E01 IoT: Posting Temperature from Raspberry Pi to Azure
Recently I have looked more at IoT, Raspberry Pi in my spare time. In my blog post I want to share my experience in a series of posts. This post is about measuring temperature, humidity and pressure with Raspberry Pi 2 Model B and Sense Hat and posting this data to Azure Table Storage. I followed this tutorial for connecting to azure with python and these instructions for reading data from Sense Hat. The python script is on github. Along the way I learned that only python 2.x can be used with azure and table names cannot contain underscore (I got Bad Request error when I tried to create a table with the name “climate_data”). But overall, the process was straightforward. The temperature is not correct, maybe because the sensor is inbetween Raspberry Pi and Sense Hat where it gets warm. But it is just a Proof-of-Concept. I have used Visual Studio 2015 to see the data in Azure Table Storage. For that I needed to install Azure SDK 2.7. There are many other “explorers” for Azure Storage. Other resources Accessing Azure from Linux and Mac Improvement #1 Corrected Temperature I found a formula for calculating more correct temperature on the raspberry pi forum.
Tag: Unicorn
Monitoring Microsoft 365 using Raspberry Pi and M365 CLI
I would like to show you my recent hobby project with a raspberry pi, a unicorn phat and the powerful cli-microsoft365: A simple monitoring solution of Microsoft 365 Services.
Status of some important services in Microsoft 365
In essence, I put the unicorn phat onto the raspberry pi zero w and wrote this python script:
The python script checks the service status every five minutes and shows it with colors on the unicorn phat.
Tag: Bash
Git Merge develop to main in an Azure DevOps Release
This post is a techy one. It’s about running git commands in Azure DevOps Releases in order to finalize a deployment job to production.
Let me first describe our scenario:
We use Azure DevOps for code and for deployment. Our branch strategy a simplified Gitflow model, where all the current work is merged to the “develop” branch. The code from the “develop” branch is then built and released to staging environments and production. After a release to Production and regression tests the develop branch needs to be merged into the “main” branch (or “master”). So simply put, the git merge into main is what we mean by finalizing a production release.
Mass remove live photo videos
While importing images from my iPhone using Image Capture on my mac, I discovered that almost all pictures had corresponding videos. They had the same name, only the file extension was different:
- IMG_2829.JPG
- IMG_2829.MOV
For archiving I don’t to have live photo videos, that’s why I needed a script for that. I found a good start in an answer on SuperUser.stackexchange.com:
I altered it a bit to remove the corresponding .MOV-file (rm):
Setting up Raspberry Pi2 for a Dashboard Monitor
I have set up Raspberry Pi as a Dashboard Monitor a couple of times. Here I want to summarize my steps. In fact, it is nothing special, a raspberry pi that is used as a browser showing a web based dashboard in full screen, but there are some important configuration steps needed to make it as good as possible.
Install Raspbian
Raspbian is the best operating system for Raspberry Pi. Just stick with that.
Install android sdk and eclipse in Ubuntu 12.04
Download and unpack the Android SDK, move it to your home folder. I prefer to set a point in front of the directory folder to make it be hidden so that my home directoy still looks tidy: .android-sdk-linux
. Then add this to your path:
export PATH=${PATH}:~/.android-sdk-linux/tools:~/.android-sdk-linux/platform-tools
.android-sdk-tools is for running android
command, and .android-sdk-tools/platform-tools is for running adb
command And add it to your .bashrc-file so that this path is loaded automatically when you log on.
Tag: Deploy
Git Merge develop to main in an Azure DevOps Release
This post is a techy one. It’s about running git commands in Azure DevOps Releases in order to finalize a deployment job to production.
Let me first describe our scenario:
We use Azure DevOps for code and for deployment. Our branch strategy a simplified Gitflow model, where all the current work is merged to the “develop” branch. The code from the “develop” branch is then built and released to staging environments and production. After a release to Production and regression tests the develop branch needs to be merged into the “main” branch (or “master”). So simply put, the git merge into main is what we mean by finalizing a production release.
defaultvärde på parametern i powershellfunktioner
Läser ett intressant inlägg om deployskript i powershell. Har upptäckt att man kan stoppa in ett defaultvärde i funktionens parameter. Så i stället för
function hello($name) {
Write-Host $name
}
Kan man köra:
function hello($name = "Gregor") {
Write-Host $name
}
```Mycket smidigt.
Tag: Pipeline
Git Merge develop to main in an Azure DevOps Release
This post is a techy one. It’s about running git commands in Azure DevOps Releases in order to finalize a deployment job to production.
Let me first describe our scenario:
We use Azure DevOps for code and for deployment. Our branch strategy a simplified Gitflow model, where all the current work is merged to the “develop” branch. The code from the “develop” branch is then built and released to staging environments and production. After a release to Production and regression tests the develop branch needs to be merged into the “main” branch (or “master”). So simply put, the git merge into main is what we mean by finalizing a production release.
Tag: Programming
Git Merge develop to main in an Azure DevOps Release
This post is a techy one. It’s about running git commands in Azure DevOps Releases in order to finalize a deployment job to production.
Let me first describe our scenario:
We use Azure DevOps for code and for deployment. Our branch strategy a simplified Gitflow model, where all the current work is merged to the “develop” branch. The code from the “develop” branch is then built and released to staging environments and production. After a release to Production and regression tests the develop branch needs to be merged into the “main” branch (or “master”). So simply put, the git merge into main is what we mean by finalizing a production release.
Vår robot Stefan
Roboten Stefan
Här är historian om Stefan, en robot jag och barnen har jobbat på under den senaste månaden. I en sann DIY-anda vill jag skriva om vårt projekt på bloggen och förhoppningsvis inspirera andra att utforska det. I och med projektet innebär en hel del pyssel, så är det lämpat i princip för alla åldrar.
Även om allting togs fram parallellt och stegvis (“i iterationer”), kommer projektet presenteras det i förenklad ordning
MagicMirror2 and Chuvash
This post is about my setup of the popular MagicMirror2 application. I show the steps needed to set it up on a Raspberry Pi Zero W and connect it to a TV set. As a bonus, I share my thoughts on the Chuvash localization work.
MagicMirror2 is a DIY project and an open-source application, voted to number one of the best Raspberry Pi Projects. In essence, it shows information of your choice (weather, calendar, news) on a screen that is embedded in a mirror.
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Setting up a HelloWorld Azure Alert
Azure Alerts are awesome for monitoring of solutions in Azure. If you are about to set up your first Alert Rules in Azure, then it’s a guide for you. Configuring alert rules can be quite intimidating at first, with all the options, metrics, evaluation times, etc.
Here is a very very simple setup that can serve as a teaser and help you get started with the Azure Alerts.
Working with resx files in Visual Studio
Today I found a nice Visual Studio Extension for working with localization and resx files: Resx Resource Manager. This extension provides an additional view in your project and scans all the resx files. I would recommend it to all projects where you have to translate your interface. Here is how it looks in my project: It can also assist with some machine translation from Bing and MyMemory: Another good thing is the Export and Import to and from Excel. Wonderful if you need help from Non-developers.
Trying out Visual Studio Code on Ubuntu
I am very curious about the new .NET Core, ASP.NET 5, EF 7 and Visual Studio Code for Linux, Mac and Windows. I have tried it out on an Ubuntu 15.04 machine. The installation and configuration required a few steps, so it is not an usual “Next-next-next”-installation. But, hey, it is just a beta, a preview so far, and first of all: It worked. I am sharing a couple of screenshots and the commands I ran in the terminal, mixed with comments and links: [source language=“bash”] #install latest node and npm #https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs sudo npm install -g yo sudo npm install -g generator-aspnet # download VS Code and make a link # make a folder mkdir workspace/tryvs cd workspace/tryvs # create “src/global.json” file: # http://docs.asp.net/en/latest/tutorials/your-first-mac-aspnet.html { “sdk”: { “version”: “1.0.0-beta7” } } nano src/global.json # start VS Code # create # install omnisharp: # http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#installing-on-debian-ubuntu-and-derivatives curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh dnvm #install dnx sudo apt-get install -y libunwind8 gettext libssl-dev libcurl3-dev zlib1g libicu-dev dnvm upgrade -r coreclr cd EmptyApplication dnu restore #install libuv #http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#using-docker sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/ sudo ldconfig #build, I got an error here dnu build #start the web server dnx web [/source]
Tag: Release
Git Merge develop to main in an Azure DevOps Release
This post is a techy one. It’s about running git commands in Azure DevOps Releases in order to finalize a deployment job to production.
Let me first describe our scenario:
We use Azure DevOps for code and for deployment. Our branch strategy a simplified Gitflow model, where all the current work is merged to the “develop” branch. The code from the “develop” branch is then built and released to staging environments and production. After a release to Production and regression tests the develop branch needs to be merged into the “main” branch (or “master”). So simply put, the git merge into main is what we mean by finalizing a production release.
Azure Key Vault vs. Pipeline Variables
Using Azure Key Vault in a Pipeline is cool, but it is less secure.
The Key Vault setup
Have you tried the Key Vault Step in an Azure DevOps Pipeline? If you haven’t, please follow these awesome guides:
- Azure DevOps Labs. Using secrets from Azure Key Vault in a pipeline
- Tobias Zimmergren. Using Azure Key Vault Secrets in Azure DevOps pipelines
The steps described in these guides are easy, but that effort made me think about the first pair of pros and cons.
Version 0.2.7: Nations added. Ready for release
It is my pleasure to announce that a new version is ready for release. The biggest news are the nations which are now on the map. Other improvements are spelling error corrections. Great thanks to Kigsz. You can read about adding nations to the map on Lusites wiki.
Tag: Print
Print2SPO - en enkel utskrift till SharePoint
Den här bloggposten är ett (en aning större) användar- (eller verksamhetsutvecklar-)tips om hur man kan sätta upp smarta utskrifter till SharePoint Online - utan några extraappar eller lösningar.
Först och främst, stort tack till min kollega Shahram som har presenterat idén för mig. Tänk dig ett följande scenario:
Du har en mall i Word som du fyller i, skriver ut på papper. Låt säga, det är en plockorder. Du vill digitalisera processen genom att skicka pdf:en till ett gemensamt dokumentbibliotek i SharePoint eller Teams.
Tag: License
1 TB = 1024 GB in SPO?
There is confusion around how the storage is calculated in SharePoint Online. I believe, in SharePoint Online 1 TB is 1024 GB (based on powers of two), although the SI Prefix is for numbers based on powers of 10 (1TB = 1000GB, Wikipedia). In this post I would like to summarize the results of my investigations and I hope Microsoft or the community can confirm or disconfirm this.
First, let me explain why we care about it. The storage in SharePont is limited and we need to keep an eye on it. Especially in our case, where we need to track storage utilization across different parts of the organization/our tenant. The storage in SharePoint is calculated like so:
Multilingual MS Forms
Want to translate your MS Forms into other languages? Create a form, not a quiz. It is available in both Forms and Forms Pro licenses.
Today I want to share one of my findings. One of those that seem obvious once you know, but that take time to find out.
Unfortunately, there is no official comparison of what is included in MS Forms vs. MS Forms Pro. So I thought that the ability to have forms in multiple languages was connected to the license.
Tag: Block Programming
Vår robot Stefan
Roboten Stefan
Här är historian om Stefan, en robot jag och barnen har jobbat på under den senaste månaden. I en sann DIY-anda vill jag skriva om vårt projekt på bloggen och förhoppningsvis inspirera andra att utforska det. I och med projektet innebär en hel del pyssel, så är det lämpat i princip för alla åldrar.
Även om allting togs fram parallellt och stegvis (“i iterationer”), kommer projektet presenteras det i förenklad ordning
Tag: Makecode
Vår robot Stefan
Roboten Stefan
Här är historian om Stefan, en robot jag och barnen har jobbat på under den senaste månaden. I en sann DIY-anda vill jag skriva om vårt projekt på bloggen och förhoppningsvis inspirera andra att utforska det. I och med projektet innebär en hel del pyssel, så är det lämpat i princip för alla åldrar.
Även om allting togs fram parallellt och stegvis (“i iterationer”), kommer projektet presenteras det i förenklad ordning
Tag: Micro:bit
Vår robot Stefan
Roboten Stefan
Här är historian om Stefan, en robot jag och barnen har jobbat på under den senaste månaden. I en sann DIY-anda vill jag skriva om vårt projekt på bloggen och förhoppningsvis inspirera andra att utforska det. I och med projektet innebär en hel del pyssel, så är det lämpat i princip för alla åldrar.
Även om allting togs fram parallellt och stegvis (“i iterationer”), kommer projektet presenteras det i förenklad ordning
Tag: Robot
Vår robot Stefan
Roboten Stefan
Här är historian om Stefan, en robot jag och barnen har jobbat på under den senaste månaden. I en sann DIY-anda vill jag skriva om vårt projekt på bloggen och förhoppningsvis inspirera andra att utforska det. I och med projektet innebär en hel del pyssel, så är det lämpat i princip för alla åldrar.
Även om allting togs fram parallellt och stegvis (“i iterationer”), kommer projektet presenteras det i förenklad ordning
Tag: Servo
Vår robot Stefan
Roboten Stefan
Här är historian om Stefan, en robot jag och barnen har jobbat på under den senaste månaden. I en sann DIY-anda vill jag skriva om vårt projekt på bloggen och förhoppningsvis inspirera andra att utforska det. I och med projektet innebär en hel del pyssel, så är det lämpat i princip för alla åldrar.
Även om allting togs fram parallellt och stegvis (“i iterationer”), kommer projektet presenteras det i förenklad ordning
Tag: Pbi
Kombinera två SharePoint-listor i PowerBI
Det här är en enkel guide på svenska om hur du kan ladda in data från två eller fler listor i SharePoint och lägga ihop dem till en.
Scenariot är följande. Du har två eller fler sajter i SharePoint Online som har var sin lista (med samma kolumner). Du vill ladda in data från båda och se en aggregerad/summerad version. Alternativet är att ha en delad lista, men ibland (av behörighetskäl eller av behovet för smärre anpassningar av enskilda listor), ligger det i separata listor/sajter.
Tag: PowerBI
Kombinera två SharePoint-listor i PowerBI
Det här är en enkel guide på svenska om hur du kan ladda in data från två eller fler listor i SharePoint och lägga ihop dem till en.
Scenariot är följande. Du har två eller fler sajter i SharePoint Online som har var sin lista (med samma kolumner). Du vill ladda in data från båda och se en aggregerad/summerad version. Alternativet är att ha en delad lista, men ibland (av behörighetskäl eller av behovet för smärre anpassningar av enskilda listor), ligger det i separata listor/sajter.
Tag: Hubber
Add a security group as hubbers using PowerShell
Today I needed to add a security group to “People who can associate sites with this hub” through PowerShell. Here is quick how-to. I usually say “hubbers” instead of the long “People who….”. By the way, if you want to know what prerequisites there are for being a hubber, read my other blog post
An example of how to add a security group is missing in the MS Docs:
Tag: Hubsite
Add a security group as hubbers using PowerShell
Today I needed to add a security group to “People who can associate sites with this hub” through PowerShell. Here is quick how-to. I usually say “hubbers” instead of the long “People who….”. By the way, if you want to know what prerequisites there are for being a hubber, read my other blog post
An example of how to add a security group is missing in the MS Docs:
Infographics. Who can associate a site with a hub
I found this nice post and a nice decision flowchart.
Low resolution, visit the post to see more.
I also have drawed a simple chart while explaining for my colleagues, you can see it above. I hope this infographics can be useful to more people. By the way, we use the word “Hubber” (sv. Hubbare) for “People who can associate sites to hubs”
Tag: Adoption
Own praise badges in Teams
While reading the Teams News recap from December 2020, I found one thing that caught my attention particularly: Custom Praise Badges in Teams. Let’s try this. But first, those badges are the default ones:
They are good starting point. But to take it a step further, to really engage people and praise, you need some specific badges that mean something for your company.
To add a new badge all you have to do is to go to Teams Admin (obviously it requires you having the Teams Administrator Role):
Tag: Badge
Own praise badges in Teams
While reading the Teams News recap from December 2020, I found one thing that caught my attention particularly: Custom Praise Badges in Teams. Let’s try this. But first, those badges are the default ones:
They are good starting point. But to take it a step further, to really engage people and praise, you need some specific badges that mean something for your company.
To add a new badge all you have to do is to go to Teams Admin (obviously it requires you having the Teams Administrator Role):
Tag: Praise
Own praise badges in Teams
While reading the Teams News recap from December 2020, I found one thing that caught my attention particularly: Custom Praise Badges in Teams. Let’s try this. But first, those badges are the default ones:
They are good starting point. But to take it a step further, to really engage people and praise, you need some specific badges that mean something for your company.
To add a new badge all you have to do is to go to Teams Admin (obviously it requires you having the Teams Administrator Role):
Tag: ListView
Two workarounds for overcoming the listview threshold
These are two workarounds to see documents / list items in a view that exceeds the listview threshold of 5000 items.
Overcoming the listview threshold is as fun as succeeding in the limbo games.
This is changing all the time. When you read this, it might have changed. Today, 2021-01-05, me and my colleague found following two workarounds for listing over 5000 items in a list view in SharePoint Online:
Get totals from a list view using PowerShell
Today I will share a short script for getting totals from a list view in SharePoint. Imagine this scenario: you have set up a list view with totals and you want get the totals every day for statistics or some other reasons. Instead of getting all items, and/or fiddling around with CamlQueries, there is a better and quicker way - List.RenderListData. This combined with a tip from Piyush K Singhs blog post Get Aggregate Values… I came up with an idea to read the ViewXml from an existing view and retrieve the totals (in my case Count and Sum). Enough talking, let’s take a look at the code:
Binda Data till ListView i WPF
Det är väldigt smidigt att koppla datakälla till en ListView i WPF. Man skriver kod i XAML. Och i koden bakom anger man: myListView.ItemsSource = myList;
Tag: Threshold
Two workarounds for overcoming the listview threshold
These are two workarounds to see documents / list items in a view that exceeds the listview threshold of 5000 items.
Overcoming the listview threshold is as fun as succeeding in the limbo games.
This is changing all the time. When you read this, it might have changed. Today, 2021-01-05, me and my colleague found following two workarounds for listing over 5000 items in a list view in SharePoint Online:
Tag: Exoprise
Teams incoming webhooks for performance monitoring
Incoming webhooks in Teams are great, indeed. Last week I saw this tweet, which inspired me to share one of our webhooks.
There are many scenarios where it can be used, I would also like to share one of our scenarios: notifying our DevOps team about performance issues in SharePoint Online, detected through Exoprise.
This adaptive card (in Swedish) shows an alarm from Exoprise about login problems.
Tag: Monitoring
Teams incoming webhooks for performance monitoring
Incoming webhooks in Teams are great, indeed. Last week I saw this tweet, which inspired me to share one of our webhooks.
There are many scenarios where it can be used, I would also like to share one of our scenarios: notifying our DevOps team about performance issues in SharePoint Online, detected through Exoprise.
This adaptive card (in Swedish) shows an alarm from Exoprise about login problems.
Setting up a HelloWorld Azure Alert
Azure Alerts are awesome for monitoring of solutions in Azure. If you are about to set up your first Alert Rules in Azure, then it’s a guide for you. Configuring alert rules can be quite intimidating at first, with all the options, metrics, evaluation times, etc.
Here is a very very simple setup that can serve as a teaser and help you get started with the Azure Alerts.
Shrink sharepoint database
A Sharepoint Database can become big and have unused spaces. To shrink database go to CA-> Health Analyzer: http://takana:1337/Lists/HealthReports/AllItems.aspx See if there is a list item about unused space in db under the Availability. Click on Repair Automatically in the opened Modal Dialog:
A simple Log for ULS
Do an unsafe update in a unified manner « Sharepoint. Kunskap. Upptäckter på resan. - Sep 3, 2011
[…] Log class is my own class which I presented in my previous post. Like this:GillaBli först att gilla denna […]
A simple Log for ULS
Here is a simple log which has been inspired of Android Log. It logs to ULS which you can open with ULSViewer, SharePoint Log Viewer.
using System;
using Microsoft.SharePoint.Administration;
namespace Contoso.Intranet.Portal.Utilities
{
public class Log
{
private static readonly string \_CATEGORYNAME = "CONTOSO";
private static readonly SPDiagnosticsCategory \_ERROR\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Unexpected, EventSeverity.Error);
private static readonly SPDiagnosticsCategory \_WARNING\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.High, EventSeverity.Warning);
private static readonly SPDiagnosticsCategory \_VERBOSE\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Verbose, EventSeverity.Verbose);
private static readonly SPDiagnosticsCategory \_INFO\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Medium, EventSeverity.Information);
private static void WriteTrace(SPDiagnosticsCategory category, string message, string trace)
{
SPDiagnosticsService.Local.WriteTrace(0, category, category.DefaultTraceSeverity, message, trace);
}
public static void Error(Exception ex)
{
WriteTrace(\_ERROR\_CATEGORY, ex.Message, ex.StackTrace);
}
public static void Warning(string message)
{
WriteTrace(\_WARNING\_CATEGORY, message, "");
}
public static void Verbose(string message)
{
WriteTrace(\_VERBOSE\_CATEGORY, message, "");
}
public static void Info(string message)
{
WriteTrace(\_INFO\_CATEGORY, message, "");
}
}
}
A possible improvement can be a custom Area. See an example of ThorstenHans on Github: CustomLogger.cs EDIT: I found an interesting article: How to log to the SharePoint ULS Logs: Clean Debugging and Error Logging broken down into steps written by Philip Stathis.
Sharepoint Log Viewer
Mycket bra verktyg för att debugga din sharepoint applikation är Sharepoint Log Viewer som är Open Source och finns att hämta på codeplex.com Det går att öppna en logg-fil, det går att köra live monitoring och att exportera. Det sköna är att det är lätt att söka efter correlations-id. Rekommenderar verktyget!
Comments from Wordpress.com
Sharepoint + OpenSource = Sant « Sharepoint. Kunskap. Upptäckter på resan. - Mar 3, 2011
Tag: Webhook
Teams incoming webhooks for performance monitoring
Incoming webhooks in Teams are great, indeed. Last week I saw this tweet, which inspired me to share one of our webhooks.
There are many scenarios where it can be used, I would also like to share one of our scenarios: notifying our DevOps team about performance issues in SharePoint Online, detected through Exoprise.
This adaptive card (in Swedish) shows an alarm from Exoprise about login problems.
Setting up a HelloWorld Azure Alert
Azure Alerts are awesome for monitoring of solutions in Azure. If you are about to set up your first Alert Rules in Azure, then it’s a guide for you. Configuring alert rules can be quite intimidating at first, with all the options, metrics, evaluation times, etc.
Here is a very very simple setup that can serve as a teaser and help you get started with the Azure Alerts.
Tag: Chuvash
MagicMirror2 and Chuvash
This post is about my setup of the popular MagicMirror2 application. I show the steps needed to set it up on a Raspberry Pi Zero W and connect it to a TV set. As a bonus, I share my thoughts on the Chuvash localization work.
MagicMirror2 is a DIY project and an open-source application, voted to number one of the best Raspberry Pi Projects. In essence, it shows information of your choice (weather, calendar, news) on a screen that is embedded in a mirror.
Chuvash Keyboard Layout for Mac
I’ve got a Mac and one of my first questions was: How can I write in Chuvash on my Mac, obviously :) In this post I am going to tell how I created Chuvash Keyboard Layout. The solution and installation instructions are on Github: Chuvash Keyboard Layout for Mac
What the heck is Chuvash?
For those who don’t know yet: Chuvash are people who live in Chuvash Republic in Russian Federation, and abroad, as me. We are 1.5 million. Chuvash is also a language, an official language of the Republic, a minority language, that is completely different from the second official language Russian. Chuvash uses Cyrillic letters, all 33 Russian letters plus 4 additional letters: A breve (Ӑ), E breve (Ӗ), C cedilla (Ҫ) and U with double acute (Ӳ).
A new Chuvash keyboard layout
The Chuvash keyboard layout has been the Russian keyboard layout with 4 Chuvash letters that are typed by pressing the right Alt button plus the base letter. Some of the arguments have been
- Users don’t need to switch or learn a new keyboard layout. They can keep on typing Russian texts and sometimes Chuvash texts
- It is easy to communicate about how the right Alt button works. The Right-Alt-technique is also used in Esperanto, Polish and other languages.
- The letters are placed according the labels
Recently two major events happened that made the question about the Chuvash keyboard layout important:
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Chuvash localization
Recently I wanted to add Chuvash localization to the jQuery UI datepicker. Unfortunately, my pull request was rejected. The reason is that jQuery UI will be using Globalize framework: The jQuery Globalize framework relies on CLDR, so What is Unicode CLDR (Common Locale Data Repository)?
The Unicode CLDR provides key building blocks for software to support the world’s languages, with the largest and most extensive standard repository of locale data available. This data is used by a wide spectrum of companies for their software internationalization and localization, adapting software to the conventions of different languages for such common software tasks
It is time to standardize the Chuvash Keyboard Layout
[caption id=“attachment_3165” align=“alignnone” width=“630”] Proto-Bulgarian Runes (Chuvash language is the closest language to the Proto-Bulgar language). Wonder if they are supported in Unicode :)[/caption] The Chuvash Computer Keyboard layouts have existed since 2001, but due to the lack for Unicode support we were forced to use the look-alike letters from other latin-based keyboard layouts. On Linux The Chuvash keyboard layout was added in [2007](https://bugs.freedesktop.org/show_bug.cgi?id=11246 “The original “bug” in FreeDesktop bugzilla”) and Linux is still the only operating system that has a native keyboard layout for Chuvash language. On Windows we have used the Keyboard Layout Creator and distributed it as an executable file. Today, when Windows XP is not supported anymore, the majority of users now have full support for the correct Chuvash letters from the Extended Cyrillic table. These four Chuvash letters are “additional” to the Russian alphabet: Ӑ, Ӗ, Ҫ and Ӳ. Now when new “keyboards” appear on Android, in web browser (they use the standardized letters) and hopefully in Windows and iOS, we have to consider put the correct letters into the keyboard layouts. For Linux the /usr/share/X11/xkb/symbols/ru
file has to be updated: [code] // Chuvash language layout // Anatoly Mironov @mirontoli partial alphanumeric_keys xkb_symbols “cv” { include “ru(winkeys)” name[Group1]= “Chuvash”; key.type[group1]=“FOUR_LEVEL”; key { [ Cyrillic_u, Cyrillic_U, 0x010004f3, 0x010004f2 ] }; key { [ Cyrillic_ie, Cyrillic_IE, 0x010004d7, 0x010004d6 ] }; key { [ Cyrillic_a, Cyrillic_A, 0x010004d1, 0x010004d0 ] }; key { [ Cyrillic_es, Cyrillic_ES, 0x010004ab, 0x010004aa ] }; include “level3(ralt_switch)” }; [/code]
Pragmatic Responsive Design
I have been curious about the responsive design but have not had time to try it out. To learn more I decided to make an existing website more responsive. A friend of mine drives a Chuvash Dictionary website: samah.chv.su. Today it looks like this in a mobile browser: The site is a classic 1000px-ish centered page with header and two columns. The left column is for the main content and the right column for additional “aside” information. Can it be more classic? This current version works, you can still use the dictionary on a mobile phone. But there are several improvements that can be done:
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Chuvash localization of moment.js
For three months ago I added Chuvash localization of moment.js. For 16 days ago moment.js 1.7.0 was officially released which included the Chuvash translation.
Wait a sec… What is moment.js?
moment.js is the best datetime tool for javascript. It supports many languages (now even Chuvash) for displaying date and time. Another very handy functionality is showing relative time which has a simple interface: fromNow().
Here is a simple example from a web browser console:
Chuvash translation of Wikipedia Mobile
The official Wikipedia mobile app is now translated into Chuvash language and available to use:
What does Chuvash mean?
I am Chuvash. Chuvash is the name of an ethnicity which counts up to 2 milions peoply (mostly in Russia). Chuvashes talk the Chuvash language which is also an official language in Chuvash Republic (besides Russian). Chuvash language is a Turkic language and has a status “Vulnerable” in the UNESCO list of languages in danger. There is a Chuvash Wikipedia cv.wikipedia.org.
Chuvash Keyboard for Android
Now there is a Chuvash keyboard for Android. The little program uses AnySoftKeyboard application, gives the ability to write in Cyrillic and Latin. All kinds of feedback are appreciated. Chuvash Keyboard for Android is open source like AnySoftKeyboard.
Tag: I18n
MagicMirror2 and Chuvash
This post is about my setup of the popular MagicMirror2 application. I show the steps needed to set it up on a Raspberry Pi Zero W and connect it to a TV set. As a bonus, I share my thoughts on the Chuvash localization work.
MagicMirror2 is a DIY project and an open-source application, voted to number one of the best Raspberry Pi Projects. In essence, it shows information of your choice (weather, calendar, news) on a screen that is embedded in a mirror.
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Javascript
MagicMirror2 and Chuvash
This post is about my setup of the popular MagicMirror2 application. I show the steps needed to set it up on a Raspberry Pi Zero W and connect it to a TV set. As a bonus, I share my thoughts on the Chuvash localization work.
MagicMirror2 is a DIY project and an open-source application, voted to number one of the best Raspberry Pi Projects. In essence, it shows information of your choice (weather, calendar, news) on a screen that is embedded in a mirror.
Filtering Azure Table Data directly in the Azure Function Binding
Instead of filtering values from an Azure Storage Table, you can do it directly in the bindings. It might not be a solution for everything, but in the right place, it is fantastic. I was very surprised to see how little code was needed after this binding change:
For that to work, define the filter attribute in the bindings: “filter”: “(PartitionKey eq ‘{package}’)”
To try it out, add a new row in a table defined in the bindings (“metadata” in my case):
Update Field.JSLink using JSOM or REST
Today I have just a little code snippet to share. This code snippet shows how to update the JSLink property for an existing field using JSOM and REST. For REST I use sharepoint-utilities. [code language=“javascript”] var updateJsLinkCsom = function(config) { var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(config.listTitle) var fields = list.get_fields(); var field = fields.getByInternalNameOrTitle(config.fieldTitle) field.set_jsLink(config.jsLink) field.update() ctx.executeQueryAsync() }; var updateJsLinkRest = function(config) { SP.SOD.registerSod(‘sputils.js’, ‘/sputils.min.js’) SP.SOD.executeFunc(‘sputils.js’, ‘’, function() { var url = _spPageContextInfo.webAbsoluteUrl + ‘/_api/web/lists/getbytitle(\’’ + config.listTitle + ‘\’)/fields/getbyinternalnameortitle(\’’+ config.fieldTitle + ‘\’)’; var payload = {’__metadata’: {’type’: ‘SP.Field’}, ‘JSLink’: config.jsLink}; var config = {‘headers’ : {‘X-HTTP-Method’: ‘MERGE’ }}; sputils.rest.post(url, payload, config); }); }; var config = { listTitle: ‘’, fieldTitle: ‘’, jsLink: ‘~site/’ }; updateJsLinkCsom(config); updateJsLinkRest(config); [/code] A couple of notes, to update a field we need:
Trigger SP2010 Workflows using JSOM
Today I found out how to start workflows in JSOM (JavaScript Object Model in SharePoint). Nothing special, but since it is not documented, it took me a while to find a solution. Here is the code which I want to keep as simple as possible. What you need to start a SP2010 Workflow for a list item or a document in JSOM, you need to load SP.WorkflowServices.js and you need to create the manager and get the service, then you can trigger a workflow using the workflow name, the list guid and the guid of the list item: [code language=“javascript”] var ctx = SP.ClientContext.get_current(); var workflowServicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web()); var service = workflowServicesManager.getWorkflowInteropService(); service.startWorkflow(workflowName, null, listGuid, plainItem.guid, initiationParams); [/code] Here is the code to trigger a workflow for multiple items: [code language=“javascript”] //fire the workflows function fire2010WorkflowForListItems(ctx, listGuid, plainItems) { var workflowServicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web()); var service = workflowServicesManager.getWorkflowInteropService(); for(var i = 0; i < plainItems.length; i++) { var plainItem = plainItems[i]; console.log(‘scheduling workflow for id: ‘, plainItem.id); service.startWorkflow(options.workflowName, null, listGuid, plainItem.guid, options.initiationParams); } console.log(’now executing…’); ctx.executeQueryAsync(function() { console.info(‘yes, workflows completed for ’ + items.length + ’ items’); }, function() { console.error(‘it didnt go well’); }); } [/code] The code above is inspired from this gist and sharepoint stackexchange. It is a simplified version that only works for list item workflows and SharePoint 2010 workflows. Here is an example how you can get multiple items and batch start a workflow: [code language=“javascript”] //just a couple of variables var options = { workflowName: ‘Behörigheter’, listName: ‘Documents’, initiationParams: {} }; //load list items function startWorfklows() { //Start 2010 Workflow for a List Item var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(options.listName); ctx.load(list); var items = list.getItems(new SP.CamlQuery()); ctx.load(items); ctx.executeQueryAsync(function() { var listGuid = list.get_id() + ‘’; var en = items.getEnumerator(); var plainItems = []; while (en.moveNext()) { var it = en.get_current(); //do not take checked out files, it won’t work if (!it.get_item(‘CheckoutUser’)) { plainItems.push({id: it.get_id(), guid: it.get_item(‘GUID’) + ’’ }); } } fire2010WorkflowForListItems(ctx, listGuid, plainItems); }, function() { alert(‘boom’); }); } //Load Worfklow Js dependency var wfScript = ‘SP.WorkflowServices.js’ SP.SOD.registerSod(wfScript, _spPageContextInfo.webAbsoluteUrl + ‘/_layouts/15/SP.WorkflowServices.js’); SP.SOD.executeFunc(wfScript, ‘’, startWorfklows); [/code]
Create and download a file in javascript
Phew, I spent a lot of time to get this to work:
- Create a text based file in javascript - a simple csv or txt
- Download a file in Chrome and Internet Explorer
- Make Excel understand Unicode characters (å ä ö and many more) in csv directly.
I found many solutions on the Internet that I used to find out a solution that works for me A deep diving jsfiddle about unicode encodings, bom, line endings: http://jsfiddle.net/kimiliini/HM4rW (unfortunately, does not work in IE). There I learned one important thing: we need a BOM in order to make Excel understand that it is not just ASCII. The BOM (byte order mark) for utf-8 is %ef%bb%bf for utf-8. Without this bom you’ll see the right characters in a text editor (except Notepad of course), but if you open the csv file directly in Excel, you’ll see wrong letters. Other good resources are FileSaver.js: https://github.com/eligrey/FileSaver.js and download.js: http://danml.com/download.html and a discussion on that github repository issue: https://github.com/mholt/PapaParse/issues/175 This is my solution that is tested in Chrome and IE10: [code language=“javascript”] function downloadContent(options) { if (!options || !options.content) { throw ‘You have at least to provide content to download’; } options.filename = options.filename || ’tolle.txt’; options.type = options.type || ’text/plain;charset=utf-8’; options.bom = options.bom || decodeURIComponent(’%ef%bb%bf’); if (window.navigator.msSaveBlob) { var blob = new Blob([options.bom + options.content], {type: options.type }); window.navigator.msSaveBlob(blob, options.filename); } else { var link = document.createElement(‘a’); var content = options.bom + options.content; var uriScheme = [‘data:’, options.type, ‘,’].join(’’); link.href = uriScheme + content; link.download = options.filename; //FF requires the link in actual DOM document.body.appendChild(link); link.click(); document.body.removeChild(link); } } //test var separator = ‘;’; downloadContent({ type: ’text/csv;charset=utf-8’, filename: ’tolle.csv’, content: [‘ASCII’, separator, ‘Åbäcka sig’, separator, ’to się podoba: żźćąęłć’, separator, ‘Яшлӑхӑма туйаймарӑм’].join(’’) }); [/code]
Minimal Download Strategy. Simple
There are many correct ways (1, 2, 3, 4, 5…) of making scripts work with the Minimal Download Strategy Feature (MDS) in SharePoint 2013 and 2016. But to be honest - every time I need it, I get confused. So now it is time to find a simple solution for that. Who is better at it than the developers of the SharePoint themselves? Look at the MDS code in the built-in Display Templates: Let’s keep it as simple as Item_Default.js, let’s take it as it is and create our own scripts. Here is a skeletton of and MDS-ready script: [code language=“javascript”] function runMyCode() { var time = new Date().toISOString(); console.log(‘runMyCode’, time ); } runMyCode(); if (typeof(RegisterModuleInit) == ‘function’) { var scriptUrl = ‘/Style Library/runMyCode.js’; RegisterModuleInit(scriptUrl, runMyCode); } [/code] Which boils down to this in pseudocode:
Minimal Display Template
We want to use our own Display Templates on Non-publishing sites - our team sites. Without the Publishing Feature activated you have to create an own javascript file. Here is short and concise instructions how to install it: Display Templates on Non-publishing Sites. As described on that blog, you can make copy of an existing Item_Default.js and adjust to your needs. I also asked Elio Struyf and I got the same tip. I did create my starter template. Here I want to share this very minimal javascript based Display Template. The real Minimal Display Template is in the SPCSR github repository: Item_Minimal.js It has been improved by Elio Stuyf himself :) [code language=“javascript”] (function () { // Config contains variables that are defined in one place var config = { propertyMappings: { ‘Path’:null, ‘Title’:[‘Title’] } }; var templateUrl; var register = function () { if (“undefined” !== typeof (Srch) && “undefined” !== typeof (Srch.U) && typeof (Srch.U.registerRenderTemplateByName) === “function”) { Srch.U.registerRenderTemplateByName(templateUrl, render); } }; render = function (ctx) { // Display template data var cachePreviousTemplateData = ctx.DisplayTemplateData; ctx.DisplayTemplateData = { ‘TemplateUrl’: templateUrl, ‘TemplateType’: ‘Item’, ‘TargetControlType’: [‘SearchResults’, ‘Content Web Parts’], ‘ManagedPropertyMapping’: config.propertyMappings }; var cachePreviousItemValuesFunction = ctx.ItemValues; ctx.ItemValues = function(slotOrPropName) { return Srch.ValueInfo.getCachedCtxItemValue(ctx, slotOrPropName); }; // Retrieve managed property data var path = $getItemValue(ctx, ‘Path’); var title = $getItemValue(ctx, ‘Title’); // HTML markup for an item var htmlMarkup = String.format( ‘’ + ‘{1}’ + ‘’, path, title); // Caching ctx.ItemValues = cachePreviousItemValuesFunction; ctx.DisplayTemplateData = cachePreviousTemplateData; // Return the HTML markup return htmlMarkup; }; // Retrieve all the loaded scripts var allScripts = document.getElementsByTagName(“script”); // Get the last script file (this is the current DT file) var scriptUrl = allScripts[allScripts.length - 1].src; if (scriptUrl.indexOf(’/_catalogs/’) > 0) { // Remove the query string if (scriptUrl.indexOf(’?’) > 0) { scriptUrl = scriptUrl.split("?")[0]; } // Insert the site collection token templateUrl = ‘~sitecollection’ + scriptUrl.substr(scriptUrl.indexOf(’/_catalogs/’)) // Register the template to load register(); if (typeof (RegisterModuleInit) === “function” && typeof(Srch.U.replaceUrlTokens) === “function”) { RegisterModuleInit(Srch.U.replaceUrlTokens(templateUrl), register); } } })(); [/code]
SharePoint Utilities - a promising JavaScript Framework
My colleagues at Bool have developed a new JavaScript framework for SharePoint - sharepoint utilities. It started on our DevDay last year - a whole free day when we could learn new things, try out new techniques or build something that was not even requested from a customer. I was not working on sharepoint utilities, so I almost forgot it until… I recently re-discovered sharepoint utilities. It is on Github, it is MIT licensed and contributions are welcome. The core of sharepoint utilities (sputils) is a set of wrappers for Search, TermStore, REST that allow you be more productive as a developer. What I find especially compelling with that it contains some other fundamental stuff that every SharePoint developer needs:
A tiny tool for User Custom Actions
Everybody loves User Custom Actions in SharePoint. That’s the only recommended way of customizing SharePoint. You have heard about it. Unfortunately there is no convinient way of administering them. People have their console applications or powershell scripts to add, update and delete user custom actions. It works but it is hard to open up Visual Studio or PowerShell every time you will try out an idea on a test site. To overcome this, I have created a tiny little tool, packaged as a bookmarklet for your browser. When you click on it, it will show your existing user custom actions and you can add new user custom actions. It is an ongoing little project, available on github, contributions are welcome. What’s left is:
Copy SharePoint WebDav Address to Clipboard
While configuring SharePoint sites and helping users I often use File Explorer View for editing pages, resources like css and javascript. In IE there is a dedicated button in the ribbon for that. Sometimes it works, sometimes it doesn’t, because of permissions or other restrictions. Anyway, I use Firefox and Chrome while troubleshooting and developing, so I have created a bookmarklet for copying the webdav address of a site that is open in the browser. [source language=“javascript”] var uri = _spPageContextInfo.webAbsoluteUrl.replace(/https?:\/\//i, “\\\\”).replace(/\//g, “\\”); window.prompt(“Copy to clipboard: Ctrl+C, Enter”, uri); [/source] Unfortunately, there is no copy function in javascript, the prompt solution plus Ctrl-C works fine. The bookmarklet: [source language=“html”] javascript:void%20function(){var%20o=_spPageContextInfo.webAbsoluteUrl.replace(/https%3F:\/\//i,%22\\\\%22).replace(/\//g,%22\\%22);window.prompt(%22Copy%20to%20clipboard:%20Ctrl+C,%20Enter%22,o)}(); [/source] Enjoy
Export Any Web Part using a Bookmarklet
My blog post about exporting any webpart from a SharePoint Page is one of the most read articles on my blog. I use this method a lot. Now what I want to do is to simplify the process. Inspired by my colleague Dan Saedén’s awesome bookmarklet for reading and updating web properties, I decided to make my own bookmarklet. That was easy. Now we can export any web part from any SharePoint page without even looking at any ids in the html markup and assembling the export url manually. Just add the bookmarklet or run the javascript code in the browser console. The code (js and bookmarklet) is on Github. Here is an animated gif that explains how to use it:
Bypass all custom jslink
Client Side Rendering (CSR) and jslink are great for customizing lists and forms in SharePoint. In my current project we use it a lot of it. A disadvantage of that path, although, is that it might occur javascript errors, during the development phase, but also in production. We do, of course, our best to leverage the best jslink code, but unfortunately we have to live with the fact that errors can occur, especially when we use it for NewForm, EditForm, DisplayForm and View (in list and grid). If an error occurs, it won’t stop the rest of javascript (it is wrapped in try and catch by SharePoint), but the fields will still not function as intended. It can also be some “corrupt” or old data in the field value that will “break” the jslink code. I would like to suggest one little fix, an idea I’ve come up to in my jslink-heavy project:
Client Side Rendering with Async dependencies
Yesterday I asked a question on SharePoint StackExchange:
I also asked Elio Struyf on Twitter: https://twitter.com/eliostruyf/status/540473976255152128 Good idea, Elio Struyf! Now I want to try it out.
Preparations
In this case I’ll be using my example from my blog post yesterday: Drag and Drop Image using Client Side Rendering I have created a new list and added a lookup field to my previous list. What I get is a Title of the lookup item, but not my custom field called DragAndDrop. In my test I will try to load the DragAndDrop Image using an ajax call and rendering it after Client Side Rendering is done with my item. To be complete, I want to show some screenshots for my lookup field: It will result in this OOTB rendering:
Drag and Drop Image using Client Side Rendering
I continue my series about Client Side Rendering (CSR) and jsgrid. Today I want to try a custom field where users can drag and drop images. The inspiration comes from:
- AutoUpload field written by Anton Vishnyakov and
- Base64 Drag and drop written by oroboto
What I want to achieve is:
- A custom field that is rendered with jslink
- Users can drag and drop small pictures (thumbnails) into the field
- A base64 image representation is saved as the field value
- Optionally implement pasting images using Clipboard API
Step 1 Create a field with a custom jslink
Create a field of type Note. I am using the PnP Core Extensions to make it quickier: ’ My jslink file is very simple to begin with: [code language=“javascript”] (function () { ‘use strict’; function view(ctx, field) { return “hello”; } var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘DragAndDropImage’: { ‘View’: view, ‘DisplayForm’: view //‘EditForm’: verySimpleNewAndEdit, //‘NewForm’: verySimpleNewAndEdit } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] This will result in the following display form. Just outputting “hello” indicates that my field is jslink are registered correctly:
Disabling a column in Quick Edit
In my project I have a column called Request Status. This column is not shown in any forms, meaning users should not edit, because it is controlled through the app. Nevertheless it is editable in the Quick Edit. Yesterday I wrote about jsgrid in my blog. Now comes more. Today I’ll share a little practical solution how one can disable editing a field in Quick Edit. The field is edited in jsgrid, but to disable it, we only have set the property called AllowGridEditing to false on our column (not even touching the heavy jsgrid api). We can do in the OnPreRender event in our Client Side Rendering (CSR) registration. Having the context object we have access to the Fields (ContextInfo.ListSchema.Field): [code language=“javascript” highlight=“6,9”] (function () { var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.OnPreRender = function(ctx) { var statusField = ctx.ListSchema.Field.filter(function(f) { return f.Name === ‘Request_x0020_Status’; }); if (statusField) { statusField[0].AllowGridEditing = false; } } SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] Another way is to implement the display form: [code language=“javascript”] (function () { var view = function (ctx, field) { if (ctx.inGridMode) { field.AllowGridEditing = false; } return window.RenderFieldValueDefault(ctx); }; var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘Request_x0020_Status’: { ‘View’: view } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code]
JSGrid Basics
JSGrid is the javascript framework in SharePoint used in Quick Edit View (previously Datasheet View). There are a few very good blog posts on this topic (See below in “Sources”). Nevertheless the fact is that jsgrid and working with quick edit from a developer’s perspective is a huge undiscovered area. Articles I have seen are intended for advanced developers. The goal with my post today is to outline the very basics of working with JSGrid. When you know the basics you will be more comfortable to discover and try out more. The example I want to show is a jsgrid code for a “VerySimpleColumn”. The source code can be found on gist.github.com To focus on jsgrid, I assume you have knowledge and some experience of working with jslink, which is related to jsgrid.
Improving the web performance of an intranet
[caption id=“attachment_3437” align=“alignnone” width=“480”] All the “small” app parts, web parts, delegate controls, user controls, and other “packages” that “must” be delivered to the users on every page load of the Start Page of your Intranet.[/caption] Recently we made an investment to improve the performance of our intranet. We made many changes in different layers: SQL, Network, Browser upgrade and code. Here I want to tell about what code changes we did to improve the web browser performance. Please leave feedback if you find it useful. You can also share your suggestions. We measured the performance before our code changes and after them. We had amazing results. Unfortunately I can not share any numbers, but we improved the Time to First Byte, time to load event firing in the browser, memory consumption in the clients and, perhaps, the most important, we improved the perceived performance of the Intranet, the way how users experience the speed and UI responsiveness. To do this I got many ideas of my project colleagues and branch colleagues. Here is the list of changes we’ve implemented:
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Using CAML with SharePoint REST API
Do you prefer REST over CSOM as I do? I’ll skip the whys. Andrew Connell put it already in wrtiting so nicely. Well, if you do prefer REST, then you must have discovered some shortcomings of REST, or its incompleteness compared to CSOM. I think of:
- Inability to filter items based on multivalued taxonomy fields
- Inability to filter items based on user fields where user is added through a group, rather than directly, e.g. AssignedTo=[Me] combined with a SharePoint group.
- …
In such situations I was forced to use CSOM. Until yesterday. Yesterday I learned that we can actually use CAML queries in REST requests. This enables using REST in all situations. The REST API is still developed and many features are added. Maybe a particular operation that needs a CAML query today, can be supported in the core REST API and can be easily refactored then. But until then, we can use CAML queries in REST requests. Here are the important things about it:
Pragmatic Responsive Design
I have been curious about the responsive design but have not had time to try it out. To learn more I decided to make an existing website more responsive. A friend of mine drives a Chuvash Dictionary website: samah.chv.su. Today it looks like this in a mobile browser: The site is a classic 1000px-ish centered page with header and two columns. The left column is for the main content and the right column for additional “aside” information. Can it be more classic? This current version works, you can still use the dictionary on a mobile phone. But there are several improvements that can be done:
Count lines of code with PowerShell
Today I got a question:
How many lines of code are there in our SharePoint solution?
After a little search, I found that PowerShell is really a nice tool to count lines of code:
I wanted to count lines for different types of code:
- Code Behind written in C#, the files have .cs file extension
- JavaScript code (except jQuery, angular or knockout frameworks)
- PowerShell files (.ps1 and psm1)
- Xml files (all the SharePoint .xml files)
Here is the powershell code that counts lines of code: [code language=“powershell”] # go to the solution folder cd #count lines in .cs files ls -include *.cs -recurse | select-string . | measure | select count #count lines in our .js files ls -include *.js -recurse ` -exclude *min.js, jquery*, _*, jsrender*, CamlBuilder*, knockout* ` | select-string . ` | measure ` | select Count #count lines in our powershell scripts ls -include *.xml -recurse | select-string . | measure | select count #count lines in our powershell scripts ls -include *.ps1, *.psm1 -recurse | select-string . | measure | select count [/code] Just a curious fact, I can’t tell you how many lines of code we have in our solution, but I can reveal the proportions. If I used the flexible box model in css3, it would look like this: There are as many lines of code written in javascript as it is in C#. The main reason that for the big js code base are the SharePoint hosted apps. The PowerShell scripts are as big the javascript code base. Xml files are 4 times bigger than C# code, and it is even bigger than the sum of all lines of code written in C#, JavaScript and PowerShell. It isn’t strange that xml is dominating, almost everything in SharePoint is defined in xml. Fortunately, there are less cases where you have to write raw xml in Visual Studio 2012/2013 and SharePoint 2013. How does it look in your project? What language is dominating in your SharePoint project?
Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)
I have had a strange bug. The comment text box in a OOB SharePoint 2013 blog doesn’t appear. It only says: “There are no comments for this post.” In this blog post I’ll tell you how I found the bug and I’ll show you how you can temporarily bring the commenting to life. I have had luck. While it doesn’t work on the Test Environment, it does actually work on my development machine. The comments text box is rendered as an OnPostRender action in the blog comments display template. After debugging the javascript in hours and comparing the two environments, I just could confirm that displaytemplates are the same. There are two main javascript files that are involved:
Log to ULS using javascript
The more javascript code is produced in SharePoint solutions, the more need we have to log information and possible errors to a central logging place in SharePoint: ULS. This blog post is about logging to ULS from javascript. For a while ago I read a blog post:
The author @avishnyakov mentions the ability log to ULS from javascript. I want to dive deeper. [sourcecode language=“javascript”] ULS.enable = true ULSOnError(“Hello from javascript”, location.href, 0); [/sourcecode] What this function actually does, is that it calls a web service called _vti_bin/diagnostics.asmx
We can follow the function in the init.debug.js [sourcecode language=“javascript”] function ULSOnError(msg, url, line) { return ULSSendExceptionImpl(msg, url, line, ULSOnError.caller); } [/sourcecode] ULSOnError invokes ULSSendExceptionImpl: [sourcecode language=“javascript”] function ULSSendExceptionImpl(msg, url, line, oCaller) { if (Boolean(ULS) && ULS.enable) { ULS.enable = false; window.onerror = ULS.OriginalOnError; ULS.WebServiceNS = “http://schemas.microsoft.com/sharepoint/diagnostics/"; try { ULS.message = msg; if (url.indexOf(’?’) != -1) url = url.substr(0, url.indexOf(’?’)); ULS.file = url.substr(url.lastIndexOf(’/’) + 1); ULS.line = line; ULS.teamName = “”; ULS.originalFile = “”; ULS.callStack = ‘\n’ + ULSGetCallstack(oCaller) + ‘’; ULS.clientInfo = ‘\n’ + ULSGetClientInfo() + ‘’; ULSSendReport(true); } catch (e) { } } if (Boolean(ULS) && Boolean(ULS.OriginalOnError)) return ULS.OriginalOnError(msg, url, String(line)); else return false; } [/sourcecode] ULSSendExceptionImpl invokes ULSSendReport: [sourcecode language=“javascript”] function ULSSendReport(async) { ULS.request = new XMLHttpRequest(); ULS.request.onreadystatechange = ULSHandleWebServiceResponse; ULS.request.open(“POST”, ULSGetWebServiceUrl(), async); ULS.request.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”); ULS.request.setRequestHeader(“SOAPAction”, ULS.WebServiceNS + “SendClientScriptErrorReport”); ULS.request.send(’’ + ‘<soap:Envelope xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=“http://www.w3.org/2001/XMLSchema" xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/">' + ‘soap:Body’ + ‘’ + ‘’ + ULSEncodeXML(ULS.message) + ‘’ + ‘’ + ULSEncodeXML(ULS.file) + ‘’ + ‘’ + String(ULS.line) + ‘’ + ‘’ + ULSEncodeXML(ULS.callStack) + ‘’ + ‘’ + ULSEncodeXML(ULS.clientInfo) + ‘’ + ‘’ + ULSEncodeXML(ULS.teamName) + ‘’ + ‘’ + ULSEncodeXML(ULS.originalFile) + ‘’ + ‘’ + ‘</soap:Body>’ + ‘</soap:Envelope>’); } [/sourcecode]
javascript: Alert Me on a Page
Recently I needed to add an Alert Me link on Pages. Alert Me is a well known SharePoint functionality for notifying users about changes in list or list items. It is availabe in OOB SharePoint as a command in Ribbon if you go to a list view: When you click on this ribbon command, SharePoint opens a modal dialog and takes you to layouts page: SubNew.aspx. To open a modal dialog and load a page is not a rocket science. So a custom “Alert Me” link is doable. As the first step I copied the html markup from the ribbon and adjusted it a little bit. [sourcecode language=“html”] Alert Me [/sourcecode] Then the javascript code which gets the List ID and Page ID is very simple because this information is there in the magic _spPageContextInfo: [sourcecode language=“javascript”] var takana = window.takana || {}; takana.alertMe = function () { var url = String.format("{0}/{1}/SubNew.aspx?List={2}&ID={3}" , _spPageContextInfo.webAbsoluteUrl , _spPageContextInfo.layoutsUrl , encodeURI(_spPageContextInfo.pageListId) , _spPageContextInfo.pageItemId); OpenPopUpPage(url); } [/sourcecode] This code will open a modal dialog in exactly the same way as the ribbon command in OOB SharePoint and let you subscribe to changes on that page. In this code I use String.format which is available on SharePoint pages and _spPageContextInfo which has existed since SharePoint 2010 and has been extended with more useful information about the current context.
javascript: Remove illegal characters in url
Recently I needed to create valid urls for pages using javascript. Also this time I thought it must be some out-of-the-box code for that in SharePoint. The first thing I came up was the “Add page” dialog. I found that the actual dialog was in the _layouts virtual folder:
/\_layouts/15/CreatePublishingPageDialog.aspx
```Bingo, it does the validation in the client side. This is the responsible javascript function that resides directly in the page: \[sourcecode language="javascript"\] function UpdateUrl() { LoadTermContextInfo(); var hiddenPageUrlLabelExtensionClientId = "<%=hiddenPageUrlLabelExtension.ClientID%>"; var hiddenPageUrlLabelExtension = document.getElementById(hiddenPageUrlLabelExtensionClientId); var pageNamePreviewUrlLabelClientId = "<%=pageNamePreviewUrlLabel.ClientID%>"; var pageNamePreviewUrlLabel = document.getElementById(pageNamePreviewUrlLabelClientId); if( pageNamePreviewUrlLabel != null ) { var nameInputTextBoxClientId = "<%=nameInput.ClientID%>"; var nameInputTextBox = document.getElementById(nameInputTextBoxClientId); var allowSpaces = false; if( GetInnerText(hiddenPageUrlLabelExtension) != "" ) { var suggestUrlValue = ""; for (var i=0; i < nameInputTextBox.value.length; i++) { var currentChar = nameInputTextBox.value.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } UpdatePreviewUrl( suggestUrlValue ); } else { if( g\_timerId != 0 ) { window.clearTimeout(g\_timerId); } g\_timerId = window.setTimeout(OnFriendlyUrlNameChanged, 500); } } } \[/sourcecode\] This function iterates through all the characters in the page url and removes the illegal characters. The space, plus sign and the dot become a hyphen. To determine if a character is illegal, it relies on another javascript function called: `IndexOfIllegalCharInUrlLeafName`. This function can be found in the init.js or init.debug.js: \[sourcecode language="javascript"\] function IndexOfIllegalCharInUrlLeafName(strLeafName) { for (var i = 0; i < strLeafName.length; i++) { var ch = strLeafName.charCodeAt(i); if (strLeafName.charAt(i) == '.' && (i == 0 || i == strLeafName.length - 1)) return i; if (ch < 160 && (strLeafName.charAt(i) == '/' || !LegalUrlChars\[ch\])) return i; } return -1; } \[/sourcecode\] This function checks a char against an array of all characters: `LegalUrlChars` from the same file: init.js. [![ill_002](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png)](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png) To use this UpdateUrl function, we have to remove the references to the fields from the Add Page Dialog. Of course, we won't overwrite this original function, we don't want to break the SharePoint OOB functionality. Here is how my new function looks like: \[sourcecode language="javascript"\] var takana = {}; function takana.updateUrl(url) { var allowSpaces = false; if( url ) { var suggestUrlValue = ""; var length = url.length; for (var i=0; i < length; i++) { var currentChar = url.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } } } \[/sourcecode\]
#### Server Side
For those of you who want run this operation on the server, here is the code written in C#: \[sourcecode language="csharp"\] //" # % & \* : < > ? \\ / { } ~ | var illegalChars = @"\[""#%&\\\*:\\<\\>\\?\\\\\\/\\{\\}~\\|\]"; pageName = Regex.Replace(pageName, illegalChars, string.Empty); var punctuation = @"\[\\s\\.;\\+\]"; pageName = Regex.Replace(pageName, punctuation, "-"); //remove "--" pageName = Regex.Replace(pageName, @"\\-{2,}", "-"); pageName = string.Format("{0}.aspx", pageName); //do it like the built-in dialog, lower case pageName = pageName.ToLower(); \[/sourcecode\] Don't forget to leave a comment if you find this post useful.
## Comments from Wordpress.com
####
[Johannes Milling](http://discoveringsharepoint.wordpress.com "johannesmilling@hotmail.com") - <time datetime="2013-08-23 09:53:30">Aug 5, 2013</time>
Good post! :)
<hr />
The CDN concept in SharePoint
How many instances of jquery are there in your SharePoint farm? [sourcecode language=“powershell”] Get-SPWebApplication http://dev ` | Select -Expand Sites ` | Select -Expand AllWebs ` | Select -Expand Lists ` | Select -Expand Items ` | ? { $_.Url -match “jquery.*.js” } ` | select Name, Url [/sourcecode] Have you more than two (jquery and jquery-ui), then you have too much. You can save much place and performance by using Content Delivery Network (CDN) links for the resources like javascript, css, fonts and icons. Consider those Content Delivery Networks:
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
SharePoint Apps: "Provider Hosted First" Approach
Recently I had an exciting mail conversation with Thomas Deutsch. He came up with an idea how to fasten the development of apps. This smart approach is called “Provider Hosted First”. See Thomas’ original blog post. Here are some highlights: What you actually do is a local website which runs in grunt server
:
localhost:9000
```Then a SharePoint-hosted app is created with an SPAppIframe that refers to that local app site. Genious!!! Some key features of this approach:
* This local app contains a livereload script. Your sharepoint app is updated every time you save your css, js, html file in your IDE
* Grunt minifies, bundles your assets
* Grunt runs your tests automatically when your content is modified
* The SharePoint app can be on Premises, on Office 365, wherever you want it.
#### Video
\[caption id="attachment\_2808" align="alignnone" width="630"\][![See the video how it looks like to develop using this approach](https://sharepointkunskap.files.wordpress.com/2013/07/sp-app-002.png?w=630)](http://www.screenr.com/LA8H) See the video how it looks like to develop using this approach\[/caption\]
## Comments from Wordpress.com
####
[Paul Tavares](http://paultavares.wordpress.com "paultavares1@gmail.com") - <time datetime="2013-07-10 02:59:34">Jul 3, 2013</time>
This is pretty cool and very similar to my current setup for developing javascript applications for SharePoint. I use a script to "deploy" updates from my PC to the folder in a document library. I'll try this out when I get around to playing with SP2013.
<hr />
####
[Björn]( "bjorn.roberg@bool.se") - <time datetime="2013-07-02 11:07:08">Jul 2, 2013</time>
Awesome! I'm gonna try that out!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-07-02 15:31:33">Jul 2, 2013</time>
Great! When you go to Thomas Deutsch blog, you can download the source code for the solution.
<hr />
Make javascript code work with Minimal Download Strategy Part 2
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
Minimal Download Strategy (MDS) is an important feature in SharePoint 2013. It lets you download only a page delta, only changes. There is still issues with the MDS and custom scripts and almost no documentation on msdn or technet. In this blog post I want to learn more about adjusting custom scripts for MDS. As in my previous post, I want to take a real problem and try to solve it. The goal is to find a solution, not nececerilly the most optimal solution, at least for now.
Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
REST API: Add a plain text file as an attachment to a list item
SharePoint 2013 REST API has been enhanced and extended. The old _vti_bin/listdata.svc is still there, but the new api for working with lists and list items is much more and obviously a part of a bigger api: _api/web/lists Yesterday I saw an interesting question on SharePoint StackExchange:
The instructions in the MSDN resource are not so detailed, the cannot be. The guy who asked the question did as it stood in the examples. But sometimes solutions for SharePoint need some small adjustments :) Here is the simplest code to create an attachment in plain text for a list item 1 in the list called List1 in the root web. That’s it. But it works: [sourcecode language=“javascript”] var content = “Hello, this text is inside the file created with REST API”; var digest = $("#__REQUESTDIGEST").val(); var composedUrl = “/_api/web/lists/GetByTitle(‘List1’)/items(1)/AttachmentFiles/add(FileName=‘readme.txt’)”; $.ajax({ url: composedUrl, type: “POST”, data: content, headers: { “X-RequestDigest”: digest } }) [/sourcecode] This example is of course just for demonstration. It uses only hard-coded values. But it shows how simple it is to create a list item attachment using SharePoint 2013 REST API and “upload” plain text asynchronously to the server.
SharePoint Modal Dialog as AngularJS directive
It has already become a series of posts in my blog about the combination of AngularJS and SharePoint:
- AngularJS: prevent form validation in Page Edit Mode
- angular jQuery UI autocomplete
- AngularJS: sync $location.search with an input value
And it will be more. Some of them are a pure angular stuff, some of them are really for SharePoint. In this post post I’ll show how to create a directive for a sharepoint modal dialog (SP.UI.ModalDialog). There is already a modal dialog implementation in the Angular UI project, but it uses the bootstrap modal dialog. But it custom attributes for angular">is not that hard to create an own directive for showing sharepoint modal dialogs. I’ve called the new directive ng-sp-modal
(ngSpModal). Here is this: [sourcecode language=“javascript”] var ngSpModal = function() { link: function (scope, element, attrs, controller) { var dialog, defaults = { html: element.get(0), showClose: false }, getOptions = function () { var options = scope.$eval(attrs.ngSpModal); return angular.extend(defaults, options); }; fireSpModal: function (value) { if (value) { var opts = getOptions(); dialog = SP.UI.ModalDialog.showModalDialog(opts); } else { dialog && dialog.close(); } }; // Watch for changes to the directives options scope.$watch(attrs.ngShow, fireSpModal, true); } return { require: ‘?ngShow’, link: link }; }; window.myApp = angular.module(‘myApp’, [‘ui.directives’]); myApp.directive(’ngSpModal’, [ngSpModal]); [/sourcecode] The new ng-sp-modal directive depends on ng-show. When your expression or value for ng-show for your html area is true, then a sharepoint modal dialog will open. This is achieved through a $watch command. The html area which is used to create will be copied to the modal dialog. I have used it for forms. To use it, just place this directive into your html element that you want be shown in a modal dialog. Here is a simple example to achieve what it is shown in the screenshot pasted above. [sourcecode language=“html”] Here is the html markup for your modal dialog [/sourcecode] Here is the very simple angular controller to let it work: [sourcecode language=“javascript”] function someCtrl($scope) { $scope.modalOptions = { height: 100, width: 300, title: “Yeah” }; } [/sourcecode]
JavaScript Localization in SharePoint
Yesterday Waldek Mastykarz published a cool post: Globalizing JavaScript in SharePoint 2013. This is a very cool technique to localize your client code in javascript and reuse your resx files in Server Side and Client Side. This is actually not new for SharePoint 2013 despite it has become more needed with the huge client focus in the new SharePoint. I have used this in SharePoint 2010 for a long time. In my blog post: ScriptResx.ashx in SharePoint I told about that technique. What I didn’t know that you can define your javascript namespace directly in the resx file. Waldek wrote in his comment that SP.Publishing.Resources.en-US.resx automatically are SP.Publishing.Resources in javascript. That was not the case for my own localization files. A simple look at SP.Publishing.Resources.en-US.resx helped: [sourcecode language=“xml”] true SP.Publishing.Resources [/sourcecode] This results in: [sourcecode language=“javascript”] _EnsureJSNamespace(‘SP.Publishing’); [/sourcecode] So what we have to do for our custom resx file is to add classFullName resheader: [sourcecode language=“xml”] Takana.Res [/sourcecode]
AngularJS: prevent form validation in Page Edit Mode
I work on a cool project where AngularJS is used for rendering of business data in a SharePoint portal. One of the beautiful parts of AngularJS is the client validation. AngularJS understands the new html5 attributes like “required” and pattern, which makes the markup and javascript concise and semantic. Recently I ran into a problem: The SharePoint webparts which had html forms with required fields were impossible to add to a page in the web browser, neither was it possible to edit the pages with these webparts. When I clicked on “Save”, the page tried to validate and failed. The solution for this is very elegant, like much of the AngularJS. If you don’t show your angular form, it won’t validate. So just use any method to detect the edit mode on a SharePoint page. I created a helper function for that. [sourcecode language=“javascript”] function isEditMode() { var publishingEdit = window.g_disableCheckoutInEditMode, form = document.forms[MSOWebPartPageFormName], input = form.MSOLayout_InDesignMode || form._wikiPageMode; return !!(publishingEdit || (input && input.value)); } [/sourcecode] In the angular controller, just define the part of it which shouldn’t be there when you are editing a page, by using ng-hide="editMode"
: [sourcecode language=“html”] [/sourcecode] editMode
is a $scope variable in your controller. So the last thing to do is to get the editMode value by invoking the previously defined isEditMode
function: [sourcecode language=“javascript”] function PhoneCallCtrl($scope, $http) { $scope.editMode = isEditMode(); } [/sourcecode]
angular jQuery UI autocomplete
Angular JS is one of the most developed MVC frameworks in the javascript world. Angular UI is a huge UI-centric extension of AngularJS (it is more or less like jQuery UI to the jQuery). It uses much jQuery UI and Twitter Bootstrap and provides many own components like modal dialogs, maps, tooltips, masked inputs and much more. And all this is easy to implement in your code just by adding a directive: [sourcecode language=“html”][/sourcecode] Much cleaner than listening on $(document).ready, traversing the DOM and appending the datepicker in your code: [sourcecode language=“html”][/sourcecode] [sourcecode language=“javascript”]$(document).ready(function() { var input = $("#myDate"); input.datepicker(); });[/sourcecode] All this code is invoked but outside your app code.
javascript: show only a part of a long string (ellipsis)
Ellipsis (…) is a character which indicates that the content is to wide. There are many solutions to truncate the text and show an ellipsis: in javascript and css. I want to share my humble function which extends the String.prototype: [sourcecode language=“javascript”]String.prototype.ellipsize = function(maxLength) { maxLength = maxLength || 100; if (this.length <= maxLength) { return this; } var text = this.toString().replace(/[\r\n]/g, “”), max = maxLength, min = maxLength - 20, elipsized, tryExtract = function () { var regex = new RegExp("^.{" + min + “,” + max + “}\\s”), match = text.match(regex); if (match) { elipsized = match[0].replace(/\.?\s$/, ‘…’); } else { //well, there were no \s between min and max min = min - 20; tryExtract(); } }; if (min <= 0) { return text; } tryExtract(); return elipsized || text; };[/sourcecode] To use it, just call the function from a string property in your favorite templating engine: Angular, jsRender, Knockout….: [sourcecode language=“javascript”]order.description.ellipsize();[/sourcecode] This function takes an argument maxLength
(default 100 chars). It doesn’t cut your text in the middle of a word, that’s why it looks after a whitespace in range of maxLength-20 and maxLength.
Cool presentation about web performance optimization
by Chris Love [slideshare id=15218139&doc=webperformanceoptimizationformodernwebapplications-121116224847-phpapp01]
AngularJS: sync $location.search with an input value
I have used AngularJS for a while and to me this seems to be the best MVC javascript framework. Today I wanted to implement a search which uses an input and a hash query string like in google. The input value and url have to be synced like:
index.html#?term=something
To do this we have to inject $location
into our angular control. See the Angular Guide about $location. Then we have to observe both the $scope.term (which is bound to the input value) and $location.search().
Determine if Silverlight is installed (javascript)
For a while ago I needed to provide an alternative solution when Silverlight isn’t installed. I searched for javascript code for this and found this:
- A blog post about that: Piotr Puszkiewicz’s Silverlight Blog. Determining if Silverlight is installed using Javascript.
- A more advanced javascript function which can even determine the version of the Silerlight can be pulled from Silverlight.js library.
I didn’t need to determine the version of Silverlight, so I wrote a simplified js function (but it works in all browsers): [sourcecode language=“javascript”] var isSilverlightInstalled = function() { var installed = false; try { installed = !!navigator.plugins[“Silverlight Plug-In”] || !!(window.ActiveXObject && new ActiveXObject(‘AgControl.AgControl’)); } catch (e) {} return installed; };[/sourcecode] This function first checks if a Silverlight plugin is installed in almost all web browsers except IE, then if it is not it tries to create an ActiveXObject (IE) for Silverlight. If an error occurs, the function returns false and indicates that Silverlight is not available.
JSOM: Alter a column's DisplayName
Here is another article in my JSOM series. For one month ago I showed how to alter a column’s ShowInDisplayForm property with JSOM. This time I’ll show a code sample for changing a column’s (field’s) display name. If you want to alter the displayname with Server Object Model, grab the code in the sharepoint.stackexchange.com: Change Field’s DisplayName in a List. [sourcecode language=“javascript”]var ctx = SP.ClientContext.get_current(), //SP.ClientContext field = ctx.get_web() //SP.Web .get_lists() //SP.ListCollection .getByTitle(‘MyList’) //SP.List .get_fields() //SP.FieldCollection .getByInternalNameOrTitle(“Body”); //SP.Field ctx.load(field, “Title”); //load only Title ctx.executeQueryAsync(function() { field.set_title(“Beskrivning”); field.update(); ctx.executeQueryAsync(); });[/sourcecode]
Delete all list items with jsom
Today I needed to “clean” a list, meaning to remove all list items. For some time ago I wrote a post about different ways of removing list items in bulk: Server Object Model, SPLinq and RPC. This time I had only the web browser. So I tried the jsom way. By the way, the javascript documentation for jsom on msdn is getting really good. Don’t miss that: How to: Complete basic operations using JavaScript library code in SharePoint 2013. Now here comes theworking code I used to remove all items in my list:
TypeScript in SharePoint
By now TypeScript shouldn’t be something one has to introduce.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
If you haven’t already done it, go and see the intro video for TypeScript, check out a tutorial and visit the typescript playground. There are other javascript libraries which extend javascript and are compatible/compile to javascript: Dart and CoffeeScript. To be honest I had never time to try those. The fact that TypeScript is well integrated into Visual Studio which I happen to work within all the days (intellisense, compilation checks and more) did me curious. This post is actually not about TypeScript itself, but a test to use it in SharePoint. In this short “lab” I even had Web Essentials 2012 which automatically compile typescript files into plain javascript files on save. This is what I did: Install TypeScript and Web Essentials 2012 Create a SharePoint-hosted app: Create a new TypeScript file in the autogenerated “Scripts”-module and call it “Greeter.ts” Just save the file as it is. The new file is created: Greeter.js Now we don’t need to copy this file to the app, so remove Greeter.ts from the Elements.xml file (or comment it out): Open the Default.aspx from the Pages module and add the reference to the new javascript file:
GeoLocation Field in SharePoint 2013
In SharePoint 2013 Preview there is a new type of field: GeoLocation which is, like the old SPUrlField, a pair of values. The geolocation is described as longitude and latitude. Unfortunately you can’t add this field in list settings. You have to create this in code. In the provided link you can find the code C# code which uses the Client Object Model. In another link you can find an example how to create the geolocation file using Server Object Model (in FeatureActivated EventReceiver). If you know me, you might already know that I will propose a JavaScript solution. Here is the code to create a geolocation field in an existing list using JSOM:
Callouts in SharePoint 2013 Preview
While ModalDialog is not default for editing list items in SharePoint 2013 Preview, there is a new “popup” element in SharePoint - callout or popover. I would like to recommend these two blogs when you want discover more: Andrey Markeev: Callouts (popovers) в SharePoint 2013 Preview (in Russian) Alex Boev: a three part series: 1. Custom Callouts in the SharePoint 2013 Metro UI: Part 1: Basics 2. Custom Callouts in the SharePoint 2013 Metro UI, Part 2: Actions 3. Custom Callouts in the SharePoint 2013 Metro UI, Part 3: CalloutManager To get introduced with callouts in SharePoint 2013, you can run this code (from Andrey Markeev’s blog):
Masked Inputs
Just a quick tip today. If you are looking after masked inputs like the old ASP.NET Ajax Control Toolkit MaskedEdit, you can try jQuery plugin called Masked Input from DigitalBush or even better jquery.inputmask.
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
Simplify js and css development with Web Essentials (Visual Studio Extension)
If you develop much javascript and css, this is the exension to Visual Studio you just can’t live without: Web Essentials (It is even released for VS2012). You can do many things with it. Here are two examples for simple but very useful functions: 1. Show which browsers support a css attribute: 2. Collapse javascript functions and create #region areas like in C# code: There is much more, like less and coffeescript parsing. Just check the documentation. And it is fully appliable in SharePoint development.
Toastr.js and SharePoint
Have you used SharePoint javascript Notifications (SP.UI.Notify)? Are you looking for something new and fresh? Well then check out the Toastr.js - a simple, beautiful, fully responsive and light-weight javascript lib for notifications, developed by John Papa and Hans Fjällemark and released under the MIT License. By the way, toastr was one of many things I discovered and learned on John Papa’s online course by pluralsight: Single Page Apps with HTML5, Web API, Knockout and jQuery. It is a really awesome course, where you learn how to create an amazing SPA. Well, how’s about SharePoint. While whatching the course videos about toastr, I thought: Can we use it in SharePoint? Yes we can! Just load the toastr css and js and start using it:
Multiple events listeners in jQuery
Maybe it is not so often we face this situation where we one event handler for different events in javascript. But in my project I use many custom events and in some situations it is the same handler which listens to different events. What I found you can define multiple event listeners at the same time.
function myClick() { console.log("tada"); }
$(".selector").on({
"click mouseover": myClick
});
JSOM: Alter a column's ShowInDisplayForm property
When you create a content type, you can define if your fields will be shown in DisplayForm, EditForm, NewForm. You can hide or show them, just as Yaroslav Pentsarsky says. If your list is already provisioned, you can change them with Server Object Model, why not in PowerShell: Technet: Setting ShowInDisplayForm, ShowInEditForm, ShowInNewForm properties with powershell. If you don’t have access to the server, then the same can be done with JSOM. Here is the code:
JSOM: Last Modified Date of a List
The data transfer between server and client can heavily affect the performance. One of the measures to reduce the amount data transferred from the server to the client is storing data on the client. In many modern browsers we can use html5 localStorage. Even in older browsers there are ways to store data. I would recommend a nice js lib called amplify.js. The interface is much easier, then:
amplify.store("key", { title: "value" });
```It comes in nicely, if we have much data which we get with JSOM. But we have to care about eventual changes to list items done after we got them the last time. So we have to store the [last modified date](http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.lastitemmodifieddate.aspx). This property is also available in JSOM:
var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(“Tasks”); ctx.load(list, “LastItemModifiedDate”); ctx.executeQueryAsync( function() { var lastmodified = list.get_lastItemModifiedDate(); }, function() {} );
Using SharePoint tooltips
I found a great post about using sharepoint tooltips on Andrey Markeev’s (@amarkeev, omlin) blog: JavaScript ToolTip’ы для SharePoint. He describes how he found the standard sharepoint tooltips and how they can be reused. The best part of it his “research”. Andrey’s conclusion is to create an own, simplified javascript class which enables “sharepoint” tooltips. I modified it somewhat. I think there is no need to instantiate a TooltipManager…
var Takana = window.Takana || {};
Takana.ToolTipManager = function () {
var \_divId = "my\_tooltip";
var \_innerDivId = "my\_tooltip\_inner";
function createTitleAndDescriptionHtml(title, description) {
return String.format(
'<div>{0}</div><div>{1}</div>',
title,
description);
}
function showTooltip(element, rawHtml) {
var tooltipDiv = $get(\_divId);
if (tooltipDiv == null)
tooltipDiv = createTooltip();
$get(\_innerDivId).innerHTML = rawHtml;
displayTooltipNextToElement(tooltipDiv, element);
}
function displayTooltipNextToElement(tooltipDiv, element) {
tooltipDiv.style.display = '';
var loc = Sys.UI.DomElement.getLocation(element);
tooltipDiv.style.left = loc.x + 'px';
tooltipDiv.style.top = loc.y + element.offsetHeight + 2 + 'px';
if (tooltipDiv.curTimeout != null)
clearTimeout(tooltipDiv.curTimeout);
}
function createTooltip() {
var mainDiv = document.createElement('span')
mainDiv.id = \_divId;
mainDiv.className = 'ms-cui-tooltip';
mainDiv.style.width = 'auto';
mainDiv.style.position = 'absolute';
var bodyDiv = document.createElement('div');
bodyDiv.className = 'ms-cui-tooltip-body';
bodyDiv.style.width = 'auto';
var innerDiv = document.createElement('div');
innerDiv.id = \_innerDivId;
innerDiv.className = 'ms-cui-tooltip-glow';
innerDiv.style.width = 'auto';
bodyDiv.appendChild(innerDiv);
mainDiv.appendChild(bodyDiv);
document.body.appendChild(mainDiv);
return mainDiv;
}
function hideDiv() {
$get(\_divId).style.display = 'none';
}
var manager = {};
manager.attachToolTip = function (element, title, description) {
$addHandler(element, 'mouseover', function (e) {
showTooltip(element, createTitleAndDescriptionHtml(title, description));
});
$addHandler(element, 'mouseout', hideDiv);
}
manager.attachToolTipRaw = function (element, rawHtml) {
$addHandler(element, 'mouseover', function (e) {
showTooltip(element, rawHtml);
});
$addHandler(element, 'mouseout', hideDiv);
}
return manager;
}();
Now a manager is created on a page per default. To add a tooltip, just use the TooltipManager:
Chuvash localization of moment.js
For three months ago I added Chuvash localization of moment.js. For 16 days ago moment.js 1.7.0 was officially released which included the Chuvash translation.
Wait a sec… What is moment.js?
moment.js is the best datetime tool for javascript. It supports many languages (now even Chuvash) for displaying date and time. Another very handy functionality is showing relative time which has a simple interface: fromNow().
Here is a simple example from a web browser console:
Chuvash translation of Wikipedia Mobile
The official Wikipedia mobile app is now translated into Chuvash language and available to use:
What does Chuvash mean?
I am Chuvash. Chuvash is the name of an ethnicity which counts up to 2 milions peoply (mostly in Russia). Chuvashes talk the Chuvash language which is also an official language in Chuvash Republic (besides Russian). Chuvash language is a Turkic language and has a status “Vulnerable” in the UNESCO list of languages in danger. There is a Chuvash Wikipedia cv.wikipedia.org.
Multiple instances of javascript webparts on the same page
Javascript has become popular among many SharePoint developers thanks to easy and fast jQuery, CSOM, SPServices and many other javascript libraries. That can make solutions modern and fast. On the other hand developers should be aware of more things (some of them at Bamboo Team Blog). One of those is scoping of javascript webparts. The problem a developer has to consider: what happens if a user creates two or more instances of the same beautiful webpart on the page? Let’s go and lab :) I’ll create a solution for this lab: sp-lend-id.ikkelen. This time it will be a sandboxed solution. This solution contains a webpart:
Three ways to get the id of last created SPListItem
An interesting question came on SharePoint StackExchange: How to retrieve the guid of the last uploaded file. It is only possible in CSOM as far as I know. But if we simplify the task, how to get the id of the last item, the we can compare three ways of getting them: SPServices, jQuery + listdata.svc and CSOM.
SPServices
The most easiest way, but not available in async:
$().SPServices.SPGetLastItemId({
listName: "Documents"
});
listdata.svc
Just combine some query strings and try in the browsers address bar:
Web Application Properties as JSON
I saw an interesting question on sharepoint.stackexchange: How to access a Web application/Farm level property bag via jQuery/Javascript/ClientContext. Some time ago I tested a custom http handler, so I wanted to try a custom httphandler for this as well. It worked. Here more details: Just deploy sp-lend-id.tupsam from the solution. If you don’t have any properties in your web application, just add some:
asnp microsoft.sharepoint.powershell
$app = get-spwebapplication http://dev
$app.Properties.Add("Santa", "Claus")
$app.Properties.Add("Ded", "Moroz")
$app.Properties.Add("Hel", "Muci")
$app.Update()
Then just to test open the httphandler directly in the browser:
Using javascript objects passed from closed popup
It is not a rocket science to pass objects from child window (popup) to main window. The problem I encountered today was IE and passing complex objects. So it is just an IE issue as far as I know. The problem occurs when you pass some object (not a simple String or Number) to main window:
window.opener.takeAnObjectFromChild = {
title: "Should even be available when I close the child"
};
and you then close the child window, next time the main window tries to access the passed object:
javascript: developing for performance
Many words have been said about the importance of performance when working with javascript files. Here I want to summarize what developers can do to increase the performance related to javascript. I found many tips on blogs. Here comes my aggregated list of actions one can do to speed up sharepoint (and not only) sites with focus on javascript:
1. Load only sharepoint stuff you need
Use prefetch option to only load sharepoint javascript files that needed. To see the difference, just add ?prefetch=0
to your sharepoint url in the browser. The downside of this lazy loading is that you wrap all sharepoint related javascript into ExecuteOrDelayUntilScriptLoaded otherwise you maybe invoke some of javascript objects and functions that are not loaded. So the prize of this huge performance improvement is a high awareness by a developer when and which scripts are loaded and run.
nodeunit and SharePoint: unit tests in javascript
nodeunit is a (relatively) new test framework for javascript, mainly for node, but it can be run in a browser as well. The most popular framework for testing javascript is Qunit, but I’ll lab with it another time. I found nodeunit tests in moment.js - the best date handling framework for javascript and it worked very well. So first of all, why should we test? The best answer is actually: Life is to short for manual testing (it was actually the slogan at the Google London Test Automation Conference 2007.
$ in cmssitemanager.js conflicts with $ in jQuery
In SharePoint 2010 if CMSSiteManager.js library is loaded besides jQuery, then much of stuff stops working. The reason is that the dollar sign ($) is used in cmssitemanager.js as well which conflicts with jQuery. Mostly it appears on pages where you load jQuery and have an image library with thumbnails. To avoid this, just replace all $ with jQuery in your custom scripts. A more crazy situation is when avoiding $ isn’t enough. It is when you load jQuery to page head automatically on all pages. The Asset picker (AssetPortalBrowser.aspx) invokes $ itself and gets with jQuery in conflict without you write a single line of custom javascript code. You usually get the following error:
javascript toolkit on text file
Referencing javascript libraries from Content Delivery Networks (CDN) like jQuery can have many benefits. The self-hosted javascript files are on the other hand give you more control. But in one situation it is much better with cdns: the development. Like Marc D Anderson pointed:
I didn’t realize it at the time, but this txt file has become a standard part of my toolkit already. I’ve added it to three client environments just since last week. It’s the A #1 fastest way to get something up and running, even if you know you’re going to host the files locally later.
jQuery mobile and SharePoint
In this post I want to explore how to build a mobile app using jQuery mobile. Recently I discovered two great blog posts about this:
- Building SharePoint web apps using Sencha Touch by Luc Stakenborg
- jQuery mobile and SharePoint by Chris Quick
In my post I’ll use their findings and share some of mine thougts. I’ll focus mostly on how to get started with jQuery mobile and SharePoint. So go ahead and create your jQuery mobile app, just drag’n’drop some controls: Download it and yout get an “app.html” file and “my.css”. For now ignore my.css. app.html is something like that:
Clone javascript objects
In javascript, if we copy objects or their properties, the reference still remains and by changing the new object the old one is changed, too. To clone or do a clean copy of an object I found a very useful solution by Jan Turoň on StackOverflow:
Object.prototype.clone = function() {
if(this.cloneNode) return this.cloneNode(true);
var copy = this instanceof Array ? \[\] : {};
for(var attr in this) {
if(typeof this\[attr\] == "function" || this\[attr\]==null || !this\[attr\].clone)
copy\[attr\] = this\[attr\];
else if(this\[attr\]==this) copy\[attr\] = copy;
else copy\[attr\] = this\[attr\].clone();
}
return copy;
}
Date.prototype.clone = function() {
var copy = new Date();
copy.setTime(this.getTime());
return copy;
}
Number.prototype.clone =
Boolean.prototype.clone =
String.prototype.clone = function() {
return this;
}
clearInterval in Chrome doesn't work on window blur
If you want to reset all interval jobs when a browser tab is inactive, the best way would be to use clearInterval on window blur. But unfortunately Chrome fires window focus and window blur two times. Here is an embryo to a solution:
var M = window.M || {};
M.counter = 0;
M.focused = true;
M.tick = function() {
if (M.focused) {
console.log("tic tac " + ++M.counter);
}
};
M.start = function(e) {
console.log("starting...");
M.focused = true;
};
M.stop = function(e) {
console.log("stopping...");
M.focused = false;
};
$(window).on({
focus: M.start,
blur: M.stop
});
M.ticker = window.setInterval(M.tick, 1000);
shorthand for jQuery(document).ready
jQuery(document).ready is used very often, why not use the shorthand variant of that?
$(function() {
// Code here
});
moment.js - the best javascript tool for working with dates
Just look at moment.js. Everybody who have worked with dates in javascript are going to love it.
Comments from Wordpress.com
Justin Cooney - Mar 3, 2012
Interesting, I hadn’t heard of moment.js. I’m taking a look at the site right now; it looks to have some very handy functionality for date manipulation!
The great thing with moment.js is e.g. that one can create a date object from asp.net date format like /Date(123543534)/
Kalendae - new javascript utility for calendars
An alternative to jQuery UI datepicker is Kalendae. (MIT License). Highly customizable and no dependencies to other javascript libraries. Here is the highlights:
Kalendae is an attempt to do something that nobody has yet been able to do: make a date picker that doesn’t suck. Kalendae provides the following features:
- Fully portable, no dependencies. No jQuery, no Prototype, no MooTools; just add the script and the stylesheet and you’re good to go.
- Fully and easily skinable. The default theme uses only one image file (a mask for the previous and next buttons), everything else is styled using CSS.
- Supports all modern browsers and IE8.
- Support single day, multiple day, or day range selection.
- Configurable number of months to be displayed at once.
- Can be displayed on the page as an inline widget, or attached to one or more input fields as a popup control.
- Can be attached to any page element, not just named elements.
- Configurable blackouts, defined either as an array of dates or via a callback function
- Output selected dates in a variety of formats
- Leverages moment.js for smart and easy date parsing.
Found through daily.js
fallback for html5 placeholders
Placeholders are very handy in html5, we don’t need to fool with input values. But in SharePoint and IE we must provide fallback for placeholders if we want use them in other browsers. Here is an jQuery extension to do that:
(function ($) {
$.fn.extend({
ensurePlaceholders: function () {
var input = document.createElement('input');
var placeholderSupported = ('placeholder' in input);
if (placeholderSupported) {
return;
}
function setHints(elem) {
var $elem = $(elem);
var value = $elem.val();
if (value == "") {
var placeholder = $elem.attr("placeholder");
$elem.val(placeholder);
$elem.addClass("empty-text");
}
}
function removeHints(elem) {
var $elem = $(elem);
$elem.removeClass("empty-text");
var value = $elem.val();
var placeholder = $elem.attr("placeholder");
if (value == placeholder) {
$elem.val("");
}
}
this.find("\[placeholder\]").each(function() {
setHints(this);
});
this.on("focus", "\[placeholder\]", function(e) {
removeHints(this);
});
this.on("blur", "\[placeholder\]", function(e) {
setHints(this);
});
}
});
})(jQuery);
```Then "ensure placeholders" by running this function on a wrapper element which contains fields with the placeholder attribute:
jQuery("#form-wrapper").ensurePlaceholders();
SP.UI.Notify in Modal Dialog
If you open a custom page (not a list item form) in a modal dialog, your notification won’t be shown. The reason is that the notification area (#notificationArea) is inside a hidden div (#s4-ribbonrow). To show this notificationArea we must display the notification area:
var $ribbon = jQuery("#s4-ribbonrow");
if ($ribbon.is(":hidden")) {
$ribbon.css({"min-height": 0, "height": "0px"})
.show().children().hide()
.filter("#notificationArea").show()
}
Comments from Wordpress.com
Jens Malmberg - Jan 3, 2013
private variables in javascript
Found a nice post about private variables and “methods” in javascript. Consider this example:
function Pizza() {
var price = 0;
this.setPrice = function(p) {
price = p;
};
this.getPrice = function() {
return price;
};
}
```Every variable and function inside the main function is private unless it is appended to "this".
javascript: Umbrella pattern
There are two great patterns for organizing javascript code: Prototype and Module pattern. More about them later in this post. But in reality I still see much of spagghetti Just an example: SharePoint 101 code samples. They are indeed very simple and isolated examples. And many projects use this simple way in mind when they begin. But when javascript code grows, it becomes a monster. Have you seen this biest? How is this monster created? Through good intentions (like everything else) in form of KISS mantra, to little time and the “commit and run”-behavior, or the worst: “I am c#-er, not Front-End-Developer”-spirit. In this post I’ll introduce a kind of compromise the Umbrella pattern. But before that, let’s see how to recognize the spagghetti monster in javascript:
Hello world in node.js
I know, node.js has been present for a while. But I actually had no time to try it. I was surprised that now it is very straight forward to start with node.js. Allright, everything begins with Hello world. Eventhough it is available for allmost all combinations of operating systems and servers, the easiest way to test it was actually Ubuntu. To install just run:
sudo apt-get install nodejs
```Then make a new directory and create the hello.js:
mkdir hello cd hello vi hello.js
New functions in jQuery 1.7+ on and off
A simpler interface for event handling in jQuery. Just read Dan Wahlin’s blog.
cross browser console.log
console.log
is the best tool for debugging javascript. In Firefox Firebug and Chrome Dev Tools you can even log objects which are represented as tree nodes of properties. If Firebug or Dev Tools in Chrome and IE9 are not opened, all these messages are ignored. But IE8 doesn’t understand console (if Dev Tools are closed) and raises an error: To avoid these errors, just declare an empty function just for IE8–:
javascript: passing arguments from popup to main window
To show a popup, we just have to invoke “window.open”, and provide some options to prevent opening this in a new tab:
var wnd = window.open('', '\_blank', 'width=750, height=400, location=no, resizable=1, menubar=0, scrollbars=0');
wnd.document.write('');
wnd.document.close(); wnd.document.close(); wnd.focus();
To communicate between parent and child we can refer to parent as window.opener. We can even invoke a function from parent window. Let’s create the most useful function:
javascript: serialize as xml
Why should we need to serialize javascript objects as XML. I don’t know. It is of course more a server side need. And there actually a need for javascript serialization as xml in node.js. To serialize as json is very simple: JSON.stringify(myobjects). I was just curious if there was a tool for xml serialization in javascript. There is a nice javascript tool called XMLWriter, developed by Ariel Flesler. Consider you have articles and want to serialize them as xml, let’s create a function for serializing:
Enable Save in IE9 mode
Wouldn’t it be nice to use html5 and css3 in SharePoint? No problems, there is actually v5 master out there, created by Kyle Schaefer. Or just use h5ml5 and css3 right away in your webparts and pages. But there is a big problem. It doesn’t work in IE9–. One of the issues (even listed by Kyle) is that “save” doesn’t work in modal dialogs where Rich Text Editor is used. Especialy it is for modal dialogs. The problem is not IE9, neither html5 and css3. After some digging in javascript code which is shipped with SharePoint I found out that the problem is some legacy javascript code which is not supported by IE9 but in IE8– (and compatibility mode). When we set IE9 mode in IE9 Dev Tools (F12) and go to Tasks list and try to create a task, we’ll get an error: It is RTE_GetEditorIFrame from init.js:
$().SPServices is best for SOAP
SPServices is a great tool, really nice work, Marc Anderson (@sympmarc). It has been there all the time I have developed for SharePoint. But the fact that you work with XML and you must parse the attributes (!) was the reason why I prefered listdata.svc and Client Object Model, where you get objects in JSON or you have a nice API to get objects and their properties. But there is an area where SPServices are really the best tool: SharePoint Web Services which only understand SOAP like SocialDataService.asmx.
$ and jQuery in SharePoint
Do you still use $ for jQuery? Well, don’t. If your code with $ resides with a SharePoint Images webpart, it will stop working. You’ll get errors like
Uncaught TypeError: Cannot call method 'empty' of null
The reason is that SharePoint uses $ in its own javascript code: CMSSiteManager.js
function $()
{ULSjlC:;
var elements=new Array();
for (var i=0; i < arguments.length; i++)
{
var element=arguments\[i\];
if (typeof element=='string')
element=document.getElementById(element);
if (arguments.length==1) return element;
elements.push(element);
}
return elements;
}
onchange isn't firing in IE
I don’t know why, but (not always, just sometimes) IE doesn’t fire the onchange event (which is added as an attribute on an html element). A better “workaround” is to add an eventlistener in javascript. Or a lazy workaround is to use the onclick event even for checkboxes.
ScriptResx.ashx in SharePoint
In my previous post I showed a little proof-of-concept for an httphandler which I want to use to dynamically get the localization resources from SharePoint as javascript object. But wait a moment. How does SharePoint handle localization on client? When you look in Script tab in Chrome dev tools, you’ll find:
ScriptResource.axd
It is added to the server when deployed. See a good introduction to WebResource.axd and ScriptResource.axd by Brian Chavez.
Custom HttpHandler in SharePoint for getting dynamic javascript code
Sometimes I want to add some dynamic javascript code. E.g. I had an idea to get javascript code for localization dynamically. Kirk Evan provides a very clean approach to add ASP.NET HttpHandler to SharePoint. This is just a little lab: Create a SharePoint empty project. I call it Jerkelle. Create a class called Resx2JsHandler and implement the IHttpHandler interface Add the mapped folder Layouts and create Jerkelle.ashx file Here is the project. I probably will publish it on my github account: The Jerkelle.ashx file is very simple, it references to the code file (Resx2JsHandler.cs):
XMLHttpRequest the hard way
$.ajax is great, it hides much of the complexity. But sometimes we need to work with “raw” javascript :) So let’s look behind the scenes. The XMLHttpRequest (or just XHR) is used to open a connection to a server without a page reload. Internet Explorer calls it ActiveXObject and it differs in IE versions. Wikipedia article gives a good example how to create one constructor for all browsers: [sourcecode language=“javascript”]if (typeof XMLHttpRequest == “undefined”) XMLHttpRequest = function () { try { return new ActiveXObject(“Msxml2.XMLHTTP.6.0”); } catch (e) {} try { return new ActiveXObject(“Msxml2.XMLHTTP.3.0”); } catch (e) {} try { return new ActiveXObject(“Microsoft.XMLHTTP”); } catch (e) {} //Microsoft.XMLHTTP points to Msxml2.XMLHTTP and is redundant throw new Error(“This browser does not support XMLHttpRequest.”); };[/sourcecode] The remainder is more or less the same among the browsers. We open a connection defining the HTTP verb, URI and async mode (true or false): [sourcecode language=“javascript”]var xhr = new XMLHttpRequest(); xhr.open(“GET”, “/_vti_bin/listdata.svc”, true); xhr.onreadystatechange = onStateChange; xhr.send(null);[/sourcecode] Pay attention to onreadystatechange (only lower case letters). If we choose async=false, the UI waits for the response which is not so kind to users, but maybe it is easier to write a program. Well, there is actually no option but to have async=true. To provide the callback for success and error we can write the responding function onreadystatechange. This function will be called every time the state is changed. There are 5 states:
Loading notification
When you load some data with ajax, you will probably want to show the users in some way, that data is loading. To show the text “loading…” would be enough. Another, very common way to do it to show a spinner, a rotating image. In sharepoint we can use the built-in gif which can be found in /_layouts/images/loading16.gif. Well, it is actually not so good, because this image is not so beautiful. A better way is to create your own gif image which is exactly suited for our needs. Or even better: don’t use any images. Use the light-weight javascript library called spin.js for creating spinners. It is fully customizable, compatible with older browsers. You can customize it interactively on the spin.js homepage.
javascript trim()
String.trim() is quite useful in many situations. Unfortunately not all browsers have this function on String prototype (e.g. IE8): I see many people use jQuery.trim(), but isn’t it better to just use String.trim and provide a backup function if it is not implemented, like we did with Date.toISOString:
if(!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^\\s+|\\s+$/g, "");
}
}
```EDIT: [found this solution on SO](http://stackoverflow.com/a/8522376/632117). Did we think the same?
Push a copy of Resources to client in javascript
In one of my previous posts I told about pushing a copy of an object into client. Now I’ll try to copy my resource values into client. The problem is often that we must create multiple localization resources: first as resx-file. If we use much ajax and client side rendering, we must provide some localization there, too. If they are different subsets of localization resources, it isn’t a problem. But when you get overlapping, it becomes more difficult to manage and sync them. See how Microsoft Ajax Library provides some strings: What if we just copy the values from resx file into client? If there are not business constraint it can make the development much easier. Let’s try it. For that we need Reflection. We start with changing the access modifiers on resx file to public: Then we must get all static properties of the auto-generated class (ResXFileCodeGenerator):
Simple select unselect all
I have a simple html table, every row in tbody has a checkbox. thead has a checkbox. When it is checked/unchecked, all checkboxes have to be selected/ unselected. Here is a very simple javascript to achieve this:
$("#mytable thead :checkbox").live({
change: function () {
var checked = $(this).is(":checked");
$("#mytable tbody :checkbox").attr("checked", checked);
}
});
Nested templates in jQuery.tmpl
I have used jQuery tmpl for a while and it is really awesome. Now I want to use some nested templates. And the thing is: it is very simple to do it: Here is the code to achieve this:
<div onclick="doo()">test</div>
<div id="container"></div>
<script id="parent-template" type="text/html">
<li>
{{tmpl t }}
</li>
</script>
<script id="red" type="text/html">
<span style="color:red">{{= title}}</span>
</script>
<script id="green" type="text/html">
<span style="color:green">{{= title}}</span>
</script>
<script type="text/javascript">
var d = \[\];
d.push({ title: "one", t: "red" });
d.push({ title: "two", t: "green" });
$.template("red", $("#red").template());
$.template("green", $("#green").template());
function doo() {
$("#parent-template").tmpl(d).appendTo("#container");
}
</script>
jQuery: select elements with a specific text
There are situations when you want to select only dom elements which only have a specific content. jQuery provides a beautiful selector :contains:
$("a:contains(Pages)")
```But what if it isn't enough to just get all the elements which contain some word? Let's check what we get if we traverse all anchors on http://sv.wikipedia.org containing "wiki":
$(“a:contains(wiki)”).each(function(i) { console.log($(this).text()); });
[![](https://sharepointkunskap.files.wordpress.com/2012/02/jquery-contains-wiki.png "jquery-contains-wiki")](https://sharepointkunskap.files.wordpress.com/2012/02/jquery-contains-wiki.png) There is another, a generic way, to filter out elements, and it is called "filter". So a little regex check will do the trick.
$(“a”).filter(function() { return /look_for/i.test($(this).text()); }
Parameterize a javascript object and create url
If you want to add some parameters to an url which you want to open, you can use jQuery.param function:
var url = "some\_url";
var params = {
name: "Setner",
email: "setner@narspi.name",
mobile: "123456789"
};
var search = "?" + $.param(p);
url += search;
```It is handy, indeed. In an environment without jQuery (are there some?:) ) you can just iterate an object and join properties:
var url = “some_url”; var params = { name: “Setner”, email: “setner@narspi.name”, mobile: “123456789” }; if (url.match("/\?/g") == null) { url += “?”; } else { url += “&”; } var search = “”; for(var p in params) { search += [p, params[p]].join("="); } url += search;
Save an excel sheet as a clean table
To save an excel sheet as a html table is very easy. Just select the needed area, then go to Save as and check the selection and choose html as output format. It works fine. It even looks like it did in Excel. But what if you don’t want all this junk, you want only the plain html table (e.g. for pasting into WP). When I saved my permission levels to html, I used this javascript code. First open the html page which Excel has created in Chrome, open the Dev Tools console, load the latest jQuery into the page, and remove all unnecessary attributes and styling, remove the comments, after that you can just copy the outerHTML of the table and paste into a text editor:
Datetime in ASP.NET javascript and $.ajax
In one of my previous blogs I wrote about serializing of javascript objects. You can do it with JSON.stringify or Sys.Serialization.JavaScriptSerializer.serialize. Both methods work fine… almost. There is a big difference when it comes to datetime objects. MS treats dates a little bit different (like RegEx and much more). Let’s try this one:
var writer = { name: "Ajgi", birthdate: new Date(1934, 8-1, 21) };
var json = JSON.stringify(writer);
var msjson = Sys.Serialization.JavaScriptSerializer.serialize(writer);
What happens if we try to parse back msjson with JSON.parse: Well, the date isn’t a valid date anymore. How can we improve it. Rick Strahl gives a solution with custom functions for serializing and deserializing of ms date. But the thing is: we don’t need any custom functions for this, not if you run ASP.NET. The only thing we need is to use serialize and deserialize functions from Sys.Serialization.JavascriptSerializer namespace which you get automatically when you add ScriptManager in ASP.NET (and you get it even automagically in SharePoint). But what about $.ajax and functions I wrote about for retrieving list items and populating them, and updating list items with listdata.svc? Well, there comes the really nice tip from Rick Strahl: not to force $.ajax to parse the response. So instead of dataType: “json”, use the plain dataType: “text”. As the result we’ll get just a text, which we, of course, will deserialize with the native code for Microsoft:…. Use text when possible. When you define json as response format:
Simple stopwatch in javascript
If some javascript code takes too much time to execute, you probably want to see what time your code or a part of the code takes to run. I found an idea in Dave Cranes Ajax in Action. The book is a little bit old and the code provided below has been changed and simplified:
var stopwatch = {};
stopwatch.watches = \[\];
stopwatch.getWatch = function(id, startNow) {
var watch = stopwatch.watches\[id\];
if (!watch) {
watch = new stopwatch.StopWatch(id);
}
if (startNow) {
watch.start();
}
return watch;
};
stopwatch.StopWatch = function (id) {
this.id = id;
stopwatch.watches\[id\] = this;
this.events = \[\];
this.total = 0;
this.count = 0;
};
stopwatch.StopWatch.prototype.start = function() {
this.current = new stopwatch.TimedEvent();
};
stopwatch.StopWatch.prototype.stop = function() {
if (this.current) {
this.current.stop();
this.events.push(this.current);
this.count++;
this.total += this.current.duration;
this.current = null;
}
};
stopwatch.TimedEvent = function () {
this.start = new Date();
this.duration = 0;
};
stopwatch.TimedEvent.prototype.stop = function() {
var stop = new Date();
this.duration = stop - this.start;
};
Get url parameters with javascript
There is a question in Stackoverflow and this one, too. There is a fine solution for jQuery. The only thing we need is window.location.search. Say we have http://domain.com?q=hello&a=good#home, then it takes only ?q=hello&a=good, and leaves #home and the main url. Anchors can be retrieved with hash. Here are all properties of window.location: Google Chrome provides a fine function: window.location.getParameter: I like the name of this function. So why not to use it or create this one if a browser doesn’t have it? Well here we go:
Reload page in js: RefreshPage
There are many ways to reload / refresh a page in javascript. One of them is as in discoveringsharepoint.wordpress.com describes:
window.location.reload()
```Today I found some tools which are shipped with ASP.NET/SharePoint to reload a page. The big advantage of them they are designed to work with SharePoint and take all possible aspects of page life cycle into account. The javascript function to refresh a page is just called, guess..: **RefreshPage** and it resides in init.js:
//init.js: function RefreshPageTo(evt, url, bForceSubmit) {ULSA13:; CoreInvoke(’_RefreshPageTo’, evt, url, bForceSubmit); }
Run javascript code except it is inside a modal dialog
Want to run some javascript code everywhere, but not in a modal dialog. Because errors are occured, or this code is unnecessary i dialogs. Well here is a solution I have found after some experiments:
$(document).ready(function() {
if (!window.location.href.match(/isdlg=1/i)) {
onDocumentReadyExceptItIsInDialog();
}
});
function onDocumentReadyExceptItIsInDialog() {}
```This code checks with Regular Expressions if the url of the parent window contains IsDlg=1, if so nothing happens. In the usual case (not inside a dialog), the javascript code runs. EDIT: after I wrote this I actually found that this is the way SharePoint itself does: [![](https://sharepointkunskap.files.wordpress.com/2012/01/isdlg.png "isdlg")](https://sharepointkunskap.files.wordpress.com/2012/01/isdlg.png) So now I update the previous function to this:
$(document).ready(function() { if (window.location.search.match(/[?&]isdlg=1/i)) { return; } onDocumentReadyExceptItIsInDialog(); });
Simplifying jQuery tmpl interface
In one of my previous posts I showed a simple example how to retrieve data from a web service and render it with jQuery tmpl. To render this I used an id for a template and the container:
<script id="contactTemplate" type="text/html">
<div>
Name: {{= Name }} <br>
Phone: {{= Phone }}
</div>
</script>
<div id="contactContainer"></div>
```To render we select the template and container with jQuery selectors:
function onSuccess(data) { $("#contactTemplate").tmpl(data.d.results).appendTo("#contactContainer"); }
(function ($, undefined) { if ($ === undefined) { throw “Dependency: jQuery is not defined. Please check javascript imports.”; } $.extend($.expr[’:’], { // :template(name) template: function (current, index, metadata, elements) { var arg = metadata[3], d = $(current).data(“template-for”); if (d === undefined) { return false; } return arg ? arg === d : true; }, // :container(name) container: function (current, index, metadata, elements) { var arg = metadata[3], d = $(current).data(“container-for”); if (d === undefined) { return false; } return arg ? arg === d : true; } }); } (jQuery));
listdata.svc vs CSOM for retrieving and manipulation of list items
What is better and where and when… I’ll try to find out.. This post will be updated soon. Take a look at this so far: http://sharepoint.stackexchange.com/questions/23209/sharepoint-2010-javascript-client-object-model-cross-site-collections
String.format for javascript
sprintf is actually the best javascript implementation of sprintf (string.format). But wait, shouldn’t it be some more .NET-like stuff in SharePoint environment? Indeed there is! (Well, not only in SP, but ASP.NET) String.format(“Hello {0}”, “world”) does exactly the same thing as on server side. Wow, it opens for many opportunities, e.g. in jQuery tmpl: String.format validates arguments, and if all is OK, it invokes another function String._toFormattedString:
function String$\_toFormattedString(useLocale, args) {
var result = '';
var format = args\[0\];
for (var i=0;;) {
var open = format.indexOf('{', i);
var close = format.indexOf('}', i);
if ((open < 0) && (close < 0)) {
result += format.slice(i);
break;
}
if ((close > 0) && ((close < open) || (open < 0))) {
if (format.charAt(close + 1) !== '}') {
throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
}
result += format.slice(i, close + 1);
i = close + 2;
continue;
}
result += format.slice(i, open);
i = open + 1;
if (format.charAt(i) === '{') {
result += '{';
i++;
continue;
}
if (close < 0) throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
var brace = format.substring(i, close);
var colonIndex = brace.indexOf(':');
var argNumber = parseInt((colonIndex < 0)? brace : brace.substring(0, colonIndex), 10) + 1;
if (isNaN(argNumber)) throw Error.argument('format', Sys.Res.stringFormatInvalid);
var argFormat = (colonIndex < 0)? '' : brace.substring(colonIndex + 1);
var arg = args\[argNumber\];
if (typeof(arg) === "undefined" || arg === null) {
arg = '';
}
if (arg.toFormattedString) {
result += arg.toFormattedString(argFormat);
}
else if (useLocale && arg.localeFormat) {
result += arg.localeFormat(argFormat);
}
else if (arg.format) {
result += arg.format(argFormat);
}
else
result += arg.toString();
i = close + 1;
}
return result;
}
```By the way, take a look at summary part of String.format:
/// /// /// ///
Batch remove
To add items to a list in bulk, or remove them in bulk. Well to do that you can use SPLinq, Server Object Model and … web.ProcessBatchData, which is the most effective. I did an experiment today. I created 1000 tasks in my task list three times and removed all items in three different ways and took time. First I put 1000 items with ajax and listdata.svc:
function pad(n) {
if (n >= 10000) return n;
if (n >= 1000) return '0' + n;
if (n >= 100) return '00' + n;
if (n >= 10) return '000' + n;
return '0000' + n;
}
var s;
var counter = 0;
var title = "task "
function foo() {
counter++;
if (counter > 10000) {
window.clearInterval(s);
}
else {
var value = {};
value.title = title + pad(counter);
createNewTask(value);
}
}
s = setInterval(foo, 200);
Then I ran three different scenarios. Here is the resut for VMWare machine Windows Server 2008 R2, 4GB RAM, SharePoint 2010 SP1:
use two different versions of jQuery on the same page
jQuery is very popular. The chance that you’ll get two or more jQuery files loaded on the same page is very high. As long as it doesn’t conflict, it is fine. But what if there are differences, and another version of jQuery destroys your functionality. To solve it we can ensure that we invoke “our”, the right version of jQuery. To do so, create a pointer to your jQuery:
var myJq = jQuery.noConfict();
```So if you can, avoid invoking $ or jQuery directly. Here is the original example from [jQuery forum](http://forum.jquery.com/topic/multiple-versions-of-jquery-on-the-same-page):
this.data in jQuery tmpl
In jQuery tmpl we can render properties with {{= SomeProperty }}. Here is an example:
<script type="text/javascript">
Writer = function (firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
Writer.prototype = {
getFullName: function () {
return this.firstName + " " + this.lastName;
}
};
$(document).ready(function () {
var writers = \[\];
writers.push(new Writer("Gennady", "Ajgi"));
writers.push(new Writer("Mišši", "Şeşpĕl"));
writers.push(new Writer("Ille", "Tuktaš"));
writers.push(new Writer("Kĕştenttin", "Ivanov"));
$("#tmpl").tmpl(writers).appendTo("#writers");
});
</script>
<script id="tmpl" type="text/html">
<li>
{{= firstName }} {{= lastName }}
</li>
</script>
<div id="writers"></div>
```It will render like:
* Gennady Ajgi
* Mišši Şeşpĕl
* Ille Tuktaš
* Kĕştenttin Ivanov
But what if we want to access the object itself, not one of the properties. Say, you want to pass the object from the array into a js function as a parameter to decide how it will be rendered, or if you want show a "calculated" property. The key word is...: this.data. this.data has the current object. After it has been rendered, we can access this object with $(this).tmplItem().data.
format javascript date in ISO 8601
There is a solution in StackOverflow:
/\* use a function for the exact format desired... \*/
function ISODateString(d){
function pad(n){return n<10 ? '0'+n : n}
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'}
var d = new Date();
print(ISODateString(d)); // prints something like 2009-09-28T19:03:12Z
```But there is already a function for this: toISOString, it came with ecmascript 5. [Unfortunately, not all browsers support this](http://kangax.github.com/es5-compat-table/ "See the best comparision for ecmascript 5 support"), to solve this problem, we can provide our own prototype function for Date if it doesn't exist:
if (!Date.prototype.toISOString) { Date.prototype.toISOString = function() { function pad(n) { return n < 10 ? ‘0’ + n : n } return this.getUTCFullYear() + ‘-’ + pad(this.getUTCMonth() + 1) + ‘-’ + pad(this.getUTCDate()) + ‘T’ + pad(this.getUTCHours()) + ‘:’ + pad(this.getUTCMinutes()) + ‘:’ + pad(this.getUTCSeconds()) + ‘Z’; }; }
javascript Module pattern
Want organize your js code in a kind of namespaces, or modules, then use the module pattern. I’ll take the dummy example for getting the current anchor. Let’s look how it would be if the prototype based approach is used:
var Contoso.Utils = function() {};
Contoso.Utils.prototype = {
getCurrentAnchor: function() {
var url = window.location;
var anchor=url.hash; //anchor with the # character
var anchor2=url.hash.substring(1); //anchor without the # character
return anchor2;
}
};
var util = new Contoso.Utils();
var anchor = util.getCurrentAnchor();
```The [prototype pattern](http://weblogs.asp.net/dwahlin/archive/2011/08/01/techniques-strategies-and-patterns-for-structuring-javascript-code-the-prototype-pattern.aspx) reminds the classic object oriented programming. Now, how would it look in the module pattern:
var Contoso = Contoso || {}; Contoso.Utils = function() { //private var invokeCounter = 0; var logInvokeCounter = function() { invokeCounter++; console.log(“invoked: " + invokeCounter + " times”); } //public return { getCurrentAnchor: function() { var url = window.location; var anchor=url.hash; //anchor with the # character var anchor2=url.hash.substring(1); //anchor without the # character logInvokeCounter(); return anchor2; } } }(); var anchor = Contoso.Utils.getCurrentAnchor();
Get the current anchor in javascript
To get the current anchor, we can use hash property::
var url = window.location;
var anchor=url.hash; //anchor with the # character
var anchor2=url.hash.substring(1); //anchor without the # character
Pass arguments from/to Modal Dialog
To pass arguments from a ModalDialog is easy. Provide some buttons and invoke close function:
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, someValue);
```The first argument is result, [it is a enumeration with three alternatives](http://msdn.microsoft.com/en-us/library/ff409060.aspx): cancel, invalid and OK. The value you pass back to the main window can be a simple string, or a complex javascript object. In this example I'll create a html element which is hidden (id="modal-form" [class="s4-die"](/2011/10/14/s4-die/)):
Pass arguments to Modal Dialog and use it
In options you pass to SP.UI.ModalDialog.showModalDialog you can define args property. It can be any object with any complexity.
Get current user and handle a success callback
In my previous post I needed the accound id of the current user for posting new list items. To retrieve the id, we can push this to the client from the code behind, or get the current user using Client Object Model. To provide a more generic way we can write a js function which get the current user. But we must even provide some callback functionality, otherwise we don’t know if the operation was successful or not. Let’s be inspired by success and error properties in $.ajax:
jQuery tmplItem and no ids
tmplItem() works even without ids. To get the current data:
$(this).tmplItem().data;
```If you want to remove, just invoke the ajax and remove with [$.parents](http://api.jquery.com/parents/):
$(this).parents(“li”).remove();
##### Updating data inside tmplItems
If you want to achieve some fancy dependency tracking, consider [knockout.js](http://knockoutjs.com/). But if you just want to update the data object inside a tmplItem, just change the object and call update:
var t = $(this).tmplItem(); var obj = t.data; obj.Address = “hello avenue”; t.update();
Update list items with listdata.svc
In one of my previous posts I showed how to retrieve data from listdata.svc with jQuery $.getJSON method. Getting data is very simple, listdata.svc provides a powerful restful interface with filtering, expanding and other features. Read the best and short introduction to listdata.svc by Suneet Sharma or a more detailed and technical article about filters, functions and operators by Mike Flasko at Microsoft with short examples here. Now back to listdata.svc in the SharePoint environment. Corey Roth provides a good images and sample results. For REST the “http verbs” are very important: GET, POST, PUT, DELETE.. SharePoint RESTful interface defines these verbs like that:
The cleanest auto resize for a textarea
The cleanest way to auto-resize a textarea while typing (like wall post on Facebook) is George Papadakis solution. It uses only standard javascript and provides eventlisteners for IE (attachEvent) and other browsers (addEventListener): [sourcecode language=“javascript”] window.onload = function() { var t = document.getElementsByTagName(’textarea’)[0]; var offset= !window.opera ? (t.offsetHeight - t.clientHeight) : (t.offsetHeight + parseInt(window.getComputedStyle(t, null).getPropertyValue(‘border-top-width’))) ; var resize = function(t) { t.style.height = ‘auto’; t.style.height = (t.scrollHeight + offset ) + ‘px’; } t.addEventListener && t.addEventListener(‘input’, function(event) { resize(t); }); t[‘attachEvent’] && t.attachEvent(‘onkeyup’, function() { resize(t); }); } [/sourcecode] Other solutions are <a href=“https://github.com/padolsey/jQuery.fn.autoResize/blob/master/jquery.autoresize.js, jQuery.autogrow, elastic
javascript load callback for UpdatePanel
Using asp:UpdatePanel isn’t so easy with jQuery(document).ready() or jQuery(window).load(). The jQuery selectors can’t find elements which are not shown in the beginning. All other elements which are loaded dynamically are difficult to catch. I found a solution in forums.asp.net. A user called germanz creates an jQuery event listener AjaxReady, he uses the ASP.NET built-in PageRequestManager. If there only few usages of it it can be invoked directly from a PageRequestManager instance:
jQuery UI Datepicker
As an alternative to asp:Calendar we can use the fancy jQuery UI Datepicker:
$(document).ready(function () {
$.datepicker.setDefaults($.datepicker.regional\["sv"\]);
$("#").datepicker({
changeMonth: true,
changeYear: true,
yearRange: "-120:+0"
});
});
```I found this a much simple and best solution for an [birthdate input](http://stackoverflow.com/questions/339956/whats-the-best-ui-for-entering-date-of-birth). We can set [international options](http://stackoverflow.com/questions/1865091/jquery-datepicker-language-problem), [year range](http://stackoverflow.com/questions/269545/jquery-datepicker-years-shown), [year](http://stackoverflow.com/questions/3164898/jquery-ui-datepicker-next-and-previous-year) and [month navigation](http://jqueryui.com/demos/datepicker/dropdown-month-year.html). Other options I have tried are asp:Calendar, ajaxtoolkit:CalendarExtender and DateJs. jQuery UI is the most simple much more than datepicker and works smoothily with SharePoint.
Push a copy of an object to client
To reduce postbacks and database calls, a copy of the current object(s) can be pushed down to the client in JSON format. Say a webpart renders information about a person, another webpart shows related information which is retrieved dynamically (like web services). Instead of getting the current person from the database in the second webpart again, we can reuse the same person object from the first webpart. To do so we must provide a DataContract for the Person class:
json serializer in Sharepoint
There is a very handy JSON lib for serializing javascript objects. It is hosted on github under douglas crockford. Download json2.js and serialize with JSON.stringify function: EDIT: There is actually this function in core javascript. It exists since javascript 1.7 and ecmascript 5. So you don’t have to add anything to get this functionality:
var t = { name: "dev", city: "new york" };
JSON.stringify(t);
```There are actually built-in goodies for serializing javascript objects in [ASP.NET](http://msdn.microsoft.com/en-us/library/bb310857.aspx): Sys.Serialization.JavaScriptSerializer.serialize
var t = { name: “dev”, city: “new york” }; Sys.Serialization.JavaScriptSerializer.serialize(t);
Load Profile Image with javascript
See a great post in “Learning Sharepoint” with an example how to get a picture of user with Client Object Model and javascript.
jQuery timeago and the localization
If you have used SPUtility.TimeDeltaAsString you must know how useful it is. There is also the jQuery plugin that can perform counting of time deltas and (!) translate it. jQuery timeago is available for many languages, Swedish among others:
// Swedish
jQuery.timeago.settings.strings = {
prefixAgo: "för",
prefixFromNow: "om",
suffixAgo: "sedan",
suffixFromNow: "",
seconds: "mindre än en minut",
minute: "ungefär en minut",
minutes: "%d minuter",
hour: "ungefär en timme",
hours: "ungefär %d timmar",
day: "en dag",
days: "%d dagar",
month: "ungefär en månad",
months: "%d månader",
year: "ungefär ett år",
years: "%d år"
};
```The code is hosted on [Github](https://github.com/rmm5t/jquery-timeago). In order the time deltas to be localized in SharePoint a ScriptLink has to be used:
<SharePoint:ScriptLink ID=“timeagoLanguage” runat=“server” Language=“javascript” Name=“jquery.timeago.lang.js” Localizable=“True” LoadAfterUI=“True” OnDemand=“False” ></SharePoint:ScriptLink>
Filtering in javascript
The simplest and the best way to filter an array is to extend the Array.prototype as described here:
if (!Array.prototype.filter) {
Array.prototype.filter = function (func) {
var len = this.length;
if (typeof func != "function")
throw new TypeError();
var res = new Array();
var thisp = arguments\[1\];
for (var i = 0; i < len; i++) {
if (i in this) {
var val = this\[i\];
if (func.call(thisp, val, i, this))
res.push(val);
}
}
return res;
};
}
```Then let's filter on [titles](/2011/11/21/sorting-dates-in-javascript/ "See an example for Sorting with Titles"), which [start with](http://stackoverflow.com/questions/646628/javascript-startswith "See the solution for startsWith in javascript on Stackoverflow") "N":
function startsWithN(element, index, array) { return element.toLowerCase().indexOf(“n”) == 0; }
Extend an event in javascript
If you use jQuery, you don’t need it. But if you for some reason must use javascript you must beware of adding events. The most dangerous is window.onload. Consider this scenario:
function doSomethingGreat() {};
window.onload = doSomethingGreat;
```It works fine if you are the only person who writes window.onload handler. But on such platforms like SharePoint you can't know which events exist. And if you just write **window.onload = doSomethingGreat;** you override all other window.onload events. Again, in jQuery you have nothing to worry. jQuery(window).load(doSomethingGreat) will just add your event, not override. In this post I'll show how to extend an event handler the pure javascript way. We have to create our own function for adding event handlers. First the old events have to be temporary saved and then the new event has to be added. [Like this](http://jsfiddle.net/mirontoli/cnN6s/):
function addOnclick(elem, func) {
var old = elem.onclick;
if (typeof elem.onclick != ‘function’) {
elem.onclick = func;
} else {
elem.onclick = function () {
if (old) {
old();
}
func();
};
}
}
Sorting Dates in javascript
To sort an array in javascript, just run sort():
array = \["skåne", "blekinge", "halland"\];
array.sort();
```To [perform a more intelligent sorting](http://stackoverflow.com/questions/3859239/sort-json-by-date "See the original answer in stackoverflow") we can define our sorting logic. What if an array has objects with different properties? For example, an object has title and lastupdated. We want to sort on lastupdated. Just create a function for this with two parameters:
function custom_sort(a, b) { return new Date(a.lastUpdated).getTime() - new Date(b.lastUpdated).getTime(); }
$.getJSON, jQuery.tmpl and _vti_bin
Javascript is very fast, responsive and unburdens the cpu at the server. Here I show a little example how to use jQuery.getJSON, jQuery.tmpl (wonderful plugin for rendering repeating data, repo hosted on Github) and REST-based service listdata.svc from /_layouts/_vti_bin/ folder. For this example I created a generic list “Contacts”, added two text fields Name and Phone. Add some phone numbers and try to go to /_vti_bin/ListData.svc/Contacts If you get 404-error, install a ADO.NET Data Services v1.5 CTP2, as described at dotnetmafia. If you want to know more about how to sort and filter, skip and limit results, read more at nothingbutsharepoint. If you encounter problems, follow Michaël’s blog post and download and install Windows6.1-KB976127-v6-x64.msu (if you have Windows Server 2008 R2), or NDP35SP1-KB976126-v2-x64.exe (if you have Windows Server 2008). After installing the version of the System.Data.Services.dll file is 3.5.30729.5004 (Windows Server 2008 R2), and 3.5.30729.4466 (Windows Server 2008). Allright, the remainder is pure javascript. In order to get it working you have to run the script from the same domain, meaning you can’t run javascript to retrieve the data from a html-file from your home folder. Create a webpart and add it to your page.
Remove links to user profiles on list with javascript
Well, if you need remove links to user profiles, you can iterate all td-elements with class ms-vb-user using jQuery each function and remove a elements. Here is a little script:
$(document).ready(function() {
$(".ms-vb-user a").each(function() {
var text = $(this).text();
var span = document.createElement("span");
var user = document.createTextNode(text);
span.appendChild(user);
var parent = $(this).parent()\[0\];
parent.removeChild(this);
parent.appendChild(span);
});
});
```EDIT 2012-02-05 A much more better way to do it is [to use replaceWith in jQuery](http://stackoverflow.com/a/2409163/632117 "See a similar question and an answer on StackOverflow"):
$(".ms-vb-user a").each(function() { $(this).replaceWith(this.childNodes); });
Reset favicon cache
Favicon is one of the hardest. Ctrl-F5 doesn’t help. You can of course see the source, find the location of the favicon, click on it (if you use Firefox or Chrome), otherwise copy the url and paste it in the address bar. When you load it separately, the favicon cache is renewed. It works. But if you want to make it easier for your users, set a version to your favicon file in the masterpage:
Go back in javascript
Add link for “Go Back” in javascript (inspired by Webmasters tips):
<a href="javascript:location.href=document.referrer;">Back</a>
```If you have access to the code behind you can [do the same](http://www.beansoftware.com/ASP.NET-FAQ/Referrer-URL.aspx) with:
Request.UrlReferrer.ToString()
```If you want to go to site collection root, it is simple, too: <SharePoint:SPLinkButton runat="server" NavigateUrl="<% $SPUrl:~SiteCollection/%>">Start</SharePoint:SPLinkButton>
Auto-resize the main container in master page
If you have a master page with fixed size (perhaps in a centered layout). Here is a simplistic js-script to auto-resize:
$(window).load(function(){
$wider = false;
$pagecontainer = $("#pagecontainer");
$elementsToCareAbout = $("#ctl00\_MSO\_ContentDiv > \*, #ctl00\_MSO\_ContentDiv table")
$elementsToCareAbout.each(function(){
if($(this).width() > $pagecontainer.width())
{
$wider = true;
}
});
if ($wider) $pagecontainer.width(1200);
});
Any improvement ideas and suggestions are more than welcome.
Check if an html element is hidden using jQuery
Well, sometimes we need to calculate width and so on. In my next post I will write about how to fix auto-resize on fixed sized master pages. But now: a very nice stuff: how to check if an element is hidden or not:
$("#s4-leftpanel").is(":visible")
```It is a pure poetry. It reminds me of the beauty of [symbols in Ruby](http://rubylearning.com/satishtalim/ruby_symbols.html).
MongoDB shell, learn directly in browser
Are you also curious about NoSQL databases. Well, MongoDB is one of the most known ones. MongoDB has a javascript syntax (json), I like it. Try out the interactive shell at the mongodb site.
Quickstart on Ubuntu
To test it on Ubuntu, just install an existing apt-package:
sudo apt-get install mongodb
Good pattern for javascript files
SP.js exists in two variants in debug mode and in modified. When you develop it is better to use debug mode. When it goes to production it is better to use minified files. The same you can do with your files. Wictor Wilen explains how to do minify your custom javascript files. I think it is a good pattern to create javascript files and call them something-something**.debug.js**. Then when you are done, run the custom tools to minify them.
Show html in ModalDialog
We can use ModalDialogs to show not only pages, but some html:
var htmlElement = document.createElement('p');
var helloWorldNode = document.createTextNode('Hello world!');
htmlElement.appendChild(helloWorldNode);
var options = {
html: htmlElement,
autoSize:true,
allowMaximize:true,
title: 'Test dialog',
showClose: true,
};
var dialog = SP.UI.ModalDialog.showModalDialog(options);
Resize image with jQuery to fit the div
There are many interesting jQuery plugins for resizing and cropping of images. Among them are jrac and image scale. I have tested the latter: It works very fine
$(window).load(function() {
var $imgContainer = $("#layout-news-image");
var $newsImg = $("#layout-news-image img\[rel!='sp\_DialogLinkIgnore'\]");
$imgContainer.css("width", $imgContainer.parent().width());
if ($newsImg.length > 0) {
if ($newsImg.width() < $imgContainer.width()) {
$imgContainer.width($newsImg.width());
}
if ($newsImg.height() < $imgContainer.height()) {
$imgContainer.height($newsImg.height());
}
$newsImg.imgscale({
parent : '#layout-news-image',
center: "true",
scale: "fill"
});
}
});
```This script checks if the original image is lesser than container div and doesn't resize if it is so. **#layout-news-image img\[rel!='sp\_DialogLinkIgnore'\]** means that do not resize if there is a hidden image with rel="sp\_DialogLinkIgnore". See the [jQuery selectors](http://api.jquery.com/category/selectors/) for more info. This script can be improved by adding window resize event in javascript. I use **$(window).load** instead of the usual _$(document).ready_ because [ready-function in jQuery runs when DOM is loaded, if the page is not cached it happens before the image is loaded](http://web.enavu.com/daily-tip/daily-tip-difference-between-document-ready-and-window-load-in-jquery/). $(document).ready doesn't work.
## Comments from Wordpress.com
####
[sdfsdf](http://sdsdfsdf "sdfsdf@ssdf.sdd") - <time datetime="2012-06-28 19:28:51">Jun 4, 2012</time>
doesn't work: it's just squeeze the picture. No examples included == no possibility to check.
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-11-05 10:06:01">Nov 1, 2012</time>
Thank you Alejandro for the awesome js lib and sharing it. I will absolutely recommend it.
<hr />
####
[Alejandro Emparan (@krc_ale)](http://twitter.com/krc_ale "krc_ale@twitter.example.com") - <time datetime="2012-11-02 20:21:55">Nov 5, 2012</time>
I wrote a jQuery plugin for that: https://github.com/karacas/imgLiquid
<hr />
Show a presence bubble
There is no built-in sharepoint control for the presence bubble. If you want to add this functionality on your pages you have to add it as html. Here is a sample:
private static int \_COUNTER = 0;
private const string PresenceBubble =
"<a class='ms-imnlink' href='javascript:;'>" +
"<img width='12' height='12' id='imn\_pawn\_{0}' onload=\\"IMNRC('{1}')\\" alt='My SID' " +
"src='/\_layouts/images/imnoff.png' border='0' " +
"showofflinepawn='1' sip='{2}'></a> {3}";
private static string FormatUser(SPUser user)
{
\_COUNTER++;
return string.Format(PresenceBubble, \_COUNTER, user.Email, user.GetSipAddress(SPContext.Current.Web), user.Name);
}
less.js
Det finns ett intressant projekt som kan hjälpa att strukturera css-filer. Du skriver regler i en kombination av css och javascript. Det omvandlas med hjälp av js till css. Projektet heter less.js, läs mer om detta på sharepointoverflow.
window.onload
Sharepoint ger en annan lösning för window.onload och jQuery(document).ready(function() {}); _spBodyOnLoadFunctionNames.push(‘gerdaRibbonInit’);"
jQuery validation with asp.net
De kan var lite jobbigt att få till jQuery validate att funka ihop med aspnetForm…
$(document).ready(function () {
newsLetterForm = $("#aspnetForm");
newsLetterForm.validate({
onsubmit: false,
rules: {
"<%= emailTextBox.UniqueID %>": {
required: true,
email: true
}
}
});
$("#<%= sendButton.ClientID %>").live("click", function {
var isValid = newsLetterForm.valid();
if (!isValid) {
e.preventDefault();
}
});
});
jQuery validate kräver name på elementen inuti formen. För att ta reda på name, måste man använda Control.UniqueId För att det ska fungera måste du köra preventDefault()
Vänta tills sp.js laddats
Här är en funktion som man kan använda för att vänta till sp.js laddats och köra sin funktion:
ExecuteOrDelayUntilScriptLoaded(myjsfucntion, "sp.js");
Eftersom det kan vara så att sp.js laddas med lazy loading:
<SharePoint:ScriptLink Name="SP.js"
runat="server" OnDemand="true"
Localizable="false"
Uppdatera web med js
Här är ett litet exempel:
function updateTitle() {
var ctx = new SP.ClientContext.get\_current();
this.web = ctx.get\_web();
web.set\_title('Examensarbete 2011');
this.web.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onUpdate),
Function.createDelegate(this, this.onFail)); }
function onUpdate(sender, args) {
alert('title updated');
}
function onFail(sender, args) {
alert('failed to update title. Error:'+args.get\_message());
}
Registrera javascript i feature
Om det inte passar att javascript i masterpage eller egen webpart, registrera det som customaction och aktivera feature. Läs mer här. Här är ett exempel:
<CustomAction
Location="ScriptLink"
ScriptSrc="~sitecollection/\_layouts/MyProject/awesome.js"
Sequence="101">
</CustomAction>
Aktivera intellisense för javascript i VS
Det finns ett sätt att aktivera intellisense för javascript i VS: Klistra in det i ditt js-fil eller aspx:
/// <reference name="MicrosoftAjax.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.core.debug.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.debug.js" />
```Men tyvärr [kommer det inte funka om du har installerat Resharper](http://devnet.jetbrains.net/thread/297493). Eller lägg till vanliga script-taggar som beskrivet i boken Sharepoint As Developer Platform:
<asp:PlaceHolder ID=“PlaceHolder1” runat=“server” Visible=“false”> </asp:PlaceHolder>
javascript API i Sharepoint
Det är supersmidigt. Här är ett exempel:
function createAnnouncement(title, body) {
var ctx = new SP.ClientContext.get\_current();
var list = ctx.get\_web().get\_lists().getByTitle('Meddelanden');
var itemCreationInfo = new SP.ListItemCreationInformation();
this.newListItem = list.addItem(itemCreationInfo);
this.newListItem.set\_item("Title", title);
this.newListItem.set\_item("Body", body);
this.newListItem.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onSucceededCallback), Function.createDelegate(this, this.onFailedCallback));
}
function onSucceededCallback(sender, args) {
SP.UI.Status.addStatus("Info", "It worked!",true);
}
function onFailedCallback(sender, args) {
SP.UI.Status.addStatus("Info", "It didn't work!",true);
}
Comments from Wordpress.com
westerdaled - Feb 0, 2013
Validera din form på klienten
Det finns ett mycket bra jQuery-tillägg som kan validera din data i en formulär på ett enkelt sätt. Se en demo. Referera till validate.js och ange rätt css-klasser på dina inputs: “required”, “error”, “url”, “valid”. Mycket smidigt.
cloud9 web ide
Skapa javascript-appar i din webbläsare. Mycket smidigt. Direkt kontakt till github.
Ladda jQuery dynamiskt till din sida
Vill du ändra innehåll, testa olika javascript-funktioner på din sida, prova något direkt i webbläsaren (utan att behöva deploya om), så är DevTools i Chrome, eller Firebug i Firefox väldigt bra verktyg. Om du har jQuery på din sida, så är det ännu bättre. Men om du inte har det, så ladda det i efterhand genom att öppna konsolen (Ctrl-Shift-J i Chrome) och kör följande rader kod (klistra in dem på en gång, och tryck på Enter):
Get coordinates from Google Maps
To get longitude and latitude can be tricky at the first time. There are many ways to do this, e.g. getlatlon.com. Good enough, but not so practical if you want to collect many coordinates. You can’t search after street names, you only can scroll and drag. Another way is to use javascript to show the longitude and latitude. See this example. This works in all web browsers.Just find your object in Google Maps and paste this javascript in URL bar: javascript:void(prompt('',gApplication.getMap().getCenter()));
You’ll be prompted the coordinates values. Just be sure the map is centered on your object. There is a third, even better way. Use javascript, but don’t be annoyed with prompts. In Chromium (or Google Chrome) navigate to maps.google.com find your object, open the Console in DevTools (press Ctrl-Shift-J). Right click on the object → Center the map here In console write: copy ( gApplication.getMap().getCenter().toString() )
So now you can paste it wherever you need it. But the best with it is: you can do whatever you want and need before copying. In LUSites, I save the coordinates another way, first latitude and then longitude. So I can shift values, trim unnecessary stuff and so on. Look at it: var loc = gApplication.getMap().getCenter().toString(); var locTrimmed = loc.replace(/[() ]/gi,""); var locArray = loc.split(","); var newLoc = locArray[1] + "," + locArray[0]; copy (newLoc)
First I get the string of the coordinates. Then I erase the unnecessary stuff: (), blank space. After splitting I shift the longitude and the latitude and create a new string which is copied. Or, we can shorten this: var coordinates = gApplication .getMap() .getCenter() .toString() .replace(/[() ]/gi,"") .split(","); copy (coordinates[1] + "," + coordinates[0]);
The same in one row (to copy-paste): var coordinates = gApplication.getMap().getCenter().toString().replace(/[() ]/gi,"").split(","); copy (coordinates[1] + "," + coordinates[0]);
To avoid to copy this line of code, just press up arrow in the DevTools console.
Undvika postback i button
Äntligen har jag kommit på hur man kan skippa oönskad postback i button. Det finns många olika lösningar. Här är ett intressant inlägg på stackoverflow om det. Men det enklaste sättet är egentligen bara lägga till
return false;
```i onclick... Här är lösningen
using System.Web.UI.HtmlControls;
…
HtmlButton HtmlButtonSendMail;
protected override void CreateChildControls()
{
…
#region Configure Send Email
HtmlButtonSendMail = new HtmlButton();
HtmlButtonSendMail.InnerText = “Send Email”;
HtmlButtonSendMail.ID = “HtmlButtonSendMail”;
string script = “”;
script += “SP.UI.Notify.addNotification(‘Loading..’, false);”;
script += “var options = {”;
script += " url: \"../_layouts/Toolbox/SendMail.aspx\",";
script += " width: 800,";
script += " height: 680,";
script += " allowMaximize: false";
script += “};”;
script += “SP.UI.ModalDialog.showModalDialog(options);”;
script += “return false;”;
HtmlButtonSendMail.Attributes.Add(“onclick”, script);
HtmlButtonSendMail.Attributes.Add(“title”,
“Skicka mail till\r\nde här personerna”);
Controls.Add(HtmlButtonSendMail);
#endregion
…
}
…
protected override void Render(HtmlTextWriter writer)
{
…
writer.RenderBeginTag(HtmlTextWriterTag.Div);
HtmlButtonSendMail.RenderControl(writer);
writer.RenderEndTag();//div
…
}
… other javascript stuff needed to work with your ajax solution
Polymorfi och javascript
En skräckscenario: du använder två javascript-bibliotek. Men de har var sin funktion som har samma namn. Det spelar även ingen roll om antalet inparametrar är olika. Så det blir samma sak som myfunc(param1, param2) och myfunc(param1). Grejen är att funktionen som laddas sist är den som kommer köras. Katastrof! Men det finns lösningar. Börja läsa här om hur man kan simulera polymorfi i javascript på about.com. Säg vi har en funktion som heter MoveToDate(strdate, ctxid) den ingår i init.debug.js (som används av Sharepoint kalenderwebpart). Sedan har vi något annat javascript-bibliotek som också har MoveToDate(param). Låt oss göra det polymorfiskt. Här är koden:
Felsök på clientsidan med Chrome DevTools
Här är en väldigt bra video som berättar om nya devtools i Google Chrome 10. Den visar 12 tricks hur man kan underlätta felsökning av html, css och javascript. Att kunna ändra html,css och js on-the-fly är faktiskt häftigt. För mig som länge har använt Firebug i Firefox (som nu inte funkar på FF4 RC) känns devtools väldigt bra. [youtube http://www.youtube.com/watch?v=nOEw9iiopwI&w=530&h=335]
Comments from Wordpress.com
Ändra utseendet på sidan direkt i webbläsaren « Sharepoint. Kunskap. Upptäckter på resan. - Mar 1, 2011
Använd inbyggd ModalDialog
Vill du visa någon formulär, eller längre information kan du använda en snygg (snygg och snygg?) ruta som är default i Sharepoint. Den är i alla fall användbar. Här är ett litet enkelt exempel, för att illustrera:
var options = {
url: "http://sverigesradio.se",
width: 800,
height: 600,
allowMaximize: false
};
SP.UI.ModalDialog.showModalDialog(options);
Det finns även möjlighet att ha OK-knappen, alltså som alert i javascript. Kolla den här länken.
Visa en popup-ruta
Visst är det fint med en formulär eller ruta som dyker upp medan ursprungssidan blir mörklagd. I grunden så ändras opacity på hela sidan, blir mörkare. En iframe med högre z-index dyker upp. I den iframe finns en annan sida. Hur gör man för att ta fram den rutan? Här berättar jag lite om det:
javascript i Webpart
Här är en bra länk hur man kan använda javascript: http://dotnetslackers.com/articles/aspnet/JavaScript_with_ASP_NET_2_0_Pages_Part1.aspx
this.Page.ClientScript.RegisterStartupScript(this.GetType(),
"ButtonSendMailConfirm\_Click",
"alert('mail skickat!')", true);
Tag: Localization
MagicMirror2 and Chuvash
This post is about my setup of the popular MagicMirror2 application. I show the steps needed to set it up on a Raspberry Pi Zero W and connect it to a TV set. As a bonus, I share my thoughts on the Chuvash localization work.
MagicMirror2 is a DIY project and an open-source application, voted to number one of the best Raspberry Pi Projects. In essence, it shows information of your choice (weather, calendar, news) on a screen that is embedded in a mirror.
Working with resx files in Visual Studio
Today I found a nice Visual Studio Extension for working with localization and resx files: Resx Resource Manager. This extension provides an additional view in your project and scans all the resx files. I would recommend it to all projects where you have to translate your interface. Here is how it looks in my project: It can also assist with some machine translation from Bing and MyMemory: Another good thing is the Export and Import to and from Excel. Wonderful if you need help from Non-developers.
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
JavaScript Localization in SharePoint
Yesterday Waldek Mastykarz published a cool post: Globalizing JavaScript in SharePoint 2013. This is a very cool technique to localize your client code in javascript and reuse your resx files in Server Side and Client Side. This is actually not new for SharePoint 2013 despite it has become more needed with the huge client focus in the new SharePoint. I have used this in SharePoint 2010 for a long time. In my blog post: ScriptResx.ashx in SharePoint I told about that technique. What I didn’t know that you can define your javascript namespace directly in the resx file. Waldek wrote in his comment that SP.Publishing.Resources.en-US.resx automatically are SP.Publishing.Resources in javascript. That was not the case for my own localization files. A simple look at SP.Publishing.Resources.en-US.resx helped: [sourcecode language=“xml”] true SP.Publishing.Resources [/sourcecode] This results in: [sourcecode language=“javascript”] _EnsureJSNamespace(‘SP.Publishing’); [/sourcecode] So what we have to do for our custom resx file is to add classFullName resheader: [sourcecode language=“xml”] Takana.Res [/sourcecode]
Chuvash localization of moment.js
For three months ago I added Chuvash localization of moment.js. For 16 days ago moment.js 1.7.0 was officially released which included the Chuvash translation.
Wait a sec… What is moment.js?
moment.js is the best datetime tool for javascript. It supports many languages (now even Chuvash) for displaying date and time. Another very handy functionality is showing relative time which has a simple interface: fromNow().
Here is a simple example from a web browser console:
Chuvash translation of Wikipedia Mobile
The official Wikipedia mobile app is now translated into Chuvash language and available to use:
What does Chuvash mean?
I am Chuvash. Chuvash is the name of an ethnicity which counts up to 2 milions peoply (mostly in Russia). Chuvashes talk the Chuvash language which is also an official language in Chuvash Republic (besides Russian). Chuvash language is a Turkic language and has a status “Vulnerable” in the UNESCO list of languages in danger. There is a Chuvash Wikipedia cv.wikipedia.org.
ResxCrunch: Localization tool
If your solution has two or more languages to support, I can recommend an open source tool ResxCrunch. Btw, you can even use ResxCrunch for localization of Android applications.
ScriptResx.ashx in SharePoint
In my previous post I showed a little proof-of-concept for an httphandler which I want to use to dynamically get the localization resources from SharePoint as javascript object. But wait a moment. How does SharePoint handle localization on client? When you look in Script tab in Chrome dev tools, you’ll find:
ScriptResource.axd
It is added to the server when deployed. See a good introduction to WebResource.axd and ScriptResource.axd by Brian Chavez.
Push a copy of Resources to client in javascript
In one of my previous posts I told about pushing a copy of an object into client. Now I’ll try to copy my resource values into client. The problem is often that we must create multiple localization resources: first as resx-file. If we use much ajax and client side rendering, we must provide some localization there, too. If they are different subsets of localization resources, it isn’t a problem. But when you get overlapping, it becomes more difficult to manage and sync them. See how Microsoft Ajax Library provides some strings: What if we just copy the values from resx file into client? If there are not business constraint it can make the development much easier. Let’s try it. For that we need Reflection. We start with changing the access modifiers on resx file to public: Then we must get all static properties of the auto-generated class (ResXFileCodeGenerator):
Hämta lokaliserad sträng från App_GlobalResources
Om man har en sträng i App_GlobalResources som man vill hämta ifrån koden, kör:
string text = HttpContext.GetGlobalResourceObject("MyProject\_Global", "submit\_label") as string;
Version 0.2.0: Swedish localization
Well, it is time to localize. The first language has been added: Swedish, of course. To localize is pretty simple in Android. All you have to do is to create a new folder /res/values-xx
where xx is the language code. sv is Swedish. In this folder create an xml file called strings.xml and copy all the content from /res/values/strings.xml
. Replace all the strings from your default language into the language you want to localize to. There is a graphical wizzard in Eclipse+Android for creating the right folder: Right click on your project → Android tools → Create a new Resource file → Choose Language → Follow your intution.
Tag: Magicmirror
MagicMirror2 and Chuvash
This post is about my setup of the popular MagicMirror2 application. I show the steps needed to set it up on a Raspberry Pi Zero W and connect it to a TV set. As a bonus, I share my thoughts on the Chuvash localization work.
MagicMirror2 is a DIY project and an open-source application, voted to number one of the best Raspberry Pi Projects. In essence, it shows information of your choice (weather, calendar, news) on a screen that is embedded in a mirror.
Tag: Node.js
MagicMirror2 and Chuvash
This post is about my setup of the popular MagicMirror2 application. I show the steps needed to set it up on a Raspberry Pi Zero W and connect it to a TV set. As a bonus, I share my thoughts on the Chuvash localization work.
MagicMirror2 is a DIY project and an open-source application, voted to number one of the best Raspberry Pi Projects. In essence, it shows information of your choice (weather, calendar, news) on a screen that is embedded in a mirror.
nodeunit and SharePoint: unit tests in javascript
nodeunit is a (relatively) new test framework for javascript, mainly for node, but it can be run in a browser as well. The most popular framework for testing javascript is Qunit, but I’ll lab with it another time. I found nodeunit tests in moment.js - the best date handling framework for javascript and it worked very well. So first of all, why should we test? The best answer is actually: Life is to short for manual testing (it was actually the slogan at the Google London Test Automation Conference 2007.
Hello world in node.js
I know, node.js has been present for a while. But I actually had no time to try it. I was surprised that now it is very straight forward to start with node.js. Allright, everything begins with Hello world. Eventhough it is available for allmost all combinations of operating systems and servers, the easiest way to test it was actually Ubuntu. To install just run:
sudo apt-get install nodejs
```Then make a new directory and create the hello.js:
mkdir hello cd hello vi hello.js
Tag: Uncategorized
MagicMirror2 and Chuvash
This post is about my setup of the popular MagicMirror2 application. I show the steps needed to set it up on a Raspberry Pi Zero W and connect it to a TV set. As a bonus, I share my thoughts on the Chuvash localization work.
MagicMirror2 is a DIY project and an open-source application, voted to number one of the best Raspberry Pi Projects. In essence, it shows information of your choice (weather, calendar, news) on a screen that is embedded in a mirror.
Mass remove live photo videos
While importing images from my iPhone using Image Capture on my mac, I discovered that almost all pictures had corresponding videos. They had the same name, only the file extension was different:
- IMG_2829.JPG
- IMG_2829.MOV
For archiving I don’t to have live photo videos, that’s why I needed a script for that. I found a good start in an answer on SuperUser.stackexchange.com:
I altered it a bit to remove the corresponding .MOV-file (rm):
Re-discovering Github
Github has changed a lot. While working mostly in Azure DevOps I haven’t followed all the development on Github. Now when I look at that, I am really amazed.
Private Repos for Free accounts
Well, for me it is not as interesting, because with my free account, I don’t see any harm having my labs public. But I know, some people used bitbucket for their smaller private repos.
Github Project
I suppose it is the Azure DevOps Project concept that was copied to Github, a place for planning and having multiple connected repos.
Update LocaleId and TimeZone with PnP
If you get an error while trying to update Regional Settings on your SharePoint Online Site, then PowerShell combination of PnP and CSOM are to the rescue.
The issue I got was that indexed columns were there. You can try to remove indexed columns and re-add them. But it is not the best solution. In my scenario, it was an indexed column that I couldn’t remove.
The reason why I use a combination of PnP and CSOM (Load, Update, ExecuteQuery), is that I have not found a way of updating RegionalSettings in PnP.
Svenska i Office 365 Admin
Svenskt gränssnitt i Office 365 är inte självklart. Här är en lista på översättningar som jag stött på som går att härleda, men som inte är helt etablerade i svenskan.
- Compliance - efterlevnad
- Policy - princip
- Retention - kvarhållning
SPFx Samples
Here is my list of repositories that provide examples of SPFx solutions.
- SharePoint/sp-dev-fx-webparts is a comprehensive collection of webparts and tutorials
- Puzzlepart/spfx-solutions is an intresting collection of spfx solutions, shared by Mikael Svenson.
- To be continued.
SwiftKey from the Chuvash point of view
SwiftKey is a keyboard app for iOS and Android, it adds a new virtual keyboard and it provides the Chuvash one among others. Here is my review of Swiftkey from the perspective of a person who writes in Chuvash on the mobile.
Positive things
- The fact that it has the Chuvash keyboard map is awesome. There is no official Chuvash keyboard in iOS, Android, MacOS, Windows (well you can add Chuvash, but you won’t get the Chuvash letters). Only Linux has the built-in Chuvash keyboard.
- It has a built-in Chuvash dictionary, so that can provide suggestions. It also can learn from your typing. Although there is an issue with the suggestions, see below.
- The Chuvash characters with diacritics are right: Unicode and Cyrillic, not their look-alikes from the Latin set. It is important: if people use the same characters, they can find more on Google.
Negative things
Actually I don’t want to call it negative things, many of them are just missing features. I hope with that review I can get in contact with the Swiftkey team and improve the app.
Solpanelexperimentet
Ett litet projekt, ett experiment som jag håller på under min föräldralediga tid: Barnvagssolpanel. Jag har en liten solpanel på 10W som jag fäster på barnvagnen. Med den laddar jag mina batteripack, och med dem min mobil. Jag vill mäta hur mycket energi jag kan samla in under sommaren
Utrustning
Solpanel på 10W av märket Exibel köpt på Clas Ohlson. Den ska ge upp till 1,5A i direkt ljus. USB-doktorn. No-brand-produkt. Den visar spänning, ström, tid och kapacitet. USB-anslutningen är lite lös och kan glappa ibland. Den i sig förbrukar lite ström. Av någon anledning backar den flera mAh tillbaka efter man nått 3000 mAh varje gång man ansluter sladden igen. En svart powerbank från Clas Ohlson på 2600mAh = 9,62Wh. Blir laddad så fort solen skiner. I direkt solljus blir det 4,92v x 0,82A = 4W. En silverfärgad powerbank från Clas Ohlson på 3350mAh = 12,1Wh. Den fungerar mycket sämre, ofta laddar den inte alls, trots att den funkar från eluttaget. I skiftande strömförhållanden lägger den av. Är det på grund av någon elektronisk skyddspärr?
Setting up Raspberry Pi2 for a Dashboard Monitor
I have set up Raspberry Pi as a Dashboard Monitor a couple of times. Here I want to summarize my steps. In fact, it is nothing special, a raspberry pi that is used as a browser showing a web based dashboard in full screen, but there are some important configuration steps needed to make it as good as possible.
Install Raspbian
Raspbian is the best operating system for Raspberry Pi. Just stick with that.
Chuvash Keyboard Layout for Mac
I’ve got a Mac and one of my first questions was: How can I write in Chuvash on my Mac, obviously :) In this post I am going to tell how I created Chuvash Keyboard Layout. The solution and installation instructions are on Github: Chuvash Keyboard Layout for Mac
What the heck is Chuvash?
For those who don’t know yet: Chuvash are people who live in Chuvash Republic in Russian Federation, and abroad, as me. We are 1.5 million. Chuvash is also a language, an official language of the Republic, a minority language, that is completely different from the second official language Russian. Chuvash uses Cyrillic letters, all 33 Russian letters plus 4 additional letters: A breve (Ӑ), E breve (Ӗ), C cedilla (Ҫ) and U with double acute (Ӳ).
Androidapp som pratar med SharePoint
Idag har vi kompetensdag på Bool: #booldevday. I min grupp ska vi utveckla en mobilapp för Android. Vi har hittat på ett följande case: Case Ett fiktivt företag Takana är oberoende bostadsinspektörer. De inspekterar bostäder när någon flyttar ut… Varje inspektion är kopplad till en bostadsadress. Den stämplas med dagens datum och inloggade användaren (från Azure AD). En inspektion innehåller en bedömning (kommentar) och kan innehålla anmärkningar. Varje anmärkning har en beskrivning och en bild (ej obligatoriskt). En anmärkning kräver en åtgärd. En inspektion utan anmärkningar innebär en godkänd överlämning och behöver inga åtgärder. En inspektion godkänns av administratörer i SharePoint Online i desktop-versionen. Takana använder SharePoint Online. Det finns en dedikerad site för inspektioner och en lista just för inspektioner och en lista för anmärkningar. Anställda har androidtelefoner. Det är inte sällan man har inte tillgång till nätet på byggarbetsplatser. Det är ett krav att det ska fungera offline och synkroniseras när man får uppkoppling med mobilt internet. Vårt team Vi är passionerade med att jobba med SharePoint och SharePoint Online, men vi är nya i mobilapputveckling. Det blir skoj att testa SharePoint APIer i Androidprojekt. I mitt team ingår Dan Saedén (https://github.com/rlv-dan) och Mattias R. Våra verktyg Vi använder Android Studio, en Nexus 9 för att debugga och Github for Windows Statusuppdateringar Vi uppdaterar om status i vår grupp på Yammer och Twitter med hashtaggen #booldevday02 (vår grupp) och #booldevday (vår komptetensdag). Den här bloggposten kommer också med största sannolikhet uppdateras under dagen. Fakta och endpoints Vår repo på Github ligger under https://github.com/mirontoli/andpoint SharePoint Online-instansen är under https://takana14.sharepoint.com/booldev2/Lists/Anmarkning Länkar Office365 SDK Android Start SDK for Android SharePoint ListClient in Office365 SDK for Android DevCamp Android Set up Android for working with List Items
Update multi-value lookup column values in SharePoint 2010 using managed CSOM
Reblogging this useful code sample for updating multi-value lookup columns using CSOM in C# in SharePoint 2010, but also valid for SharePoint 2013.
AngularJS Performance Tuning for Long Lists
This is a must-read for all SharePoint Developers who use Angular.
How to reference nested class or struct etc, in PowerShell
Comments from Wordpress.com
Anatoly Mironov - May 3, 2014
Thank you Hugh! It explains the syntax!
It happens because it is using .net and reflection Type.GetType(“ParentClass+NestedClass”)
IntelliJ Keyboard Shortcuts
I want to use shortcuts. I prefer the IntelliJ keyboard scheme. Which do you use?
The CDN concept in SharePoint
How many instances of jquery are there in your SharePoint farm? [sourcecode language=“powershell”] Get-SPWebApplication http://dev ` | Select -Expand Sites ` | Select -Expand AllWebs ` | Select -Expand Lists ` | Select -Expand Items ` | ? { $_.Url -match “jquery.*.js” } ` | select Name, Url [/sourcecode] Have you more than two (jquery and jquery-ui), then you have too much. You can save much place and performance by using Content Delivery Network (CDN) links for the resources like javascript, css, fonts and icons. Consider those Content Delivery Networks:
Run Hyper-V and VirtualBox on the same machine
This applies to the combination Hyper-V and VMWare as well. Really good stuff. [code language=powershell] #disable, needs computer restart bcdedit /set hypervisorlaunchtype off #enable, needs computer restart bcdedit /set hypervisorlaunchtype auto [/code]
Using GitFlow with Visual Studio and SourceTree
I enjoyed this intro to git in visual studio.
Making the Newsfeed web part available outside of My Sites in SharePoint 2013
Easy to add a newsfeeed to a web other than My Site.
JQuery 2.0 - Notes About the Official Release
jQuery 2.0 leaves behind the older Internet Explorer 6, 7, and 8 browsers. In return it is smaller, faster.
Knas på Swedbanks mobilsida
Försökte ladda mitt kontantkort idag via Swedbanks mobilsida. Det gick inte. Och det berodde inte på iPhone som jag först trodde. Orsaken var ett knasigt användande av ett html5-attribut i en annars html4-hemsida: input type=“number”: Att skriva en nolla i telefonnumret var helt omöjligt trots att sidan spottade ut fel och krävde en nolla. Med lite handpåläggning gick det! Tur att man bara kunde rader type=“number” och att sånt knasigt fel inte låg i code-behind. Testar man inte sin programvara på Swedbank?
Simple autocomplete in jQuery UI
Thanks to Justin Cooney and jsfiddle. Here is a simple autocomplete example:
The new interface of wp.com is great.
The new interface of wp.com is great. For a while I had some considerations to migrate to tumblr, now I definitivly stay with wp. Now wp takes the best from itself, tumblr and twitter.
Vertically align input text in IE
Well, input and IE aren’t friends, are they? I found a solution: not defining input height. The only shortcoming of this solution is…, well the solution itself, sometimes you need to define the input height. However, don’t set height, just define, font-size for text inside and padding, and it will be aligned:
input {
font-size:20pt;
padding: 10px;
}
Do you know some better ways to do it, Tell me.
Playing with play!
play! framework Inspired by ComputerSweden I played with Play! Here I’ll just put some commands to create and deploy a Play! web application, actually more for myself, to remember the steps to get started quickly. It would be great of course, if someone else finds it useful. The code for this little simple app. Play! is a java based framework for web applications. It reminds the rails framework and provides many useful features as CRUD, REST and more out of the box. In this post I create an download play and unpack in your home directory add to your path and save this in login script (.bashrc)
css3 transform
See Richards Bradshaw’s page with explanations and examples of css3 transform and transitions. His code is also available for forking on Github.
Extend an event in javascript
If you use jQuery, you don’t need it. But if you for some reason must use javascript you must beware of adding events. The most dangerous is window.onload. Consider this scenario:
function doSomethingGreat() {};
window.onload = doSomethingGreat;
```It works fine if you are the only person who writes window.onload handler. But on such platforms like SharePoint you can't know which events exist. And if you just write **window.onload = doSomethingGreat;** you override all other window.onload events. Again, in jQuery you have nothing to worry. jQuery(window).load(doSomethingGreat) will just add your event, not override. In this post I'll show how to extend an event handler the pure javascript way. We have to create our own function for adding event handlers. First the old events have to be temporary saved and then the new event has to be added. [Like this](http://jsfiddle.net/mirontoli/cnN6s/):
function addOnclick(elem, func) {
var old = elem.onclick;
if (typeof elem.onclick != ‘function’) {
elem.onclick = func;
} else {
elem.onclick = function () {
if (old) {
old();
}
func();
};
}
}
Sorting Dates in javascript
To sort an array in javascript, just run sort():
array = \["skåne", "blekinge", "halland"\];
array.sort();
```To [perform a more intelligent sorting](http://stackoverflow.com/questions/3859239/sort-json-by-date "See the original answer in stackoverflow") we can define our sorting logic. What if an array has objects with different properties? For example, an object has title and lastupdated. We want to sort on lastupdated. Just create a function for this with two parameters:
function custom_sort(a, b) { return new Date(a.lastUpdated).getTime() - new Date(b.lastUpdated).getTime(); }
Bootstrap and Sharepoint
Twitter Bootstrap is awesome, based on less.js, ust add this line in your html code:
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/1.3.0/bootstrap.min.css">
And your page looks already good. If you use css classes like btn label warning danger and much more, you get a right design directly out of the box. Now I want to test it in Sharepoint. Will it work? What do you think? jQuery Theme Roller. Another interesting resources are jQuery ThemeRoller. WebResources Depot:
New types of inputs in html5
html5 provides more types of inputs than the classic submit and text and a few more. Here you can see an example on fiddle
.gitignore for .net
At appharbor there is a simple .gitignore file for .net applications. If you use Resharper, you may find the extended version of .gitignore useful. A most comprehensive .gitignore can be found on gitextensions website. (Thanks to Vasiliy Aksyonov for the comment):
#ignore thumbnails created by windows
Thumbs.db
#Ignore files build by Visual Studio
\*.obj
\*.exe
\*.pdb
\*.user
\*.aps
\*.pch
\*.vspscc
\*\_i.c
\*\_p.c
\*.ncb
\*.suo
\*.tlb
\*.tlh
\*.bak
\*.cache
\*.ilk
\*.log
\[Bb\]in
\[Dd\]ebug\*/
\*.lib
\*.sbr
obj/
\[Rr\]elease\*/
\_ReSharper\*/
\[Tt\]est\[Rr\]esult\*
```If git tracks some files you don't want it to track, [just remove these files from the git repo](http://stackoverflow.com/questions/1273108/how-do-i-git-rm-a-file-without-deleting-it-from-disk "See the answer at Stackoverflow"):
git rm –cached file
s4-die
s4-die is a funny stuff. Now I realized the purpose of it. Everything that has to be hidden, Microsoft wraps in an element with class=“s4-die”. In corev4.css it is defined with display:none. Not so bad. Another approach is to create a invisible panel like Randy Drisgill has done. But with s4-die you don’t need to move your stuff around, just add the class s4-die.
Increase responsivity of a virtual machine in VMWare
Sometimes a virtual machine can freeze, just add these lines to vmx:
MemTrimRate=0
sched.mem.pshare.enable = "FALSE"
mainMem.useNamedFile = "FALSE"
prefvmx.minVmMemPct = "100"
Change the layout of Search Box without custom delegate control
The surest way to customize Search box in Sharepoint is to create a delegate control. In Sharepoint.Stackexchange there are many links to resources about this. But if you don’t have access to server or can’t deploy, the easiest way to do it is to style it with css. Thanks Steve Ottenad.
.s4-search .ms-sbgo a {
background:url(../images/search\_btn.png) no-repeat;
width:27px;
height:22px;
display:block;
}
.s4-search .srch-gosearchimg, .s4-search .ms-sbgo span {
display:none;
}
First we hide the the default image and then we add our image for search button as background.
Automated tests for Sharepoint
[slideshare id=7671059&doc=obriendev203introducingautomatedbuildsanduitestingwithscreenshots-13031986159416-phpapp02]
Provisioning multiple pages with one source file
I found an easy way to provision multiple pages. Create a module. Add an aspx.file (e.g. default.aspx). In the elements file define nodes for every page. Path should be the same for all pages, but the Url should be your destination page. The “default.aspx” (name doesn’t matter) can contain content, or just one @Page directive if Publishing feature is available:
<%@ Page Inherits="Microsoft.SharePoint.Publishing.TemplateRedirectionPage,Microsoft.SharePoint.Publishing,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
```In the Element.xml define all your pages: [![](https://sharepointkunskap.files.wordpress.com/2011/10/abunchofpages-elements.png "abunchofpages-elements")](https://sharepointkunskap.files.wordpress.com/2011/10/abunchofpages-elements.png) In every File node you can add webparts, here is an example:
<![CDATA[ Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c Microsoft.SharePoint.WebPartPages.ContentEditorWebPart About cars Test None true Lorem ipsum dolor sit amet ]]>
Team Explorer
Until now I have only worked with svn and git. So I am very curious about the Team Foundation Server and Team Explorer which all talk much about. The best thing is the integration with the issue tracking. I can see all work item, or just my work items. Another fine feature, at leat if you use codeplex, is the Team Explorer Everywhere.
The Team Explorer Everywhere client works on Windows, Linux, Mac, or Solaris. It provides a command line client and plug-in for Eclipse to access Team Foundation Server. For information on obtaining the client and connecting to the Team Foundation Server please read the Team Explorer Everywhere Client wiki page. You will need the information on the right to connect to the Team Foundation Server in Team Explorer Everywhere.
Good pattern for javascript files
SP.js exists in two variants in debug mode and in modified. When you develop it is better to use debug mode. When it goes to production it is better to use minified files. The same you can do with your files. Wictor Wilen explains how to do minify your custom javascript files. I think it is a good pattern to create javascript files and call them something-something**.debug.js**. Then when you are done, run the custom tools to minify them.
Show html in ModalDialog
We can use ModalDialogs to show not only pages, but some html:
var htmlElement = document.createElement('p');
var helloWorldNode = document.createTextNode('Hello world!');
htmlElement.appendChild(helloWorldNode);
var options = {
html: htmlElement,
autoSize:true,
allowMaximize:true,
title: 'Test dialog',
showClose: true,
};
var dialog = SP.UI.ModalDialog.showModalDialog(options);
Custom PlaceHolder
You want some custom content in your site and it is different from page to page. Well, I wrote how to achieve this with delegate controls. Another approach is to use PlaceHolders. Maybe you can use some existing placeholders. There are so many unused placeholders in v4.master. Like PlaceHolderLeftActions. If you use starter master pages from Randy Drisgill, you must move these from invisible panel. To create custom placeholder is very easy: Just copy an existing placeholder in the master page and name it som appropriate like:
Create your own search box
It is very simple. Create a new module: SearchArea. Delete Sample.txt and Elements.xml. Create a new file: SearchArea.xml
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Control
Id="ContosoSearchAreaBox"
Sequence="15"
ControlClass="Microsoft.SharePoint.Portal.WebControls.SearchBoxEx"
ControlAssembly="Microsoft.Office.Server.Search, Version=14.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Property Name="GoImageUrl">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="GoImageUrlRTL">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="GoImageActiveUrl">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="GoImageActiveUrlRTL">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="DropDownMode">HideDD\_useDefaultScope</Property>
<Property Name="FrameType">None</Property>
<Property Name="UseSiteDefaults">false</Property>
</Control>
</Elements>
Next add your searcharea module to a site scoped feature.
In the masterpage locate this:
<SharePoint:DelegateControl runat="server"
ControlId="SmallSearchInputBox" Version="4" />
and replace with your brand new search area:
Link to Home on Top Navigation Bar
If you have a custom site definition and want to have a link to RootWeb, just add NavBarPage to your module:
<Module Name="OrklaRootBlank" Url="" Path="">
<File Url="default.aspx">
<NavBarPage Name="$Resources:core,nav\_Home;"
Url="~site" ID="1002" Position="Start" />
</File>
</Module>
Add local admin in cmd
Just run this in cmd, or powershell:
net localgroup Administrators /add domainname\\users
Check if a file exists
var imgName = "hello.jpg";
var folder = web.GetFolder("PublishingImages");
var img = web.GetFile(folder.ServerRelativeUrl + "/" + imgName);
if (img.Exists) {
doSomething();
}
Todolist in VS
A really nice feature is a task list. Just write //TODO something something in your code and it appears in the task list which can be shown through View - Task List in Visual Studio.
Resize image with jQuery to fit the div
There are many interesting jQuery plugins for resizing and cropping of images. Among them are jrac and image scale. I have tested the latter: It works very fine
$(window).load(function() {
var $imgContainer = $("#layout-news-image");
var $newsImg = $("#layout-news-image img\[rel!='sp\_DialogLinkIgnore'\]");
$imgContainer.css("width", $imgContainer.parent().width());
if ($newsImg.length > 0) {
if ($newsImg.width() < $imgContainer.width()) {
$imgContainer.width($newsImg.width());
}
if ($newsImg.height() < $imgContainer.height()) {
$imgContainer.height($newsImg.height());
}
$newsImg.imgscale({
parent : '#layout-news-image',
center: "true",
scale: "fill"
});
}
});
```This script checks if the original image is lesser than container div and doesn't resize if it is so. **#layout-news-image img\[rel!='sp\_DialogLinkIgnore'\]** means that do not resize if there is a hidden image with rel="sp\_DialogLinkIgnore". See the [jQuery selectors](http://api.jquery.com/category/selectors/) for more info. This script can be improved by adding window resize event in javascript. I use **$(window).load** instead of the usual _$(document).ready_ because [ready-function in jQuery runs when DOM is loaded, if the page is not cached it happens before the image is loaded](http://web.enavu.com/daily-tip/daily-tip-difference-between-document-ready-and-window-load-in-jquery/). $(document).ready doesn't work.
## Comments from Wordpress.com
####
[sdfsdf](http://sdsdfsdf "sdfsdf@ssdf.sdd") - <time datetime="2012-06-28 19:28:51">Jun 4, 2012</time>
doesn't work: it's just squeeze the picture. No examples included == no possibility to check.
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-11-05 10:06:01">Nov 1, 2012</time>
Thank you Alejandro for the awesome js lib and sharing it. I will absolutely recommend it.
<hr />
####
[Alejandro Emparan (@krc_ale)](http://twitter.com/krc_ale "krc_ale@twitter.example.com") - <time datetime="2012-11-02 20:21:55">Nov 5, 2012</time>
I wrote a jQuery plugin for that: https://github.com/karacas/imgLiquid
<hr />
ListUrl on EventReceiver
When you create an eventreceiver, you get the ListTemplateId attribute. It works fine. But if you want the eventreceiver to trigger on one particular list, just replace ListTemplateId attribute with ListUrl. For Pages you can use:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Receivers **ListUrl="$Resources:cmscore,List\_Pages\_UrlName;"**\>
<Receiver>
<Name>NewsPageEventReceiverItemUpdated</Name>
<Type>ItemUpdated</Type>
<Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
<Class>Contoso.EventReceivers.NewsPageEventReceiver.NewsPageEventReceiver</Class>
<SequenceNumber>1000</SequenceNumber>
</Receiver>
</Receivers>
</Elements>
Change CA port number
In order to change port number for the Central Administration site, run this cmdlet:
Set-SPCentralAdministration -Port 1337
You can set any number between 1023 and 32767 except 443.
Create own delegate control
In this post I’ll show how to create a simple (but own) delegate control. A short intro and links on delegate controls can be found on sharepointoverflow. Take a look on master page. There are already many delegate controls. The delegate control with id AdditionalPageHead can be used for adding your script or jQuery library.:
<SharePoint:DelegateControl
runat="server"
ControlId="AdditionalPageHead"
AllowMultipleControls="true"/>
You can also override existing controls like searchbox. But what if you want to add some content in the master page where no delegate controls are present. Of course, you can add it directly to the master page. Perhaps not on all webs? You can use placeholders to manage it. But do you want to update all the page layouts? So the solution is to use delegate controls, for adding multiple pieces of content or overriding using Sequence. In this example I’ll add some new content to the quicklaunch bottom area:
SiteLogoImage to RootWeb
If you click on the site logo, as default you go to the current spweb’s default.aspx page. If you want to override this, locate:
<SharePoint:SPLinkButton
runat="server"
NavigateUrl="~site/"
id="onetidProjectPropertyTitleGraphic" >
```Change ~site to ~sitecollection:
<SharePoint:SPLinkButton runat=“server” NavigateUrl="~sitecollection/" id=“onetidProjectPropertyTitleGraphic” >
Hide Site Actions
The easiest way to hide Site Actions for a specific audience is to wrap this into a SPSecuritityTrimmingControl. Locate in your master page. Paste this before span element:
<SharePoint:SPSecurityTrimmedControl runat="server" Permissions="ManageLists">
Find the ending element and paste:
</SharePoint:SPSecurityTrimmedControl>
Get all comments
If you try to get comments quantity for a url, you may wonder, why there is only quantity of the comments which the current user has posted:
public int GetNumberOfNewsPageComments
(SPSite currentSite, string pageUrl, int max)
{
var serviceContext =
SPServiceContext.GetContext(currentSite);
var socialCommentManager =
new SocialCommentManager(serviceContext);
var comments = socialCommentManager
.GetComments(new Uri(pageUrl), max);
if (comments != null)
{
return comments.Length;
}
return -1;
}
```The solution is to impersonate the SPSite object with an account who has the rights to manage social data. Give this permission to the account in CA - Application Management - Service Applications - User Profile Service. [![](https://sharepointkunskap.files.wordpress.com/2011/09/manage-social-data.png?w=284 "manage-social-data")](https://sharepointkunskap.files.wordpress.com/2011/09/manage-social-data.png)
Custom favicon
It is easy to use a custom favicon, put a ico image into a mapped folder Images and then locate this line in your master page:
<SharePoint:SPShortcutIcon runat="server" IconUrl="/\_layouts/images/favicon.ico" />
```And replace it with your ico:
<SharePoint:SPShortcutIcon runat=“server” IconUrl="/_layouts/images/CONTOSO/favicon.ico" />
Increase performance while retrieving data with LINQ to SP
If you are just intrested in getting data, not writing to the source like SubmitChange, you can disable ObjectTracking and increase the performance.
context.ObjectTrackingEnabled = false;
```I found this tip on page 248 in the book "[Sharepoint 2010 as a development platform](http://www.apress.com/9781430227069)"
Do an unsafe update in a unified manner
Recently I talked about a WithWeb-pattern as described in Jonas Nilssons blog where you can isolate the disposal logic in one place. Another thing is to isolate unsafe updates:
public static class SPWebExtension
{
public static void UnsafeUpdate(this SPWeb web, Action<SPWeb> action)
{
try
{
Log.Info("Trying to do an unsafe update on a web: " + web.Title);
web.AllowUnsafeUpdates = true;
action(web);
}
catch (Exception e)
{
Log.Error(e);
}
finally
{
web.AllowUnsafeUpdates = false;
}
}
}
```The Log class is my own class which I presented in [my previous post](https://sharepointkunskap.wordpress.com/2011/09/19/a-simple-log/).
## Comments from Wordpress.com
####
[WithWeb-pattern of Jonas Nilsson « Sharepoint. Kunskap. Upptäckter på resan.](https://sharepointkunskap.wordpress.com/2011/09/15/withweb-pattern-of-jonas-nilsson/ "") - <time datetime="2011-09-21 17:28:23">Sep 3, 2011</time>
\[...\] Here I use another fancy way to consolidate the unsafe updates. \[...\]
<hr />
Show Title on Page
If you want to show the page title in another part than defined in your master page just add this tag to your page layout.
<SharePoint:ProjectProperty
Property="Title" runat="server" />
```It must be within <asp:Content> tag
Show a presence bubble
There is no built-in sharepoint control for the presence bubble. If you want to add this functionality on your pages you have to add it as html. Here is a sample:
private static int \_COUNTER = 0;
private const string PresenceBubble =
"<a class='ms-imnlink' href='javascript:;'>" +
"<img width='12' height='12' id='imn\_pawn\_{0}' onload=\\"IMNRC('{1}')\\" alt='My SID' " +
"src='/\_layouts/images/imnoff.png' border='0' " +
"showofflinepawn='1' sip='{2}'></a> {3}";
private static string FormatUser(SPUser user)
{
\_COUNTER++;
return string.Format(PresenceBubble, \_COUNTER, user.Email, user.GetSipAddress(SPContext.Current.Web), user.Name);
}
Get role assignments of a web or a list
In Powershell you can easily get the permissions in a web or in a list:
$web = get-spweb http://contoso.com
$web.Groups | select Name, Roles > .\\Desktop\\webgroups.txt
$list = $web.Lists.TryGetList("Assets");
$list.RoleAssignments | select Member, RoleDefinitionBindings > .\\Desktop\\assets-roleassignements.txt
```To get all users in all groups run:
$web.Groups | Foreach { Write $_.Name; Write “————-”; $_.Users | Select Name; Write “”; Write "" }
Windows 8 preview
I have tested the Windows 8 developer preview. VMWare player 3 didn’t manage it, so I installed VirtualBox and it ran very well. One thing I did was to enable full screen on VirtualBox. Here is the list of features you get if you install the developer preview:
- Windows SDK for Metro style apps
- Microsoft Visual Studio 11 Express for Windows Developer Preview
- Microsoft Expression Blend 5 Developer Preview
- 28 Metro style apps including the BUILD Conference app
1DayLater.com - the best time tracking
I discovered a great tool for time tracking: 1DayLater. So far I am very pleased. You can add activities, write hash tagged descriptions, get an overview over you consultant hours and much more
My favorite tools
When you code, you can save a lot of time and nerves if you have good tools. Here are my favorites: Programmer’s notepad ULS Log Viewer Resharper t4toolbox HTML5 and CSS3 standards
Webpart in a reusable user control
In my previous post I wrote about using IgnoreIfAlreadyExists=“True” for preventing of adding webparts multiple times. It works fine until you redeploy your project. Another approach is to use a user control with you webpart. Add mapped folder CONTROLTEMPLATES. Create a new user control, add you assembly and your webpart. Then you can add this user control wherever you need it.
<%@ Register
tagprefix="SPSWC"
Namespace="Microsoft.SharePoint.Portal.WebControls"
Assembly="Microsoft.SharePoint.Portal, Version=14.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<SPSWC:SocialCommentWebPart runat="server"
AllowEdit="True"
AllowConnect="True"
ConnectionID="00000000-0000-0000-0000-000000000000"
Title="Note Board"
IsIncluded="True"
Dir="Default"
PartImageLarge=""
IsVisible="True"
AllowMinimize="True"
ZoneID=""
ID="g\_5937b022\_83bb\_40cb\_b68f\_bd565bf96885"
FrameState="Normal"
ExportMode="All"
TitleLocIdNum="0"
AllowHide="True"
SuppressWebPartChrome="False"
DetailLink=""
ChromeType="None"
DescriptionLocId="Null"
TitleLocId="Null"
MissingAssembly="Cannot import this Web Part."
PartImageSmall=""
AllowRemove="True"
HelpMode="Modeless"
FrameType="None"
AllowZoneChange="True"
PartOrder="1"
Description="Enable users to leave short, publicly-viewable notes about this page."
HelpLink=""
DescriptionLocIdNum="0"
ExportControlledProperties="True"
IsIncludedFilter=""
\_\_MarkupType="vsattributemarkup"
\_\_WebPartId="{5937b022-83bb-40cb-b68f-bd565bf96885}"
WebPart="true"
Height=""
Width="">
</SPSWC:SocialCommentWebPart>
```Then add your user control into page layout like this:
<%@ Register Tagprefix=“CONTOSO” TagName=“SocialComment” Src="~/_CONTROLTEMPLATES/CONTOSO/SocialCommentUserControl.ascx" %> <CONTOSO:SocialComment id=“SocialComment” runat=“server” />
Sharepoint repos on github
You may think all interesting open source Sharepoint projects on codeplex. Well it is true, but there are some interesting projects on github as well. There are 17 projects for now. From a matrix to RichControls.
Webparts on a layoutpage which is provisioned several times
It is pretty easy to add webparts to a layout page. Just define the webparts in the corresponding Elements.xml file. Like you do in onet.xml. It works fine if you provision just a single page with this layout on a web. If you have multiple pages that use the same page layout (e.g. in WCM). The trick is to use the attribute IgnoreIfAlreadyExists in the File tag:
IgnoreIfAlreadyExists="True"
Comments from Wordpress.com
Webpart in a reusable user control « Sharepoint. Kunskap. Upptäckter på resan. - Sep 1, 2011
TryGetList
How do we get a list? Perhaps like that:
var list = web.Lists\[listname"\];
```But we must be aware of exceptions that can appear and we must handle them. A better way to get a list is to use [TryGetList](http://sharepoint.stackexchange.com/questions/18035/custom-webpart-being-rendered-twice-on-layout-page):
var list = web.Lists.TryGetList(listname);
WithWeb-pattern of Jonas Nilsson
Jonas Nilsson shows an interesting approach for working with SPSite and SPWeb which must be disposed. Create a helper method WithWeb and send an Action parameter:
public void WithWeb(string uri, Action<SPWeb> action)
{
using (SPSite site = new SPSite(uri))
{
using (SPWeb web = site.OpenWeb())
{
action(web);
}
}
}
```Here is my implementation of this pattern:
public static class DisposalService { public static void WithWeb(string uri, Action action) { using (var site = new SPSite(uri)) { using (var web = site.OpenWeb()) { web.UnsafeUpdate(action); } } } public static void WithElevatedWeb(string uri, Action action) { SPSecurity.RunWithElevatedPrivileges(() => WithWeb(uri, action)); } }
Compare two TimeSpan objects
var TimeToIgnore = new TimeSpan(0, 0, 0, 60); var created = (DateTime)properties.ListItem[SPBuiltInFieldId.Created]; var now = DateTime.Now; var span = now.Subtract(created); return span.CompareTo(this.TimeToIgnore) < 0;
Server Relative Url of an SPListItem
The easiest way to get the server relative url of an SPListItem is to retrieve the property “ServerUrl”.
SPListItem item...
var url = item\["ServerUrl"\];
Check if user is in group
Use LINQ to check if user is in a group. Create an extension method.
public static bool InGroup(this SPUser user, SPGroup group)
{
return user.Groups.Cast<SPGroup>()
.Any(g => g.ID == group.ID);
}
```EDIT 2011-01-22: There is a shortcoming of this method. You won't get a user which is in group through a AD group. You'll get only users and ad groups. [But there is another method to check if a user is inside an AD group](/2012/01/16/check-if-a-user-is-in-a-ou/ "See my post about how to retrieve users from AD groups with PrincipalSearcher"). How could we combine them?... I think we must start from group this time, not from user:
public static bool HasUser(this SPGroup user, SPUser user) { var users = group.Users.Cast(); var samAccount = Regex.Replace(user.LoginName, @".*\\(.*)", “$1”, RegexOptions.None); var exists = users.Any(u => u.LoginName.Equals(user.LoginName)); if (!exists) { var ctx = new PrincipalContext(ContextType.Domain); foreach (var u in users) { var login = u.LoginName; var groupName = Regex.Replace(login, @".*\\(.*)", “$1”, RegexOptions.None); var grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName); if (grp == null) continue; var principals = grp.GetMembers(true); exists = principals.Any(p => p.SamAccountName.Equals(samAccount, StringComparison.InvariantCultureIgnoreCase)); if (exists) break; } } return exists; }
PublishingRollupImage
The internal name of Rollup Image or Upplyft bild is PublishingRollupImage
Content Type Id for Image, Audio and Video
After debugging I have found the Content Type Ids for Image, Audio and Video in the assets library. These content type ids are not present in SPBuiltInContentTypeId.
public class SPBuiltInContentTypeIdExtension
{
public static SPContentTypeId Video =
new SPContentTypeId
("0x0101009148F5A04DDD49CBA7127AADA5FB792B00291D173ECE694D56B19D111489C4369D");
public static SPContentTypeId Audio =
new SPContentTypeId
("0x0101009148F5A04DDD49CBA7127AADA5FB792B006973ACD696DC4858A76371B2FB2F439A");
public static SPContentTypeId Image =
new SPContentTypeId
("0x0101009148F5A04DDD49CBA7127AADA5FB792B00AADE34325A8B49CDA8BB4DB53328F214");
}
These three asset content types inherit from Document CT (“0x0101”) and have “0x0101009148F5A04DDD49CBA7127AADA5FB792B” in common, which is the content type id for multimedia content type. So if you want to check if it is a multimedia, use this id. You can see the content type id when you go to Site Actions - Site Settings - Content Types. Click on a content type you interested in. In the address bar of your browser find ?ctype=.
Rensa text från html-taggar
Ett bra exempel finns här.
using System.Text.RegularExpressions;
...
const string HTML\_TAG\_PATTERN = "<.\*?>";
static string StripHTML (string inputString)
{
return Regex.Replace(inputString, HTML\_TAG\_PATTERN, string.Empty);
}
lästips om sharepoint-licenser
Känns licenser för Sharepoint är ett djungel. Läs det här bloginlägget.
less.js
Det finns ett intressant projekt som kan hjälpa att strukturera css-filer. Du skriver regler i en kombination av css och javascript. Det omvandlas med hjälp av js till css. Projektet heter less.js, läs mer om detta på sharepointoverflow.
Se om det är en tråd eller inlägg i diskussionsforum
Diskussioner sparas i en vanlig lista. En ny tråd sparas som en folder. Alla svar sparas som SPListItem i den foldern. En folder är så klart också en SPListItem, fast har en annan typ. För att se om det är en tråd, kan man jämföra ett fält som har ett guid som man kommer åt via SPBuiltInFieldId.FSObjType.
var item = properties.ListItem;
var type = Convert.ToInt32(item\[SPBuiltInFieldId.FSObjType\]);
var foldertype = (int) SPFileSystemObjectType.Folder;
if (type == foldertype)
{
//Yes, this is the thread head
var body = item\["Body"\].ToString();
}
AfterProperties kräver InternalName
AfterProperties kommer inte leda till Exception, men de kommer returnera bara null, om du använder DisplayName. Man måste ha InternalName. Här är ett litet exempel på hur man kan få ut värden före och efter uppdateringen. Exemplet har testats i ItemUpdated-eventreceiver.
var before = properties.BeforeProperties;
var after = properties.AfterProperties;
var contentDisplayName = "News Content";
var list = properties.List;
var contentInternalName = list.Fields\[contentDisplayName\].InternalName;
var contentBefore = before\[contentInternalName\];
var contentAfter = after\[contentInternalName\];
window.onload
Sharepoint ger en annan lösning för window.onload och jQuery(document).ready(function() {}); _spBodyOnLoadFunctionNames.push(‘gerdaRibbonInit’);"
ViewState
Om du vill behålla dina värden på variabler mellan postbacks, använd ViewState:
if (ViewState\["MaxNumberOfArticles"\] != null)
{
MaxNumberOfArticles = (int) ViewState\["MaxNumberOfArticles"\];
}
MaxNumberOfArticles += 10;
ViewState.Add("MaxNumberOfArticles", MaxNumberOfArticles);
RenderNews();
Webpart Livscykel
http://nishantrana.wordpress.com/2009/02/14/understanding-web-part-life-cycle/ OnInit – Configuration values set using WebBrowsable properties and those in web part task pane are loaded into the web part. LoadViewState – The view state of the web part is populated over here. CreateChildControls – All the controls specified are created and added to controls collection. When the page is being rendered for the first time the method generally occurs after the OnLoad() event. In case of postback, it is called before the OnLoad() event. We can make use of EnsureChildControls() - It checks to see if the CreateChildControls method has yet been called, and if it has not, calls it. OnLoad User Generated Event – for e.g. button click on the web part. OnPreRender – Here we can change any of the web part properties before the control output is drawn. RenderContents – Html Output is generated. SaveViewState - View state of the web part is serialized and saved. Dispose UnLoad.
Kontrollera om SPView finns
bool exists = splist.Views.Cast().Any(view => string.Equals(view.Title, viewName));
Lägg till en sida
Här är ett litet exempel på hur man kan lägga till sidor:
private void PublishNews(SPWeb web, string spamnewsname)
{
PublishingSite pSite = new PublishingSite(web.Site);
SPContentType ctype = pSite.ContentTypes\["NewsPageContentType"\];
PageLayoutCollection pageLayouts = pSite.GetPageLayouts(ctype, true);
PageLayout pageLayout = pageLayouts\["/\_catalogs/masterpage/MyNewsLayout.aspx"\];
PublishingWeb pWeb = PublishingWeb.GetPublishingWeb(web);
PublishingPageCollection pPages = pWeb.GetPublishingPages();
PublishingPage pPage = pPages.Add(spamnewsname, pageLayout);
SPListItem newpage = pPage.ListItem;
newpage\["Title"\] = "Page added programmatically";
newpage\["NewsContent"\] = lorem;
newpage.Update();
newpage.File.CheckIn("all looks good");
newpage.File.Publish("all looks good");
}
formatera int
Här finns en lista över formateringsmöjligheter med C# string.Format
String.Format("{0:00000}", 15); // "00015"
resharper
Bara att rekommendera. Dagens: Ctrl-Shift-Backspace: Go to last edit. http://www.jetbrains.com/resharper/webhelp/Reference__Keyboard_Shortcuts.html http://blog.drorhelper.com/2009/05/15-resharper-keyboard-shortcuts-you.html
commaseparatedaccounts
om du lägger till commaseparatedaccounts i PeopleEditor, använd ett komma, inte semikolon, som man kan tro…
jQuery validation with asp.net
De kan var lite jobbigt att få till jQuery validate att funka ihop med aspnetForm…
$(document).ready(function () {
newsLetterForm = $("#aspnetForm");
newsLetterForm.validate({
onsubmit: false,
rules: {
"<%= emailTextBox.UniqueID %>": {
required: true,
email: true
}
}
});
$("#<%= sendButton.ClientID %>").live("click", function {
var isValid = newsLetterForm.valid();
if (!isValid) {
e.preventDefault();
}
});
});
jQuery validate kräver name på elementen inuti formen. För att ta reda på name, måste man använda Control.UniqueId För att det ska fungera måste du köra preventDefault()
webpart för att uppdatera title och description av web
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"
Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages"
Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="WelcomeTextUserControl.ascx.cs"
Inherits="MyProject.WelcomeTextUserControl" %>
<style type="text/css">
#welcome-text-wp-input-title
{
font-size: 2em;
}
.welcome-text-wp-edit-mode, #welcome-text-wp-updateImage
{
display: none;
}
</style>
<img src="/\_layouts/Images/homepageSamplePhoto.jpg" alt="sample" class="teamsite-welcome-text-image">
<h1 id="welcome-text-wp-web-title" class="welcome-text-wp-show-mode">
<%= SPContext.Current.Web.Title %></h1>
<p id="welcome-text-wp-web-description" class="welcome-text-wp-show-mode">
<%= SPContext.Current.Web.Description %></p>
<img src="../\_layouts/images/loading16.gif" id="welcome-text-wp-updateImage" />
<SharePoint:SPSecurityTrimmedControl ID="SPSecurityTrimmedControlUpdateWelcomeText"
runat="server" Permissions="ManageLists">
<div>
<div>
<input type="text" id="welcome-text-wp-input-title" value="<%= SPContext.Current.Web.Title %>"
class="welcome-text-wp-edit-mode input" />
</div>
<textarea rows="5" cols="25" id="welcome-text-wp-input-description" class="welcome-text-wp-edit-mode input"><%= SPContext.Current.Web.Description %></textarea>
<p id="welcome-text-wp-edit-button" class="welcome-text-wp-show-mode" onclick="javascript:toggleInputsVisibility();">
edit</p>
</div>
<div>
<input type="button" id="welcome-text-wp-input-submit" value="spara" class="welcome-text-wp-edit-mode button"
disabled="disabled" />
<input type="button" id="welcome-text-wp-input-cancel" value="avbryt" class="welcome-text-wp-edit-mode button" />
</div>
<script type="text/javascript">
function updateWeb(webTitle, webDescription) {
var ctx = new SP.ClientContext.get\_current();
this.web = ctx.get\_web();
web.set\_title(webTitle);
web.set\_description(webDescription);
this.web.update();
toggleUpdateImageVisibility();
ctx.executeQueryAsync(Function.createDelegate(this, this.onSuccessfulWebUpdate),
Function.createDelegate(this, this.onFailedWebUpdate));
}
function onSuccessfulWebUpdate(sender, args) {
var webTitle = jQuery("#welcome-text-wp-input-title").attr("value");
var webDescription = jQuery("#welcome-text-wp-input-description").attr("value");
jQuery("#welcome-text-wp-web-title").text(webTitle);
jQuery("#welcome-text-wp-web-description").text(webDescription);
toggleInputsVisibility();
toggleUpdateImageVisibility();
showWelcomeTextUpdateMessage("Välkomsttext uppdaterad")
}
function onFailedWebUpdate(sender, args) {
resetValuesAndToggleInputsVisibility();
toggleUpdateImageVisibility();
showWelcomeTextUpdateError('failed to update title. Error:' + args.get\_message())
}
function toggleInputsVisibility() {
jQuery(".welcome-text-wp-show-mode, .welcome-text-wp-edit-mode").toggle();
}
function toggleUpdateImageVisibility() {
jQuery("#welcome-text-wp-updateImage").toggle();
}
function resetValuesAndToggleInputsVisibility() {
var webTitle = jQuery("#welcome-text-wp-web-title").text().trim();
var webDescription = jQuery("#welcome-text-wp-web-description").text().trim();
jQuery("#welcome-text-wp-input-title").attr("value", webTitle);
jQuery("#welcome-text-wp-input-description").attr("value", webDescription);
toggleInputsVisibility();
}
function showWelcomeTextUpdateError(errorMessage) {
showWelcomeTextUpdateMessage(errorMessage);
}
function showWelcomeTextUpdateMessage(msg) {
SP.UI.Notify.addNotification(msg, false)
}
jQuery(document).ready(function () {
jQuery(".welcome-text-wp-edit-mode.input").live("keyup", function () {
jQuery(".welcome-text-wp-edit-mode.button").removeAttr("disabled");
});
jQuery("#welcome-text-wp-input-submit").live("click", function () {
var webTitle = jQuery("#welcome-text-wp-input-title").attr("value");
var webDescription = jQuery("#welcome-text-wp-input-description").attr("value");
updateWeb(webTitle, webDescription);
});
jQuery("#welcome-text-wp-input-cancel").live("click", function () {
resetValuesAndToggleInputsVisibility();
});
});
</script>
</SharePoint:SPSecurityTrimmedControl>
pause in Powershell
Om man högerklickar och väljer “Run With Powershell”, är det bra om fönstret inte försvinner… Det hade varit bra med en funktion som pause… Här kommer väl till pass en egen pause.:
function Pause ($Message="Press any key to continue...")
{
Write-Host -NoNewLine $Message
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Write-Host ""
}
powershell.exe -Command
man kan skapa en .bat-fil med olika powershell-anrop:
powershell.exe -Command "& {.\\Script1.ps1}"
Vilka rättigheter står bakom olika roller
Här är en lista. För att få fram den listan kan man köra kod:
StringBuilder sb = new StringBuilder();
using (SPSite site = new SPSite("http://wss"))
{
using (SPWeb web = site.OpenWeb())
{
SPRoleDefinitionCollection roleDefinitions = web.RoleDefinitions;
foreach (SPRoleDefinition roleDefinition in roleDefinitions)
{
sb.Append(System.Environment.NewLine + System.Environment.NewLine +
"Role Definition: " + roleDefinition.Name + System.Environment.NewLine +
"==================================================" +
System.Environment.NewLine);
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(roleDefinition.Xml);
XmlNode nodes = xmldoc.DocumentElement;
sb.Append(nodes.Attributes\["BasePermissions"\].Value);
}
textBox1.Text = sb.ToString();
}
}
Vänta tills sp.js laddats
Här är en funktion som man kan använda för att vänta till sp.js laddats och köra sin funktion:
ExecuteOrDelayUntilScriptLoaded(myjsfucntion, "sp.js");
Eftersom det kan vara så att sp.js laddas med lazy loading:
<SharePoint:ScriptLink Name="SP.js"
runat="server" OnDemand="true"
Localizable="false"
Uppdatera web med js
Här är ett litet exempel:
function updateTitle() {
var ctx = new SP.ClientContext.get\_current();
this.web = ctx.get\_web();
web.set\_title('Examensarbete 2011');
this.web.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onUpdate),
Function.createDelegate(this, this.onFail)); }
function onUpdate(sender, args) {
alert('title updated');
}
function onFail(sender, args) {
alert('failed to update title. Error:'+args.get\_message());
}
Sharepoint Manager 2010
Ett ytterligare grym verktyg från codeplex-lägret: Sharepoint Manager.
jQuery hide
Jag har alltid använt hide-funktionen i jQuery för att gömma vissa element som inte behövs i början. Det kan resultera att användaren ser skymningen av dem i laddningen av sidan. Vilket inte är så bra. Men det har visat sig, att hide behöver inte köras av jQuery. Bara göm dem med hjälp av css. jQuery show kommer funka ändå.
spribbon fluent
Ett mycket intressant projekt för att skapa ribbon-anpassningar. Som så här:
new ButtonDefinition()
{
Id = "New",
Title = "Start new game",
CommandJavaScript = "window.location.reload();",
Image = new ImageDefinition()
{
Url16 = "/\_layouts/images/ChessWebPart/new16.png",
Url32 = "/\_layouts/images/ChessWebPart/new32.png"
}
}
```Så blir resultatet: ![spribbong](http://markeev.com/sharepoint/ribbon/media/buttonSample.png)
Viss hjälpinnehåll
Om det strular med att visa hjälpinnehåll, följ denna beskrivning för att lösa det. Du måste ge rättigheter på procedure som heter proc_EnumResourcesAtScope på Sharepoint-AdminContent-databasen:
GRANT EXECUTE ON " proc\_EnumResourcesAtScope" TO "contoso\\SP\_Apppool"
Registrera javascript i feature
Om det inte passar att javascript i masterpage eller egen webpart, registrera det som customaction och aktivera feature. Läs mer här. Här är ett exempel:
<CustomAction
Location="ScriptLink"
ScriptSrc="~sitecollection/\_layouts/MyProject/awesome.js"
Sequence="101">
</CustomAction>
Hämta innehåll på något element i contentEditorWebpart
string content = welcomeWebpart.Content.InnerText;
//get heading
string heading = string.Empty;
Match m = Regex.Match(content, @"(
.\*?
====
)", RegexOptions.Singleline);
if (m.Success)
{
heading = m.Groups\[1\].Value;
}
heading = Regex.Replace(heading, @"(
|
=
)", "", RegexOptions.Singleline);
welcomeValues.Add("#HEADING#", heading);
Hämta lokaliserad sträng från App_GlobalResources
Om man har en sträng i App_GlobalResources som man vill hämta ifrån koden, kör:
string text = HttpContext.GetGlobalResourceObject("MyProject\_Global", "submit\_label") as string;
Rättigheter på CustomAction
Om man vill begränsa vem so kan se kan man lägga till “Rights”-attribut på CustomAction. Ett exempel: Hela listan finns på msdn.
Ändra content i ContentEditorWebPart
Det finns ett exempel här.
//defaultAspx är sidan (SPListItem i Sidor)
//måste checkas ut först
//mgr är WebPartManager
//wp är contentEditorWebPart
web.AllowUnsafeUpdates = true;
XmlDocument xmlDoc = new XmlDocument();
XmlElement xmlElement = xmlDoc.CreateElement("Content");
xmlElement.InnerText = ((Microsoft.SharePoint.WebPartPages.ContentEditorWebPart)wp).Content.InnerText.ToString();
xmlElement.InnerText = xmlElement.InnerText.ToString().Replace("#HEADING#", "Welcome for welcome");
wp.Content = xmlElement;
mgr.SaveChanges(wp);
defaultAspx.File.CheckIn("");
defaultAspx.File.Publish("");
web.AllowUnsafeUpdates = false;
```Man måste skapa nytt XmlDocument och XmlElement, om man försöker skriva direkt till wp.Content.InnerText kommer det inte uppdateras. I det här fallet, byter vi ut #HEADING# mot något mer passande.
styra css för modaldialog
Säg du har application page med samma master page som resten av portalen. Men vad göra om du vill ändra css bara om den är i modal dialog. Overrida dina css-regler genom att lägga till .ms-dialog. .ms-dialog är css-klassen som läggs på html-taggen om sidan laddas i modaldialog:
html.ms-dialog body {
background-color:white;
}
Ge andra rättigheter på default.aspx
Om man inte vill medlemmarna på SPWeb rättighet att redigera första sidan hur som helst, måste man bryta arvet på Sidor/default.aspx. Lätt att göra det manuellt (Site Actions - Show all Content - Pages - default.aspx - dokumenträttigheter). I koden kan man göra det så här:
//first find SPListItem defaultAspx
//then find SPGroup members (perhaps via web.AssociatedMemberGroup
defaultAspx.BreakRoleInheritance(true);
defaultAspx.RoleAssignments.RemoveFromCurrentScopeOnly(members);
SPRoleAssignment roles = new SPRoleAssignment(members);
SPRoleDefinition perms = web.RoleDefinitions.GetByType(SPRoleType.Reader);
roles.RoleDefinitionBindings.Add(perms);
defaultAspx.RoleAssignments.Add(roles);
Sök på hela SPSite
När man skapar en egen searchbox, kan det vara lite meckigt att få till söken rätt. För att kunna söka på hela SPSite, oberoende var man är (subsite), ange property:
<Property Name="DropDownMode">**HideDD\_useDefaultScope**</Property>
Det kan hända att du måste skapa en egen scope.
PeopleEditor med ifyllt värde
I vissa fall är det bra att ha ett ifyllt värde i PeoplePicker, till exempel, namn på personen som kör koden. Det finns olika beskrivningar om hur man gör det. Allmänt, och mer specifikt för webparts. Jag har även testat kod från boken Sharepoint 2010 as a Development Platform:
private PeopleEditor peopleEditor;
private void EnsureChildControls()
{
peopleEditor = new PeopleEditor();
peopleEditor.AutoPostBack = true;
peopleEditor.ID = "MyPeopleEditor";
peopleEditor.AllowEmpty = false;
peopleEditor.MultiSelect = true;
peopleEditor.SelectionSet = "User,SPGroup" ;
MyPanel.Controls.Add(peopleEditor);
}
protected void initPeopleEditor()
{
PickerEntity entity = new PickerEntity();
entity.Key = SPContext.Current.Web.CurrentUser.LoginName;
// Make sure the entity is correct
entity = peopleEditor.ValidateEntity(entity);
ArrayList entityArrayList = new ArrayList();
entityArrayList.Add(entity);
peopleEditor.UpdateEntities(entityArrayList);
}
```Problemet med denna kod är att man får felet "Ingen exakt matchning" och man kan inte submitta. I application pages kan man enkelt fylla i aktuella användaren genom att ändra **CommaSeparatedAccounts** property i **Page\_Load**\-metoden.
peopleEditor.CommaSeparatedAccounts = SPContext.Current.Web.CurrentUser.LoginName;
~masterurl/default.master & ~masterurl/custom.master
Läser “SharePoint 2010 as a Development Platform”. Kan verkligen rekommendera den. Idag har jag förståt vad default.master och custom.master innebär. De pekar på de master-filer som är inställda på web-nivå. Så det är ingen idé att ändra DynamicMasterUrl i @Page-direktivet till sin egen (om du inte vill ha någon helt annan master än i resten av portalen).
Flaggor i powershellfunktioner
Har länge letat efter möjligheten att skriva funktioner med egna flaggor på ett enkelt sätt. “Flaggor” (flags) är namngivna parametrar. Följande kommando har flaggor: -Identity, -WebApplication och -GACDeployment.
Install-SPSolution -Identity contoso.portal.wsp -WebApplication http://contoso -GACDeployment
```Låt oss titta på ett gammalt exempel:
function hello($firstname, $lastname) { Write “Hello $firstname $lastname” }
hello -firstname Gregor -lastname Samsa
hello -lastname Samsa -firstname Gregor
function helloInColor($firstname, $lastname, [switch]$red = $false, [switch]$green = $false) { $greeting = “Hello, $firstname $lastname” if($red) { Write-Host -ForegroundColor Red $greeting } if($green) { Write-Host -ForegroundColor Green $greeting } }
Lägg till en annan administrator på site collection
Man kan göra det i CA (Application Mgmnt - Change Site Cltn Admins). Det kan man också snabbt göra med powershell:
Set-SPSite http://contoso -SecondaryOwnerAlias contoso\\admin2
defaultvärde på parametern i powershellfunktioner
Läser ett intressant inlägg om deployskript i powershell. Har upptäckt att man kan stoppa in ett defaultvärde i funktionens parameter. Så i stället för
function hello($name) {
Write-Host $name
}
Kan man köra:
function hello($name = "Gregor") {
Write-Host $name
}
```Mycket smidigt.
Videokurs om Web Content Management
På microsoft.com finns en ny videokurs om web content management. Där kan du lära dig om hur man implementerar cms-funktionalitet med sharepoint, bl.a.: content types, page layouts med mera. Tack för tipset, deutschsprachige Sharepoint-Community.
Autocomplete för sökruta i Sharepoint
Ett mycket trevligt projekt: Search As You Type på Codeplex. Ladda ner textfilen och lägg till javascript och css från den filen till masterpage. Så enkelt är det. Jag har testat det genom att direkt stoppa in koden i Chrome Console.
uls logger
Det finns ett intressant projekt på codeplex: ULS Logger. Är absolut värt att testa.
SPSecurityTrimmedControl
Ett mycket bra inlägg från Tom Puleos blogg om SPSecurityTrimmedControl. Måste absolut testa det.
parametrar i powershell-funktioner
Man kan skapa funktioner med parametrar som påminner mycket om i C#. Så i stället för:
function Just-Test {
Write-Host $args\[0\]
}
```Skriv:
function Just-Test($param) { Write-Host $param }
if($site -ne $null -and $url -ne $null) {“Url OR Site can be given”; return}
powershell_ise
Powershell ISE (Integrated Scripting Environment) är ett bra verktyg för att skriva powershell-skript med färgmarkering och möjligheten att testköra det. Synd bara att det inte är aktiverat ifrån början i Server 2008. För att [aktivera](Import-Module ServerManager 2 Add-Windowsfeature PowerShell-ISE ) kör följande kommandon i powershell:
Import-Module ServerManager
Add-Windowsfeature PowerShell-ISE
För att sedan starta powershell kör:
powershell\_ise
Lägga till Företagsnyckelord
Det är enkelt att lägga till kolumnen företagsnyckelord. Skapa egen contenttype och lägg till fieldref.
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
Funkar utmärkt t.ex. om du ärver ContentTypen från Announcements. Lite svårare är det med Dokument. I själva verket läggs till fler kolumner för att det ska fungera. I Announcements finns de redan. Men i dokument måste du lägga till dem extra:
<!-- Enterprise Keywords-->
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
<!-- in order keywords to work, two additional fields have to be created-->
<!-- TaxKeywordTaxHTField -->
<FieldRef ID="{1390a86a-23da-45f0-8efe-ef36edadfb39}"/>
<!-- TaxCatchAll -->
<FieldRef ID="{f3b0adf9-c1a2-4b02-920d-943fba4b3611}"/>
Utan TaxKeywordTaxHTField uppstår fel av typen: “Kan inte hämta värdet från kolumnen {00000000…}”.
Länkar på quicklaunchen
Det är en skum grej: Länkar (listor och bibliotek, kalender och dylikt) visas inte. När jag har ändrat Navigation properties i min konfiguration i onet.xml, då funkar det:
<WebFeatures>
...
<!-- Navigation Properties -->
<Feature ID="541F5F57-C847-4e16-B59A-B31E90E6F9EA">
<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<Property Key="InheritGlobalNavigation" Value="true"/>
**<Property Key="ShowSiblings" Value="false"/>**
<Property Key="IncludeSubSites" Value="true" />
<Property Key="IncludePages" Value="false" />
</Properties>
</Feature>
</WebFeatures>
Sharepoint CSS Chart
Mycket bra resurs om olika css-klasser och id i standard Sharepoint. Bara att börja designa… http://sharepointexperience.com/csschart/csschart.html
masterpage i application page
Om det inte funkar att ändra masterpage genom DynamicMasterPageFile:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CreateNews.aspx.cs" Inherits="MyProject.Layouts.MyProject.CreateNews"
DynamicMasterPageFile="~masterurl/default.master" %>
Kör det här
<script type="text/C#" runat="server">
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
this.MasterPageFile = "/\_catalogs/masterpage/my-custom.master";
}
</script>
field type
Här är en hel lista över olika typer som Field kan få i Content Type. Type=“File” motsvarar SPFieldFile
Visa i hur länge sedan något hänt
Säg du vill visa när något har skapats. Att visa datum funkar. Ännu bättre är att visa det i stil: “För tre dagar sedan” eller så. Det finns en bra metod i SPUtility:
SPUtility.TimeDeltaAsString(Published, DateTime.Now);
ID på befintliga kolumner
Det finns en fin lista över id på kolumner som man kan lägga till. Här är ett exempel hur man kan använda det. Här är ett exempel på två extra kolumner i contenttype:
<FieldRefs>
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
<!-- Enterprise Keywords-->
<FieldRef ID="{3de94b06-4120-41a5-b907-88773e493458}"/>
<!-- PublishingImage-->
</FieldRefs>
javascript API i Sharepoint
Det är supersmidigt. Här är ett exempel:
function createAnnouncement(title, body) {
var ctx = new SP.ClientContext.get\_current();
var list = ctx.get\_web().get\_lists().getByTitle('Meddelanden');
var itemCreationInfo = new SP.ListItemCreationInformation();
this.newListItem = list.addItem(itemCreationInfo);
this.newListItem.set\_item("Title", title);
this.newListItem.set\_item("Body", body);
this.newListItem.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onSucceededCallback), Function.createDelegate(this, this.onFailedCallback));
}
function onSucceededCallback(sender, args) {
SP.UI.Status.addStatus("Info", "It worked!",true);
}
function onFailedCallback(sender, args) {
SP.UI.Status.addStatus("Info", "It didn't work!",true);
}
Comments from Wordpress.com
westerdaled - Feb 0, 2013
Validera din form på klienten
Det finns ett mycket bra jQuery-tillägg som kan validera din data i en formulär på ett enkelt sätt. Se en demo. Referera till validate.js och ange rätt css-klasser på dina inputs: “required”, “error”, “url”, “valid”. Mycket smidigt.
cloud9 web ide
Skapa javascript-appar i din webbläsare. Mycket smidigt. Direkt kontakt till github.
Använd egen logo på feature
För att använda en egen logo på feature, lägg till en bild på 31x22px i mapped image folder, och referera till den i your-feature.Template.xml: ImageUrl=“YOUR_PROJECT/mylogo.gif” (/_layouts/images/ behövs inte i sökvägen)
Gratis webparts från Amrein
Finns gratis webparts från Amrein Engineering. Fått tips från sharepoint.stackexchange.com. Testat AELightBox. Men det är rätt så krångligt med inställningar. Den kräver att man skriver in vilken vy och så vidare. Vyn ska ha “title” och den kräver även kolumner så som ImageWidth och ImageHeight. Detta känns lite mindre användbart eftersom de här värdena kunde man hämta från bilden själv och anpassa till skärmens upplösning. [caption id=“attachment_405” align=“aligncenter” width=“291” caption=“Amrein Lightbox”][/caption]
Delegate Control
Just nu håller jag på med ribbon och en teknik jag precis upptäckt som är bra för att få igenom kod för alla sites i en site collection är Delegate Control. Jag tänkte tippsa om länkarna här då det är något som alla utvecklare kan behöva lära sig för eller senare. http://www.sharepointnutsandbolts.com/2007/06/using-delegate-control.html http://www.devx.com/enterprise/Article/36628
Hämta en lokaliserad sträng
Om du använder olika språk så lär du använda Sharepoints lokaliseringsverktyg ($Resources…) Här är ett sätt att hämta generiskt ett värde:
string res = "$Resources:ContosoPortal, List\_Products";
string listName = SPUtility.GetLocalizedString(res,
"Produkter",
(uint)CultureInfo.CurrentCulture.LCID);
```I andra rader stoppar vi in även default-värde
TreeNode
Ibland vill man visa data i TreeView. Här är ett litet exempel på koden:
using (SPWeb web = SPContext.Current.Web)
{
foreach (SPWeb topWeb in web.GetSubwebsForCurrentUser())
{
TreeNode tn = new TreeNode(topWeb.Name);
tn.NavigateUrl = topWeb.ServerRelativeUrl;
this.treeviewProjects.Nodes.Add(tn);
if (topWeb.Webs.Count > 0)
{
foreach (SPWeb subWeb in topWeb.GetSubwebsForCurrentUser())
{
TreeNode childNode = new TreeNode(subWeb.Name);
childNode.NavigateUrl = subWeb.ServerRelativeUrl;
tn.ChildNodes.Add(childNode);
subWeb.Dispose();
}
}
topWeb.Dispose();
}
}
ForEach-metod i List
En intressant variant av foreach är ForEach-metoden i List. Titta på det lilla exemplet:
private static void SavePlacesToDB(SQLiteConnection cnn,
List<dynamic> places)
{
places.ForEach(obj => SavePlaceToDB(obj, cnn));
}
```Här används även det nya objektet [dynamic](http://msdn.microsoft.com/en-us/library/dd264736.aspx) som har kommit i Visual Studio 2010, samt en [lambda expression (=>)](http://msdn.microsoft.com/en-us/library/bb397687.aspx).
Chuvash Keyboard for Android
Now there is a Chuvash keyboard for Android. The little program uses AnySoftKeyboard application, gives the ability to write in Cyrillic and Latin. All kinds of feedback are appreciated. Chuvash Keyboard for Android is open source like AnySoftKeyboard.
Uppföljning till automatisk installation av Sharepoint utvecklingsmiljö på Windows 7
I mitt förra inlägg skrev jag kort om några intressanta länkar kring poweshell-skriptbaserad installation av allt som behövs på in utvecklingsmaskin för Sharepoint 2010 lösningar. Nu har jag testat installera skriptet på en ny installation Windows 7 64-bit på en rad olika sätt. Till en början testade jag skriptet på en nyisntallerad Windows 7 virtuell VMPlayer maskin. Det fungerade bra, utan krångel. Sedan installerade jag Windows 7 på en virtuell VHD maskin, som jag bootade native från. För mer info se inläggen som Anatoly redan skrivit. Sedan gjorde jag en kopia på denna VHD. Bootade från en av dem och startade skriptet, i config.xml filen ändrade jag några rader som såg till att min kopia som jag inte bootade från för tillfället fick så som mall vid skapandet av en ny VHD som sedan alla isntallationsfiler för sharepoint installation kopierades till. Efter det så fixade skriptet en nytt startalternativ i BCDn, startade denna och installerade allt som behövdes på den sista VHDn. Funktionen för VHDn kändes helt onödig i mitt fall. Då jag kunde kört skriptet från en VHD från början. Istället stötte jag på ett par problem. Först så fick jag ett problem då jag skriptet skulle maunta VHDn för att föra över installationsfilerna. Då denna VHD var en kopia på systemet jag just nu körde ifrån blev det en krock på de unika disk identifikationerna. Så innan detta steget fungerade var jag tvungen att manuellt ändra uniqe disk Id eller vad det nu hette på min VHD. Det kan göras via diskpart. Samma verktyg som används vid skapandet av VHDn. Vid intresse från läsare eller tid över kan jag förklarade i detalj hur denna process fungerar. Problem två var att mot slutet av skriptkörningen fick jag ett felmeddelande angående att jag som användare inte hade rättigheter till att ändra i sharepoint databasen eller liknande. Jag antar att det hängde ihop med att jag bytt användarnamn på kontot automatisk då jag använde sysprep innan jag gjorde en kopia på den nyinstallerade VHDn. Efter första starten med sysprep i autitmode så skapas en tempanvändare. Och detta ställde till det. Men det enda som återstog i installationen var SharePoint 2010 Products Configuration Wizard, vilket jag kunde göra manuellt. Jag glömde berätta att jag provade att ändra produktnycklarna från de som är standard (trail-versioner) till de som jag fått via msdna. Men nånting gick inte som det skulle och detta var på ett Windows 7 system jag redan labbat lite med. Ska prova ändra dessa nycklar nästa gång jag gör en ren installation. Ska jag göra det en gång till så har jag några saker jag skulle prova annorlunda. Det kommer förmodligen ske inom en snar framtid och när jag kommit fram till en bra metod tänker jag posta den här. Men så här har jag planerat det:
Förenkla skapandet av utvecklingsmiljön till SharePoint 2010
Jag är fortfarande i mitt sökande efter den perfekta (för mig) utvecklingsmiljön för SharePoint 2010. Fram tills nu har jag arbetat med en virtuell (VMware) maskin som kollegor till mig har konfigurerat. Men jag vill ha kunskapen att göra det själv. Än så länge har jag bara stött på procedurer som är relativt långdragna, fram tills idag. Se på videon på sidan jag länkat nedan. Jag ska testa det och sen förhoppningsvis komma med resultat här. Mitt mål är att lätt komma igång med en maskin som körs som VHD eller native dualboot. Men jag börjar med en virtuell VMware maskin. Ett dygn senare: Igår lät jag skriptet köra (utan config ändringar) och efter många timmar är allt installerat och klart. Dock trailversioner. Men gör man det en natt efter 2 veckor eller när trailen är slut, då kan man börja på en ny maskin igen. Jag gillar skarpt detta skript! Ännu bättre blir det nog när man konfigurerar det att fixa en VHD. Kommer mer om det när det är testat! Länksamling Film från Channel 9 Ladda ner Scriptet här Skriptskaparnas bloggar http://blogs.msdn.com/b/cjohnson/archive/2010/10/28/announcing-sharepoint-easy-setup-for-developers.aspx http://blogs.msdn.com/b/pstubbs/archive/2010/10/27/sharepoint-2010-easy-setup-script.aspx
Bobusos. Rövarspråk translator
I have published my old app “Rövarspråksöversättare”, an assignment on the android course. Rövarspråket is the Swedish language game. Of course Bobusos (“bus” - en:prank in Rövarspråket) is open source and can be found on Github.
.gitignore for android
.gitignore is very important. This file tells git which files not to care about. I found a good template for android .gitignore: .metadata tmp/** .DS_Store *.tmp *.bak tmp/**/* *.swp *~.nib Thumbs.db Desktop.ini *~ *.apk bin gen local.properties *.jar **.classpath**
The only thing I have added is the last row: .classpath.
Comments from Wordpress.com
J. Pablo Fernández - Apr 2, 2011
Good beginners' tutorial on android, eclipse and git
Smashing magazine has a pretty good tutorial how to start programming for android using git, github, eclipse and datastorage. I recommend: Get Started Developing For Android With Eclipse, Reloaded
Update from git
So if you have an existing copy of the project, just type: git pull origin master
Or in Egit in Eclipse, right-click on repo and run “Fetch from upstream”.
New files in Eclipse
If there are new classes or files in the project (say you have got the latest version from github into existing workspace in Eclipse). In order for Eclipse to see them, right click on the package and press “Refresh”.
Get coordinates from Google Maps
To get longitude and latitude can be tricky at the first time. There are many ways to do this, e.g. getlatlon.com. Good enough, but not so practical if you want to collect many coordinates. You can’t search after street names, you only can scroll and drag. Another way is to use javascript to show the longitude and latitude. See this example. This works in all web browsers.Just find your object in Google Maps and paste this javascript in URL bar: javascript:void(prompt('',gApplication.getMap().getCenter()));
You’ll be prompted the coordinates values. Just be sure the map is centered on your object. There is a third, even better way. Use javascript, but don’t be annoyed with prompts. In Chromium (or Google Chrome) navigate to maps.google.com find your object, open the Console in DevTools (press Ctrl-Shift-J). Right click on the object → Center the map here In console write: copy ( gApplication.getMap().getCenter().toString() )
So now you can paste it wherever you need it. But the best with it is: you can do whatever you want and need before copying. In LUSites, I save the coordinates another way, first latitude and then longitude. So I can shift values, trim unnecessary stuff and so on. Look at it: var loc = gApplication.getMap().getCenter().toString(); var locTrimmed = loc.replace(/[() ]/gi,""); var locArray = loc.split(","); var newLoc = locArray[1] + "," + locArray[0]; copy (newLoc)
First I get the string of the coordinates. Then I erase the unnecessary stuff: (), blank space. After splitting I shift the longitude and the latitude and create a new string which is copied. Or, we can shorten this: var coordinates = gApplication .getMap() .getCenter() .toString() .replace(/[() ]/gi,"") .split(","); copy (coordinates[1] + "," + coordinates[0]);
The same in one row (to copy-paste): var coordinates = gApplication.getMap().getCenter().toString().replace(/[() ]/gi,"").split(","); copy (coordinates[1] + "," + coordinates[0]);
To avoid to copy this line of code, just press up arrow in the DevTools console.
Undvika postback i button
Äntligen har jag kommit på hur man kan skippa oönskad postback i button. Det finns många olika lösningar. Här är ett intressant inlägg på stackoverflow om det. Men det enklaste sättet är egentligen bara lägga till
return false;
```i onclick... Här är lösningen
using System.Web.UI.HtmlControls;
…
HtmlButton HtmlButtonSendMail;
protected override void CreateChildControls()
{
…
#region Configure Send Email
HtmlButtonSendMail = new HtmlButton();
HtmlButtonSendMail.InnerText = “Send Email”;
HtmlButtonSendMail.ID = “HtmlButtonSendMail”;
string script = “”;
script += “SP.UI.Notify.addNotification(‘Loading..’, false);”;
script += “var options = {”;
script += " url: \"../_layouts/Toolbox/SendMail.aspx\",";
script += " width: 800,";
script += " height: 680,";
script += " allowMaximize: false";
script += “};”;
script += “SP.UI.ModalDialog.showModalDialog(options);”;
script += “return false;”;
HtmlButtonSendMail.Attributes.Add(“onclick”, script);
HtmlButtonSendMail.Attributes.Add(“title”,
“Skicka mail till\r\nde här personerna”);
Controls.Add(HtmlButtonSendMail);
#endregion
…
}
…
protected override void Render(HtmlTextWriter writer)
{
…
writer.RenderBeginTag(HtmlTextWriterTag.Div);
HtmlButtonSendMail.RenderControl(writer);
writer.RenderEndTag();//div
…
}
… other javascript stuff needed to work with your ajax solution
Ny skribent
Jag är mycket glad att det finns en ny skribent på den här bloggen: timswe. Det här är en kille som har mycket att berätta om Sharepoint och om andra tekniker.
Programmers notepad
De flesta känner nog till Notepad++. Det finns en annan väldigt duktig textredigerare: Programmers notepad. Den är väldigt bra. code highlighting, filnavigering direkt i programmet mm. Testa gärna.
Powershell med tysk precision
Master Powershell ebookDe som har missat Powershell, läser nog andra sorts bloggar än denna. Så rak på sak: det finns en lovande ebook om Powershell, skriven av Tobias Weltner. Ska absolut läsa den. Ni som har läst, vad tycker ni om den? Master-PowerShell | With Dr. Tobias Weltner i html
Få alla items i Telerik Radgrid
Jag har haft följande problem: I Telerik Radgrid var Paging aktiverat. I varje Page visades 15 items, alltså när jag försökte hämta Items, så fick jag bara 15. Jag ville dock ta ut alla för att kunna skicka värden till en annan funktion på hemsidan (ModalDialog - om det i ett annat inlägg). Efter mycket googlande har jag hittat en lösning:
grid.MasterTableView.AllowPaging = false;
grid.MasterTableView.Rebind();
```Observera att man det måste vara grid.MasterTableView... Förresten, du behöver inte ändra det tillbaka (AllowPaging = true och Rebind). Det kommer inte påverka själva griden. Lite konstigt, men det funkar. Här är ett litet exempel. Detta är en Property som hämtar alla items i grid:
private List ItemIds { get { List list = new List(); grid.MasterTableView.AllowPaging = false; grid.MasterTableView.Rebind(); foreach (GridDataItem item in grid.MasterTableView.Items) { string id = item[“Id”].Text.Trim(); int itemtId = Convert.ToInt32(id); list.Add(itemId); } return list; } }
.NET HtmlControls
ASP.NET WebControls är en vanligt använd klass inom Sharepoint-utveckling. Den ger tillång till asp controllers som används mycket inom WebForms. Men allt för ofta glöms det bort att man programmatiskt kan skapa Html element/controllers programatiskt, utan att använda (missbruka) literals. Genom att använda inbyggda classer blir koden renare, mer lättläst och lättare att bygga ut (intelisense m.m.). För att läsa mer om HtmlContols klicka på länken nedan. http://msdn.microsoft.com/en-us/library/system.web.ui.htmlcontrols.htmlcontrol.aspx
Ctrl-Shift-J is the shit
devtools i google chrome underlättar så enormt. Lägg Ctrl-Shift-J på minnet. För då kommer du direkt till konsolen i devtools och kan testa.
Om man till exempel bara vill omdefiniera en funktion så kan man göra det direkt i webbläsarens addressruta: Inled det med javascript:function till exempel: javascript:function shout_out(greeting) {alert(greeting);};
Polymorfi och javascript
En skräckscenario: du använder två javascript-bibliotek. Men de har var sin funktion som har samma namn. Det spelar även ingen roll om antalet inparametrar är olika. Så det blir samma sak som myfunc(param1, param2) och myfunc(param1). Grejen är att funktionen som laddas sist är den som kommer köras. Katastrof! Men det finns lösningar. Börja läsa här om hur man kan simulera polymorfi i javascript på about.com. Säg vi har en funktion som heter MoveToDate(strdate, ctxid) den ingår i init.debug.js (som används av Sharepoint kalenderwebpart). Sedan har vi något annat javascript-bibliotek som också har MoveToDate(param). Låt oss göra det polymorfiskt. Här är koden:
migrera svn till git
Ja, hur gör man om man vill migrera till git? Låt oss säga, man vill använda github. Jag ska berätta hur man kan göra det. Jag gör det i Linux, förmodar samma gäller Mac. Det finns en bra manual om hur man migrerar svn till git. Vi ska gå igenom steg för steg. Skapa en fil som heter users.txt på ditt Skrivbord:
jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>
VisualSVN Server = server <server@server.com>
Det sista är nödvändigt. Eftersom om du har skapat en repository från VisualSVN, kommer det krävas en användarmappning för det med. Installera git-svn:
Ändra utseendet på sidan direkt i webbläsaren
I förra inlägget har jag berättat om devtools i Google Chrome. Ett ytterligare tips för att hålla på med klient-delen är att använda Optimizely.com. Det är väldigt smidigt. Gå in på optimizely.com och skriv in adressen till din sharepoint-applikation. Eller se denna video. [youtube http://www.youtube.com/watch?v=0S0IrbwpfzE&rel=0&hl=en_US&feature=player_embedded&version=3]
Felsök på clientsidan med Chrome DevTools
Här är en väldigt bra video som berättar om nya devtools i Google Chrome 10. Den visar 12 tricks hur man kan underlätta felsökning av html, css och javascript. Att kunna ändra html,css och js on-the-fly är faktiskt häftigt. För mig som länge har använt Firebug i Firefox (som nu inte funkar på FF4 RC) känns devtools väldigt bra. [youtube http://www.youtube.com/watch?v=nOEw9iiopwI&w=530&h=335]
Comments from Wordpress.com
Ändra utseendet på sidan direkt i webbläsaren « Sharepoint. Kunskap. Upptäckter på resan. - Mar 1, 2011
Använd inbyggd ModalDialog
Vill du visa någon formulär, eller längre information kan du använda en snygg (snygg och snygg?) ruta som är default i Sharepoint. Den är i alla fall användbar. Här är ett litet enkelt exempel, för att illustrera:
var options = {
url: "http://sverigesradio.se",
width: 800,
height: 600,
allowMaximize: false
};
SP.UI.ModalDialog.showModalDialog(options);
Det finns även möjlighet att ha OK-knappen, alltså som alert i javascript. Kolla den här länken.
Visa en snygg och konsistent notifikation
Det finns ett fint sätt att visa någon information med hjälp av Sharpoints javascript-bibliotek.
SP.UI.Notify.addNotification(\\"Loading..\\", false);
Det används i själva Sharepoint. Det ger en högre grad av consistency och folk slipper klicka på “OK” i vanliga alert-rutan.
Comments from Wordpress.com
Tim - Mar 5, 2011
Duktigt, nu kommer vi aldrig glömma :) Jag har glömt hur man får fram den där långa feedbackrutan som hamnar under navigationen, vet du hur man får fram den, är en SP.UI metod den med.
Formatera export xml av wordpress
Ville spara min blogg som en dagbok för utskrift. Exporterade hela bloggen som xml. Inga problem. Sedan var det dock nästan omöjligt att enkelt skriva in det i Word / OpenOffice. Jag har skrivit en liten css-fil som formaterar det lite så att man kan skriva ut. Lägg till:
<?xml-stylesheet type = "text/css" href="wordpress.css"?>
direkt efter:
<?xml version="1.0" encoding="UTF-8" ?>
Lägg filen “wordpress.com” i samma mapp. Här är wordpress.css
channel title {
font-size:3em;
}
channel description {
color:green;
margin-bottom:1em;
}
item title {
font-size:2em;
font-family:Arial;
margin-top:1em;
}
creator {
color:green;
}
creator:before {
content:"Skrivet av: ";
color:black;
font-style:italic;
font-size:0.8em;
}
post\_date:before {
content:"Datum: ";
}
comment {
margin-left:3em;
}
comment\_author:before {
content:"Kommentar av: ";
font-style:italic;
color:black;
}
comment\_author {
color:green;
}
comment\_date:before {
content:"(";
}
comment\_date:after {
content:"):";
}
/\* Ska inte visas\*/
link, channel language, pubDate,
guid, author, base\_site\_url,
base\_blog\_url, wxr\_version, generator,
post\_id, is\_sticky, post\_type, post\_name,
status, comment\_status, menu\_order,
post\_parent, ping\_status, post\_date\_gmt,
category, postmeta,
comment\_id, comment\_author\_email,
comment\_author\_IP, comment\_date\_gmt,
comment\_approved, comment\_type,
comment\_user\_id, comment\_parent {
display:none;
}
/\* block style \*/
title, description, post\_date, comment {
display:block;
}
Sharepoint + OpenSource = Sant
Om man söker på Sharepoint i codeplex.com får man 729 projekt som är alltså öppna. Det är inte illa. Bland dem finns till exempel Sharepoint Log Viewer. Till det kommer 713 öppna projekt som är taggade ASP.NET som kan användas väldigt mycket i Sharepoint-utveckling. Bland ASP.NET-taggade finns smidiga Telerik Extensions. Powershell är också absolut en tag som man ska söka på i codeplex. codeplex.com är Microsofts officiella OpenSource-portal. Det måste finnas andra sidor där öppna projekt inom Sharepoint och ASP.NET samlas. Tipsa gärna i kommentarer.
Sharepoint Log Viewer
Mycket bra verktyg för att debugga din sharepoint applikation är Sharepoint Log Viewer som är Open Source och finns att hämta på codeplex.com Det går att öppna en logg-fil, det går att köra live monitoring och att exportera. Det sköna är att det är lätt att söka efter correlations-id. Rekommenderar verktyget!
Comments from Wordpress.com
Sharepoint + OpenSource = Sant « Sharepoint. Kunskap. Upptäckter på resan. - Mar 3, 2011
Skapa en egen gadget i Google för att lägga till i Sharepoint
Ibland vill man visa saker som kommer utifrån din sharepoint-installation. Du vill kanske sortera det, ändra det. Man får jättegärna använda javascript. Använd gärna GGE (Google Gadget Editor)
Sharepoint Overflow
Alla känner nog till stackoverflow.com. Det finns även sådant för enbart Sharepoint Overflow. Värt att testa.
Interna fältnamn i SPList
Här är en väldigt bra lista över fältnamn, eller denna lista, till och med bättre i SPList, både Display Name, Internal Name och GUID. En annan bra länk är förklaringen om hur interna fältnamn är uppbyggda av Marc Anderson. För att se interna namnet kan man klicka på kolumnrubriken (för att sortera) så ser man det i URL:en. EDIT: den här tyckte jag mycket om.
Använda gmail smtp i Sharepoint
Användbart om man vill test mail-funktioner. Skapa gmail-konto eller använd ett befintligt. Aktivera POP i gmail-konto Aktivera smtp i features i Server Manager Klicka på Add Feature. Välj SMTP-Server Klicka OK på “Install required server roles” Öppna IIS Manager (IIS 6.0 Manager) Fortsättning följer
Köra debug
Det är mycket enklare att köra debug i SP 2010. Högerklicka på projektet -> Debug -> Add new instance. Resten är som vanligt.
Radera en sajt ifrån Powershell
Att radera en sajt ifrån Powershell är väldigt enkelt. Skriv bara:
Remove-SPWeb [http://sharepoint/test](http://sharepoint/test)
Aktivera PowerShell för Sharepoint
Som standard så är snap-in i Powershell för Sharepoint inte aktiverat. Gå in på Powershell och aktivera det genom att skriva in: Enable PowerShell Sharepoint:
Add-PSSnapin Microsoft.SharePoint.Powershell
```Se mer på [social.technet.microsoft](http://social.technet.microsoft.com/Forums/en/sharepoint2010setup/thread/81392f4c-549c-4c4b-a158-99ab8ef8e114).
Browsa från din host
Visst är det skönt att slippa gå in på sidan på Internet Explorer på den virtuella maskinen. Kolla upp ip-adressen på den virtuella maskinen och på din riktiga maskinen: Start -> Skriv cmd -> ipconfig Hitta adresser som har samma tre tal i början, typ 192.168.10.1 och 192.168.10.147 Om den virtuella har 192.168.10.147, ändra hosts filen så att namnet på din sharepoint-applikation pekar på den adressen. Hosts låter sig inte uppdateras med ett vanligt konto. Öppna cmd som Administrator (högerklicka på cmd i startmenyn och “kör som Administrator”). Navigera till
Återgå till en tidigare version i SVN
Tänk om du vill återgå till en tidigare version. Vill strunta i de sista ändringarna, eller lägga dem på is så länge. Att uppdatera till en tidigare version hjälper inte så mycket eftersom det kommer inte gå att commita vidare ändringar. För att det ska funka måste man reverta till en specifik version, commita direkt, göra ändringar och commita igen. Högercklicka på filen i Visual Studio -> Subversion -> Show history -> Högerklicka på en revision som du vill återskapa -> Revert to this revision. Commita sedan direkt Nu kan du göra ändringar och commita dem också.
Merge en fil i taget
Om man vill testa någonting, så är det bra att isolera det till en branch. En branch kan inte skapas för en fil. Det måste vara en mapp. Hitta den minimala mappen, så att man inte branchar hela projektet. Högerklicka -> Subversion -> Branch. Sedan måste man byta till sin branch. Högerklicka på samma mapp -> Subversion -> Switch. Välj din mapp i branches. Det gör ingenting om mappen inte heter samma. Nu har du hela solution och alla dina projekt, medan någon del inte är från trunken utan är en branch, fritt fram att testa. När du är klar med improviserandet, tycker att det funkar, det går att deploya. Då kan man merga med trunken. Det går att mergea en fil i taget, om man vill på säkra sidan. För att göra det så måste man göra switch tillbaka till master, alltså Högerklicka på mappen -> Subversion -> Switch. Välj den riktiga mappen i trunken. Efter det så högerklicka på din fil -> Subversion -> Merge. Välj filen från din branch och följ wizzarden. Allt detta kan göras direkt ifrån Visual Studio. När du är färdig med din branch så kan man radera det.
Visa en popup-ruta
Visst är det fint med en formulär eller ruta som dyker upp medan ursprungssidan blir mörklagd. I grunden så ändras opacity på hela sidan, blir mörkare. En iframe med högre z-index dyker upp. I den iframe finns en annan sida. Hur gör man för att ta fram den rutan? Här berättar jag lite om det:
javascript i Webpart
Här är en bra länk hur man kan använda javascript: http://dotnetslackers.com/articles/aspnet/JavaScript_with_ASP_NET_2_0_Pages_Part1.aspx
this.Page.ClientScript.RegisterStartupScript(this.GetType(),
"ButtonSendMailConfirm\_Click",
"alert('mail skickat!')", true);
Problem med Sharepoint efter installation av SQL Server
Jag installerade Sharepoint först vilket skapade nödvändiga databaser. Sedan installerade jag SQL Server och angav det som default instance. Efter det gick det inte att använda Sharepoint. Felmeddelandet som spottades ut var “Cannot connect to the configuration database”. Alla försök att starta SQL Server med instansen “Sharepoint” var verkningslösa. Den enda lösningen var att avinstallera Sharepoint, alla Web Sites (i IIS administration) och installera Sharepoint på nytt, ange den nya SQL Server som standard för denna Sharepoint-installation.
Återskapa koppling till login i DB efter restore
Om du har kört restore på en databas, så kan det hända att det inte går att ändra rättigheter, och den login du använt inte kan se databasen. SQL Server spottar ut felmeddelandet med kod 15023:
The database is not accessible. (Object Explorer)
Om det är WebService som i sin tur anropar databasen, kan det komma ett sådant felmeddelande:
The underlying provider failed on Open.
Lösningen är att uppdatera kopplingen. Hämtat från denna blog.
Installera viktiga program på Windows Server
Nu när vi kommit så långt med installationen, så kan vi installera viktiga program.
- Alcohol 52 för att mounta .iso-filer.
- Visual Studio 2010 Ultimate. Klicka på “Custom” under installationen och välj bort komponenter man inte intresserad av. Jag valde bort Visual Basic, C++, F#, SQL Server Express.
- SQL Server 2008 R2 Enterprise.
- Silverlight 4 Tools for Visual Studio 2010
- TortoiseSVN, klienten för Subversion
- AnkhSVN, plugin till Visual Studio för versionhantering.
Comments from Wordpress.com
timswe - May 4, 2011
Installera Sharepoint Server
Nu när du installerat Windows Server, så kan du installera Sharepoint Server. 1. Skaffa Sharepoint. Som student kan du få licensnyckeln från MSDNAA på ditt universitet. Ladda ner Sharepoint Server (Trial Version). Som version, välj “Enterprise Client Access License features”.
Läs i min serie om server installation:
- Installera Windows Server
- Konfigurera backup
- Installera Sharepoint Server
2. Kör den nerladdade SharePointServer.exe-filen. Klicka på “Install software prerequisites”. Tar en stund (10 för mig). Efter det krävs det omstart. Efter omstart fortsätter den installera program. (Det tog 10 minter till). 3. Klicka på “Install Sharepoint Server”. Välj Standalone. Ange din licensnyckel från MSDNAA eller trial du fått. 4. Kör “SharePoint Products Configuration Wizard” (inga val att göra).
Windows Server Backup
Följ denna instruktion för att köra backup. Lägg till Feature: Windows Server Backup. När det är installerat expandera Storage under Server Manager. Klicka på Backup Once till höger. Välj helst Full Server (då sparas hela hårddisken). Destinationshårddisken ska vara formaterad som NTFS.
Restore
Har inte provat köra restore än. Så fort jag kört det kommer jag rapportera om det.
Omvandla en partition till VHD
Som nämnts tidigare så kan man omvandla en fysisk hårddiskpartition till VHD. Använd Disk2VHD. [caption id="" align=“aligncenter” width=“313” caption=“Taget från Disk2VHDs hemsida.”] “disk2vhd screenshot”[/caption] Problemet med detta är att det inte går att köra vhd:n. “Missing operating system” spottar VirtualPC ut. Medan den fysiska ikopplad, går det inte heller att mounta vhd:n. Även om man valt bara en partition så syns alla partitioner (som nu blir tomma). Partitionens alla filer är dock på plats och är åtkomliga. Orsaken är nog att jag har partitionerat hårddisken. Edit 2010-12-11: Det funkar att köra VHD:n i Virtual PC. Man måste dock inkludera partitionen som skapades automatiskt under Windows-Server-installationen som heter “System Reserved” (Jag installerade till allokerat ställe i hårddisken, så det skapades två partitioner av det). Denna “System Reserved”-partition har bland annat mappen “boot”, så den är viktig. Dock går det inte att köra. Även om det finns operativsystem där, så visas “Windows is loading files”. Sedan startas det om och om igen. Förmodar problemet är att det är annorlunda “hårdvara” då.
Partitionera hårddisk
Det bästa och det snabbaste sättet jag kommit fram till är att använda Ubuntu LiveCD och dess inbyggda GParted. Hög nivå av affordance. Det behövs egentligen inte några förklaringar.
Konvertera vmdk till vhd
VMWare har massor med fördelar som jag inte går in på här. VMDK:s (VMWares hårddisk-filändelse) Windows Virtual PC:s motsvarighet heter VHD. VHD har en stor fördel att den är integrerad med Windows. Det går bland annat att mounta VHD-avbildning som en extra disk och se och kopiera filer. Det går att boota direkt till VHD. Det går att skapa varianter av VHD där bara ändringar sparas i nya och på det sättet sparas plats. För att konvertera från vmdk till vhd rekommenderas StarWind Free V2V Converter.
Installera Windows Server på fysisk hårddisk
Det bästa är att installera Windows Server och Sharepoint på en virtuell hårddisk. Följ denna instruktion och installera det. Men om man har en äldre dator (som är mitt fall) och ändå vill testa saker och kunna utveckla, så är det lönt att installera på en riktig hårddisk. Det bästa är att använda en SSD-hårddisk. Sedan är det möjligt att installera Windows Server på en VHD och boota från den (mer info kommer senare förhoppningsvis). Om man har installerat på en riktig hårddisk, kan man omvandla det till VHD med hjälp av till exempel Disk2VHD (mer info om det kommer senare förhoppningsvis). 1. Välj Svenska som locale. När installationen av Windows Swerver 2010 R2 är klar ombeds du att “Press CTRL + ALT + DELETE” för att logga in. 2. Tryck på “OK” för att byta lösenord för administratörskontot. Välj ett lösenord, bekräfta det och tryck på Enter (eller pilen till höger). Tryck på OK för att bekräfta att lösenordet är bytt. Du kommer nu in på skrivbordet. 3. Tryck på “Provide computer name and domain”. I system properties, fliken Computer Name, tryck på Change och ge din dator ett bättre namn exempelvis “SharePoint”. Tryck på OK och “Restart Later”. 4. Aktivera trådlöst: Tryck på “Add feature”. Bocka i Wireless. 5. Tryck på “Download and install updates” och i “Windows Update”, tryck på “Turn on automatic updates”. Tryck på “Install updates” när Windows har letat fram de du behöver. Starta om datorn. 6. Logga in igen som administratör och välj “Add features” under avdelning 3 i “Initial Configuration Tasks”. Kicka på “Desktop Experience” (som gör Windows Server mer användare vänligt) och “Add requered features”. Därefter Next och Install. Starta om datorn. I “Shutdown Event Tracker”, skriv vad som helst i “Comment” och tryck OK. 7. När du har loggat in igen så tryck Close för att avsluta konfigurationen av “Desktop Experience”. Du är nu klar med “Initial Configuration Tasks”. Syns den fortfarande kan du klicka i “Do not show this window at logon” och trycka close. Saknar du den kan du få tillbaka den genom att trycka på Start och skriva OOBE.EXE. 8. Du skall nu in i “Server Manager” som bör ha startat. Om inte, klicka på symbolen till höger om Start-knappen (dator med väska). Se till att “Server Manager” är markerad i vänster kolumn. För att slippa att IE blockerar alla webbplatser så klicka på “Configure IE ESC” under “Security Information”. Klicka Off för både administratörer och användare. 9. Om du vill slippa ge en kommentar varje gång du stänger av eller startar om den virtuella maskinen i “Spåra händelser i samband med avstängning” (“Shutdown Event Tracker”) kan du göra såhär: Tryck Start och skriv gpedit.msc och tryck Enter. Expandera Datorkonfiguration (“Computer Configuration”) och Administrativa mallar (“Administrative Templates”) och välj “System”. I höger kolumn, dubbelklicka på Visa spåraren av avstängningshändelser (“Display Shutdown Event Tracker”), klicka Inaktiverad (“Disabled”) och OK. 10. Konfigurationen av Windows Server är nu klar. Du bör stänga en restore point.’ Nu är Windows Server installerad. Fortsätt med: Konfigurera backup Installera Sharepoint Server …
Aktivera trådlöst i Windows Server
Om man installerat Windows Server på fysisk hårddisk på din bärbara så vill man säkert använda trådlöst nätverk. Här är en guide med bilder hur man aktiverar denna feature.
Mounta VHD
Det kan vara ett helvete att köra en virtuell maskin på en slö dator. En lösning kan vara att boota direkt till VHD utan värdsystemet. Det enklaste sättet är att använda EasyBCD. Testa gärna med en färdig VHD. Edit 2010-12-10. EasyBCD funkar bara med Windows7-vhd för tillfället. Kolla mer om hur man får vhd att boota.
out ref
Om en metod har en inparameter med out framför sig. så innebär det att man skickar en referens till ett objekt. Alltså om det är out string param, så kommer det inte funka att skicka “någonting” direkt. Utan man måste instansiera först. string hej = “någonting”; CallTheMethod(ref hej); http://msdn.microsoft.com/en-us/library/t3c3bfhx(VS.80).aspx
kort variant av if-else
Inget speciellt egentligen med detta men vill skriva upp det här för att jag brukar glömma det. Det är samma syntax som i många andra språk:
bool value = "dit" == "dat" ? true : false;
Motsvarar:
bool value;
if ("dit" == "dat")
{
value = true;
}
else
{
value = false;
}
Ändra properties i efterhand
Ibland ändras vissa variabler. Man vill så klart inte kompilera varje gång man ändrar ApplicationName eller connectionString. I mitt förra inlägg har jag visat hur man använder app.config, hur man lägger till ett värde och hur man hämtar det i programmet. Nu vill jag visa hur man ändrar det efter kompileringen. I mappen var projektet finns gå in på bin -> Debug. Där finns både .exe-filen och en fil som heter samma som .exe-filen fast har en filändelse .config. Om man bara kör .exe-filen eller om man inte har .config-filen så finns properties ändå, såklart. Fast då är de “inkompilerade”. Finns config-filen så är det bara att öppna i Notepad och ändra värden till de aktuella.
app.config
app.config kan användas till mycket. Här är ett litet exempel hur man använder den. Så kan app.config se ut:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ApplicationName" value="SharePoint - 80" />
</appSettings>
</configuration>
```Sedan i programmet måste vi importera:
using System.Configuration
appName = ConfigurationSettings .AppSettings[“ApplicationName”] .ToString();
## Comments from Wordpress.com
####
[Ändra properties i efterhand « Sharepoint. Huvudvärk och smärtstillande.](http://sharepointheadache.wordpress.com/2010/10/31/andra-properties-i-efterhand/ "") - <time datetime="2010-10-31 23:12:43">Oct 0, 2010</time>
\[...\] Man vill så klart inte kompilera varje gång man ändrar ApplicationName eller connectionString. I mitt förra inlägg har jag visat hur man använder app.config, hur man lägger till ett värde och hur man hämtar det \[...\]
<hr />
Komma åt andra tabeller via foreign keys i LINQ
I stället för att köra join-statements i LINQ som jag visat i ett av mina tidigare inlägg, kan man utnyttja inbyggda möjligheter att komma åt saker via foreign keys. Jfr de här två:
var q = from s in ctx.Staffs
join si in context.StaffOnCourseInstances
on s.uid equals si.uid
where si.CourseInstanceId == 1435
select new { s.adAccount };
```och
var q = from c in context.StaffOnCourseInstances where c.CourseInstanceId == 1435 select new { c.Staff.adAccount };
Lägga till en användare i en grupp på sajten
I stället för att köra group.Users.Add(“adAccount”, “name”, “email”, “comment”) är det bättre att köra: SPUser user = web.EnsureUser(emp.adAccount); group.AddUser(user);
Installera Subversion på klienten
För att komma igång med versionhanteringen när man utvecklar i Visual Studio, måste man installera tortoisesvn, sedan AnkhSVN. TortoiseSVN är själva klienten, medan VisualSVN är ett tillägg för Visual Studio. Gå in på C:\ i Windows. Högerklicka och välj SVN Checkout. Sedan ange din svn-server och mappen där du vill ha en working copy: [caption id=“attachment_97” align=“aligncenter” width=“300” caption=“subversion uppgifter”][/caption] Logga in [caption id=“attachment_99” align=“aligncenter” width=“300” caption=“subversion login”][/caption] AnkhSVN måhända inte syns direkt i Visual Studio. Bara öppna View > Other Windows > Pending Changes. Om man inte ser ändringar, gå in på File - Open from SVN - och tryck på Cancel. Nu måste allting fungera.
Bläddra i Sharepoint från Android
Det finns en app som heter Quick Browser för Android från SPElements. Med den kan man bläddra i olika bibliotek och listor i en sharepoint direkt från mobilen. Mycket smidigt. Den aktuella versionen är 0.2.8. Den uppdateras rätt så ofta och blir bättre och bättre. Den enda nackdelen jag tycker är att man får alla element i ett bibliotek bara som en lista. Om det är image library så måste man long-klicka på ett element för att “download and view”. Mycket smidigare hade det varit om bilder visades i en Gallery.
Subversion mappstruktur
Subversion verkar väldigt smidigt och användbart när man jobbar flera stycken med samma projekt. Är det ett litet program hjälper Dropbox tillräckligt. Vill man ha kolla på alla ändringar och ha möjlighet att backa till äldre versioner är Subversion det bästa alternativet. Det kan underlätta mycket om man har en riktig mappstruktur ifrån början:
main
trunk
branches
tags
trunk används för löpande utveckling. Vill man testa saker eller lösa några buggar, används branches. tags används för att spika fast olika versioner.
join i LINQ
LINQ är ett kraftfullt verktyg. Det som kan vara lite krångligt är join. Men om man gör rätt blir det bra. Låt oss titta på det sql-exemplet:
SELECT s.adAccount
FROM Staff s join StaffOnCourseInstance si
ON s.uid = si.uid
WHERE si.CourseInstanceId = 1435
För att köra motsvarande LINQ måste vi vara väldigt noga med on:
var testQuery = (from s in ctx.Staffs
join si in ctx.StaffOnCourseInstances
on s.uid equals si.uid
where si.CourseInstanceId == 1435
select new { s.adAccount });
```Edit 20101031: Det finns ett smidigare sätt att komma åt information i relaterade tabeller. Se mitt inlägg från 20101031 om [LINQ och foreign keys](https://sharepointkunskap.wordpress.com/2010/10/31/komma-at-andra-tabeller-via-foreign-keys-i-linq/).
local dns
Hur gör man om man vill ha två olika internet-adresser för olika inloggningar. Om man har DNS inställt rätt - inga problem. Men hur gör man för att testa det på sin lokala maskin. Man kan ändra dns-information på sin maskin. För detta ska filen [hosts](http://en.wikipedia.org/wiki/Hosts_%28file% 29#Content_and_location) uppdateras. I Windows tryck på Start och i sökrutan skriv:
%SystemRoot%\\system32\\drivers\\etc\\hosts
Den här filen är raka motsvarigheten till /etc/hosts i Linux. I filen som öppnas lägg till följande rader som sist:
HelpUrl i WebPart
Man kan lägga till HelpUrl i en WebPart, för att användare kan klicka och få instruktioner eller hjälp med just denna webpart. För att göra det manuellt, ska man klicka på pilen, välja “modify this web part”, och sedan i “Advanced” skriva url-länken i “HelpUrl”-fältet. För att lägga till HelpUrl ifrån början, när sajter skapas, måste man ange den egenskapen i onet.xml i Module för din sajt. Man måste hitta , och ändra den: <property name="HelpUrl" type="string">http://sr.se</property>
Så ser hela biten ut i onet.xml:
Komma åt Title-kolumnen i SPList
Vad gör man om man vill lägga till Title-kolumnen till en ny vy? SPField fieldTitle = scheduleList.Fields["Title"];
Det kommer funka, men Title kommer vara bara text, utan en länk till SPListItem. Kolla på den koden: SPField fieldTitle = scheduleList.Fields[**SPBuiltInFieldId.LinkTitle**];
Här hämtar vi kolumnen som heter i Sharepoint “Title linked with item menu”. Det finns fler sådana “inbygda” kolumner.
PowerShell
PowerShell är ett sätt att manipulera data och struktur i SharePoint-portalen. Samma uppgifter låter göras med konsoll-applikationer. Fördelen med PowerShell är att man kan skapa skript som är flexibla och kan köras med olika parametrar. PowerShell påminner starkt om shell-skript i Linux. För mig som egentligen kommer snarare från bash-världen. Där har Microsoft låtit sig inspireras starkt :). Det finns en bok om PowerShell, skriven av svenskar, som låter intressant. Man behöver inte heller uppfinna hjul på nytt: det finns färdiga skripts som man direkt. Bara man skriver rätt parametrar. Här är ett ställe där man kan hitta skripts. Det finns många sidor som förklarar hur man skriver skript.
Hämta schema från en befintlig SPList
Ibland är det så att man vill ha en speciell mall för en SPList, man har redan skapat en mall manuellt på sajten. Då är det enklaste sättet att hämta schema.xml och Windows SharePoint Services 3.0 Tools. När man installerat det så startar man Sharepoint Solution Generator 2008. Sedan måste man hitta sin lista, eller dokumentbiblioteket och exportera. Sedan är det bara att importera till sitt projekt i Visual Studio.
Ändra query på en SPView i koden
När man vill ändra hur data ska visas i en SPView i SPList, då måste man ändra CAML-Query. Det enklaste sättet att skapa en CAML Query är att använda ett program som heter CAML Query Builder. Ta bara bort och för att de behövs inte. Sedan är det bara att loopa igenom alla vyer man behöver.
private void UpdateQueryInGroupViews(SPList list)
{
for (int i = 1; i < 11; i++)
{
string viewname = String.Format("Group {0:D2}", i);
SPView view = list.Views\[viewname\];
string query =
String.Format(
"<Where><Or><Contains><FieldRef Name='Group' />"
+ "<Value Type='Text'>{0:D2}</Value></Contains>"
+ "<IsNull><FieldRef Name='Group' /></IsNull></Or></Where>"
+ "<OrderBy><FieldRef Name='EventDate' Ascending='True' />"
+ "</OrderBy>", i);
view.Query = query;
view.Update();
}
}
I denna query sorterar vi efter Start Date och visar bara händelser för sin grupp.
Radera en specifik sida i en site
Om man vill radera någon specifik sida som finns på flera siter, så måste man loopa igenom alla SPList objekt som finns i ett SPWeb objekt. På ett SPList som heter “Pages” ska man loopa igenom alla SPListItem och radera den som har Title som man är ute efter. Jag raderar alla sidor som heter “schedule.aspx”:
private void DeleteScheduleAspx(SPWeb web)
{
bool found = false;
foreach (SPList list in web.Lists)
{
if (list.Title.Equals("Pages")
&& list is SPDocumentLibrary)
{
foreach(SPListItem item in list.Items)
{
if(item.Name.Equals("schedule.aspx"))
{
item.Delete();
list.Update();
found = true;
break;
}
}
}
if (found)
{
break;
}
}
}
Tag: Logo
Two site logos?
We have had troubles updating site icons in SharePoint Online. It might be related to one of the following:
- It occures only on hub sites
- The sites have a custom theme
The error message:
We experienced a problem updating the icon. Please try again in a few minutes.
But what I found is that there are two places where you change the site icon. If the first does not work, try the second one, that was what worked for us:
Tag: Site
Two site logos?
We have had troubles updating site icons in SharePoint Online. It might be related to one of the following:
- It occures only on hub sites
- The sites have a custom theme
The error message:
We experienced a problem updating the icon. Please try again in a few minutes.
But what I found is that there are two places where you change the site icon. If the first does not work, try the second one, that was what worked for us:
Tag: Troubleshooting
Two site logos?
We have had troubles updating site icons in SharePoint Online. It might be related to one of the following:
- It occures only on hub sites
- The sites have a custom theme
The error message:
We experienced a problem updating the icon. Please try again in a few minutes.
But what I found is that there are two places where you change the site icon. If the first does not work, try the second one, that was what worked for us:
Page Diagnostics for SharePoint
While trying to set up a new Home Site, I discovered that there is a tool (browser extension) called Page Diagnostics for SharePoint.
After running this, I tried that command again and it was smart enough to detect the problem the tool discovered.
Also Network Trace is available.
Network trace
Page Diagnostics Tool is defnitely a tool to have in the troubleshooting toolbelt for SharePoint.
Setting up a Home Site
Here is the script:
Troubleshooting Performance in SharePoint Online
This is my personal list of links and thoughts on troubleshooting performance in SharePoint Online.
Resources
- @MSFT365Status, a twitter flow on the incidents and resolutions
- connectivity service
- Service Status (open for all), Service Health (for admins)
Health info in Response Headers
Every response from SharePoint Online contains some health information:
- Diagnosing performance issues with SharePoint Online (MSDocs)
- Troubleshooting SharePoint Performance Issues with F12 (blog post)
Following Response Headers could reveal the health:
Method "GetList" does not exist
I troubleshooted a piece of CSOM code in SharePoint 2013. I got the following error:
Method “GetList” does not exist
The reason was that the method GetList was not imlemented until March 2015 CU (15.0.4701.1001), and the SharePoint farm I had was SharePoint 2013 SP1 (15.0.4569.1000). So the solution is to install the Cumulative Update or use web.Lists.GetByTitle. GetByTitle has one aweful shortcoming: it doesn’t work in multilingual environments. So I have recommended to install the March 2015 CU.
Tag: Workaround
Two site logos?
We have had troubles updating site icons in SharePoint Online. It might be related to one of the following:
- It occures only on hub sites
- The sites have a custom theme
The error message:
We experienced a problem updating the icon. Please try again in a few minutes.
But what I found is that there are two places where you change the site icon. If the first does not work, try the second one, that was what worked for us:
A user can only create 250 groups
A non-admin user can create no more than 250 resources in Azure AD. That is one of the many Azure AD service limits and restrictions. A “resource” can be an app registration, an Office 365 Group etc. But I would like to discuss Groups more in detail.
Imagine the following scenario: Your organization has disabled Office 365 Group Creation. Only IT can create new groups. A service account has been set up for creation of team sites. The application permissions are “binary”, either everything or nothing: Group.ReadWrite.All. This service account will hit the limit very soon.
$ in cmssitemanager.js conflicts with $ in jQuery
In SharePoint 2010 if CMSSiteManager.js library is loaded besides jQuery, then much of stuff stops working. The reason is that the dollar sign ($) is used in cmssitemanager.js as well which conflicts with jQuery. Mostly it appears on pages where you load jQuery and have an image library with thumbnails. To avoid this, just replace all $ with jQuery in your custom scripts. A more crazy situation is when avoiding $ isn’t enough. It is when you load jQuery to page head automatically on all pages. The Asset picker (AssetPortalBrowser.aspx) invokes $ itself and gets with jQuery in conflict without you write a single line of custom javascript code. You usually get the following error:
Tag: Ikea
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Tag: Msgraph
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Using Sway as a simple static site builder
Sometimes all you need is just a simple static web page: instructions, a landing page, a collection of links. I think I have a perfect use case for Sway. Consider a scenario similar to what Laura Kokkarinen writes in her blog post:
An external user invitation needs an inviteRedirectUrl. Usually it is myapps.microsoft.com. In Laura’s case it was a given extranet url.
Tag: O365
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Is an M365 Group a Yammer Community
Nowadays a Yammer Community gets a corresponding Microsoft 365 Group (Office 365 Group, Unified Group). In your work as an SPO Admin, you might need to differentiate “ordinary” Modern Team Sites from those ones that were created for a Yammer Community.
They both have GROUP#0 as Template. On the actual SPO Site object, there is nothing that you can use to differentiate those. Neither you can use the Office 365 Group information. But there is a way: if you connect to Exchange Online and get the group from there, then there is something useful.
Deploying SPFx using Office 365 cli, custom AAD App and Azure Pipelines
In this post I would like to share some findings from setting a deployment of SPFx. In my work:
- I need to deploy SPFx solutions using Azure Pipelines
- I need to use the least privileges/permissions
- I cannot use Legacy Authentication
First of all, big thanks to @waldekm and the whole community of @office365cli and @m365pnp for the quick help, and that outside working hours.
Let’s take a look at the setup piece by piece
Tag: Presence
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Tag: Python3
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Tag: Status
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Tag: Tradfri
DIY: Integrating Trådfri lights with Teams presence
It seems that Work from Home (WFH) is here to stay, it’s okay. I’d say, Work from a Smart Home is even more okay. To me, Home Automation (HA) and Work from Home (WFH) are really two peas in a pod.
Today’s “guest” is a tiny application that I’ve set up on my raspberry pi to listen to my presence (status) in Teams and show it with colors of my smart RGB light (IKEA Trådfri).
Tag: Image
Mass remove live photo videos
While importing images from my iPhone using Image Capture on my mac, I discovered that almost all pictures had corresponding videos. They had the same name, only the file extension was different:
- IMG_2829.JPG
- IMG_2829.MOV
For archiving I don’t to have live photo videos, that’s why I needed a script for that. I found a good start in an answer on SuperUser.stackexchange.com:
I altered it a bit to remove the corresponding .MOV-file (rm):
Drag and Drop Image using Client Side Rendering
I continue my series about Client Side Rendering (CSR) and jsgrid. Today I want to try a custom field where users can drag and drop images. The inspiration comes from:
- AutoUpload field written by Anton Vishnyakov and
- Base64 Drag and drop written by oroboto
What I want to achieve is:
- A custom field that is rendered with jslink
- Users can drag and drop small pictures (thumbnails) into the field
- A base64 image representation is saved as the field value
- Optionally implement pasting images using Clipboard API
Step 1 Create a field with a custom jslink
Create a field of type Note. I am using the PnP Core Extensions to make it quickier: ’ My jslink file is very simple to begin with: [code language=“javascript”] (function () { ‘use strict’; function view(ctx, field) { return “hello”; } var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘DragAndDropImage’: { ‘View’: view, ‘DisplayForm’: view //‘EditForm’: verySimpleNewAndEdit, //‘NewForm’: verySimpleNewAndEdit } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] This will result in the following display form. Just outputting “hello” indicates that my field is jslink are registered correctly:
Tag: Iphone
Mass remove live photo videos
While importing images from my iPhone using Image Capture on my mac, I discovered that almost all pictures had corresponding videos. They had the same name, only the file extension was different:
- IMG_2829.JPG
- IMG_2829.MOV
For archiving I don’t to have live photo videos, that’s why I needed a script for that. I found a good start in an answer on SuperUser.stackexchange.com:
I altered it a bit to remove the corresponding .MOV-file (rm):
Tag: Osx
Mass remove live photo videos
While importing images from my iPhone using Image Capture on my mac, I discovered that almost all pictures had corresponding videos. They had the same name, only the file extension was different:
- IMG_2829.JPG
- IMG_2829.MOV
For archiving I don’t to have live photo videos, that’s why I needed a script for that. I found a good start in an answer on SuperUser.stackexchange.com:
I altered it a bit to remove the corresponding .MOV-file (rm):
Chuvash Keyboard Layout for Mac
I’ve got a Mac and one of my first questions was: How can I write in Chuvash on my Mac, obviously :) In this post I am going to tell how I created Chuvash Keyboard Layout. The solution and installation instructions are on Github: Chuvash Keyboard Layout for Mac
What the heck is Chuvash?
For those who don’t know yet: Chuvash are people who live in Chuvash Republic in Russian Federation, and abroad, as me. We are 1.5 million. Chuvash is also a language, an official language of the Republic, a minority language, that is completely different from the second official language Russian. Chuvash uses Cyrillic letters, all 33 Russian letters plus 4 additional letters: A breve (Ӑ), E breve (Ӗ), C cedilla (Ҫ) and U with double acute (Ӳ).
Tag: Video
Mass remove live photo videos
While importing images from my iPhone using Image Capture on my mac, I discovered that almost all pictures had corresponding videos. They had the same name, only the file extension was different:
- IMG_2829.JPG
- IMG_2829.MOV
For archiving I don’t to have live photo videos, that’s why I needed a script for that. I found a good start in an answer on SuperUser.stackexchange.com:
I altered it a bit to remove the corresponding .MOV-file (rm):
Tag: Alert
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Setting up a HelloWorld Azure Alert
Azure Alerts are awesome for monitoring of solutions in Azure. If you are about to set up your first Alert Rules in Azure, then it’s a guide for you. Configuring alert rules can be quite intimidating at first, with all the options, metrics, evaluation times, etc.
Here is a very very simple setup that can serve as a teaser and help you get started with the Azure Alerts.
javascript: Alert Me on a Page
Recently I needed to add an Alert Me link on Pages. Alert Me is a well known SharePoint functionality for notifying users about changes in list or list items. It is availabe in OOB SharePoint as a command in Ribbon if you go to a list view: When you click on this ribbon command, SharePoint opens a modal dialog and takes you to layouts page: SubNew.aspx. To open a modal dialog and load a page is not a rocket science. So a custom “Alert Me” link is doable. As the first step I copied the html markup from the ribbon and adjusted it a little bit. [sourcecode language=“html”] Alert Me [/sourcecode] Then the javascript code which gets the List ID and Page ID is very simple because this information is there in the magic _spPageContextInfo: [sourcecode language=“javascript”] var takana = window.takana || {}; takana.alertMe = function () { var url = String.format("{0}/{1}/SubNew.aspx?List={2}&ID={3}" , _spPageContextInfo.webAbsoluteUrl , _spPageContextInfo.layoutsUrl , encodeURI(_spPageContextInfo.pageListId) , _spPageContextInfo.pageItemId); OpenPopUpPage(url); } [/sourcecode] This code will open a modal dialog in exactly the same way as the ribbon command in OOB SharePoint and let you subscribe to changes on that page. In this code I use String.format which is available on SharePoint pages and _spPageContextInfo which has existed since SharePoint 2010 and has been extended with more useful information about the current context.
Tag: Gateway
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Tag: Homeautomation
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Tag: Lamp
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Tag: Light
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Tag: Remote
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Run powershell remotely
To run powershell remotely is really easy. First enable it on the machine which will receive the remote commands:
Enable-PSRemoting
Then go to another machine and connect to your host:
$cred = Get-Credential
Enter-PSSession -Computername dev -Credential $cred
If you want to know more about powershell remoting, I recommend “A layman’s guide…”. See even a detailed example on poshcode.
Tag: Smarthome
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Tag: Wfh
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Tag: Workfromhome
Flashing Trådfri lights on Azure Alerts
What if you put together Work From Home and Home Automation? Well, removing the common denominator (HOME) would mean Work Automation (sic!). I want to tell you about a tiny hobby project I have had at home, still related to work of mine: Whenever an Azure alert is triggered, my Trådfri smart light from IKEA flashes for a couple of seconds.
Summary (if you want to skip the long story below): The solution is a tiny web application. The publicly accessible url, exposed using ngrok, is registered as a webhook in an Azure Alert. It’s on Github, you’re welcome to use it as you please 😎:
Tag: Azurefunction
Setting up a HelloWorld Azure Alert
Azure Alerts are awesome for monitoring of solutions in Azure. If you are about to set up your first Alert Rules in Azure, then it’s a guide for you. Configuring alert rules can be quite intimidating at first, with all the options, metrics, evaluation times, etc.
Here is a very very simple setup that can serve as a teaser and help you get started with the Azure Alerts.
Tag: Channel
Setting up a HelloWorld Azure Alert
Azure Alerts are awesome for monitoring of solutions in Azure. If you are about to set up your first Alert Rules in Azure, then it’s a guide for you. Configuring alert rules can be quite intimidating at first, with all the options, metrics, evaluation times, etc.
Here is a very very simple setup that can serve as a teaser and help you get started with the Azure Alerts.
Tag: Incoming
Setting up a HelloWorld Azure Alert
Azure Alerts are awesome for monitoring of solutions in Azure. If you are about to set up your first Alert Rules in Azure, then it’s a guide for you. Configuring alert rules can be quite intimidating at first, with all the options, metrics, evaluation times, etc.
Here is a very very simple setup that can serve as a teaser and help you get started with the Azure Alerts.
Tag: Spoadmin
Listing all renamed sites in SharePoint Online
When you rename a site, a new site is REDIRECTSITE#0, you can get all the sites of that type by running
Get-SPOSite -Template REDIRECTSITE#0
Please consider some caveats with renaming a site url
Automatically detect new sites in SharePoint Online
Original image by William Warby. https://www.flickr.com/photos/wwarby/16414155179/in/photostream/
Sites in SharePoint are created all the time, not only for SharePoint, but also as storage for Yammer, Teams, Planner and other services in Microsoft 365. There are ways to keep track of them, but the ability to automatically detect a new site creation is quite appealing. Automatic detection means a trigger of a Power Automate (Flow) or a Logic App.
There are a few blog posts that exactly describe how you can detect when a new site is created in SharePoint Online:
Tag: Sharepoint Online
Automatically detect new sites in SharePoint Online
Original image by William Warby. https://www.flickr.com/photos/wwarby/16414155179/in/photostream/
Sites in SharePoint are created all the time, not only for SharePoint, but also as storage for Yammer, Teams, Planner and other services in Microsoft 365. There are ways to keep track of them, but the ability to automatically detect a new site creation is quite appealing. Automatic detection means a trigger of a Power Automate (Flow) or a Logic App.
There are a few blog posts that exactly describe how you can detect when a new site is created in SharePoint Online:
Is an M365 Group a Yammer Community
Nowadays a Yammer Community gets a corresponding Microsoft 365 Group (Office 365 Group, Unified Group). In your work as an SPO Admin, you might need to differentiate “ordinary” Modern Team Sites from those ones that were created for a Yammer Community.
They both have GROUP#0 as Template. On the actual SPO Site object, there is nothing that you can use to differentiate those. Neither you can use the Office 365 Group information. But there is a way: if you connect to Exchange Online and get the group from there, then there is something useful.
Estimated Completion in Write-Progress in PowerShell
Have you also got many sites in your tenant? Write-Progress is the bare minimum in a script that goes through all sites. But there is also another nice way to make easier to see the progress - estimated completion time.
Although the idea comes from another blog post (My life is a message), I thought it could be worth sharing it again, especially in the cloud context.
Here is a bit simplified scenario: Getting information for every site. The status message in Write-Progress contains also the estimated completion time.
Kalendern i SharePoint
Dags för ett svenskt inlägg igen. Idag vill jag titta på kalenderfunktionaliteten i SharePoint Online.
Fortfarande gammalt (classic) utseende
Tyvärr är det gammalt utseende som gäller och det finns inga planer från Microsoft att modernisera kalendern:
Jag förstår att det är väldigt mycket kod för att få till kalendervyn och att det inte är så lätt omvandla till ett modernt utseende, men det ställer till eftersom det upplevs som gammalt och inte användarvänligt ute i verksamheten.
Renaming site urls
I saw a demo of it on the European SharePoint Conference in Copenhagen in 2018. Sebastian Fouillade, who showed this, compared this big change with brain surgery. All the urls, all the connections. But now it is possible. Today I have seen it even in my standard release tenant.
It is really appreciated. Soon it will be possible to rename misspelled sites, like “devlepment” to “development” etc.
To rename you need to go the SharePoint Admin, find your site among Active sites and click on “Edit” in the site url area.
The CDN concept in SharePoint
How many instances of jquery are there in your SharePoint farm? [sourcecode language=“powershell”] Get-SPWebApplication http://dev ` | Select -Expand Sites ` | Select -Expand AllWebs ` | Select -Expand Lists ` | Select -Expand Items ` | ? { $_.Url -match “jquery.*.js” } ` | select Name, Url [/sourcecode] Have you more than two (jquery and jquery-ui), then you have too much. You can save much place and performance by using Content Delivery Network (CDN) links for the resources like javascript, css, fonts and icons. Consider those Content Delivery Networks:
Tag: Devops
Re-discovering Github
Github has changed a lot. While working mostly in Azure DevOps I haven’t followed all the development on Github. Now when I look at that, I am really amazed.
Private Repos for Free accounts
Well, for me it is not as interesting, because with my free account, I don’t see any harm having my labs public. But I know, some people used bitbucket for their smaller private repos.
Github Project
I suppose it is the Azure DevOps Project concept that was copied to Github, a place for planning and having multiple connected repos.
Azure Key Vault vs. Pipeline Variables
Using Azure Key Vault in a Pipeline is cool, but it is less secure.
The Key Vault setup
Have you tried the Key Vault Step in an Azure DevOps Pipeline? If you haven’t, please follow these awesome guides:
- Azure DevOps Labs. Using secrets from Azure Key Vault in a pipeline
- Tobias Zimmergren. Using Azure Key Vault Secrets in Azure DevOps pipelines
The steps described in these guides are easy, but that effort made me think about the first pair of pros and cons.
Simple Build for dotnet new react
I created a sample ASP.NET Core app with React.
dotnet new react
Then it took a couple of hours to get the build to work. Here is my working azure-pipelines.yml:
Resources:
Tag: Microsoft365
Is an M365 Group a Yammer Community
Nowadays a Yammer Community gets a corresponding Microsoft 365 Group (Office 365 Group, Unified Group). In your work as an SPO Admin, you might need to differentiate “ordinary” Modern Team Sites from those ones that were created for a Yammer Community.
They both have GROUP#0 as Template. On the actual SPO Site object, there is nothing that you can use to differentiate those. Neither you can use the Office 365 Group information. But there is a way: if you connect to Exchange Online and get the group from there, then there is something useful.
Tag: Yammer
Is an M365 Group a Yammer Community
Nowadays a Yammer Community gets a corresponding Microsoft 365 Group (Office 365 Group, Unified Group). In your work as an SPO Admin, you might need to differentiate “ordinary” Modern Team Sites from those ones that were created for a Yammer Community.
They both have GROUP#0 as Template. On the actual SPO Site object, there is nothing that you can use to differentiate those. Neither you can use the Office 365 Group information. But there is a way: if you connect to Exchange Online and get the group from there, then there is something useful.
First look at Yammer integration in SharePoint 2013 SP1
I have installed SharePoint SP1 on my development machine. Yammer and OneDrive links have appeared in the Central Administration: If you go ahead and click “Configure Yammer”, you can activate it: Because:
Yammer is Microsoft’s recommended tool for social collaboration.
When you activate Yammer, you’ll get this dialog, and the Yammer link in the SuiteBar: What happens when you click on Yammer, is that you are redirected to Yammer.com and you are prompted a login page. Then you have a usual yammer site with all your networks and stuff (in my case, SPC14 network): Then, if you go to your newsfeed, the following message is shown:
Tag: Array
Optimizing lookups in PowerShell
Have you had a PowerShell script that contains two bigger arrays and you wanted merge the information. It can become quite slow if you need to search for every item from array A through all items in array B. The solution is called a HashTable! It might be not an advanced tip for some, but I was really glad to see a huge improvement, so I decided to share it as a post.
Tag: Filtering
Optimizing lookups in PowerShell
Have you had a PowerShell script that contains two bigger arrays and you wanted merge the information. It can become quite slow if you need to search for every item from array A through all items in array B. The solution is called a HashTable! It might be not an advanced tip for some, but I was really glad to see a huge improvement, so I decided to share it as a post.
Tag: Hashtable
Optimizing lookups in PowerShell
Have you had a PowerShell script that contains two bigger arrays and you wanted merge the information. It can become quite slow if you need to search for every item from array A through all items in array B. The solution is called a HashTable! It might be not an advanced tip for some, but I was really glad to see a huge improvement, so I decided to share it as a post.
Tag: Optimization
Optimizing lookups in PowerShell
Have you had a PowerShell script that contains two bigger arrays and you wanted merge the information. It can become quite slow if you need to search for every item from array A through all items in array B. The solution is called a HashTable! It might be not an advanced tip for some, but I was really glad to see a huge improvement, so I decided to share it as a post.
Tag: Diagnostics
Page Diagnostics for SharePoint
While trying to set up a new Home Site, I discovered that there is a tool (browser extension) called Page Diagnostics for SharePoint.
After running this, I tried that command again and it was smart enough to detect the problem the tool discovered.
Also Network Trace is available.
Network trace
Page Diagnostics Tool is defnitely a tool to have in the troubleshooting toolbelt for SharePoint.
Setting up a Home Site
Here is the script:
Tag: Performance
Page Diagnostics for SharePoint
While trying to set up a new Home Site, I discovered that there is a tool (browser extension) called Page Diagnostics for SharePoint.
After running this, I tried that command again and it was smart enough to detect the problem the tool discovered.
Also Network Trace is available.
Network trace
Page Diagnostics Tool is defnitely a tool to have in the troubleshooting toolbelt for SharePoint.
Setting up a Home Site
Here is the script:
Troubleshooting Performance in SharePoint Online
This is my personal list of links and thoughts on troubleshooting performance in SharePoint Online.
Resources
- @MSFT365Status, a twitter flow on the incidents and resolutions
- connectivity service
- Service Status (open for all), Service Health (for admins)
Health info in Response Headers
Every response from SharePoint Online contains some health information:
- Diagnosing performance issues with SharePoint Online (MSDocs)
- Troubleshooting SharePoint Performance Issues with F12 (blog post)
Following Response Headers could reveal the health:
Announcing web based SQL Max Memory calculator
Today I want to announce a tiny web application for calculating max memory in the SQL Server to improve the overall performance in you SharePoint environment: SQL Max Memory Calculator. One of the important actions to improve the performance in SharePoint is fine tuning of the SQL Databases. Regarding the databases one of the crucial settings is the Max Memory Setting. You can read more about database optimizations for SharePoint in a whitepaper written by SharePoint MVP Vlad Catrinescu. The document is available on the SharePoint Community Web Site:
Improving the web performance of an intranet
[caption id=“attachment_3437” align=“alignnone” width=“480”] All the “small” app parts, web parts, delegate controls, user controls, and other “packages” that “must” be delivered to the users on every page load of the Start Page of your Intranet.[/caption] Recently we made an investment to improve the performance of our intranet. We made many changes in different layers: SQL, Network, Browser upgrade and code. Here I want to tell about what code changes we did to improve the web browser performance. Please leave feedback if you find it useful. You can also share your suggestions. We measured the performance before our code changes and after them. We had amazing results. Unfortunately I can not share any numbers, but we improved the Time to First Byte, time to load event firing in the browser, memory consumption in the clients and, perhaps, the most important, we improved the perceived performance of the Intranet, the way how users experience the speed and UI responsiveness. To do this I got many ideas of my project colleagues and branch colleagues. Here is the list of changes we’ve implemented:
The CDN concept in SharePoint
How many instances of jquery are there in your SharePoint farm? [sourcecode language=“powershell”] Get-SPWebApplication http://dev ` | Select -Expand Sites ` | Select -Expand AllWebs ` | Select -Expand Lists ` | Select -Expand Items ` | ? { $_.Url -match “jquery.*.js” } ` | select Name, Url [/sourcecode] Have you more than two (jquery and jquery-ui), then you have too much. You can save much place and performance by using Content Delivery Network (CDN) links for the resources like javascript, css, fonts and icons. Consider those Content Delivery Networks:
Cool presentation about web performance optimization
by Chris Love [slideshare id=15218139&doc=webperformanceoptimizationformodernwebapplications-121116224847-phpapp01]
javascript: developing for performance
Many words have been said about the importance of performance when working with javascript files. Here I want to summarize what developers can do to increase the performance related to javascript. I found many tips on blogs. Here comes my aggregated list of actions one can do to speed up sharepoint (and not only) sites with focus on javascript:
1. Load only sharepoint stuff you need
Use prefetch option to only load sharepoint javascript files that needed. To see the difference, just add ?prefetch=0
to your sharepoint url in the browser. The downside of this lazy loading is that you wrap all sharepoint related javascript into ExecuteOrDelayUntilScriptLoaded otherwise you maybe invoke some of javascript objects and functions that are not loaded. So the prize of this huge performance improvement is a high awareness by a developer when and which scripts are loaded and run.
Shrink sharepoint database
A Sharepoint Database can become big and have unused spaces. To shrink database go to CA-> Health Analyzer: http://takana:1337/Lists/HealthReports/AllItems.aspx See if there is a list item about unused space in db under the Availability. Click on Repair Automatically in the opened Modal Dialog:
Set ObjectTrackingEnabled = false when reading
In LINQ 2 SP we work with a data context. By default a data context has the property ObjectTrackingEnabled = true. This property is crucial for all other operations in CRUD except Read. I performed a mini experiment. I created 20 000 items in my task list. Every seventh item contains “pärla”. Allright, here is what I found out:
2857 / 20 000 items
ObjectTrackingEnabled = true
Tag: Cli
Deploying SPFx using Office 365 cli, custom AAD App and Azure Pipelines
In this post I would like to share some findings from setting a deployment of SPFx. In my work:
- I need to deploy SPFx solutions using Azure Pipelines
- I need to use the least privileges/permissions
- I cannot use Legacy Authentication
First of all, big thanks to @waldekm and the whole community of @office365cli and @m365pnp for the quick help, and that outside working hours.
Let’s take a look at the setup piece by piece
Tag: Office365cli
Deploying SPFx using Office 365 cli, custom AAD App and Azure Pipelines
In this post I would like to share some findings from setting a deployment of SPFx. In my work:
- I need to deploy SPFx solutions using Azure Pipelines
- I need to use the least privileges/permissions
- I cannot use Legacy Authentication
First of all, big thanks to @waldekm and the whole community of @office365cli and @m365pnp for the quick help, and that outside working hours.
Let’s take a look at the setup piece by piece
Tag: Group
Modern Team Site without an Office 365 Group
These are my findings around Modern Sites without Office 365 Groups. It is, of course, a subject to change.
Today (2020-02-21) when you create a Modern Team Site without a group, you will get a site with the template STS#3. This oldie has been around for a while, hasn’t it?
I would always recommend creating Office 365 Group Connected sites.
How it is created
Through PowerShell/REST or from SharePoint Home, if your account is not allowed to create Office 365 Groups, it will automatically create a site without a group.
A user can only create 250 groups
A non-admin user can create no more than 250 resources in Azure AD. That is one of the many Azure AD service limits and restrictions. A “resource” can be an app registration, an Office 365 Group etc. But I would like to discuss Groups more in detail.
Imagine the following scenario: Your organization has disabled Office 365 Group Creation. Only IT can create new groups. A service account has been set up for creation of team sites. The application permissions are “binary”, either everything or nothing: Group.ReadWrite.All. This service account will hit the limit very soon.
Tag: Teamsite
Modern Team Site without an Office 365 Group
These are my findings around Modern Sites without Office 365 Groups. It is, of course, a subject to change.
Today (2020-02-21) when you create a Modern Team Site without a group, you will get a site with the template STS#3. This oldie has been around for a while, hasn’t it?
I would always recommend creating Office 365 Group Connected sites.
How it is created
Through PowerShell/REST or from SharePoint Home, if your account is not allowed to create Office 365 Groups, it will automatically create a site without a group.
Tag: Forms
Multilingual MS Forms
Want to translate your MS Forms into other languages? Create a form, not a quiz. It is available in both Forms and Forms Pro licenses.
Today I want to share one of my findings. One of those that seem obvious once you know, but that take time to find out.
Unfortunately, there is no official comparison of what is included in MS Forms vs. MS Forms Pro. So I thought that the ability to have forms in multiple languages was connected to the license.
Tag: Lessonlearned
Multilingual MS Forms
Want to translate your MS Forms into other languages? Create a form, not a quiz. It is available in both Forms and Forms Pro licenses.
Today I want to share one of my findings. One of those that seem obvious once you know, but that take time to find out.
Unfortunately, there is no official comparison of what is included in MS Forms vs. MS Forms Pro. So I thought that the ability to have forms in multiple languages was connected to the license.
Tag: Quiz
Multilingual MS Forms
Want to translate your MS Forms into other languages? Create a form, not a quiz. It is available in both Forms and Forms Pro licenses.
Today I want to share one of my findings. One of those that seem obvious once you know, but that take time to find out.
Unfortunately, there is no official comparison of what is included in MS Forms vs. MS Forms Pro. So I thought that the ability to have forms in multiple languages was connected to the license.
Tag: External
Using Sway as a simple static site builder
Sometimes all you need is just a simple static web page: instructions, a landing page, a collection of links. I think I have a perfect use case for Sway. Consider a scenario similar to what Laura Kokkarinen writes in her blog post:
An external user invitation needs an inviteRedirectUrl. Usually it is myapps.microsoft.com. In Laura’s case it was a given extranet url.
Tag: Sway
Using Sway as a simple static site builder
Sometimes all you need is just a simple static web page: instructions, a landing page, a collection of links. I think I have a perfect use case for Sway. Consider a scenario similar to what Laura Kokkarinen writes in her blog post:
An external user invitation needs an inviteRedirectUrl. Usually it is myapps.microsoft.com. In Laura’s case it was a given extranet url.
Tag: Calendar
Kalendern i SharePoint
Dags för ett svenskt inlägg igen. Idag vill jag titta på kalenderfunktionaliteten i SharePoint Online.
Fortfarande gammalt (classic) utseende
Tyvärr är det gammalt utseende som gäller och det finns inga planer från Microsoft att modernisera kalendern:
Jag förstår att det är väldigt mycket kod för att få till kalendervyn och att det inte är så lätt omvandla till ett modernt utseende, men det ställer till eftersom det upplevs som gammalt och inte användarvänligt ute i verksamheten.
Tag: Classic
Kalendern i SharePoint
Dags för ett svenskt inlägg igen. Idag vill jag titta på kalenderfunktionaliteten i SharePoint Online.
Fortfarande gammalt (classic) utseende
Tyvärr är det gammalt utseende som gäller och det finns inga planer från Microsoft att modernisera kalendern:
Jag förstår att det är väldigt mycket kod för att få till kalendervyn och att det inte är så lätt omvandla till ett modernt utseende, men det ställer till eftersom det upplevs som gammalt och inte användarvänligt ute i verksamheten.
Tag: Uservoice
Kalendern i SharePoint
Dags för ett svenskt inlägg igen. Idag vill jag titta på kalenderfunktionaliteten i SharePoint Online.
Fortfarande gammalt (classic) utseende
Tyvärr är det gammalt utseende som gäller och det finns inga planer från Microsoft att modernisera kalendern:
Jag förstår att det är väldigt mycket kod för att få till kalendervyn och att det inte är så lätt omvandla till ett modernt utseende, men det ställer till eftersom det upplevs som gammalt och inte användarvänligt ute i verksamheten.
Tag: REST
Hiding Teamify Prompt
If you want to remove the Microsoft Teams Banner on your SharePoint Site, the only thing you need is to set a web property on a site: TeamifyHidden=TRUE. I’ll give you some guidance below. But before you do that, consider following:
- If there is already a team created for a group connected site, the prompt won’t show up. Why fix something that is not a problem?
- Only group owners will get the prompt, if they are few and they know what it is, it is better to let them to decide whether to create or not to create a team.
- Only licensed users within your organization will be shown that choice. No external users or users without a license.
- And the most important part: if any site owner selects “Don’t show me again” it will stop popping up for all other site owners. If you happen to have a manual step in the group creation process, then you can just click it away.
Using CAML with SharePoint REST API
Do you prefer REST over CSOM as I do? I’ll skip the whys. Andrew Connell put it already in wrtiting so nicely. Well, if you do prefer REST, then you must have discovered some shortcomings of REST, or its incompleteness compared to CSOM. I think of:
- Inability to filter items based on multivalued taxonomy fields
- Inability to filter items based on user fields where user is added through a group, rather than directly, e.g. AssignedTo=[Me] combined with a SharePoint group.
- …
In such situations I was forced to use CSOM. Until yesterday. Yesterday I learned that we can actually use CAML queries in REST requests. This enables using REST in all situations. The REST API is still developed and many features are added. Maybe a particular operation that needs a CAML query today, can be supported in the core REST API and can be easily refactored then. But until then, we can use CAML queries in REST requests. Here are the important things about it:
Apps can only call the OOB CSOM and REST endpoints
As a SharePoint architect or a SharePoint developer, you must have been thinking about the benefits/limitations of SharePoint apps a lot. I want to point out one of them today, which is very important: using custom webservices deployed to SharePoint inside apps. That is impossible and it is designed to be so due to the security architecture in the sharepoint app framework. I have read much about SharePoint apps (books, whitepapers, blog posts) and stumbled over these two contradictive statements:
REST API: Add a plain text file as an attachment to a list item
SharePoint 2013 REST API has been enhanced and extended. The old _vti_bin/listdata.svc is still there, but the new api for working with lists and list items is much more and obviously a part of a bigger api: _api/web/lists Yesterday I saw an interesting question on SharePoint StackExchange:
The instructions in the MSDN resource are not so detailed, the cannot be. The guy who asked the question did as it stood in the examples. But sometimes solutions for SharePoint need some small adjustments :) Here is the simplest code to create an attachment in plain text for a list item 1 in the list called List1 in the root web. That’s it. But it works: [sourcecode language=“javascript”] var content = “Hello, this text is inside the file created with REST API”; var digest = $("#__REQUESTDIGEST").val(); var composedUrl = “/_api/web/lists/GetByTitle(‘List1’)/items(1)/AttachmentFiles/add(FileName=‘readme.txt’)”; $.ajax({ url: composedUrl, type: “POST”, data: content, headers: { “X-RequestDigest”: digest } }) [/sourcecode] This example is of course just for demonstration. It uses only hard-coded values. But it shows how simple it is to create a list item attachment using SharePoint 2013 REST API and “upload” plain text asynchronously to the server.
$().SPServices is best for SOAP
SPServices is a great tool, really nice work, Marc Anderson (@sympmarc). It has been there all the time I have developed for SharePoint. But the fact that you work with XML and you must parse the attributes (!) was the reason why I prefered listdata.svc and Client Object Model, where you get objects in JSON or you have a nice API to get objects and their properties. But there is an area where SPServices are really the best tool: SharePoint Web Services which only understand SOAP like SocialDataService.asmx.
Update list items with listdata.svc
In one of my previous posts I showed how to retrieve data from listdata.svc with jQuery $.getJSON method. Getting data is very simple, listdata.svc provides a powerful restful interface with filtering, expanding and other features. Read the best and short introduction to listdata.svc by Suneet Sharma or a more detailed and technical article about filters, functions and operators by Mike Flasko at Microsoft with short examples here. Now back to listdata.svc in the SharePoint environment. Corey Roth provides a good images and sample results. For REST the “http verbs” are very important: GET, POST, PUT, DELETE.. SharePoint RESTful interface defines these verbs like that:
Tag: Keyvault
Using secrets in Logic Apps in a secure way
This is a guide for how to handle secrets in a logic app in a secure way. It combines three resources:
- Accessing Key Vault from Logic App with Managed Identity
- Get Secrets Key Vault API
- Hide your logic apps secrets from prying eyes
First, enable a Managed Identity for your Logic App:
In the KeyVault, add a new Access Policy for the new Managed Identity (from the previous step). Use the least priviliges. In my case it is just enough with GET for secrets.
Azure Key Vault vs. Pipeline Variables
Using Azure Key Vault in a Pipeline is cool, but it is less secure.
The Key Vault setup
Have you tried the Key Vault Step in an Azure DevOps Pipeline? If you haven’t, please follow these awesome guides:
- Azure DevOps Labs. Using secrets from Azure Key Vault in a pipeline
- Tobias Zimmergren. Using Azure Key Vault Secrets in Azure DevOps pipelines
The steps described in these guides are easy, but that effort made me think about the first pair of pros and cons.
Tag: Secret
Using secrets in Logic Apps in a secure way
This is a guide for how to handle secrets in a logic app in a secure way. It combines three resources:
- Accessing Key Vault from Logic App with Managed Identity
- Get Secrets Key Vault API
- Hide your logic apps secrets from prying eyes
First, enable a Managed Identity for your Logic App:
In the KeyVault, add a new Access Policy for the new Managed Identity (from the previous step). Use the least priviliges. In my case it is just enough with GET for secrets.
Tag: Azurestorage
Filtering Azure Table Data directly in the Azure Function Binding
Instead of filtering values from an Azure Storage Table, you can do it directly in the bindings. It might not be a solution for everything, but in the right place, it is fantastic. I was very surprised to see how little code was needed after this binding change:
For that to work, define the filter attribute in the bindings: “filter”: “(PartitionKey eq ‘{package}’)”
To try it out, add a new row in a table defined in the bindings (“metadata” in my case):
Tag: Binding
Filtering Azure Table Data directly in the Azure Function Binding
Instead of filtering values from an Azure Storage Table, you can do it directly in the bindings. It might not be a solution for everything, but in the right place, it is fantastic. I was very surprised to see how little code was needed after this binding change:
For that to work, define the filter attribute in the bindings: “filter”: “(PartitionKey eq ‘{package}’)”
To try it out, add a new row in a table defined in the bindings (“metadata” in my case):
AngularJS: sync $location.search with an input value
I have used AngularJS for a while and to me this seems to be the best MVC javascript framework. Today I wanted to implement a search which uses an input and a hash query string like in google. The input value and url have to be synced like:
index.html#?term=something
To do this we have to inject $location
into our angular control. See the Angular Guide about $location. Then we have to observe both the $scope.term (which is bound to the input value) and $location.search().
Implement public wcf service in SharePoint
If you have an external web service reference in your sharepoint solution, you can use web.config configuration like:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding\_ISuperService" >
<security mode="None">
<message clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://super.domain/SuperService.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding\_ISuperService"
contract="ISuperService"
name="SuperServiceEndpoint">
</endpoint>
</client>
</system.serviceModel>
```security mode is set to "None". Then in code just get this configuration:
var proxy = new SuperServiceClient(“SuperServiceEndpoint”); var result = proxy.GetSomething();
var binding = new WSHttpBinding(); binding.Security.Mode = SecurityMode.None; var endpoint = new EndpointAddress(“http://super.domain/SuperService.svc"); var proxy = new ExternalServices.DreamServiceClient(binding, endpoint); var result = proxy.GetSomething();
Binda Data till ListView i WPF
Det är väldigt smidigt att koppla datakälla till en ListView i WPF. Man skriver kod i XAML. Och i koden bakom anger man: myListView.ItemsSource = myList;
Tag: Table
Filtering Azure Table Data directly in the Azure Function Binding
Instead of filtering values from an Azure Storage Table, you can do it directly in the bindings. It might not be a solution for everything, but in the right place, it is fantastic. I was very surprised to see how little code was needed after this binding change:
For that to work, define the filter attribute in the bindings: “filter”: “(PartitionKey eq ‘{package}’)”
To try it out, add a new row in a table defined in the bindings (“metadata” in my case):
Save an excel sheet as a clean table
To save an excel sheet as a html table is very easy. Just select the needed area, then go to Save as and check the selection and choose html as output format. It works fine. It even looks like it did in Excel. But what if you don’t want all this junk, you want only the plain html table (e.g. for pasting into WP). When I saved my permission levels to html, I used this javascript code. First open the html page which Excel has created in Chrome, open the Dev Tools console, load the latest jQuery into the page, and remove all unnecessary attributes and styling, remove the comments, after that you can just copy the outerHTML of the table and paste into a text editor:
Tag: Typescript
Filtering Azure Table Data directly in the Azure Function Binding
Instead of filtering values from an Azure Storage Table, you can do it directly in the bindings. It might not be a solution for everything, but in the right place, it is fantastic. I was very surprised to see how little code was needed after this binding change:
For that to work, define the filter attribute in the bindings: “filter”: “(PartitionKey eq ‘{package}’)”
To try it out, add a new row in a table defined in the bindings (“metadata” in my case):
TypeScript in SharePoint
By now TypeScript shouldn’t be something one has to introduce.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
If you haven’t already done it, go and see the intro video for TypeScript, check out a tutorial and visit the typescript playground. There are other javascript libraries which extend javascript and are compatible/compile to javascript: Dart and CoffeeScript. To be honest I had never time to try those. The fact that TypeScript is well integrated into Visual Studio which I happen to work within all the days (intellisense, compilation checks and more) did me curious. This post is actually not about TypeScript itself, but a test to use it in SharePoint. In this short “lab” I even had Web Essentials 2012 which automatically compile typescript files into plain javascript files on save. This is what I did: Install TypeScript and Web Essentials 2012 Create a SharePoint-hosted app: Create a new TypeScript file in the autogenerated “Scripts”-module and call it “Greeter.ts” Just save the file as it is. The new file is created: Greeter.js Now we don’t need to copy this file to the app, so remove Greeter.ts from the Elements.xml file (or comment it out): Open the Default.aspx from the Pages module and add the reference to the new javascript file:
Tag: Addin
Site Collection App Catalog vs. Tenant App Catalog
Site Collection App Catalogs are great for special cases (like developing apps or site unique apps), but using them on scale would be a mess.
I got a question: Why should we use the Tenant App Catalog at all when we could enable a Site Collection App Catalog on every teamsite? So the suggestion here is to install SharePoint Framework Packages on many Site Collection App Catalogs, instead of the Tenant App Catalog. In that way those wouldn’t be visible for all users in the “Add an app” page.
Tips and tricks for Site Collection App Catalogs
Site Collection App Catalogs (SCAC) are much appreciated, thank you, Office 365 Team. Here is a couple of tips and tricks for SCAC.
Tip #1 You don’t need Tenant Admin rights to add a new Site Collection App Catalog
I have seen many blogs, forum threads etc that state that only Global Tenant Administrators can add new Site Collection App Catalogs. The truth is that a SharePoint Admin rights are enough. The trick is to make that SharePoint Admin Account to a site collection administrator of the app catalog site. To be precise the account that adds a new SCAC must have Manage Web Permissions, as stated in error message:
Tag: Appcatalog
Site Collection App Catalog vs. Tenant App Catalog
Site Collection App Catalogs are great for special cases (like developing apps or site unique apps), but using them on scale would be a mess.
I got a question: Why should we use the Tenant App Catalog at all when we could enable a Site Collection App Catalog on every teamsite? So the suggestion here is to install SharePoint Framework Packages on many Site Collection App Catalogs, instead of the Tenant App Catalog. In that way those wouldn’t be visible for all users in the “Add an app” page.
Tag: Service
Azure Key Vault vs. Pipeline Variables
Using Azure Key Vault in a Pipeline is cool, but it is less secure.
The Key Vault setup
Have you tried the Key Vault Step in an Azure DevOps Pipeline? If you haven’t, please follow these awesome guides:
- Azure DevOps Labs. Using secrets from Azure Key Vault in a pipeline
- Tobias Zimmergren. Using Azure Key Vault Secrets in Azure DevOps pipelines
The steps described in these guides are easy, but that effort made me think about the first pair of pros and cons.
Implement public wcf service in SharePoint
If you have an external web service reference in your sharepoint solution, you can use web.config configuration like:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding\_ISuperService" >
<security mode="None">
<message clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://super.domain/SuperService.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding\_ISuperService"
contract="ISuperService"
name="SuperServiceEndpoint">
</endpoint>
</client>
</system.serviceModel>
```security mode is set to "None". Then in code just get this configuration:
var proxy = new SuperServiceClient(“SuperServiceEndpoint”); var result = proxy.GetSomething();
var binding = new WSHttpBinding(); binding.Security.Mode = SecurityMode.None; var endpoint = new EndpointAddress(“http://super.domain/SuperService.svc"); var proxy = new ExternalServices.DreamServiceClient(binding, endpoint); var result = proxy.GetSomething();
Tag: Variable
Azure Key Vault vs. Pipeline Variables
Using Azure Key Vault in a Pipeline is cool, but it is less secure.
The Key Vault setup
Have you tried the Key Vault Step in an Azure DevOps Pipeline? If you haven’t, please follow these awesome guides:
- Azure DevOps Labs. Using secrets from Azure Key Vault in a pipeline
- Tobias Zimmergren. Using Azure Key Vault Secrets in Azure DevOps pipelines
The steps described in these guides are easy, but that effort made me think about the first pair of pros and cons.
Tag: Certificate
Trust gulp-connect certificate from Visual Studio Online on Mac OS
I have read and followed this awesome post:
Getting SPFx working in Visual Studio Online by SPDavid.
I got my fingers and tried that guide out. This worked good, I spent some time, though, googling (binging) around to get rid of the SSL Warnings for the remote “localhost” on my Mac.
I would like to share this simple instruction on how to trust a self signed certificate from gulp-connect on Mac OS. The implication is that the certificate is on the remote linux machine (on the Visual Studio Environment), that you are connected to through the Visual Studio Code extension.
Tag: Gulp
Trust gulp-connect certificate from Visual Studio Online on Mac OS
I have read and followed this awesome post:
Getting SPFx working in Visual Studio Online by SPDavid.
I got my fingers and tried that guide out. This worked good, I spent some time, though, googling (binging) around to get rid of the SSL Warnings for the remote “localhost” on my Mac.
I would like to share this simple instruction on how to trust a self signed certificate from gulp-connect on Mac OS. The implication is that the certificate is on the remote linux machine (on the Visual Studio Environment), that you are connected to through the Visual Studio Code extension.
Tag: Macos
Trust gulp-connect certificate from Visual Studio Online on Mac OS
I have read and followed this awesome post:
Getting SPFx working in Visual Studio Online by SPDavid.
I got my fingers and tried that guide out. This worked good, I spent some time, though, googling (binging) around to get rid of the SSL Warnings for the remote “localhost” on my Mac.
I would like to share this simple instruction on how to trust a self signed certificate from gulp-connect on Mac OS. The implication is that the certificate is on the remote linux machine (on the Visual Studio Environment), that you are connected to through the Visual Studio Code extension.
Tag: Visual Studio
Trust gulp-connect certificate from Visual Studio Online on Mac OS
I have read and followed this awesome post:
Getting SPFx working in Visual Studio Online by SPDavid.
I got my fingers and tried that guide out. This worked good, I spent some time, though, googling (binging) around to get rid of the SSL Warnings for the remote “localhost” on my Mac.
I would like to share this simple instruction on how to trust a self signed certificate from gulp-connect on Mac OS. The implication is that the certificate is on the remote linux machine (on the Visual Studio Environment), that you are connected to through the Visual Studio Code extension.
Working with resx files in Visual Studio
Today I found a nice Visual Studio Extension for working with localization and resx files: Resx Resource Manager. This extension provides an additional view in your project and scans all the resx files. I would recommend it to all projects where you have to translate your interface. Here is how it looks in my project: It can also assist with some machine translation from Bing and MyMemory: Another good thing is the Export and Import to and from Excel. Wonderful if you need help from Non-developers.
TypeScript in SharePoint
By now TypeScript shouldn’t be something one has to introduce.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
If you haven’t already done it, go and see the intro video for TypeScript, check out a tutorial and visit the typescript playground. There are other javascript libraries which extend javascript and are compatible/compile to javascript: Dart and CoffeeScript. To be honest I had never time to try those. The fact that TypeScript is well integrated into Visual Studio which I happen to work within all the days (intellisense, compilation checks and more) did me curious. This post is actually not about TypeScript itself, but a test to use it in SharePoint. In this short “lab” I even had Web Essentials 2012 which automatically compile typescript files into plain javascript files on save. This is what I did: Install TypeScript and Web Essentials 2012 Create a SharePoint-hosted app: Create a new TypeScript file in the autogenerated “Scripts”-module and call it “Greeter.ts” Just save the file as it is. The new file is created: Greeter.js Now we don’t need to copy this file to the app, so remove Greeter.ts from the Elements.xml file (or comment it out): Open the Default.aspx from the Pages module and add the reference to the new javascript file:
.tfignore - ".gitignore" for TFS
I haven’t used TFS so much. But I like it so far. It works smoothly, both TFS 2012 (on premises) and TFS Preview (online). I really appreciate that Microsoft has been inspired from git - the world’s best VCS :). For example .tfignore which works exactly like the .gitignore file. It is nice that the non-classic Microsoft dot notation convention for naming the hidden files is chosen. So if you have any files to ignore just do it like you did in your git projects. Here is a .tfignore which I use in my SharePoint project for now. I suppose it will be extended soon:
Simplify js and css development with Web Essentials (Visual Studio Extension)
If you develop much javascript and css, this is the exension to Visual Studio you just can’t live without: Web Essentials (It is even released for VS2012). You can do many things with it. Here are two examples for simple but very useful functions: 1. Show which browsers support a css attribute: 2. Collapse javascript functions and create #region areas like in C# code: There is much more, like less and coffeescript parsing. Just check the documentation. And it is fully appliable in SharePoint development.
The original Visual Web Part template is missing in Visual Studio 2012
Today I encountered a weird issue, the classic Visual Web Part template was gone in Visual Studio 2012. When I created a Visual WebPart, a webpart was created with a generated .g.cs file, like the sandboxed visual webparts. I am not exactly sure why it happened. According to the MSDN guide Creating Web Parts for SharePoint, the structure of Visual Webparts should be the same as in Visual Studio 2010. It could have happened after I installed the power tools. However, if someone runs into the same issue, here is the solution: Copy this zip file from a computer with VS2010 installed:
Develop for SharePoint on Windows 8
Do you like Windows 8 user expirience, as me? Well than you want to try developing sharepoint solutions in Windows 8. Here I will show what I found out.
Environment
I installed Windows 8 Release Preview as a VMWare machine. Then I installed Visual Studio 2012 RC. Then I followed the steps for installing SharePoint on Windows 8 which are more or less the same as for Windows 7 client install. But then I encountered an error I haven’t found solution for yet. In my standalone sharepoint installation there were some permission problems:
Todolist in VS
A really nice feature is a task list. Just write //TODO something something in your code and it appears in the task list which can be shown through View - Task List in Visual Studio.
Aktivera intellisense för javascript i VS
Det finns ett sätt att aktivera intellisense för javascript i VS: Klistra in det i ditt js-fil eller aspx:
/// <reference name="MicrosoftAjax.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.core.debug.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.debug.js" />
```Men tyvärr [kommer det inte funka om du har installerat Resharper](http://devnet.jetbrains.net/thread/297493). Eller lägg till vanliga script-taggar som beskrivet i boken Sharepoint As Developer Platform:
<asp:PlaceHolder ID=“PlaceHolder1” runat=“server” Visible=“false”> </asp:PlaceHolder>
ForEach-metod i List
En intressant variant av foreach är ForEach-metoden i List. Titta på det lilla exemplet:
private static void SavePlacesToDB(SQLiteConnection cnn,
List<dynamic> places)
{
places.ForEach(obj => SavePlaceToDB(obj, cnn));
}
```Här används även det nya objektet [dynamic](http://msdn.microsoft.com/en-us/library/dd264736.aspx) som har kommit i Visual Studio 2010, samt en [lambda expression (=>)](http://msdn.microsoft.com/en-us/library/bb397687.aspx).
Tag: Visual Studio Code
Trust gulp-connect certificate from Visual Studio Online on Mac OS
I have read and followed this awesome post:
Getting SPFx working in Visual Studio Online by SPDavid.
I got my fingers and tried that guide out. This worked good, I spent some time, though, googling (binging) around to get rid of the SSL Warnings for the remote “localhost” on my Mac.
I would like to share this simple instruction on how to trust a self signed certificate from gulp-connect on Mac OS. The implication is that the certificate is on the remote linux machine (on the Visual Studio Environment), that you are connected to through the Visual Studio Code extension.
Tag: Vscode
Trust gulp-connect certificate from Visual Studio Online on Mac OS
I have read and followed this awesome post:
Getting SPFx working in Visual Studio Online by SPDavid.
I got my fingers and tried that guide out. This worked good, I spent some time, though, googling (binging) around to get rid of the SSL Warnings for the remote “localhost” on my Mac.
I would like to share this simple instruction on how to trust a self signed certificate from gulp-connect on Mac OS. The implication is that the certificate is on the remote linux machine (on the Visual Studio Environment), that you are connected to through the Visual Studio Code extension.
Tag: Vso
Trust gulp-connect certificate from Visual Studio Online on Mac OS
I have read and followed this awesome post:
Getting SPFx working in Visual Studio Online by SPDavid.
I got my fingers and tried that guide out. This worked good, I spent some time, though, googling (binging) around to get rid of the SSL Warnings for the remote “localhost” on my Mac.
I would like to share this simple instruction on how to trust a self signed certificate from gulp-connect on Mac OS. The implication is that the certificate is on the remote linux machine (on the Visual Studio Environment), that you are connected to through the Visual Studio Code extension.
Tag: Web
Trust gulp-connect certificate from Visual Studio Online on Mac OS
I have read and followed this awesome post:
Getting SPFx working in Visual Studio Online by SPDavid.
I got my fingers and tried that guide out. This worked good, I spent some time, though, googling (binging) around to get rid of the SSL Warnings for the remote “localhost” on my Mac.
I would like to share this simple instruction on how to trust a self signed certificate from gulp-connect on Mac OS. The implication is that the certificate is on the remote linux machine (on the Visual Studio Environment), that you are connected to through the Visual Studio Code extension.
Simple Build for dotnet new react
I created a sample ASP.NET Core app with React.
dotnet new react
Then it took a couple of hours to get the build to work. Here is my working azure-pipelines.yml:
Resources:
Cool presentation about web performance optimization
by Chris Love [slideshare id=15218139&doc=webperformanceoptimizationformodernwebapplications-121116224847-phpapp01]
cloud9 web ide
Skapa javascript-appar i din webbläsare. Mycket smidigt. Direkt kontakt till github.
Tag: Contenteditor
Is Custom Script Dangerous
Allowing custom script has its security implications. But what exactly does it mean? Is it dangerous? My colleauge Daniel and me have done a little experiment. There are two implications stated on MS Docs:
- Scripts have access to everything the user has access to.
- Scripts can access content across several Office 365 services and even beyond with Microsoft Graph integration.
To summarize, we can look at that picture:
So the risk that user 1 (the Blue User) intentionally or unintentionally places a script and lets user 2 (the Red User) run this script by linking to the page that has this script. The page must be in a “common” place.
Tag: Contenteditorwebpart
Is Custom Script Dangerous
Allowing custom script has its security implications. But what exactly does it mean? Is it dangerous? My colleauge Daniel and me have done a little experiment. There are two implications stated on MS Docs:
- Scripts have access to everything the user has access to.
- Scripts can access content across several Office 365 services and even beyond with Microsoft Graph integration.
To summarize, we can look at that picture:
So the risk that user 1 (the Blue User) intentionally or unintentionally places a script and lets user 2 (the Red User) run this script by linking to the page that has this script. The page must be in a “common” place.
Ändra content i ContentEditorWebPart
Det finns ett exempel här.
//defaultAspx är sidan (SPListItem i Sidor)
//måste checkas ut först
//mgr är WebPartManager
//wp är contentEditorWebPart
web.AllowUnsafeUpdates = true;
XmlDocument xmlDoc = new XmlDocument();
XmlElement xmlElement = xmlDoc.CreateElement("Content");
xmlElement.InnerText = ((Microsoft.SharePoint.WebPartPages.ContentEditorWebPart)wp).Content.InnerText.ToString();
xmlElement.InnerText = xmlElement.InnerText.ToString().Replace("#HEADING#", "Welcome for welcome");
wp.Content = xmlElement;
mgr.SaveChanges(wp);
defaultAspx.File.CheckIn("");
defaultAspx.File.Publish("");
web.AllowUnsafeUpdates = false;
```Man måste skapa nytt XmlDocument och XmlElement, om man försöker skriva direkt till wp.Content.InnerText kommer det inte uppdateras. I det här fallet, byter vi ut #HEADING# mot något mer passande.
Tag: Custom Script
Is Custom Script Dangerous
Allowing custom script has its security implications. But what exactly does it mean? Is it dangerous? My colleauge Daniel and me have done a little experiment. There are two implications stated on MS Docs:
- Scripts have access to everything the user has access to.
- Scripts can access content across several Office 365 services and even beyond with Microsoft Graph integration.
To summarize, we can look at that picture:
So the risk that user 1 (the Blue User) intentionally or unintentionally places a script and lets user 2 (the Red User) run this script by linking to the page that has this script. The page must be in a “common” place.
Tag: Ethical Hacking
Is Custom Script Dangerous
Allowing custom script has its security implications. But what exactly does it mean? Is it dangerous? My colleauge Daniel and me have done a little experiment. There are two implications stated on MS Docs:
- Scripts have access to everything the user has access to.
- Scripts can access content across several Office 365 services and even beyond with Microsoft Graph integration.
To summarize, we can look at that picture:
So the risk that user 1 (the Blue User) intentionally or unintentionally places a script and lets user 2 (the Red User) run this script by linking to the page that has this script. The page must be in a “common” place.
Tag: Scripteditor
Is Custom Script Dangerous
Allowing custom script has its security implications. But what exactly does it mean? Is it dangerous? My colleauge Daniel and me have done a little experiment. There are two implications stated on MS Docs:
- Scripts have access to everything the user has access to.
- Scripts can access content across several Office 365 services and even beyond with Microsoft Graph integration.
To summarize, we can look at that picture:
So the risk that user 1 (the Blue User) intentionally or unintentionally places a script and lets user 2 (the Red User) run this script by linking to the page that has this script. The page must be in a “common” place.
Tag: Boundary
The Path Length Limit of 400 chars in SharePoint Online
This post is my summary and my conclusions on the Path Length Limit in SharePoint Online and OneDrive.
How the path length is calculated
Path Length is not the same as the URL length. It is the relative Url.
/sites/site-url/documenlibrary/folder1/folder2/filename.fileextension
Calculations rules
- Only the server relative url part is counted. The “https://[tenant].sharepoin.com” has no impact on that. It starts from the foward slash: “/sites” (or /teams).
- An encoded value such as a blankspace (%20) is treated as one character, not three.
- A unicode character, and an emoji is treated as one character. Good news for Non-English Names.
- Url Parameters, like “?Web=1” are not calculated.
- The site url and the document library url is taken into account
- All slashes are included
- A file extension is also included, and even the dot, e.g. “.docx”
Other related information
- A site url and a group name can only be 64 characters max.
- The path in the “Copy Link” is much shorter than the “real” path
- There is no limit (as of time of writing - 2019-10-30) on the folder name length (other than the bigger limit of 400 characters), I had no issues to add a folder name with 312 characters.
Tag: Limit
The Path Length Limit of 400 chars in SharePoint Online
This post is my summary and my conclusions on the Path Length Limit in SharePoint Online and OneDrive.
How the path length is calculated
Path Length is not the same as the URL length. It is the relative Url.
/sites/site-url/documenlibrary/folder1/folder2/filename.fileextension
Calculations rules
- Only the server relative url part is counted. The “https://[tenant].sharepoin.com” has no impact on that. It starts from the foward slash: “/sites” (or /teams).
- An encoded value such as a blankspace (%20) is treated as one character, not three.
- A unicode character, and an emoji is treated as one character. Good news for Non-English Names.
- Url Parameters, like “?Web=1” are not calculated.
- The site url and the document library url is taken into account
- All slashes are included
- A file extension is also included, and even the dot, e.g. “.docx”
Other related information
- A site url and a group name can only be 64 characters max.
- The path in the “Copy Link” is much shorter than the “real” path
- There is no limit (as of time of writing - 2019-10-30) on the folder name length (other than the bigger limit of 400 characters), I had no issues to add a folder name with 312 characters.
A user can only create 250 groups
A non-admin user can create no more than 250 resources in Azure AD. That is one of the many Azure AD service limits and restrictions. A “resource” can be an app registration, an Office 365 Group etc. But I would like to discuss Groups more in detail.
Imagine the following scenario: Your organization has disabled Office 365 Group Creation. Only IT can create new groups. A service account has been set up for creation of team sites. The application permissions are “binary”, either everything or nothing: Group.ReadWrite.All. This service account will hit the limit very soon.
Tag: Link
The Path Length Limit of 400 chars in SharePoint Online
This post is my summary and my conclusions on the Path Length Limit in SharePoint Online and OneDrive.
How the path length is calculated
Path Length is not the same as the URL length. It is the relative Url.
/sites/site-url/documenlibrary/folder1/folder2/filename.fileextension
Calculations rules
- Only the server relative url part is counted. The “https://[tenant].sharepoin.com” has no impact on that. It starts from the foward slash: “/sites” (or /teams).
- An encoded value such as a blankspace (%20) is treated as one character, not three.
- A unicode character, and an emoji is treated as one character. Good news for Non-English Names.
- Url Parameters, like “?Web=1” are not calculated.
- The site url and the document library url is taken into account
- All slashes are included
- A file extension is also included, and even the dot, e.g. “.docx”
Other related information
- A site url and a group name can only be 64 characters max.
- The path in the “Copy Link” is much shorter than the “real” path
- There is no limit (as of time of writing - 2019-10-30) on the folder name length (other than the bigger limit of 400 characters), I had no issues to add a folder name with 312 characters.
Good beginners' tutorial on android, eclipse and git
Smashing magazine has a pretty good tutorial how to start programming for android using git, github, eclipse and datastorage. I recommend: Get Started Developing For Android With Eclipse, Reloaded
Tag: Onedrive
The Path Length Limit of 400 chars in SharePoint Online
This post is my summary and my conclusions on the Path Length Limit in SharePoint Online and OneDrive.
How the path length is calculated
Path Length is not the same as the URL length. It is the relative Url.
/sites/site-url/documenlibrary/folder1/folder2/filename.fileextension
Calculations rules
- Only the server relative url part is counted. The “https://[tenant].sharepoin.com” has no impact on that. It starts from the foward slash: “/sites” (or /teams).
- An encoded value such as a blankspace (%20) is treated as one character, not three.
- A unicode character, and an emoji is treated as one character. Good news for Non-English Names.
- Url Parameters, like “?Web=1” are not calculated.
- The site url and the document library url is taken into account
- All slashes are included
- A file extension is also included, and even the dot, e.g. “.docx”
Other related information
- A site url and a group name can only be 64 characters max.
- The path in the “Copy Link” is much shorter than the “real” path
- There is no limit (as of time of writing - 2019-10-30) on the folder name length (other than the bigger limit of 400 characters), I had no issues to add a folder name with 312 characters.
Tag: Path
The Path Length Limit of 400 chars in SharePoint Online
This post is my summary and my conclusions on the Path Length Limit in SharePoint Online and OneDrive.
How the path length is calculated
Path Length is not the same as the URL length. It is the relative Url.
/sites/site-url/documenlibrary/folder1/folder2/filename.fileextension
Calculations rules
- Only the server relative url part is counted. The “https://[tenant].sharepoin.com” has no impact on that. It starts from the foward slash: “/sites” (or /teams).
- An encoded value such as a blankspace (%20) is treated as one character, not three.
- A unicode character, and an emoji is treated as one character. Good news for Non-English Names.
- Url Parameters, like “?Web=1” are not calculated.
- The site url and the document library url is taken into account
- All slashes are included
- A file extension is also included, and even the dot, e.g. “.docx”
Other related information
- A site url and a group name can only be 64 characters max.
- The path in the “Copy Link” is much shorter than the “real” path
- There is no limit (as of time of writing - 2019-10-30) on the folder name length (other than the bigger limit of 400 characters), I had no issues to add a folder name with 312 characters.
Tag: Microsoft
A user can only create 250 groups
A non-admin user can create no more than 250 resources in Azure AD. That is one of the many Azure AD service limits and restrictions. A “resource” can be an app registration, an Office 365 Group etc. But I would like to discuss Groups more in detail.
Imagine the following scenario: Your organization has disabled Office 365 Group Creation. Only IT can create new groups. A service account has been set up for creation of team sites. The application permissions are “binary”, either everything or nothing: Group.ReadWrite.All. This service account will hit the limit very soon.
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Diagram
Snabba diagram i SharePoint Online
Ett nytt tips på svenska: det finns en webpart i SharePoint Online: snabbdiagram.
När du har lagt till ett snabbdiagram, kan du skriva välja mellan stapel och cirkeldiagram
Du kan bara välja mellan stapel- och cirkeldiagram.
Data går att mata in direkt.
Resultatet får du direkt:
Använd data från en lista
Det går att visualisera data från en SharePoint-lista. Det är inte så mycket mer komplicerat, men det öppnar nya möjligheter. Du behöver bara hålla listan uppdaterad.
Publishing Visio diagrams as html image maps
I got a question from a customer: We have our processes defined in Visio, we don’t have SharePoint Enterprise CALs to use the Visio webpart. We have links in process maps. What can we do? Well there are three five ways to solve this business need:
- Find money for SharePoint Enterprise - Very expensive
- Show Visio diagrams as pdf files on SharePoint Pages - Expensive.
- Embed Visio diagrams as html image maps - Least expensive
- Embed Visio diagrams as svg pictures - Separate blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
If the business needs other features available only in Enterprise, just use the solution 1. Stop reading. If you are looking for alternatives, then consider pdf and image maps. I have seen projects where pdf files were embedded in the SharePoint Pages. It required a pdf plugin in IE, a lot of time to make it look the same in different browsers and the scroll and fixed size was still there. It was expensive because of the development and configuration time. In this blog post, I want to show the alternative number 3: embedding Visio diagrams as html image maps. This is only a Proof-of-concept so far.
Tag: Modern
Snabba diagram i SharePoint Online
Ett nytt tips på svenska: det finns en webpart i SharePoint Online: snabbdiagram.
När du har lagt till ett snabbdiagram, kan du skriva välja mellan stapel och cirkeldiagram
Du kan bara välja mellan stapel- och cirkeldiagram.
Data går att mata in direkt.
Resultatet får du direkt:
Använd data från en lista
Det går att visualisera data från en SharePoint-lista. Det är inte så mycket mer komplicerat, men det öppnar nya möjligheter. Du behöver bara hålla listan uppdaterad.
Switch back to Modern UI
Just a little tip. When you switched to a Classic View of Site Contents, you can switch back by removing a cookie called “splnu”.
Tag: Webparts
Snabba diagram i SharePoint Online
Ett nytt tips på svenska: det finns en webpart i SharePoint Online: snabbdiagram.
När du har lagt till ett snabbdiagram, kan du skriva välja mellan stapel och cirkeldiagram
Du kan bara välja mellan stapel- och cirkeldiagram.
Data går att mata in direkt.
Resultatet får du direkt:
Använd data från en lista
Det går att visualisera data från en SharePoint-lista. Det är inte så mycket mer komplicerat, men det öppnar nya möjligheter. Du behöver bara hålla listan uppdaterad.
Webpart in a reusable user control
In my previous post I wrote about using IgnoreIfAlreadyExists=“True” for preventing of adding webparts multiple times. It works fine until you redeploy your project. Another approach is to use a user control with you webpart. Add mapped folder CONTROLTEMPLATES. Create a new user control, add you assembly and your webpart. Then you can add this user control wherever you need it.
<%@ Register
tagprefix="SPSWC"
Namespace="Microsoft.SharePoint.Portal.WebControls"
Assembly="Microsoft.SharePoint.Portal, Version=14.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<SPSWC:SocialCommentWebPart runat="server"
AllowEdit="True"
AllowConnect="True"
ConnectionID="00000000-0000-0000-0000-000000000000"
Title="Note Board"
IsIncluded="True"
Dir="Default"
PartImageLarge=""
IsVisible="True"
AllowMinimize="True"
ZoneID=""
ID="g\_5937b022\_83bb\_40cb\_b68f\_bd565bf96885"
FrameState="Normal"
ExportMode="All"
TitleLocIdNum="0"
AllowHide="True"
SuppressWebPartChrome="False"
DetailLink=""
ChromeType="None"
DescriptionLocId="Null"
TitleLocId="Null"
MissingAssembly="Cannot import this Web Part."
PartImageSmall=""
AllowRemove="True"
HelpMode="Modeless"
FrameType="None"
AllowZoneChange="True"
PartOrder="1"
Description="Enable users to leave short, publicly-viewable notes about this page."
HelpLink=""
DescriptionLocIdNum="0"
ExportControlledProperties="True"
IsIncludedFilter=""
\_\_MarkupType="vsattributemarkup"
\_\_WebPartId="{5937b022-83bb-40cb-b68f-bd565bf96885}"
WebPart="true"
Height=""
Width="">
</SPSWC:SocialCommentWebPart>
```Then add your user control into page layout like this:
<%@ Register Tagprefix=“CONTOSO” TagName=“SocialComment” Src="~/_CONTROLTEMPLATES/CONTOSO/SocialCommentUserControl.ascx" %> <CONTOSO:SocialComment id=“SocialComment” runat=“server” />
Webparts on a layoutpage which is provisioned several times
It is pretty easy to add webparts to a layout page. Just define the webparts in the corresponding Elements.xml file. Like you do in onet.xml. It works fine if you provision just a single page with this layout on a web. If you have multiple pages that use the same page layout (e.g. in WCM). The trick is to use the attribute IgnoreIfAlreadyExists in the File tag:
IgnoreIfAlreadyExists="True"
Comments from Wordpress.com
Webpart in a reusable user control « Sharepoint. Kunskap. Upptäckter på resan. - Sep 1, 2011
Custom Title on built-in webpart
What to do if you want to change the title in the built-in webpart like Tasks or so. Your own title or just to avoid tasks (1) and tasks (2) if you add two views of them to a page. In onet.xml you add them as view:
<View
List="$Resources:core,lists\_Folder;/$Resources:core,tasks\_Folder;"
BaseViewID="7" WebPartZoneID="Middle"
WebPartOrder="6"/>
```The solution is to add [cdata element and webpart tag within it](http://www.novolocus.com/2011/06/14/set-the-title-of-a-listviewwebpart/). So now replace this with:
<![CDATA[ Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c Microsoft.SharePoint.WebPartPages.XsltListViewWebPart Task Title as I want it ]]>
Webpart Livscykel
http://nishantrana.wordpress.com/2009/02/14/understanding-web-part-life-cycle/ OnInit – Configuration values set using WebBrowsable properties and those in web part task pane are loaded into the web part. LoadViewState – The view state of the web part is populated over here. CreateChildControls – All the controls specified are created and added to controls collection. When the page is being rendered for the first time the method generally occurs after the OnLoad() event. In case of postback, it is called before the OnLoad() event. We can make use of EnsureChildControls() - It checks to see if the CreateChildControls method has yet been called, and if it has not, calls it. OnLoad User Generated Event – for e.g. button click on the web part. OnPreRender – Here we can change any of the web part properties before the control output is drawn. RenderContents – Html Output is generated. SaveViewState - View state of the web part is serialized and saved. Dispose UnLoad.
Ändra content i ContentEditorWebPart
Det finns ett exempel här.
//defaultAspx är sidan (SPListItem i Sidor)
//måste checkas ut först
//mgr är WebPartManager
//wp är contentEditorWebPart
web.AllowUnsafeUpdates = true;
XmlDocument xmlDoc = new XmlDocument();
XmlElement xmlElement = xmlDoc.CreateElement("Content");
xmlElement.InnerText = ((Microsoft.SharePoint.WebPartPages.ContentEditorWebPart)wp).Content.InnerText.ToString();
xmlElement.InnerText = xmlElement.InnerText.ToString().Replace("#HEADING#", "Welcome for welcome");
wp.Content = xmlElement;
mgr.SaveChanges(wp);
defaultAspx.File.CheckIn("");
defaultAspx.File.Publish("");
web.AllowUnsafeUpdates = false;
```Man måste skapa nytt XmlDocument och XmlElement, om man försöker skriva direkt till wp.Content.InnerText kommer det inte uppdateras. I det här fallet, byter vi ut #HEADING# mot något mer passande.
SocialCommentWebPart
Lägg till en kommentarruta i din sida. Gör det lite till webb2.0. Här finns lite info. På denna sida står det hur man kan lägga till webparten mha xml. You can even provision a social comment webpart like it is done in my site:
<File Url="person.aspx" Type="Ghostable">
<AllUsersWebPart WebPartZoneID="MiddleLeftZone" WebPartOrder="3">
<!\[CDATA\[
<WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">
<Assembly>Microsoft.SharePoint.Portal, Version=14.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<TypeName>Microsoft.SharePoint.Portal.WebControls.SocialCommentWebPart</TypeName>
<Title>$Resources:spscore,SocialComment\_WebPart\_Title</Title>
<Description>$Resources:spscore,SocialComment\_WebPart\_Description</Description>
<PartOrder>3</PartOrder>
<FrameType>TitleBarOnly</FrameType>
<AllowMinimize>true</AllowMinimize>
<AllowRemove>true</AllowRemove>
<IsVisible>true</IsVisible>
</WebPart>
\]\]>
</AllUsersWebPart>
</File>
Gratis webparts från Amrein
Finns gratis webparts från Amrein Engineering. Fått tips från sharepoint.stackexchange.com. Testat AELightBox. Men det är rätt så krångligt med inställningar. Den kräver att man skriver in vilken vy och så vidare. Vyn ska ha “title” och den kräver även kolumner så som ImageWidth och ImageHeight. Detta känns lite mindre användbart eftersom de här värdena kunde man hämta från bilden själv och anpassa till skärmens upplösning. [caption id=“attachment_405” align=“aligncenter” width=“291” caption=“Amrein Lightbox”][/caption]
Tag: Column-Formatting
Min första kolumnformatering
Jag har precis börjat med kolumnformatering, bara testat. Det är annorlunda, jag är nöjd med första resultatet. Även om det påminner om jslink som jag har jobbat mycket med, så är det mycket lättare att sätta igång:
Det är enklare att ändra, även för en icke-utvecklare. Man får en början:
Med hjälp av dokumentation av List Formatting och Office UI Fabric Icons, har jag skapat en enkel formatering som jag är riktigt nöjd med:
Tag: Jslink
Min första kolumnformatering
Jag har precis börjat med kolumnformatering, bara testat. Det är annorlunda, jag är nöjd med första resultatet. Även om det påminner om jslink som jag har jobbat mycket med, så är det mycket lättare att sätta igång:
Det är enklare att ändra, även för en icke-utvecklare. Man får en början:
Med hjälp av dokumentation av List Formatting och Office UI Fabric Icons, har jag skapat en enkel formatering som jag är riktigt nöjd med:
Update Field.JSLink using JSOM or REST
Today I have just a little code snippet to share. This code snippet shows how to update the JSLink property for an existing field using JSOM and REST. For REST I use sharepoint-utilities. [code language=“javascript”] var updateJsLinkCsom = function(config) { var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(config.listTitle) var fields = list.get_fields(); var field = fields.getByInternalNameOrTitle(config.fieldTitle) field.set_jsLink(config.jsLink) field.update() ctx.executeQueryAsync() }; var updateJsLinkRest = function(config) { SP.SOD.registerSod(‘sputils.js’, ‘/sputils.min.js’) SP.SOD.executeFunc(‘sputils.js’, ‘’, function() { var url = _spPageContextInfo.webAbsoluteUrl + ‘/_api/web/lists/getbytitle(\’’ + config.listTitle + ‘\’)/fields/getbyinternalnameortitle(\’’+ config.fieldTitle + ‘\’)’; var payload = {’__metadata’: {’type’: ‘SP.Field’}, ‘JSLink’: config.jsLink}; var config = {‘headers’ : {‘X-HTTP-Method’: ‘MERGE’ }}; sputils.rest.post(url, payload, config); }); }; var config = { listTitle: ‘’, fieldTitle: ‘’, jsLink: ‘~site/’ }; updateJsLinkCsom(config); updateJsLinkRest(config); [/code] A couple of notes, to update a field we need:
Provisioning Google Maps JSLink with SPMeta2
Among PnP Samples there is a solution for using Google Maps. Great solution where where you can pick a point on a map and define a spacial area on the map. Unfortunately it is a sandbox solution. I rewrote it to a code based template with SPMeta2 Framework. Now it can be installed on any site very easily, without needing UserCode Service and a cumbersome process of uploading a wsp package and activating it. The code is very simple, you can see it on github.
Bypass all custom jslink
Client Side Rendering (CSR) and jslink are great for customizing lists and forms in SharePoint. In my current project we use it a lot of it. A disadvantage of that path, although, is that it might occur javascript errors, during the development phase, but also in production. We do, of course, our best to leverage the best jslink code, but unfortunately we have to live with the fact that errors can occur, especially when we use it for NewForm, EditForm, DisplayForm and View (in list and grid). If an error occurs, it won’t stop the rest of javascript (it is wrapped in try and catch by SharePoint), but the fields will still not function as intended. It can also be some “corrupt” or old data in the field value that will “break” the jslink code. I would like to suggest one little fix, an idea I’ve come up to in my jslink-heavy project:
Client Side Rendering with Async dependencies
Yesterday I asked a question on SharePoint StackExchange:
I also asked Elio Struyf on Twitter: https://twitter.com/eliostruyf/status/540473976255152128 Good idea, Elio Struyf! Now I want to try it out.
Preparations
In this case I’ll be using my example from my blog post yesterday: Drag and Drop Image using Client Side Rendering I have created a new list and added a lookup field to my previous list. What I get is a Title of the lookup item, but not my custom field called DragAndDrop. In my test I will try to load the DragAndDrop Image using an ajax call and rendering it after Client Side Rendering is done with my item. To be complete, I want to show some screenshots for my lookup field: It will result in this OOTB rendering:
Drag and Drop Image using Client Side Rendering
I continue my series about Client Side Rendering (CSR) and jsgrid. Today I want to try a custom field where users can drag and drop images. The inspiration comes from:
- AutoUpload field written by Anton Vishnyakov and
- Base64 Drag and drop written by oroboto
What I want to achieve is:
- A custom field that is rendered with jslink
- Users can drag and drop small pictures (thumbnails) into the field
- A base64 image representation is saved as the field value
- Optionally implement pasting images using Clipboard API
Step 1 Create a field with a custom jslink
Create a field of type Note. I am using the PnP Core Extensions to make it quickier: ’ My jslink file is very simple to begin with: [code language=“javascript”] (function () { ‘use strict’; function view(ctx, field) { return “hello”; } var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘DragAndDropImage’: { ‘View’: view, ‘DisplayForm’: view //‘EditForm’: verySimpleNewAndEdit, //‘NewForm’: verySimpleNewAndEdit } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] This will result in the following display form. Just outputting “hello” indicates that my field is jslink are registered correctly:
Disabling a column in Quick Edit
In my project I have a column called Request Status. This column is not shown in any forms, meaning users should not edit, because it is controlled through the app. Nevertheless it is editable in the Quick Edit. Yesterday I wrote about jsgrid in my blog. Now comes more. Today I’ll share a little practical solution how one can disable editing a field in Quick Edit. The field is edited in jsgrid, but to disable it, we only have set the property called AllowGridEditing to false on our column (not even touching the heavy jsgrid api). We can do in the OnPreRender event in our Client Side Rendering (CSR) registration. Having the context object we have access to the Fields (ContextInfo.ListSchema.Field): [code language=“javascript” highlight=“6,9”] (function () { var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.OnPreRender = function(ctx) { var statusField = ctx.ListSchema.Field.filter(function(f) { return f.Name === ‘Request_x0020_Status’; }); if (statusField) { statusField[0].AllowGridEditing = false; } } SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] Another way is to implement the display form: [code language=“javascript”] (function () { var view = function (ctx, field) { if (ctx.inGridMode) { field.AllowGridEditing = false; } return window.RenderFieldValueDefault(ctx); }; var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘Request_x0020_Status’: { ‘View’: view } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code]
JSGrid Basics
JSGrid is the javascript framework in SharePoint used in Quick Edit View (previously Datasheet View). There are a few very good blog posts on this topic (See below in “Sources”). Nevertheless the fact is that jsgrid and working with quick edit from a developer’s perspective is a huge undiscovered area. Articles I have seen are intended for advanced developers. The goal with my post today is to outline the very basics of working with JSGrid. When you know the basics you will be more comfortable to discover and try out more. The example I want to show is a jsgrid code for a “VerySimpleColumn”. The source code can be found on gist.github.com To focus on jsgrid, I assume you have knowledge and some experience of working with jslink, which is related to jsgrid.
Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
Tag: Json
Min första kolumnformatering
Jag har precis börjat med kolumnformatering, bara testat. Det är annorlunda, jag är nöjd med första resultatet. Även om det påminner om jslink som jag har jobbat mycket med, så är det mycket lättare att sätta igång:
Det är enklare att ändra, även för en icke-utvecklare. Man får en början:
Med hjälp av dokumentation av List Formatting och Office UI Fabric Icons, har jag skapat en enkel formatering som jag är riktigt nöjd med:
XMLHttpRequest the hard way
$.ajax is great, it hides much of the complexity. But sometimes we need to work with “raw” javascript :) So let’s look behind the scenes. The XMLHttpRequest (or just XHR) is used to open a connection to a server without a page reload. Internet Explorer calls it ActiveXObject and it differs in IE versions. Wikipedia article gives a good example how to create one constructor for all browsers: [sourcecode language=“javascript”]if (typeof XMLHttpRequest == “undefined”) XMLHttpRequest = function () { try { return new ActiveXObject(“Msxml2.XMLHTTP.6.0”); } catch (e) {} try { return new ActiveXObject(“Msxml2.XMLHTTP.3.0”); } catch (e) {} try { return new ActiveXObject(“Microsoft.XMLHTTP”); } catch (e) {} //Microsoft.XMLHTTP points to Msxml2.XMLHTTP and is redundant throw new Error(“This browser does not support XMLHttpRequest.”); };[/sourcecode] The remainder is more or less the same among the browsers. We open a connection defining the HTTP verb, URI and async mode (true or false): [sourcecode language=“javascript”]var xhr = new XMLHttpRequest(); xhr.open(“GET”, “/_vti_bin/listdata.svc”, true); xhr.onreadystatechange = onStateChange; xhr.send(null);[/sourcecode] Pay attention to onreadystatechange (only lower case letters). If we choose async=false, the UI waits for the response which is not so kind to users, but maybe it is easier to write a program. Well, there is actually no option but to have async=true. To provide the callback for success and error we can write the responding function onreadystatechange. This function will be called every time the state is changed. There are 5 states:
Update list items with listdata.svc
In one of my previous posts I showed how to retrieve data from listdata.svc with jQuery $.getJSON method. Getting data is very simple, listdata.svc provides a powerful restful interface with filtering, expanding and other features. Read the best and short introduction to listdata.svc by Suneet Sharma or a more detailed and technical article about filters, functions and operators by Mike Flasko at Microsoft with short examples here. Now back to listdata.svc in the SharePoint environment. Corey Roth provides a good images and sample results. For REST the “http verbs” are very important: GET, POST, PUT, DELETE.. SharePoint RESTful interface defines these verbs like that:
Push a copy of an object to client
To reduce postbacks and database calls, a copy of the current object(s) can be pushed down to the client in JSON format. Say a webpart renders information about a person, another webpart shows related information which is retrieved dynamically (like web services). Instead of getting the current person from the database in the second webpart again, we can reuse the same person object from the first webpart. To do so we must provide a DataContract for the Person class:
json serializer in Sharepoint
There is a very handy JSON lib for serializing javascript objects. It is hosted on github under douglas crockford. Download json2.js and serialize with JSON.stringify function: EDIT: There is actually this function in core javascript. It exists since javascript 1.7 and ecmascript 5. So you don’t have to add anything to get this functionality:
var t = { name: "dev", city: "new york" };
JSON.stringify(t);
```There are actually built-in goodies for serializing javascript objects in [ASP.NET](http://msdn.microsoft.com/en-us/library/bb310857.aspx): Sys.Serialization.JavaScriptSerializer.serialize
var t = { name: “dev”, city: “new york” }; Sys.Serialization.JavaScriptSerializer.serialize(t);
Tag: Locale
English vs. Non-English
This post is about the default language of a new site in SharePoint Online. There are some pros and cons of using English as the default language for Non-English sites.
In my case I want to know what is better for Swedish users:
- A site with English as default and Swedish as an alternate language (among many other alternate languages)?
- A site with Swedish as default?
Today, when you create a site, English is pre-selected in the form, you have to choose Swedish actively. When you create a team, the underlying SharePoint Site will have English as the default language.
Chuvash localization
Recently I wanted to add Chuvash localization to the jQuery UI datepicker. Unfortunately, my pull request was rejected. The reason is that jQuery UI will be using Globalize framework: The jQuery Globalize framework relies on CLDR, so What is Unicode CLDR (Common Locale Data Repository)?
The Unicode CLDR provides key building blocks for software to support the world’s languages, with the largest and most extensive standard repository of locale data available. This data is used by a wide spectrum of companies for their software internationalization and localization, adapting software to the conventions of different languages for such common software tasks
Tag: Function
Tips and Trick for Azure Functions
These are my favourite tips and tricks. These are only those who me and my colleguages have tried out.
Architecture tips
Keep it slim
Functions should do one thing and they should do it well. When you develop it in C# and Visual Studio, it is so tempting to develop a “microservice” in a good way, you add interfaces, implement good patterns, and all of a sudden you get a monolith packaged in a microservice. If your function grows, stop, rethink. Better to see how it input and output bindings can be used. Also orchestration with Logic Apps or Durable Functions can help.
Tag: Queue
Tips and Trick for Azure Functions
These are my favourite tips and tricks. These are only those who me and my colleguages have tried out.
Architecture tips
Keep it slim
Functions should do one thing and they should do it well. When you develop it in C# and Visual Studio, it is so tempting to develop a “microservice” in a good way, you add interfaces, implement good patterns, and all of a sudden you get a monolith packaged in a microservice. If your function grows, stop, rethink. Better to see how it input and output bindings can be used. Also orchestration with Logic Apps or Durable Functions can help.
Tag: Reactive
Tips and Trick for Azure Functions
These are my favourite tips and tricks. These are only those who me and my colleguages have tried out.
Architecture tips
Keep it slim
Functions should do one thing and they should do it well. When you develop it in C# and Visual Studio, it is so tempting to develop a “microservice” in a good way, you add interfaces, implement good patterns, and all of a sudden you get a monolith packaged in a microservice. If your function grows, stop, rethink. Better to see how it input and output bindings can be used. Also orchestration with Logic Apps or Durable Functions can help.
Tag: Serverless
Tips and Trick for Azure Functions
These are my favourite tips and tricks. These are only those who me and my colleguages have tried out.
Architecture tips
Keep it slim
Functions should do one thing and they should do it well. When you develop it in C# and Visual Studio, it is so tempting to develop a “microservice” in a good way, you add interfaces, implement good patterns, and all of a sudden you get a monolith packaged in a microservice. If your function grows, stop, rethink. Better to see how it input and output bindings can be used. Also orchestration with Logic Apps or Durable Functions can help.
Tag: Cookie
Switch back to Modern UI
Just a little tip. When you switched to a Classic View of Site Contents, you can switch back by removing a cookie called “splnu”.
Tag: Devtools
Switch back to Modern UI
Just a little tip. When you switched to a Classic View of Site Contents, you can switch back by removing a cookie called “splnu”.
Updating hover style in IE8 Developer Tools
In our project we still have to support Internet Explorer 8. The CSS issues in IE8 are most difficult to debug and solve. You can not add a new rule in Developer Tools or toggle the state of an element to hover as in moder web browser dev tools. One solution that I’ve come up to today, is to add a style with javascript or jQuery, open the script pane in IE8 Dev Tools and add this line: [code language=“javascript”] $(’.ms-srch-item:hover {filter:none !important;}’) .appendTo($(‘body’)) [/code] This will fill update the hover effect of the .ms-srch-item directly. That’s it, just a little tip.
TypeScript in SharePoint
By now TypeScript shouldn’t be something one has to introduce.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
If you haven’t already done it, go and see the intro video for TypeScript, check out a tutorial and visit the typescript playground. There are other javascript libraries which extend javascript and are compatible/compile to javascript: Dart and CoffeeScript. To be honest I had never time to try those. The fact that TypeScript is well integrated into Visual Studio which I happen to work within all the days (intellisense, compilation checks and more) did me curious. This post is actually not about TypeScript itself, but a test to use it in SharePoint. In this short “lab” I even had Web Essentials 2012 which automatically compile typescript files into plain javascript files on save. This is what I did: Install TypeScript and Web Essentials 2012 Create a SharePoint-hosted app: Create a new TypeScript file in the autogenerated “Scripts”-module and call it “Greeter.ts” Just save the file as it is. The new file is created: Greeter.js Now we don’t need to copy this file to the app, so remove Greeter.ts from the Elements.xml file (or comment it out): Open the Default.aspx from the Pages module and add the reference to the new javascript file:
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
Enable Save in IE9 mode
Wouldn’t it be nice to use html5 and css3 in SharePoint? No problems, there is actually v5 master out there, created by Kyle Schaefer. Or just use h5ml5 and css3 right away in your webparts and pages. But there is a big problem. It doesn’t work in IE9–. One of the issues (even listed by Kyle) is that “save” doesn’t work in modal dialogs where Rich Text Editor is used. Especialy it is for modal dialogs. The problem is not IE9, neither html5 and css3. After some digging in javascript code which is shipped with SharePoint I found out that the problem is some legacy javascript code which is not supported by IE9 but in IE8– (and compatibility mode). When we set IE9 mode in IE9 Dev Tools (F12) and go to Tasks list and try to create a task, we’ll get an error: It is RTE_GetEditorIFrame from init.js:
Save an excel sheet as a clean table
To save an excel sheet as a html table is very easy. Just select the needed area, then go to Save as and check the selection and choose html as output format. It works fine. It even looks like it did in Excel. But what if you don’t want all this junk, you want only the plain html table (e.g. for pasting into WP). When I saved my permission levels to html, I used this javascript code. First open the html page which Excel has created in Chrome, open the Dev Tools console, load the latest jQuery into the page, and remove all unnecessary attributes and styling, remove the comments, after that you can just copy the outerHTML of the table and paste into a text editor:
Autocomplete för sökruta i Sharepoint
Ett mycket trevligt projekt: Search As You Type på Codeplex. Ladda ner textfilen och lägg till javascript och css från den filen till masterpage. Så enkelt är det. Jag har testat det genom att direkt stoppa in koden i Chrome Console.
Ladda jQuery dynamiskt till din sida
Vill du ändra innehåll, testa olika javascript-funktioner på din sida, prova något direkt i webbläsaren (utan att behöva deploya om), så är DevTools i Chrome, eller Firebug i Firefox väldigt bra verktyg. Om du har jQuery på din sida, så är det ännu bättre. Men om du inte har det, så ladda det i efterhand genom att öppna konsolen (Ctrl-Shift-J i Chrome) och kör följande rader kod (klistra in dem på en gång, och tryck på Enter):
Ctrl-Shift-J is the shit
devtools i google chrome underlättar så enormt. Lägg Ctrl-Shift-J på minnet. För då kommer du direkt till konsolen i devtools och kan testa.
Om man till exempel bara vill omdefiniera en funktion så kan man göra det direkt i webbläsarens addressruta: Inled det med javascript:function till exempel: javascript:function shout_out(greeting) {alert(greeting);};
Felsök på clientsidan med Chrome DevTools
Här är en väldigt bra video som berättar om nya devtools i Google Chrome 10. Den visar 12 tricks hur man kan underlätta felsökning av html, css och javascript. Att kunna ändra html,css och js on-the-fly är faktiskt häftigt. För mig som länge har använt Firebug i Firefox (som nu inte funkar på FF4 RC) känns devtools väldigt bra. [youtube http://www.youtube.com/watch?v=nOEw9iiopwI&w=530&h=335]
Comments from Wordpress.com
Ändra utseendet på sidan direkt i webbläsaren « Sharepoint. Kunskap. Upptäckter på resan. - Mar 1, 2011
Tag: Cdn
Just because I can should I use Private Office 365 CDN
This is about a topic brought up by Waldek Mastykarz: Just because you can should you use the Office 365 CDN. In my post I want to take a closer look at the private CDN option in Office 365. Please note, the whole thing is subject to change, and it reflects the circumstances at the time of writing - 2019-08-26.
I’ll skip the introduction of Office 365, let’s jump directly to the Private CDN option. Consider following scenarios.
The CDN concept in SharePoint
How many instances of jquery are there in your SharePoint farm? [sourcecode language=“powershell”] Get-SPWebApplication http://dev ` | Select -Expand Sites ` | Select -Expand AllWebs ` | Select -Expand Lists ` | Select -Expand Items ` | ? { $_.Url -match “jquery.*.js” } ` | select Name, Url [/sourcecode] Have you more than two (jquery and jquery-ui), then you have too much. You can save much place and performance by using Content Delivery Network (CDN) links for the resources like javascript, css, fonts and icons. Consider those Content Delivery Networks:
Tag: Publishing
Just because I can should I use Private Office 365 CDN
This is about a topic brought up by Waldek Mastykarz: Just because you can should you use the Office 365 CDN. In my post I want to take a closer look at the private CDN option in Office 365. Please note, the whole thing is subject to change, and it reflects the circumstances at the time of writing - 2019-08-26.
I’ll skip the introduction of Office 365, let’s jump directly to the Private CDN option. Consider following scenarios.
javascript: Remove illegal characters in url
Recently I needed to create valid urls for pages using javascript. Also this time I thought it must be some out-of-the-box code for that in SharePoint. The first thing I came up was the “Add page” dialog. I found that the actual dialog was in the _layouts virtual folder:
/\_layouts/15/CreatePublishingPageDialog.aspx
```Bingo, it does the validation in the client side. This is the responsible javascript function that resides directly in the page: \[sourcecode language="javascript"\] function UpdateUrl() { LoadTermContextInfo(); var hiddenPageUrlLabelExtensionClientId = "<%=hiddenPageUrlLabelExtension.ClientID%>"; var hiddenPageUrlLabelExtension = document.getElementById(hiddenPageUrlLabelExtensionClientId); var pageNamePreviewUrlLabelClientId = "<%=pageNamePreviewUrlLabel.ClientID%>"; var pageNamePreviewUrlLabel = document.getElementById(pageNamePreviewUrlLabelClientId); if( pageNamePreviewUrlLabel != null ) { var nameInputTextBoxClientId = "<%=nameInput.ClientID%>"; var nameInputTextBox = document.getElementById(nameInputTextBoxClientId); var allowSpaces = false; if( GetInnerText(hiddenPageUrlLabelExtension) != "" ) { var suggestUrlValue = ""; for (var i=0; i < nameInputTextBox.value.length; i++) { var currentChar = nameInputTextBox.value.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } UpdatePreviewUrl( suggestUrlValue ); } else { if( g\_timerId != 0 ) { window.clearTimeout(g\_timerId); } g\_timerId = window.setTimeout(OnFriendlyUrlNameChanged, 500); } } } \[/sourcecode\] This function iterates through all the characters in the page url and removes the illegal characters. The space, plus sign and the dot become a hyphen. To determine if a character is illegal, it relies on another javascript function called: `IndexOfIllegalCharInUrlLeafName`. This function can be found in the init.js or init.debug.js: \[sourcecode language="javascript"\] function IndexOfIllegalCharInUrlLeafName(strLeafName) { for (var i = 0; i < strLeafName.length; i++) { var ch = strLeafName.charCodeAt(i); if (strLeafName.charAt(i) == '.' && (i == 0 || i == strLeafName.length - 1)) return i; if (ch < 160 && (strLeafName.charAt(i) == '/' || !LegalUrlChars\[ch\])) return i; } return -1; } \[/sourcecode\] This function checks a char against an array of all characters: `LegalUrlChars` from the same file: init.js. [![ill_002](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png)](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png) To use this UpdateUrl function, we have to remove the references to the fields from the Add Page Dialog. Of course, we won't overwrite this original function, we don't want to break the SharePoint OOB functionality. Here is how my new function looks like: \[sourcecode language="javascript"\] var takana = {}; function takana.updateUrl(url) { var allowSpaces = false; if( url ) { var suggestUrlValue = ""; var length = url.length; for (var i=0; i < length; i++) { var currentChar = url.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } } } \[/sourcecode\]
#### Server Side
For those of you who want run this operation on the server, here is the code written in C#: \[sourcecode language="csharp"\] //" # % & \* : < > ? \\ / { } ~ | var illegalChars = @"\[""#%&\\\*:\\<\\>\\?\\\\\\/\\{\\}~\\|\]"; pageName = Regex.Replace(pageName, illegalChars, string.Empty); var punctuation = @"\[\\s\\.;\\+\]"; pageName = Regex.Replace(pageName, punctuation, "-"); //remove "--" pageName = Regex.Replace(pageName, @"\\-{2,}", "-"); pageName = string.Format("{0}.aspx", pageName); //do it like the built-in dialog, lower case pageName = pageName.ToLower(); \[/sourcecode\] Don't forget to leave a comment if you find this post useful.
## Comments from Wordpress.com
####
[Johannes Milling](http://discoveringsharepoint.wordpress.com "johannesmilling@hotmail.com") - <time datetime="2013-08-23 09:53:30">Aug 5, 2013</time>
Good post! :)
<hr />
$ in cmssitemanager.js conflicts with $ in jQuery
In SharePoint 2010 if CMSSiteManager.js library is loaded besides jQuery, then much of stuff stops working. The reason is that the dollar sign ($) is used in cmssitemanager.js as well which conflicts with jQuery. Mostly it appears on pages where you load jQuery and have an image library with thumbnails. To avoid this, just replace all $ with jQuery in your custom scripts. A more crazy situation is when avoiding $ isn’t enough. It is when you load jQuery to page head automatically on all pages. The Asset picker (AssetPortalBrowser.aspx) invokes $ itself and gets with jQuery in conflict without you write a single line of custom javascript code. You usually get the following error:
Add content to a provisioned publishing page
We can use PublishingPageContent Property to write content to a page:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="Pages" Url="$Resources:cmscore,List\_Pages\_UrlName;" >
<File Path="Pages\\Help.aspx" Url="Help.aspx" Type="GhostableInLibrary">
<Property Name="Title" Value="Contoso Help Page" />
<Property Name="PublishingPageLayout" Value="~SiteCollection/\_catalogs/masterpage/ContosoPageLayout.aspx, Text page" />
<Property Name="ContentType" Value="$Resources:cmscore,contenttype\_welcomepage\_name;" />
<Property Name="PublishingPageContent" Value="hello world"/>
</File>
</Module>
</Elements>
Tag: Azure-Pipelines.yml
Simple Build for dotnet new react
I created a sample ASP.NET Core app with React.
dotnet new react
Then it took a couple of hours to get the build to work. Here is my working azure-pipelines.yml:
Resources:
Tag: Cd
Simple Build for dotnet new react
I created a sample ASP.NET Core app with React.
dotnet new react
Then it took a couple of hours to get the build to work. Here is my working azure-pipelines.yml:
Resources:
Tag: Dotnet
Simple Build for dotnet new react
I created a sample ASP.NET Core app with React.
dotnet new react
Then it took a couple of hours to get the build to work. Here is my working azure-pipelines.yml:
Resources:
Tag: Prompt
My PowerShell Profile
It has been a while I last worked with PowerShell. I had my custom profile where I had my own prompt and some other customizations. Now I cannot find it anymore. I’ll start with the new one and I am saving it on my blog, so it will be easier to find in future: [code language=“powershell”] Function Prompt { $PromptData=“PS $($executionContext.SessionState.Path.CurrentLocation)$(’>’ * ($nestedPromptLevel + 1)) " $host.ui.RawUI.WindowTitle=$PromptData +’-’+(Get-Date).tostring() # .Link# http://go.microsoft.com/fwlink/?LinkID=225750 # .ExternalHelp System.Management.Automation.dll-help.xml } [/code] The prompt function comes from the scripting guy blog. To customize your profile, just open it in a text editor (in my case: code) [code language=“powershell”] code $profile [/code] Update 2018-04-10 You can also include these lines: [code language=“powershell”] $path1 = “C:\Program Files\Common Files\microsoft shared\Web Server Extensions\” $path2 = “15” Add-Type -Path “$path1\$path2\ISAPI\Microsoft.SharePoint.Client.dll” Add-Type -Path “$path1\$path2\ISAPI\Microsoft.SharePoint.Client.Runtime.dll” [/code] VS Code Now we can run VS Code to create ps1 scripts and run selections as we did it in PowerShell ISE.
Tag: Csr
Update Field.JSLink using JSOM or REST
Today I have just a little code snippet to share. This code snippet shows how to update the JSLink property for an existing field using JSOM and REST. For REST I use sharepoint-utilities. [code language=“javascript”] var updateJsLinkCsom = function(config) { var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(config.listTitle) var fields = list.get_fields(); var field = fields.getByInternalNameOrTitle(config.fieldTitle) field.set_jsLink(config.jsLink) field.update() ctx.executeQueryAsync() }; var updateJsLinkRest = function(config) { SP.SOD.registerSod(‘sputils.js’, ‘/sputils.min.js’) SP.SOD.executeFunc(‘sputils.js’, ‘’, function() { var url = _spPageContextInfo.webAbsoluteUrl + ‘/_api/web/lists/getbytitle(\’’ + config.listTitle + ‘\’)/fields/getbyinternalnameortitle(\’’+ config.fieldTitle + ‘\’)’; var payload = {’__metadata’: {’type’: ‘SP.Field’}, ‘JSLink’: config.jsLink}; var config = {‘headers’ : {‘X-HTTP-Method’: ‘MERGE’ }}; sputils.rest.post(url, payload, config); }); }; var config = { listTitle: ‘’, fieldTitle: ‘’, jsLink: ‘~site/’ }; updateJsLinkCsom(config); updateJsLinkRest(config); [/code] A couple of notes, to update a field we need:
Minimal Display Template
We want to use our own Display Templates on Non-publishing sites - our team sites. Without the Publishing Feature activated you have to create an own javascript file. Here is short and concise instructions how to install it: Display Templates on Non-publishing Sites. As described on that blog, you can make copy of an existing Item_Default.js and adjust to your needs. I also asked Elio Struyf and I got the same tip. I did create my starter template. Here I want to share this very minimal javascript based Display Template. The real Minimal Display Template is in the SPCSR github repository: Item_Minimal.js It has been improved by Elio Stuyf himself :) [code language=“javascript”] (function () { // Config contains variables that are defined in one place var config = { propertyMappings: { ‘Path’:null, ‘Title’:[‘Title’] } }; var templateUrl; var register = function () { if (“undefined” !== typeof (Srch) && “undefined” !== typeof (Srch.U) && typeof (Srch.U.registerRenderTemplateByName) === “function”) { Srch.U.registerRenderTemplateByName(templateUrl, render); } }; render = function (ctx) { // Display template data var cachePreviousTemplateData = ctx.DisplayTemplateData; ctx.DisplayTemplateData = { ‘TemplateUrl’: templateUrl, ‘TemplateType’: ‘Item’, ‘TargetControlType’: [‘SearchResults’, ‘Content Web Parts’], ‘ManagedPropertyMapping’: config.propertyMappings }; var cachePreviousItemValuesFunction = ctx.ItemValues; ctx.ItemValues = function(slotOrPropName) { return Srch.ValueInfo.getCachedCtxItemValue(ctx, slotOrPropName); }; // Retrieve managed property data var path = $getItemValue(ctx, ‘Path’); var title = $getItemValue(ctx, ‘Title’); // HTML markup for an item var htmlMarkup = String.format( ‘’ + ‘{1}’ + ‘’, path, title); // Caching ctx.ItemValues = cachePreviousItemValuesFunction; ctx.DisplayTemplateData = cachePreviousTemplateData; // Return the HTML markup return htmlMarkup; }; // Retrieve all the loaded scripts var allScripts = document.getElementsByTagName(“script”); // Get the last script file (this is the current DT file) var scriptUrl = allScripts[allScripts.length - 1].src; if (scriptUrl.indexOf(’/_catalogs/’) > 0) { // Remove the query string if (scriptUrl.indexOf(’?’) > 0) { scriptUrl = scriptUrl.split("?")[0]; } // Insert the site collection token templateUrl = ‘~sitecollection’ + scriptUrl.substr(scriptUrl.indexOf(’/_catalogs/’)) // Register the template to load register(); if (typeof (RegisterModuleInit) === “function” && typeof(Srch.U.replaceUrlTokens) === “function”) { RegisterModuleInit(Srch.U.replaceUrlTokens(templateUrl), register); } } })(); [/code]
Bypass all custom jslink
Client Side Rendering (CSR) and jslink are great for customizing lists and forms in SharePoint. In my current project we use it a lot of it. A disadvantage of that path, although, is that it might occur javascript errors, during the development phase, but also in production. We do, of course, our best to leverage the best jslink code, but unfortunately we have to live with the fact that errors can occur, especially when we use it for NewForm, EditForm, DisplayForm and View (in list and grid). If an error occurs, it won’t stop the rest of javascript (it is wrapped in try and catch by SharePoint), but the fields will still not function as intended. It can also be some “corrupt” or old data in the field value that will “break” the jslink code. I would like to suggest one little fix, an idea I’ve come up to in my jslink-heavy project:
Client Side Rendering with Async dependencies
Yesterday I asked a question on SharePoint StackExchange:
I also asked Elio Struyf on Twitter: https://twitter.com/eliostruyf/status/540473976255152128 Good idea, Elio Struyf! Now I want to try it out.
Preparations
In this case I’ll be using my example from my blog post yesterday: Drag and Drop Image using Client Side Rendering I have created a new list and added a lookup field to my previous list. What I get is a Title of the lookup item, but not my custom field called DragAndDrop. In my test I will try to load the DragAndDrop Image using an ajax call and rendering it after Client Side Rendering is done with my item. To be complete, I want to show some screenshots for my lookup field: It will result in this OOTB rendering:
Drag and Drop Image using Client Side Rendering
I continue my series about Client Side Rendering (CSR) and jsgrid. Today I want to try a custom field where users can drag and drop images. The inspiration comes from:
- AutoUpload field written by Anton Vishnyakov and
- Base64 Drag and drop written by oroboto
What I want to achieve is:
- A custom field that is rendered with jslink
- Users can drag and drop small pictures (thumbnails) into the field
- A base64 image representation is saved as the field value
- Optionally implement pasting images using Clipboard API
Step 1 Create a field with a custom jslink
Create a field of type Note. I am using the PnP Core Extensions to make it quickier: ’ My jslink file is very simple to begin with: [code language=“javascript”] (function () { ‘use strict’; function view(ctx, field) { return “hello”; } var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘DragAndDropImage’: { ‘View’: view, ‘DisplayForm’: view //‘EditForm’: verySimpleNewAndEdit, //‘NewForm’: verySimpleNewAndEdit } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] This will result in the following display form. Just outputting “hello” indicates that my field is jslink are registered correctly:
Disabling a column in Quick Edit
In my project I have a column called Request Status. This column is not shown in any forms, meaning users should not edit, because it is controlled through the app. Nevertheless it is editable in the Quick Edit. Yesterday I wrote about jsgrid in my blog. Now comes more. Today I’ll share a little practical solution how one can disable editing a field in Quick Edit. The field is edited in jsgrid, but to disable it, we only have set the property called AllowGridEditing to false on our column (not even touching the heavy jsgrid api). We can do in the OnPreRender event in our Client Side Rendering (CSR) registration. Having the context object we have access to the Fields (ContextInfo.ListSchema.Field): [code language=“javascript” highlight=“6,9”] (function () { var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.OnPreRender = function(ctx) { var statusField = ctx.ListSchema.Field.filter(function(f) { return f.Name === ‘Request_x0020_Status’; }); if (statusField) { statusField[0].AllowGridEditing = false; } } SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] Another way is to implement the display form: [code language=“javascript”] (function () { var view = function (ctx, field) { if (ctx.inGridMode) { field.AllowGridEditing = false; } return window.RenderFieldValueDefault(ctx); }; var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘Request_x0020_Status’: { ‘View’: view } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code]
Tag: Jsom
Trigger SP2010 Workflows using JSOM
Today I found out how to start workflows in JSOM (JavaScript Object Model in SharePoint). Nothing special, but since it is not documented, it took me a while to find a solution. Here is the code which I want to keep as simple as possible. What you need to start a SP2010 Workflow for a list item or a document in JSOM, you need to load SP.WorkflowServices.js and you need to create the manager and get the service, then you can trigger a workflow using the workflow name, the list guid and the guid of the list item: [code language=“javascript”] var ctx = SP.ClientContext.get_current(); var workflowServicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web()); var service = workflowServicesManager.getWorkflowInteropService(); service.startWorkflow(workflowName, null, listGuid, plainItem.guid, initiationParams); [/code] Here is the code to trigger a workflow for multiple items: [code language=“javascript”] //fire the workflows function fire2010WorkflowForListItems(ctx, listGuid, plainItems) { var workflowServicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web()); var service = workflowServicesManager.getWorkflowInteropService(); for(var i = 0; i < plainItems.length; i++) { var plainItem = plainItems[i]; console.log(‘scheduling workflow for id: ‘, plainItem.id); service.startWorkflow(options.workflowName, null, listGuid, plainItem.guid, options.initiationParams); } console.log(’now executing…’); ctx.executeQueryAsync(function() { console.info(‘yes, workflows completed for ’ + items.length + ’ items’); }, function() { console.error(‘it didnt go well’); }); } [/code] The code above is inspired from this gist and sharepoint stackexchange. It is a simplified version that only works for list item workflows and SharePoint 2010 workflows. Here is an example how you can get multiple items and batch start a workflow: [code language=“javascript”] //just a couple of variables var options = { workflowName: ‘Behörigheter’, listName: ‘Documents’, initiationParams: {} }; //load list items function startWorfklows() { //Start 2010 Workflow for a List Item var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(options.listName); ctx.load(list); var items = list.getItems(new SP.CamlQuery()); ctx.load(items); ctx.executeQueryAsync(function() { var listGuid = list.get_id() + ‘’; var en = items.getEnumerator(); var plainItems = []; while (en.moveNext()) { var it = en.get_current(); //do not take checked out files, it won’t work if (!it.get_item(‘CheckoutUser’)) { plainItems.push({id: it.get_id(), guid: it.get_item(‘GUID’) + ’’ }); } } fire2010WorkflowForListItems(ctx, listGuid, plainItems); }, function() { alert(‘boom’); }); } //Load Worfklow Js dependency var wfScript = ‘SP.WorkflowServices.js’ SP.SOD.registerSod(wfScript, _spPageContextInfo.webAbsoluteUrl + ‘/_layouts/15/SP.WorkflowServices.js’); SP.SOD.executeFunc(wfScript, ‘’, startWorfklows); [/code]
JSOM: Alter a column's DisplayName
Here is another article in my JSOM series. For one month ago I showed how to alter a column’s ShowInDisplayForm property with JSOM. This time I’ll show a code sample for changing a column’s (field’s) display name. If you want to alter the displayname with Server Object Model, grab the code in the sharepoint.stackexchange.com: Change Field’s DisplayName in a List. [sourcecode language=“javascript”]var ctx = SP.ClientContext.get_current(), //SP.ClientContext field = ctx.get_web() //SP.Web .get_lists() //SP.ListCollection .getByTitle(‘MyList’) //SP.List .get_fields() //SP.FieldCollection .getByInternalNameOrTitle(“Body”); //SP.Field ctx.load(field, “Title”); //load only Title ctx.executeQueryAsync(function() { field.set_title(“Beskrivning”); field.update(); ctx.executeQueryAsync(); });[/sourcecode]
Delete all list items with jsom
Today I needed to “clean” a list, meaning to remove all list items. For some time ago I wrote a post about different ways of removing list items in bulk: Server Object Model, SPLinq and RPC. This time I had only the web browser. So I tried the jsom way. By the way, the javascript documentation for jsom on msdn is getting really good. Don’t miss that: How to: Complete basic operations using JavaScript library code in SharePoint 2013. Now here comes theworking code I used to remove all items in my list:
GeoLocation Field in SharePoint 2013
In SharePoint 2013 Preview there is a new type of field: GeoLocation which is, like the old SPUrlField, a pair of values. The geolocation is described as longitude and latitude. Unfortunately you can’t add this field in list settings. You have to create this in code. In the provided link you can find the code C# code which uses the Client Object Model. In another link you can find an example how to create the geolocation file using Server Object Model (in FeatureActivated EventReceiver). If you know me, you might already know that I will propose a JavaScript solution. Here is the code to create a geolocation field in an existing list using JSOM:
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
JSOM: Alter a column's ShowInDisplayForm property
When you create a content type, you can define if your fields will be shown in DisplayForm, EditForm, NewForm. You can hide or show them, just as Yaroslav Pentsarsky says. If your list is already provisioned, you can change them with Server Object Model, why not in PowerShell: Technet: Setting ShowInDisplayForm, ShowInEditForm, ShowInNewForm properties with powershell. If you don’t have access to the server, then the same can be done with JSOM. Here is the code:
JSOM: Last Modified Date of a List
The data transfer between server and client can heavily affect the performance. One of the measures to reduce the amount data transferred from the server to the client is storing data on the client. In many modern browsers we can use html5 localStorage. Even in older browsers there are ways to store data. I would recommend a nice js lib called amplify.js. The interface is much easier, then:
amplify.store("key", { title: "value" });
```It comes in nicely, if we have much data which we get with JSOM. But we have to care about eventual changes to list items done after we got them the last time. So we have to store the [last modified date](http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.lastitemmodifieddate.aspx). This property is also available in JSOM:
var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(“Tasks”); ctx.load(list, “LastItemModifiedDate”); ctx.executeQueryAsync( function() { var lastmodified = list.get_lastItemModifiedDate(); }, function() {} );
$().SPServices is best for SOAP
SPServices is a great tool, really nice work, Marc Anderson (@sympmarc). It has been there all the time I have developed for SharePoint. But the fact that you work with XML and you must parse the attributes (!) was the reason why I prefered listdata.svc and Client Object Model, where you get objects in JSON or you have a nice API to get objects and their properties. But there is an area where SPServices are really the best tool: SharePoint Web Services which only understand SOAP like SocialDataService.asmx.
Tag: Sharepoint 2013
Trigger SP2010 Workflows using JSOM
Today I found out how to start workflows in JSOM (JavaScript Object Model in SharePoint). Nothing special, but since it is not documented, it took me a while to find a solution. Here is the code which I want to keep as simple as possible. What you need to start a SP2010 Workflow for a list item or a document in JSOM, you need to load SP.WorkflowServices.js and you need to create the manager and get the service, then you can trigger a workflow using the workflow name, the list guid and the guid of the list item: [code language=“javascript”] var ctx = SP.ClientContext.get_current(); var workflowServicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web()); var service = workflowServicesManager.getWorkflowInteropService(); service.startWorkflow(workflowName, null, listGuid, plainItem.guid, initiationParams); [/code] Here is the code to trigger a workflow for multiple items: [code language=“javascript”] //fire the workflows function fire2010WorkflowForListItems(ctx, listGuid, plainItems) { var workflowServicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web()); var service = workflowServicesManager.getWorkflowInteropService(); for(var i = 0; i < plainItems.length; i++) { var plainItem = plainItems[i]; console.log(‘scheduling workflow for id: ‘, plainItem.id); service.startWorkflow(options.workflowName, null, listGuid, plainItem.guid, options.initiationParams); } console.log(’now executing…’); ctx.executeQueryAsync(function() { console.info(‘yes, workflows completed for ’ + items.length + ’ items’); }, function() { console.error(‘it didnt go well’); }); } [/code] The code above is inspired from this gist and sharepoint stackexchange. It is a simplified version that only works for list item workflows and SharePoint 2010 workflows. Here is an example how you can get multiple items and batch start a workflow: [code language=“javascript”] //just a couple of variables var options = { workflowName: ‘Behörigheter’, listName: ‘Documents’, initiationParams: {} }; //load list items function startWorfklows() { //Start 2010 Workflow for a List Item var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(options.listName); ctx.load(list); var items = list.getItems(new SP.CamlQuery()); ctx.load(items); ctx.executeQueryAsync(function() { var listGuid = list.get_id() + ‘’; var en = items.getEnumerator(); var plainItems = []; while (en.moveNext()) { var it = en.get_current(); //do not take checked out files, it won’t work if (!it.get_item(‘CheckoutUser’)) { plainItems.push({id: it.get_id(), guid: it.get_item(‘GUID’) + ’’ }); } } fire2010WorkflowForListItems(ctx, listGuid, plainItems); }, function() { alert(‘boom’); }); } //Load Worfklow Js dependency var wfScript = ‘SP.WorkflowServices.js’ SP.SOD.registerSod(wfScript, _spPageContextInfo.webAbsoluteUrl + ‘/_layouts/15/SP.WorkflowServices.js’); SP.SOD.executeFunc(wfScript, ‘’, startWorfklows); [/code]
Minimal Download Strategy. Simple
There are many correct ways (1, 2, 3, 4, 5…) of making scripts work with the Minimal Download Strategy Feature (MDS) in SharePoint 2013 and 2016. But to be honest - every time I need it, I get confused. So now it is time to find a simple solution for that. Who is better at it than the developers of the SharePoint themselves? Look at the MDS code in the built-in Display Templates: Let’s keep it as simple as Item_Default.js, let’s take it as it is and create our own scripts. Here is a skeletton of and MDS-ready script: [code language=“javascript”] function runMyCode() { var time = new Date().toISOString(); console.log(‘runMyCode’, time ); } runMyCode(); if (typeof(RegisterModuleInit) == ‘function’) { var scriptUrl = ‘/Style Library/runMyCode.js’; RegisterModuleInit(scriptUrl, runMyCode); } [/code] Which boils down to this in pseudocode:
A tiny tool for User Custom Actions
Everybody loves User Custom Actions in SharePoint. That’s the only recommended way of customizing SharePoint. You have heard about it. Unfortunately there is no convinient way of administering them. People have their console applications or powershell scripts to add, update and delete user custom actions. It works but it is hard to open up Visual Studio or PowerShell every time you will try out an idea on a test site. To overcome this, I have created a tiny little tool, packaged as a bookmarklet for your browser. When you click on it, it will show your existing user custom actions and you can add new user custom actions. It is an ongoing little project, available on github, contributions are welcome. What’s left is:
Export any web part from a SharePoint page
The blog post below describes the technical details about how Web Parts can be exported using a hidden tool in OOB SharePoint, though this requires manual assembling of a special url. If you are just interested in a solution for an easy Web Part Export function, just proceed directly to my new blog post where you can download my tool that you can add to your web browser.
Export SharePoint List Data To Xml through PowerShell
Today my colleague Johannes Milling wrote an awesome post: Export SharePoint List Data To XML Directly from the GUI He uses the old and forgotten RPC-based web service owssvr.dll (that has existed since SharePoint 2003). This url pattern is used to get the xml-formatted list data for a specific ListView: [source] http://<site_url>/_vti_bin/owssvr.dll?Cmd=Display&List=&View=&Query=*&XMLDATA=TRUE [/source] To automate this I have written a PowerShell function. All the details are in the comments: [source language=“PowerShell”] function Export-OIPSPListDataAsXml { <# .Synopsis Exports list items as xml .DESCRIPTION This function uses a built-in hidden service owssvr.dll in SharePoint .PARAMETER Web SPWeb or a url for the SPWeb object where the list resides .PARAMETER ListName List Name (List Title) .PARAMETER ViewName Name of the List View to export the data .EXAMPLE Export-OIPSPListView -Web http://myawesomesite -ListName “Teddy Bears” -ViewName “All Items” .EXAMPLE Export-OIPSPListView -Web $webInstance -ListName “Top Links” -ViewName “All Items” .Notes Name: Export-OIPSPListDataAsXml Author: Anatoly Mironov Last Edit: 2014-09-11 Keywords: SPList, SPWeb, SPListView, Xml .Link http://chuvash.eu #> [CmdLetBinding()] param( [Parameter(Mandatory=$true)] [Microsoft.SharePoint.PowerShell.SPWebPipeBind]$Web, [Parameter(Mandatory=$true)] [string]$ListName, [Parameter(Mandatory=$true)] [string]$ViewName) $spWeb = $Web.Read() $list = $spWeb.Lists[$ListName] if (!$list) { throw “List $ListName on web $($spWeb.Url) could not be found” } $view = $list.Views[$ViewName] if (!$view) { throw “View $ViewName on web $ListName could not be found” } $url = “{0}/_vti_bin/owssvr.dll?Cmd=Display&List={1}&View={2}&Query=*&XMLDATA=TRUE” ` -f $spWeb.Url, $list.ID, $view.ID $wc = New-Object Net.WebClient $wc.UseDefaultCredentials = $true $wc.DownloadString($url) } [/source]
Improving the web performance of an intranet
[caption id=“attachment_3437” align=“alignnone” width=“480”] All the “small” app parts, web parts, delegate controls, user controls, and other “packages” that “must” be delivered to the users on every page load of the Start Page of your Intranet.[/caption] Recently we made an investment to improve the performance of our intranet. We made many changes in different layers: SQL, Network, Browser upgrade and code. Here I want to tell about what code changes we did to improve the web browser performance. Please leave feedback if you find it useful. You can also share your suggestions. We measured the performance before our code changes and after them. We had amazing results. Unfortunately I can not share any numbers, but we improved the Time to First Byte, time to load event firing in the browser, memory consumption in the clients and, perhaps, the most important, we improved the perceived performance of the Intranet, the way how users experience the speed and UI responsiveness. To do this I got many ideas of my project colleagues and branch colleagues. Here is the list of changes we’ve implemented:
Showing Birthdays and Job Anniversaries in the Newsfeed
In our project we have a requirement to show birthdays and job anniversaries in the Newsfeed. The solution is simple (when you know it) but there has not been any information about it online, until today. I want to share a few lines of PowerShell code to enable Anniversary notifications in the Newsfeed. This desired piece of code was written by my colleague Emma Degerman. Enjoy:
[source language=“PowerShell”] $job = Get-SPTimerJob | ? { $_.TypeName -like “*.UserProfileChangeJob” } $job.GenerateAnniversaries = $true $job.Schedule = [Microsoft.SharePoint.SPSchedule]::FromString(“hourly between 55 and 55”) $job.Update() [/source]
Debugging "What's happening" in Communities
Recently an issue was reported about count mismatches in SharePoint 2013 Communities. The number of replies in category tiles sometimes is different compared to the community stats in the web part called “What’s happening”. The actual number of replies is 1 in the figure below. The user who has reported has tried to add, update and delete discussions and replies. I have invested some time debugging this issue. It would be pity to not share my findings. Well the first thing to do was to determine the type name for the “What’s happening” web part. To do so just edit the page and export the web part. In the exported .webpart file I saw that the type was Microsoft.SharePoint.Portal.WebControls.DashboardWebPart. With that knowledge it is time to open ILSpy, an awesome and free(!) assembly browser and decompiler. Load the “Microsoft.SharePoint.Portal” assembly from GAC into ILSpy. Then use F3 to search for DashboardWebPart: The number of replies is retrieved from SPWeb.AllProperties: If the Property Bag does not contain it, it gets the number of replies from the list. The formula is as follows: [code language=“csharp”] list.ItemCount - list.RootFolder.ItemCount [/code] It means that it gets the number of both discussions and replies: ItemCount of Discusssions List. The number of Discussions is determined by the ItemCount in the RootFolder of the Discussions List. Discussions are List Items in the RootFolder (num2 in the figure below). Replies are saved in the subfolders, every discussion gets an own folder. The number of all replies are num3 in the figure below. After checking the web properties I could see that the number of replies there were wrong: 2. The next step was to determine where and when the Web Properties are updated. The first guess every SharePoint Developer has in such cases is an EventReceiver. Here are all EventReceivers connected to the Discussions List: [code language=“powershell”] $list.EventReceivers | select class, Type, Synchronization | Out-GridView [/code] Allright, CommunityEventReceiver then: Found where the actual update happens: CommunityUtils.UpdateWebIndexedPropertyBag The method is used in DiscussionListCommunityEventHandler.HandleEvent There is a flag, flag5 that is used to determine if the Web Properties should be updated: But the flag5 is not true on Delete operations in some code flows: That’s it. So deleting a reply will not have any effect on “What’s happening”. But adding a new discussion will also update the stats: To summarize the debug session, there is an issue in the OOB code that misses to update community stats when deleting a discussion or a reply. Adding a new discussion, or a reply will synchronize the stats.
Tip: Use the weakest CSS selectors
I am reading Mobile HTML5 written by Estelle Weyle. It is an awesome recap and new knowledge about html, css and javascript. I want to highlight one of tips I got: Use the weakest CSS selectors (can be found on page 204). We all know, that inline CSS and !important are evil. They have a higher level of specifity and override the standard cascade of the CSS rules. If you use !important, then it will be hard to override CSS rules when you really need it. After these two classic “evils” the evil number three is overqualifying of CSS selectors. You should really never add more classes or ids or elements than needed. Consider this: [code language=“css”] .warning { background-color: red; } [/code] It is often enough, you don’t need those: [code language=“css”] html .warning div .warning div.warning, div > .warning body p#myP.blue strong.warning [/code]
Using CAML with SharePoint REST API
Do you prefer REST over CSOM as I do? I’ll skip the whys. Andrew Connell put it already in wrtiting so nicely. Well, if you do prefer REST, then you must have discovered some shortcomings of REST, or its incompleteness compared to CSOM. I think of:
- Inability to filter items based on multivalued taxonomy fields
- Inability to filter items based on user fields where user is added through a group, rather than directly, e.g. AssignedTo=[Me] combined with a SharePoint group.
- …
In such situations I was forced to use CSOM. Until yesterday. Yesterday I learned that we can actually use CAML queries in REST requests. This enables using REST in all situations. The REST API is still developed and many features are added. Maybe a particular operation that needs a CAML query today, can be supported in the core REST API and can be easily refactored then. But until then, we can use CAML queries in REST requests. Here are the important things about it:
What about the SharePoint app domain?
This is an open question about the domains for SharePoint apps. On Technet: Configure an environment for apps for SharePoint (SharePoint 2013) we can read the following:
You must configure a new name in Domain Name Services (DNS) to host the apps. To help improve security, the domain name should not be a subdomain of the domain that hosts the SharePoint sites. For example, if the SharePoint sites are at Contoso.com, consider ContosoApps.com instead of App.Contoso.com as the domain name.
First look at Yammer integration in SharePoint 2013 SP1
I have installed SharePoint SP1 on my development machine. Yammer and OneDrive links have appeared in the Central Administration: If you go ahead and click “Configure Yammer”, you can activate it: Because:
Yammer is Microsoft’s recommended tool for social collaboration.
When you activate Yammer, you’ll get this dialog, and the Yammer link in the SuiteBar: What happens when you click on Yammer, is that you are redirected to Yammer.com and you are prompted a login page. Then you have a usual yammer site with all your networks and stuff (in my case, SPC14 network): Then, if you go to your newsfeed, the following message is shown:
The sessions I attended
My colleagues and friends keep asking me what sessions I went to and what I would recommend to see on channel9 where all of them are publicly available. Here is my prioritized list of sessions:
- #spc325 Real-world examples of FTC to CAM transformations. This was the most exciting developer session. Vesa Juvonen takes the Cloud App Model to its maximum. Wanna know more about the future. See this session.
- #spc404 Build your own REST service with WebAPI 2. You know REST? You like $filter, $top and $select? Good, why not create an own api? You have all the tools in Visual Studio 2013. Just get inspired by Scott Hillier.
- #spc269 Developer audience keynote | What’s new for the Office & SharePoint developer. Get all the developer news presented at #spc14.
- #spc3999 SharePoint Power Hour - New developer APIs and features for Apps for SharePoint.
- #spc371 Developing socially connected apps with Yammer, SharePoint and OpenGraph. Chris Johnson talks about how to use Yammer API to post updates, like and comment from code. What if you wanted to send an update to Yammer from your Line-of-Business application? Very easy.
- #spc303 Advanced Performance Analysis for SharePoint. A real-world case study how performance of a SharePoint site is measured, captured and analyzed. Really interesting.
- #spc391 Deep dive into Mail Compose Apps APIs. Main compose apps are similar to SharePoint apps, they are run as iframes and can be used to update an email while writing it or start a workflow. Good stuff.
- #spc334 Real-world SharePoint architecture decisions. Wictor Wilén talked about his best topic: architecture decisions. He is probably the best in this area in the world, and his presentation becomes better and better every time he presents it.
- #spc3000 Changing the look of Search using Display Templates and CSR. You can do a lot of stuff using the Display Templates and Cliend-Side Rendering. See this session to get inspired and gather a deeper understanding how it works.
- #spc382 Managing Search Relevance in SharePoint 2013 and O365. How does XRANK work? Well it is complicated. This session is a must-see.
- #spc224 The SharePointConference.com Site: From Sketch to Launch to Live! Did you know that SharePointConference.com was built upon SharePoint? See this session to find out what was good in SharePoint for this site, and what workarounds and hacks were necessary to get it to work.
- #spc302 Advanced development patterns for SharePoint Apps. Provider-Hosted Apps are the best type of apps. Let’s see what examples and tips are provided in this session.
- #spc322 SharePoint 2013 Search display templates and query rules. An introduction to Search Display Templates.
- #spc301 Access is back! High-value, ’no code’, functional & flexible business apps with the new Access services. There were a lot of jokes in this session. Access apps are new “no-code” solutions and will replace the InfoPath solutions.
- #spc407 Deep dive into the SharePoint 2013 CSOM API’s. The name is not correct. It is a dive into the CSOM, but it is not deep. See it if you want an introduction, but please keep in mind, the examples don’t follow the javascript coding conventions.
- #spc381 Load testing SharePoint 2013 using Visual Studio 2013. Never used load-testing with Visual Studio? Got a 1.15 hr to kill? Well, see it to learn how to start the Visual Studio and what difference is between a web test and load test.
The sessions I wish I had attended:
Custom Error and Access denied pages in Sharepoint
Unfortunately in SharePoint 2013 the custom error pages are not applied: link 1, link 2. Hopefully there will be a hotfix that solves it.
Comments from Wordpress.com
ryan - Mar 5, 2014
I agree, I have seen a few about. Thanks for the post
Jon - Mar 2, 2014
PowerShell: Migrate field choices to a termset
In my current project we are migrating a custom sharepoint solution from SharePoint 2010 to SharePoint 2013. One of the improvements is that we migrate custom field choices to Managed Metadata. Choice Fields were not intended to be so many. So now it is time to convert them to metadata terms. I have written a PowerShell script which copies all the choices from a field to a termset. The script uses Client Side Object Model (CSOM) to get the choice values and it uses Server Object Model to write data to the termset. [sourcecode language=“PowerShell”] <# .Synopsis Use MigrateChoices.ps1 to migrate choices from a field to managed metadata. The source can be a contenttype field from SharePoint 2010 or from SharePoint 2013. .Description This script uses client object model to get the list items from the old environment. Then it uses the Server Object Model to create new terms and termsets (if needed) in the new environment. This script doesn’t override anything. The reason why we use it, is that importing feature isnt easy It creates a new, instead of adding new terms to old ones. It is very hard to create an csv file for that purpose. .Example MigrateChoices.ps1 -Source http://sp2010.contoso.com -Target https://sp2013.contoso.com .Notes Name: MigrateChoices.ps1 Author: Anatoly Mironov Last Edit: 2013-09-04 Keywords: CSOM, Field, FieldChoice, Metadata, Termset .Links http://chuvash.eu .Inputs The script takes Source parameter, it is url for the root web in the Source Site Collection The script takes Target parameter, it is url for the root web in the Target Site Collection .Outputs None #Requires -Version 2.0 #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)][System.String]$Source = $(Read-Host -prompt “Source site Url”), [Parameter(Mandatory=$true)][System.String]$Target = $(Read-Host -prompt “Target site Url”), [Parameter(Mandatory=$false)][System.String]$TermGroupName = “My group”, [Parameter(Mandatory=$false)][System.String]$TermGroupId, [Parameter(Mandatory=$false)][System.String]$TermSetName = “My termset”, [Parameter(Mandatory=$false)][System.String]$TermSetId, [Parameter(Mandatory=$false)][System.String]$FieldName = $(Read-Host -prompt “Field Choice Name”) ) if(-not(gsnp | ? { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { asnp Microsoft.SharePoint.PowerShell } # try to instantiate the target site, if it fails, then it does not run in the right environment $targetSite = get-spsite $Target # predefined termset guids: $guids = @{ “group” = if ($TermGroupId) {New-Object system.guid $TermGroupId } else { [system.guid]::NewGuid() } “termset” = if ($TermSetId) {New-Object system.guid $TermSetId } else { [system.guid]::NewGuid() } } function GetChoices() { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Source) $field = $ctx.Web.Fields.GetByInternalNameOrTitle($FieldName) $ctx.Load($field) $ctx.ExecuteQuery() return ([xml]$field.SchemaXml).Field.Choices.Choice } function New-Term { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermSetItem]$parent, [Parameter(Mandatory=$true)][System.String]$name ) if (!$parent) { throw new-object System.ArgumentException $parent } if (!$name) { throw new-object System.ArgumentException $name } $term = $parent[$name] if (!$term) { $parent.CreateTerm($name, 1033) | out-null } } function CreateTerms() { $taxSession = Get-SPTaxonomySession -Site $targetSite $termStore = $taxSession.DefaultSiteCollectionTermStore $group = $termstore.Groups[$TermGroupName] if (!$group) { $group = $termStore.CreateGroup($TermGroupName, $guids.group) } $termSet = $group.TermSets[$TermsetName] if (!$termset) { $termset = $group.CreateTermSet($SecurityClassificationTermSetName, $guids.termset, 1033) } GetChoices | % { New-Term $termSet $_ } $termStore.CommitAll() $targetSite.Dispose() write-host -ForegroundColor Green “The term sets have been created” } CreateTerms [/sourcecode]
PowerShell: Get version and ProductId from an .app package
In my project I deploy some apps directly through the ObjectModel directly with PowerShell. The apps are built with TFS I have a script that installs or updates apps if there is a new version of the app. Previously I used Import-SPAppPackage to compare the version and productid with an existing app instance, but often I get this error:
The provided App differs from another App with the same version and product ID.
Count lines of code with PowerShell
Today I got a question:
How many lines of code are there in our SharePoint solution?
After a little search, I found that PowerShell is really a nice tool to count lines of code:
I wanted to count lines for different types of code:
- Code Behind written in C#, the files have .cs file extension
- JavaScript code (except jQuery, angular or knockout frameworks)
- PowerShell files (.ps1 and psm1)
- Xml files (all the SharePoint .xml files)
Here is the powershell code that counts lines of code: [code language=“powershell”] # go to the solution folder cd #count lines in .cs files ls -include *.cs -recurse | select-string . | measure | select count #count lines in our .js files ls -include *.js -recurse ` -exclude *min.js, jquery*, _*, jsrender*, CamlBuilder*, knockout* ` | select-string . ` | measure ` | select Count #count lines in our powershell scripts ls -include *.xml -recurse | select-string . | measure | select count #count lines in our powershell scripts ls -include *.ps1, *.psm1 -recurse | select-string . | measure | select count [/code] Just a curious fact, I can’t tell you how many lines of code we have in our solution, but I can reveal the proportions. If I used the flexible box model in css3, it would look like this: There are as many lines of code written in javascript as it is in C#. The main reason that for the big js code base are the SharePoint hosted apps. The PowerShell scripts are as big the javascript code base. Xml files are 4 times bigger than C# code, and it is even bigger than the sum of all lines of code written in C#, JavaScript and PowerShell. It isn’t strange that xml is dominating, almost everything in SharePoint is defined in xml. Fortunately, there are less cases where you have to write raw xml in Visual Studio 2012/2013 and SharePoint 2013. How does it look in your project? What language is dominating in your SharePoint project?
Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)
I have had a strange bug. The comment text box in a OOB SharePoint 2013 blog doesn’t appear. It only says: “There are no comments for this post.” In this blog post I’ll tell you how I found the bug and I’ll show you how you can temporarily bring the commenting to life. I have had luck. While it doesn’t work on the Test Environment, it does actually work on my development machine. The comments text box is rendered as an OnPostRender action in the blog comments display template. After debugging the javascript in hours and comparing the two environments, I just could confirm that displaytemplates are the same. There are two main javascript files that are involved:
Log to ULS using javascript
The more javascript code is produced in SharePoint solutions, the more need we have to log information and possible errors to a central logging place in SharePoint: ULS. This blog post is about logging to ULS from javascript. For a while ago I read a blog post:
The author @avishnyakov mentions the ability log to ULS from javascript. I want to dive deeper. [sourcecode language=“javascript”] ULS.enable = true ULSOnError(“Hello from javascript”, location.href, 0); [/sourcecode] What this function actually does, is that it calls a web service called _vti_bin/diagnostics.asmx
We can follow the function in the init.debug.js [sourcecode language=“javascript”] function ULSOnError(msg, url, line) { return ULSSendExceptionImpl(msg, url, line, ULSOnError.caller); } [/sourcecode] ULSOnError invokes ULSSendExceptionImpl: [sourcecode language=“javascript”] function ULSSendExceptionImpl(msg, url, line, oCaller) { if (Boolean(ULS) && ULS.enable) { ULS.enable = false; window.onerror = ULS.OriginalOnError; ULS.WebServiceNS = “http://schemas.microsoft.com/sharepoint/diagnostics/"; try { ULS.message = msg; if (url.indexOf(’?’) != -1) url = url.substr(0, url.indexOf(’?’)); ULS.file = url.substr(url.lastIndexOf(’/’) + 1); ULS.line = line; ULS.teamName = “”; ULS.originalFile = “”; ULS.callStack = ‘\n’ + ULSGetCallstack(oCaller) + ‘’; ULS.clientInfo = ‘\n’ + ULSGetClientInfo() + ‘’; ULSSendReport(true); } catch (e) { } } if (Boolean(ULS) && Boolean(ULS.OriginalOnError)) return ULS.OriginalOnError(msg, url, String(line)); else return false; } [/sourcecode] ULSSendExceptionImpl invokes ULSSendReport: [sourcecode language=“javascript”] function ULSSendReport(async) { ULS.request = new XMLHttpRequest(); ULS.request.onreadystatechange = ULSHandleWebServiceResponse; ULS.request.open(“POST”, ULSGetWebServiceUrl(), async); ULS.request.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”); ULS.request.setRequestHeader(“SOAPAction”, ULS.WebServiceNS + “SendClientScriptErrorReport”); ULS.request.send(’’ + ‘<soap:Envelope xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=“http://www.w3.org/2001/XMLSchema" xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/">' + ‘soap:Body’ + ‘’ + ‘’ + ULSEncodeXML(ULS.message) + ‘’ + ‘’ + ULSEncodeXML(ULS.file) + ‘’ + ‘’ + String(ULS.line) + ‘’ + ‘’ + ULSEncodeXML(ULS.callStack) + ‘’ + ‘’ + ULSEncodeXML(ULS.clientInfo) + ‘’ + ‘’ + ULSEncodeXML(ULS.teamName) + ‘’ + ‘’ + ULSEncodeXML(ULS.originalFile) + ‘’ + ‘’ + ‘</soap:Body>’ + ‘</soap:Envelope>’); } [/sourcecode]
scriptcs and SharePoint. How SharePoint can benefit?
Last Saturday I attended Leetspeak. Among many awesome speeches and presentations I discovered scriptcs. scriptcs lets you write C# code directly in the console, or execute scripts written with just your favourite editor. Please see more about it on the site. What I thought during Justin Rusbatch’s session at Leetspeak:
Can we use scriptcs in SharePoint?
Technically there is no limitations in SharePoint for scriptcs. Any .NET code can be registered, imported and invoked in a console or in a standalone script. Here is the simple code for instantiating a site collection and disposing it: [code language=“csharp”] #r Microsoft.SharePoint; using Microsoft.SharePoint; var site = new SPSite(“http://dev”); site.Url site.Dispose(); [/code] The code above does not do anything, it is just there to demonstrate how you can register the SharePoint assembly (“Microsoft.SharePoint”) and import it into the script: [code language=“csharp”] using Microsoft.SharePoint; [/code] The example shows even that you in scriptcs no longer need the necessary “boilerplate” (compared to a console application): namespace, Program, Main()… You can just directly write your code. The rest is the same as in a C# application. The code samples for scriptcs can be any code written in C# for SharePoint, code from custom console applications, from feature receivers, you name it. So my next question is:
Apps can only call the OOB CSOM and REST endpoints
As a SharePoint architect or a SharePoint developer, you must have been thinking about the benefits/limitations of SharePoint apps a lot. I want to point out one of them today, which is very important: using custom webservices deployed to SharePoint inside apps. That is impossible and it is designed to be so due to the security architecture in the sharepoint app framework. I have read much about SharePoint apps (books, whitepapers, blog posts) and stumbled over these two contradictive statements:
javascript: Alert Me on a Page
Recently I needed to add an Alert Me link on Pages. Alert Me is a well known SharePoint functionality for notifying users about changes in list or list items. It is availabe in OOB SharePoint as a command in Ribbon if you go to a list view: When you click on this ribbon command, SharePoint opens a modal dialog and takes you to layouts page: SubNew.aspx. To open a modal dialog and load a page is not a rocket science. So a custom “Alert Me” link is doable. As the first step I copied the html markup from the ribbon and adjusted it a little bit. [sourcecode language=“html”] Alert Me [/sourcecode] Then the javascript code which gets the List ID and Page ID is very simple because this information is there in the magic _spPageContextInfo: [sourcecode language=“javascript”] var takana = window.takana || {}; takana.alertMe = function () { var url = String.format("{0}/{1}/SubNew.aspx?List={2}&ID={3}" , _spPageContextInfo.webAbsoluteUrl , _spPageContextInfo.layoutsUrl , encodeURI(_spPageContextInfo.pageListId) , _spPageContextInfo.pageItemId); OpenPopUpPage(url); } [/sourcecode] This code will open a modal dialog in exactly the same way as the ribbon command in OOB SharePoint and let you subscribe to changes on that page. In this code I use String.format which is available on SharePoint pages and _spPageContextInfo which has existed since SharePoint 2010 and has been extended with more useful information about the current context.
javascript: Remove illegal characters in url
Recently I needed to create valid urls for pages using javascript. Also this time I thought it must be some out-of-the-box code for that in SharePoint. The first thing I came up was the “Add page” dialog. I found that the actual dialog was in the _layouts virtual folder:
/\_layouts/15/CreatePublishingPageDialog.aspx
```Bingo, it does the validation in the client side. This is the responsible javascript function that resides directly in the page: \[sourcecode language="javascript"\] function UpdateUrl() { LoadTermContextInfo(); var hiddenPageUrlLabelExtensionClientId = "<%=hiddenPageUrlLabelExtension.ClientID%>"; var hiddenPageUrlLabelExtension = document.getElementById(hiddenPageUrlLabelExtensionClientId); var pageNamePreviewUrlLabelClientId = "<%=pageNamePreviewUrlLabel.ClientID%>"; var pageNamePreviewUrlLabel = document.getElementById(pageNamePreviewUrlLabelClientId); if( pageNamePreviewUrlLabel != null ) { var nameInputTextBoxClientId = "<%=nameInput.ClientID%>"; var nameInputTextBox = document.getElementById(nameInputTextBoxClientId); var allowSpaces = false; if( GetInnerText(hiddenPageUrlLabelExtension) != "" ) { var suggestUrlValue = ""; for (var i=0; i < nameInputTextBox.value.length; i++) { var currentChar = nameInputTextBox.value.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } UpdatePreviewUrl( suggestUrlValue ); } else { if( g\_timerId != 0 ) { window.clearTimeout(g\_timerId); } g\_timerId = window.setTimeout(OnFriendlyUrlNameChanged, 500); } } } \[/sourcecode\] This function iterates through all the characters in the page url and removes the illegal characters. The space, plus sign and the dot become a hyphen. To determine if a character is illegal, it relies on another javascript function called: `IndexOfIllegalCharInUrlLeafName`. This function can be found in the init.js or init.debug.js: \[sourcecode language="javascript"\] function IndexOfIllegalCharInUrlLeafName(strLeafName) { for (var i = 0; i < strLeafName.length; i++) { var ch = strLeafName.charCodeAt(i); if (strLeafName.charAt(i) == '.' && (i == 0 || i == strLeafName.length - 1)) return i; if (ch < 160 && (strLeafName.charAt(i) == '/' || !LegalUrlChars\[ch\])) return i; } return -1; } \[/sourcecode\] This function checks a char against an array of all characters: `LegalUrlChars` from the same file: init.js. [![ill_002](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png)](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png) To use this UpdateUrl function, we have to remove the references to the fields from the Add Page Dialog. Of course, we won't overwrite this original function, we don't want to break the SharePoint OOB functionality. Here is how my new function looks like: \[sourcecode language="javascript"\] var takana = {}; function takana.updateUrl(url) { var allowSpaces = false; if( url ) { var suggestUrlValue = ""; var length = url.length; for (var i=0; i < length; i++) { var currentChar = url.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } } } \[/sourcecode\]
#### Server Side
For those of you who want run this operation on the server, here is the code written in C#: \[sourcecode language="csharp"\] //" # % & \* : < > ? \\ / { } ~ | var illegalChars = @"\[""#%&\\\*:\\<\\>\\?\\\\\\/\\{\\}~\\|\]"; pageName = Regex.Replace(pageName, illegalChars, string.Empty); var punctuation = @"\[\\s\\.;\\+\]"; pageName = Regex.Replace(pageName, punctuation, "-"); //remove "--" pageName = Regex.Replace(pageName, @"\\-{2,}", "-"); pageName = string.Format("{0}.aspx", pageName); //do it like the built-in dialog, lower case pageName = pageName.ToLower(); \[/sourcecode\] Don't forget to leave a comment if you find this post useful.
## Comments from Wordpress.com
####
[Johannes Milling](http://discoveringsharepoint.wordpress.com "johannesmilling@hotmail.com") - <time datetime="2013-08-23 09:53:30">Aug 5, 2013</time>
Good post! :)
<hr />
The CDN concept in SharePoint
How many instances of jquery are there in your SharePoint farm? [sourcecode language=“powershell”] Get-SPWebApplication http://dev ` | Select -Expand Sites ` | Select -Expand AllWebs ` | Select -Expand Lists ` | Select -Expand Items ` | ? { $_.Url -match “jquery.*.js” } ` | select Name, Url [/sourcecode] Have you more than two (jquery and jquery-ui), then you have too much. You can save much place and performance by using Content Delivery Network (CDN) links for the resources like javascript, css, fonts and icons. Consider those Content Delivery Networks:
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
SharePoint Apps: "Provider Hosted First" Approach
Recently I had an exciting mail conversation with Thomas Deutsch. He came up with an idea how to fasten the development of apps. This smart approach is called “Provider Hosted First”. See Thomas’ original blog post. Here are some highlights: What you actually do is a local website which runs in grunt server
:
localhost:9000
```Then a SharePoint-hosted app is created with an SPAppIframe that refers to that local app site. Genious!!! Some key features of this approach:
* This local app contains a livereload script. Your sharepoint app is updated every time you save your css, js, html file in your IDE
* Grunt minifies, bundles your assets
* Grunt runs your tests automatically when your content is modified
* The SharePoint app can be on Premises, on Office 365, wherever you want it.
#### Video
\[caption id="attachment\_2808" align="alignnone" width="630"\][![See the video how it looks like to develop using this approach](https://sharepointkunskap.files.wordpress.com/2013/07/sp-app-002.png?w=630)](http://www.screenr.com/LA8H) See the video how it looks like to develop using this approach\[/caption\]
## Comments from Wordpress.com
####
[Paul Tavares](http://paultavares.wordpress.com "paultavares1@gmail.com") - <time datetime="2013-07-10 02:59:34">Jul 3, 2013</time>
This is pretty cool and very similar to my current setup for developing javascript applications for SharePoint. I use a script to "deploy" updates from my PC to the folder in a document library. I'll try this out when I get around to playing with SP2013.
<hr />
####
[Björn]( "bjorn.roberg@bool.se") - <time datetime="2013-07-02 11:07:08">Jul 2, 2013</time>
Awesome! I'm gonna try that out!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-07-02 15:31:33">Jul 2, 2013</time>
Great! When you go to Thomas Deutsch blog, you can download the source code for the solution.
<hr />
Make javascript code work with Minimal Download Strategy Part 2
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
Minimal Download Strategy (MDS) is an important feature in SharePoint 2013. It lets you download only a page delta, only changes. There is still issues with the MDS and custom scripts and almost no documentation on msdn or technet. In this blog post I want to learn more about adjusting custom scripts for MDS. As in my previous post, I want to take a real problem and try to solve it. The goal is to find a solution, not nececerilly the most optimal solution, at least for now.
Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
Styling suiteBar and IE8
Today I want to share little css tip for styling the suiteBar in SharePoint 2013 and making it work even in IE8. I needed to apply a green color to the suiteBar (#005128). It worked in all browsers except IE8: The reason why is a special css rule (in corev15.css) that only IE8 understands: [sourcecode language=“css”] .ms-core-needIEFilter #suiteBarLeft { filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=#ff0072c6,endColorstr=#ff0072c6); } [/sourcecode] I found this answer in an blog post written by Trace Armstrong: SharePoint 2013 – Branding the Top Bar and the Importance of Browser Testing. You could override this css rule with your colors, just dig into the msdn documentation. What I needed though, was just a plain color, so I didn’t want to dig into that old progid-definitions. There is actually a simpler solution on social.msdn.microsoft.com. A guy called avshinnikov just overrides the “filter” rule by setting it to none. If you apply it only with id selector (#suiteBarLeft) then you have to put “!important” after that. Fortunately I allready had my own css class on html tag which is a sort of a “namespace” for my selectors: [sourcecode language=“css”] .takana-html #suiteBarLeft { background-color: #005128; filter: none; } [/sourcecode] The class .takana-html can have any name, of course, and it can be a class on a closer parent element to the suiteBar. The only goal for that is to make your css rules more important in your design in a natural way (and avoiding the “!important”). Eventhough many people use this principle without thinking about it, I’ve not found any info regarding this principle. I only heard Jeremy Foster and Michael Palermo talking about it and referring to it as “css namespaces” in a video course: Developing in HTML5 with JavaScript and CSS3 Jump Start. Of course, the name isn’t unique, there is another thing called css namespaces. But the concept is really good.
Multi-lingual "Last Modified" footer
You want to show when a page is last modified? The label should, of course, work in multi-language environment. For MOSS, there is a great article about how to achieve this: Jamie McAllister. Building a multi-lingual ‘Last Modified’ Footer for MOSS. Here is a simple example for doing the same in SharePoint 2013: [sourcecode language=“html”] <%@ Register TagPrefix=‘SharePointWebControls’ Namespace=‘Microsoft.SharePoint.WebControls’ Assembly=‘Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c’ %> <SharePointWebControls:EncodedLiteral runat=‘server’ Text=’<%$Resources:cms,pagesettings_modifieddate_label%>’ EncodeMethod=‘HtmlEncode’/>: <SharePointWebControls:DateTimeField runat=“server” FieldName=“Modified” ControlMode=“Display”/> [/sourcecode] It fetches the localized value from cms.resx and puts it into your page as html.
REST API: Add a plain text file as an attachment to a list item
SharePoint 2013 REST API has been enhanced and extended. The old _vti_bin/listdata.svc is still there, but the new api for working with lists and list items is much more and obviously a part of a bigger api: _api/web/lists Yesterday I saw an interesting question on SharePoint StackExchange:
The instructions in the MSDN resource are not so detailed, the cannot be. The guy who asked the question did as it stood in the examples. But sometimes solutions for SharePoint need some small adjustments :) Here is the simplest code to create an attachment in plain text for a list item 1 in the list called List1 in the root web. That’s it. But it works: [sourcecode language=“javascript”] var content = “Hello, this text is inside the file created with REST API”; var digest = $("#__REQUESTDIGEST").val(); var composedUrl = “/_api/web/lists/GetByTitle(‘List1’)/items(1)/AttachmentFiles/add(FileName=‘readme.txt’)”; $.ajax({ url: composedUrl, type: “POST”, data: content, headers: { “X-RequestDigest”: digest } }) [/sourcecode] This example is of course just for demonstration. It uses only hard-coded values. But it shows how simple it is to create a list item attachment using SharePoint 2013 REST API and “upload” plain text asynchronously to the server.
Error: Sorry, we're having trouble reaching the server
I ran into a an issue today. When I tried to add a user to a site in my SharePoint 2013 site, I got this error:
Sorry, we’re having trouble reaching the server
A google search gave these two possible solutions:
I know it can almost everything that can cause this error. Here are my two öre :) I found that when I tried to add a user, an ajax call was made. And this was the error:
TypeScript in SharePoint
By now TypeScript shouldn’t be something one has to introduce.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
If you haven’t already done it, go and see the intro video for TypeScript, check out a tutorial and visit the typescript playground. There are other javascript libraries which extend javascript and are compatible/compile to javascript: Dart and CoffeeScript. To be honest I had never time to try those. The fact that TypeScript is well integrated into Visual Studio which I happen to work within all the days (intellisense, compilation checks and more) did me curious. This post is actually not about TypeScript itself, but a test to use it in SharePoint. In this short “lab” I even had Web Essentials 2012 which automatically compile typescript files into plain javascript files on save. This is what I did: Install TypeScript and Web Essentials 2012 Create a SharePoint-hosted app: Create a new TypeScript file in the autogenerated “Scripts”-module and call it “Greeter.ts” Just save the file as it is. The new file is created: Greeter.js Now we don’t need to copy this file to the app, so remove Greeter.ts from the Elements.xml file (or comment it out): Open the Default.aspx from the Pages module and add the reference to the new javascript file:
$ in cmssitemanager.js conflicts with $ in jQuery
In SharePoint 2010 if CMSSiteManager.js library is loaded besides jQuery, then much of stuff stops working. The reason is that the dollar sign ($) is used in cmssitemanager.js as well which conflicts with jQuery. Mostly it appears on pages where you load jQuery and have an image library with thumbnails. To avoid this, just replace all $ with jQuery in your custom scripts. A more crazy situation is when avoiding $ isn’t enough. It is when you load jQuery to page head automatically on all pages. The Asset picker (AssetPortalBrowser.aspx) invokes $ itself and gets with jQuery in conflict without you write a single line of custom javascript code. You usually get the following error:
Tag: Workflow
Trigger SP2010 Workflows using JSOM
Today I found out how to start workflows in JSOM (JavaScript Object Model in SharePoint). Nothing special, but since it is not documented, it took me a while to find a solution. Here is the code which I want to keep as simple as possible. What you need to start a SP2010 Workflow for a list item or a document in JSOM, you need to load SP.WorkflowServices.js and you need to create the manager and get the service, then you can trigger a workflow using the workflow name, the list guid and the guid of the list item: [code language=“javascript”] var ctx = SP.ClientContext.get_current(); var workflowServicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web()); var service = workflowServicesManager.getWorkflowInteropService(); service.startWorkflow(workflowName, null, listGuid, plainItem.guid, initiationParams); [/code] Here is the code to trigger a workflow for multiple items: [code language=“javascript”] //fire the workflows function fire2010WorkflowForListItems(ctx, listGuid, plainItems) { var workflowServicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web()); var service = workflowServicesManager.getWorkflowInteropService(); for(var i = 0; i < plainItems.length; i++) { var plainItem = plainItems[i]; console.log(‘scheduling workflow for id: ‘, plainItem.id); service.startWorkflow(options.workflowName, null, listGuid, plainItem.guid, options.initiationParams); } console.log(’now executing…’); ctx.executeQueryAsync(function() { console.info(‘yes, workflows completed for ’ + items.length + ’ items’); }, function() { console.error(‘it didnt go well’); }); } [/code] The code above is inspired from this gist and sharepoint stackexchange. It is a simplified version that only works for list item workflows and SharePoint 2010 workflows. Here is an example how you can get multiple items and batch start a workflow: [code language=“javascript”] //just a couple of variables var options = { workflowName: ‘Behörigheter’, listName: ‘Documents’, initiationParams: {} }; //load list items function startWorfklows() { //Start 2010 Workflow for a List Item var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(options.listName); ctx.load(list); var items = list.getItems(new SP.CamlQuery()); ctx.load(items); ctx.executeQueryAsync(function() { var listGuid = list.get_id() + ‘’; var en = items.getEnumerator(); var plainItems = []; while (en.moveNext()) { var it = en.get_current(); //do not take checked out files, it won’t work if (!it.get_item(‘CheckoutUser’)) { plainItems.push({id: it.get_id(), guid: it.get_item(‘GUID’) + ’’ }); } } fire2010WorkflowForListItems(ctx, listGuid, plainItems); }, function() { alert(‘boom’); }); } //Load Worfklow Js dependency var wfScript = ‘SP.WorkflowServices.js’ SP.SOD.registerSod(wfScript, _spPageContextInfo.webAbsoluteUrl + ‘/_layouts/15/SP.WorkflowServices.js’); SP.SOD.executeFunc(wfScript, ‘’, startWorfklows); [/code]
Tag: Mds
Minimal Download Strategy. Simple
There are many correct ways (1, 2, 3, 4, 5…) of making scripts work with the Minimal Download Strategy Feature (MDS) in SharePoint 2013 and 2016. But to be honest - every time I need it, I get confused. So now it is time to find a simple solution for that. Who is better at it than the developers of the SharePoint themselves? Look at the MDS code in the built-in Display Templates: Let’s keep it as simple as Item_Default.js, let’s take it as it is and create our own scripts. Here is a skeletton of and MDS-ready script: [code language=“javascript”] function runMyCode() { var time = new Date().toISOString(); console.log(‘runMyCode’, time ); } runMyCode(); if (typeof(RegisterModuleInit) == ‘function’) { var scriptUrl = ‘/Style Library/runMyCode.js’; RegisterModuleInit(scriptUrl, runMyCode); } [/code] Which boils down to this in pseudocode:
Make javascript code work with Minimal Download Strategy Part 2
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
Minimal Download Strategy (MDS) is an important feature in SharePoint 2013. It lets you download only a page delta, only changes. There is still issues with the MDS and custom scripts and almost no documentation on msdn or technet. In this blog post I want to learn more about adjusting custom scripts for MDS. As in my previous post, I want to take a real problem and try to solve it. The goal is to find a solution, not nececerilly the most optimal solution, at least for now.
Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
Tag: Display Template
Minimal Display Template
We want to use our own Display Templates on Non-publishing sites - our team sites. Without the Publishing Feature activated you have to create an own javascript file. Here is short and concise instructions how to install it: Display Templates on Non-publishing Sites. As described on that blog, you can make copy of an existing Item_Default.js and adjust to your needs. I also asked Elio Struyf and I got the same tip. I did create my starter template. Here I want to share this very minimal javascript based Display Template. The real Minimal Display Template is in the SPCSR github repository: Item_Minimal.js It has been improved by Elio Stuyf himself :) [code language=“javascript”] (function () { // Config contains variables that are defined in one place var config = { propertyMappings: { ‘Path’:null, ‘Title’:[‘Title’] } }; var templateUrl; var register = function () { if (“undefined” !== typeof (Srch) && “undefined” !== typeof (Srch.U) && typeof (Srch.U.registerRenderTemplateByName) === “function”) { Srch.U.registerRenderTemplateByName(templateUrl, render); } }; render = function (ctx) { // Display template data var cachePreviousTemplateData = ctx.DisplayTemplateData; ctx.DisplayTemplateData = { ‘TemplateUrl’: templateUrl, ‘TemplateType’: ‘Item’, ‘TargetControlType’: [‘SearchResults’, ‘Content Web Parts’], ‘ManagedPropertyMapping’: config.propertyMappings }; var cachePreviousItemValuesFunction = ctx.ItemValues; ctx.ItemValues = function(slotOrPropName) { return Srch.ValueInfo.getCachedCtxItemValue(ctx, slotOrPropName); }; // Retrieve managed property data var path = $getItemValue(ctx, ‘Path’); var title = $getItemValue(ctx, ‘Title’); // HTML markup for an item var htmlMarkup = String.format( ‘’ + ‘{1}’ + ‘’, path, title); // Caching ctx.ItemValues = cachePreviousItemValuesFunction; ctx.DisplayTemplateData = cachePreviousTemplateData; // Return the HTML markup return htmlMarkup; }; // Retrieve all the loaded scripts var allScripts = document.getElementsByTagName(“script”); // Get the last script file (this is the current DT file) var scriptUrl = allScripts[allScripts.length - 1].src; if (scriptUrl.indexOf(’/_catalogs/’) > 0) { // Remove the query string if (scriptUrl.indexOf(’?’) > 0) { scriptUrl = scriptUrl.split("?")[0]; } // Insert the site collection token templateUrl = ‘~sitecollection’ + scriptUrl.substr(scriptUrl.indexOf(’/_catalogs/’)) // Register the template to load register(); if (typeof (RegisterModuleInit) === “function” && typeof(Srch.U.replaceUrlTokens) === “function”) { RegisterModuleInit(Srch.U.replaceUrlTokens(templateUrl), register); } } })(); [/code]
Tag: Minimal
Minimal Display Template
We want to use our own Display Templates on Non-publishing sites - our team sites. Without the Publishing Feature activated you have to create an own javascript file. Here is short and concise instructions how to install it: Display Templates on Non-publishing Sites. As described on that blog, you can make copy of an existing Item_Default.js and adjust to your needs. I also asked Elio Struyf and I got the same tip. I did create my starter template. Here I want to share this very minimal javascript based Display Template. The real Minimal Display Template is in the SPCSR github repository: Item_Minimal.js It has been improved by Elio Stuyf himself :) [code language=“javascript”] (function () { // Config contains variables that are defined in one place var config = { propertyMappings: { ‘Path’:null, ‘Title’:[‘Title’] } }; var templateUrl; var register = function () { if (“undefined” !== typeof (Srch) && “undefined” !== typeof (Srch.U) && typeof (Srch.U.registerRenderTemplateByName) === “function”) { Srch.U.registerRenderTemplateByName(templateUrl, render); } }; render = function (ctx) { // Display template data var cachePreviousTemplateData = ctx.DisplayTemplateData; ctx.DisplayTemplateData = { ‘TemplateUrl’: templateUrl, ‘TemplateType’: ‘Item’, ‘TargetControlType’: [‘SearchResults’, ‘Content Web Parts’], ‘ManagedPropertyMapping’: config.propertyMappings }; var cachePreviousItemValuesFunction = ctx.ItemValues; ctx.ItemValues = function(slotOrPropName) { return Srch.ValueInfo.getCachedCtxItemValue(ctx, slotOrPropName); }; // Retrieve managed property data var path = $getItemValue(ctx, ‘Path’); var title = $getItemValue(ctx, ‘Title’); // HTML markup for an item var htmlMarkup = String.format( ‘’ + ‘{1}’ + ‘’, path, title); // Caching ctx.ItemValues = cachePreviousItemValuesFunction; ctx.DisplayTemplateData = cachePreviousTemplateData; // Return the HTML markup return htmlMarkup; }; // Retrieve all the loaded scripts var allScripts = document.getElementsByTagName(“script”); // Get the last script file (this is the current DT file) var scriptUrl = allScripts[allScripts.length - 1].src; if (scriptUrl.indexOf(’/_catalogs/’) > 0) { // Remove the query string if (scriptUrl.indexOf(’?’) > 0) { scriptUrl = scriptUrl.split("?")[0]; } // Insert the site collection token templateUrl = ‘~sitecollection’ + scriptUrl.substr(scriptUrl.indexOf(’/_catalogs/’)) // Register the template to load register(); if (typeof (RegisterModuleInit) === “function” && typeof(Srch.U.replaceUrlTokens) === “function”) { RegisterModuleInit(Srch.U.replaceUrlTokens(templateUrl), register); } } })(); [/code]
Tag: Framework
SharePoint Utilities - a promising JavaScript Framework
My colleagues at Bool have developed a new JavaScript framework for SharePoint - sharepoint utilities. It started on our DevDay last year - a whole free day when we could learn new things, try out new techniques or build something that was not even requested from a customer. I was not working on sharepoint utilities, so I almost forgot it until… I recently re-discovered sharepoint utilities. It is on Github, it is MIT licensed and contributions are welcome. The core of sharepoint utilities (sputils) is a set of wrappers for Search, TermStore, REST that allow you be more productive as a developer. What I find especially compelling with that it contains some other fundamental stuff that every SharePoint developer needs:
Bootstrap and Sharepoint
Twitter Bootstrap is awesome, based on less.js, ust add this line in your html code:
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/1.3.0/bootstrap.min.css">
And your page looks already good. If you use css classes like btn label warning danger and much more, you get a right design directly out of the box. Now I want to test it in Sharepoint. Will it work? What do you think? jQuery Theme Roller. Another interesting resources are jQuery ThemeRoller. WebResources Depot:
Tag: Bookmarklet
A tiny tool for User Custom Actions
Everybody loves User Custom Actions in SharePoint. That’s the only recommended way of customizing SharePoint. You have heard about it. Unfortunately there is no convinient way of administering them. People have their console applications or powershell scripts to add, update and delete user custom actions. It works but it is hard to open up Visual Studio or PowerShell every time you will try out an idea on a test site. To overcome this, I have created a tiny little tool, packaged as a bookmarklet for your browser. When you click on it, it will show your existing user custom actions and you can add new user custom actions. It is an ongoing little project, available on github, contributions are welcome. What’s left is:
Copy SharePoint WebDav Address to Clipboard
While configuring SharePoint sites and helping users I often use File Explorer View for editing pages, resources like css and javascript. In IE there is a dedicated button in the ribbon for that. Sometimes it works, sometimes it doesn’t, because of permissions or other restrictions. Anyway, I use Firefox and Chrome while troubleshooting and developing, so I have created a bookmarklet for copying the webdav address of a site that is open in the browser. [source language=“javascript”] var uri = _spPageContextInfo.webAbsoluteUrl.replace(/https?:\/\//i, “\\\\”).replace(/\//g, “\\”); window.prompt(“Copy to clipboard: Ctrl+C, Enter”, uri); [/source] Unfortunately, there is no copy function in javascript, the prompt solution plus Ctrl-C works fine. The bookmarklet: [source language=“html”] javascript:void%20function(){var%20o=_spPageContextInfo.webAbsoluteUrl.replace(/https%3F:\/\//i,%22\\\\%22).replace(/\//g,%22\\%22);window.prompt(%22Copy%20to%20clipboard:%20Ctrl+C,%20Enter%22,o)}(); [/source] Enjoy
Export Any Web Part using a Bookmarklet
My blog post about exporting any webpart from a SharePoint Page is one of the most read articles on my blog. I use this method a lot. Now what I want to do is to simplify the process. Inspired by my colleague Dan Saedén’s awesome bookmarklet for reading and updating web properties, I decided to make my own bookmarklet. That was easy. Now we can export any web part from any SharePoint page without even looking at any ids in the html markup and assembling the export url manually. Just add the bookmarklet or run the javascript code in the browser console. The code (js and bookmarklet) is on Github. Here is an animated gif that explains how to use it:
Tag: Customaction
A tiny tool for User Custom Actions
Everybody loves User Custom Actions in SharePoint. That’s the only recommended way of customizing SharePoint. You have heard about it. Unfortunately there is no convinient way of administering them. People have their console applications or powershell scripts to add, update and delete user custom actions. It works but it is hard to open up Visual Studio or PowerShell every time you will try out an idea on a test site. To overcome this, I have created a tiny little tool, packaged as a bookmarklet for your browser. When you click on it, it will show your existing user custom actions and you can add new user custom actions. It is an ongoing little project, available on github, contributions are welcome. What’s left is:
Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
Registrera javascript i feature
Om det inte passar att javascript i masterpage eller egen webpart, registrera det som customaction och aktivera feature. Läs mer här. Här är ett exempel:
<CustomAction
Location="ScriptLink"
ScriptSrc="~sitecollection/\_layouts/MyProject/awesome.js"
Sequence="101">
</CustomAction>
Tag: Usercustomaction
A tiny tool for User Custom Actions
Everybody loves User Custom Actions in SharePoint. That’s the only recommended way of customizing SharePoint. You have heard about it. Unfortunately there is no convinient way of administering them. People have their console applications or powershell scripts to add, update and delete user custom actions. It works but it is hard to open up Visual Studio or PowerShell every time you will try out an idea on a test site. To overcome this, I have created a tiny little tool, packaged as a bookmarklet for your browser. When you click on it, it will show your existing user custom actions and you can add new user custom actions. It is an ongoing little project, available on github, contributions are welcome. What’s left is:
Tag: EF
Provisioning Google Maps JSLink with SPMeta2
Among PnP Samples there is a solution for using Google Maps. Great solution where where you can pick a point on a map and define a spacial area on the map. Unfortunately it is a sandbox solution. I rewrote it to a code based template with SPMeta2 Framework. Now it can be installed on any site very easily, without needing UserCode Service and a cumbersome process of uploading a wsp package and activating it. The code is very simple, you can see it on github.
Trying out Visual Studio Code on Ubuntu
I am very curious about the new .NET Core, ASP.NET 5, EF 7 and Visual Studio Code for Linux, Mac and Windows. I have tried it out on an Ubuntu 15.04 machine. The installation and configuration required a few steps, so it is not an usual “Next-next-next”-installation. But, hey, it is just a beta, a preview so far, and first of all: It worked. I am sharing a couple of screenshots and the commands I ran in the terminal, mixed with comments and links: [source language=“bash”] #install latest node and npm #https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs sudo npm install -g yo sudo npm install -g generator-aspnet # download VS Code and make a link # make a folder mkdir workspace/tryvs cd workspace/tryvs # create “src/global.json” file: # http://docs.asp.net/en/latest/tutorials/your-first-mac-aspnet.html { “sdk”: { “version”: “1.0.0-beta7” } } nano src/global.json # start VS Code # create # install omnisharp: # http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#installing-on-debian-ubuntu-and-derivatives curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh dnvm #install dnx sudo apt-get install -y libunwind8 gettext libssl-dev libcurl3-dev zlib1g libicu-dev dnvm upgrade -r coreclr cd EmptyApplication dnu restore #install libuv #http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#using-docker sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/ sudo ldconfig #build, I got an error here dnu build #start the web server dnx web [/source]
Tag: Google Maps
Provisioning Google Maps JSLink with SPMeta2
Among PnP Samples there is a solution for using Google Maps. Great solution where where you can pick a point on a map and define a spacial area on the map. Unfortunately it is a sandbox solution. I rewrote it to a code based template with SPMeta2 Framework. Now it can be installed on any site very easily, without needing UserCode Service and a cumbersome process of uploading a wsp package and activating it. The code is very simple, you can see it on github.
Get coordinates from Google Maps
To get longitude and latitude can be tricky at the first time. There are many ways to do this, e.g. getlatlon.com. Good enough, but not so practical if you want to collect many coordinates. You can’t search after street names, you only can scroll and drag. Another way is to use javascript to show the longitude and latitude. See this example. This works in all web browsers.Just find your object in Google Maps and paste this javascript in URL bar: javascript:void(prompt('',gApplication.getMap().getCenter()));
You’ll be prompted the coordinates values. Just be sure the map is centered on your object. There is a third, even better way. Use javascript, but don’t be annoyed with prompts. In Chromium (or Google Chrome) navigate to maps.google.com find your object, open the Console in DevTools (press Ctrl-Shift-J). Right click on the object → Center the map here In console write: copy ( gApplication.getMap().getCenter().toString() )
So now you can paste it wherever you need it. But the best with it is: you can do whatever you want and need before copying. In LUSites, I save the coordinates another way, first latitude and then longitude. So I can shift values, trim unnecessary stuff and so on. Look at it: var loc = gApplication.getMap().getCenter().toString(); var locTrimmed = loc.replace(/[() ]/gi,""); var locArray = loc.split(","); var newLoc = locArray[1] + "," + locArray[0]; copy (newLoc)
First I get the string of the coordinates. Then I erase the unnecessary stuff: (), blank space. After splitting I shift the longitude and the latitude and create a new string which is copied. Or, we can shorten this: var coordinates = gApplication .getMap() .getCenter() .toString() .replace(/[() ]/gi,"") .split(","); copy (coordinates[1] + "," + coordinates[0]);
The same in one row (to copy-paste): var coordinates = gApplication.getMap().getCenter().toString().replace(/[() ]/gi,"").split(","); copy (coordinates[1] + "," + coordinates[0]);
To avoid to copy this line of code, just press up arrow in the DevTools console.
Tag: Spmeta2
Provisioning Google Maps JSLink with SPMeta2
Among PnP Samples there is a solution for using Google Maps. Great solution where where you can pick a point on a map and define a spacial area on the map. Unfortunately it is a sandbox solution. I rewrote it to a code based template with SPMeta2 Framework. Now it can be installed on any site very easily, without needing UserCode Service and a cumbersome process of uploading a wsp package and activating it. The code is very simple, you can see it on github.
Kom igång med SPMeta2
SPMeta2 (eller bara M2) är ett relativt nytt ramverk för provisionering av SharePoint-artefakter. Bakom ramverket ligger ett gediget arbete. I den här posten vill jag skriva upp mina steg för att sätta upp ett litet projekt. För mig är SPMeta2 nytt och huvudprincipen i den här bloggposten att få en fungerande lösning så snabbt som möjligt. Informationen här kan snabbt bli inaktuell, eftersom SPMeta2 förändras och förbättras väldigt snabbt. Vad är SPMeta2 SPMeta är ett ramverk för att provisionera SharePoint-artefakter, allt från fält, innehållstyper, listor, dokumentbibliotek, user custom actions, ladda upp filer med mera. Klassiskt har vi gjort provisionering med hjälp av XML-baserade moduler och features. SPMeta2 erbjuder ett Fluent API som är kodbaserat. Med hjälp av SPMeta2 definierar man en modell (enkla objekt POCOs) som inte har beroendet till SharePoint. Modellen används sedan av Provision-delen som anropar modellen för specifika versioner: SharePoint 2013, SharePoint 2010, Office 365 med mera. Man kan välja CSOM och SSOM. Provision är också flexibel vad som gäller paketering: det kan vara en konsolapplikation, en SharePoint-app, ett wsp-paket, en PowerShell-modul. Se följande länkar:
Tag: Browser
Setting up Raspberry Pi2 for a Dashboard Monitor
I have set up Raspberry Pi as a Dashboard Monitor a couple of times. Here I want to summarize my steps. In fact, it is nothing special, a raspberry pi that is used as a browser showing a web based dashboard in full screen, but there are some important configuration steps needed to make it as good as possible.
Install Raspbian
Raspbian is the best operating system for Raspberry Pi. Just stick with that.
Improving the web performance of an intranet
[caption id=“attachment_3437” align=“alignnone” width=“480”] All the “small” app parts, web parts, delegate controls, user controls, and other “packages” that “must” be delivered to the users on every page load of the Start Page of your Intranet.[/caption] Recently we made an investment to improve the performance of our intranet. We made many changes in different layers: SQL, Network, Browser upgrade and code. Here I want to tell about what code changes we did to improve the web browser performance. Please leave feedback if you find it useful. You can also share your suggestions. We measured the performance before our code changes and after them. We had amazing results. Unfortunately I can not share any numbers, but we improved the Time to First Byte, time to load event firing in the browser, memory consumption in the clients and, perhaps, the most important, we improved the perceived performance of the Intranet, the way how users experience the speed and UI responsiveness. To do this I got many ideas of my project colleagues and branch colleagues. Here is the list of changes we’ve implemented:
clearInterval in Chrome doesn't work on window blur
If you want to reset all interval jobs when a browser tab is inactive, the best way would be to use clearInterval on window blur. But unfortunately Chrome fires window focus and window blur two times. Here is an embryo to a solution:
var M = window.M || {};
M.counter = 0;
M.focused = true;
M.tick = function() {
if (M.focused) {
console.log("tic tac " + ++M.counter);
}
};
M.start = function(e) {
console.log("starting...");
M.focused = true;
};
M.stop = function(e) {
console.log("stopping...");
M.focused = false;
};
$(window).on({
focus: M.start,
blur: M.stop
});
M.ticker = window.setInterval(M.tick, 1000);
Tag: Dashboard
Setting up Raspberry Pi2 for a Dashboard Monitor
I have set up Raspberry Pi as a Dashboard Monitor a couple of times. Here I want to summarize my steps. In fact, it is nothing special, a raspberry pi that is used as a browser showing a web based dashboard in full screen, but there are some important configuration steps needed to make it as good as possible.
Install Raspbian
Raspbian is the best operating system for Raspberry Pi. Just stick with that.
Tag: Iceweasel
Setting up Raspberry Pi2 for a Dashboard Monitor
I have set up Raspberry Pi as a Dashboard Monitor a couple of times. Here I want to summarize my steps. In fact, it is nothing special, a raspberry pi that is used as a browser showing a web based dashboard in full screen, but there are some important configuration steps needed to make it as good as possible.
Install Raspbian
Raspbian is the best operating system for Raspberry Pi. Just stick with that.
Tag: Kbd
Chuvash Keyboard Layout for Mac
I’ve got a Mac and one of my first questions was: How can I write in Chuvash on my Mac, obviously :) In this post I am going to tell how I created Chuvash Keyboard Layout. The solution and installation instructions are on Github: Chuvash Keyboard Layout for Mac
What the heck is Chuvash?
For those who don’t know yet: Chuvash are people who live in Chuvash Republic in Russian Federation, and abroad, as me. We are 1.5 million. Chuvash is also a language, an official language of the Republic, a minority language, that is completely different from the second official language Russian. Chuvash uses Cyrillic letters, all 33 Russian letters plus 4 additional letters: A breve (Ӑ), E breve (Ӗ), C cedilla (Ҫ) and U with double acute (Ӳ).
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Keyboard
Chuvash Keyboard Layout for Mac
I’ve got a Mac and one of my first questions was: How can I write in Chuvash on my Mac, obviously :) In this post I am going to tell how I created Chuvash Keyboard Layout. The solution and installation instructions are on Github: Chuvash Keyboard Layout for Mac
What the heck is Chuvash?
For those who don’t know yet: Chuvash are people who live in Chuvash Republic in Russian Federation, and abroad, as me. We are 1.5 million. Chuvash is also a language, an official language of the Republic, a minority language, that is completely different from the second official language Russian. Chuvash uses Cyrillic letters, all 33 Russian letters plus 4 additional letters: A breve (Ӑ), E breve (Ӗ), C cedilla (Ҫ) and U with double acute (Ӳ).
A new Chuvash keyboard layout
The Chuvash keyboard layout has been the Russian keyboard layout with 4 Chuvash letters that are typed by pressing the right Alt button plus the base letter. Some of the arguments have been
- Users don’t need to switch or learn a new keyboard layout. They can keep on typing Russian texts and sometimes Chuvash texts
- It is easy to communicate about how the right Alt button works. The Right-Alt-technique is also used in Esperanto, Polish and other languages.
- The letters are placed according the labels
Recently two major events happened that made the question about the Chuvash keyboard layout important:
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
It is time to standardize the Chuvash Keyboard Layout
[caption id=“attachment_3165” align=“alignnone” width=“630”] Proto-Bulgarian Runes (Chuvash language is the closest language to the Proto-Bulgar language). Wonder if they are supported in Unicode :)[/caption] The Chuvash Computer Keyboard layouts have existed since 2001, but due to the lack for Unicode support we were forced to use the look-alike letters from other latin-based keyboard layouts. On Linux The Chuvash keyboard layout was added in [2007](https://bugs.freedesktop.org/show_bug.cgi?id=11246 “The original “bug” in FreeDesktop bugzilla”) and Linux is still the only operating system that has a native keyboard layout for Chuvash language. On Windows we have used the Keyboard Layout Creator and distributed it as an executable file. Today, when Windows XP is not supported anymore, the majority of users now have full support for the correct Chuvash letters from the Extended Cyrillic table. These four Chuvash letters are “additional” to the Russian alphabet: Ӑ, Ӗ, Ҫ and Ӳ. Now when new “keyboards” appear on Android, in web browser (they use the standardized letters) and hopefully in Windows and iOS, we have to consider put the correct letters into the keyboard layouts. For Linux the /usr/share/X11/xkb/symbols/ru
file has to be updated: [code] // Chuvash language layout // Anatoly Mironov @mirontoli partial alphanumeric_keys xkb_symbols “cv” { include “ru(winkeys)” name[Group1]= “Chuvash”; key.type[group1]=“FOUR_LEVEL”; key { [ Cyrillic_u, Cyrillic_U, 0x010004f3, 0x010004f2 ] }; key { [ Cyrillic_ie, Cyrillic_IE, 0x010004d7, 0x010004d6 ] }; key { [ Cyrillic_a, Cyrillic_A, 0x010004d1, 0x010004d0 ] }; key { [ Cyrillic_es, Cyrillic_ES, 0x010004ab, 0x010004aa ] }; include “level3(ralt_switch)” }; [/code]
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Chuvash Keyboard for Android
Now there is a Chuvash keyboard for Android. The little program uses AnySoftKeyboard application, gives the ability to write in Cyrillic and Latin. All kinds of feedback are appreciated. Chuvash Keyboard for Android is open source like AnySoftKeyboard.
Tag: Keyboard Layout
Chuvash Keyboard Layout for Mac
I’ve got a Mac and one of my first questions was: How can I write in Chuvash on my Mac, obviously :) In this post I am going to tell how I created Chuvash Keyboard Layout. The solution and installation instructions are on Github: Chuvash Keyboard Layout for Mac
What the heck is Chuvash?
For those who don’t know yet: Chuvash are people who live in Chuvash Republic in Russian Federation, and abroad, as me. We are 1.5 million. Chuvash is also a language, an official language of the Republic, a minority language, that is completely different from the second official language Russian. Chuvash uses Cyrillic letters, all 33 Russian letters plus 4 additional letters: A breve (Ӑ), E breve (Ӗ), C cedilla (Ҫ) and U with double acute (Ӳ).
A new Chuvash keyboard layout
The Chuvash keyboard layout has been the Russian keyboard layout with 4 Chuvash letters that are typed by pressing the right Alt button plus the base letter. Some of the arguments have been
- Users don’t need to switch or learn a new keyboard layout. They can keep on typing Russian texts and sometimes Chuvash texts
- It is easy to communicate about how the right Alt button works. The Right-Alt-technique is also used in Esperanto, Polish and other languages.
- The letters are placed according the labels
Recently two major events happened that made the question about the Chuvash keyboard layout important:
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
It is time to standardize the Chuvash Keyboard Layout
[caption id=“attachment_3165” align=“alignnone” width=“630”] Proto-Bulgarian Runes (Chuvash language is the closest language to the Proto-Bulgar language). Wonder if they are supported in Unicode :)[/caption] The Chuvash Computer Keyboard layouts have existed since 2001, but due to the lack for Unicode support we were forced to use the look-alike letters from other latin-based keyboard layouts. On Linux The Chuvash keyboard layout was added in [2007](https://bugs.freedesktop.org/show_bug.cgi?id=11246 “The original “bug” in FreeDesktop bugzilla”) and Linux is still the only operating system that has a native keyboard layout for Chuvash language. On Windows we have used the Keyboard Layout Creator and distributed it as an executable file. Today, when Windows XP is not supported anymore, the majority of users now have full support for the correct Chuvash letters from the Extended Cyrillic table. These four Chuvash letters are “additional” to the Russian alphabet: Ӑ, Ӗ, Ҫ and Ӳ. Now when new “keyboards” appear on Android, in web browser (they use the standardized letters) and hopefully in Windows and iOS, we have to consider put the correct letters into the keyboard layouts. For Linux the /usr/share/X11/xkb/symbols/ru
file has to be updated: [code] // Chuvash language layout // Anatoly Mironov @mirontoli partial alphanumeric_keys xkb_symbols “cv” { include “ru(winkeys)” name[Group1]= “Chuvash”; key.type[group1]=“FOUR_LEVEL”; key { [ Cyrillic_u, Cyrillic_U, 0x010004f3, 0x010004f2 ] }; key { [ Cyrillic_ie, Cyrillic_IE, 0x010004d7, 0x010004d6 ] }; key { [ Cyrillic_a, Cyrillic_A, 0x010004d1, 0x010004d0 ] }; key { [ Cyrillic_es, Cyrillic_ES, 0x010004ab, 0x010004aa ] }; include “level3(ralt_switch)” }; [/code]
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Ukulele
Chuvash Keyboard Layout for Mac
I’ve got a Mac and one of my first questions was: How can I write in Chuvash on my Mac, obviously :) In this post I am going to tell how I created Chuvash Keyboard Layout. The solution and installation instructions are on Github: Chuvash Keyboard Layout for Mac
What the heck is Chuvash?
For those who don’t know yet: Chuvash are people who live in Chuvash Republic in Russian Federation, and abroad, as me. We are 1.5 million. Chuvash is also a language, an official language of the Republic, a minority language, that is completely different from the second official language Russian. Chuvash uses Cyrillic letters, all 33 Russian letters plus 4 additional letters: A breve (Ӑ), E breve (Ӗ), C cedilla (Ҫ) and U with double acute (Ӳ).
Tag: Add-In
My first Office Add-In
Yesterday I participated in the Hackathon at European SharePoin Conference in Stockholm. The main goal was to learn more about Office Add-Ins. I wanted to create a very very simple app to learn the basics. Here in this post I’ll provide some links and describe the steps needed to start developing your Office Add-Ins. The Add-in I created is an Outlook Add-In, it is called “Joke Inserter” and with it you can insert a random Chuck Norris joke. It is just for fun, but it demonstrated how an add-in can be installed, made available in “New E-mail” and interact with the e-mail you are writing.
Onpremifying SharePoint apps
We want to make an app available in SharePoint OnPrem, we want to onpremify it. Rethink SharePoint apps and provisioning SharePoint artifacts. It has been a while since I updated my blog – Chuvash.eu. I had my vacation, I visited the sunny and green Chuvashia. Now I am back and I am looking forward to an awesome SharePoint Autumn. One of the first things I had to deal with in this SharePoint Autumn was Onpremifying of a SharePoint Online App. We have an app that has gained popularity and we want to make it available for SharePoint OnPrem. There is no such word Onpremify (yet?), I know, it is a Swenglish happy word making (onpremifiera), but I like the word “onpremify” a lot. There is still uncertainty around the purpose of SharePoint apps. One app type, though, has been used a lot in our company: an app that provisions SharePoint Artifacts – that creates SharePoint Applications. What I mean by SharePoint Applications can be read in my blog post:
Tag: Apps
My first Office Add-In
Yesterday I participated in the Hackathon at European SharePoin Conference in Stockholm. The main goal was to learn more about Office Add-Ins. I wanted to create a very very simple app to learn the basics. Here in this post I’ll provide some links and describe the steps needed to start developing your Office Add-Ins. The Add-in I created is an Outlook Add-In, it is called “Joke Inserter” and with it you can insert a random Chuck Norris joke. It is just for fun, but it demonstrated how an add-in can be installed, made available in “New E-mail” and interact with the e-mail you are writing.
What is a SharePoint application
[caption id=“attachment_3759” align=“alignnone” width=“660”] A meaningful collection of Lego bricks is a toy. A meaningful collection of Lists, Fields, Files and other SharePoint artefacts becomes a SharePoint Application. Private picture.[/caption] App, Add-In, List, Web, Site, Sandbox solution, Workflow. There are too many words flying around in SharePoint that confuse users and Non-SharePoint-Developers. I want to introduce a “new” concept that is so simple and that a company can understand and govern: a SharePoint Application. That is so simple. It can be called a tool, a functionality. That can be a SharePoint list, a document library with a workflow, or a document library with custom jslink. All they can be SharePoint Applications. Let’s use lego as a metaphor. Have you seen this? [caption id=“attachment_3760” align=“alignnone” width=“660”] The same toy car in just brics. SharePoint Artefacts like Webs, Lists, Fields, Content Types, JSLink etc are just lego bricks. Private picture.[/caption] These lego bricks together become a cool toy that you can play with (as you can see in the picture above). So it is with SharePoint Applications, too. SharePoint Applications solve actual business needs. A List, or a JSLink by themselves do not solve a business need. It must be a meaningful collection of SharePoint Artefacts that becomes a SharePoint Application. Example Does the lego metaphor make sense to you? To go back to SharePoint, I’ll give you an example of a SharePoint Application. I would say everybody has done such Applications. In a project we created a document library for product icons that were used for all products in a company. Easy? Yes. But the icons had several states (active, inactive…). Versioning and Approval was required. A workflow for new requests and submits was implemented, too, permissions for different roles, metadata navigation in the document library and so on. Sure, SharePoint provided us with great “lego bricks”. But we created a tool, a functionality - a SharePoint Application, that makes sense to our business. What’s new then? Well, we all have done such applications. The new is to understand SharePoint Applications as an own alternative and quality assurance. See more below. Another example is an “App” for SharePoint Online that I converted into a SharePoint Application by adjusting it for SPO and OnPrem. That’s when I came up with the idea of the SharePoint Application. Definition
Http to Https Redirect in Provider Hosted Apps
It is strongly recommended to use https in SharePoint Provider Hosted Apps. In many provider hosted apps I have seen, only https works. I would recommend to configure a simple http to https redirect in IIS and make solutions better. Many Provider Hosted Apps can be done in that way that they are available without SharePoint Context, e.g. for browsing information. In that case that is important to have an easy url and an automatic http -> https redirect. In this post I’ll give a short manual for doing that. I would recommend this step for all provider hosted apps. 1. In the Provider Hosted Apps Server install the URL Rewrite IIS Module using Web Platform Installer: 2. Next step is to add the http binding to your solution (this is needed for the future redirect): Then you can configure the automatic http to https redirect using the GUI or the web.config update. My instructions originally come from JPPInto.com blog. I suggest updating the web.config file directly in the Provider Hosted App: 3. Add this section to the web.config file: [source language=“xml”] <system.webServer> </system.webServer> [/source] It is important to know that his web.config section will cause failure on the server if URL Rewrite module is not installed. Summary These steps are very easy to accomplish and I recommend it for every Provider Hosted App, especially those ones that are accessible without going through SharePoint (Web Content -> Apps). This also reflects the configurations in Azure Apps (WebSites).
Kom igång med SPMeta2
SPMeta2 (eller bara M2) är ett relativt nytt ramverk för provisionering av SharePoint-artefakter. Bakom ramverket ligger ett gediget arbete. I den här posten vill jag skriva upp mina steg för att sätta upp ett litet projekt. För mig är SPMeta2 nytt och huvudprincipen i den här bloggposten att få en fungerande lösning så snabbt som möjligt. Informationen här kan snabbt bli inaktuell, eftersom SPMeta2 förändras och förbättras väldigt snabbt. Vad är SPMeta2 SPMeta är ett ramverk för att provisionera SharePoint-artefakter, allt från fält, innehållstyper, listor, dokumentbibliotek, user custom actions, ladda upp filer med mera. Klassiskt har vi gjort provisionering med hjälp av XML-baserade moduler och features. SPMeta2 erbjuder ett Fluent API som är kodbaserat. Med hjälp av SPMeta2 definierar man en modell (enkla objekt POCOs) som inte har beroendet till SharePoint. Modellen används sedan av Provision-delen som anropar modellen för specifika versioner: SharePoint 2013, SharePoint 2010, Office 365 med mera. Man kan välja CSOM och SSOM. Provision är också flexibel vad som gäller paketering: det kan vara en konsolapplikation, en SharePoint-app, ett wsp-paket, en PowerShell-modul. Se följande länkar:
Onpremifying SharePoint apps
We want to make an app available in SharePoint OnPrem, we want to onpremify it. Rethink SharePoint apps and provisioning SharePoint artifacts. It has been a while since I updated my blog – Chuvash.eu. I had my vacation, I visited the sunny and green Chuvashia. Now I am back and I am looking forward to an awesome SharePoint Autumn. One of the first things I had to deal with in this SharePoint Autumn was Onpremifying of a SharePoint Online App. We have an app that has gained popularity and we want to make it available for SharePoint OnPrem. There is no such word Onpremify (yet?), I know, it is a Swenglish happy word making (onpremifiera), but I like the word “onpremify” a lot. There is still uncertainty around the purpose of SharePoint apps. One app type, though, has been used a lot in our company: an app that provisions SharePoint Artifacts – that creates SharePoint Applications. What I mean by SharePoint Applications can be read in my blog post:
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
What about the SharePoint app domain?
This is an open question about the domains for SharePoint apps. On Technet: Configure an environment for apps for SharePoint (SharePoint 2013) we can read the following:
You must configure a new name in Domain Name Services (DNS) to host the apps. To help improve security, the domain name should not be a subdomain of the domain that hosts the SharePoint sites. For example, if the SharePoint sites are at Contoso.com, consider ContosoApps.com instead of App.Contoso.com as the domain name.
My five takeaways from the SharePoint Conference 2014
The SharePoint Conference 2014 was an astounding event. Over 10 000 like-minded SharePointers that met, learned a lot and shared new ideas, couldn’t be better. It was also the first time I was to the U.S. and Las Vegas. What a country, what a city! This place must burn people’s lives faster than anywhere else in the world :) I want to share my five takeaways from this conference. I’ll keep it short:
Apps can only call the OOB CSOM and REST endpoints
As a SharePoint architect or a SharePoint developer, you must have been thinking about the benefits/limitations of SharePoint apps a lot. I want to point out one of them today, which is very important: using custom webservices deployed to SharePoint inside apps. That is impossible and it is designed to be so due to the security architecture in the sharepoint app framework. I have read much about SharePoint apps (books, whitepapers, blog posts) and stumbled over these two contradictive statements:
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
SharePoint Apps: "Provider Hosted First" Approach
Recently I had an exciting mail conversation with Thomas Deutsch. He came up with an idea how to fasten the development of apps. This smart approach is called “Provider Hosted First”. See Thomas’ original blog post. Here are some highlights: What you actually do is a local website which runs in grunt server
:
localhost:9000
```Then a SharePoint-hosted app is created with an SPAppIframe that refers to that local app site. Genious!!! Some key features of this approach:
* This local app contains a livereload script. Your sharepoint app is updated every time you save your css, js, html file in your IDE
* Grunt minifies, bundles your assets
* Grunt runs your tests automatically when your content is modified
* The SharePoint app can be on Premises, on Office 365, wherever you want it.
#### Video
\[caption id="attachment\_2808" align="alignnone" width="630"\][![See the video how it looks like to develop using this approach](https://sharepointkunskap.files.wordpress.com/2013/07/sp-app-002.png?w=630)](http://www.screenr.com/LA8H) See the video how it looks like to develop using this approach\[/caption\]
## Comments from Wordpress.com
####
[Paul Tavares](http://paultavares.wordpress.com "paultavares1@gmail.com") - <time datetime="2013-07-10 02:59:34">Jul 3, 2013</time>
This is pretty cool and very similar to my current setup for developing javascript applications for SharePoint. I use a script to "deploy" updates from my PC to the folder in a document library. I'll try this out when I get around to playing with SP2013.
<hr />
####
[Björn]( "bjorn.roberg@bool.se") - <time datetime="2013-07-02 11:07:08">Jul 2, 2013</time>
Awesome! I'm gonna try that out!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-07-02 15:31:33">Jul 2, 2013</time>
Great! When you go to Thomas Deutsch blog, you can download the source code for the solution.
<hr />
Tag: Sharepoint2013
My first Office Add-In
Yesterday I participated in the Hackathon at European SharePoin Conference in Stockholm. The main goal was to learn more about Office Add-Ins. I wanted to create a very very simple app to learn the basics. Here in this post I’ll provide some links and describe the steps needed to start developing your Office Add-Ins. The Add-in I created is an Outlook Add-In, it is called “Joke Inserter” and with it you can insert a random Chuck Norris joke. It is just for fun, but it demonstrated how an add-in can be installed, made available in “New E-mail” and interact with the e-mail you are writing.
Export Any Web Part using a Bookmarklet
My blog post about exporting any webpart from a SharePoint Page is one of the most read articles on my blog. I use this method a lot. Now what I want to do is to simplify the process. Inspired by my colleague Dan Saedén’s awesome bookmarklet for reading and updating web properties, I decided to make my own bookmarklet. That was easy. Now we can export any web part from any SharePoint page without even looking at any ids in the html markup and assembling the export url manually. Just add the bookmarklet or run the javascript code in the browser console. The code (js and bookmarklet) is on Github. Here is an animated gif that explains how to use it:
Add Search Verticals by code
Adding own search verticals is a common task in the Search Configuration in SharePoint. Here I want to share a code sample for achieving this programmatically. I hope, this model can be added to SPMeta2. First of all, Search Verticals are dedicated Search Results Pages and links to them. How to add them manually is described on technet:
There is no API in CSOM for that. Luckily, Mikael Svenson found how to get the Search Navigation and contributed to PnP by writing an Extension: web.LoadSearchNavigation. Here is my sample code for adding new Search Verticals programmatically: [source language=“csharp”] NavigationNode searchNav = context.Web.Navigation.GetNodeById(1040); NavigationNodeCollection nodeCollection = searchNav.Children; NavigationNodeCreationInformation everything = new NavigationNodeCreationInformation { Title = “Everyting”, Url = “/search/Pages/results.aspx”, }; NavigationNodeCreationInformation myresults = new NavigationNodeCreationInformation { Title = “My Results”, Url = “/search/Pages/myresults.aspx”, }; nodeCollection.Add(everything); nodeCollection.Add(myresults); context.ExecuteQuery(); [/source]
What is a SharePoint application
[caption id=“attachment_3759” align=“alignnone” width=“660”] A meaningful collection of Lego bricks is a toy. A meaningful collection of Lists, Fields, Files and other SharePoint artefacts becomes a SharePoint Application. Private picture.[/caption] App, Add-In, List, Web, Site, Sandbox solution, Workflow. There are too many words flying around in SharePoint that confuse users and Non-SharePoint-Developers. I want to introduce a “new” concept that is so simple and that a company can understand and govern: a SharePoint Application. That is so simple. It can be called a tool, a functionality. That can be a SharePoint list, a document library with a workflow, or a document library with custom jslink. All they can be SharePoint Applications. Let’s use lego as a metaphor. Have you seen this? [caption id=“attachment_3760” align=“alignnone” width=“660”] The same toy car in just brics. SharePoint Artefacts like Webs, Lists, Fields, Content Types, JSLink etc are just lego bricks. Private picture.[/caption] These lego bricks together become a cool toy that you can play with (as you can see in the picture above). So it is with SharePoint Applications, too. SharePoint Applications solve actual business needs. A List, or a JSLink by themselves do not solve a business need. It must be a meaningful collection of SharePoint Artefacts that becomes a SharePoint Application. Example Does the lego metaphor make sense to you? To go back to SharePoint, I’ll give you an example of a SharePoint Application. I would say everybody has done such Applications. In a project we created a document library for product icons that were used for all products in a company. Easy? Yes. But the icons had several states (active, inactive…). Versioning and Approval was required. A workflow for new requests and submits was implemented, too, permissions for different roles, metadata navigation in the document library and so on. Sure, SharePoint provided us with great “lego bricks”. But we created a tool, a functionality - a SharePoint Application, that makes sense to our business. What’s new then? Well, we all have done such applications. The new is to understand SharePoint Applications as an own alternative and quality assurance. See more below. Another example is an “App” for SharePoint Online that I converted into a SharePoint Application by adjusting it for SPO and OnPrem. That’s when I came up with the idea of the SharePoint Application. Definition
Http to Https Redirect in Provider Hosted Apps
It is strongly recommended to use https in SharePoint Provider Hosted Apps. In many provider hosted apps I have seen, only https works. I would recommend to configure a simple http to https redirect in IIS and make solutions better. Many Provider Hosted Apps can be done in that way that they are available without SharePoint Context, e.g. for browsing information. In that case that is important to have an easy url and an automatic http -> https redirect. In this post I’ll give a short manual for doing that. I would recommend this step for all provider hosted apps. 1. In the Provider Hosted Apps Server install the URL Rewrite IIS Module using Web Platform Installer: 2. Next step is to add the http binding to your solution (this is needed for the future redirect): Then you can configure the automatic http to https redirect using the GUI or the web.config update. My instructions originally come from JPPInto.com blog. I suggest updating the web.config file directly in the Provider Hosted App: 3. Add this section to the web.config file: [source language=“xml”] <system.webServer> </system.webServer> [/source] It is important to know that his web.config section will cause failure on the server if URL Rewrite module is not installed. Summary These steps are very easy to accomplish and I recommend it for every Provider Hosted App, especially those ones that are accessible without going through SharePoint (Web Content -> Apps). This also reflects the configurations in Azure Apps (WebSites).
Kom igång med SPMeta2
SPMeta2 (eller bara M2) är ett relativt nytt ramverk för provisionering av SharePoint-artefakter. Bakom ramverket ligger ett gediget arbete. I den här posten vill jag skriva upp mina steg för att sätta upp ett litet projekt. För mig är SPMeta2 nytt och huvudprincipen i den här bloggposten att få en fungerande lösning så snabbt som möjligt. Informationen här kan snabbt bli inaktuell, eftersom SPMeta2 förändras och förbättras väldigt snabbt. Vad är SPMeta2 SPMeta är ett ramverk för att provisionera SharePoint-artefakter, allt från fält, innehållstyper, listor, dokumentbibliotek, user custom actions, ladda upp filer med mera. Klassiskt har vi gjort provisionering med hjälp av XML-baserade moduler och features. SPMeta2 erbjuder ett Fluent API som är kodbaserat. Med hjälp av SPMeta2 definierar man en modell (enkla objekt POCOs) som inte har beroendet till SharePoint. Modellen används sedan av Provision-delen som anropar modellen för specifika versioner: SharePoint 2013, SharePoint 2010, Office 365 med mera. Man kan välja CSOM och SSOM. Provision är också flexibel vad som gäller paketering: det kan vara en konsolapplikation, en SharePoint-app, ett wsp-paket, en PowerShell-modul. Se följande länkar:
Method "GetList" does not exist
I troubleshooted a piece of CSOM code in SharePoint 2013. I got the following error:
Method “GetList” does not exist
The reason was that the method GetList was not imlemented until March 2015 CU (15.0.4701.1001), and the SharePoint farm I had was SharePoint 2013 SP1 (15.0.4569.1000). So the solution is to install the Cumulative Update or use web.Lists.GetByTitle. GetByTitle has one aweful shortcoming: it doesn’t work in multilingual environments. So I have recommended to install the March 2015 CU.
Onpremifying SharePoint apps
We want to make an app available in SharePoint OnPrem, we want to onpremify it. Rethink SharePoint apps and provisioning SharePoint artifacts. It has been a while since I updated my blog – Chuvash.eu. I had my vacation, I visited the sunny and green Chuvashia. Now I am back and I am looking forward to an awesome SharePoint Autumn. One of the first things I had to deal with in this SharePoint Autumn was Onpremifying of a SharePoint Online App. We have an app that has gained popularity and we want to make it available for SharePoint OnPrem. There is no such word Onpremify (yet?), I know, it is a Swenglish happy word making (onpremifiera), but I like the word “onpremify” a lot. There is still uncertainty around the purpose of SharePoint apps. One app type, though, has been used a lot in our company: an app that provisions SharePoint Artifacts – that creates SharePoint Applications. What I mean by SharePoint Applications can be read in my blog post:
Why Swedish matters
I Sverige är engelskan är väldigt stark. Speciellt i IT-branschen är vi vana att ha i princip allt på engelska, från kommentarer i koden till stora upphandlingar, rapporter och dokumentation. Trots det ser jag ett stort behov av att kunna prata om IT på svenska. Det gäller både lokala företag och globala företag. Det finns flera anledningar:
- Företag i Sverige följer svenska lagar som är skrivna på svenska, för att leva upp till kraven ska man kunna formulera sig på svenska.
- Modersmål eller det språk som man använder mest i vardagen (gäller mig bland annat) är den snabbaste vägen för kommunikation som ger en högre grad av nyansering. Att kunna nyansera krav och önskemål tidigt i projekt är guld värt (enligt många av mina korrespondenter). Man behöver spendera mindre tid på att formulera och tolka krav.
- En mer ideologisk anledning (men en viktig sådan) är att vi som bor i Sverige har skyldighet att utveckla och hålla svenskan levande, inte minst inom IT-sektorn.
Svenska är en stor möjlighet för att verkligen ge mervärde till våra kunder, möta dem på hemmaplan, prata ett gemensamt språk. Startpunkten till den här diskussionen har varit en ny webinar som jag planerar hålla den 14 april kl 10. Webinarens titel är SharePoint i molnet.Det finns ganska mycket information om SharePoint Online och Office 365 på engelska. Det är dock ganska sparsamt med information på svenska. https://www.eventbrite.com/e/sharepoint-i-molnet-tickets-15976529229 Det här är det som väntar dig som vill delta i webinaren:
Publishing Visio diagrams as html image maps
I got a question from a customer: We have our processes defined in Visio, we don’t have SharePoint Enterprise CALs to use the Visio webpart. We have links in process maps. What can we do? Well there are three five ways to solve this business need:
- Find money for SharePoint Enterprise - Very expensive
- Show Visio diagrams as pdf files on SharePoint Pages - Expensive.
- Embed Visio diagrams as html image maps - Least expensive
- Embed Visio diagrams as svg pictures - Separate blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
If the business needs other features available only in Enterprise, just use the solution 1. Stop reading. If you are looking for alternatives, then consider pdf and image maps. I have seen projects where pdf files were embedded in the SharePoint Pages. It required a pdf plugin in IE, a lot of time to make it look the same in different browsers and the scroll and fixed size was still there. It was expensive because of the development and configuration time. In this blog post, I want to show the alternative number 3: embedding Visio diagrams as html image maps. This is only a Proof-of-concept so far.
Struggling with Taxonomy in CSOM
The parts of the CSOM for updating Taxonomy fields are really cumbersome. I mean, look at this code, nicely provided by Vadim Gremyshev (@vgrem). To set a value in a taxonomy field we have to assemble a text representation, and adding a “fake” lookup id. What is needed is a wrapper for handling Taxonomy fields. SPMeta2 and PnP don’t seem to have it yet. Another issue that I have struggled with today was the missing Microsoft.SharePoint.Client.Taxonomy.dll. If you see this error (set customErrors=“Off” in the Web.config), then you have update the reference in the Visual Studio project: Open Properties for the reference called: Microsoft.SharePoint.Client.Taxonomy and ensure that Copy To Local is set to True: For some reason, this reference added through “App for SharePoint Web Toolkit” nuget package adds a reference to an assembly from your computers GAC.
Bypass all custom jslink
Client Side Rendering (CSR) and jslink are great for customizing lists and forms in SharePoint. In my current project we use it a lot of it. A disadvantage of that path, although, is that it might occur javascript errors, during the development phase, but also in production. We do, of course, our best to leverage the best jslink code, but unfortunately we have to live with the fact that errors can occur, especially when we use it for NewForm, EditForm, DisplayForm and View (in list and grid). If an error occurs, it won’t stop the rest of javascript (it is wrapped in try and catch by SharePoint), but the fields will still not function as intended. It can also be some “corrupt” or old data in the field value that will “break” the jslink code. I would like to suggest one little fix, an idea I’ve come up to in my jslink-heavy project:
Client Side Rendering with Async dependencies
Yesterday I asked a question on SharePoint StackExchange:
I also asked Elio Struyf on Twitter: https://twitter.com/eliostruyf/status/540473976255152128 Good idea, Elio Struyf! Now I want to try it out.
Preparations
In this case I’ll be using my example from my blog post yesterday: Drag and Drop Image using Client Side Rendering I have created a new list and added a lookup field to my previous list. What I get is a Title of the lookup item, but not my custom field called DragAndDrop. In my test I will try to load the DragAndDrop Image using an ajax call and rendering it after Client Side Rendering is done with my item. To be complete, I want to show some screenshots for my lookup field: It will result in this OOTB rendering:
Drag and Drop Image using Client Side Rendering
I continue my series about Client Side Rendering (CSR) and jsgrid. Today I want to try a custom field where users can drag and drop images. The inspiration comes from:
- AutoUpload field written by Anton Vishnyakov and
- Base64 Drag and drop written by oroboto
What I want to achieve is:
- A custom field that is rendered with jslink
- Users can drag and drop small pictures (thumbnails) into the field
- A base64 image representation is saved as the field value
- Optionally implement pasting images using Clipboard API
Step 1 Create a field with a custom jslink
Create a field of type Note. I am using the PnP Core Extensions to make it quickier: ’ My jslink file is very simple to begin with: [code language=“javascript”] (function () { ‘use strict’; function view(ctx, field) { return “hello”; } var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘DragAndDropImage’: { ‘View’: view, ‘DisplayForm’: view //‘EditForm’: verySimpleNewAndEdit, //‘NewForm’: verySimpleNewAndEdit } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] This will result in the following display form. Just outputting “hello” indicates that my field is jslink are registered correctly:
Disabling a column in Quick Edit
In my project I have a column called Request Status. This column is not shown in any forms, meaning users should not edit, because it is controlled through the app. Nevertheless it is editable in the Quick Edit. Yesterday I wrote about jsgrid in my blog. Now comes more. Today I’ll share a little practical solution how one can disable editing a field in Quick Edit. The field is edited in jsgrid, but to disable it, we only have set the property called AllowGridEditing to false on our column (not even touching the heavy jsgrid api). We can do in the OnPreRender event in our Client Side Rendering (CSR) registration. Having the context object we have access to the Fields (ContextInfo.ListSchema.Field): [code language=“javascript” highlight=“6,9”] (function () { var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.OnPreRender = function(ctx) { var statusField = ctx.ListSchema.Field.filter(function(f) { return f.Name === ‘Request_x0020_Status’; }); if (statusField) { statusField[0].AllowGridEditing = false; } } SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] Another way is to implement the display form: [code language=“javascript”] (function () { var view = function (ctx, field) { if (ctx.inGridMode) { field.AllowGridEditing = false; } return window.RenderFieldValueDefault(ctx); }; var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘Request_x0020_Status’: { ‘View’: view } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code]
JSGrid Basics
JSGrid is the javascript framework in SharePoint used in Quick Edit View (previously Datasheet View). There are a few very good blog posts on this topic (See below in “Sources”). Nevertheless the fact is that jsgrid and working with quick edit from a developer’s perspective is a huge undiscovered area. Articles I have seen are intended for advanced developers. The goal with my post today is to outline the very basics of working with JSGrid. When you know the basics you will be more comfortable to discover and try out more. The example I want to show is a jsgrid code for a “VerySimpleColumn”. The source code can be found on gist.github.com To focus on jsgrid, I assume you have knowledge and some experience of working with jslink, which is related to jsgrid.
Do not mess with the hive
In our Intranet we got this nasty double encoding error that was introduced in SharePoint April 2014 CU. In July 2014 CU the problem is still there. I often hear the suggestions to update files directly in the hive (the root folder for SharePoint: C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\) In that blog post it is described what the problem is and what files are affected and what code must be altered in order to get it to work (which I like). But it is also suggested to update the Search.ClientControls.js directly on the server (which I don’t like). So my advise is:
Showing Birthdays and Job Anniversaries in the Newsfeed
In our project we have a requirement to show birthdays and job anniversaries in the Newsfeed. The solution is simple (when you know it) but there has not been any information about it online, until today. I want to share a few lines of PowerShell code to enable Anniversary notifications in the Newsfeed. This desired piece of code was written by my colleague Emma Degerman. Enjoy:
[source language=“PowerShell”] $job = Get-SPTimerJob | ? { $_.TypeName -like “*.UserProfileChangeJob” } $job.GenerateAnniversaries = $true $job.Schedule = [Microsoft.SharePoint.SPSchedule]::FromString(“hourly between 55 and 55”) $job.Update() [/source]
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
GeoLocation Field in SharePoint 2013
In SharePoint 2013 Preview there is a new type of field: GeoLocation which is, like the old SPUrlField, a pair of values. The geolocation is described as longitude and latitude. Unfortunately you can’t add this field in list settings. You have to create this in code. In the provided link you can find the code C# code which uses the Client Object Model. In another link you can find an example how to create the geolocation file using Server Object Model (in FeatureActivated EventReceiver). If you know me, you might already know that I will propose a JavaScript solution. Here is the code to create a geolocation field in an existing list using JSOM:
Tag: Extension
Working with resx files in Visual Studio
Today I found a nice Visual Studio Extension for working with localization and resx files: Resx Resource Manager. This extension provides an additional view in your project and scans all the resx files. I would recommend it to all projects where you have to translate your interface. Here is how it looks in my project: It can also assist with some machine translation from Bing and MyMemory: Another good thing is the Export and Import to and from Excel. Wonderful if you need help from Non-developers.
Simplify js and css development with Web Essentials (Visual Studio Extension)
If you develop much javascript and css, this is the exension to Visual Studio you just can’t live without: Web Essentials (It is even released for VS2012). You can do many things with it. Here are two examples for simple but very useful functions: 1. Show which browsers support a css attribute: 2. Collapse javascript functions and create #region areas like in C# code: There is much more, like less and coffeescript parsing. Just check the documentation. And it is fully appliable in SharePoint development.
Do an unsafe update in a unified manner
Recently I talked about a WithWeb-pattern as described in Jonas Nilssons blog where you can isolate the disposal logic in one place. Another thing is to isolate unsafe updates:
public static class SPWebExtension
{
public static void UnsafeUpdate(this SPWeb web, Action<SPWeb> action)
{
try
{
Log.Info("Trying to do an unsafe update on a web: " + web.Title);
web.AllowUnsafeUpdates = true;
action(web);
}
catch (Exception e)
{
Log.Error(e);
}
finally
{
web.AllowUnsafeUpdates = false;
}
}
}
```The Log class is my own class which I presented in [my previous post](https://sharepointkunskap.wordpress.com/2011/09/19/a-simple-log/).
## Comments from Wordpress.com
####
[WithWeb-pattern of Jonas Nilsson « Sharepoint. Kunskap. Upptäckter på resan.](https://sharepointkunskap.wordpress.com/2011/09/15/withweb-pattern-of-jonas-nilsson/ "") - <time datetime="2011-09-21 17:28:23">Sep 3, 2011</time>
\[...\] Here I use another fancy way to consolidate the unsafe updates. \[...\]
<hr />
Check if user is in group
Use LINQ to check if user is in a group. Create an extension method.
public static bool InGroup(this SPUser user, SPGroup group)
{
return user.Groups.Cast<SPGroup>()
.Any(g => g.ID == group.ID);
}
```EDIT 2011-01-22: There is a shortcoming of this method. You won't get a user which is in group through a AD group. You'll get only users and ad groups. [But there is another method to check if a user is inside an AD group](/2012/01/16/check-if-a-user-is-in-a-ou/ "See my post about how to retrieve users from AD groups with PrincipalSearcher"). How could we combine them?... I think we must start from group this time, not from user:
public static bool HasUser(this SPGroup user, SPUser user) { var users = group.Users.Cast(); var samAccount = Regex.Replace(user.LoginName, @".*\\(.*)", “$1”, RegexOptions.None); var exists = users.Any(u => u.LoginName.Equals(user.LoginName)); if (!exists) { var ctx = new PrincipalContext(ContextType.Domain); foreach (var u in users) { var login = u.LoginName; var groupName = Regex.Replace(login, @".*\\(.*)", “$1”, RegexOptions.None); var grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName); if (grp == null) continue; var principals = grp.GetMembers(true); exists = principals.Any(p => p.SamAccountName.Equals(samAccount, StringComparison.InvariantCultureIgnoreCase)); if (exists) break; } } return exists; }
Content Type Id for Image, Audio and Video
After debugging I have found the Content Type Ids for Image, Audio and Video in the assets library. These content type ids are not present in SPBuiltInContentTypeId.
public class SPBuiltInContentTypeIdExtension
{
public static SPContentTypeId Video =
new SPContentTypeId
("0x0101009148F5A04DDD49CBA7127AADA5FB792B00291D173ECE694D56B19D111489C4369D");
public static SPContentTypeId Audio =
new SPContentTypeId
("0x0101009148F5A04DDD49CBA7127AADA5FB792B006973ACD696DC4858A76371B2FB2F439A");
public static SPContentTypeId Image =
new SPContentTypeId
("0x0101009148F5A04DDD49CBA7127AADA5FB792B00AADE34325A8B49CDA8BB4DB53328F214");
}
These three asset content types inherit from Document CT (“0x0101”) and have “0x0101009148F5A04DDD49CBA7127AADA5FB792B” in common, which is the content type id for multimedia content type. So if you want to check if it is a multimedia, use this id. You can see the content type id when you go to Site Actions - Site Settings - Content Types. Click on a content type you interested in. In the address bar of your browser find ?ctype=.
Tag: L10n
Working with resx files in Visual Studio
Today I found a nice Visual Studio Extension for working with localization and resx files: Resx Resource Manager. This extension provides an additional view in your project and scans all the resx files. I would recommend it to all projects where you have to translate your interface. Here is how it looks in my project: It can also assist with some machine translation from Bing and MyMemory: Another good thing is the Export and Import to and from Excel. Wonderful if you need help from Non-developers.
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Resx
Working with resx files in Visual Studio
Today I found a nice Visual Studio Extension for working with localization and resx files: Resx Resource Manager. This extension provides an additional view in your project and scans all the resx files. I would recommend it to all projects where you have to translate your interface. Here is how it looks in my project: It can also assist with some machine translation from Bing and MyMemory: Another good thing is the Export and Import to and from Excel. Wonderful if you need help from Non-developers.
JavaScript Localization in SharePoint
Yesterday Waldek Mastykarz published a cool post: Globalizing JavaScript in SharePoint 2013. This is a very cool technique to localize your client code in javascript and reuse your resx files in Server Side and Client Side. This is actually not new for SharePoint 2013 despite it has become more needed with the huge client focus in the new SharePoint. I have used this in SharePoint 2010 for a long time. In my blog post: ScriptResx.ashx in SharePoint I told about that technique. What I didn’t know that you can define your javascript namespace directly in the resx file. Waldek wrote in his comment that SP.Publishing.Resources.en-US.resx automatically are SP.Publishing.Resources in javascript. That was not the case for my own localization files. A simple look at SP.Publishing.Resources.en-US.resx helped: [sourcecode language=“xml”] true SP.Publishing.Resources [/sourcecode] This results in: [sourcecode language=“javascript”] _EnsureJSNamespace(‘SP.Publishing’); [/sourcecode] So what we have to do for our custom resx file is to add classFullName resheader: [sourcecode language=“xml”] Takana.Res [/sourcecode]
ResxCrunch: Localization tool
If your solution has two or more languages to support, I can recommend an open source tool ResxCrunch. Btw, you can even use ResxCrunch for localization of Android applications.
Tag: Translation
Working with resx files in Visual Studio
Today I found a nice Visual Studio Extension for working with localization and resx files: Resx Resource Manager. This extension provides an additional view in your project and scans all the resx files. I would recommend it to all projects where you have to translate your interface. Here is how it looks in my project: It can also assist with some machine translation from Bing and MyMemory: Another good thing is the Export and Import to and from Excel. Wonderful if you need help from Non-developers.
Chuvash localization of moment.js
For three months ago I added Chuvash localization of moment.js. For 16 days ago moment.js 1.7.0 was officially released which included the Chuvash translation.
Wait a sec… What is moment.js?
moment.js is the best datetime tool for javascript. It supports many languages (now even Chuvash) for displaying date and time. Another very handy functionality is showing relative time which has a simple interface: fromNow().
Here is a simple example from a web browser console:
Chuvash translation of Wikipedia Mobile
The official Wikipedia mobile app is now translated into Chuvash language and available to use:
What does Chuvash mean?
I am Chuvash. Chuvash is the name of an ethnicity which counts up to 2 milions peoply (mostly in Russia). Chuvashes talk the Chuvash language which is also an official language in Chuvash Republic (besides Russian). Chuvash language is a Turkic language and has a status “Vulnerable” in the UNESCO list of languages in danger. There is a Chuvash Wikipedia cv.wikipedia.org.
Tag: Explorer
Copy SharePoint WebDav Address to Clipboard
While configuring SharePoint sites and helping users I often use File Explorer View for editing pages, resources like css and javascript. In IE there is a dedicated button in the ribbon for that. Sometimes it works, sometimes it doesn’t, because of permissions or other restrictions. Anyway, I use Firefox and Chrome while troubleshooting and developing, so I have created a bookmarklet for copying the webdav address of a site that is open in the browser. [source language=“javascript”] var uri = _spPageContextInfo.webAbsoluteUrl.replace(/https?:\/\//i, “\\\\”).replace(/\//g, “\\”); window.prompt(“Copy to clipboard: Ctrl+C, Enter”, uri); [/source] Unfortunately, there is no copy function in javascript, the prompt solution plus Ctrl-C works fine. The bookmarklet: [source language=“html”] javascript:void%20function(){var%20o=_spPageContextInfo.webAbsoluteUrl.replace(/https%3F:\/\//i,%22\\\\%22).replace(/\//g,%22\\%22);window.prompt(%22Copy%20to%20clipboard:%20Ctrl+C,%20Enter%22,o)}(); [/source] Enjoy
Tag: File
Copy SharePoint WebDav Address to Clipboard
While configuring SharePoint sites and helping users I often use File Explorer View for editing pages, resources like css and javascript. In IE there is a dedicated button in the ribbon for that. Sometimes it works, sometimes it doesn’t, because of permissions or other restrictions. Anyway, I use Firefox and Chrome while troubleshooting and developing, so I have created a bookmarklet for copying the webdav address of a site that is open in the browser. [source language=“javascript”] var uri = _spPageContextInfo.webAbsoluteUrl.replace(/https?:\/\//i, “\\\\”).replace(/\//g, “\\”); window.prompt(“Copy to clipboard: Ctrl+C, Enter”, uri); [/source] Unfortunately, there is no copy function in javascript, the prompt solution plus Ctrl-C works fine. The bookmarklet: [source language=“html”] javascript:void%20function(){var%20o=_spPageContextInfo.webAbsoluteUrl.replace(/https%3F:\/\//i,%22\\\\%22).replace(/\//g,%22\\%22);window.prompt(%22Copy%20to%20clipboard:%20Ctrl+C,%20Enter%22,o)}(); [/source] Enjoy
PowerShell: Copy an entire document library from SharePoint 2007 to disk
For a while ago I needed to copy all files from a document library within a SharePoint 2007 site to the hard drive. So I didn’t need to copy files from SharePoint to SharePoint so I couldn’t use the stsadm -o export command or Chris O’Brien’s nice SharePoint Content Deployment Wizard. I came across the SPIEFolder application which should work with SharePoint 2007 and 2010. It has a site on codeplex: spiefolder.codeplex.com, but neither the binary nor the source code can be downloaded from there. After some searching I found the binary in the author’s skydrive. The fact that the source code was not available seemed as an disanvantage because I could not know what code was run. Nevertheless I tried it out and it didn’t work:
Tag: Google Chrome
Copy SharePoint WebDav Address to Clipboard
While configuring SharePoint sites and helping users I often use File Explorer View for editing pages, resources like css and javascript. In IE there is a dedicated button in the ribbon for that. Sometimes it works, sometimes it doesn’t, because of permissions or other restrictions. Anyway, I use Firefox and Chrome while troubleshooting and developing, so I have created a bookmarklet for copying the webdav address of a site that is open in the browser. [source language=“javascript”] var uri = _spPageContextInfo.webAbsoluteUrl.replace(/https?:\/\//i, “\\\\”).replace(/\//g, “\\”); window.prompt(“Copy to clipboard: Ctrl+C, Enter”, uri); [/source] Unfortunately, there is no copy function in javascript, the prompt solution plus Ctrl-C works fine. The bookmarklet: [source language=“html”] javascript:void%20function(){var%20o=_spPageContextInfo.webAbsoluteUrl.replace(/https%3F:\/\//i,%22\\\\%22).replace(/\//g,%22\\%22);window.prompt(%22Copy%20to%20clipboard:%20Ctrl+C,%20Enter%22,o)}(); [/source] Enjoy
Autocomplete för sökruta i Sharepoint
Ett mycket trevligt projekt: Search As You Type på Codeplex. Ladda ner textfilen och lägg till javascript och css från den filen till masterpage. Så enkelt är det. Jag har testat det genom att direkt stoppa in koden i Chrome Console.
Ladda jQuery dynamiskt till din sida
Vill du ändra innehåll, testa olika javascript-funktioner på din sida, prova något direkt i webbläsaren (utan att behöva deploya om), så är DevTools i Chrome, eller Firebug i Firefox väldigt bra verktyg. Om du har jQuery på din sida, så är det ännu bättre. Men om du inte har det, så ladda det i efterhand genom att öppna konsolen (Ctrl-Shift-J i Chrome) och kör följande rader kod (klistra in dem på en gång, och tryck på Enter):
Ctrl-Shift-J is the shit
devtools i google chrome underlättar så enormt. Lägg Ctrl-Shift-J på minnet. För då kommer du direkt till konsolen i devtools och kan testa.
Om man till exempel bara vill omdefiniera en funktion så kan man göra det direkt i webbläsarens addressruta: Inled det med javascript:function till exempel: javascript:function shout_out(greeting) {alert(greeting);};
Felsök på clientsidan med Chrome DevTools
Här är en väldigt bra video som berättar om nya devtools i Google Chrome 10. Den visar 12 tricks hur man kan underlätta felsökning av html, css och javascript. Att kunna ändra html,css och js on-the-fly är faktiskt häftigt. För mig som länge har använt Firebug i Firefox (som nu inte funkar på FF4 RC) känns devtools väldigt bra. [youtube http://www.youtube.com/watch?v=nOEw9iiopwI&w=530&h=335]
Comments from Wordpress.com
Ändra utseendet på sidan direkt i webbläsaren « Sharepoint. Kunskap. Upptäckter på resan. - Mar 1, 2011
Tag: Webdav
Copy SharePoint WebDav Address to Clipboard
While configuring SharePoint sites and helping users I often use File Explorer View for editing pages, resources like css and javascript. In IE there is a dedicated button in the ribbon for that. Sometimes it works, sometimes it doesn’t, because of permissions or other restrictions. Anyway, I use Firefox and Chrome while troubleshooting and developing, so I have created a bookmarklet for copying the webdav address of a site that is open in the browser. [source language=“javascript”] var uri = _spPageContextInfo.webAbsoluteUrl.replace(/https?:\/\//i, “\\\\”).replace(/\//g, “\\”); window.prompt(“Copy to clipboard: Ctrl+C, Enter”, uri); [/source] Unfortunately, there is no copy function in javascript, the prompt solution plus Ctrl-C works fine. The bookmarklet: [source language=“html”] javascript:void%20function(){var%20o=_spPageContextInfo.webAbsoluteUrl.replace(/https%3F:\/\//i,%22\\\\%22).replace(/\//g,%22\\%22);window.prompt(%22Copy%20to%20clipboard:%20Ctrl+C,%20Enter%22,o)}(); [/source] Enjoy
Tag: Iot
S01E01 IoT: Posting Temperature from Raspberry Pi to Azure
Recently I have looked more at IoT, Raspberry Pi in my spare time. In my blog post I want to share my experience in a series of posts. This post is about measuring temperature, humidity and pressure with Raspberry Pi 2 Model B and Sense Hat and posting this data to Azure Table Storage. I followed this tutorial for connecting to azure with python and these instructions for reading data from Sense Hat. The python script is on github. Along the way I learned that only python 2.x can be used with azure and table names cannot contain underscore (I got Bad Request error when I tried to create a table with the name “climate_data”). But overall, the process was straightforward. The temperature is not correct, maybe because the sensor is inbetween Raspberry Pi and Sense Hat where it gets warm. But it is just a Proof-of-Concept. I have used Visual Studio 2015 to see the data in Azure Table Storage. For that I needed to install Azure SDK 2.7. There are many other “explorers” for Azure Storage. Other resources Accessing Azure from Linux and Mac Improvement #1 Corrected Temperature I found a formula for calculating more correct temperature on the raspberry pi forum.
Tag: Sensehat
S01E01 IoT: Posting Temperature from Raspberry Pi to Azure
Recently I have looked more at IoT, Raspberry Pi in my spare time. In my blog post I want to share my experience in a series of posts. This post is about measuring temperature, humidity and pressure with Raspberry Pi 2 Model B and Sense Hat and posting this data to Azure Table Storage. I followed this tutorial for connecting to azure with python and these instructions for reading data from Sense Hat. The python script is on github. Along the way I learned that only python 2.x can be used with azure and table names cannot contain underscore (I got Bad Request error when I tried to create a table with the name “climate_data”). But overall, the process was straightforward. The temperature is not correct, maybe because the sensor is inbetween Raspberry Pi and Sense Hat where it gets warm. But it is just a Proof-of-Concept. I have used Visual Studio 2015 to see the data in Azure Table Storage. For that I needed to install Azure SDK 2.7. There are many other “explorers” for Azure Storage. Other resources Accessing Azure from Linux and Mac Improvement #1 Corrected Temperature I found a formula for calculating more correct temperature on the raspberry pi forum.
Tag: Sensor
S01E01 IoT: Posting Temperature from Raspberry Pi to Azure
Recently I have looked more at IoT, Raspberry Pi in my spare time. In my blog post I want to share my experience in a series of posts. This post is about measuring temperature, humidity and pressure with Raspberry Pi 2 Model B and Sense Hat and posting this data to Azure Table Storage. I followed this tutorial for connecting to azure with python and these instructions for reading data from Sense Hat. The python script is on github. Along the way I learned that only python 2.x can be used with azure and table names cannot contain underscore (I got Bad Request error when I tried to create a table with the name “climate_data”). But overall, the process was straightforward. The temperature is not correct, maybe because the sensor is inbetween Raspberry Pi and Sense Hat where it gets warm. But it is just a Proof-of-Concept. I have used Visual Studio 2015 to see the data in Azure Table Storage. For that I needed to install Azure SDK 2.7. There are many other “explorers” for Azure Storage. Other resources Accessing Azure from Linux and Mac Improvement #1 Corrected Temperature I found a formula for calculating more correct temperature on the raspberry pi forum.
Tag: .NET
Trying out Visual Studio Code on Ubuntu
I am very curious about the new .NET Core, ASP.NET 5, EF 7 and Visual Studio Code for Linux, Mac and Windows. I have tried it out on an Ubuntu 15.04 machine. The installation and configuration required a few steps, so it is not an usual “Next-next-next”-installation. But, hey, it is just a beta, a preview so far, and first of all: It worked. I am sharing a couple of screenshots and the commands I ran in the terminal, mixed with comments and links: [source language=“bash”] #install latest node and npm #https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs sudo npm install -g yo sudo npm install -g generator-aspnet # download VS Code and make a link # make a folder mkdir workspace/tryvs cd workspace/tryvs # create “src/global.json” file: # http://docs.asp.net/en/latest/tutorials/your-first-mac-aspnet.html { “sdk”: { “version”: “1.0.0-beta7” } } nano src/global.json # start VS Code # create # install omnisharp: # http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#installing-on-debian-ubuntu-and-derivatives curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh dnvm #install dnx sudo apt-get install -y libunwind8 gettext libssl-dev libcurl3-dev zlib1g libicu-dev dnvm upgrade -r coreclr cd EmptyApplication dnu restore #install libuv #http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#using-docker sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/ sudo ldconfig #build, I got an error here dnu build #start the web server dnx web [/source]
Tag: .NET Core
Trying out Visual Studio Code on Ubuntu
I am very curious about the new .NET Core, ASP.NET 5, EF 7 and Visual Studio Code for Linux, Mac and Windows. I have tried it out on an Ubuntu 15.04 machine. The installation and configuration required a few steps, so it is not an usual “Next-next-next”-installation. But, hey, it is just a beta, a preview so far, and first of all: It worked. I am sharing a couple of screenshots and the commands I ran in the terminal, mixed with comments and links: [source language=“bash”] #install latest node and npm #https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs sudo npm install -g yo sudo npm install -g generator-aspnet # download VS Code and make a link # make a folder mkdir workspace/tryvs cd workspace/tryvs # create “src/global.json” file: # http://docs.asp.net/en/latest/tutorials/your-first-mac-aspnet.html { “sdk”: { “version”: “1.0.0-beta7” } } nano src/global.json # start VS Code # create # install omnisharp: # http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#installing-on-debian-ubuntu-and-derivatives curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh dnvm #install dnx sudo apt-get install -y libunwind8 gettext libssl-dev libcurl3-dev zlib1g libicu-dev dnvm upgrade -r coreclr cd EmptyApplication dnu restore #install libuv #http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#using-docker sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/ sudo ldconfig #build, I got an error here dnu build #start the web server dnx web [/source]
Tag: ASP.NET
Trying out Visual Studio Code on Ubuntu
I am very curious about the new .NET Core, ASP.NET 5, EF 7 and Visual Studio Code for Linux, Mac and Windows. I have tried it out on an Ubuntu 15.04 machine. The installation and configuration required a few steps, so it is not an usual “Next-next-next”-installation. But, hey, it is just a beta, a preview so far, and first of all: It worked. I am sharing a couple of screenshots and the commands I ran in the terminal, mixed with comments and links: [source language=“bash”] #install latest node and npm #https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs sudo npm install -g yo sudo npm install -g generator-aspnet # download VS Code and make a link # make a folder mkdir workspace/tryvs cd workspace/tryvs # create “src/global.json” file: # http://docs.asp.net/en/latest/tutorials/your-first-mac-aspnet.html { “sdk”: { “version”: “1.0.0-beta7” } } nano src/global.json # start VS Code # create # install omnisharp: # http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#installing-on-debian-ubuntu-and-derivatives curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh dnvm #install dnx sudo apt-get install -y libunwind8 gettext libssl-dev libcurl3-dev zlib1g libicu-dev dnvm upgrade -r coreclr cd EmptyApplication dnu restore #install libuv #http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#using-docker sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/ sudo ldconfig #build, I got an error here dnu build #start the web server dnx web [/source]
cross browser console.log
console.log
is the best tool for debugging javascript. In Firefox Firebug and Chrome Dev Tools you can even log objects which are represented as tree nodes of properties. If Firebug or Dev Tools in Chrome and IE9 are not opened, all these messages are ignored. But IE8 doesn’t understand console (if Dev Tools are closed) and raises an error: To avoid these errors, just declare an empty function just for IE8–:
XMLHttpRequest the hard way
$.ajax is great, it hides much of the complexity. But sometimes we need to work with “raw” javascript :) So let’s look behind the scenes. The XMLHttpRequest (or just XHR) is used to open a connection to a server without a page reload. Internet Explorer calls it ActiveXObject and it differs in IE versions. Wikipedia article gives a good example how to create one constructor for all browsers: [sourcecode language=“javascript”]if (typeof XMLHttpRequest == “undefined”) XMLHttpRequest = function () { try { return new ActiveXObject(“Msxml2.XMLHTTP.6.0”); } catch (e) {} try { return new ActiveXObject(“Msxml2.XMLHTTP.3.0”); } catch (e) {} try { return new ActiveXObject(“Microsoft.XMLHTTP”); } catch (e) {} //Microsoft.XMLHTTP points to Msxml2.XMLHTTP and is redundant throw new Error(“This browser does not support XMLHttpRequest.”); };[/sourcecode] The remainder is more or less the same among the browsers. We open a connection defining the HTTP verb, URI and async mode (true or false): [sourcecode language=“javascript”]var xhr = new XMLHttpRequest(); xhr.open(“GET”, “/_vti_bin/listdata.svc”, true); xhr.onreadystatechange = onStateChange; xhr.send(null);[/sourcecode] Pay attention to onreadystatechange (only lower case letters). If we choose async=false, the UI waits for the response which is not so kind to users, but maybe it is easier to write a program. Well, there is actually no option but to have async=true. To provide the callback for success and error we can write the responding function onreadystatechange. This function will be called every time the state is changed. There are 5 states:
Datetime in ASP.NET javascript and $.ajax
In one of my previous blogs I wrote about serializing of javascript objects. You can do it with JSON.stringify or Sys.Serialization.JavaScriptSerializer.serialize. Both methods work fine… almost. There is a big difference when it comes to datetime objects. MS treats dates a little bit different (like RegEx and much more). Let’s try this one:
var writer = { name: "Ajgi", birthdate: new Date(1934, 8-1, 21) };
var json = JSON.stringify(writer);
var msjson = Sys.Serialization.JavaScriptSerializer.serialize(writer);
What happens if we try to parse back msjson with JSON.parse: Well, the date isn’t a valid date anymore. How can we improve it. Rick Strahl gives a solution with custom functions for serializing and deserializing of ms date. But the thing is: we don’t need any custom functions for this, not if you run ASP.NET. The only thing we need is to use serialize and deserialize functions from Sys.Serialization.JavascriptSerializer namespace which you get automatically when you add ScriptManager in ASP.NET (and you get it even automagically in SharePoint). But what about $.ajax and functions I wrote about for retrieving list items and populating them, and updating list items with listdata.svc? Well, there comes the really nice tip from Rick Strahl: not to force $.ajax to parse the response. So instead of dataType: “json”, use the plain dataType: “text”. As the result we’ll get just a text, which we, of course, will deserialize with the native code for Microsoft:…. Use text when possible. When you define json as response format:
String.format for javascript
sprintf is actually the best javascript implementation of sprintf (string.format). But wait, shouldn’t it be some more .NET-like stuff in SharePoint environment? Indeed there is! (Well, not only in SP, but ASP.NET) String.format(“Hello {0}”, “world”) does exactly the same thing as on server side. Wow, it opens for many opportunities, e.g. in jQuery tmpl: String.format validates arguments, and if all is OK, it invokes another function String._toFormattedString:
function String$\_toFormattedString(useLocale, args) {
var result = '';
var format = args\[0\];
for (var i=0;;) {
var open = format.indexOf('{', i);
var close = format.indexOf('}', i);
if ((open < 0) && (close < 0)) {
result += format.slice(i);
break;
}
if ((close > 0) && ((close < open) || (open < 0))) {
if (format.charAt(close + 1) !== '}') {
throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
}
result += format.slice(i, close + 1);
i = close + 2;
continue;
}
result += format.slice(i, open);
i = open + 1;
if (format.charAt(i) === '{') {
result += '{';
i++;
continue;
}
if (close < 0) throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
var brace = format.substring(i, close);
var colonIndex = brace.indexOf(':');
var argNumber = parseInt((colonIndex < 0)? brace : brace.substring(0, colonIndex), 10) + 1;
if (isNaN(argNumber)) throw Error.argument('format', Sys.Res.stringFormatInvalid);
var argFormat = (colonIndex < 0)? '' : brace.substring(colonIndex + 1);
var arg = args\[argNumber\];
if (typeof(arg) === "undefined" || arg === null) {
arg = '';
}
if (arg.toFormattedString) {
result += arg.toFormattedString(argFormat);
}
else if (useLocale && arg.localeFormat) {
result += arg.localeFormat(argFormat);
}
else if (arg.format) {
result += arg.format(argFormat);
}
else
result += arg.toString();
i = close + 1;
}
return result;
}
```By the way, take a look at summary part of String.format:
/// /// /// ///
ASP.NET Ajax Toolkit
To integrate ASP.NET Ajax Toolkit is not the most straight forward task in SharePoint. If you want to take the risk, “Inspired by Technology” provides the best guide so far.
Push a copy of an object to client
To reduce postbacks and database calls, a copy of the current object(s) can be pushed down to the client in JSON format. Say a webpart renders information about a person, another webpart shows related information which is retrieved dynamically (like web services). Instead of getting the current person from the database in the second webpart again, we can reuse the same person object from the first webpart. To do so we must provide a DataContract for the Person class:
json serializer in Sharepoint
There is a very handy JSON lib for serializing javascript objects. It is hosted on github under douglas crockford. Download json2.js and serialize with JSON.stringify function: EDIT: There is actually this function in core javascript. It exists since javascript 1.7 and ecmascript 5. So you don’t have to add anything to get this functionality:
var t = { name: "dev", city: "new york" };
JSON.stringify(t);
```There are actually built-in goodies for serializing javascript objects in [ASP.NET](http://msdn.microsoft.com/en-us/library/bb310857.aspx): Sys.Serialization.JavaScriptSerializer.serialize
var t = { name: “dev”, city: “new york” }; Sys.Serialization.JavaScriptSerializer.serialize(t);
ViewState
Om du vill behålla dina värden på variabler mellan postbacks, använd ViewState:
if (ViewState\["MaxNumberOfArticles"\] != null)
{
MaxNumberOfArticles = (int) ViewState\["MaxNumberOfArticles"\];
}
MaxNumberOfArticles += 10;
ViewState.Add("MaxNumberOfArticles", MaxNumberOfArticles);
RenderNews();
SPSecurityTrimmedControl
Ett mycket bra inlägg från Tom Puleos blogg om SPSecurityTrimmedControl. Måste absolut testa det.
Sharepoint + OpenSource = Sant
Om man söker på Sharepoint i codeplex.com får man 729 projekt som är alltså öppna. Det är inte illa. Bland dem finns till exempel Sharepoint Log Viewer. Till det kommer 713 öppna projekt som är taggade ASP.NET som kan användas väldigt mycket i Sharepoint-utveckling. Bland ASP.NET-taggade finns smidiga Telerik Extensions. Powershell är också absolut en tag som man ska söka på i codeplex. codeplex.com är Microsofts officiella OpenSource-portal. Det måste finnas andra sidor där öppna projekt inom Sharepoint och ASP.NET samlas. Tipsa gärna i kommentarer.
Tag: C-Sharp
Trying out Visual Studio Code on Ubuntu
I am very curious about the new .NET Core, ASP.NET 5, EF 7 and Visual Studio Code for Linux, Mac and Windows. I have tried it out on an Ubuntu 15.04 machine. The installation and configuration required a few steps, so it is not an usual “Next-next-next”-installation. But, hey, it is just a beta, a preview so far, and first of all: It worked. I am sharing a couple of screenshots and the commands I ran in the terminal, mixed with comments and links: [source language=“bash”] #install latest node and npm #https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs sudo npm install -g yo sudo npm install -g generator-aspnet # download VS Code and make a link # make a folder mkdir workspace/tryvs cd workspace/tryvs # create “src/global.json” file: # http://docs.asp.net/en/latest/tutorials/your-first-mac-aspnet.html { “sdk”: { “version”: “1.0.0-beta7” } } nano src/global.json # start VS Code # create # install omnisharp: # http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#installing-on-debian-ubuntu-and-derivatives curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh dnvm #install dnx sudo apt-get install -y libunwind8 gettext libssl-dev libcurl3-dev zlib1g libicu-dev dnvm upgrade -r coreclr cd EmptyApplication dnu restore #install libuv #http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#using-docker sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/ sudo ldconfig #build, I got an error here dnu build #start the web server dnx web [/source]
Debugging "What's happening" in Communities
Recently an issue was reported about count mismatches in SharePoint 2013 Communities. The number of replies in category tiles sometimes is different compared to the community stats in the web part called “What’s happening”. The actual number of replies is 1 in the figure below. The user who has reported has tried to add, update and delete discussions and replies. I have invested some time debugging this issue. It would be pity to not share my findings. Well the first thing to do was to determine the type name for the “What’s happening” web part. To do so just edit the page and export the web part. In the exported .webpart file I saw that the type was Microsoft.SharePoint.Portal.WebControls.DashboardWebPart. With that knowledge it is time to open ILSpy, an awesome and free(!) assembly browser and decompiler. Load the “Microsoft.SharePoint.Portal” assembly from GAC into ILSpy. Then use F3 to search for DashboardWebPart: The number of replies is retrieved from SPWeb.AllProperties: If the Property Bag does not contain it, it gets the number of replies from the list. The formula is as follows: [code language=“csharp”] list.ItemCount - list.RootFolder.ItemCount [/code] It means that it gets the number of both discussions and replies: ItemCount of Discusssions List. The number of Discussions is determined by the ItemCount in the RootFolder of the Discussions List. Discussions are List Items in the RootFolder (num2 in the figure below). Replies are saved in the subfolders, every discussion gets an own folder. The number of all replies are num3 in the figure below. After checking the web properties I could see that the number of replies there were wrong: 2. The next step was to determine where and when the Web Properties are updated. The first guess every SharePoint Developer has in such cases is an EventReceiver. Here are all EventReceivers connected to the Discussions List: [code language=“powershell”] $list.EventReceivers | select class, Type, Synchronization | Out-GridView [/code] Allright, CommunityEventReceiver then: Found where the actual update happens: CommunityUtils.UpdateWebIndexedPropertyBag The method is used in DiscussionListCommunityEventHandler.HandleEvent There is a flag, flag5 that is used to determine if the Web Properties should be updated: But the flag5 is not true on Delete operations in some code flows: That’s it. So deleting a reply will not have any effect on “What’s happening”. But adding a new discussion will also update the stats: To summarize the debug session, there is an issue in the OOB code that misses to update community stats when deleting a discussion or a reply. Adding a new discussion, or a reply will synchronize the stats.
qoutes in @ strings
I use @-prefixed strings very often. You can use line breaks as much as you want. Very useful e.g. when I must create an xml in code. One thing I didn’t know was that you CAN use quotation marks inside @-strings. But you must write double quoutes like:
var t = @"säg ""hej""
och ""hå""";
Singleton vs static
Have you wondered what to use a singleton object or a class with static methods. Well, here is an awesome comparision of these techniques. Static methods and classes are easy to use, but you can’t them as objects, implement interfaces and have constructors with parameters.
A simple Log for ULS
Do an unsafe update in a unified manner « Sharepoint. Kunskap. Upptäckter på resan. - Sep 3, 2011
[…] Log class is my own class which I presented in my previous post. Like this:GillaBli först att gilla denna […]
A simple Log for ULS
Here is a simple log which has been inspired of Android Log. It logs to ULS which you can open with ULSViewer, SharePoint Log Viewer.
using System;
using Microsoft.SharePoint.Administration;
namespace Contoso.Intranet.Portal.Utilities
{
public class Log
{
private static readonly string \_CATEGORYNAME = "CONTOSO";
private static readonly SPDiagnosticsCategory \_ERROR\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Unexpected, EventSeverity.Error);
private static readonly SPDiagnosticsCategory \_WARNING\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.High, EventSeverity.Warning);
private static readonly SPDiagnosticsCategory \_VERBOSE\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Verbose, EventSeverity.Verbose);
private static readonly SPDiagnosticsCategory \_INFO\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Medium, EventSeverity.Information);
private static void WriteTrace(SPDiagnosticsCategory category, string message, string trace)
{
SPDiagnosticsService.Local.WriteTrace(0, category, category.DefaultTraceSeverity, message, trace);
}
public static void Error(Exception ex)
{
WriteTrace(\_ERROR\_CATEGORY, ex.Message, ex.StackTrace);
}
public static void Warning(string message)
{
WriteTrace(\_WARNING\_CATEGORY, message, "");
}
public static void Verbose(string message)
{
WriteTrace(\_VERBOSE\_CATEGORY, message, "");
}
public static void Info(string message)
{
WriteTrace(\_INFO\_CATEGORY, message, "");
}
}
}
A possible improvement can be a custom Area. See an example of ThorstenHans on Github: CustomLogger.cs EDIT: I found an interesting article: How to log to the SharePoint ULS Logs: Clean Debugging and Error Logging broken down into steps written by Philip Stathis.
formatera int
Här finns en lista över formateringsmöjligheter med C# string.Format
String.Format("{0:00000}", 15); // "00015"
ForEach-metod i List
En intressant variant av foreach är ForEach-metoden i List. Titta på det lilla exemplet:
private static void SavePlacesToDB(SQLiteConnection cnn,
List<dynamic> places)
{
places.ForEach(obj => SavePlaceToDB(obj, cnn));
}
```Här används även det nya objektet [dynamic](http://msdn.microsoft.com/en-us/library/dd264736.aspx) som har kommit i Visual Studio 2010, samt en [lambda expression (=>)](http://msdn.microsoft.com/en-us/library/bb397687.aspx).
Binda Data till ListView i WPF
Det är väldigt smidigt att koppla datakälla till en ListView i WPF. Man skriver kod i XAML. Och i koden bakom anger man: myListView.ItemsSource = myList;
out ref
Om en metod har en inparameter med out framför sig. så innebär det att man skickar en referens till ett objekt. Alltså om det är out string param, så kommer det inte funka att skicka “någonting” direkt. Utan man måste instansiera först. string hej = “någonting”; CallTheMethod(ref hej); http://msdn.microsoft.com/en-us/library/t3c3bfhx(VS.80).aspx
kort variant av if-else
Inget speciellt egentligen med detta men vill skriva upp det här för att jag brukar glömma det. Det är samma syntax som i många andra språk:
bool value = "dit" == "dat" ? true : false;
Motsvarar:
bool value;
if ("dit" == "dat")
{
value = true;
}
else
{
value = false;
}
join i LINQ
LINQ är ett kraftfullt verktyg. Det som kan vara lite krångligt är join. Men om man gör rätt blir det bra. Låt oss titta på det sql-exemplet:
SELECT s.adAccount
FROM Staff s join StaffOnCourseInstance si
ON s.uid = si.uid
WHERE si.CourseInstanceId = 1435
För att köra motsvarande LINQ måste vi vara väldigt noga med on:
var testQuery = (from s in ctx.Staffs
join si in ctx.StaffOnCourseInstances
on s.uid equals si.uid
where si.CourseInstanceId == 1435
select new { s.adAccount });
```Edit 20101031: Det finns ett smidigare sätt att komma åt information i relaterade tabeller. Se mitt inlägg från 20101031 om [LINQ och foreign keys](https://sharepointkunskap.wordpress.com/2010/10/31/komma-at-andra-tabeller-via-foreign-keys-i-linq/).
keyword using {}
Ibland när man vill att ett objekt som man jobbar med är tungt och man vill slänga den direkt när man är färdig, så kan man använda keyword using…
public void Test()
{
using (SPweb web = site.OpenWeb("blabla")
{
//gör något och släng SPWeb-objektet
}
//.... metoden fortsätter
}
Men de objekten man använder i using, måste implementera interface IDisposable. Försök med using. Visual Studio säger ifrån om objektet av den typen inte implementerar IDisposable.
String.IsNullOrEmpty
I C# kan man testa om en sträng är null eller tom på ett enkelt sätt. I stället för att köra så:
string test;...
if (**test !=null && test != ""**)
{
//gör något.
}
Använder man en statisk metod String.IsNullOrEmpty(string value):
string test;...
if(**!String.IsNullOrEmtpy(test)**)
{
//do something
}
Tag: Codeplex
Trying out Visual Studio Code on Ubuntu
I am very curious about the new .NET Core, ASP.NET 5, EF 7 and Visual Studio Code for Linux, Mac and Windows. I have tried it out on an Ubuntu 15.04 machine. The installation and configuration required a few steps, so it is not an usual “Next-next-next”-installation. But, hey, it is just a beta, a preview so far, and first of all: It worked. I am sharing a couple of screenshots and the commands I ran in the terminal, mixed with comments and links: [source language=“bash”] #install latest node and npm #https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs sudo npm install -g yo sudo npm install -g generator-aspnet # download VS Code and make a link # make a folder mkdir workspace/tryvs cd workspace/tryvs # create “src/global.json” file: # http://docs.asp.net/en/latest/tutorials/your-first-mac-aspnet.html { “sdk”: { “version”: “1.0.0-beta7” } } nano src/global.json # start VS Code # create # install omnisharp: # http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#installing-on-debian-ubuntu-and-derivatives curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh dnvm #install dnx sudo apt-get install -y libunwind8 gettext libssl-dev libcurl3-dev zlib1g libicu-dev dnvm upgrade -r coreclr cd EmptyApplication dnu restore #install libuv #http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#using-docker sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/ sudo ldconfig #build, I got an error here dnu build #start the web server dnx web [/source]
Google Analytics in Sharepoint
Google Analytics is a popular and mature tool for monitoring network activities on your site. Why not use it in Sharepoint? Dave Coleman and Mike Knowles provide good guides for doing that. There is a promising plugin to SP SPGoogleAnalytics which integrates both and provides an easy interface to put GA to your SharePoint installation and see the data directly on your intranet. It comes from codeplex: What do you think about spgoogleanalytics.codeplex? When I recently had to turn on Google Analytics on an intranet, I had no time for evaluating SPGoogleAnalytics, so I did the harder way: just put ga script in the end of a master page, just before ending tag. But what if one has multiple masterpages? Is there a way to put GA in one step? Maybe a user control like Knowles suggests?
Sharepoint repos on github
You may think all interesting open source Sharepoint projects on codeplex. Well it is true, but there are some interesting projects on github as well. There are 17 projects for now. From a matrix to RichControls.
Sharepoint Manager 2010
Ett ytterligare grym verktyg från codeplex-lägret: Sharepoint Manager.
spribbon fluent
Ett mycket intressant projekt för att skapa ribbon-anpassningar. Som så här:
new ButtonDefinition()
{
Id = "New",
Title = "Start new game",
CommandJavaScript = "window.location.reload();",
Image = new ImageDefinition()
{
Url16 = "/\_layouts/images/ChessWebPart/new16.png",
Url32 = "/\_layouts/images/ChessWebPart/new32.png"
}
}
```Så blir resultatet: ![spribbong](http://markeev.com/sharepoint/ribbon/media/buttonSample.png)
Autocomplete för sökruta i Sharepoint
Ett mycket trevligt projekt: Search As You Type på Codeplex. Ladda ner textfilen och lägg till javascript och css från den filen till masterpage. Så enkelt är det. Jag har testat det genom att direkt stoppa in koden i Chrome Console.
Sharepoint + OpenSource = Sant
Om man söker på Sharepoint i codeplex.com får man 729 projekt som är alltså öppna. Det är inte illa. Bland dem finns till exempel Sharepoint Log Viewer. Till det kommer 713 öppna projekt som är taggade ASP.NET som kan användas väldigt mycket i Sharepoint-utveckling. Bland ASP.NET-taggade finns smidiga Telerik Extensions. Powershell är också absolut en tag som man ska söka på i codeplex. codeplex.com är Microsofts officiella OpenSource-portal. Det måste finnas andra sidor där öppna projekt inom Sharepoint och ASP.NET samlas. Tipsa gärna i kommentarer.
Sharepoint Log Viewer
Mycket bra verktyg för att debugga din sharepoint applikation är Sharepoint Log Viewer som är Open Source och finns att hämta på codeplex.com Det går att öppna en logg-fil, det går att köra live monitoring och att exportera. Det sköna är att det är lätt att söka efter correlations-id. Rekommenderar verktyget!
Comments from Wordpress.com
Sharepoint + OpenSource = Sant « Sharepoint. Kunskap. Upptäckter på resan. - Mar 3, 2011
Tag: VS Code
Trying out Visual Studio Code on Ubuntu
I am very curious about the new .NET Core, ASP.NET 5, EF 7 and Visual Studio Code for Linux, Mac and Windows. I have tried it out on an Ubuntu 15.04 machine. The installation and configuration required a few steps, so it is not an usual “Next-next-next”-installation. But, hey, it is just a beta, a preview so far, and first of all: It worked. I am sharing a couple of screenshots and the commands I ran in the terminal, mixed with comments and links: [source language=“bash”] #install latest node and npm #https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs sudo npm install -g yo sudo npm install -g generator-aspnet # download VS Code and make a link # make a folder mkdir workspace/tryvs cd workspace/tryvs # create “src/global.json” file: # http://docs.asp.net/en/latest/tutorials/your-first-mac-aspnet.html { “sdk”: { “version”: “1.0.0-beta7” } } nano src/global.json # start VS Code # create # install omnisharp: # http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#installing-on-debian-ubuntu-and-derivatives curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh dnvm #install dnx sudo apt-get install -y libunwind8 gettext libssl-dev libcurl3-dev zlib1g libicu-dev dnvm upgrade -r coreclr cd EmptyApplication dnu restore #install libuv #http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#using-docker sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/ sudo ldconfig #build, I got an error here dnu build #start the web server dnx web [/source]
Tag: Yeoman
Trying out Visual Studio Code on Ubuntu
I am very curious about the new .NET Core, ASP.NET 5, EF 7 and Visual Studio Code for Linux, Mac and Windows. I have tried it out on an Ubuntu 15.04 machine. The installation and configuration required a few steps, so it is not an usual “Next-next-next”-installation. But, hey, it is just a beta, a preview so far, and first of all: It worked. I am sharing a couple of screenshots and the commands I ran in the terminal, mixed with comments and links: [source language=“bash”] #install latest node and npm #https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs sudo npm install -g yo sudo npm install -g generator-aspnet # download VS Code and make a link # make a folder mkdir workspace/tryvs cd workspace/tryvs # create “src/global.json” file: # http://docs.asp.net/en/latest/tutorials/your-first-mac-aspnet.html { “sdk”: { “version”: “1.0.0-beta7” } } nano src/global.json # start VS Code # create # install omnisharp: # http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#installing-on-debian-ubuntu-and-derivatives curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh dnvm #install dnx sudo apt-get install -y libunwind8 gettext libssl-dev libcurl3-dev zlib1g libicu-dev dnvm upgrade -r coreclr cd EmptyApplication dnu restore #install libuv #http://docs.asp.net/en/latest/getting-started/installing-on-linux.html#using-docker sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/ sudo ldconfig #build, I got an error here dnu build #start the web server dnx web [/source]
Tag: Js
Export Any Web Part using a Bookmarklet
My blog post about exporting any webpart from a SharePoint Page is one of the most read articles on my blog. I use this method a lot. Now what I want to do is to simplify the process. Inspired by my colleague Dan Saedén’s awesome bookmarklet for reading and updating web properties, I decided to make my own bookmarklet. That was easy. Now we can export any web part from any SharePoint page without even looking at any ids in the html markup and assembling the export url manually. Just add the bookmarklet or run the javascript code in the browser console. The code (js and bookmarklet) is on Github. Here is an animated gif that explains how to use it:
AngularJS: sync $location.search with an input value
I have used AngularJS for a while and to me this seems to be the best MVC javascript framework. Today I wanted to implement a search which uses an input and a hash query string like in google. The input value and url have to be synced like:
index.html#?term=something
To do this we have to inject $location
into our angular control. See the Angular Guide about $location. Then we have to observe both the $scope.term (which is bound to the input value) and $location.search().
Determine if Silverlight is installed (javascript)
For a while ago I needed to provide an alternative solution when Silverlight isn’t installed. I searched for javascript code for this and found this:
- A blog post about that: Piotr Puszkiewicz’s Silverlight Blog. Determining if Silverlight is installed using Javascript.
- A more advanced javascript function which can even determine the version of the Silerlight can be pulled from Silverlight.js library.
I didn’t need to determine the version of Silverlight, so I wrote a simplified js function (but it works in all browsers): [sourcecode language=“javascript”] var isSilverlightInstalled = function() { var installed = false; try { installed = !!navigator.plugins[“Silverlight Plug-In”] || !!(window.ActiveXObject && new ActiveXObject(‘AgControl.AgControl’)); } catch (e) {} return installed; };[/sourcecode] This function first checks if a Silverlight plugin is installed in almost all web browsers except IE, then if it is not it tries to create an ActiveXObject (IE) for Silverlight. If an error occurs, the function returns false and indicates that Silverlight is not available.
Masked Inputs
Just a quick tip today. If you are looking after masked inputs like the old ASP.NET Ajax Control Toolkit MaskedEdit, you can try jQuery plugin called Masked Input from DigitalBush or even better jquery.inputmask.
javascript: developing for performance
Many words have been said about the importance of performance when working with javascript files. Here I want to summarize what developers can do to increase the performance related to javascript. I found many tips on blogs. Here comes my aggregated list of actions one can do to speed up sharepoint (and not only) sites with focus on javascript:
1. Load only sharepoint stuff you need
Use prefetch option to only load sharepoint javascript files that needed. To see the difference, just add ?prefetch=0
to your sharepoint url in the browser. The downside of this lazy loading is that you wrap all sharepoint related javascript into ExecuteOrDelayUntilScriptLoaded otherwise you maybe invoke some of javascript objects and functions that are not loaded. So the prize of this huge performance improvement is a high awareness by a developer when and which scripts are loaded and run.
Tag: Webpart
Export Any Web Part using a Bookmarklet
My blog post about exporting any webpart from a SharePoint Page is one of the most read articles on my blog. I use this method a lot. Now what I want to do is to simplify the process. Inspired by my colleague Dan Saedén’s awesome bookmarklet for reading and updating web properties, I decided to make my own bookmarklet. That was easy. Now we can export any web part from any SharePoint page without even looking at any ids in the html markup and assembling the export url manually. Just add the bookmarklet or run the javascript code in the browser console. The code (js and bookmarklet) is on Github. Here is an animated gif that explains how to use it:
Export any web part from a SharePoint page
The blog post below describes the technical details about how Web Parts can be exported using a hidden tool in OOB SharePoint, though this requires manual assembling of a special url. If you are just interested in a solution for an easy Web Part Export function, just proceed directly to my new blog post where you can download my tool that you can add to your web browser.
AngularJS: prevent form validation in Page Edit Mode
I work on a cool project where AngularJS is used for rendering of business data in a SharePoint portal. One of the beautiful parts of AngularJS is the client validation. AngularJS understands the new html5 attributes like “required” and pattern, which makes the markup and javascript concise and semantic. Recently I ran into a problem: The SharePoint webparts which had html forms with required fields were impossible to add to a page in the web browser, neither was it possible to edit the pages with these webparts. When I clicked on “Save”, the page tried to validate and failed. The solution for this is very elegant, like much of the AngularJS. If you don’t show your angular form, it won’t validate. So just use any method to detect the edit mode on a SharePoint page. I created a helper function for that. [sourcecode language=“javascript”] function isEditMode() { var publishingEdit = window.g_disableCheckoutInEditMode, form = document.forms[MSOWebPartPageFormName], input = form.MSOLayout_InDesignMode || form._wikiPageMode; return !!(publishingEdit || (input && input.value)); } [/sourcecode] In the angular controller, just define the part of it which shouldn’t be there when you are editing a page, by using ng-hide="editMode"
: [sourcecode language=“html”] [/sourcecode] editMode
is a $scope variable in your controller. So the last thing to do is to get the editMode value by invoking the previously defined isEditMode
function: [sourcecode language=“javascript”] function PhoneCallCtrl($scope, $http) { $scope.editMode = isEditMode(); } [/sourcecode]
The original Visual Web Part template is missing in Visual Studio 2012
Today I encountered a weird issue, the classic Visual Web Part template was gone in Visual Studio 2012. When I created a Visual WebPart, a webpart was created with a generated .g.cs file, like the sandboxed visual webparts. I am not exactly sure why it happened. According to the MSDN guide Creating Web Parts for SharePoint, the structure of Visual Webparts should be the same as in Visual Studio 2010. It could have happened after I installed the power tools. However, if someone runs into the same issue, here is the solution: Copy this zip file from a computer with VS2010 installed:
Multiple instances of javascript webparts on the same page
Javascript has become popular among many SharePoint developers thanks to easy and fast jQuery, CSOM, SPServices and many other javascript libraries. That can make solutions modern and fast. On the other hand developers should be aware of more things (some of them at Bamboo Team Blog). One of those is scoping of javascript webparts. The problem a developer has to consider: what happens if a user creates two or more instances of the same beautiful webpart on the page? Let’s go and lab :) I’ll create a solution for this lab: sp-lend-id.ikkelen. This time it will be a sandboxed solution. This solution contains a webpart:
Develop for SharePoint on Windows 8
Do you like Windows 8 user expirience, as me? Well than you want to try developing sharepoint solutions in Windows 8. Here I will show what I found out.
Environment
I installed Windows 8 Release Preview as a VMWare machine. Then I installed Visual Studio 2012 RC. Then I followed the steps for installing SharePoint on Windows 8 which are more or less the same as for Windows 7 client install. But then I encountered an error I haven’t found solution for yet. In my standalone sharepoint installation there were some permission problems:
Tag: Nav
Add Search Verticals by code
Adding own search verticals is a common task in the Search Configuration in SharePoint. Here I want to share a code sample for achieving this programmatically. I hope, this model can be added to SPMeta2. First of all, Search Verticals are dedicated Search Results Pages and links to them. How to add them manually is described on technet:
There is no API in CSOM for that. Luckily, Mikael Svenson found how to get the Search Navigation and contributed to PnP by writing an Extension: web.LoadSearchNavigation. Here is my sample code for adding new Search Verticals programmatically: [source language=“csharp”] NavigationNode searchNav = context.Web.Navigation.GetNodeById(1040); NavigationNodeCollection nodeCollection = searchNav.Children; NavigationNodeCreationInformation everything = new NavigationNodeCreationInformation { Title = “Everyting”, Url = “/search/Pages/results.aspx”, }; NavigationNodeCreationInformation myresults = new NavigationNodeCreationInformation { Title = “My Results”, Url = “/search/Pages/myresults.aspx”, }; nodeCollection.Add(everything); nodeCollection.Add(myresults); context.ExecuteQuery(); [/source]
Tag: Navigation
Add Search Verticals by code
Adding own search verticals is a common task in the Search Configuration in SharePoint. Here I want to share a code sample for achieving this programmatically. I hope, this model can be added to SPMeta2. First of all, Search Verticals are dedicated Search Results Pages and links to them. How to add them manually is described on technet:
There is no API in CSOM for that. Luckily, Mikael Svenson found how to get the Search Navigation and contributed to PnP by writing an Extension: web.LoadSearchNavigation. Here is my sample code for adding new Search Verticals programmatically: [source language=“csharp”] NavigationNode searchNav = context.Web.Navigation.GetNodeById(1040); NavigationNodeCollection nodeCollection = searchNav.Children; NavigationNodeCreationInformation everything = new NavigationNodeCreationInformation { Title = “Everyting”, Url = “/search/Pages/results.aspx”, }; NavigationNodeCreationInformation myresults = new NavigationNodeCreationInformation { Title = “My Results”, Url = “/search/Pages/myresults.aspx”, }; nodeCollection.Add(everything); nodeCollection.Add(myresults); context.ExecuteQuery(); [/source]
Add global navigation links in Powershell and Feature Receiver
I think, powershell is the best way to do configurations you have to do once. Adding some links to global (top) navigation is one of them:
asnp microsoft.sharepoint.powershell
$w = get-spweb http://takana
$l = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Smells like team spirit", "/pages/teamspirit.aspx")
$w.Navigation.TopNavigationBar.AddAsLast($l)
Feature receiver
The alternative is to create a web scoped feature and provide properties:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
var web = properties.Feature.Parent as SPWeb;
var prop = properties.Feature.Properties\["MyGlobalLinks"\];
var links = prop.Value.Split(new\[\] { ";#" },
StringSplitOptions.RemoveEmptyEntries);
foreach (var item in links)
{
var newLink = item.Split(new\[\] { ";" },
StringSplitOptions.RemoveEmptyEntries);
var newMenuItem =
new SPNavigationNode(newLink\[0\], newLink\[1\]);
web.Navigation.TopNavigationBar.AddAsLast(newMenuItem);
}
}
```This feature can be prefereably hidden. The properties are passed in onet:
NavBarLink
I found even a third way to add links to global navigation: NavBarLink
Can't add a global site navigation link
If you encounter problems while customizing global site navigation in a custom site definition for SharePoint 2010, you probably can solve it by adding the necessary navbar element in navbars section of the onet.xml:
<NavBar Name="$Resources:core,category\_Top;"
Separator="&nbsp;&nbsp;&nbsp;"
Body="<a ID='onettopnavbar#LABEL\_ID#' href='#URL#' accesskey='J'>#LABEL#</a>"
ID="1002" />
It solved the problems for me :).
Comments from Wordpress.com
Chilly - Nov 3, 2012
How did you edit the Onet.XML file? What if this is only happening on one site in a whole site colleciton will this help this site as well. Thanks for any help you can give. This problem is bugging me on one of my sites.
Link to Home on Top Navigation Bar
If you have a custom site definition and want to have a link to RootWeb, just add NavBarPage to your module:
<Module Name="OrklaRootBlank" Url="" Path="">
<File Url="default.aspx">
<NavBarPage Name="$Resources:core,nav\_Home;"
Url="~site" ID="1002" Position="Start" />
</File>
</Module>
Tag: Phapp
Http to Https Redirect in Provider Hosted Apps
It is strongly recommended to use https in SharePoint Provider Hosted Apps. In many provider hosted apps I have seen, only https works. I would recommend to configure a simple http to https redirect in IIS and make solutions better. Many Provider Hosted Apps can be done in that way that they are available without SharePoint Context, e.g. for browsing information. In that case that is important to have an easy url and an automatic http -> https redirect. In this post I’ll give a short manual for doing that. I would recommend this step for all provider hosted apps. 1. In the Provider Hosted Apps Server install the URL Rewrite IIS Module using Web Platform Installer: 2. Next step is to add the http binding to your solution (this is needed for the future redirect): Then you can configure the automatic http to https redirect using the GUI or the web.config update. My instructions originally come from JPPInto.com blog. I suggest updating the web.config file directly in the Provider Hosted App: 3. Add this section to the web.config file: [source language=“xml”] <system.webServer> </system.webServer> [/source] It is important to know that his web.config section will cause failure on the server if URL Rewrite module is not installed. Summary These steps are very easy to accomplish and I recommend it for every Provider Hosted App, especially those ones that are accessible without going through SharePoint (Web Content -> Apps). This also reflects the configurations in Azure Apps (WebSites).
Tag: Provider Hosted App
Http to Https Redirect in Provider Hosted Apps
It is strongly recommended to use https in SharePoint Provider Hosted Apps. In many provider hosted apps I have seen, only https works. I would recommend to configure a simple http to https redirect in IIS and make solutions better. Many Provider Hosted Apps can be done in that way that they are available without SharePoint Context, e.g. for browsing information. In that case that is important to have an easy url and an automatic http -> https redirect. In this post I’ll give a short manual for doing that. I would recommend this step for all provider hosted apps. 1. In the Provider Hosted Apps Server install the URL Rewrite IIS Module using Web Platform Installer: 2. Next step is to add the http binding to your solution (this is needed for the future redirect): Then you can configure the automatic http to https redirect using the GUI or the web.config update. My instructions originally come from JPPInto.com blog. I suggest updating the web.config file directly in the Provider Hosted App: 3. Add this section to the web.config file: [source language=“xml”] <system.webServer> </system.webServer> [/source] It is important to know that his web.config section will cause failure on the server if URL Rewrite module is not installed. Summary These steps are very easy to accomplish and I recommend it for every Provider Hosted App, especially those ones that are accessible without going through SharePoint (Web Content -> Apps). This also reflects the configurations in Azure Apps (WebSites).
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
Tag: Sharepoint2016
Http to Https Redirect in Provider Hosted Apps
It is strongly recommended to use https in SharePoint Provider Hosted Apps. In many provider hosted apps I have seen, only https works. I would recommend to configure a simple http to https redirect in IIS and make solutions better. Many Provider Hosted Apps can be done in that way that they are available without SharePoint Context, e.g. for browsing information. In that case that is important to have an easy url and an automatic http -> https redirect. In this post I’ll give a short manual for doing that. I would recommend this step for all provider hosted apps. 1. In the Provider Hosted Apps Server install the URL Rewrite IIS Module using Web Platform Installer: 2. Next step is to add the http binding to your solution (this is needed for the future redirect): Then you can configure the automatic http to https redirect using the GUI or the web.config update. My instructions originally come from JPPInto.com blog. I suggest updating the web.config file directly in the Provider Hosted App: 3. Add this section to the web.config file: [source language=“xml”] <system.webServer> </system.webServer> [/source] It is important to know that his web.config section will cause failure on the server if URL Rewrite module is not installed. Summary These steps are very easy to accomplish and I recommend it for every Provider Hosted App, especially those ones that are accessible without going through SharePoint (Web Content -> Apps). This also reflects the configurations in Azure Apps (WebSites).
Tag: M2
Kom igång med SPMeta2
SPMeta2 (eller bara M2) är ett relativt nytt ramverk för provisionering av SharePoint-artefakter. Bakom ramverket ligger ett gediget arbete. I den här posten vill jag skriva upp mina steg för att sätta upp ett litet projekt. För mig är SPMeta2 nytt och huvudprincipen i den här bloggposten att få en fungerande lösning så snabbt som möjligt. Informationen här kan snabbt bli inaktuell, eftersom SPMeta2 förändras och förbättras väldigt snabbt. Vad är SPMeta2 SPMeta är ett ramverk för att provisionera SharePoint-artefakter, allt från fält, innehållstyper, listor, dokumentbibliotek, user custom actions, ladda upp filer med mera. Klassiskt har vi gjort provisionering med hjälp av XML-baserade moduler och features. SPMeta2 erbjuder ett Fluent API som är kodbaserat. Med hjälp av SPMeta2 definierar man en modell (enkla objekt POCOs) som inte har beroendet till SharePoint. Modellen används sedan av Provision-delen som anropar modellen för specifika versioner: SharePoint 2013, SharePoint 2010, Office 365 med mera. Man kan välja CSOM och SSOM. Provision är också flexibel vad som gäller paketering: det kan vara en konsolapplikation, en SharePoint-app, ett wsp-paket, en PowerShell-modul. Se följande länkar:
Tag: CU
Method "GetList" does not exist
I troubleshooted a piece of CSOM code in SharePoint 2013. I got the following error:
Method “GetList” does not exist
The reason was that the method GetList was not imlemented until March 2015 CU (15.0.4701.1001), and the SharePoint farm I had was SharePoint 2013 SP1 (15.0.4569.1000). So the solution is to install the Cumulative Update or use web.Lists.GetByTitle. GetByTitle has one aweful shortcoming: it doesn’t work in multilingual environments. So I have recommended to install the March 2015 CU.
Do not mess with the hive
In our Intranet we got this nasty double encoding error that was introduced in SharePoint April 2014 CU. In July 2014 CU the problem is still there. I often hear the suggestions to update files directly in the hive (the root folder for SharePoint: C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\) In that blog post it is described what the problem is and what files are affected and what code must be altered in order to get it to work (which I like). But it is also suggested to update the Search.ClientControls.js directly on the server (which I don’t like). So my advise is:
Tag: Platform
Tillgänglighet i SharePoint
From 1 januari 2015 är bristande tillgänglighet inkluderad i svenska diskrimineringslagen. Detta krav på tillgängligt webbinnehåll ställer högre krav på SharePoint-baserade webbplatser i offentliga sektorn (och helst i alla webbplatser). Regler och riktlinjer för tillgänglighet på webben är definierade av W3C i ett dokument som heter: Web Content Accessibility Guidelines (WCAG) 2.0 vilket finns i en auktoriserad översättning på svenska: Riktlinjer för tillgängligt webbinnehåll (WCAG) 2.0. (Gjort av Funka)
Hur ska vi tänka om Tillgänglighet i SharePoint
Som vilket webbaserat system som helst bör man i SharePointlösningar tänka på tillgänglighet i alla faser av projektet. Liksom säkerhet och prestanda, finns Tillgänglighet med både i Design- och arkiktekturfasen, i utvecklingen, i lanseringen och utbildingen samt i förvaltningen av ett system. Det ska finnas med Governance-modellen. SharePoint är såklart inte ett vanligt webbsystem, utan det är ett stort metasystem. Vi kan dela in det i tre lager för att kunna hantera problem som kan uppstå: [caption id=“attachment_3709” align=“alignnone” width=“454”] ”Sköldpaddor hela vägen ner”: Tre lager av SharePoint som påverkar tillgänglighet: Platform, Egna Lösningar och Använarinnehåll[/caption]
Tag: Solutions
Tillgänglighet i SharePoint
From 1 januari 2015 är bristande tillgänglighet inkluderad i svenska diskrimineringslagen. Detta krav på tillgängligt webbinnehåll ställer högre krav på SharePoint-baserade webbplatser i offentliga sektorn (och helst i alla webbplatser). Regler och riktlinjer för tillgänglighet på webben är definierade av W3C i ett dokument som heter: Web Content Accessibility Guidelines (WCAG) 2.0 vilket finns i en auktoriserad översättning på svenska: Riktlinjer för tillgängligt webbinnehåll (WCAG) 2.0. (Gjort av Funka)
Hur ska vi tänka om Tillgänglighet i SharePoint
Som vilket webbaserat system som helst bör man i SharePointlösningar tänka på tillgänglighet i alla faser av projektet. Liksom säkerhet och prestanda, finns Tillgänglighet med både i Design- och arkiktekturfasen, i utvecklingen, i lanseringen och utbildingen samt i förvaltningen av ett system. Det ska finnas med Governance-modellen. SharePoint är såklart inte ett vanligt webbsystem, utan det är ett stort metasystem. Vi kan dela in det i tre lager för att kunna hantera problem som kan uppstå: [caption id=“attachment_3709” align=“alignnone” width=“454”] ”Sköldpaddor hela vägen ner”: Tre lager av SharePoint som påverkar tillgänglighet: Platform, Egna Lösningar och Använarinnehåll[/caption]
Tag: Tillgänglighet
Tillgänglighet i SharePoint
From 1 januari 2015 är bristande tillgänglighet inkluderad i svenska diskrimineringslagen. Detta krav på tillgängligt webbinnehåll ställer högre krav på SharePoint-baserade webbplatser i offentliga sektorn (och helst i alla webbplatser). Regler och riktlinjer för tillgänglighet på webben är definierade av W3C i ett dokument som heter: Web Content Accessibility Guidelines (WCAG) 2.0 vilket finns i en auktoriserad översättning på svenska: Riktlinjer för tillgängligt webbinnehåll (WCAG) 2.0. (Gjort av Funka)
Hur ska vi tänka om Tillgänglighet i SharePoint
Som vilket webbaserat system som helst bör man i SharePointlösningar tänka på tillgänglighet i alla faser av projektet. Liksom säkerhet och prestanda, finns Tillgänglighet med både i Design- och arkiktekturfasen, i utvecklingen, i lanseringen och utbildingen samt i förvaltningen av ett system. Det ska finnas med Governance-modellen. SharePoint är såklart inte ett vanligt webbsystem, utan det är ett stort metasystem. Vi kan dela in det i tre lager för att kunna hantera problem som kan uppstå: [caption id=“attachment_3709” align=“alignnone” width=“454”] ”Sköldpaddor hela vägen ner”: Tre lager av SharePoint som påverkar tillgänglighet: Platform, Egna Lösningar och Använarinnehåll[/caption]
Tag: Wcag
Tillgänglighet i SharePoint
From 1 januari 2015 är bristande tillgänglighet inkluderad i svenska diskrimineringslagen. Detta krav på tillgängligt webbinnehåll ställer högre krav på SharePoint-baserade webbplatser i offentliga sektorn (och helst i alla webbplatser). Regler och riktlinjer för tillgänglighet på webben är definierade av W3C i ett dokument som heter: Web Content Accessibility Guidelines (WCAG) 2.0 vilket finns i en auktoriserad översättning på svenska: Riktlinjer för tillgängligt webbinnehåll (WCAG) 2.0. (Gjort av Funka)
Hur ska vi tänka om Tillgänglighet i SharePoint
Som vilket webbaserat system som helst bör man i SharePointlösningar tänka på tillgänglighet i alla faser av projektet. Liksom säkerhet och prestanda, finns Tillgänglighet med både i Design- och arkiktekturfasen, i utvecklingen, i lanseringen och utbildingen samt i förvaltningen av ett system. Det ska finnas med Governance-modellen. SharePoint är såklart inte ett vanligt webbsystem, utan det är ett stort metasystem. Vi kan dela in det i tre lager för att kunna hantera problem som kan uppstå: [caption id=“attachment_3709” align=“alignnone” width=“454”] ”Sköldpaddor hela vägen ner”: Tre lager av SharePoint som påverkar tillgänglighet: Platform, Egna Lösningar och Använarinnehåll[/caption]
Tag: Web Accessibility
Tillgänglighet i SharePoint
From 1 januari 2015 är bristande tillgänglighet inkluderad i svenska diskrimineringslagen. Detta krav på tillgängligt webbinnehåll ställer högre krav på SharePoint-baserade webbplatser i offentliga sektorn (och helst i alla webbplatser). Regler och riktlinjer för tillgänglighet på webben är definierade av W3C i ett dokument som heter: Web Content Accessibility Guidelines (WCAG) 2.0 vilket finns i en auktoriserad översättning på svenska: Riktlinjer för tillgängligt webbinnehåll (WCAG) 2.0. (Gjort av Funka)
Hur ska vi tänka om Tillgänglighet i SharePoint
Som vilket webbaserat system som helst bör man i SharePointlösningar tänka på tillgänglighet i alla faser av projektet. Liksom säkerhet och prestanda, finns Tillgänglighet med både i Design- och arkiktekturfasen, i utvecklingen, i lanseringen och utbildingen samt i förvaltningen av ett system. Det ska finnas med Governance-modellen. SharePoint är såklart inte ett vanligt webbsystem, utan det är ett stort metasystem. Vi kan dela in det i tre lager för att kunna hantera problem som kan uppstå: [caption id=“attachment_3709” align=“alignnone” width=“454”] ”Sköldpaddor hela vägen ner”: Tre lager av SharePoint som påverkar tillgänglighet: Platform, Egna Lösningar och Använarinnehåll[/caption]
Tag: Console
Onpremifying SharePoint apps
We want to make an app available in SharePoint OnPrem, we want to onpremify it. Rethink SharePoint apps and provisioning SharePoint artifacts. It has been a while since I updated my blog – Chuvash.eu. I had my vacation, I visited the sunny and green Chuvashia. Now I am back and I am looking forward to an awesome SharePoint Autumn. One of the first things I had to deal with in this SharePoint Autumn was Onpremifying of a SharePoint Online App. We have an app that has gained popularity and we want to make it available for SharePoint OnPrem. There is no such word Onpremify (yet?), I know, it is a Swenglish happy word making (onpremifiera), but I like the word “onpremify” a lot. There is still uncertainty around the purpose of SharePoint apps. One app type, though, has been used a lot in our company: an app that provisions SharePoint Artifacts – that creates SharePoint Applications. What I mean by SharePoint Applications can be read in my blog post:
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
clearInterval in Chrome doesn't work on window blur
If you want to reset all interval jobs when a browser tab is inactive, the best way would be to use clearInterval on window blur. But unfortunately Chrome fires window focus and window blur two times. Here is an embryo to a solution:
var M = window.M || {};
M.counter = 0;
M.focused = true;
M.tick = function() {
if (M.focused) {
console.log("tic tac " + ++M.counter);
}
};
M.start = function(e) {
console.log("starting...");
M.focused = true;
};
M.stop = function(e) {
console.log("stopping...");
M.focused = false;
};
$(window).on({
focus: M.start,
blur: M.stop
});
M.ticker = window.setInterval(M.tick, 1000);
cross browser console.log
console.log
is the best tool for debugging javascript. In Firefox Firebug and Chrome Dev Tools you can even log objects which are represented as tree nodes of properties. If Firebug or Dev Tools in Chrome and IE9 are not opened, all these messages are ignored. But IE8 doesn’t understand console (if Dev Tools are closed) and raises an error: To avoid these errors, just declare an empty function just for IE8–:
Save an excel sheet as a clean table
To save an excel sheet as a html table is very easy. Just select the needed area, then go to Save as and check the selection and choose html as output format. It works fine. It even looks like it did in Excel. But what if you don’t want all this junk, you want only the plain html table (e.g. for pasting into WP). When I saved my permission levels to html, I used this javascript code. First open the html page which Excel has created in Chrome, open the Dev Tools console, load the latest jQuery into the page, and remove all unnecessary attributes and styling, remove the comments, after that you can just copy the outerHTML of the table and paste into a text editor:
Find the current Active Directory Domain
While working with Active Directory within SharePoint we probably don’t need to specify the domain or the root container. We can the current values. Here is a simple method from a console application just to demonstrate:
internal static void GetDomain()
{
var context = new DirectoryContext(DirectoryContextType.Domain);
var domain = Domain.GetDomain(context);
Console.WriteLine("Full domain:");
Console.WriteLine(domain.Name); //takana.local
Console.WriteLine();
Console.WriteLine("root container");
var parts = domain.Name.Split(new\[\] {"."}, StringSplitOptions.RemoveEmptyEntries);
var dcParts = parts.Select(n => "dc=" + n).ToArray();
var d = string.Join(",", dcParts); //dc=takana, dc=local
Console.WriteLine(d);
}
First we get get the full domain, then we split and join them again.
Autocomplete för sökruta i Sharepoint
Ett mycket trevligt projekt: Search As You Type på Codeplex. Ladda ner textfilen och lägg till javascript och css från den filen till masterpage. Så enkelt är det. Jag har testat det genom att direkt stoppa in koden i Chrome Console.
Tag: Sharepoint Apps
Onpremifying SharePoint apps
We want to make an app available in SharePoint OnPrem, we want to onpremify it. Rethink SharePoint apps and provisioning SharePoint artifacts. It has been a while since I updated my blog – Chuvash.eu. I had my vacation, I visited the sunny and green Chuvashia. Now I am back and I am looking forward to an awesome SharePoint Autumn. One of the first things I had to deal with in this SharePoint Autumn was Onpremifying of a SharePoint Online App. We have an app that has gained popularity and we want to make it available for SharePoint OnPrem. There is no such word Onpremify (yet?), I know, it is a Swenglish happy word making (onpremifiera), but I like the word “onpremify” a lot. There is still uncertainty around the purpose of SharePoint apps. One app type, though, has been used a lot in our company: an app that provisions SharePoint Artifacts – that creates SharePoint Applications. What I mean by SharePoint Applications can be read in my blog post:
What about the SharePoint app domain?
This is an open question about the domains for SharePoint apps. On Technet: Configure an environment for apps for SharePoint (SharePoint 2013) we can read the following:
You must configure a new name in Domain Name Services (DNS) to host the apps. To help improve security, the domain name should not be a subdomain of the domain that hosts the SharePoint sites. For example, if the SharePoint sites are at Contoso.com, consider ContosoApps.com instead of App.Contoso.com as the domain name.
PowerShell: Get version and ProductId from an .app package
In my project I deploy some apps directly through the ObjectModel directly with PowerShell. The apps are built with TFS I have a script that installs or updates apps if there is a new version of the app. Previously I used Import-SPAppPackage to compare the version and productid with an existing app instance, but often I get this error:
The provided App differs from another App with the same version and product ID.
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
SharePoint Apps: "Provider Hosted First" Approach
Recently I had an exciting mail conversation with Thomas Deutsch. He came up with an idea how to fasten the development of apps. This smart approach is called “Provider Hosted First”. See Thomas’ original blog post. Here are some highlights: What you actually do is a local website which runs in grunt server
:
localhost:9000
```Then a SharePoint-hosted app is created with an SPAppIframe that refers to that local app site. Genious!!! Some key features of this approach:
* This local app contains a livereload script. Your sharepoint app is updated every time you save your css, js, html file in your IDE
* Grunt minifies, bundles your assets
* Grunt runs your tests automatically when your content is modified
* The SharePoint app can be on Premises, on Office 365, wherever you want it.
#### Video
\[caption id="attachment\_2808" align="alignnone" width="630"\][![See the video how it looks like to develop using this approach](https://sharepointkunskap.files.wordpress.com/2013/07/sp-app-002.png?w=630)](http://www.screenr.com/LA8H) See the video how it looks like to develop using this approach\[/caption\]
## Comments from Wordpress.com
####
[Paul Tavares](http://paultavares.wordpress.com "paultavares1@gmail.com") - <time datetime="2013-07-10 02:59:34">Jul 3, 2013</time>
This is pretty cool and very similar to my current setup for developing javascript applications for SharePoint. I use a script to "deploy" updates from my PC to the folder in a document library. I'll try this out when I get around to playing with SP2013.
<hr />
####
[Björn]( "bjorn.roberg@bool.se") - <time datetime="2013-07-02 11:07:08">Jul 2, 2013</time>
Awesome! I'm gonna try that out!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-07-02 15:31:33">Jul 2, 2013</time>
Great! When you go to Thomas Deutsch blog, you can download the source code for the solution.
<hr />
Tag: Ssa
Resetting SharePoint Search Configuration Cache
Now it is the second time it happens that the search cannot return any results. This hickup is rare but it happens. To solve it I had to follow these steps:
- Stop the Timer Service
- Clear the configuration cache
- Find in \ProgramData\Microsoft\SharePoint\Config the folder where the file cache.ini exists
- Delete every file from this folder EXCEPT cache.ini
- Open cache.ini, delete the content and put ’1′ (without the quotes) in it and save the file
- Restart the Timer Service
- Index reset
- Full crawl
Source: ITIDea. The linked blog post saved my afternoon today. Thank you, Anita Boerboom.
Tag: Business
Why Swedish matters
I Sverige är engelskan är väldigt stark. Speciellt i IT-branschen är vi vana att ha i princip allt på engelska, från kommentarer i koden till stora upphandlingar, rapporter och dokumentation. Trots det ser jag ett stort behov av att kunna prata om IT på svenska. Det gäller både lokala företag och globala företag. Det finns flera anledningar:
- Företag i Sverige följer svenska lagar som är skrivna på svenska, för att leva upp till kraven ska man kunna formulera sig på svenska.
- Modersmål eller det språk som man använder mest i vardagen (gäller mig bland annat) är den snabbaste vägen för kommunikation som ger en högre grad av nyansering. Att kunna nyansera krav och önskemål tidigt i projekt är guld värt (enligt många av mina korrespondenter). Man behöver spendera mindre tid på att formulera och tolka krav.
- En mer ideologisk anledning (men en viktig sådan) är att vi som bor i Sverige har skyldighet att utveckla och hålla svenskan levande, inte minst inom IT-sektorn.
Svenska är en stor möjlighet för att verkligen ge mervärde till våra kunder, möta dem på hemmaplan, prata ett gemensamt språk. Startpunkten till den här diskussionen har varit en ny webinar som jag planerar hålla den 14 april kl 10. Webinarens titel är SharePoint i molnet.Det finns ganska mycket information om SharePoint Online och Office 365 på engelska. Det är dock ganska sparsamt med information på svenska. https://www.eventbrite.com/e/sharepoint-i-molnet-tickets-15976529229 Det här är det som väntar dig som vill delta i webinaren:
Publishing Visio diagrams as html image maps
I got a question from a customer: We have our processes defined in Visio, we don’t have SharePoint Enterprise CALs to use the Visio webpart. We have links in process maps. What can we do? Well there are three five ways to solve this business need:
- Find money for SharePoint Enterprise - Very expensive
- Show Visio diagrams as pdf files on SharePoint Pages - Expensive.
- Embed Visio diagrams as html image maps - Least expensive
- Embed Visio diagrams as svg pictures - Separate blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
If the business needs other features available only in Enterprise, just use the solution 1. Stop reading. If you are looking for alternatives, then consider pdf and image maps. I have seen projects where pdf files were embedded in the SharePoint Pages. It required a pdf plugin in IE, a lot of time to make it look the same in different browsers and the scroll and fixed size was still there. It was expensive because of the development and configuration time. In this blog post, I want to show the alternative number 3: embedding Visio diagrams as html image maps. This is only a Proof-of-concept so far.
Tag: Language
Why Swedish matters
I Sverige är engelskan är väldigt stark. Speciellt i IT-branschen är vi vana att ha i princip allt på engelska, från kommentarer i koden till stora upphandlingar, rapporter och dokumentation. Trots det ser jag ett stort behov av att kunna prata om IT på svenska. Det gäller både lokala företag och globala företag. Det finns flera anledningar:
- Företag i Sverige följer svenska lagar som är skrivna på svenska, för att leva upp till kraven ska man kunna formulera sig på svenska.
- Modersmål eller det språk som man använder mest i vardagen (gäller mig bland annat) är den snabbaste vägen för kommunikation som ger en högre grad av nyansering. Att kunna nyansera krav och önskemål tidigt i projekt är guld värt (enligt många av mina korrespondenter). Man behöver spendera mindre tid på att formulera och tolka krav.
- En mer ideologisk anledning (men en viktig sådan) är att vi som bor i Sverige har skyldighet att utveckla och hålla svenskan levande, inte minst inom IT-sektorn.
Svenska är en stor möjlighet för att verkligen ge mervärde till våra kunder, möta dem på hemmaplan, prata ett gemensamt språk. Startpunkten till den här diskussionen har varit en ny webinar som jag planerar hålla den 14 april kl 10. Webinarens titel är SharePoint i molnet.Det finns ganska mycket information om SharePoint Online och Office 365 på engelska. Det är dock ganska sparsamt med information på svenska. https://www.eventbrite.com/e/sharepoint-i-molnet-tickets-15976529229 Det här är det som väntar dig som vill delta i webinaren:
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Webinar
Why Swedish matters
I Sverige är engelskan är väldigt stark. Speciellt i IT-branschen är vi vana att ha i princip allt på engelska, från kommentarer i koden till stora upphandlingar, rapporter och dokumentation. Trots det ser jag ett stort behov av att kunna prata om IT på svenska. Det gäller både lokala företag och globala företag. Det finns flera anledningar:
- Företag i Sverige följer svenska lagar som är skrivna på svenska, för att leva upp till kraven ska man kunna formulera sig på svenska.
- Modersmål eller det språk som man använder mest i vardagen (gäller mig bland annat) är den snabbaste vägen för kommunikation som ger en högre grad av nyansering. Att kunna nyansera krav och önskemål tidigt i projekt är guld värt (enligt många av mina korrespondenter). Man behöver spendera mindre tid på att formulera och tolka krav.
- En mer ideologisk anledning (men en viktig sådan) är att vi som bor i Sverige har skyldighet att utveckla och hålla svenskan levande, inte minst inom IT-sektorn.
Svenska är en stor möjlighet för att verkligen ge mervärde till våra kunder, möta dem på hemmaplan, prata ett gemensamt språk. Startpunkten till den här diskussionen har varit en ny webinar som jag planerar hålla den 14 april kl 10. Webinarens titel är SharePoint i molnet.Det finns ganska mycket information om SharePoint Online och Office 365 på engelska. Det är dock ganska sparsamt med information på svenska. https://www.eventbrite.com/e/sharepoint-i-molnet-tickets-15976529229 Det här är det som väntar dig som vill delta i webinaren:
Tag: Alternative
Publishing Visio drawings as SVG
In my post yesterday I showed how to publish Visio files as html image maps. That was one of the alternatives. Today I’ll present how to use SVG to achieve the same goal: publish Visio diagrams in SharePoint without having the Enterprise license. There are some alternatives:
- Show Visio diagrams as pdf files on SharePoint Pages
- Embed Visio diagrams as html image maps - Read more in my previous blog post
- Embed Visio diagrams as svg pictures - This blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
SVG
SVG stands for scalable vector graphic, it is a xml-based format for defining images. It is supported in all modern browsers. Because SVG can be part of a page markup, it can be easily embedded into SharePoint.
Tag: Html
Publishing Visio drawings as SVG
In my post yesterday I showed how to publish Visio files as html image maps. That was one of the alternatives. Today I’ll present how to use SVG to achieve the same goal: publish Visio diagrams in SharePoint without having the Enterprise license. There are some alternatives:
- Show Visio diagrams as pdf files on SharePoint Pages
- Embed Visio diagrams as html image maps - Read more in my previous blog post
- Embed Visio diagrams as svg pictures - This blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
SVG
SVG stands for scalable vector graphic, it is a xml-based format for defining images. It is supported in all modern browsers. Because SVG can be part of a page markup, it can be easily embedded into SharePoint.
Publishing Visio diagrams as html image maps
I got a question from a customer: We have our processes defined in Visio, we don’t have SharePoint Enterprise CALs to use the Visio webpart. We have links in process maps. What can we do? Well there are three five ways to solve this business need:
- Find money for SharePoint Enterprise - Very expensive
- Show Visio diagrams as pdf files on SharePoint Pages - Expensive.
- Embed Visio diagrams as html image maps - Least expensive
- Embed Visio diagrams as svg pictures - Separate blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
If the business needs other features available only in Enterprise, just use the solution 1. Stop reading. If you are looking for alternatives, then consider pdf and image maps. I have seen projects where pdf files were embedded in the SharePoint Pages. It required a pdf plugin in IE, a lot of time to make it look the same in different browsers and the scroll and fixed size was still there. It was expensive because of the development and configuration time. In this blog post, I want to show the alternative number 3: embedding Visio diagrams as html image maps. This is only a Proof-of-concept so far.
Tip: Use the weakest CSS selectors
I am reading Mobile HTML5 written by Estelle Weyle. It is an awesome recap and new knowledge about html, css and javascript. I want to highlight one of tips I got: Use the weakest CSS selectors (can be found on page 204). We all know, that inline CSS and !important are evil. They have a higher level of specifity and override the standard cascade of the CSS rules. If you use !important, then it will be hard to override CSS rules when you really need it. After these two classic “evils” the evil number three is overqualifying of CSS selectors. You should really never add more classes or ids or elements than needed. Consider this: [code language=“css”] .warning { background-color: red; } [/code] It is often enough, you don’t need those: [code language=“css”] html .warning div .warning div.warning, div > .warning body p#myP.blue strong.warning [/code]
Masked Inputs
Just a quick tip today. If you are looking after masked inputs like the old ASP.NET Ajax Control Toolkit MaskedEdit, you can try jQuery plugin called Masked Input from DigitalBush or even better jquery.inputmask.
Two interesting html5-in-sharepoint presentations
[slideshare id=11031050&doc=sharepointhtml5-120113215236-phpapp02] HTML5-and-CSS3-What-About-SharePoint.pdf (968 KB) by Kyle Schaefer
accesskey
accesskey provides keyboard shortcuts. The restriction is that accesskey works well only with anchors. To bind keyboard shortcuts to other html elements, follow Scott Klarr. Here is an example of binding Alt and L:
var isAlt = false;
function addShortcuts() {
//add keyboard shortcut
document.onkeyup = function (e) {
if (e.which == 18) isAlt = false;
};
document.onkeydown = function (e) {
if (e.which == 18) isAlt = true;
// Alt-L
if (e.which == 76 && isAlt == true) {
$("#add-item").click();
return false;
}
};
}
master page for html5 and css3
A great work: v5.master. I am recommending to try it. The problem are some javascript bugs in the IE 9 when you run IE mode 9 that are necessary to enable html5 and css3 support. You can’t “save” a list item: The reason why it doesn’t work in IE, but in Chrome, Firefox, is that IE invokes some functionality that it doesn’t invoke in other browsers. Next: Enable Save button in IE9
Show a presence bubble
There is no built-in sharepoint control for the presence bubble. If you want to add this functionality on your pages you have to add it as html. Here is a sample:
private static int \_COUNTER = 0;
private const string PresenceBubble =
"<a class='ms-imnlink' href='javascript:;'>" +
"<img width='12' height='12' id='imn\_pawn\_{0}' onload=\\"IMNRC('{1}')\\" alt='My SID' " +
"src='/\_layouts/images/imnoff.png' border='0' " +
"showofflinepawn='1' sip='{2}'></a> {3}";
private static string FormatUser(SPUser user)
{
\_COUNTER++;
return string.Format(PresenceBubble, \_COUNTER, user.Email, user.GetSipAddress(SPContext.Current.Web), user.Name);
}
Rensa text från html-taggar
Ett bra exempel finns här.
using System.Text.RegularExpressions;
...
const string HTML\_TAG\_PATTERN = "<.\*?>";
static string StripHTML (string inputString)
{
return Regex.Replace(inputString, HTML\_TAG\_PATTERN, string.Empty);
}
Ladda jQuery dynamiskt till din sida
Vill du ändra innehåll, testa olika javascript-funktioner på din sida, prova något direkt i webbläsaren (utan att behöva deploya om), så är DevTools i Chrome, eller Firebug i Firefox väldigt bra verktyg. Om du har jQuery på din sida, så är det ännu bättre. Men om du inte har det, så ladda det i efterhand genom att öppna konsolen (Ctrl-Shift-J i Chrome) och kör följande rader kod (klistra in dem på en gång, och tryck på Enter):
Felsök på clientsidan med Chrome DevTools
Här är en väldigt bra video som berättar om nya devtools i Google Chrome 10. Den visar 12 tricks hur man kan underlätta felsökning av html, css och javascript. Att kunna ändra html,css och js on-the-fly är faktiskt häftigt. För mig som länge har använt Firebug i Firefox (som nu inte funkar på FF4 RC) känns devtools väldigt bra. [youtube http://www.youtube.com/watch?v=nOEw9iiopwI&w=530&h=335]
Comments from Wordpress.com
Ändra utseendet på sidan direkt i webbläsaren « Sharepoint. Kunskap. Upptäckter på resan. - Mar 1, 2011
Tag: Html5
Publishing Visio drawings as SVG
In my post yesterday I showed how to publish Visio files as html image maps. That was one of the alternatives. Today I’ll present how to use SVG to achieve the same goal: publish Visio diagrams in SharePoint without having the Enterprise license. There are some alternatives:
- Show Visio diagrams as pdf files on SharePoint Pages
- Embed Visio diagrams as html image maps - Read more in my previous blog post
- Embed Visio diagrams as svg pictures - This blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
SVG
SVG stands for scalable vector graphic, it is a xml-based format for defining images. It is supported in all modern browsers. Because SVG can be part of a page markup, it can be easily embedded into SharePoint.
Tip: Use the weakest CSS selectors
I am reading Mobile HTML5 written by Estelle Weyle. It is an awesome recap and new knowledge about html, css and javascript. I want to highlight one of tips I got: Use the weakest CSS selectors (can be found on page 204). We all know, that inline CSS and !important are evil. They have a higher level of specifity and override the standard cascade of the CSS rules. If you use !important, then it will be hard to override CSS rules when you really need it. After these two classic “evils” the evil number three is overqualifying of CSS selectors. You should really never add more classes or ids or elements than needed. Consider this: [code language=“css”] .warning { background-color: red; } [/code] It is often enough, you don’t need those: [code language=“css”] html .warning div .warning div.warning, div > .warning body p#myP.blue strong.warning [/code]
fallback for html5 placeholders
Placeholders are very handy in html5, we don’t need to fool with input values. But in SharePoint and IE we must provide fallback for placeholders if we want use them in other browsers. Here is an jQuery extension to do that:
(function ($) {
$.fn.extend({
ensurePlaceholders: function () {
var input = document.createElement('input');
var placeholderSupported = ('placeholder' in input);
if (placeholderSupported) {
return;
}
function setHints(elem) {
var $elem = $(elem);
var value = $elem.val();
if (value == "") {
var placeholder = $elem.attr("placeholder");
$elem.val(placeholder);
$elem.addClass("empty-text");
}
}
function removeHints(elem) {
var $elem = $(elem);
$elem.removeClass("empty-text");
var value = $elem.val();
var placeholder = $elem.attr("placeholder");
if (value == placeholder) {
$elem.val("");
}
}
this.find("\[placeholder\]").each(function() {
setHints(this);
});
this.on("focus", "\[placeholder\]", function(e) {
removeHints(this);
});
this.on("blur", "\[placeholder\]", function(e) {
setHints(this);
});
}
});
})(jQuery);
```Then "ensure placeholders" by running this function on a wrapper element which contains fields with the placeholder attribute:
jQuery("#form-wrapper").ensurePlaceholders();
Enable Save in IE9 mode
Wouldn’t it be nice to use html5 and css3 in SharePoint? No problems, there is actually v5 master out there, created by Kyle Schaefer. Or just use h5ml5 and css3 right away in your webparts and pages. But there is a big problem. It doesn’t work in IE9–. One of the issues (even listed by Kyle) is that “save” doesn’t work in modal dialogs where Rich Text Editor is used. Especialy it is for modal dialogs. The problem is not IE9, neither html5 and css3. After some digging in javascript code which is shipped with SharePoint I found out that the problem is some legacy javascript code which is not supported by IE9 but in IE8– (and compatibility mode). When we set IE9 mode in IE9 Dev Tools (F12) and go to Tasks list and try to create a task, we’ll get an error: It is RTE_GetEditorIFrame from init.js:
Knas på Swedbanks mobilsida
Försökte ladda mitt kontantkort idag via Swedbanks mobilsida. Det gick inte. Och det berodde inte på iPhone som jag först trodde. Orsaken var ett knasigt användande av ett html5-attribut i en annars html4-hemsida: input type=“number”: Att skriva en nolla i telefonnumret var helt omöjligt trots att sidan spottade ut fel och krävde en nolla. Med lite handpåläggning gick det! Tur att man bara kunde rader type=“number” och att sånt knasigt fel inte låg i code-behind. Testar man inte sin programvara på Swedbank?
Two interesting html5-in-sharepoint presentations
[slideshare id=11031050&doc=sharepointhtml5-120113215236-phpapp02] HTML5-and-CSS3-What-About-SharePoint.pdf (968 KB) by Kyle Schaefer
New types of inputs in html5
html5 provides more types of inputs than the classic submit and text and a few more. Here you can see an example on fiddle
master page for html5 and css3
A great work: v5.master. I am recommending to try it. The problem are some javascript bugs in the IE 9 when you run IE mode 9 that are necessary to enable html5 and css3 support. You can’t “save” a list item: The reason why it doesn’t work in IE, but in Chrome, Firefox, is that IE invokes some functionality that it doesn’t invoke in other browsers. Next: Enable Save button in IE9
Tag: Process
Publishing Visio drawings as SVG
In my post yesterday I showed how to publish Visio files as html image maps. That was one of the alternatives. Today I’ll present how to use SVG to achieve the same goal: publish Visio diagrams in SharePoint without having the Enterprise license. There are some alternatives:
- Show Visio diagrams as pdf files on SharePoint Pages
- Embed Visio diagrams as html image maps - Read more in my previous blog post
- Embed Visio diagrams as svg pictures - This blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
SVG
SVG stands for scalable vector graphic, it is a xml-based format for defining images. It is supported in all modern browsers. Because SVG can be part of a page markup, it can be easily embedded into SharePoint.
Publishing Visio diagrams as html image maps
I got a question from a customer: We have our processes defined in Visio, we don’t have SharePoint Enterprise CALs to use the Visio webpart. We have links in process maps. What can we do? Well there are three five ways to solve this business need:
- Find money for SharePoint Enterprise - Very expensive
- Show Visio diagrams as pdf files on SharePoint Pages - Expensive.
- Embed Visio diagrams as html image maps - Least expensive
- Embed Visio diagrams as svg pictures - Separate blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
If the business needs other features available only in Enterprise, just use the solution 1. Stop reading. If you are looking for alternatives, then consider pdf and image maps. I have seen projects where pdf files were embedded in the SharePoint Pages. It required a pdf plugin in IE, a lot of time to make it look the same in different browsers and the scroll and fixed size was still there. It was expensive because of the development and configuration time. In this blog post, I want to show the alternative number 3: embedding Visio diagrams as html image maps. This is only a Proof-of-concept so far.
Tag: Scalable
Publishing Visio drawings as SVG
In my post yesterday I showed how to publish Visio files as html image maps. That was one of the alternatives. Today I’ll present how to use SVG to achieve the same goal: publish Visio diagrams in SharePoint without having the Enterprise license. There are some alternatives:
- Show Visio diagrams as pdf files on SharePoint Pages
- Embed Visio diagrams as html image maps - Read more in my previous blog post
- Embed Visio diagrams as svg pictures - This blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
SVG
SVG stands for scalable vector graphic, it is a xml-based format for defining images. It is supported in all modern browsers. Because SVG can be part of a page markup, it can be easily embedded into SharePoint.
Tag: Svg
Publishing Visio drawings as SVG
In my post yesterday I showed how to publish Visio files as html image maps. That was one of the alternatives. Today I’ll present how to use SVG to achieve the same goal: publish Visio diagrams in SharePoint without having the Enterprise license. There are some alternatives:
- Show Visio diagrams as pdf files on SharePoint Pages
- Embed Visio diagrams as html image maps - Read more in my previous blog post
- Embed Visio diagrams as svg pictures - This blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
SVG
SVG stands for scalable vector graphic, it is a xml-based format for defining images. It is supported in all modern browsers. Because SVG can be part of a page markup, it can be easily embedded into SharePoint.
Tag: Vector
Publishing Visio drawings as SVG
In my post yesterday I showed how to publish Visio files as html image maps. That was one of the alternatives. Today I’ll present how to use SVG to achieve the same goal: publish Visio diagrams in SharePoint without having the Enterprise license. There are some alternatives:
- Show Visio diagrams as pdf files on SharePoint Pages
- Embed Visio diagrams as html image maps - Read more in my previous blog post
- Embed Visio diagrams as svg pictures - This blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
SVG
SVG stands for scalable vector graphic, it is a xml-based format for defining images. It is supported in all modern browsers. Because SVG can be part of a page markup, it can be easily embedded into SharePoint.
Tag: Convert
Publishing Visio diagrams as html image maps
I got a question from a customer: We have our processes defined in Visio, we don’t have SharePoint Enterprise CALs to use the Visio webpart. We have links in process maps. What can we do? Well there are three five ways to solve this business need:
- Find money for SharePoint Enterprise - Very expensive
- Show Visio diagrams as pdf files on SharePoint Pages - Expensive.
- Embed Visio diagrams as html image maps - Least expensive
- Embed Visio diagrams as svg pictures - Separate blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
If the business needs other features available only in Enterprise, just use the solution 1. Stop reading. If you are looking for alternatives, then consider pdf and image maps. I have seen projects where pdf files were embedded in the SharePoint Pages. It required a pdf plugin in IE, a lot of time to make it look the same in different browsers and the scroll and fixed size was still there. It was expensive because of the development and configuration time. In this blog post, I want to show the alternative number 3: embedding Visio diagrams as html image maps. This is only a Proof-of-concept so far.
Tag: Drawing
Publishing Visio diagrams as html image maps
I got a question from a customer: We have our processes defined in Visio, we don’t have SharePoint Enterprise CALs to use the Visio webpart. We have links in process maps. What can we do? Well there are three five ways to solve this business need:
- Find money for SharePoint Enterprise - Very expensive
- Show Visio diagrams as pdf files on SharePoint Pages - Expensive.
- Embed Visio diagrams as html image maps - Least expensive
- Embed Visio diagrams as svg pictures - Separate blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
If the business needs other features available only in Enterprise, just use the solution 1. Stop reading. If you are looking for alternatives, then consider pdf and image maps. I have seen projects where pdf files were embedded in the SharePoint Pages. It required a pdf plugin in IE, a lot of time to make it look the same in different browsers and the scroll and fixed size was still there. It was expensive because of the development and configuration time. In this blog post, I want to show the alternative number 3: embedding Visio diagrams as html image maps. This is only a Proof-of-concept so far.
Tag: Imagemap
Publishing Visio diagrams as html image maps
I got a question from a customer: We have our processes defined in Visio, we don’t have SharePoint Enterprise CALs to use the Visio webpart. We have links in process maps. What can we do? Well there are three five ways to solve this business need:
- Find money for SharePoint Enterprise - Very expensive
- Show Visio diagrams as pdf files on SharePoint Pages - Expensive.
- Embed Visio diagrams as html image maps - Least expensive
- Embed Visio diagrams as svg pictures - Separate blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
If the business needs other features available only in Enterprise, just use the solution 1. Stop reading. If you are looking for alternatives, then consider pdf and image maps. I have seen projects where pdf files were embedded in the SharePoint Pages. It required a pdf plugin in IE, a lot of time to make it look the same in different browsers and the scroll and fixed size was still there. It was expensive because of the development and configuration time. In this blog post, I want to show the alternative number 3: embedding Visio diagrams as html image maps. This is only a Proof-of-concept so far.
Tag: Visio
Publishing Visio diagrams as html image maps
I got a question from a customer: We have our processes defined in Visio, we don’t have SharePoint Enterprise CALs to use the Visio webpart. We have links in process maps. What can we do? Well there are three five ways to solve this business need:
- Find money for SharePoint Enterprise - Very expensive
- Show Visio diagrams as pdf files on SharePoint Pages - Expensive.
- Embed Visio diagrams as html image maps - Least expensive
- Embed Visio diagrams as svg pictures - Separate blog post.
- Link to Visio files that are opened using Visio Web Viewer in a new browser tab.
If the business needs other features available only in Enterprise, just use the solution 1. Stop reading. If you are looking for alternatives, then consider pdf and image maps. I have seen projects where pdf files were embedded in the SharePoint Pages. It required a pdf plugin in IE, a lot of time to make it look the same in different browsers and the scroll and fixed size was still there. It was expensive because of the development and configuration time. In this blog post, I want to show the alternative number 3: embedding Visio diagrams as html image maps. This is only a Proof-of-concept so far.
Tag: Assembly
Struggling with Taxonomy in CSOM
The parts of the CSOM for updating Taxonomy fields are really cumbersome. I mean, look at this code, nicely provided by Vadim Gremyshev (@vgrem). To set a value in a taxonomy field we have to assemble a text representation, and adding a “fake” lookup id. What is needed is a wrapper for handling Taxonomy fields. SPMeta2 and PnP don’t seem to have it yet. Another issue that I have struggled with today was the missing Microsoft.SharePoint.Client.Taxonomy.dll. If you see this error (set customErrors=“Off” in the Web.config), then you have update the reference in the Visual Studio project: Open Properties for the reference called: Microsoft.SharePoint.Client.Taxonomy and ensure that Copy To Local is set to True: For some reason, this reference added through “App for SharePoint Web Toolkit” nuget package adds a reference to an assembly from your computers GAC.
Install a custom timer job in Powershell
First we have to create a class for our timer job which inherits SPTimerJobDefinition, build it and deploy it.
public class TakanaTimer : SPJobDefinition
{
public TakanaTimer(){}
public TakanaTimer(string jobName, SPService service,
SPServer server, SPJobLockType targetType)
: base(jobName, service, server, targetType) { }
public TakanaTimer(string jobName, SPWebApplication webapp)
: base(jobName, webapp, null, SPJobLockType.ContentDatabase)
{
Title = jobName;
}
public override void Execute(Guid contentDbId)
{
Log.Info("Running Takana Timer");
}
}
There is a powershell example for this, but it has not been updated since MOSS.
Tag: GAC
Struggling with Taxonomy in CSOM
The parts of the CSOM for updating Taxonomy fields are really cumbersome. I mean, look at this code, nicely provided by Vadim Gremyshev (@vgrem). To set a value in a taxonomy field we have to assemble a text representation, and adding a “fake” lookup id. What is needed is a wrapper for handling Taxonomy fields. SPMeta2 and PnP don’t seem to have it yet. Another issue that I have struggled with today was the missing Microsoft.SharePoint.Client.Taxonomy.dll. If you see this error (set customErrors=“Off” in the Web.config), then you have update the reference in the Visual Studio project: Open Properties for the reference called: Microsoft.SharePoint.Client.Taxonomy and ensure that Copy To Local is set to True: For some reason, this reference added through “App for SharePoint Web Toolkit” nuget package adds a reference to an assembly from your computers GAC.
Install a custom timer job in Powershell
First we have to create a class for our timer job which inherits SPTimerJobDefinition, build it and deploy it.
public class TakanaTimer : SPJobDefinition
{
public TakanaTimer(){}
public TakanaTimer(string jobName, SPService service,
SPServer server, SPJobLockType targetType)
: base(jobName, service, server, targetType) { }
public TakanaTimer(string jobName, SPWebApplication webapp)
: base(jobName, webapp, null, SPJobLockType.ContentDatabase)
{
Title = jobName;
}
public override void Execute(Guid contentDbId)
{
Log.Info("Running Takana Timer");
}
}
There is a powershell example for this, but it has not been updated since MOSS.
Tag: Taxonomy
Struggling with Taxonomy in CSOM
The parts of the CSOM for updating Taxonomy fields are really cumbersome. I mean, look at this code, nicely provided by Vadim Gremyshev (@vgrem). To set a value in a taxonomy field we have to assemble a text representation, and adding a “fake” lookup id. What is needed is a wrapper for handling Taxonomy fields. SPMeta2 and PnP don’t seem to have it yet. Another issue that I have struggled with today was the missing Microsoft.SharePoint.Client.Taxonomy.dll. If you see this error (set customErrors=“Off” in the Web.config), then you have update the reference in the Visual Studio project: Open Properties for the reference called: Microsoft.SharePoint.Client.Taxonomy and ensure that Copy To Local is set to True: For some reason, this reference added through “App for SharePoint Web Toolkit” nuget package adds a reference to an assembly from your computers GAC.
Lägga till Företagsnyckelord
Det är enkelt att lägga till kolumnen företagsnyckelord. Skapa egen contenttype och lägg till fieldref.
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
Funkar utmärkt t.ex. om du ärver ContentTypen från Announcements. Lite svårare är det med Dokument. I själva verket läggs till fler kolumner för att det ska fungera. I Announcements finns de redan. Men i dokument måste du lägga till dem extra:
<!-- Enterprise Keywords-->
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
<!-- in order keywords to work, two additional fields have to be created-->
<!-- TaxKeywordTaxHTField -->
<FieldRef ID="{1390a86a-23da-45f0-8efe-ef36edadfb39}"/>
<!-- TaxCatchAll -->
<FieldRef ID="{f3b0adf9-c1a2-4b02-920d-943fba4b3611}"/>
Utan TaxKeywordTaxHTField uppstår fel av typen: “Kan inte hämta värdet från kolumnen {00000000…}”.
Tag: Ossetian
A new Chuvash keyboard layout
The Chuvash keyboard layout has been the Russian keyboard layout with 4 Chuvash letters that are typed by pressing the right Alt button plus the base letter. Some of the arguments have been
- Users don’t need to switch or learn a new keyboard layout. They can keep on typing Russian texts and sometimes Chuvash texts
- It is easy to communicate about how the right Alt button works. The Right-Alt-technique is also used in Esperanto, Polish and other languages.
- The letters are placed according the labels
Recently two major events happened that made the question about the Chuvash keyboard layout important:
Tag: Tatar
A new Chuvash keyboard layout
The Chuvash keyboard layout has been the Russian keyboard layout with 4 Chuvash letters that are typed by pressing the right Alt button plus the base letter. Some of the arguments have been
- Users don’t need to switch or learn a new keyboard layout. They can keep on typing Russian texts and sometimes Chuvash texts
- It is easy to communicate about how the right Alt button works. The Right-Alt-technique is also used in Esperanto, Polish and other languages.
- The letters are placed according the labels
Recently two major events happened that made the question about the Chuvash keyboard layout important:
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Windows
A new Chuvash keyboard layout
The Chuvash keyboard layout has been the Russian keyboard layout with 4 Chuvash letters that are typed by pressing the right Alt button plus the base letter. Some of the arguments have been
- Users don’t need to switch or learn a new keyboard layout. They can keep on typing Russian texts and sometimes Chuvash texts
- It is easy to communicate about how the right Alt button works. The Right-Alt-technique is also used in Esperanto, Polish and other languages.
- The letters are placed according the labels
Recently two major events happened that made the question about the Chuvash keyboard layout important:
Load git into PowerShell
Just a little productivity tip. If you use git on Windows, you probably already have the Github for Windows application. This application adds the Git Shell:
The Git Shell will open a PowerShell window and execute shell.ps1 from the Github directory:
What it won’t do is to load your personal PowerShell profile. I want to use my PowerShell profile that creates some links and adjust the look-and-feel and the promt of the shell. By the way I have published my profile.ps1 as a gist:
It is time to standardize the Chuvash Keyboard Layout
[caption id=“attachment_3165” align=“alignnone” width=“630”] Proto-Bulgarian Runes (Chuvash language is the closest language to the Proto-Bulgar language). Wonder if they are supported in Unicode :)[/caption] The Chuvash Computer Keyboard layouts have existed since 2001, but due to the lack for Unicode support we were forced to use the look-alike letters from other latin-based keyboard layouts. On Linux The Chuvash keyboard layout was added in [2007](https://bugs.freedesktop.org/show_bug.cgi?id=11246 “The original “bug” in FreeDesktop bugzilla”) and Linux is still the only operating system that has a native keyboard layout for Chuvash language. On Windows we have used the Keyboard Layout Creator and distributed it as an executable file. Today, when Windows XP is not supported anymore, the majority of users now have full support for the correct Chuvash letters from the Extended Cyrillic table. These four Chuvash letters are “additional” to the Russian alphabet: Ӑ, Ӗ, Ҫ and Ӳ. Now when new “keyboards” appear on Android, in web browser (they use the standardized letters) and hopefully in Windows and iOS, we have to consider put the correct letters into the keyboard layouts. For Linux the /usr/share/X11/xkb/symbols/ru
file has to be updated: [code] // Chuvash language layout // Anatoly Mironov @mirontoli partial alphanumeric_keys xkb_symbols “cv” { include “ru(winkeys)” name[Group1]= “Chuvash”; key.type[group1]=“FOUR_LEVEL”; key { [ Cyrillic_u, Cyrillic_U, 0x010004f3, 0x010004f2 ] }; key { [ Cyrillic_ie, Cyrillic_IE, 0x010004d7, 0x010004d6 ] }; key { [ Cyrillic_a, Cyrillic_A, 0x010004d1, 0x010004d0 ] }; key { [ Cyrillic_es, Cyrillic_ES, 0x010004ab, 0x010004aa ] }; include “level3(ralt_switch)” }; [/code]
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Windows 8: shutdown button on your start and desktop
If you think that “Go to corner” -> Settings -> Power -> Shut down are three steps to much if you just want to shutdown your Windows 8 machine, than do as I did: create a shortcut on you desktop and a tile on your start screen. Create a shortcut as usual: Write in the location field:
shutdown /s /t 0
Name it something, why not “shutdown”? Change the default icon: There it is. Now we can pin it to Start: Done. Now, if you want to shutdown, you have to click only once: Enjoy!
Windows 8 preview
I have tested the Windows 8 developer preview. VMWare player 3 didn’t manage it, so I installed VirtualBox and it ran very well. One thing I did was to enable full screen on VirtualBox. Here is the list of features you get if you install the developer preview:
- Windows SDK for Metro style apps
- Microsoft Visual Studio 11 Express for Windows Developer Preview
- Microsoft Expression Blend 5 Developer Preview
- 28 Metro style apps including the BUILD Conference app
powershell_ise
Powershell ISE (Integrated Scripting Environment) är ett bra verktyg för att skriva powershell-skript med färgmarkering och möjligheten att testköra det. Synd bara att det inte är aktiverat ifrån början i Server 2008. För att [aktivera](Import-Module ServerManager 2 Add-Windowsfeature PowerShell-ISE ) kör följande kommandon i powershell:
Import-Module ServerManager
Add-Windowsfeature PowerShell-ISE
För att sedan starta powershell kör:
powershell\_ise
local dns
Hur gör man om man vill ha två olika internet-adresser för olika inloggningar. Om man har DNS inställt rätt - inga problem. Men hur gör man för att testa det på sin lokala maskin. Man kan ändra dns-information på sin maskin. För detta ska filen [hosts](http://en.wikipedia.org/wiki/Hosts_%28file% 29#Content_and_location) uppdateras. I Windows tryck på Start och i sökrutan skriv:
%SystemRoot%\\system32\\drivers\\etc\\hosts
Den här filen är raka motsvarigheten till /etc/hosts i Linux. I filen som öppnas lägg till följande rader som sist:
Tag: Xkb
A new Chuvash keyboard layout
The Chuvash keyboard layout has been the Russian keyboard layout with 4 Chuvash letters that are typed by pressing the right Alt button plus the base letter. Some of the arguments have been
- Users don’t need to switch or learn a new keyboard layout. They can keep on typing Russian texts and sometimes Chuvash texts
- It is easy to communicate about how the right Alt button works. The Right-Alt-technique is also used in Esperanto, Polish and other languages.
- The letters are placed according the labels
Recently two major events happened that made the question about the Chuvash keyboard layout important:
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
It is time to standardize the Chuvash Keyboard Layout
[caption id=“attachment_3165” align=“alignnone” width=“630”] Proto-Bulgarian Runes (Chuvash language is the closest language to the Proto-Bulgar language). Wonder if they are supported in Unicode :)[/caption] The Chuvash Computer Keyboard layouts have existed since 2001, but due to the lack for Unicode support we were forced to use the look-alike letters from other latin-based keyboard layouts. On Linux The Chuvash keyboard layout was added in [2007](https://bugs.freedesktop.org/show_bug.cgi?id=11246 “The original “bug” in FreeDesktop bugzilla”) and Linux is still the only operating system that has a native keyboard layout for Chuvash language. On Windows we have used the Keyboard Layout Creator and distributed it as an executable file. Today, when Windows XP is not supported anymore, the majority of users now have full support for the correct Chuvash letters from the Extended Cyrillic table. These four Chuvash letters are “additional” to the Russian alphabet: Ӑ, Ӗ, Ҫ and Ӳ. Now when new “keyboards” appear on Android, in web browser (they use the standardized letters) and hopefully in Windows and iOS, we have to consider put the correct letters into the keyboard layouts. For Linux the /usr/share/X11/xkb/symbols/ru
file has to be updated: [code] // Chuvash language layout // Anatoly Mironov @mirontoli partial alphanumeric_keys xkb_symbols “cv” { include “ru(winkeys)” name[Group1]= “Chuvash”; key.type[group1]=“FOUR_LEVEL”; key { [ Cyrillic_u, Cyrillic_U, 0x010004f3, 0x010004f2 ] }; key { [ Cyrillic_ie, Cyrillic_IE, 0x010004d7, 0x010004d6 ] }; key { [ Cyrillic_a, Cyrillic_A, 0x010004d1, 0x010004d0 ] }; key { [ Cyrillic_es, Cyrillic_ES, 0x010004ab, 0x010004aa ] }; include “level3(ralt_switch)” }; [/code]
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Bashkir
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Belarusian
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Cyrillic
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Erzya
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Kalmyk
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Kazakh
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Komi
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Mari
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Moksha
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Mongol
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Sakha
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Ubuntu
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
It is time to standardize the Chuvash Keyboard Layout
[caption id=“attachment_3165” align=“alignnone” width=“630”] Proto-Bulgarian Runes (Chuvash language is the closest language to the Proto-Bulgar language). Wonder if they are supported in Unicode :)[/caption] The Chuvash Computer Keyboard layouts have existed since 2001, but due to the lack for Unicode support we were forced to use the look-alike letters from other latin-based keyboard layouts. On Linux The Chuvash keyboard layout was added in [2007](https://bugs.freedesktop.org/show_bug.cgi?id=11246 “The original “bug” in FreeDesktop bugzilla”) and Linux is still the only operating system that has a native keyboard layout for Chuvash language. On Windows we have used the Keyboard Layout Creator and distributed it as an executable file. Today, when Windows XP is not supported anymore, the majority of users now have full support for the correct Chuvash letters from the Extended Cyrillic table. These four Chuvash letters are “additional” to the Russian alphabet: Ӑ, Ӗ, Ҫ and Ӳ. Now when new “keyboards” appear on Android, in web browser (they use the standardized letters) and hopefully in Windows and iOS, we have to consider put the correct letters into the keyboard layouts. For Linux the /usr/share/X11/xkb/symbols/ru
file has to be updated: [code] // Chuvash language layout // Anatoly Mironov @mirontoli partial alphanumeric_keys xkb_symbols “cv” { include “ru(winkeys)” name[Group1]= “Chuvash”; key.type[group1]=“FOUR_LEVEL”; key { [ Cyrillic_u, Cyrillic_U, 0x010004f3, 0x010004f2 ] }; key { [ Cyrillic_ie, Cyrillic_IE, 0x010004d7, 0x010004d6 ] }; key { [ Cyrillic_a, Cyrillic_A, 0x010004d1, 0x010004d0 ] }; key { [ Cyrillic_es, Cyrillic_ES, 0x010004ab, 0x010004aa ] }; include “level3(ralt_switch)” }; [/code]
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Hello world in node.js
I know, node.js has been present for a while. But I actually had no time to try it. I was surprised that now it is very straight forward to start with node.js. Allright, everything begins with Hello world. Eventhough it is available for allmost all combinations of operating systems and servers, the easiest way to test it was actually Ubuntu. To install just run:
sudo apt-get install nodejs
```Then make a new directory and create the hello.js:
mkdir hello cd hello vi hello.js
MongoDB shell, learn directly in browser
Are you also curious about NoSQL databases. Well, MongoDB is one of the most known ones. MongoDB has a javascript syntax (json), I like it. Try out the interactive shell at the mongodb site.
Quickstart on Ubuntu
To test it on Ubuntu, just install an existing apt-package:
sudo apt-get install mongodb
Tag: Udmurt
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Ukrainian
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Unicode
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Chuvash localization
Recently I wanted to add Chuvash localization to the jQuery UI datepicker. Unfortunately, my pull request was rejected. The reason is that jQuery UI will be using Globalize framework: The jQuery Globalize framework relies on CLDR, so What is Unicode CLDR (Common Locale Data Repository)?
The Unicode CLDR provides key building blocks for software to support the world’s languages, with the largest and most extensive standard repository of locale data available. This data is used by a wide spectrum of companies for their software internationalization and localization, adapting software to the conventions of different languages for such common software tasks
It is time to standardize the Chuvash Keyboard Layout
[caption id=“attachment_3165” align=“alignnone” width=“630”] Proto-Bulgarian Runes (Chuvash language is the closest language to the Proto-Bulgar language). Wonder if they are supported in Unicode :)[/caption] The Chuvash Computer Keyboard layouts have existed since 2001, but due to the lack for Unicode support we were forced to use the look-alike letters from other latin-based keyboard layouts. On Linux The Chuvash keyboard layout was added in [2007](https://bugs.freedesktop.org/show_bug.cgi?id=11246 “The original “bug” in FreeDesktop bugzilla”) and Linux is still the only operating system that has a native keyboard layout for Chuvash language. On Windows we have used the Keyboard Layout Creator and distributed it as an executable file. Today, when Windows XP is not supported anymore, the majority of users now have full support for the correct Chuvash letters from the Extended Cyrillic table. These four Chuvash letters are “additional” to the Russian alphabet: Ӑ, Ӗ, Ҫ and Ӳ. Now when new “keyboards” appear on Android, in web browser (they use the standardized letters) and hopefully in Windows and iOS, we have to consider put the correct letters into the keyboard layouts. For Linux the /usr/share/X11/xkb/symbols/ru
file has to be updated: [code] // Chuvash language layout // Anatoly Mironov @mirontoli partial alphanumeric_keys xkb_symbols “cv” { include “ru(winkeys)” name[Group1]= “Chuvash”; key.type[group1]=“FOUR_LEVEL”; key { [ Cyrillic_u, Cyrillic_U, 0x010004f3, 0x010004f2 ] }; key { [ Cyrillic_ie, Cyrillic_IE, 0x010004d7, 0x010004d6 ] }; key { [ Cyrillic_a, Cyrillic_A, 0x010004d1, 0x010004d0 ] }; key { [ Cyrillic_es, Cyrillic_ES, 0x010004ab, 0x010004aa ] }; include “level3(ralt_switch)” }; [/code]
Tag: Yakut
Creating a Russian Extended Keyboard Layout
In my spare time I am currently working on a Chuvash-Tatar phrasebook. I have used the Chuvash and Tatar keyboard layout on Linux. They work fine, but switching between them takes time. So I decided to add Tatar letters (right Alt + combinations) to my Chuvash keyboard layout. While adding it I found a combined Russian-Ukranian United keyboard layout and I thought:
- What if I create a new keyboard layout for Russian that will have almost all additional Cyrillic letters? A Russian Extended keyboard layout could be based on the Russian keyboard layout and have other non-Russian letters.
This is what I have come up to so far. The definition can be found on my project at github: russian-extended-kbd. I will update it more and provide more info about how it is organized and how to install it. I’ll also try to implement it for Windows and maybe for Mac (I doubt it, everything is so locked-down there). This is just a proof-of-concept so far. It only works on Linux (with xkb). Nevertheless, some key characteristics of this layout:
Tag: Cldr
Chuvash localization
Recently I wanted to add Chuvash localization to the jQuery UI datepicker. Unfortunately, my pull request was rejected. The reason is that jQuery UI will be using Globalize framework: The jQuery Globalize framework relies on CLDR, so What is Unicode CLDR (Common Locale Data Repository)?
The Unicode CLDR provides key building blocks for software to support the world’s languages, with the largest and most extensive standard repository of locale data available. This data is used by a wide spectrum of companies for their software internationalization and localization, adapting software to the conventions of different languages for such common software tasks
Tag: Mirontoli
Chuvash localization
Recently I wanted to add Chuvash localization to the jQuery UI datepicker. Unfortunately, my pull request was rejected. The reason is that jQuery UI will be using Globalize framework: The jQuery Globalize framework relies on CLDR, so What is Unicode CLDR (Common Locale Data Repository)?
The Unicode CLDR provides key building blocks for software to support the world’s languages, with the largest and most extensive standard repository of locale data available. This data is used by a wide spectrum of companies for their software internationalization and localization, adapting software to the conventions of different languages for such common software tasks
Announcing web based SQL Max Memory calculator
Today I want to announce a tiny web application for calculating max memory in the SQL Server to improve the overall performance in you SharePoint environment: SQL Max Memory Calculator. One of the important actions to improve the performance in SharePoint is fine tuning of the SQL Databases. Regarding the databases one of the crucial settings is the Max Memory Setting. You can read more about database optimizations for SharePoint in a whitepaper written by SharePoint MVP Vlad Catrinescu. The document is available on the SharePoint Community Web Site:
Tag: Best Practice
Bypass all custom jslink
Client Side Rendering (CSR) and jslink are great for customizing lists and forms in SharePoint. In my current project we use it a lot of it. A disadvantage of that path, although, is that it might occur javascript errors, during the development phase, but also in production. We do, of course, our best to leverage the best jslink code, but unfortunately we have to live with the fact that errors can occur, especially when we use it for NewForm, EditForm, DisplayForm and View (in list and grid). If an error occurs, it won’t stop the rest of javascript (it is wrapped in try and catch by SharePoint), but the fields will still not function as intended. It can also be some “corrupt” or old data in the field value that will “break” the jslink code. I would like to suggest one little fix, an idea I’ve come up to in my jslink-heavy project:
javascript: Umbrella pattern
There are two great patterns for organizing javascript code: Prototype and Module pattern. More about them later in this post. But in reality I still see much of spagghetti Just an example: SharePoint 101 code samples. They are indeed very simple and isolated examples. And many projects use this simple way in mind when they begin. But when javascript code grows, it becomes a monster. Have you seen this biest? How is this monster created? Through good intentions (like everything else) in form of KISS mantra, to little time and the “commit and run”-behavior, or the worst: “I am c#-er, not Front-End-Developer”-spirit. In this post I’ll introduce a kind of compromise the Umbrella pattern. But before that, let’s see how to recognize the spagghetti monster in javascript:
Tag: Url
Bypass all custom jslink
Client Side Rendering (CSR) and jslink are great for customizing lists and forms in SharePoint. In my current project we use it a lot of it. A disadvantage of that path, although, is that it might occur javascript errors, during the development phase, but also in production. We do, of course, our best to leverage the best jslink code, but unfortunately we have to live with the fact that errors can occur, especially when we use it for NewForm, EditForm, DisplayForm and View (in list and grid). If an error occurs, it won’t stop the rest of javascript (it is wrapped in try and catch by SharePoint), but the fields will still not function as intended. It can also be some “corrupt” or old data in the field value that will “break” the jslink code. I would like to suggest one little fix, an idea I’ve come up to in my jslink-heavy project:
javascript: Remove illegal characters in url
Recently I needed to create valid urls for pages using javascript. Also this time I thought it must be some out-of-the-box code for that in SharePoint. The first thing I came up was the “Add page” dialog. I found that the actual dialog was in the _layouts virtual folder:
/\_layouts/15/CreatePublishingPageDialog.aspx
```Bingo, it does the validation in the client side. This is the responsible javascript function that resides directly in the page: \[sourcecode language="javascript"\] function UpdateUrl() { LoadTermContextInfo(); var hiddenPageUrlLabelExtensionClientId = "<%=hiddenPageUrlLabelExtension.ClientID%>"; var hiddenPageUrlLabelExtension = document.getElementById(hiddenPageUrlLabelExtensionClientId); var pageNamePreviewUrlLabelClientId = "<%=pageNamePreviewUrlLabel.ClientID%>"; var pageNamePreviewUrlLabel = document.getElementById(pageNamePreviewUrlLabelClientId); if( pageNamePreviewUrlLabel != null ) { var nameInputTextBoxClientId = "<%=nameInput.ClientID%>"; var nameInputTextBox = document.getElementById(nameInputTextBoxClientId); var allowSpaces = false; if( GetInnerText(hiddenPageUrlLabelExtension) != "" ) { var suggestUrlValue = ""; for (var i=0; i < nameInputTextBox.value.length; i++) { var currentChar = nameInputTextBox.value.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } UpdatePreviewUrl( suggestUrlValue ); } else { if( g\_timerId != 0 ) { window.clearTimeout(g\_timerId); } g\_timerId = window.setTimeout(OnFriendlyUrlNameChanged, 500); } } } \[/sourcecode\] This function iterates through all the characters in the page url and removes the illegal characters. The space, plus sign and the dot become a hyphen. To determine if a character is illegal, it relies on another javascript function called: `IndexOfIllegalCharInUrlLeafName`. This function can be found in the init.js or init.debug.js: \[sourcecode language="javascript"\] function IndexOfIllegalCharInUrlLeafName(strLeafName) { for (var i = 0; i < strLeafName.length; i++) { var ch = strLeafName.charCodeAt(i); if (strLeafName.charAt(i) == '.' && (i == 0 || i == strLeafName.length - 1)) return i; if (ch < 160 && (strLeafName.charAt(i) == '/' || !LegalUrlChars\[ch\])) return i; } return -1; } \[/sourcecode\] This function checks a char against an array of all characters: `LegalUrlChars` from the same file: init.js. [![ill_002](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png)](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png) To use this UpdateUrl function, we have to remove the references to the fields from the Add Page Dialog. Of course, we won't overwrite this original function, we don't want to break the SharePoint OOB functionality. Here is how my new function looks like: \[sourcecode language="javascript"\] var takana = {}; function takana.updateUrl(url) { var allowSpaces = false; if( url ) { var suggestUrlValue = ""; var length = url.length; for (var i=0; i < length; i++) { var currentChar = url.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } } } \[/sourcecode\]
#### Server Side
For those of you who want run this operation on the server, here is the code written in C#: \[sourcecode language="csharp"\] //" # % & \* : < > ? \\ / { } ~ | var illegalChars = @"\[""#%&\\\*:\\<\\>\\?\\\\\\/\\{\\}~\\|\]"; pageName = Regex.Replace(pageName, illegalChars, string.Empty); var punctuation = @"\[\\s\\.;\\+\]"; pageName = Regex.Replace(pageName, punctuation, "-"); //remove "--" pageName = Regex.Replace(pageName, @"\\-{2,}", "-"); pageName = string.Format("{0}.aspx", pageName); //do it like the built-in dialog, lower case pageName = pageName.ToLower(); \[/sourcecode\] Don't forget to leave a comment if you find this post useful.
## Comments from Wordpress.com
####
[Johannes Milling](http://discoveringsharepoint.wordpress.com "johannesmilling@hotmail.com") - <time datetime="2013-08-23 09:53:30">Aug 5, 2013</time>
Good post! :)
<hr />
Parameterize a javascript object and create url
If you want to add some parameters to an url which you want to open, you can use jQuery.param function:
var url = "some\_url";
var params = {
name: "Setner",
email: "setner@narspi.name",
mobile: "123456789"
};
var search = "?" + $.param(p);
url += search;
```It is handy, indeed. In an environment without jQuery (are there some?:) ) you can just iterate an object and join properties:
var url = “some_url”; var params = { name: “Setner”, email: “setner@narspi.name”, mobile: “123456789” }; if (url.match("/\?/g") == null) { url += “?”; } else { url += “&”; } var search = “”; for(var p in params) { search += [p, params[p]].join("="); } url += search;
Tag: Ajax
Client Side Rendering with Async dependencies
Yesterday I asked a question on SharePoint StackExchange:
I also asked Elio Struyf on Twitter: https://twitter.com/eliostruyf/status/540473976255152128 Good idea, Elio Struyf! Now I want to try it out.
Preparations
In this case I’ll be using my example from my blog post yesterday: Drag and Drop Image using Client Side Rendering I have created a new list and added a lookup field to my previous list. What I get is a Title of the lookup item, but not my custom field called DragAndDrop. In my test I will try to load the DragAndDrop Image using an ajax call and rendering it after Client Side Rendering is done with my item. To be complete, I want to show some screenshots for my lookup field: It will result in this OOTB rendering:
Simple stopwatch in javascript
If some javascript code takes too much time to execute, you probably want to see what time your code or a part of the code takes to run. I found an idea in Dave Cranes Ajax in Action. The book is a little bit old and the code provided below has been changed and simplified:
var stopwatch = {};
stopwatch.watches = \[\];
stopwatch.getWatch = function(id, startNow) {
var watch = stopwatch.watches\[id\];
if (!watch) {
watch = new stopwatch.StopWatch(id);
}
if (startNow) {
watch.start();
}
return watch;
};
stopwatch.StopWatch = function (id) {
this.id = id;
stopwatch.watches\[id\] = this;
this.events = \[\];
this.total = 0;
this.count = 0;
};
stopwatch.StopWatch.prototype.start = function() {
this.current = new stopwatch.TimedEvent();
};
stopwatch.StopWatch.prototype.stop = function() {
if (this.current) {
this.current.stop();
this.events.push(this.current);
this.count++;
this.total += this.current.duration;
this.current = null;
}
};
stopwatch.TimedEvent = function () {
this.start = new Date();
this.duration = 0;
};
stopwatch.TimedEvent.prototype.stop = function() {
var stop = new Date();
this.duration = stop - this.start;
};
jQuery tmplItem and no ids
tmplItem() works even without ids. To get the current data:
$(this).tmplItem().data;
```If you want to remove, just invoke the ajax and remove with [$.parents](http://api.jquery.com/parents/):
$(this).parents(“li”).remove();
##### Updating data inside tmplItems
If you want to achieve some fancy dependency tracking, consider [knockout.js](http://knockoutjs.com/). But if you just want to update the data object inside a tmplItem, just change the object and call update:
var t = $(this).tmplItem(); var obj = t.data; obj.Address = “hello avenue”; t.update();
Update list items with listdata.svc
In one of my previous posts I showed how to retrieve data from listdata.svc with jQuery $.getJSON method. Getting data is very simple, listdata.svc provides a powerful restful interface with filtering, expanding and other features. Read the best and short introduction to listdata.svc by Suneet Sharma or a more detailed and technical article about filters, functions and operators by Mike Flasko at Microsoft with short examples here. Now back to listdata.svc in the SharePoint environment. Corey Roth provides a good images and sample results. For REST the “http verbs” are very important: GET, POST, PUT, DELETE.. SharePoint RESTful interface defines these verbs like that:
ASP.NET Ajax Toolkit
To integrate ASP.NET Ajax Toolkit is not the most straight forward task in SharePoint. If you want to take the risk, “Inspired by Technology” provides the best guide so far.
Tag: Async
Client Side Rendering with Async dependencies
Yesterday I asked a question on SharePoint StackExchange:
I also asked Elio Struyf on Twitter: https://twitter.com/eliostruyf/status/540473976255152128 Good idea, Elio Struyf! Now I want to try it out.
Preparations
In this case I’ll be using my example from my blog post yesterday: Drag and Drop Image using Client Side Rendering I have created a new list and added a lookup field to my previous list. What I get is a Title of the lookup item, but not my custom field called DragAndDrop. In my test I will try to load the DragAndDrop Image using an ajax call and rendering it after Client Side Rendering is done with my item. To be complete, I want to show some screenshots for my lookup field: It will result in this OOTB rendering:
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
Android: Asynchronously download images
In the Malmöfestivalen for Android where I participate we wanted to show thumbnails of events in lists. We have urls of thumbnails from Malmofestivalen API. This information is stored in a sqlite database and a SimpleCursorAdapter is used for getting the events from the database. It is possible to bind the urls to ImageView objects (by downloading the stream: 1, 2, 3). The problem is in a listactivity with many images it will freeze. So it must be an AsyncTask, and it should be some kind of local cache to avoid loading same images over and over again. Fortunately there is already ImageDownloader class provided in the android blog post: Multithreading For Performance . The next step is to create custom adapter and extend from SimpleCursorAdapter: EventCursorAdapter, like described on Android-er and and SP-Technolab: [sourcecode language=“java”]public class EventCursorAdapter extends SimpleCursorAdapter { private final ImageDownloader imageDownloader = new ImageDownloader(); public EventCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { super(context, layout, c, from, to); imageDownloader.setMode(ImageDownloader.Mode.NO_DOWNLOADED_DRAWABLE); } @Override public View getView(int position, View convertView, ViewGroup parent) { View row = super.getView(position, convertView, parent); Cursor cursor = getCursor(); cursor.moveToPosition(position); ImageView iv = (ImageView) row.findViewById(R.id.eventitemrowimage); String url = cursor.getString(cursor.getColumnIndex(EventProvider.EVENT_KEY_URISMALLIIMAGE)); if (url.length() > 0) { imageDownloader.download(url, iv); } String start = cursor.getString(cursor.getColumnIndex(EventProvider.EVENT_KEY_STARTDATE)); String end = cursor.getString(cursor.getColumnIndex(EventProvider.EVENT_KEY_ENDDATE)); String dateString = DateHelper.createShortDateResume(start, end); TextView tv = (TextView) row.findViewById(R.id.eventitemrowtimeresume); tv.setText(dateString); return row; } }[/sourcecode] In this code the view is created by the super class and then it is modified, the alternative is to “inflate the view” completely self. The result is an event list which opens directly and loads thumbnails asynchronously: listactivity with images
XMLHttpRequest the hard way
$.ajax is great, it hides much of the complexity. But sometimes we need to work with “raw” javascript :) So let’s look behind the scenes. The XMLHttpRequest (or just XHR) is used to open a connection to a server without a page reload. Internet Explorer calls it ActiveXObject and it differs in IE versions. Wikipedia article gives a good example how to create one constructor for all browsers: [sourcecode language=“javascript”]if (typeof XMLHttpRequest == “undefined”) XMLHttpRequest = function () { try { return new ActiveXObject(“Msxml2.XMLHTTP.6.0”); } catch (e) {} try { return new ActiveXObject(“Msxml2.XMLHTTP.3.0”); } catch (e) {} try { return new ActiveXObject(“Microsoft.XMLHTTP”); } catch (e) {} //Microsoft.XMLHTTP points to Msxml2.XMLHTTP and is redundant throw new Error(“This browser does not support XMLHttpRequest.”); };[/sourcecode] The remainder is more or less the same among the browsers. We open a connection defining the HTTP verb, URI and async mode (true or false): [sourcecode language=“javascript”]var xhr = new XMLHttpRequest(); xhr.open(“GET”, “/_vti_bin/listdata.svc”, true); xhr.onreadystatechange = onStateChange; xhr.send(null);[/sourcecode] Pay attention to onreadystatechange (only lower case letters). If we choose async=false, the UI waits for the response which is not so kind to users, but maybe it is easier to write a program. Well, there is actually no option but to have async=true. To provide the callback for success and error we can write the responding function onreadystatechange. This function will be called every time the state is changed. There are 5 states:
Tag: Requestexecutor
Client Side Rendering with Async dependencies
Yesterday I asked a question on SharePoint StackExchange:
I also asked Elio Struyf on Twitter: https://twitter.com/eliostruyf/status/540473976255152128 Good idea, Elio Struyf! Now I want to try it out.
Preparations
In this case I’ll be using my example from my blog post yesterday: Drag and Drop Image using Client Side Rendering I have created a new list and added a lookup field to my previous list. What I get is a Title of the lookup item, but not my custom field called DragAndDrop. In my test I will try to load the DragAndDrop Image using an ajax call and rendering it after Client Side Rendering is done with my item. To be complete, I want to show some screenshots for my lookup field: It will result in this OOTB rendering:
Tag: Base64
Drag and Drop Image using Client Side Rendering
I continue my series about Client Side Rendering (CSR) and jsgrid. Today I want to try a custom field where users can drag and drop images. The inspiration comes from:
- AutoUpload field written by Anton Vishnyakov and
- Base64 Drag and drop written by oroboto
What I want to achieve is:
- A custom field that is rendered with jslink
- Users can drag and drop small pictures (thumbnails) into the field
- A base64 image representation is saved as the field value
- Optionally implement pasting images using Clipboard API
Step 1 Create a field with a custom jslink
Create a field of type Note. I am using the PnP Core Extensions to make it quickier: ’ My jslink file is very simple to begin with: [code language=“javascript”] (function () { ‘use strict’; function view(ctx, field) { return “hello”; } var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘DragAndDropImage’: { ‘View’: view, ‘DisplayForm’: view //‘EditForm’: verySimpleNewAndEdit, //‘NewForm’: verySimpleNewAndEdit } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] This will result in the following display form. Just outputting “hello” indicates that my field is jslink are registered correctly:
Tag: Customfield
Drag and Drop Image using Client Side Rendering
I continue my series about Client Side Rendering (CSR) and jsgrid. Today I want to try a custom field where users can drag and drop images. The inspiration comes from:
- AutoUpload field written by Anton Vishnyakov and
- Base64 Drag and drop written by oroboto
What I want to achieve is:
- A custom field that is rendered with jslink
- Users can drag and drop small pictures (thumbnails) into the field
- A base64 image representation is saved as the field value
- Optionally implement pasting images using Clipboard API
Step 1 Create a field with a custom jslink
Create a field of type Note. I am using the PnP Core Extensions to make it quickier: ’ My jslink file is very simple to begin with: [code language=“javascript”] (function () { ‘use strict’; function view(ctx, field) { return “hello”; } var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘DragAndDropImage’: { ‘View’: view, ‘DisplayForm’: view //‘EditForm’: verySimpleNewAndEdit, //‘NewForm’: verySimpleNewAndEdit } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] This will result in the following display form. Just outputting “hello” indicates that my field is jslink are registered correctly:
Tag: Jsgrid
Drag and Drop Image using Client Side Rendering
I continue my series about Client Side Rendering (CSR) and jsgrid. Today I want to try a custom field where users can drag and drop images. The inspiration comes from:
- AutoUpload field written by Anton Vishnyakov and
- Base64 Drag and drop written by oroboto
What I want to achieve is:
- A custom field that is rendered with jslink
- Users can drag and drop small pictures (thumbnails) into the field
- A base64 image representation is saved as the field value
- Optionally implement pasting images using Clipboard API
Step 1 Create a field with a custom jslink
Create a field of type Note. I am using the PnP Core Extensions to make it quickier: ’ My jslink file is very simple to begin with: [code language=“javascript”] (function () { ‘use strict’; function view(ctx, field) { return “hello”; } var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘DragAndDropImage’: { ‘View’: view, ‘DisplayForm’: view //‘EditForm’: verySimpleNewAndEdit, //‘NewForm’: verySimpleNewAndEdit } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] This will result in the following display form. Just outputting “hello” indicates that my field is jslink are registered correctly:
Disabling a column in Quick Edit
In my project I have a column called Request Status. This column is not shown in any forms, meaning users should not edit, because it is controlled through the app. Nevertheless it is editable in the Quick Edit. Yesterday I wrote about jsgrid in my blog. Now comes more. Today I’ll share a little practical solution how one can disable editing a field in Quick Edit. The field is edited in jsgrid, but to disable it, we only have set the property called AllowGridEditing to false on our column (not even touching the heavy jsgrid api). We can do in the OnPreRender event in our Client Side Rendering (CSR) registration. Having the context object we have access to the Fields (ContextInfo.ListSchema.Field): [code language=“javascript” highlight=“6,9”] (function () { var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.OnPreRender = function(ctx) { var statusField = ctx.ListSchema.Field.filter(function(f) { return f.Name === ‘Request_x0020_Status’; }); if (statusField) { statusField[0].AllowGridEditing = false; } } SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] Another way is to implement the display form: [code language=“javascript”] (function () { var view = function (ctx, field) { if (ctx.inGridMode) { field.AllowGridEditing = false; } return window.RenderFieldValueDefault(ctx); }; var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘Request_x0020_Status’: { ‘View’: view } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code]
JSGrid Basics
JSGrid is the javascript framework in SharePoint used in Quick Edit View (previously Datasheet View). There are a few very good blog posts on this topic (See below in “Sources”). Nevertheless the fact is that jsgrid and working with quick edit from a developer’s perspective is a huge undiscovered area. Articles I have seen are intended for advanced developers. The goal with my post today is to outline the very basics of working with JSGrid. When you know the basics you will be more comfortable to discover and try out more. The example I want to show is a jsgrid code for a “VerySimpleColumn”. The source code can be found on gist.github.com To focus on jsgrid, I assume you have knowledge and some experience of working with jslink, which is related to jsgrid.
Tag: Template
Disabling a column in Quick Edit
In my project I have a column called Request Status. This column is not shown in any forms, meaning users should not edit, because it is controlled through the app. Nevertheless it is editable in the Quick Edit. Yesterday I wrote about jsgrid in my blog. Now comes more. Today I’ll share a little practical solution how one can disable editing a field in Quick Edit. The field is edited in jsgrid, but to disable it, we only have set the property called AllowGridEditing to false on our column (not even touching the heavy jsgrid api). We can do in the OnPreRender event in our Client Side Rendering (CSR) registration. Having the context object we have access to the Fields (ContextInfo.ListSchema.Field): [code language=“javascript” highlight=“6,9”] (function () { var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.OnPreRender = function(ctx) { var statusField = ctx.ListSchema.Field.filter(function(f) { return f.Name === ‘Request_x0020_Status’; }); if (statusField) { statusField[0].AllowGridEditing = false; } } SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code] Another way is to implement the display form: [code language=“javascript”] (function () { var view = function (ctx, field) { if (ctx.inGridMode) { field.AllowGridEditing = false; } return window.RenderFieldValueDefault(ctx); }; var overrideContext = {}; overrideContext.Templates = overrideContext.Templates || {}; overrideContext.Templates.Fields = { ‘Request_x0020_Status’: { ‘View’: view } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext); })(); [/code]
Nested templates in jQuery.tmpl
I have used jQuery tmpl for a while and it is really awesome. Now I want to use some nested templates. And the thing is: it is very simple to do it: Here is the code to achieve this:
<div onclick="doo()">test</div>
<div id="container"></div>
<script id="parent-template" type="text/html">
<li>
{{tmpl t }}
</li>
</script>
<script id="red" type="text/html">
<span style="color:red">{{= title}}</span>
</script>
<script id="green" type="text/html">
<span style="color:green">{{= title}}</span>
</script>
<script type="text/javascript">
var d = \[\];
d.push({ title: "one", t: "red" });
d.push({ title: "two", t: "green" });
$.template("red", $("#red").template());
$.template("green", $("#green").template());
function doo() {
$("#parent-template").tmpl(d).appendTo("#container");
}
</script>
Tag: Basics
JSGrid Basics
JSGrid is the javascript framework in SharePoint used in Quick Edit View (previously Datasheet View). There are a few very good blog posts on this topic (See below in “Sources”). Nevertheless the fact is that jsgrid and working with quick edit from a developer’s perspective is a huge undiscovered area. Articles I have seen are intended for advanced developers. The goal with my post today is to outline the very basics of working with JSGrid. When you know the basics you will be more comfortable to discover and try out more. The example I want to show is a jsgrid code for a “VerySimpleColumn”. The source code can be found on gist.github.com To focus on jsgrid, I assume you have knowledge and some experience of working with jslink, which is related to jsgrid.
Tag: Datasheet
JSGrid Basics
JSGrid is the javascript framework in SharePoint used in Quick Edit View (previously Datasheet View). There are a few very good blog posts on this topic (See below in “Sources”). Nevertheless the fact is that jsgrid and working with quick edit from a developer’s perspective is a huge undiscovered area. Articles I have seen are intended for advanced developers. The goal with my post today is to outline the very basics of working with JSGrid. When you know the basics you will be more comfortable to discover and try out more. The example I want to show is a jsgrid code for a “VerySimpleColumn”. The source code can be found on gist.github.com To focus on jsgrid, I assume you have knowledge and some experience of working with jslink, which is related to jsgrid.
Tag: Quickedit
JSGrid Basics
JSGrid is the javascript framework in SharePoint used in Quick Edit View (previously Datasheet View). There are a few very good blog posts on this topic (See below in “Sources”). Nevertheless the fact is that jsgrid and working with quick edit from a developer’s perspective is a huge undiscovered area. Articles I have seen are intended for advanced developers. The goal with my post today is to outline the very basics of working with JSGrid. When you know the basics you will be more comfortable to discover and try out more. The example I want to show is a jsgrid code for a “VerySimpleColumn”. The source code can be found on gist.github.com To focus on jsgrid, I assume you have knowledge and some experience of working with jslink, which is related to jsgrid.
Tag: Sample
JSGrid Basics
JSGrid is the javascript framework in SharePoint used in Quick Edit View (previously Datasheet View). There are a few very good blog posts on this topic (See below in “Sources”). Nevertheless the fact is that jsgrid and working with quick edit from a developer’s perspective is a huge undiscovered area. Articles I have seen are intended for advanced developers. The goal with my post today is to outline the very basics of working with JSGrid. When you know the basics you will be more comfortable to discover and try out more. The example I want to show is a jsgrid code for a “VerySimpleColumn”. The source code can be found on gist.github.com To focus on jsgrid, I assume you have knowledge and some experience of working with jslink, which is related to jsgrid.
Tag: Announcement
Announcing web based SQL Max Memory calculator
Today I want to announce a tiny web application for calculating max memory in the SQL Server to improve the overall performance in you SharePoint environment: SQL Max Memory Calculator. One of the important actions to improve the performance in SharePoint is fine tuning of the SQL Databases. Regarding the databases one of the crucial settings is the Max Memory Setting. You can read more about database optimizations for SharePoint in a whitepaper written by SharePoint MVP Vlad Catrinescu. The document is available on the SharePoint Community Web Site:
Tag: Calculator
Announcing web based SQL Max Memory calculator
Today I want to announce a tiny web application for calculating max memory in the SQL Server to improve the overall performance in you SharePoint environment: SQL Max Memory Calculator. One of the important actions to improve the performance in SharePoint is fine tuning of the SQL Databases. Regarding the databases one of the crucial settings is the Max Memory Setting. You can read more about database optimizations for SharePoint in a whitepaper written by SharePoint MVP Vlad Catrinescu. The document is available on the SharePoint Community Web Site:
Tag: Eakron
Announcing web based SQL Max Memory calculator
Today I want to announce a tiny web application for calculating max memory in the SQL Server to improve the overall performance in you SharePoint environment: SQL Max Memory Calculator. One of the important actions to improve the performance in SharePoint is fine tuning of the SQL Databases. Regarding the databases one of the crucial settings is the Max Memory Setting. You can read more about database optimizations for SharePoint in a whitepaper written by SharePoint MVP Vlad Catrinescu. The document is available on the SharePoint Community Web Site:
Tag: SQL Server
Announcing web based SQL Max Memory calculator
Today I want to announce a tiny web application for calculating max memory in the SQL Server to improve the overall performance in you SharePoint environment: SQL Max Memory Calculator. One of the important actions to improve the performance in SharePoint is fine tuning of the SQL Databases. Regarding the databases one of the crucial settings is the Max Memory Setting. You can read more about database optimizations for SharePoint in a whitepaper written by SharePoint MVP Vlad Catrinescu. The document is available on the SharePoint Community Web Site:
Problem med Sharepoint efter installation av SQL Server
Jag installerade Sharepoint först vilket skapade nödvändiga databaser. Sedan installerade jag SQL Server och angav det som default instance. Efter det gick det inte att använda Sharepoint. Felmeddelandet som spottades ut var “Cannot connect to the configuration database”. Alla försök att starta SQL Server med instansen “Sharepoint” var verkningslösa. Den enda lösningen var att avinstallera Sharepoint, alla Web Sites (i IIS administration) och installera Sharepoint på nytt, ange den nya SQL Server som standard för denna Sharepoint-installation.
Återskapa koppling till login i DB efter restore
Om du har kört restore på en databas, så kan det hända att det inte går att ändra rättigheter, och den login du använt inte kan se databasen. SQL Server spottar ut felmeddelandet med kod 15023:
The database is not accessible. (Object Explorer)
Om det är WebService som i sin tur anropar databasen, kan det komma ett sådant felmeddelande:
The underlying provider failed on Open.
Lösningen är att uppdatera kopplingen. Hämtat från denna blog.
Tag: Webapp
Announcing web based SQL Max Memory calculator
Today I want to announce a tiny web application for calculating max memory in the SQL Server to improve the overall performance in you SharePoint environment: SQL Max Memory Calculator. One of the important actions to improve the performance in SharePoint is fine tuning of the SQL Databases. Regarding the databases one of the crucial settings is the Max Memory Setting. You can read more about database optimizations for SharePoint in a whitepaper written by SharePoint MVP Vlad Catrinescu. The document is available on the SharePoint Community Web Site:
Tag: SharePoint 2010
Export any web part from a SharePoint page
The blog post below describes the technical details about how Web Parts can be exported using a hidden tool in OOB SharePoint, though this requires manual assembling of a special url. If you are just interested in a solution for an easy Web Part Export function, just proceed directly to my new blog post where you can download my tool that you can add to your web browser.
Custom Error and Access denied pages in Sharepoint
Unfortunately in SharePoint 2013 the custom error pages are not applied: link 1, link 2. Hopefully there will be a hotfix that solves it.
Comments from Wordpress.com
ryan - Mar 5, 2014
I agree, I have seen a few about. Thanks for the post
Jon - Mar 2, 2014
PowerShell: Migrate field choices to a termset
In my current project we are migrating a custom sharepoint solution from SharePoint 2010 to SharePoint 2013. One of the improvements is that we migrate custom field choices to Managed Metadata. Choice Fields were not intended to be so many. So now it is time to convert them to metadata terms. I have written a PowerShell script which copies all the choices from a field to a termset. The script uses Client Side Object Model (CSOM) to get the choice values and it uses Server Object Model to write data to the termset. [sourcecode language=“PowerShell”] <# .Synopsis Use MigrateChoices.ps1 to migrate choices from a field to managed metadata. The source can be a contenttype field from SharePoint 2010 or from SharePoint 2013. .Description This script uses client object model to get the list items from the old environment. Then it uses the Server Object Model to create new terms and termsets (if needed) in the new environment. This script doesn’t override anything. The reason why we use it, is that importing feature isnt easy It creates a new, instead of adding new terms to old ones. It is very hard to create an csv file for that purpose. .Example MigrateChoices.ps1 -Source http://sp2010.contoso.com -Target https://sp2013.contoso.com .Notes Name: MigrateChoices.ps1 Author: Anatoly Mironov Last Edit: 2013-09-04 Keywords: CSOM, Field, FieldChoice, Metadata, Termset .Links http://chuvash.eu .Inputs The script takes Source parameter, it is url for the root web in the Source Site Collection The script takes Target parameter, it is url for the root web in the Target Site Collection .Outputs None #Requires -Version 2.0 #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)][System.String]$Source = $(Read-Host -prompt “Source site Url”), [Parameter(Mandatory=$true)][System.String]$Target = $(Read-Host -prompt “Target site Url”), [Parameter(Mandatory=$false)][System.String]$TermGroupName = “My group”, [Parameter(Mandatory=$false)][System.String]$TermGroupId, [Parameter(Mandatory=$false)][System.String]$TermSetName = “My termset”, [Parameter(Mandatory=$false)][System.String]$TermSetId, [Parameter(Mandatory=$false)][System.String]$FieldName = $(Read-Host -prompt “Field Choice Name”) ) if(-not(gsnp | ? { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { asnp Microsoft.SharePoint.PowerShell } # try to instantiate the target site, if it fails, then it does not run in the right environment $targetSite = get-spsite $Target # predefined termset guids: $guids = @{ “group” = if ($TermGroupId) {New-Object system.guid $TermGroupId } else { [system.guid]::NewGuid() } “termset” = if ($TermSetId) {New-Object system.guid $TermSetId } else { [system.guid]::NewGuid() } } function GetChoices() { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Source) $field = $ctx.Web.Fields.GetByInternalNameOrTitle($FieldName) $ctx.Load($field) $ctx.ExecuteQuery() return ([xml]$field.SchemaXml).Field.Choices.Choice } function New-Term { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermSetItem]$parent, [Parameter(Mandatory=$true)][System.String]$name ) if (!$parent) { throw new-object System.ArgumentException $parent } if (!$name) { throw new-object System.ArgumentException $name } $term = $parent[$name] if (!$term) { $parent.CreateTerm($name, 1033) | out-null } } function CreateTerms() { $taxSession = Get-SPTaxonomySession -Site $targetSite $termStore = $taxSession.DefaultSiteCollectionTermStore $group = $termstore.Groups[$TermGroupName] if (!$group) { $group = $termStore.CreateGroup($TermGroupName, $guids.group) } $termSet = $group.TermSets[$TermsetName] if (!$termset) { $termset = $group.CreateTermSet($SecurityClassificationTermSetName, $guids.termset, 1033) } GetChoices | % { New-Term $termSet $_ } $termStore.CommitAll() $targetSite.Dispose() write-host -ForegroundColor Green “The term sets have been created” } CreateTerms [/sourcecode]
scriptcs and SharePoint. How SharePoint can benefit?
Last Saturday I attended Leetspeak. Among many awesome speeches and presentations I discovered scriptcs. scriptcs lets you write C# code directly in the console, or execute scripts written with just your favourite editor. Please see more about it on the site. What I thought during Justin Rusbatch’s session at Leetspeak:
Can we use scriptcs in SharePoint?
Technically there is no limitations in SharePoint for scriptcs. Any .NET code can be registered, imported and invoked in a console or in a standalone script. Here is the simple code for instantiating a site collection and disposing it: [code language=“csharp”] #r Microsoft.SharePoint; using Microsoft.SharePoint; var site = new SPSite(“http://dev”); site.Url site.Dispose(); [/code] The code above does not do anything, it is just there to demonstrate how you can register the SharePoint assembly (“Microsoft.SharePoint”) and import it into the script: [code language=“csharp”] using Microsoft.SharePoint; [/code] The example shows even that you in scriptcs no longer need the necessary “boilerplate” (compared to a console application): namespace, Program, Main()… You can just directly write your code. The rest is the same as in a C# application. The code samples for scriptcs can be any code written in C# for SharePoint, code from custom console applications, from feature receivers, you name it. So my next question is:
javascript: Alert Me on a Page
Recently I needed to add an Alert Me link on Pages. Alert Me is a well known SharePoint functionality for notifying users about changes in list or list items. It is availabe in OOB SharePoint as a command in Ribbon if you go to a list view: When you click on this ribbon command, SharePoint opens a modal dialog and takes you to layouts page: SubNew.aspx. To open a modal dialog and load a page is not a rocket science. So a custom “Alert Me” link is doable. As the first step I copied the html markup from the ribbon and adjusted it a little bit. [sourcecode language=“html”] Alert Me [/sourcecode] Then the javascript code which gets the List ID and Page ID is very simple because this information is there in the magic _spPageContextInfo: [sourcecode language=“javascript”] var takana = window.takana || {}; takana.alertMe = function () { var url = String.format("{0}/{1}/SubNew.aspx?List={2}&ID={3}" , _spPageContextInfo.webAbsoluteUrl , _spPageContextInfo.layoutsUrl , encodeURI(_spPageContextInfo.pageListId) , _spPageContextInfo.pageItemId); OpenPopUpPage(url); } [/sourcecode] This code will open a modal dialog in exactly the same way as the ribbon command in OOB SharePoint and let you subscribe to changes on that page. In this code I use String.format which is available on SharePoint pages and _spPageContextInfo which has existed since SharePoint 2010 and has been extended with more useful information about the current context.
PowerShell: Copy an entire document library from SharePoint 2007 to disk
For a while ago I needed to copy all files from a document library within a SharePoint 2007 site to the hard drive. So I didn’t need to copy files from SharePoint to SharePoint so I couldn’t use the stsadm -o export command or Chris O’Brien’s nice SharePoint Content Deployment Wizard. I came across the SPIEFolder application which should work with SharePoint 2007 and 2010. It has a site on codeplex: spiefolder.codeplex.com, but neither the binary nor the source code can be downloaded from there. After some searching I found the binary in the author’s skydrive. The fact that the source code was not available seemed as an disanvantage because I could not know what code was run. Nevertheless I tried it out and it didn’t work:
JSOM: Alter a column's DisplayName
Here is another article in my JSOM series. For one month ago I showed how to alter a column’s ShowInDisplayForm property with JSOM. This time I’ll show a code sample for changing a column’s (field’s) display name. If you want to alter the displayname with Server Object Model, grab the code in the sharepoint.stackexchange.com: Change Field’s DisplayName in a List. [sourcecode language=“javascript”]var ctx = SP.ClientContext.get_current(), //SP.ClientContext field = ctx.get_web() //SP.Web .get_lists() //SP.ListCollection .getByTitle(‘MyList’) //SP.List .get_fields() //SP.FieldCollection .getByInternalNameOrTitle(“Body”); //SP.Field ctx.load(field, “Title”); //load only Title ctx.executeQueryAsync(function() { field.set_title(“Beskrivning”); field.update(); ctx.executeQueryAsync(); });[/sourcecode]
Delete all list items with jsom
Today I needed to “clean” a list, meaning to remove all list items. For some time ago I wrote a post about different ways of removing list items in bulk: Server Object Model, SPLinq and RPC. This time I had only the web browser. So I tried the jsom way. By the way, the javascript documentation for jsom on msdn is getting really good. Don’t miss that: How to: Complete basic operations using JavaScript library code in SharePoint 2013. Now here comes theworking code I used to remove all items in my list:
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
Toastr.js and SharePoint
Have you used SharePoint javascript Notifications (SP.UI.Notify)? Are you looking for something new and fresh? Well then check out the Toastr.js - a simple, beautiful, fully responsive and light-weight javascript lib for notifications, developed by John Papa and Hans Fjällemark and released under the MIT License. By the way, toastr was one of many things I discovered and learned on John Papa’s online course by pluralsight: Single Page Apps with HTML5, Web API, Knockout and jQuery. It is a really awesome course, where you learn how to create an amazing SPA. Well, how’s about SharePoint. While whatching the course videos about toastr, I thought: Can we use it in SharePoint? Yes we can! Just load the toastr css and js and start using it:
The original Visual Web Part template is missing in Visual Studio 2012
Today I encountered a weird issue, the classic Visual Web Part template was gone in Visual Studio 2012. When I created a Visual WebPart, a webpart was created with a generated .g.cs file, like the sandboxed visual webparts. I am not exactly sure why it happened. According to the MSDN guide Creating Web Parts for SharePoint, the structure of Visual Webparts should be the same as in Visual Studio 2010. It could have happened after I installed the power tools. However, if someone runs into the same issue, here is the solution: Copy this zip file from a computer with VS2010 installed:
The right URL regardless AAM zone
For a while ago my colleague gave me a nice tip of getting the right absolute url regardless sharepoint zone in Alternate Access Mappings. I want to share it, because it is brilliant:
var url = SPUtility.AlternateServerUrlFromHttpRequestUrl(new Uri(value)).AbsoluteUri;
$ in cmssitemanager.js conflicts with $ in jQuery
In SharePoint 2010 if CMSSiteManager.js library is loaded besides jQuery, then much of stuff stops working. The reason is that the dollar sign ($) is used in cmssitemanager.js as well which conflicts with jQuery. Mostly it appears on pages where you load jQuery and have an image library with thumbnails. To avoid this, just replace all $ with jQuery in your custom scripts. A more crazy situation is when avoiding $ isn’t enough. It is when you load jQuery to page head automatically on all pages. The Asset picker (AssetPortalBrowser.aspx) invokes $ itself and gets with jQuery in conflict without you write a single line of custom javascript code. You usually get the following error:
Add Comments column to your sharepoint list
If you have used Issue tracking list template in SharePoint you must have marked that the comments are added and marked with author name and datetime. It is handy to have these micro “discussion boards” on items. The comment-formed communication can help to fine-tune task definitions. By the way, have you seen Trello? So the question is how we can create this column in other lists? Here is a little tutorial how to create “append-only comments”, as they are called:
A simple Log for ULS
Do an unsafe update in a unified manner « Sharepoint. Kunskap. Upptäckter på resan. - Sep 3, 2011
[…] Log class is my own class which I presented in my previous post. Like this:GillaBli först att gilla denna […]
A simple Log for ULS
Here is a simple log which has been inspired of Android Log. It logs to ULS which you can open with ULSViewer, SharePoint Log Viewer.
using System;
using Microsoft.SharePoint.Administration;
namespace Contoso.Intranet.Portal.Utilities
{
public class Log
{
private static readonly string \_CATEGORYNAME = "CONTOSO";
private static readonly SPDiagnosticsCategory \_ERROR\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Unexpected, EventSeverity.Error);
private static readonly SPDiagnosticsCategory \_WARNING\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.High, EventSeverity.Warning);
private static readonly SPDiagnosticsCategory \_VERBOSE\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Verbose, EventSeverity.Verbose);
private static readonly SPDiagnosticsCategory \_INFO\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Medium, EventSeverity.Information);
private static void WriteTrace(SPDiagnosticsCategory category, string message, string trace)
{
SPDiagnosticsService.Local.WriteTrace(0, category, category.DefaultTraceSeverity, message, trace);
}
public static void Error(Exception ex)
{
WriteTrace(\_ERROR\_CATEGORY, ex.Message, ex.StackTrace);
}
public static void Warning(string message)
{
WriteTrace(\_WARNING\_CATEGORY, message, "");
}
public static void Verbose(string message)
{
WriteTrace(\_VERBOSE\_CATEGORY, message, "");
}
public static void Info(string message)
{
WriteTrace(\_INFO\_CATEGORY, message, "");
}
}
}
A possible improvement can be a custom Area. See an example of ThorstenHans on Github: CustomLogger.cs EDIT: I found an interesting article: How to log to the SharePoint ULS Logs: Clean Debugging and Error Logging broken down into steps written by Philip Stathis.
Sharepoint Manager 2010
Ett ytterligare grym verktyg från codeplex-lägret: Sharepoint Manager.
Förenkla skapandet av utvecklingsmiljön till SharePoint 2010
Jag är fortfarande i mitt sökande efter den perfekta (för mig) utvecklingsmiljön för SharePoint 2010. Fram tills nu har jag arbetat med en virtuell (VMware) maskin som kollegor till mig har konfigurerat. Men jag vill ha kunskapen att göra det själv. Än så länge har jag bara stött på procedurer som är relativt långdragna, fram tills idag. Se på videon på sidan jag länkat nedan. Jag ska testa det och sen förhoppningsvis komma med resultat här. Mitt mål är att lätt komma igång med en maskin som körs som VHD eller native dualboot. Men jag börjar med en virtuell VMware maskin. Ett dygn senare: Igår lät jag skriptet köra (utan config ändringar) och efter många timmar är allt installerat och klart. Dock trailversioner. Men gör man det en natt efter 2 veckor eller när trailen är slut, då kan man börja på en ny maskin igen. Jag gillar skarpt detta skript! Ännu bättre blir det nog när man konfigurerar det att fixa en VHD. Kommer mer om det när det är testat! Länksamling Film från Channel 9 Ladda ner Scriptet här Skriptskaparnas bloggar http://blogs.msdn.com/b/cjohnson/archive/2010/10/28/announcing-sharepoint-easy-setup-for-developers.aspx http://blogs.msdn.com/b/pstubbs/archive/2010/10/27/sharepoint-2010-easy-setup-script.aspx
Tag: RPC
Export SharePoint List Data To Xml through PowerShell
Today my colleague Johannes Milling wrote an awesome post: Export SharePoint List Data To XML Directly from the GUI He uses the old and forgotten RPC-based web service owssvr.dll (that has existed since SharePoint 2003). This url pattern is used to get the xml-formatted list data for a specific ListView: [source] http://<site_url>/_vti_bin/owssvr.dll?Cmd=Display&List=&View=&Query=*&XMLDATA=TRUE [/source] To automate this I have written a PowerShell function. All the details are in the comments: [source language=“PowerShell”] function Export-OIPSPListDataAsXml { <# .Synopsis Exports list items as xml .DESCRIPTION This function uses a built-in hidden service owssvr.dll in SharePoint .PARAMETER Web SPWeb or a url for the SPWeb object where the list resides .PARAMETER ListName List Name (List Title) .PARAMETER ViewName Name of the List View to export the data .EXAMPLE Export-OIPSPListView -Web http://myawesomesite -ListName “Teddy Bears” -ViewName “All Items” .EXAMPLE Export-OIPSPListView -Web $webInstance -ListName “Top Links” -ViewName “All Items” .Notes Name: Export-OIPSPListDataAsXml Author: Anatoly Mironov Last Edit: 2014-09-11 Keywords: SPList, SPWeb, SPListView, Xml .Link http://chuvash.eu #> [CmdLetBinding()] param( [Parameter(Mandatory=$true)] [Microsoft.SharePoint.PowerShell.SPWebPipeBind]$Web, [Parameter(Mandatory=$true)] [string]$ListName, [Parameter(Mandatory=$true)] [string]$ViewName) $spWeb = $Web.Read() $list = $spWeb.Lists[$ListName] if (!$list) { throw “List $ListName on web $($spWeb.Url) could not be found” } $view = $list.Views[$ViewName] if (!$view) { throw “View $ViewName on web $ListName could not be found” } $url = “{0}/_vti_bin/owssvr.dll?Cmd=Display&List={1}&View={2}&Query=*&XMLDATA=TRUE” ` -f $spWeb.Url, $list.ID, $view.ID $wc = New-Object Net.WebClient $wc.UseDefaultCredentials = $true $wc.DownloadString($url) } [/source]
Tag: Css
Improving the web performance of an intranet
[caption id=“attachment_3437” align=“alignnone” width=“480”] All the “small” app parts, web parts, delegate controls, user controls, and other “packages” that “must” be delivered to the users on every page load of the Start Page of your Intranet.[/caption] Recently we made an investment to improve the performance of our intranet. We made many changes in different layers: SQL, Network, Browser upgrade and code. Here I want to tell about what code changes we did to improve the web browser performance. Please leave feedback if you find it useful. You can also share your suggestions. We measured the performance before our code changes and after them. We had amazing results. Unfortunately I can not share any numbers, but we improved the Time to First Byte, time to load event firing in the browser, memory consumption in the clients and, perhaps, the most important, we improved the perceived performance of the Intranet, the way how users experience the speed and UI responsiveness. To do this I got many ideas of my project colleagues and branch colleagues. Here is the list of changes we’ve implemented:
Updating hover style in IE8 Developer Tools
In our project we still have to support Internet Explorer 8. The CSS issues in IE8 are most difficult to debug and solve. You can not add a new rule in Developer Tools or toggle the state of an element to hover as in moder web browser dev tools. One solution that I’ve come up to today, is to add a style with javascript or jQuery, open the script pane in IE8 Dev Tools and add this line: [code language=“javascript”] $(’.ms-srch-item:hover {filter:none !important;}’) .appendTo($(‘body’)) [/code] This will fill update the hover effect of the .ms-srch-item directly. That’s it, just a little tip.
Tip: Use the weakest CSS selectors
I am reading Mobile HTML5 written by Estelle Weyle. It is an awesome recap and new knowledge about html, css and javascript. I want to highlight one of tips I got: Use the weakest CSS selectors (can be found on page 204). We all know, that inline CSS and !important are evil. They have a higher level of specifity and override the standard cascade of the CSS rules. If you use !important, then it will be hard to override CSS rules when you really need it. After these two classic “evils” the evil number three is overqualifying of CSS selectors. You should really never add more classes or ids or elements than needed. Consider this: [code language=“css”] .warning { background-color: red; } [/code] It is often enough, you don’t need those: [code language=“css”] html .warning div .warning div.warning, div > .warning body p#myP.blue strong.warning [/code]
Pragmatic Responsive Design
I have been curious about the responsive design but have not had time to try it out. To learn more I decided to make an existing website more responsive. A friend of mine drives a Chuvash Dictionary website: samah.chv.su. Today it looks like this in a mobile browser: The site is a classic 1000px-ish centered page with header and two columns. The left column is for the main content and the right column for additional “aside” information. Can it be more classic? This current version works, you can still use the dictionary on a mobile phone. But there are several improvements that can be done:
Styling suiteBar and IE8
Today I want to share little css tip for styling the suiteBar in SharePoint 2013 and making it work even in IE8. I needed to apply a green color to the suiteBar (#005128). It worked in all browsers except IE8: The reason why is a special css rule (in corev15.css) that only IE8 understands: [sourcecode language=“css”] .ms-core-needIEFilter #suiteBarLeft { filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=#ff0072c6,endColorstr=#ff0072c6); } [/sourcecode] I found this answer in an blog post written by Trace Armstrong: SharePoint 2013 – Branding the Top Bar and the Importance of Browser Testing. You could override this css rule with your colors, just dig into the msdn documentation. What I needed though, was just a plain color, so I didn’t want to dig into that old progid-definitions. There is actually a simpler solution on social.msdn.microsoft.com. A guy called avshinnikov just overrides the “filter” rule by setting it to none. If you apply it only with id selector (#suiteBarLeft) then you have to put “!important” after that. Fortunately I allready had my own css class on html tag which is a sort of a “namespace” for my selectors: [sourcecode language=“css”] .takana-html #suiteBarLeft { background-color: #005128; filter: none; } [/sourcecode] The class .takana-html can have any name, of course, and it can be a class on a closer parent element to the suiteBar. The only goal for that is to make your css rules more important in your design in a natural way (and avoiding the “!important”). Eventhough many people use this principle without thinking about it, I’ve not found any info regarding this principle. I only heard Jeremy Foster and Michael Palermo talking about it and referring to it as “css namespaces” in a video course: Developing in HTML5 with JavaScript and CSS3 Jump Start. Of course, the name isn’t unique, there is another thing called css namespaces. But the concept is really good.
Cool presentation about web performance optimization
by Chris Love [slideshare id=15218139&doc=webperformanceoptimizationformodernwebapplications-121116224847-phpapp01]
Simplify js and css development with Web Essentials (Visual Studio Extension)
If you develop much javascript and css, this is the exension to Visual Studio you just can’t live without: Web Essentials (It is even released for VS2012). You can do many things with it. Here are two examples for simple but very useful functions: 1. Show which browsers support a css attribute: 2. Collapse javascript functions and create #region areas like in C# code: There is much more, like less and coffeescript parsing. Just check the documentation. And it is fully appliable in SharePoint development.
Enable Save in IE9 mode
Wouldn’t it be nice to use html5 and css3 in SharePoint? No problems, there is actually v5 master out there, created by Kyle Schaefer. Or just use h5ml5 and css3 right away in your webparts and pages. But there is a big problem. It doesn’t work in IE9–. One of the issues (even listed by Kyle) is that “save” doesn’t work in modal dialogs where Rich Text Editor is used. Especialy it is for modal dialogs. The problem is not IE9, neither html5 and css3. After some digging in javascript code which is shipped with SharePoint I found out that the problem is some legacy javascript code which is not supported by IE9 but in IE8– (and compatibility mode). When we set IE9 mode in IE9 Dev Tools (F12) and go to Tasks list and try to create a task, we’ll get an error: It is RTE_GetEditorIFrame from init.js:
Erik Swensson's book about Sharepoint Branding
Today Erik Swensson’s book Practical SharePoint 2010 Branding and Customization came to our company. I am looking forward to read it. It’s about time to see alternatives to Randy’s starters.
Vertically align input text in IE
Well, input and IE aren’t friends, are they? I found a solution: not defining input height. The only shortcoming of this solution is…, well the solution itself, sometimes you need to define the input height. However, don’t set height, just define, font-size for text inside and padding, and it will be aligned:
input {
font-size:20pt;
padding: 10px;
}
Do you know some better ways to do it, Tell me.
css3 transform
See Richards Bradshaw’s page with explanations and examples of css3 transform and transitions. His code is also available for forking on Github.
Bootstrap and Sharepoint
Twitter Bootstrap is awesome, based on less.js, ust add this line in your html code:
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/1.3.0/bootstrap.min.css">
And your page looks already good. If you use css classes like btn label warning danger and much more, you get a right design directly out of the box. Now I want to test it in Sharepoint. Will it work? What do you think? jQuery Theme Roller. Another interesting resources are jQuery ThemeRoller. WebResources Depot:
Reset favicon cache
Favicon is one of the hardest. Ctrl-F5 doesn’t help. You can of course see the source, find the location of the favicon, click on it (if you use Firefox or Chrome), otherwise copy the url and paste it in the address bar. When you load it separately, the favicon cache is renewed. It works. But if you want to make it easier for your users, set a version to your favicon file in the masterpage:
Hide my site link with css
Want to hide my site link without disabling social features. Well, the simplest way to do it is to use css:
#mp1\_0\_0\_Anchor { display: none; }
```If you want to hide my profile instead, just hide #mp1\_0\_1\_Anchor:
#mp1_0_1_Anchor { display: none; }
.ms-MenuUIUL li[text=‘My Site’] { display: none;}
##### Disable the my profile feature An even better solution is maybe to disable the ability to change the profiles. [Just remove the permission to "user personalization..." for All authenticated users in User Profile Service](http://blog.libinuko.com/2010/10/10/sharepoint-2010-howto-disable-my-site-and-my-profile-link/).
## Comments from Wordpress.com
####
[John]( "johnandrewdavies@hotmail.com") - <time datetime="2012-03-07 00:15:32">Mar 3, 2012</time>
Be careful this cannot be used, the classes for pop up menus are generated dynamically on the page, and that class can be applied to a number of menus I assume depending on the order which they load on the page, which isnt the same every time, so for instance this hides something in the site actions menu, or the new button on a library sometimes.
<hr />
####
[Brett Anderson](http://sharepoint2020.wordpress.com "brettando@live.com.au") - <time datetime="2012-05-02 06:13:05">May 3, 2012</time>
Hi, The amended solution does not work in IE7.
<hr />
####
[Fredrik]( "fredrik.eriksson234@gmail.com") - <time datetime="2012-03-09 15:27:24">Mar 5, 2012</time>
Thank you Anatoly, that worked perfectly in all browsers! I had problems with the first suggested solution, because it would hide other menu items, like "edit this page" from the site settings dropdown!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:10:36">Mar 3, 2012</time>
You are totally right, John! I realized that too. Fortunately, I didn't need that then. But while using that I saw that sometimes Site Actions -Edit Page disappeared. These IDs are really generated dynamically. Thanks for your comment. I'll update my post.
<hr />
####
[vishal]( "vishals.shivan@gmail.com") - <time datetime="2012-03-07 07:27:54">Mar 3, 2012</time>
Hi Anatoly. Thanks for the solution. but the problem we are facing one problem after implementing this. Once we make this change and when login to the portal next time, the "Edit Page" link under site action menu is not getting displayed and the My Site Link is getting displyed. any suggestion?
<hr />
####
[Material SharePoint » Hide ‘My Site’ Link from Welcome User Dropdown Control](http://sharepoint.jsturges.com/2012/05/hide-my-site-link-from-welcome-user-dropdown-control/ "") - <time datetime="2012-05-12 17:45:13">May 6, 2012</time>
\[...\] of my enterprise level clients that we usually hide it all together! To do this, you can use an awesome CSS trick I learned from Anatoly \[...\]
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:24:39">Mar 3, 2012</time>
Hi Vishal. Unfortunately we cannot rely on these IDs, as John in previous comment mentioned, because these IDs are generated dynamically. I'll update my post. One possible solution would be use attribute selectors... Something like .ms-MenuUIUL li\[text='My Site'\] { display: none;}
<hr />
####
[jim]( "jim.omara@gmail.com") - <time datetime="2014-02-12 17:38:05">Feb 3, 2014</time>
.ms-welcomeMenu #mp1\_0\_0{ display:none; } .ms-welcomeMenu #mp1\_0\_1{ display:none; } .ms-welcomeMenu #mp1\_0\_2{ display:none; } .ms-welcomeMenu #mp1\_0\_3{ display:none; } .ms-welcomeMenu #mp1\_0\_4{ display:none; } .ms-welcomeMenu #mp1\_0\_8{ display:none; } .ms-welcomeMenu #mp1\_0\_9{ display:none; } these work for me.
<hr />
####
[Anatoly Mironov](http://chuvash.eu "mirontoli@gmail.com") - <time datetime="2014-02-12 23:20:59">Feb 3, 2014</time>
Thank you for sharing your solution. Appreciate.
<hr />
s4-die
s4-die is a funny stuff. Now I realized the purpose of it. Everything that has to be hidden, Microsoft wraps in an element with class=“s4-die”. In corev4.css it is defined with display:none. Not so bad. Another approach is to create a invisible panel like Randy Drisgill has done. But with s4-die you don’t need to move your stuff around, just add the class s4-die.
master page for html5 and css3
A great work: v5.master. I am recommending to try it. The problem are some javascript bugs in the IE 9 when you run IE mode 9 that are necessary to enable html5 and css3 support. You can’t “save” a list item: The reason why it doesn’t work in IE, but in Chrome, Firefox, is that IE invokes some functionality that it doesn’t invoke in other browsers. Next: Enable Save button in IE9
Change the layout of Search Box without custom delegate control
The surest way to customize Search box in Sharepoint is to create a delegate control. In Sharepoint.Stackexchange there are many links to resources about this. But if you don’t have access to server or can’t deploy, the easiest way to do it is to style it with css. Thanks Steve Ottenad.
.s4-search .ms-sbgo a {
background:url(../images/search\_btn.png) no-repeat;
width:27px;
height:22px;
display:block;
}
.s4-search .srch-gosearchimg, .s4-search .ms-sbgo span {
display:none;
}
First we hide the the default image and then we add our image for search button as background.
less.js
Det finns ett intressant projekt som kan hjälpa att strukturera css-filer. Du skriver regler i en kombination av css och javascript. Det omvandlas med hjälp av js till css. Projektet heter less.js, läs mer om detta på sharepointoverflow.
jQuery hide
Jag har alltid använt hide-funktionen i jQuery för att gömma vissa element som inte behövs i början. Det kan resultera att användaren ser skymningen av dem i laddningen av sidan. Vilket inte är så bra. Men det har visat sig, att hide behöver inte köras av jQuery. Bara göm dem med hjälp av css. jQuery show kommer funka ändå.
styra css för modaldialog
Säg du har application page med samma master page som resten av portalen. Men vad göra om du vill ändra css bara om den är i modal dialog. Overrida dina css-regler genom att lägga till .ms-dialog. .ms-dialog är css-klassen som läggs på html-taggen om sidan laddas i modaldialog:
html.ms-dialog body {
background-color:white;
}
Felsök på clientsidan med Chrome DevTools
Här är en väldigt bra video som berättar om nya devtools i Google Chrome 10. Den visar 12 tricks hur man kan underlätta felsökning av html, css och javascript. Att kunna ändra html,css och js on-the-fly är faktiskt häftigt. För mig som länge har använt Firebug i Firefox (som nu inte funkar på FF4 RC) känns devtools väldigt bra. [youtube http://www.youtube.com/watch?v=nOEw9iiopwI&w=530&h=335]
Comments from Wordpress.com
Ändra utseendet på sidan direkt i webbläsaren « Sharepoint. Kunskap. Upptäckter på resan. - Mar 1, 2011
Formatera export xml av wordpress
Ville spara min blogg som en dagbok för utskrift. Exporterade hela bloggen som xml. Inga problem. Sedan var det dock nästan omöjligt att enkelt skriva in det i Word / OpenOffice. Jag har skrivit en liten css-fil som formaterar det lite så att man kan skriva ut. Lägg till:
<?xml-stylesheet type = "text/css" href="wordpress.css"?>
direkt efter:
<?xml version="1.0" encoding="UTF-8" ?>
Lägg filen “wordpress.com” i samma mapp. Här är wordpress.css
channel title {
font-size:3em;
}
channel description {
color:green;
margin-bottom:1em;
}
item title {
font-size:2em;
font-family:Arial;
margin-top:1em;
}
creator {
color:green;
}
creator:before {
content:"Skrivet av: ";
color:black;
font-style:italic;
font-size:0.8em;
}
post\_date:before {
content:"Datum: ";
}
comment {
margin-left:3em;
}
comment\_author:before {
content:"Kommentar av: ";
font-style:italic;
color:black;
}
comment\_author {
color:green;
}
comment\_date:before {
content:"(";
}
comment\_date:after {
content:"):";
}
/\* Ska inte visas\*/
link, channel language, pubDate,
guid, author, base\_site\_url,
base\_blog\_url, wxr\_version, generator,
post\_id, is\_sticky, post\_type, post\_name,
status, comment\_status, menu\_order,
post\_parent, ping\_status, post\_date\_gmt,
category, postmeta,
comment\_id, comment\_author\_email,
comment\_author\_IP, comment\_date\_gmt,
comment\_approved, comment\_type,
comment\_user\_id, comment\_parent {
display:none;
}
/\* block style \*/
title, description, post\_date, comment {
display:block;
}
Tag: JQuery
Improving the web performance of an intranet
[caption id=“attachment_3437” align=“alignnone” width=“480”] All the “small” app parts, web parts, delegate controls, user controls, and other “packages” that “must” be delivered to the users on every page load of the Start Page of your Intranet.[/caption] Recently we made an investment to improve the performance of our intranet. We made many changes in different layers: SQL, Network, Browser upgrade and code. Here I want to tell about what code changes we did to improve the web browser performance. Please leave feedback if you find it useful. You can also share your suggestions. We measured the performance before our code changes and after them. We had amazing results. Unfortunately I can not share any numbers, but we improved the Time to First Byte, time to load event firing in the browser, memory consumption in the clients and, perhaps, the most important, we improved the perceived performance of the Intranet, the way how users experience the speed and UI responsiveness. To do this I got many ideas of my project colleagues and branch colleagues. Here is the list of changes we’ve implemented:
Count lines of code with PowerShell
Today I got a question:
How many lines of code are there in our SharePoint solution?
After a little search, I found that PowerShell is really a nice tool to count lines of code:
I wanted to count lines for different types of code:
- Code Behind written in C#, the files have .cs file extension
- JavaScript code (except jQuery, angular or knockout frameworks)
- PowerShell files (.ps1 and psm1)
- Xml files (all the SharePoint .xml files)
Here is the powershell code that counts lines of code: [code language=“powershell”] # go to the solution folder cd #count lines in .cs files ls -include *.cs -recurse | select-string . | measure | select count #count lines in our .js files ls -include *.js -recurse ` -exclude *min.js, jquery*, _*, jsrender*, CamlBuilder*, knockout* ` | select-string . ` | measure ` | select Count #count lines in our powershell scripts ls -include *.xml -recurse | select-string . | measure | select count #count lines in our powershell scripts ls -include *.ps1, *.psm1 -recurse | select-string . | measure | select count [/code] Just a curious fact, I can’t tell you how many lines of code we have in our solution, but I can reveal the proportions. If I used the flexible box model in css3, it would look like this: There are as many lines of code written in javascript as it is in C#. The main reason that for the big js code base are the SharePoint hosted apps. The PowerShell scripts are as big the javascript code base. Xml files are 4 times bigger than C# code, and it is even bigger than the sum of all lines of code written in C#, JavaScript and PowerShell. It isn’t strange that xml is dominating, almost everything in SharePoint is defined in xml. Fortunately, there are less cases where you have to write raw xml in Visual Studio 2012/2013 and SharePoint 2013. How does it look in your project? What language is dominating in your SharePoint project?
Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)
I have had a strange bug. The comment text box in a OOB SharePoint 2013 blog doesn’t appear. It only says: “There are no comments for this post.” In this blog post I’ll tell you how I found the bug and I’ll show you how you can temporarily bring the commenting to life. I have had luck. While it doesn’t work on the Test Environment, it does actually work on my development machine. The comments text box is rendered as an OnPostRender action in the blog comments display template. After debugging the javascript in hours and comparing the two environments, I just could confirm that displaytemplates are the same. There are two main javascript files that are involved:
Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
Multiple events listeners in jQuery
Maybe it is not so often we face this situation where we one event handler for different events in javascript. But in my project I use many custom events and in some situations it is the same handler which listens to different events. What I found you can define multiple event listeners at the same time.
function myClick() { console.log("tada"); }
$(".selector").on({
"click mouseover": myClick
});
Chuvash translation of Wikipedia Mobile
The official Wikipedia mobile app is now translated into Chuvash language and available to use:
What does Chuvash mean?
I am Chuvash. Chuvash is the name of an ethnicity which counts up to 2 milions peoply (mostly in Russia). Chuvashes talk the Chuvash language which is also an official language in Chuvash Republic (besides Russian). Chuvash language is a Turkic language and has a status “Vulnerable” in the UNESCO list of languages in danger. There is a Chuvash Wikipedia cv.wikipedia.org.
Using javascript objects passed from closed popup
It is not a rocket science to pass objects from child window (popup) to main window. The problem I encountered today was IE and passing complex objects. So it is just an IE issue as far as I know. The problem occurs when you pass some object (not a simple String or Number) to main window:
window.opener.takeAnObjectFromChild = {
title: "Should even be available when I close the child"
};
and you then close the child window, next time the main window tries to access the passed object:
$ in cmssitemanager.js conflicts with $ in jQuery
In SharePoint 2010 if CMSSiteManager.js library is loaded besides jQuery, then much of stuff stops working. The reason is that the dollar sign ($) is used in cmssitemanager.js as well which conflicts with jQuery. Mostly it appears on pages where you load jQuery and have an image library with thumbnails. To avoid this, just replace all $ with jQuery in your custom scripts. A more crazy situation is when avoiding $ isn’t enough. It is when you load jQuery to page head automatically on all pages. The Asset picker (AssetPortalBrowser.aspx) invokes $ itself and gets with jQuery in conflict without you write a single line of custom javascript code. You usually get the following error:
jQuery mobile and SharePoint
In this post I want to explore how to build a mobile app using jQuery mobile. Recently I discovered two great blog posts about this:
- Building SharePoint web apps using Sencha Touch by Luc Stakenborg
- jQuery mobile and SharePoint by Chris Quick
In my post I’ll use their findings and share some of mine thougts. I’ll focus mostly on how to get started with jQuery mobile and SharePoint. So go ahead and create your jQuery mobile app, just drag’n’drop some controls: Download it and yout get an “app.html” file and “my.css”. For now ignore my.css. app.html is something like that:
clearInterval in Chrome doesn't work on window blur
If you want to reset all interval jobs when a browser tab is inactive, the best way would be to use clearInterval on window blur. But unfortunately Chrome fires window focus and window blur two times. Here is an embryo to a solution:
var M = window.M || {};
M.counter = 0;
M.focused = true;
M.tick = function() {
if (M.focused) {
console.log("tic tac " + ++M.counter);
}
};
M.start = function(e) {
console.log("starting...");
M.focused = true;
};
M.stop = function(e) {
console.log("stopping...");
M.focused = false;
};
$(window).on({
focus: M.start,
blur: M.stop
});
M.ticker = window.setInterval(M.tick, 1000);
shorthand for jQuery(document).ready
jQuery(document).ready is used very often, why not use the shorthand variant of that?
$(function() {
// Code here
});
fallback for html5 placeholders
Placeholders are very handy in html5, we don’t need to fool with input values. But in SharePoint and IE we must provide fallback for placeholders if we want use them in other browsers. Here is an jQuery extension to do that:
(function ($) {
$.fn.extend({
ensurePlaceholders: function () {
var input = document.createElement('input');
var placeholderSupported = ('placeholder' in input);
if (placeholderSupported) {
return;
}
function setHints(elem) {
var $elem = $(elem);
var value = $elem.val();
if (value == "") {
var placeholder = $elem.attr("placeholder");
$elem.val(placeholder);
$elem.addClass("empty-text");
}
}
function removeHints(elem) {
var $elem = $(elem);
$elem.removeClass("empty-text");
var value = $elem.val();
var placeholder = $elem.attr("placeholder");
if (value == placeholder) {
$elem.val("");
}
}
this.find("\[placeholder\]").each(function() {
setHints(this);
});
this.on("focus", "\[placeholder\]", function(e) {
removeHints(this);
});
this.on("blur", "\[placeholder\]", function(e) {
setHints(this);
});
}
});
})(jQuery);
```Then "ensure placeholders" by running this function on a wrapper element which contains fields with the placeholder attribute:
jQuery("#form-wrapper").ensurePlaceholders();
New functions in jQuery 1.7+ on and off
A simpler interface for event handling in jQuery. Just read Dan Wahlin’s blog.
$ and jQuery in SharePoint
Do you still use $ for jQuery? Well, don’t. If your code with $ resides with a SharePoint Images webpart, it will stop working. You’ll get errors like
Uncaught TypeError: Cannot call method 'empty' of null
The reason is that SharePoint uses $ in its own javascript code: CMSSiteManager.js
function $()
{ULSjlC:;
var elements=new Array();
for (var i=0; i < arguments.length; i++)
{
var element=arguments\[i\];
if (typeof element=='string')
element=document.getElementById(element);
if (arguments.length==1) return element;
elements.push(element);
}
return elements;
}
Simple select unselect all
I have a simple html table, every row in tbody has a checkbox. thead has a checkbox. When it is checked/unchecked, all checkboxes have to be selected/ unselected. Here is a very simple javascript to achieve this:
$("#mytable thead :checkbox").live({
change: function () {
var checked = $(this).is(":checked");
$("#mytable tbody :checkbox").attr("checked", checked);
}
});
Nested templates in jQuery.tmpl
I have used jQuery tmpl for a while and it is really awesome. Now I want to use some nested templates. And the thing is: it is very simple to do it: Here is the code to achieve this:
<div onclick="doo()">test</div>
<div id="container"></div>
<script id="parent-template" type="text/html">
<li>
{{tmpl t }}
</li>
</script>
<script id="red" type="text/html">
<span style="color:red">{{= title}}</span>
</script>
<script id="green" type="text/html">
<span style="color:green">{{= title}}</span>
</script>
<script type="text/javascript">
var d = \[\];
d.push({ title: "one", t: "red" });
d.push({ title: "two", t: "green" });
$.template("red", $("#red").template());
$.template("green", $("#green").template());
function doo() {
$("#parent-template").tmpl(d).appendTo("#container");
}
</script>
jQuery: select elements with a specific text
There are situations when you want to select only dom elements which only have a specific content. jQuery provides a beautiful selector :contains:
$("a:contains(Pages)")
```But what if it isn't enough to just get all the elements which contain some word? Let's check what we get if we traverse all anchors on http://sv.wikipedia.org containing "wiki":
$(“a:contains(wiki)”).each(function(i) { console.log($(this).text()); });
[![](https://sharepointkunskap.files.wordpress.com/2012/02/jquery-contains-wiki.png "jquery-contains-wiki")](https://sharepointkunskap.files.wordpress.com/2012/02/jquery-contains-wiki.png) There is another, a generic way, to filter out elements, and it is called "filter". So a little regex check will do the trick.
$(“a”).filter(function() { return /look_for/i.test($(this).text()); }
Parameterize a javascript object and create url
If you want to add some parameters to an url which you want to open, you can use jQuery.param function:
var url = "some\_url";
var params = {
name: "Setner",
email: "setner@narspi.name",
mobile: "123456789"
};
var search = "?" + $.param(p);
url += search;
```It is handy, indeed. In an environment without jQuery (are there some?:) ) you can just iterate an object and join properties:
var url = “some_url”; var params = { name: “Setner”, email: “setner@narspi.name”, mobile: “123456789” }; if (url.match("/\?/g") == null) { url += “?”; } else { url += “&”; } var search = “”; for(var p in params) { search += [p, params[p]].join("="); } url += search;
Save an excel sheet as a clean table
To save an excel sheet as a html table is very easy. Just select the needed area, then go to Save as and check the selection and choose html as output format. It works fine. It even looks like it did in Excel. But what if you don’t want all this junk, you want only the plain html table (e.g. for pasting into WP). When I saved my permission levels to html, I used this javascript code. First open the html page which Excel has created in Chrome, open the Dev Tools console, load the latest jQuery into the page, and remove all unnecessary attributes and styling, remove the comments, after that you can just copy the outerHTML of the table and paste into a text editor:
Simplifying jQuery tmpl interface
In one of my previous posts I showed a simple example how to retrieve data from a web service and render it with jQuery tmpl. To render this I used an id for a template and the container:
<script id="contactTemplate" type="text/html">
<div>
Name: {{= Name }} <br>
Phone: {{= Phone }}
</div>
</script>
<div id="contactContainer"></div>
```To render we select the template and container with jQuery selectors:
function onSuccess(data) { $("#contactTemplate").tmpl(data.d.results).appendTo("#contactContainer"); }
(function ($, undefined) { if ($ === undefined) { throw “Dependency: jQuery is not defined. Please check javascript imports.”; } $.extend($.expr[’:’], { // :template(name) template: function (current, index, metadata, elements) { var arg = metadata[3], d = $(current).data(“template-for”); if (d === undefined) { return false; } return arg ? arg === d : true; }, // :container(name) container: function (current, index, metadata, elements) { var arg = metadata[3], d = $(current).data(“container-for”); if (d === undefined) { return false; } return arg ? arg === d : true; } }); } (jQuery));
use two different versions of jQuery on the same page
jQuery is very popular. The chance that you’ll get two or more jQuery files loaded on the same page is very high. As long as it doesn’t conflict, it is fine. But what if there are differences, and another version of jQuery destroys your functionality. To solve it we can ensure that we invoke “our”, the right version of jQuery. To do so, create a pointer to your jQuery:
var myJq = jQuery.noConfict();
```So if you can, avoid invoking $ or jQuery directly. Here is the original example from [jQuery forum](http://forum.jquery.com/topic/multiple-versions-of-jquery-on-the-same-page):
this.data in jQuery tmpl
In jQuery tmpl we can render properties with {{= SomeProperty }}. Here is an example:
<script type="text/javascript">
Writer = function (firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
Writer.prototype = {
getFullName: function () {
return this.firstName + " " + this.lastName;
}
};
$(document).ready(function () {
var writers = \[\];
writers.push(new Writer("Gennady", "Ajgi"));
writers.push(new Writer("Mišši", "Şeşpĕl"));
writers.push(new Writer("Ille", "Tuktaš"));
writers.push(new Writer("Kĕştenttin", "Ivanov"));
$("#tmpl").tmpl(writers).appendTo("#writers");
});
</script>
<script id="tmpl" type="text/html">
<li>
{{= firstName }} {{= lastName }}
</li>
</script>
<div id="writers"></div>
```It will render like:
* Gennady Ajgi
* Mišši Şeşpĕl
* Ille Tuktaš
* Kĕştenttin Ivanov
But what if we want to access the object itself, not one of the properties. Say, you want to pass the object from the array into a js function as a parameter to decide how it will be rendered, or if you want show a "calculated" property. The key word is...: this.data. this.data has the current object. After it has been rendered, we can access this object with $(this).tmplItem().data.
jQuery tmplItem and no ids
tmplItem() works even without ids. To get the current data:
$(this).tmplItem().data;
```If you want to remove, just invoke the ajax and remove with [$.parents](http://api.jquery.com/parents/):
$(this).parents(“li”).remove();
##### Updating data inside tmplItems
If you want to achieve some fancy dependency tracking, consider [knockout.js](http://knockoutjs.com/). But if you just want to update the data object inside a tmplItem, just change the object and call update:
var t = $(this).tmplItem(); var obj = t.data; obj.Address = “hello avenue”; t.update();
Update list items with listdata.svc
In one of my previous posts I showed how to retrieve data from listdata.svc with jQuery $.getJSON method. Getting data is very simple, listdata.svc provides a powerful restful interface with filtering, expanding and other features. Read the best and short introduction to listdata.svc by Suneet Sharma or a more detailed and technical article about filters, functions and operators by Mike Flasko at Microsoft with short examples here. Now back to listdata.svc in the SharePoint environment. Corey Roth provides a good images and sample results. For REST the “http verbs” are very important: GET, POST, PUT, DELETE.. SharePoint RESTful interface defines these verbs like that:
jQuery UI Datepicker
As an alternative to asp:Calendar we can use the fancy jQuery UI Datepicker:
$(document).ready(function () {
$.datepicker.setDefaults($.datepicker.regional\["sv"\]);
$("#").datepicker({
changeMonth: true,
changeYear: true,
yearRange: "-120:+0"
});
});
```I found this a much simple and best solution for an [birthdate input](http://stackoverflow.com/questions/339956/whats-the-best-ui-for-entering-date-of-birth). We can set [international options](http://stackoverflow.com/questions/1865091/jquery-datepicker-language-problem), [year range](http://stackoverflow.com/questions/269545/jquery-datepicker-years-shown), [year](http://stackoverflow.com/questions/3164898/jquery-ui-datepicker-next-and-previous-year) and [month navigation](http://jqueryui.com/demos/datepicker/dropdown-month-year.html). Other options I have tried are asp:Calendar, ajaxtoolkit:CalendarExtender and DateJs. jQuery UI is the most simple much more than datepicker and works smoothily with SharePoint.
Filtering in javascript
The simplest and the best way to filter an array is to extend the Array.prototype as described here:
if (!Array.prototype.filter) {
Array.prototype.filter = function (func) {
var len = this.length;
if (typeof func != "function")
throw new TypeError();
var res = new Array();
var thisp = arguments\[1\];
for (var i = 0; i < len; i++) {
if (i in this) {
var val = this\[i\];
if (func.call(thisp, val, i, this))
res.push(val);
}
}
return res;
};
}
```Then let's filter on [titles](/2011/11/21/sorting-dates-in-javascript/ "See an example for Sorting with Titles"), which [start with](http://stackoverflow.com/questions/646628/javascript-startswith "See the solution for startsWith in javascript on Stackoverflow") "N":
function startsWithN(element, index, array) { return element.toLowerCase().indexOf(“n”) == 0; }
$.getJSON, jQuery.tmpl and _vti_bin
Javascript is very fast, responsive and unburdens the cpu at the server. Here I show a little example how to use jQuery.getJSON, jQuery.tmpl (wonderful plugin for rendering repeating data, repo hosted on Github) and REST-based service listdata.svc from /_layouts/_vti_bin/ folder. For this example I created a generic list “Contacts”, added two text fields Name and Phone. Add some phone numbers and try to go to /_vti_bin/ListData.svc/Contacts If you get 404-error, install a ADO.NET Data Services v1.5 CTP2, as described at dotnetmafia. If you want to know more about how to sort and filter, skip and limit results, read more at nothingbutsharepoint. If you encounter problems, follow Michaël’s blog post and download and install Windows6.1-KB976127-v6-x64.msu (if you have Windows Server 2008 R2), or NDP35SP1-KB976126-v2-x64.exe (if you have Windows Server 2008). After installing the version of the System.Data.Services.dll file is 3.5.30729.5004 (Windows Server 2008 R2), and 3.5.30729.4466 (Windows Server 2008). Allright, the remainder is pure javascript. In order to get it working you have to run the script from the same domain, meaning you can’t run javascript to retrieve the data from a html-file from your home folder. Create a webpart and add it to your page.
Remove links to user profiles on list with javascript
Well, if you need remove links to user profiles, you can iterate all td-elements with class ms-vb-user using jQuery each function and remove a elements. Here is a little script:
$(document).ready(function() {
$(".ms-vb-user a").each(function() {
var text = $(this).text();
var span = document.createElement("span");
var user = document.createTextNode(text);
span.appendChild(user);
var parent = $(this).parent()\[0\];
parent.removeChild(this);
parent.appendChild(span);
});
});
```EDIT 2012-02-05 A much more better way to do it is [to use replaceWith in jQuery](http://stackoverflow.com/a/2409163/632117 "See a similar question and an answer on StackOverflow"):
$(".ms-vb-user a").each(function() { $(this).replaceWith(this.childNodes); });
Auto-resize the main container in master page
If you have a master page with fixed size (perhaps in a centered layout). Here is a simplistic js-script to auto-resize:
$(window).load(function(){
$wider = false;
$pagecontainer = $("#pagecontainer");
$elementsToCareAbout = $("#ctl00\_MSO\_ContentDiv > \*, #ctl00\_MSO\_ContentDiv table")
$elementsToCareAbout.each(function(){
if($(this).width() > $pagecontainer.width())
{
$wider = true;
}
});
if ($wider) $pagecontainer.width(1200);
});
Any improvement ideas and suggestions are more than welcome.
Check if an html element is hidden using jQuery
Well, sometimes we need to calculate width and so on. In my next post I will write about how to fix auto-resize on fixed sized master pages. But now: a very nice stuff: how to check if an element is hidden or not:
$("#s4-leftpanel").is(":visible")
```It is a pure poetry. It reminds me of the beauty of [symbols in Ruby](http://rubylearning.com/satishtalim/ruby_symbols.html).
Resize image with jQuery to fit the div
There are many interesting jQuery plugins for resizing and cropping of images. Among them are jrac and image scale. I have tested the latter: It works very fine
$(window).load(function() {
var $imgContainer = $("#layout-news-image");
var $newsImg = $("#layout-news-image img\[rel!='sp\_DialogLinkIgnore'\]");
$imgContainer.css("width", $imgContainer.parent().width());
if ($newsImg.length > 0) {
if ($newsImg.width() < $imgContainer.width()) {
$imgContainer.width($newsImg.width());
}
if ($newsImg.height() < $imgContainer.height()) {
$imgContainer.height($newsImg.height());
}
$newsImg.imgscale({
parent : '#layout-news-image',
center: "true",
scale: "fill"
});
}
});
```This script checks if the original image is lesser than container div and doesn't resize if it is so. **#layout-news-image img\[rel!='sp\_DialogLinkIgnore'\]** means that do not resize if there is a hidden image with rel="sp\_DialogLinkIgnore". See the [jQuery selectors](http://api.jquery.com/category/selectors/) for more info. This script can be improved by adding window resize event in javascript. I use **$(window).load** instead of the usual _$(document).ready_ because [ready-function in jQuery runs when DOM is loaded, if the page is not cached it happens before the image is loaded](http://web.enavu.com/daily-tip/daily-tip-difference-between-document-ready-and-window-load-in-jquery/). $(document).ready doesn't work.
## Comments from Wordpress.com
####
[sdfsdf](http://sdsdfsdf "sdfsdf@ssdf.sdd") - <time datetime="2012-06-28 19:28:51">Jun 4, 2012</time>
doesn't work: it's just squeeze the picture. No examples included == no possibility to check.
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-11-05 10:06:01">Nov 1, 2012</time>
Thank you Alejandro for the awesome js lib and sharing it. I will absolutely recommend it.
<hr />
####
[Alejandro Emparan (@krc_ale)](http://twitter.com/krc_ale "krc_ale@twitter.example.com") - <time datetime="2012-11-02 20:21:55">Nov 5, 2012</time>
I wrote a jQuery plugin for that: https://github.com/karacas/imgLiquid
<hr />
window.onload
Sharepoint ger en annan lösning för window.onload och jQuery(document).ready(function() {}); _spBodyOnLoadFunctionNames.push(‘gerdaRibbonInit’);"
jQuery validation with asp.net
De kan var lite jobbigt att få till jQuery validate att funka ihop med aspnetForm…
$(document).ready(function () {
newsLetterForm = $("#aspnetForm");
newsLetterForm.validate({
onsubmit: false,
rules: {
"<%= emailTextBox.UniqueID %>": {
required: true,
email: true
}
}
});
$("#<%= sendButton.ClientID %>").live("click", function {
var isValid = newsLetterForm.valid();
if (!isValid) {
e.preventDefault();
}
});
});
jQuery validate kräver name på elementen inuti formen. För att ta reda på name, måste man använda Control.UniqueId För att det ska fungera måste du köra preventDefault()
jQuery hide
Jag har alltid använt hide-funktionen i jQuery för att gömma vissa element som inte behövs i början. Det kan resultera att användaren ser skymningen av dem i laddningen av sidan. Vilket inte är så bra. Men det har visat sig, att hide behöver inte köras av jQuery. Bara göm dem med hjälp av css. jQuery show kommer funka ändå.
Validera din form på klienten
Det finns ett mycket bra jQuery-tillägg som kan validera din data i en formulär på ett enkelt sätt. Se en demo. Referera till validate.js och ange rätt css-klasser på dina inputs: “required”, “error”, “url”, “valid”. Mycket smidigt.
Ladda jQuery dynamiskt till din sida
Vill du ändra innehåll, testa olika javascript-funktioner på din sida, prova något direkt i webbläsaren (utan att behöva deploya om), så är DevTools i Chrome, eller Firebug i Firefox väldigt bra verktyg. Om du har jQuery på din sida, så är det ännu bättre. Men om du inte har det, så ladda det i efterhand genom att öppna konsolen (Ctrl-Shift-J i Chrome) och kör följande rader kod (klistra in dem på en gång, och tryck på Enter):
Polymorfi och javascript
En skräckscenario: du använder två javascript-bibliotek. Men de har var sin funktion som har samma namn. Det spelar även ingen roll om antalet inparametrar är olika. Så det blir samma sak som myfunc(param1, param2) och myfunc(param1). Grejen är att funktionen som laddas sist är den som kommer köras. Katastrof! Men det finns lösningar. Börja läsa här om hur man kan simulera polymorfi i javascript på about.com. Säg vi har en funktion som heter MoveToDate(strdate, ctxid) den ingår i init.debug.js (som används av Sharepoint kalenderwebpart). Sedan har vi något annat javascript-bibliotek som också har MoveToDate(param). Låt oss göra det polymorfiskt. Här är koden:
Tag: Memory
Improving the web performance of an intranet
[caption id=“attachment_3437” align=“alignnone” width=“480”] All the “small” app parts, web parts, delegate controls, user controls, and other “packages” that “must” be delivered to the users on every page load of the Start Page of your Intranet.[/caption] Recently we made an investment to improve the performance of our intranet. We made many changes in different layers: SQL, Network, Browser upgrade and code. Here I want to tell about what code changes we did to improve the web browser performance. Please leave feedback if you find it useful. You can also share your suggestions. We measured the performance before our code changes and after them. We had amazing results. Unfortunately I can not share any numbers, but we improved the Time to First Byte, time to load event firing in the browser, memory consumption in the clients and, perhaps, the most important, we improved the perceived performance of the Intranet, the way how users experience the speed and UI responsiveness. To do this I got many ideas of my project colleagues and branch colleagues. Here is the list of changes we’ve implemented:
Tag: Hive
Do not mess with the hive
In our Intranet we got this nasty double encoding error that was introduced in SharePoint April 2014 CU. In July 2014 CU the problem is still there. I often hear the suggestions to update files directly in the hive (the root folder for SharePoint: C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\) In that blog post it is described what the problem is and what files are affected and what code must be altered in order to get it to work (which I like). But it is also suggested to update the Search.ClientControls.js directly on the server (which I don’t like). So my advise is:
Tag: Newsfeed
Showing Birthdays and Job Anniversaries in the Newsfeed
In our project we have a requirement to show birthdays and job anniversaries in the Newsfeed. The solution is simple (when you know it) but there has not been any information about it online, until today. I want to share a few lines of PowerShell code to enable Anniversary notifications in the Newsfeed. This desired piece of code was written by my colleague Emma Degerman. Enjoy:
[source language=“PowerShell”] $job = Get-SPTimerJob | ? { $_.TypeName -like “*.UserProfileChangeJob” } $job.GenerateAnniversaries = $true $job.Schedule = [Microsoft.SharePoint.SPSchedule]::FromString(“hourly between 55 and 55”) $job.Update() [/source]
Tag: Social
Showing Birthdays and Job Anniversaries in the Newsfeed
In our project we have a requirement to show birthdays and job anniversaries in the Newsfeed. The solution is simple (when you know it) but there has not been any information about it online, until today. I want to share a few lines of PowerShell code to enable Anniversary notifications in the Newsfeed. This desired piece of code was written by my colleague Emma Degerman. Enjoy:
[source language=“PowerShell”] $job = Get-SPTimerJob | ? { $_.TypeName -like “*.UserProfileChangeJob” } $job.GenerateAnniversaries = $true $job.Schedule = [Microsoft.SharePoint.SPSchedule]::FromString(“hourly between 55 and 55”) $job.Update() [/source]
Get all comments
If you try to get comments quantity for a url, you may wonder, why there is only quantity of the comments which the current user has posted:
public int GetNumberOfNewsPageComments
(SPSite currentSite, string pageUrl, int max)
{
var serviceContext =
SPServiceContext.GetContext(currentSite);
var socialCommentManager =
new SocialCommentManager(serviceContext);
var comments = socialCommentManager
.GetComments(new Uri(pageUrl), max);
if (comments != null)
{
return comments.Length;
}
return -1;
}
```The solution is to impersonate the SPSite object with an account who has the rights to manage social data. Give this permission to the account in CA - Application Management - Service Applications - User Profile Service. [![](https://sharepointkunskap.files.wordpress.com/2011/09/manage-social-data.png?w=284 "manage-social-data")](https://sharepointkunskap.files.wordpress.com/2011/09/manage-social-data.png)
SocialCommentWebPart
Lägg till en kommentarruta i din sida. Gör det lite till webb2.0. Här finns lite info. På denna sida står det hur man kan lägga till webparten mha xml. You can even provision a social comment webpart like it is done in my site:
<File Url="person.aspx" Type="Ghostable">
<AllUsersWebPart WebPartZoneID="MiddleLeftZone" WebPartOrder="3">
<!\[CDATA\[
<WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">
<Assembly>Microsoft.SharePoint.Portal, Version=14.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<TypeName>Microsoft.SharePoint.Portal.WebControls.SocialCommentWebPart</TypeName>
<Title>$Resources:spscore,SocialComment\_WebPart\_Title</Title>
<Description>$Resources:spscore,SocialComment\_WebPart\_Description</Description>
<PartOrder>3</PartOrder>
<FrameType>TitleBarOnly</FrameType>
<AllowMinimize>true</AllowMinimize>
<AllowRemove>true</AllowRemove>
<IsVisible>true</IsVisible>
</WebPart>
\]\]>
</AllUsersWebPart>
</File>
Tag: Timer
Showing Birthdays and Job Anniversaries in the Newsfeed
In our project we have a requirement to show birthdays and job anniversaries in the Newsfeed. The solution is simple (when you know it) but there has not been any information about it online, until today. I want to share a few lines of PowerShell code to enable Anniversary notifications in the Newsfeed. This desired piece of code was written by my colleague Emma Degerman. Enjoy:
[source language=“PowerShell”] $job = Get-SPTimerJob | ? { $_.TypeName -like “*.UserProfileChangeJob” } $job.GenerateAnniversaries = $true $job.Schedule = [Microsoft.SharePoint.SPSchedule]::FromString(“hourly between 55 and 55”) $job.Update() [/source]
Tag: Timerjob
Showing Birthdays and Job Anniversaries in the Newsfeed
In our project we have a requirement to show birthdays and job anniversaries in the Newsfeed. The solution is simple (when you know it) but there has not been any information about it online, until today. I want to share a few lines of PowerShell code to enable Anniversary notifications in the Newsfeed. This desired piece of code was written by my colleague Emma Degerman. Enjoy:
[source language=“PowerShell”] $job = Get-SPTimerJob | ? { $_.TypeName -like “*.UserProfileChangeJob” } $job.GenerateAnniversaries = $true $job.Schedule = [Microsoft.SharePoint.SPSchedule]::FromString(“hourly between 55 and 55”) $job.Update() [/source]
Tag: Profile
Load git into PowerShell
Just a little productivity tip. If you use git on Windows, you probably already have the Github for Windows application. This application adds the Git Shell:
The Git Shell will open a PowerShell window and execute shell.ps1 from the Github directory:
What it won’t do is to load your personal PowerShell profile. I want to use my PowerShell profile that creates some links and adjust the look-and-feel and the promt of the shell. By the way I have published my profile.ps1 as a gist:
Hide my site link with css
Want to hide my site link without disabling social features. Well, the simplest way to do it is to use css:
#mp1\_0\_0\_Anchor { display: none; }
```If you want to hide my profile instead, just hide #mp1\_0\_1\_Anchor:
#mp1_0_1_Anchor { display: none; }
.ms-MenuUIUL li[text=‘My Site’] { display: none;}
##### Disable the my profile feature An even better solution is maybe to disable the ability to change the profiles. [Just remove the permission to "user personalization..." for All authenticated users in User Profile Service](http://blog.libinuko.com/2010/10/10/sharepoint-2010-howto-disable-my-site-and-my-profile-link/).
## Comments from Wordpress.com
####
[John]( "johnandrewdavies@hotmail.com") - <time datetime="2012-03-07 00:15:32">Mar 3, 2012</time>
Be careful this cannot be used, the classes for pop up menus are generated dynamically on the page, and that class can be applied to a number of menus I assume depending on the order which they load on the page, which isnt the same every time, so for instance this hides something in the site actions menu, or the new button on a library sometimes.
<hr />
####
[Brett Anderson](http://sharepoint2020.wordpress.com "brettando@live.com.au") - <time datetime="2012-05-02 06:13:05">May 3, 2012</time>
Hi, The amended solution does not work in IE7.
<hr />
####
[Fredrik]( "fredrik.eriksson234@gmail.com") - <time datetime="2012-03-09 15:27:24">Mar 5, 2012</time>
Thank you Anatoly, that worked perfectly in all browsers! I had problems with the first suggested solution, because it would hide other menu items, like "edit this page" from the site settings dropdown!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:10:36">Mar 3, 2012</time>
You are totally right, John! I realized that too. Fortunately, I didn't need that then. But while using that I saw that sometimes Site Actions -Edit Page disappeared. These IDs are really generated dynamically. Thanks for your comment. I'll update my post.
<hr />
####
[vishal]( "vishals.shivan@gmail.com") - <time datetime="2012-03-07 07:27:54">Mar 3, 2012</time>
Hi Anatoly. Thanks for the solution. but the problem we are facing one problem after implementing this. Once we make this change and when login to the portal next time, the "Edit Page" link under site action menu is not getting displayed and the My Site Link is getting displyed. any suggestion?
<hr />
####
[Material SharePoint » Hide ‘My Site’ Link from Welcome User Dropdown Control](http://sharepoint.jsturges.com/2012/05/hide-my-site-link-from-welcome-user-dropdown-control/ "") - <time datetime="2012-05-12 17:45:13">May 6, 2012</time>
\[...\] of my enterprise level clients that we usually hide it all together! To do this, you can use an awesome CSS trick I learned from Anatoly \[...\]
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:24:39">Mar 3, 2012</time>
Hi Vishal. Unfortunately we cannot rely on these IDs, as John in previous comment mentioned, because these IDs are generated dynamically. I'll update my post. One possible solution would be use attribute selectors... Something like .ms-MenuUIUL li\[text='My Site'\] { display: none;}
<hr />
####
[jim]( "jim.omara@gmail.com") - <time datetime="2014-02-12 17:38:05">Feb 3, 2014</time>
.ms-welcomeMenu #mp1\_0\_0{ display:none; } .ms-welcomeMenu #mp1\_0\_1{ display:none; } .ms-welcomeMenu #mp1\_0\_2{ display:none; } .ms-welcomeMenu #mp1\_0\_3{ display:none; } .ms-welcomeMenu #mp1\_0\_4{ display:none; } .ms-welcomeMenu #mp1\_0\_8{ display:none; } .ms-welcomeMenu #mp1\_0\_9{ display:none; } these work for me.
<hr />
####
[Anatoly Mironov](http://chuvash.eu "mirontoli@gmail.com") - <time datetime="2014-02-12 23:20:59">Feb 3, 2014</time>
Thank you for sharing your solution. Appreciate.
<hr />
Tag: Ps1
Load git into PowerShell
Just a little productivity tip. If you use git on Windows, you probably already have the Github for Windows application. This application adds the Git Shell:
The Git Shell will open a PowerShell window and execute shell.ps1 from the Github directory:
What it won’t do is to load your personal PowerShell profile. I want to use my PowerShell profile that creates some links and adjust the look-and-feel and the promt of the shell. By the way I have published my profile.ps1 as a gist:
Tag: Apploader
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Tag: CAM
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
My five takeaways from the SharePoint Conference 2014
The SharePoint Conference 2014 was an astounding event. Over 10 000 like-minded SharePointers that met, learned a lot and shared new ideas, couldn’t be better. It was also the first time I was to the U.S. and Las Vegas. What a country, what a city! This place must burn people’s lives faster than anywhere else in the world :) I want to share my five takeaways from this conference. I’ll keep it short:
Tag: Concept
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Tag: Masterpage
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Erik Swensson's book about Sharepoint Branding
Today Erik Swensson’s book Practical SharePoint 2010 Branding and Customization came to our company. I am looking forward to read it. It’s about time to see alternatives to Randy’s starters.
Add TreeView to Site
For all of who use Randy Drisgill’s starter masters, it won’t help if you go to Site Actions TreView and just enable it, because the DelegateControl is in a hidden panel. To really restore the original treeview you have to copy this xml from v4.master:
<Sharepoint:UIVersionedContent runat="server" UIVersion="4">
<ContentTemplate>
<Sharepoint:SPNavigationManager
id="TreeViewNavigationManagerV4"
runat="server"
ContainedControl="TreeView"
CssClass="s4-treeView"
>
<SharePoint:SPLinkButton runat="server"
NavigateUrl="~site/\_layouts/viewlsts.aspx"
id="idNavLinkSiteHierarchyV4"
Text="<%$Resources:wss,treeview\_header%>"
accesskey="<%$Resources:wss,quiklnch\_allcontent\_AK%>"
CssClass="s4-qlheader" />
<div class="ms-treeviewouter">
<SharePoint:DelegateControl runat="server" ControlId="TreeViewAndDataSource">
<Template\_Controls>
<SharePoint:SPHierarchyDataSourceControl
runat="server"
id="TreeViewDataSourceV4"
RootContextObject="Web"
IncludeDiscussionFolders="true"
/>
<SharePoint:SPRememberScroll runat="server"
id="TreeViewRememberScrollV4"
onscroll="javascript:_spRecordScrollPositions(this);"
style="overflow: auto;height: 400px;width: 155px; ">
<Sharepoint:SPTreeView
id="WebTreeViewV4"
runat="server"
ShowLines="false"
DataSourceId="TreeViewDataSourceV4"
ExpandDepth="0"
SelectedNodeStyle-CssClass="ms-tvselected"
NodeStyle-CssClass="ms-navitem"
SkipLinkText=""
NodeIndent="12"
ExpandImageUrl="/_layouts/images/tvclosed.png"
ExpandImageUrlRtl="/_layouts/images/tvclosedrtl.png"
CollapseImageUrl="/_layouts/images/tvopen.png"
CollapseImageUrlRtl="/_layouts/images/tvopenrtl.png"
NoExpandImageUrl="/_layouts/images/tvblank.gif"
>
</Sharepoint:SPTreeView>
</Sharepoint:SPRememberScroll>
</Template_Controls>
</SharePoint:DelegateControl>
</div>
</Sharepoint:SPNavigationManager>
</ContentTemplate>
</SharePoint:UIVersionedContent>
and paste it before:
s4-die
s4-die is a funny stuff. Now I realized the purpose of it. Everything that has to be hidden, Microsoft wraps in an element with class=“s4-die”. In corev4.css it is defined with display:none. Not so bad. Another approach is to create a invisible panel like Randy Drisgill has done. But with s4-die you don’t need to move your stuff around, just add the class s4-die.
master page for html5 and css3
A great work: v5.master. I am recommending to try it. The problem are some javascript bugs in the IE 9 when you run IE mode 9 that are necessary to enable html5 and css3 support. You can’t “save” a list item: The reason why it doesn’t work in IE, but in Chrome, Firefox, is that IE invokes some functionality that it doesn’t invoke in other browsers. Next: Enable Save button in IE9
Custom PlaceHolder
You want some custom content in your site and it is different from page to page. Well, I wrote how to achieve this with delegate controls. Another approach is to use PlaceHolders. Maybe you can use some existing placeholders. There are so many unused placeholders in v4.master. Like PlaceHolderLeftActions. If you use starter master pages from Randy Drisgill, you must move these from invisible panel. To create custom placeholder is very easy: Just copy an existing placeholder in the master page and name it som appropriate like:
Create your own search box
It is very simple. Create a new module: SearchArea. Delete Sample.txt and Elements.xml. Create a new file: SearchArea.xml
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Control
Id="ContosoSearchAreaBox"
Sequence="15"
ControlClass="Microsoft.SharePoint.Portal.WebControls.SearchBoxEx"
ControlAssembly="Microsoft.Office.Server.Search, Version=14.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Property Name="GoImageUrl">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="GoImageUrlRTL">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="GoImageActiveUrl">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="GoImageActiveUrlRTL">/\_layouts/images/Contoso/searchbutton.png</Property>
<Property Name="DropDownMode">HideDD\_useDefaultScope</Property>
<Property Name="FrameType">None</Property>
<Property Name="UseSiteDefaults">false</Property>
</Control>
</Elements>
Next add your searcharea module to a site scoped feature.
In the masterpage locate this:
<SharePoint:DelegateControl runat="server"
ControlId="SmallSearchInputBox" Version="4" />
and replace with your brand new search area:
Create own delegate control
In this post I’ll show how to create a simple (but own) delegate control. A short intro and links on delegate controls can be found on sharepointoverflow. Take a look on master page. There are already many delegate controls. The delegate control with id AdditionalPageHead can be used for adding your script or jQuery library.:
<SharePoint:DelegateControl
runat="server"
ControlId="AdditionalPageHead"
AllowMultipleControls="true"/>
You can also override existing controls like searchbox. But what if you want to add some content in the master page where no delegate controls are present. Of course, you can add it directly to the master page. Perhaps not on all webs? You can use placeholders to manage it. But do you want to update all the page layouts? So the solution is to use delegate controls, for adding multiple pieces of content or overriding using Sequence. In this example I’ll add some new content to the quicklaunch bottom area:
Custom favicon
It is easy to use a custom favicon, put a ico image into a mapped folder Images and then locate this line in your master page:
<SharePoint:SPShortcutIcon runat="server" IconUrl="/\_layouts/images/favicon.ico" />
```And replace it with your ico:
<SharePoint:SPShortcutIcon runat=“server” IconUrl="/_layouts/images/CONTOSO/favicon.ico" />
Videokurs om Web Content Management
På microsoft.com finns en ny videokurs om web content management. Där kan du lära dig om hur man implementerar cms-funktionalitet med sharepoint, bl.a.: content types, page layouts med mera. Tack för tipset, deutschsprachige Sharepoint-Community.
masterpage i application page
Om det inte funkar att ändra masterpage genom DynamicMasterPageFile:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CreateNews.aspx.cs" Inherits="MyProject.Layouts.MyProject.CreateNews"
DynamicMasterPageFile="~masterurl/default.master" %>
Kör det här
<script type="text/C#" runat="server">
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
this.MasterPageFile = "/\_catalogs/masterpage/my-custom.master";
}
</script>
Tag: SharePointOnline
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Tag: Tenancy
AppLoader Concept for SharePoint apps
In this post I want to share an unusual, nevertheless interesting conceptual idea of loading content from SharePoint 2013 apps on many pages. The original awesome concept was proposed and developed by my colleague Martin Villysson at Bool.
The problem we are trying to solve
SharePoint apps are great to extend functionality in SharePoint and integrate other systems (full page apps available through Site Contents), they also provide tools to enrich the default SharePoint experience by App Parts (Client Web Parts) and Custom Actions (additional menus).
Tag: Dns
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
local dns
Hur gör man om man vill ha två olika internet-adresser för olika inloggningar. Om man har DNS inställt rätt - inga problem. Men hur gör man för att testa det på sin lokala maskin. Man kan ändra dns-information på sin maskin. För detta ska filen [hosts](http://en.wikipedia.org/wiki/Hosts_%28file% 29#Content_and_location) uppdateras. I Windows tryck på Start och i sökrutan skriv:
%SystemRoot%\\system32\\drivers\\etc\\hosts
Den här filen är raka motsvarigheten till /etc/hosts i Linux. I filen som öppnas lägg till följande rader som sist:
Tag: Ip
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
Tag: Network
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
Tag: Sharepoint App
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
Tag: Spapp
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
What about the SharePoint app domain?
This is an open question about the domains for SharePoint apps. On Technet: Configure an environment for apps for SharePoint (SharePoint 2013) we can read the following:
You must configure a new name in Domain Name Services (DNS) to host the apps. To help improve security, the domain name should not be a subdomain of the domain that hosts the SharePoint sites. For example, if the SharePoint sites are at Contoso.com, consider ContosoApps.com instead of App.Contoso.com as the domain name.
PowerShell: Get version and ProductId from an .app package
In my project I deploy some apps directly through the ObjectModel directly with PowerShell. The apps are built with TFS I have a script that installs or updates apps if there is a new version of the app. Previously I used Import-SPAppPackage to compare the version and productid with an existing app instance, but often I get this error:
The provided App differs from another App with the same version and product ID.
Apps can only call the OOB CSOM and REST endpoints
As a SharePoint architect or a SharePoint developer, you must have been thinking about the benefits/limitations of SharePoint apps a lot. I want to point out one of them today, which is very important: using custom webservices deployed to SharePoint inside apps. That is impossible and it is designed to be so due to the security architecture in the sharepoint app framework. I have read much about SharePoint apps (books, whitepapers, blog posts) and stumbled over these two contradictive statements:
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
SharePoint Apps: "Provider Hosted First" Approach
Recently I had an exciting mail conversation with Thomas Deutsch. He came up with an idea how to fasten the development of apps. This smart approach is called “Provider Hosted First”. See Thomas’ original blog post. Here are some highlights: What you actually do is a local website which runs in grunt server
:
localhost:9000
```Then a SharePoint-hosted app is created with an SPAppIframe that refers to that local app site. Genious!!! Some key features of this approach:
* This local app contains a livereload script. Your sharepoint app is updated every time you save your css, js, html file in your IDE
* Grunt minifies, bundles your assets
* Grunt runs your tests automatically when your content is modified
* The SharePoint app can be on Premises, on Office 365, wherever you want it.
#### Video
\[caption id="attachment\_2808" align="alignnone" width="630"\][![See the video how it looks like to develop using this approach](https://sharepointkunskap.files.wordpress.com/2013/07/sp-app-002.png?w=630)](http://www.screenr.com/LA8H) See the video how it looks like to develop using this approach\[/caption\]
## Comments from Wordpress.com
####
[Paul Tavares](http://paultavares.wordpress.com "paultavares1@gmail.com") - <time datetime="2013-07-10 02:59:34">Jul 3, 2013</time>
This is pretty cool and very similar to my current setup for developing javascript applications for SharePoint. I use a script to "deploy" updates from my PC to the folder in a document library. I'll try this out when I get around to playing with SP2013.
<hr />
####
[Björn]( "bjorn.roberg@bool.se") - <time datetime="2013-07-02 11:07:08">Jul 2, 2013</time>
Awesome! I'm gonna try that out!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-07-02 15:31:33">Jul 2, 2013</time>
Great! When you go to Thomas Deutsch blog, you can download the source code for the solution.
<hr />
Tag: Vbox
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
Tag: Virtualbox
Configuring VirtualBox for SharePoint-Hosted Apps
Recently I have switched from VMWare to VirtualBox for my SharePoint Development. So far it really works good. I have prepared this guide for configuring VirtualBox for SharePoint-hosted apps. That means we need a new adapter with a static ip address. All the steps done inside the virtual machine are applicable for VMWare and Hyper-V, too. This guide does not cover the full configuration of the app environment, it covers only the network and dns settings needed for SharePoint-hosted apps on Premises in a Development machine.
Tag: Presentation
A presentation about PowerShell and SharePoint
Yesterday I had a little presentation about PowerShell basics in the SharePoint context. Here you can see the presentation I’ve published on slideshare. The text is in Swedish.
[slideshare id=37316916&doc=sharepoint-140724063012-phpapp01&w=600]
Two interesting html5-in-sharepoint presentations
[slideshare id=11031050&doc=sharepointhtml5-120113215236-phpapp02] HTML5-and-CSS3-What-About-SharePoint.pdf (968 KB) by Kyle Schaefer
Tag: Slideshare
A presentation about PowerShell and SharePoint
Yesterday I had a little presentation about PowerShell basics in the SharePoint context. Here you can see the presentation I’ve published on slideshare. The text is in Swedish.
[slideshare id=37316916&doc=sharepoint-140724063012-phpapp01&w=600]
Tag: Functional
A PowerShell one liner
PowerShell is powerful. You can write concise, well formulated, functional-style code. Recently I got the following quiz:
You’ve got $100. You have to buy exactly 100 animal, at least 1 dog, 1 cat and 1 mouse. 1 dog costs $15, 1 cat costs $1, 1 mouse costs $0.25.
There can be many ways to solve it. But look at this one line solution. It is quite impressive what you can do with PowerShell [code language=“powershell”] 1..98 | % { $dog = $_ 1..98 | % { $cat = $_ @{ “Dog” = $dog “Cat” = $cat “Mouse” = 100 - $dog -$cat } } } | ? { $_.Mouse -gt 0 } | ? { $_.Dog * 15 + $_.Cat * 1 + $_.Mouse * 0.25 -eq 100 } [/code] This solution uses ranges, dynamic objects (PSObject), nested for loops, implicit returns and advanced filtering. All that is is out-of-the-box PowerShell.
Tag: Oneliner
A PowerShell one liner
PowerShell is powerful. You can write concise, well formulated, functional-style code. Recently I got the following quiz:
You’ve got $100. You have to buy exactly 100 animal, at least 1 dog, 1 cat and 1 mouse. 1 dog costs $15, 1 cat costs $1, 1 mouse costs $0.25.
There can be many ways to solve it. But look at this one line solution. It is quite impressive what you can do with PowerShell [code language=“powershell”] 1..98 | % { $dog = $_ 1..98 | % { $cat = $_ @{ “Dog” = $dog “Cat” = $cat “Mouse” = 100 - $dog -$cat } } } | ? { $_.Mouse -gt 0 } | ? { $_.Dog * 15 + $_.Cat * 1 + $_.Mouse * 0.25 -eq 100 } [/code] This solution uses ranges, dynamic objects (PSObject), nested for loops, implicit returns and advanced filtering. All that is is out-of-the-box PowerShell.
Tag: Ie8
Updating hover style in IE8 Developer Tools
In our project we still have to support Internet Explorer 8. The CSS issues in IE8 are most difficult to debug and solve. You can not add a new rule in Developer Tools or toggle the state of an element to hover as in moder web browser dev tools. One solution that I’ve come up to today, is to add a style with javascript or jQuery, open the script pane in IE8 Dev Tools and add this line: [code language=“javascript”] $(’.ms-srch-item:hover {filter:none !important;}’) .appendTo($(‘body’)) [/code] This will fill update the hover effect of the .ms-srch-item directly. That’s it, just a little tip.
Styling suiteBar and IE8
Today I want to share little css tip for styling the suiteBar in SharePoint 2013 and making it work even in IE8. I needed to apply a green color to the suiteBar (#005128). It worked in all browsers except IE8: The reason why is a special css rule (in corev15.css) that only IE8 understands: [sourcecode language=“css”] .ms-core-needIEFilter #suiteBarLeft { filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=#ff0072c6,endColorstr=#ff0072c6); } [/sourcecode] I found this answer in an blog post written by Trace Armstrong: SharePoint 2013 – Branding the Top Bar and the Importance of Browser Testing. You could override this css rule with your colors, just dig into the msdn documentation. What I needed though, was just a plain color, so I didn’t want to dig into that old progid-definitions. There is actually a simpler solution on social.msdn.microsoft.com. A guy called avshinnikov just overrides the “filter” rule by setting it to none. If you apply it only with id selector (#suiteBarLeft) then you have to put “!important” after that. Fortunately I allready had my own css class on html tag which is a sort of a “namespace” for my selectors: [sourcecode language=“css”] .takana-html #suiteBarLeft { background-color: #005128; filter: none; } [/sourcecode] The class .takana-html can have any name, of course, and it can be a class on a closer parent element to the suiteBar. The only goal for that is to make your css rules more important in your design in a natural way (and avoiding the “!important”). Eventhough many people use this principle without thinking about it, I’ve not found any info regarding this principle. I only heard Jeremy Foster and Michael Palermo talking about it and referring to it as “css namespaces” in a video course: Developing in HTML5 with JavaScript and CSS3 Jump Start. Of course, the name isn’t unique, there is another thing called css namespaces. But the concept is really good.
Tag: Community
Debugging "What's happening" in Communities
Recently an issue was reported about count mismatches in SharePoint 2013 Communities. The number of replies in category tiles sometimes is different compared to the community stats in the web part called “What’s happening”. The actual number of replies is 1 in the figure below. The user who has reported has tried to add, update and delete discussions and replies. I have invested some time debugging this issue. It would be pity to not share my findings. Well the first thing to do was to determine the type name for the “What’s happening” web part. To do so just edit the page and export the web part. In the exported .webpart file I saw that the type was Microsoft.SharePoint.Portal.WebControls.DashboardWebPart. With that knowledge it is time to open ILSpy, an awesome and free(!) assembly browser and decompiler. Load the “Microsoft.SharePoint.Portal” assembly from GAC into ILSpy. Then use F3 to search for DashboardWebPart: The number of replies is retrieved from SPWeb.AllProperties: If the Property Bag does not contain it, it gets the number of replies from the list. The formula is as follows: [code language=“csharp”] list.ItemCount - list.RootFolder.ItemCount [/code] It means that it gets the number of both discussions and replies: ItemCount of Discusssions List. The number of Discussions is determined by the ItemCount in the RootFolder of the Discussions List. Discussions are List Items in the RootFolder (num2 in the figure below). Replies are saved in the subfolders, every discussion gets an own folder. The number of all replies are num3 in the figure below. After checking the web properties I could see that the number of replies there were wrong: 2. The next step was to determine where and when the Web Properties are updated. The first guess every SharePoint Developer has in such cases is an EventReceiver. Here are all EventReceivers connected to the Discussions List: [code language=“powershell”] $list.EventReceivers | select class, Type, Synchronization | Out-GridView [/code] Allright, CommunityEventReceiver then: Found where the actual update happens: CommunityUtils.UpdateWebIndexedPropertyBag The method is used in DiscussionListCommunityEventHandler.HandleEvent There is a flag, flag5 that is used to determine if the Web Properties should be updated: But the flag5 is not true on Delete operations in some code flows: That’s it. So deleting a reply will not have any effect on “What’s happening”. But adding a new discussion will also update the stats: To summarize the debug session, there is an issue in the OOB code that misses to update community stats when deleting a discussion or a reply. Adding a new discussion, or a reply will synchronize the stats.
My five takeaways from the SharePoint Conference 2014
The SharePoint Conference 2014 was an astounding event. Over 10 000 like-minded SharePointers that met, learned a lot and shared new ideas, couldn’t be better. It was also the first time I was to the U.S. and Las Vegas. What a country, what a city! This place must burn people’s lives faster than anywhere else in the world :) I want to share my five takeaways from this conference. I’ll keep it short:
Tag: Debug
Debugging "What's happening" in Communities
Recently an issue was reported about count mismatches in SharePoint 2013 Communities. The number of replies in category tiles sometimes is different compared to the community stats in the web part called “What’s happening”. The actual number of replies is 1 in the figure below. The user who has reported has tried to add, update and delete discussions and replies. I have invested some time debugging this issue. It would be pity to not share my findings. Well the first thing to do was to determine the type name for the “What’s happening” web part. To do so just edit the page and export the web part. In the exported .webpart file I saw that the type was Microsoft.SharePoint.Portal.WebControls.DashboardWebPart. With that knowledge it is time to open ILSpy, an awesome and free(!) assembly browser and decompiler. Load the “Microsoft.SharePoint.Portal” assembly from GAC into ILSpy. Then use F3 to search for DashboardWebPart: The number of replies is retrieved from SPWeb.AllProperties: If the Property Bag does not contain it, it gets the number of replies from the list. The formula is as follows: [code language=“csharp”] list.ItemCount - list.RootFolder.ItemCount [/code] It means that it gets the number of both discussions and replies: ItemCount of Discusssions List. The number of Discussions is determined by the ItemCount in the RootFolder of the Discussions List. Discussions are List Items in the RootFolder (num2 in the figure below). Replies are saved in the subfolders, every discussion gets an own folder. The number of all replies are num3 in the figure below. After checking the web properties I could see that the number of replies there were wrong: 2. The next step was to determine where and when the Web Properties are updated. The first guess every SharePoint Developer has in such cases is an EventReceiver. Here are all EventReceivers connected to the Discussions List: [code language=“powershell”] $list.EventReceivers | select class, Type, Synchronization | Out-GridView [/code] Allright, CommunityEventReceiver then: Found where the actual update happens: CommunityUtils.UpdateWebIndexedPropertyBag The method is used in DiscussionListCommunityEventHandler.HandleEvent There is a flag, flag5 that is used to determine if the Web Properties should be updated: But the flag5 is not true on Delete operations in some code flows: That’s it. So deleting a reply will not have any effect on “What’s happening”. But adding a new discussion will also update the stats: To summarize the debug session, there is an issue in the OOB code that misses to update community stats when deleting a discussion or a reply. Adding a new discussion, or a reply will synchronize the stats.
Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)
I have had a strange bug. The comment text box in a OOB SharePoint 2013 blog doesn’t appear. It only says: “There are no comments for this post.” In this blog post I’ll tell you how I found the bug and I’ll show you how you can temporarily bring the commenting to life. I have had luck. While it doesn’t work on the Test Environment, it does actually work on my development machine. The comments text box is rendered as an OnPostRender action in the blog comments display template. After debugging the javascript in hours and comparing the two environments, I just could confirm that displaytemplates are the same. There are two main javascript files that are involved:
Tag: Ilspy
Debugging "What's happening" in Communities
Recently an issue was reported about count mismatches in SharePoint 2013 Communities. The number of replies in category tiles sometimes is different compared to the community stats in the web part called “What’s happening”. The actual number of replies is 1 in the figure below. The user who has reported has tried to add, update and delete discussions and replies. I have invested some time debugging this issue. It would be pity to not share my findings. Well the first thing to do was to determine the type name for the “What’s happening” web part. To do so just edit the page and export the web part. In the exported .webpart file I saw that the type was Microsoft.SharePoint.Portal.WebControls.DashboardWebPart. With that knowledge it is time to open ILSpy, an awesome and free(!) assembly browser and decompiler. Load the “Microsoft.SharePoint.Portal” assembly from GAC into ILSpy. Then use F3 to search for DashboardWebPart: The number of replies is retrieved from SPWeb.AllProperties: If the Property Bag does not contain it, it gets the number of replies from the list. The formula is as follows: [code language=“csharp”] list.ItemCount - list.RootFolder.ItemCount [/code] It means that it gets the number of both discussions and replies: ItemCount of Discusssions List. The number of Discussions is determined by the ItemCount in the RootFolder of the Discussions List. Discussions are List Items in the RootFolder (num2 in the figure below). Replies are saved in the subfolders, every discussion gets an own folder. The number of all replies are num3 in the figure below. After checking the web properties I could see that the number of replies there were wrong: 2. The next step was to determine where and when the Web Properties are updated. The first guess every SharePoint Developer has in such cases is an EventReceiver. Here are all EventReceivers connected to the Discussions List: [code language=“powershell”] $list.EventReceivers | select class, Type, Synchronization | Out-GridView [/code] Allright, CommunityEventReceiver then: Found where the actual update happens: CommunityUtils.UpdateWebIndexedPropertyBag The method is used in DiscussionListCommunityEventHandler.HandleEvent There is a flag, flag5 that is used to determine if the Web Properties should be updated: But the flag5 is not true on Delete operations in some code flows: That’s it. So deleting a reply will not have any effect on “What’s happening”. But adding a new discussion will also update the stats: To summarize the debug session, there is an issue in the OOB code that misses to update community stats when deleting a discussion or a reply. Adding a new discussion, or a reply will synchronize the stats.
Tag: Oob
Debugging "What's happening" in Communities
Recently an issue was reported about count mismatches in SharePoint 2013 Communities. The number of replies in category tiles sometimes is different compared to the community stats in the web part called “What’s happening”. The actual number of replies is 1 in the figure below. The user who has reported has tried to add, update and delete discussions and replies. I have invested some time debugging this issue. It would be pity to not share my findings. Well the first thing to do was to determine the type name for the “What’s happening” web part. To do so just edit the page and export the web part. In the exported .webpart file I saw that the type was Microsoft.SharePoint.Portal.WebControls.DashboardWebPart. With that knowledge it is time to open ILSpy, an awesome and free(!) assembly browser and decompiler. Load the “Microsoft.SharePoint.Portal” assembly from GAC into ILSpy. Then use F3 to search for DashboardWebPart: The number of replies is retrieved from SPWeb.AllProperties: If the Property Bag does not contain it, it gets the number of replies from the list. The formula is as follows: [code language=“csharp”] list.ItemCount - list.RootFolder.ItemCount [/code] It means that it gets the number of both discussions and replies: ItemCount of Discusssions List. The number of Discussions is determined by the ItemCount in the RootFolder of the Discussions List. Discussions are List Items in the RootFolder (num2 in the figure below). Replies are saved in the subfolders, every discussion gets an own folder. The number of all replies are num3 in the figure below. After checking the web properties I could see that the number of replies there were wrong: 2. The next step was to determine where and when the Web Properties are updated. The first guess every SharePoint Developer has in such cases is an EventReceiver. Here are all EventReceivers connected to the Discussions List: [code language=“powershell”] $list.EventReceivers | select class, Type, Synchronization | Out-GridView [/code] Allright, CommunityEventReceiver then: Found where the actual update happens: CommunityUtils.UpdateWebIndexedPropertyBag The method is used in DiscussionListCommunityEventHandler.HandleEvent There is a flag, flag5 that is used to determine if the Web Properties should be updated: But the flag5 is not true on Delete operations in some code flows: That’s it. So deleting a reply will not have any effect on “What’s happening”. But adding a new discussion will also update the stats: To summarize the debug session, there is an issue in the OOB code that misses to update community stats when deleting a discussion or a reply. Adding a new discussion, or a reply will synchronize the stats.
Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)
I have had a strange bug. The comment text box in a OOB SharePoint 2013 blog doesn’t appear. It only says: “There are no comments for this post.” In this blog post I’ll tell you how I found the bug and I’ll show you how you can temporarily bring the commenting to life. I have had luck. While it doesn’t work on the Test Environment, it does actually work on my development machine. The comments text box is rendered as an OnPostRender action in the blog comments display template. After debugging the javascript in hours and comparing the two environments, I just could confirm that displaytemplates are the same. There are two main javascript files that are involved:
Tag: Reflector
Debugging "What's happening" in Communities
Recently an issue was reported about count mismatches in SharePoint 2013 Communities. The number of replies in category tiles sometimes is different compared to the community stats in the web part called “What’s happening”. The actual number of replies is 1 in the figure below. The user who has reported has tried to add, update and delete discussions and replies. I have invested some time debugging this issue. It would be pity to not share my findings. Well the first thing to do was to determine the type name for the “What’s happening” web part. To do so just edit the page and export the web part. In the exported .webpart file I saw that the type was Microsoft.SharePoint.Portal.WebControls.DashboardWebPart. With that knowledge it is time to open ILSpy, an awesome and free(!) assembly browser and decompiler. Load the “Microsoft.SharePoint.Portal” assembly from GAC into ILSpy. Then use F3 to search for DashboardWebPart: The number of replies is retrieved from SPWeb.AllProperties: If the Property Bag does not contain it, it gets the number of replies from the list. The formula is as follows: [code language=“csharp”] list.ItemCount - list.RootFolder.ItemCount [/code] It means that it gets the number of both discussions and replies: ItemCount of Discusssions List. The number of Discussions is determined by the ItemCount in the RootFolder of the Discussions List. Discussions are List Items in the RootFolder (num2 in the figure below). Replies are saved in the subfolders, every discussion gets an own folder. The number of all replies are num3 in the figure below. After checking the web properties I could see that the number of replies there were wrong: 2. The next step was to determine where and when the Web Properties are updated. The first guess every SharePoint Developer has in such cases is an EventReceiver. Here are all EventReceivers connected to the Discussions List: [code language=“powershell”] $list.EventReceivers | select class, Type, Synchronization | Out-GridView [/code] Allright, CommunityEventReceiver then: Found where the actual update happens: CommunityUtils.UpdateWebIndexedPropertyBag The method is used in DiscussionListCommunityEventHandler.HandleEvent There is a flag, flag5 that is used to determine if the Web Properties should be updated: But the flag5 is not true on Delete operations in some code flows: That’s it. So deleting a reply will not have any effect on “What’s happening”. But adding a new discussion will also update the stats: To summarize the debug session, there is an issue in the OOB code that misses to update community stats when deleting a discussion or a reply. Adding a new discussion, or a reply will synchronize the stats.
Tag: Css3
Tip: Use the weakest CSS selectors
I am reading Mobile HTML5 written by Estelle Weyle. It is an awesome recap and new knowledge about html, css and javascript. I want to highlight one of tips I got: Use the weakest CSS selectors (can be found on page 204). We all know, that inline CSS and !important are evil. They have a higher level of specifity and override the standard cascade of the CSS rules. If you use !important, then it will be hard to override CSS rules when you really need it. After these two classic “evils” the evil number three is overqualifying of CSS selectors. You should really never add more classes or ids or elements than needed. Consider this: [code language=“css”] .warning { background-color: red; } [/code] It is often enough, you don’t need those: [code language=“css”] html .warning div .warning div.warning, div > .warning body p#myP.blue strong.warning [/code]
Pragmatic Responsive Design
I have been curious about the responsive design but have not had time to try it out. To learn more I decided to make an existing website more responsive. A friend of mine drives a Chuvash Dictionary website: samah.chv.su. Today it looks like this in a mobile browser: The site is a classic 1000px-ish centered page with header and two columns. The left column is for the main content and the right column for additional “aside” information. Can it be more classic? This current version works, you can still use the dictionary on a mobile phone. But there are several improvements that can be done:
Cool presentation about web performance optimization
by Chris Love [slideshare id=15218139&doc=webperformanceoptimizationformodernwebapplications-121116224847-phpapp01]
Enable Save in IE9 mode
Wouldn’t it be nice to use html5 and css3 in SharePoint? No problems, there is actually v5 master out there, created by Kyle Schaefer. Or just use h5ml5 and css3 right away in your webparts and pages. But there is a big problem. It doesn’t work in IE9–. One of the issues (even listed by Kyle) is that “save” doesn’t work in modal dialogs where Rich Text Editor is used. Especialy it is for modal dialogs. The problem is not IE9, neither html5 and css3. After some digging in javascript code which is shipped with SharePoint I found out that the problem is some legacy javascript code which is not supported by IE9 but in IE8– (and compatibility mode). When we set IE9 mode in IE9 Dev Tools (F12) and go to Tasks list and try to create a task, we’ll get an error: It is RTE_GetEditorIFrame from init.js:
Two interesting html5-in-sharepoint presentations
[slideshare id=11031050&doc=sharepointhtml5-120113215236-phpapp02] HTML5-and-CSS3-What-About-SharePoint.pdf (968 KB) by Kyle Schaefer
css3 transform
See Richards Bradshaw’s page with explanations and examples of css3 transform and transitions. His code is also available for forking on Github.
master page for html5 and css3
A great work: v5.master. I am recommending to try it. The problem are some javascript bugs in the IE 9 when you run IE mode 9 that are necessary to enable html5 and css3 support. You can’t “save” a list item: The reason why it doesn’t work in IE, but in Chrome, Firefox, is that IE invokes some functionality that it doesn’t invoke in other browsers. Next: Enable Save button in IE9
Tag: Mobile
Tip: Use the weakest CSS selectors
I am reading Mobile HTML5 written by Estelle Weyle. It is an awesome recap and new knowledge about html, css and javascript. I want to highlight one of tips I got: Use the weakest CSS selectors (can be found on page 204). We all know, that inline CSS and !important are evil. They have a higher level of specifity and override the standard cascade of the CSS rules. If you use !important, then it will be hard to override CSS rules when you really need it. After these two classic “evils” the evil number three is overqualifying of CSS selectors. You should really never add more classes or ids or elements than needed. Consider this: [code language=“css”] .warning { background-color: red; } [/code] It is often enough, you don’t need those: [code language=“css”] html .warning div .warning div.warning, div > .warning body p#myP.blue strong.warning [/code]
Chuvash translation of Wikipedia Mobile
The official Wikipedia mobile app is now translated into Chuvash language and available to use:
What does Chuvash mean?
I am Chuvash. Chuvash is the name of an ethnicity which counts up to 2 milions peoply (mostly in Russia). Chuvashes talk the Chuvash language which is also an official language in Chuvash Republic (besides Russian). Chuvash language is a Turkic language and has a status “Vulnerable” in the UNESCO list of languages in danger. There is a Chuvash Wikipedia cv.wikipedia.org.
jQuery mobile and SharePoint
In this post I want to explore how to build a mobile app using jQuery mobile. Recently I discovered two great blog posts about this:
- Building SharePoint web apps using Sencha Touch by Luc Stakenborg
- jQuery mobile and SharePoint by Chris Quick
In my post I’ll use their findings and share some of mine thougts. I’ll focus mostly on how to get started with jQuery mobile and SharePoint. So go ahead and create your jQuery mobile app, just drag’n’drop some controls: Download it and yout get an “app.html” file and “my.css”. For now ignore my.css. app.html is something like that:
Tag: Selector
Tip: Use the weakest CSS selectors
I am reading Mobile HTML5 written by Estelle Weyle. It is an awesome recap and new knowledge about html, css and javascript. I want to highlight one of tips I got: Use the weakest CSS selectors (can be found on page 204). We all know, that inline CSS and !important are evil. They have a higher level of specifity and override the standard cascade of the CSS rules. If you use !important, then it will be hard to override CSS rules when you really need it. After these two classic “evils” the evil number three is overqualifying of CSS selectors. You should really never add more classes or ids or elements than needed. Consider this: [code language=“css”] .warning { background-color: red; } [/code] It is often enough, you don’t need those: [code language=“css”] html .warning div .warning div.warning, div > .warning body p#myP.blue strong.warning [/code]
jQuery: select elements with a specific text
There are situations when you want to select only dom elements which only have a specific content. jQuery provides a beautiful selector :contains:
$("a:contains(Pages)")
```But what if it isn't enough to just get all the elements which contain some word? Let's check what we get if we traverse all anchors on http://sv.wikipedia.org containing "wiki":
$(“a:contains(wiki)”).each(function(i) { console.log($(this).text()); });
[![](https://sharepointkunskap.files.wordpress.com/2012/02/jquery-contains-wiki.png "jquery-contains-wiki")](https://sharepointkunskap.files.wordpress.com/2012/02/jquery-contains-wiki.png) There is another, a generic way, to filter out elements, and it is called "filter". So a little regex check will do the trick.
$(“a”).filter(function() { return /look_for/i.test($(this).text()); }
Hide my site link with css
Want to hide my site link without disabling social features. Well, the simplest way to do it is to use css:
#mp1\_0\_0\_Anchor { display: none; }
```If you want to hide my profile instead, just hide #mp1\_0\_1\_Anchor:
#mp1_0_1_Anchor { display: none; }
.ms-MenuUIUL li[text=‘My Site’] { display: none;}
##### Disable the my profile feature An even better solution is maybe to disable the ability to change the profiles. [Just remove the permission to "user personalization..." for All authenticated users in User Profile Service](http://blog.libinuko.com/2010/10/10/sharepoint-2010-howto-disable-my-site-and-my-profile-link/).
## Comments from Wordpress.com
####
[John]( "johnandrewdavies@hotmail.com") - <time datetime="2012-03-07 00:15:32">Mar 3, 2012</time>
Be careful this cannot be used, the classes for pop up menus are generated dynamically on the page, and that class can be applied to a number of menus I assume depending on the order which they load on the page, which isnt the same every time, so for instance this hides something in the site actions menu, or the new button on a library sometimes.
<hr />
####
[Brett Anderson](http://sharepoint2020.wordpress.com "brettando@live.com.au") - <time datetime="2012-05-02 06:13:05">May 3, 2012</time>
Hi, The amended solution does not work in IE7.
<hr />
####
[Fredrik]( "fredrik.eriksson234@gmail.com") - <time datetime="2012-03-09 15:27:24">Mar 5, 2012</time>
Thank you Anatoly, that worked perfectly in all browsers! I had problems with the first suggested solution, because it would hide other menu items, like "edit this page" from the site settings dropdown!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:10:36">Mar 3, 2012</time>
You are totally right, John! I realized that too. Fortunately, I didn't need that then. But while using that I saw that sometimes Site Actions -Edit Page disappeared. These IDs are really generated dynamically. Thanks for your comment. I'll update my post.
<hr />
####
[vishal]( "vishals.shivan@gmail.com") - <time datetime="2012-03-07 07:27:54">Mar 3, 2012</time>
Hi Anatoly. Thanks for the solution. but the problem we are facing one problem after implementing this. Once we make this change and when login to the portal next time, the "Edit Page" link under site action menu is not getting displayed and the My Site Link is getting displyed. any suggestion?
<hr />
####
[Material SharePoint » Hide ‘My Site’ Link from Welcome User Dropdown Control](http://sharepoint.jsturges.com/2012/05/hide-my-site-link-from-welcome-user-dropdown-control/ "") - <time datetime="2012-05-12 17:45:13">May 6, 2012</time>
\[...\] of my enterprise level clients that we usually hide it all together! To do this, you can use an awesome CSS trick I learned from Anatoly \[...\]
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:24:39">Mar 3, 2012</time>
Hi Vishal. Unfortunately we cannot rely on these IDs, as John in previous comment mentioned, because these IDs are generated dynamically. I'll update my post. One possible solution would be use attribute selectors... Something like .ms-MenuUIUL li\[text='My Site'\] { display: none;}
<hr />
####
[jim]( "jim.omara@gmail.com") - <time datetime="2014-02-12 17:38:05">Feb 3, 2014</time>
.ms-welcomeMenu #mp1\_0\_0{ display:none; } .ms-welcomeMenu #mp1\_0\_1{ display:none; } .ms-welcomeMenu #mp1\_0\_2{ display:none; } .ms-welcomeMenu #mp1\_0\_3{ display:none; } .ms-welcomeMenu #mp1\_0\_4{ display:none; } .ms-welcomeMenu #mp1\_0\_8{ display:none; } .ms-welcomeMenu #mp1\_0\_9{ display:none; } these work for me.
<hr />
####
[Anatoly Mironov](http://chuvash.eu "mirontoli@gmail.com") - <time datetime="2014-02-12 23:20:59">Feb 3, 2014</time>
Thank you for sharing your solution. Appreciate.
<hr />
Tag: Utf-8
It is time to standardize the Chuvash Keyboard Layout
[caption id=“attachment_3165” align=“alignnone” width=“630”] Proto-Bulgarian Runes (Chuvash language is the closest language to the Proto-Bulgar language). Wonder if they are supported in Unicode :)[/caption] The Chuvash Computer Keyboard layouts have existed since 2001, but due to the lack for Unicode support we were forced to use the look-alike letters from other latin-based keyboard layouts. On Linux The Chuvash keyboard layout was added in [2007](https://bugs.freedesktop.org/show_bug.cgi?id=11246 “The original “bug” in FreeDesktop bugzilla”) and Linux is still the only operating system that has a native keyboard layout for Chuvash language. On Windows we have used the Keyboard Layout Creator and distributed it as an executable file. Today, when Windows XP is not supported anymore, the majority of users now have full support for the correct Chuvash letters from the Extended Cyrillic table. These four Chuvash letters are “additional” to the Russian alphabet: Ӑ, Ӗ, Ҫ and Ӳ. Now when new “keyboards” appear on Android, in web browser (they use the standardized letters) and hopefully in Windows and iOS, we have to consider put the correct letters into the keyboard layouts. For Linux the /usr/share/X11/xkb/symbols/ru
file has to be updated: [code] // Chuvash language layout // Anatoly Mironov @mirontoli partial alphanumeric_keys xkb_symbols “cv” { include “ru(winkeys)” name[Group1]= “Chuvash”; key.type[group1]=“FOUR_LEVEL”; key { [ Cyrillic_u, Cyrillic_U, 0x010004f3, 0x010004f2 ] }; key { [ Cyrillic_ie, Cyrillic_IE, 0x010004d7, 0x010004d6 ] }; key { [ Cyrillic_a, Cyrillic_A, 0x010004d1, 0x010004d0 ] }; key { [ Cyrillic_es, Cyrillic_ES, 0x010004ab, 0x010004aa ] }; include “level3(ralt_switch)” }; [/code]
Tag: CAML
Using CAML with SharePoint REST API
Do you prefer REST over CSOM as I do? I’ll skip the whys. Andrew Connell put it already in wrtiting so nicely. Well, if you do prefer REST, then you must have discovered some shortcomings of REST, or its incompleteness compared to CSOM. I think of:
- Inability to filter items based on multivalued taxonomy fields
- Inability to filter items based on user fields where user is added through a group, rather than directly, e.g. AssignedTo=[Me] combined with a SharePoint group.
- …
In such situations I was forced to use CSOM. Until yesterday. Yesterday I learned that we can actually use CAML queries in REST requests. This enables using REST in all situations. The REST API is still developed and many features are added. Maybe a particular operation that needs a CAML query today, can be supported in the core REST API and can be easily refactored then. But until then, we can use CAML queries in REST requests. Here are the important things about it:
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
Ändra query på en SPView i koden
När man vill ändra hur data ska visas i en SPView i SPList, då måste man ändra CAML-Query. Det enklaste sättet att skapa en CAML Query är att använda ett program som heter CAML Query Builder. Ta bara bort och för att de behövs inte. Sedan är det bara att loopa igenom alla vyer man behöver.
private void UpdateQueryInGroupViews(SPList list)
{
for (int i = 1; i < 11; i++)
{
string viewname = String.Format("Group {0:D2}", i);
SPView view = list.Views\[viewname\];
string query =
String.Format(
"<Where><Or><Contains><FieldRef Name='Group' />"
+ "<Value Type='Text'>{0:D2}</Value></Contains>"
+ "<IsNull><FieldRef Name='Group' /></IsNull></Or></Where>"
+ "<OrderBy><FieldRef Name='EventDate' Ascending='True' />"
+ "</OrderBy>", i);
view.Query = query;
view.Update();
}
}
I denna query sorterar vi efter Start Date och visar bara händelser för sin grupp.
Tag: Pragmatic
Pragmatic Responsive Design
I have been curious about the responsive design but have not had time to try it out. To learn more I decided to make an existing website more responsive. A friend of mine drives a Chuvash Dictionary website: samah.chv.su. Today it looks like this in a mobile browser: The site is a classic 1000px-ish centered page with header and two columns. The left column is for the main content and the right column for additional “aside” information. Can it be more classic? This current version works, you can still use the dictionary on a mobile phone. But there are several improvements that can be done:
Tag: Responsive
Pragmatic Responsive Design
I have been curious about the responsive design but have not had time to try it out. To learn more I decided to make an existing website more responsive. A friend of mine drives a Chuvash Dictionary website: samah.chv.su. Today it looks like this in a mobile browser: The site is a classic 1000px-ish centered page with header and two columns. The left column is for the main content and the right column for additional “aside” information. Can it be more classic? This current version works, you can still use the dictionary on a mobile phone. But there are several improvements that can be done:
Toastr.js and SharePoint
Have you used SharePoint javascript Notifications (SP.UI.Notify)? Are you looking for something new and fresh? Well then check out the Toastr.js - a simple, beautiful, fully responsive and light-weight javascript lib for notifications, developed by John Papa and Hans Fjällemark and released under the MIT License. By the way, toastr was one of many things I discovered and learned on John Papa’s online course by pluralsight: Single Page Apps with HTML5, Web API, Knockout and jQuery. It is a really awesome course, where you learn how to create an amazing SPA. Well, how’s about SharePoint. While whatching the course videos about toastr, I thought: Can we use it in SharePoint? Yes we can! Just load the toastr css and js and start using it:
Tag: Quote
What about the SharePoint app domain?
This is an open question about the domains for SharePoint apps. On Technet: Configure an environment for apps for SharePoint (SharePoint 2013) we can read the following:
You must configure a new name in Domain Name Services (DNS) to host the apps. To help improve security, the domain name should not be a subdomain of the domain that hosts the SharePoint sites. For example, if the SharePoint sites are at Contoso.com, consider ContosoApps.com instead of App.Contoso.com as the domain name.
Apps can only call the OOB CSOM and REST endpoints
As a SharePoint architect or a SharePoint developer, you must have been thinking about the benefits/limitations of SharePoint apps a lot. I want to point out one of them today, which is very important: using custom webservices deployed to SharePoint inside apps. That is impossible and it is designed to be so due to the security architecture in the sharepoint app framework. I have read much about SharePoint apps (books, whitepapers, blog posts) and stumbled over these two contradictive statements:
Tag: First Look
First look at Yammer integration in SharePoint 2013 SP1
I have installed SharePoint SP1 on my development machine. Yammer and OneDrive links have appeared in the Central Administration: If you go ahead and click “Configure Yammer”, you can activate it: Because:
Yammer is Microsoft’s recommended tool for social collaboration.
When you activate Yammer, you’ll get this dialog, and the Yammer link in the SuiteBar: What happens when you click on Yammer, is that you are redirected to Yammer.com and you are prompted a login page. Then you have a usual yammer site with all your networks and stuff (in my case, SPC14 network): Then, if you go to your newsfeed, the following message is shown:
Tag: SP1
First look at Yammer integration in SharePoint 2013 SP1
I have installed SharePoint SP1 on my development machine. Yammer and OneDrive links have appeared in the Central Administration: If you go ahead and click “Configure Yammer”, you can activate it: Because:
Yammer is Microsoft’s recommended tool for social collaboration.
When you activate Yammer, you’ll get this dialog, and the Yammer link in the SuiteBar: What happens when you click on Yammer, is that you are redirected to Yammer.com and you are prompted a login page. Then you have a usual yammer site with all your networks and stuff (in my case, SPC14 network): Then, if you go to your newsfeed, the following message is shown:
Retention policies
Ziegler provides a cool intro, implementation sample and much more. When deployed we can apply this policy to a contenttype in the UI, or in code. To create our own expiration logic we have to implement IExpirationFormula and its ComputeExpireDate:
public class TaskExpiration : IExpirationFormula
{
public DateTime? ComputeExpireDate(SPListItem item,
XmlNode parametersData)
{
if (!item\["Status"\].Equals("Completed"))
{
return null;
}
var dt = (DateTime) item\["Modified"\];
return dt.AddDays(30);
}
}
```In order to see IExpirationFormula, add a reference to Microsoft.Office.Policy (and maybe Microsoft.Office.DocumentManagement): [![](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png "policy-dll")](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png) To see our custom retention policy, we have to register it in xml, we can do it in Feature Receiver like [Yaroslav](http://www.sharemuch.com/2011/01/10/creation-custom-retention-policies-for-sharepoint-2010-libraries/):
public override void FeatureActivated(SPFeatureReceiverProperties properties) { const string xmlManifest = “<PolicyResource xmlns=‘urn:schemas-microsoft-com:office:server:policy’” + " id = ‘Takana.TaskRetentionPolicy’" + " featureId=‘Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration’" + " type = ‘DateCalculator’>" + " Takana Task Retention Policy" + “Tasks expire 30 days after they have been completed” + “Takana.SharePoint, Version=1.0.0.0, Culture=neutral, " + “PublicKeyToken=920c0327f8b01d97” + “Takana.SharePoint.Policies.TaskExpiration” + “”; PolicyResourceCollection.Add(xmlManifest); }
Tag: Upgrade
First look at Yammer integration in SharePoint 2013 SP1
I have installed SharePoint SP1 on my development machine. Yammer and OneDrive links have appeared in the Central Administration: If you go ahead and click “Configure Yammer”, you can activate it: Because:
Yammer is Microsoft’s recommended tool for social collaboration.
When you activate Yammer, you’ll get this dialog, and the Yammer link in the SuiteBar: What happens when you click on Yammer, is that you are redirected to Yammer.com and you are prompted a login page. Then you have a usual yammer site with all your networks and stuff (in my case, SPC14 network): Then, if you go to your newsfeed, the following message is shown:
Publish upgrade on Market - checklist
Here comes my checklist about what has to be done in order to publish an upgrade on Market.
- get all code from github (git pull origin master)
- Test the application
- Change version number in AndroidManifest.xml
- Commit “version x.x.” and push
- (Change google map api key in res/layout/main.xml to the prod key)
- In Eclipse: Project → Clean
- Right-click on project → Android tools → Export signed… (~/Skrivbord/LUSites-unaligned.apk)
- Zipalign (e.g.: zipalign -v 4 LUSites-unaligned.apk LUSites-v0.2.7.apk)
- Publish upgrade on market
- Save the apk to the archive
Tag: Channel9
The sessions I attended
My colleagues and friends keep asking me what sessions I went to and what I would recommend to see on channel9 where all of them are publicly available. Here is my prioritized list of sessions:
- #spc325 Real-world examples of FTC to CAM transformations. This was the most exciting developer session. Vesa Juvonen takes the Cloud App Model to its maximum. Wanna know more about the future. See this session.
- #spc404 Build your own REST service with WebAPI 2. You know REST? You like $filter, $top and $select? Good, why not create an own api? You have all the tools in Visual Studio 2013. Just get inspired by Scott Hillier.
- #spc269 Developer audience keynote | What’s new for the Office & SharePoint developer. Get all the developer news presented at #spc14.
- #spc3999 SharePoint Power Hour - New developer APIs and features for Apps for SharePoint.
- #spc371 Developing socially connected apps with Yammer, SharePoint and OpenGraph. Chris Johnson talks about how to use Yammer API to post updates, like and comment from code. What if you wanted to send an update to Yammer from your Line-of-Business application? Very easy.
- #spc303 Advanced Performance Analysis for SharePoint. A real-world case study how performance of a SharePoint site is measured, captured and analyzed. Really interesting.
- #spc391 Deep dive into Mail Compose Apps APIs. Main compose apps are similar to SharePoint apps, they are run as iframes and can be used to update an email while writing it or start a workflow. Good stuff.
- #spc334 Real-world SharePoint architecture decisions. Wictor Wilén talked about his best topic: architecture decisions. He is probably the best in this area in the world, and his presentation becomes better and better every time he presents it.
- #spc3000 Changing the look of Search using Display Templates and CSR. You can do a lot of stuff using the Display Templates and Cliend-Side Rendering. See this session to get inspired and gather a deeper understanding how it works.
- #spc382 Managing Search Relevance in SharePoint 2013 and O365. How does XRANK work? Well it is complicated. This session is a must-see.
- #spc224 The SharePointConference.com Site: From Sketch to Launch to Live! Did you know that SharePointConference.com was built upon SharePoint? See this session to find out what was good in SharePoint for this site, and what workarounds and hacks were necessary to get it to work.
- #spc302 Advanced development patterns for SharePoint Apps. Provider-Hosted Apps are the best type of apps. Let’s see what examples and tips are provided in this session.
- #spc322 SharePoint 2013 Search display templates and query rules. An introduction to Search Display Templates.
- #spc301 Access is back! High-value, ’no code’, functional & flexible business apps with the new Access services. There were a lot of jokes in this session. Access apps are new “no-code” solutions and will replace the InfoPath solutions.
- #spc407 Deep dive into the SharePoint 2013 CSOM API’s. The name is not correct. It is a dive into the CSOM, but it is not deep. See it if you want an introduction, but please keep in mind, the examples don’t follow the javascript coding conventions.
- #spc381 Load testing SharePoint 2013 using Visual Studio 2013. Never used load-testing with Visual Studio? Got a 1.15 hr to kill? Well, see it to learn how to start the Visual Studio and what difference is between a web test and load test.
The sessions I wish I had attended:
Tag: Spc14
The sessions I attended
My colleagues and friends keep asking me what sessions I went to and what I would recommend to see on channel9 where all of them are publicly available. Here is my prioritized list of sessions:
- #spc325 Real-world examples of FTC to CAM transformations. This was the most exciting developer session. Vesa Juvonen takes the Cloud App Model to its maximum. Wanna know more about the future. See this session.
- #spc404 Build your own REST service with WebAPI 2. You know REST? You like $filter, $top and $select? Good, why not create an own api? You have all the tools in Visual Studio 2013. Just get inspired by Scott Hillier.
- #spc269 Developer audience keynote | What’s new for the Office & SharePoint developer. Get all the developer news presented at #spc14.
- #spc3999 SharePoint Power Hour - New developer APIs and features for Apps for SharePoint.
- #spc371 Developing socially connected apps with Yammer, SharePoint and OpenGraph. Chris Johnson talks about how to use Yammer API to post updates, like and comment from code. What if you wanted to send an update to Yammer from your Line-of-Business application? Very easy.
- #spc303 Advanced Performance Analysis for SharePoint. A real-world case study how performance of a SharePoint site is measured, captured and analyzed. Really interesting.
- #spc391 Deep dive into Mail Compose Apps APIs. Main compose apps are similar to SharePoint apps, they are run as iframes and can be used to update an email while writing it or start a workflow. Good stuff.
- #spc334 Real-world SharePoint architecture decisions. Wictor Wilén talked about his best topic: architecture decisions. He is probably the best in this area in the world, and his presentation becomes better and better every time he presents it.
- #spc3000 Changing the look of Search using Display Templates and CSR. You can do a lot of stuff using the Display Templates and Cliend-Side Rendering. See this session to get inspired and gather a deeper understanding how it works.
- #spc382 Managing Search Relevance in SharePoint 2013 and O365. How does XRANK work? Well it is complicated. This session is a must-see.
- #spc224 The SharePointConference.com Site: From Sketch to Launch to Live! Did you know that SharePointConference.com was built upon SharePoint? See this session to find out what was good in SharePoint for this site, and what workarounds and hacks were necessary to get it to work.
- #spc302 Advanced development patterns for SharePoint Apps. Provider-Hosted Apps are the best type of apps. Let’s see what examples and tips are provided in this session.
- #spc322 SharePoint 2013 Search display templates and query rules. An introduction to Search Display Templates.
- #spc301 Access is back! High-value, ’no code’, functional & flexible business apps with the new Access services. There were a lot of jokes in this session. Access apps are new “no-code” solutions and will replace the InfoPath solutions.
- #spc407 Deep dive into the SharePoint 2013 CSOM API’s. The name is not correct. It is a dive into the CSOM, but it is not deep. See it if you want an introduction, but please keep in mind, the examples don’t follow the javascript coding conventions.
- #spc381 Load testing SharePoint 2013 using Visual Studio 2013. Never used load-testing with Visual Studio? Got a 1.15 hr to kill? Well, see it to learn how to start the Visual Studio and what difference is between a web test and load test.
The sessions I wish I had attended:
My five takeaways from the SharePoint Conference 2014
The SharePoint Conference 2014 was an astounding event. Over 10 000 like-minded SharePointers that met, learned a lot and shared new ideas, couldn’t be better. It was also the first time I was to the U.S. and Las Vegas. What a country, what a city! This place must burn people’s lives faster than anywhere else in the world :) I want to share my five takeaways from this conference. I’ll keep it short:
Tag: Las Vegas
My five takeaways from the SharePoint Conference 2014
The SharePoint Conference 2014 was an astounding event. Over 10 000 like-minded SharePointers that met, learned a lot and shared new ideas, couldn’t be better. It was also the first time I was to the U.S. and Las Vegas. What a country, what a city! This place must burn people’s lives faster than anywhere else in the world :) I want to share my five takeaways from this conference. I’ll keep it short:
Tag: SharePoint Conference
My five takeaways from the SharePoint Conference 2014
The SharePoint Conference 2014 was an astounding event. Over 10 000 like-minded SharePointers that met, learned a lot and shared new ideas, couldn’t be better. It was also the first time I was to the U.S. and Las Vegas. What a country, what a city! This place must burn people’s lives faster than anywhere else in the world :) I want to share my five takeaways from this conference. I’ll keep it short:
Tag: Client Object Model
PowerShell: Migrate field choices to a termset
In my current project we are migrating a custom sharepoint solution from SharePoint 2010 to SharePoint 2013. One of the improvements is that we migrate custom field choices to Managed Metadata. Choice Fields were not intended to be so many. So now it is time to convert them to metadata terms. I have written a PowerShell script which copies all the choices from a field to a termset. The script uses Client Side Object Model (CSOM) to get the choice values and it uses Server Object Model to write data to the termset. [sourcecode language=“PowerShell”] <# .Synopsis Use MigrateChoices.ps1 to migrate choices from a field to managed metadata. The source can be a contenttype field from SharePoint 2010 or from SharePoint 2013. .Description This script uses client object model to get the list items from the old environment. Then it uses the Server Object Model to create new terms and termsets (if needed) in the new environment. This script doesn’t override anything. The reason why we use it, is that importing feature isnt easy It creates a new, instead of adding new terms to old ones. It is very hard to create an csv file for that purpose. .Example MigrateChoices.ps1 -Source http://sp2010.contoso.com -Target https://sp2013.contoso.com .Notes Name: MigrateChoices.ps1 Author: Anatoly Mironov Last Edit: 2013-09-04 Keywords: CSOM, Field, FieldChoice, Metadata, Termset .Links http://chuvash.eu .Inputs The script takes Source parameter, it is url for the root web in the Source Site Collection The script takes Target parameter, it is url for the root web in the Target Site Collection .Outputs None #Requires -Version 2.0 #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)][System.String]$Source = $(Read-Host -prompt “Source site Url”), [Parameter(Mandatory=$true)][System.String]$Target = $(Read-Host -prompt “Target site Url”), [Parameter(Mandatory=$false)][System.String]$TermGroupName = “My group”, [Parameter(Mandatory=$false)][System.String]$TermGroupId, [Parameter(Mandatory=$false)][System.String]$TermSetName = “My termset”, [Parameter(Mandatory=$false)][System.String]$TermSetId, [Parameter(Mandatory=$false)][System.String]$FieldName = $(Read-Host -prompt “Field Choice Name”) ) if(-not(gsnp | ? { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { asnp Microsoft.SharePoint.PowerShell } # try to instantiate the target site, if it fails, then it does not run in the right environment $targetSite = get-spsite $Target # predefined termset guids: $guids = @{ “group” = if ($TermGroupId) {New-Object system.guid $TermGroupId } else { [system.guid]::NewGuid() } “termset” = if ($TermSetId) {New-Object system.guid $TermSetId } else { [system.guid]::NewGuid() } } function GetChoices() { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Source) $field = $ctx.Web.Fields.GetByInternalNameOrTitle($FieldName) $ctx.Load($field) $ctx.ExecuteQuery() return ([xml]$field.SchemaXml).Field.Choices.Choice } function New-Term { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermSetItem]$parent, [Parameter(Mandatory=$true)][System.String]$name ) if (!$parent) { throw new-object System.ArgumentException $parent } if (!$name) { throw new-object System.ArgumentException $name } $term = $parent[$name] if (!$term) { $parent.CreateTerm($name, 1033) | out-null } } function CreateTerms() { $taxSession = Get-SPTaxonomySession -Site $targetSite $termStore = $taxSession.DefaultSiteCollectionTermStore $group = $termstore.Groups[$TermGroupName] if (!$group) { $group = $termStore.CreateGroup($TermGroupName, $guids.group) } $termSet = $group.TermSets[$TermsetName] if (!$termset) { $termset = $group.CreateTermSet($SecurityClassificationTermSetName, $guids.termset, 1033) } GetChoices | % { New-Term $termSet $_ } $termStore.CommitAll() $targetSite.Dispose() write-host -ForegroundColor Green “The term sets have been created” } CreateTerms [/sourcecode]
JSOM: Alter a column's DisplayName
Here is another article in my JSOM series. For one month ago I showed how to alter a column’s ShowInDisplayForm property with JSOM. This time I’ll show a code sample for changing a column’s (field’s) display name. If you want to alter the displayname with Server Object Model, grab the code in the sharepoint.stackexchange.com: Change Field’s DisplayName in a List. [sourcecode language=“javascript”]var ctx = SP.ClientContext.get_current(), //SP.ClientContext field = ctx.get_web() //SP.Web .get_lists() //SP.ListCollection .getByTitle(‘MyList’) //SP.List .get_fields() //SP.FieldCollection .getByInternalNameOrTitle(“Body”); //SP.Field ctx.load(field, “Title”); //load only Title ctx.executeQueryAsync(function() { field.set_title(“Beskrivning”); field.update(); ctx.executeQueryAsync(); });[/sourcecode]
GeoLocation Field in SharePoint 2013
In SharePoint 2013 Preview there is a new type of field: GeoLocation which is, like the old SPUrlField, a pair of values. The geolocation is described as longitude and latitude. Unfortunately you can’t add this field in list settings. You have to create this in code. In the provided link you can find the code C# code which uses the Client Object Model. In another link you can find an example how to create the geolocation file using Server Object Model (in FeatureActivated EventReceiver). If you know me, you might already know that I will propose a JavaScript solution. Here is the code to create a geolocation field in an existing list using JSOM:
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
JSOM: Alter a column's ShowInDisplayForm property
When you create a content type, you can define if your fields will be shown in DisplayForm, EditForm, NewForm. You can hide or show them, just as Yaroslav Pentsarsky says. If your list is already provisioned, you can change them with Server Object Model, why not in PowerShell: Technet: Setting ShowInDisplayForm, ShowInEditForm, ShowInNewForm properties with powershell. If you don’t have access to the server, then the same can be done with JSOM. Here is the code:
$().SPServices is best for SOAP
SPServices is a great tool, really nice work, Marc Anderson (@sympmarc). It has been there all the time I have developed for SharePoint. But the fact that you work with XML and you must parse the attributes (!) was the reason why I prefered listdata.svc and Client Object Model, where you get objects in JSON or you have a nice API to get objects and their properties. But there is an area where SPServices are really the best tool: SharePoint Web Services which only understand SOAP like SocialDataService.asmx.
Get current user and handle a success callback
In my previous post I needed the accound id of the current user for posting new list items. To retrieve the id, we can push this to the client from the code behind, or get the current user using Client Object Model. To provide a more generic way we can write a js function which get the current user. But we must even provide some callback functionality, otherwise we don’t know if the operation was successful or not. Let’s be inspired by success and error properties in $.ajax:
Uppdatera web med js
Här är ett litet exempel:
function updateTitle() {
var ctx = new SP.ClientContext.get\_current();
this.web = ctx.get\_web();
web.set\_title('Examensarbete 2011');
this.web.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onUpdate),
Function.createDelegate(this, this.onFail)); }
function onUpdate(sender, args) {
alert('title updated');
}
function onFail(sender, args) {
alert('failed to update title. Error:'+args.get\_message());
}
Tag: Managed Metadata
PowerShell: Migrate field choices to a termset
In my current project we are migrating a custom sharepoint solution from SharePoint 2010 to SharePoint 2013. One of the improvements is that we migrate custom field choices to Managed Metadata. Choice Fields were not intended to be so many. So now it is time to convert them to metadata terms. I have written a PowerShell script which copies all the choices from a field to a termset. The script uses Client Side Object Model (CSOM) to get the choice values and it uses Server Object Model to write data to the termset. [sourcecode language=“PowerShell”] <# .Synopsis Use MigrateChoices.ps1 to migrate choices from a field to managed metadata. The source can be a contenttype field from SharePoint 2010 or from SharePoint 2013. .Description This script uses client object model to get the list items from the old environment. Then it uses the Server Object Model to create new terms and termsets (if needed) in the new environment. This script doesn’t override anything. The reason why we use it, is that importing feature isnt easy It creates a new, instead of adding new terms to old ones. It is very hard to create an csv file for that purpose. .Example MigrateChoices.ps1 -Source http://sp2010.contoso.com -Target https://sp2013.contoso.com .Notes Name: MigrateChoices.ps1 Author: Anatoly Mironov Last Edit: 2013-09-04 Keywords: CSOM, Field, FieldChoice, Metadata, Termset .Links http://chuvash.eu .Inputs The script takes Source parameter, it is url for the root web in the Source Site Collection The script takes Target parameter, it is url for the root web in the Target Site Collection .Outputs None #Requires -Version 2.0 #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)][System.String]$Source = $(Read-Host -prompt “Source site Url”), [Parameter(Mandatory=$true)][System.String]$Target = $(Read-Host -prompt “Target site Url”), [Parameter(Mandatory=$false)][System.String]$TermGroupName = “My group”, [Parameter(Mandatory=$false)][System.String]$TermGroupId, [Parameter(Mandatory=$false)][System.String]$TermSetName = “My termset”, [Parameter(Mandatory=$false)][System.String]$TermSetId, [Parameter(Mandatory=$false)][System.String]$FieldName = $(Read-Host -prompt “Field Choice Name”) ) if(-not(gsnp | ? { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { asnp Microsoft.SharePoint.PowerShell } # try to instantiate the target site, if it fails, then it does not run in the right environment $targetSite = get-spsite $Target # predefined termset guids: $guids = @{ “group” = if ($TermGroupId) {New-Object system.guid $TermGroupId } else { [system.guid]::NewGuid() } “termset” = if ($TermSetId) {New-Object system.guid $TermSetId } else { [system.guid]::NewGuid() } } function GetChoices() { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Source) $field = $ctx.Web.Fields.GetByInternalNameOrTitle($FieldName) $ctx.Load($field) $ctx.ExecuteQuery() return ([xml]$field.SchemaXml).Field.Choices.Choice } function New-Term { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermSetItem]$parent, [Parameter(Mandatory=$true)][System.String]$name ) if (!$parent) { throw new-object System.ArgumentException $parent } if (!$name) { throw new-object System.ArgumentException $name } $term = $parent[$name] if (!$term) { $parent.CreateTerm($name, 1033) | out-null } } function CreateTerms() { $taxSession = Get-SPTaxonomySession -Site $targetSite $termStore = $taxSession.DefaultSiteCollectionTermStore $group = $termstore.Groups[$TermGroupName] if (!$group) { $group = $termStore.CreateGroup($TermGroupName, $guids.group) } $termSet = $group.TermSets[$TermsetName] if (!$termset) { $termset = $group.CreateTermSet($SecurityClassificationTermSetName, $guids.termset, 1033) } GetChoices | % { New-Term $termSet $_ } $termStore.CommitAll() $targetSite.Dispose() write-host -ForegroundColor Green “The term sets have been created” } CreateTerms [/sourcecode]
Tag: Term
PowerShell: Migrate field choices to a termset
In my current project we are migrating a custom sharepoint solution from SharePoint 2010 to SharePoint 2013. One of the improvements is that we migrate custom field choices to Managed Metadata. Choice Fields were not intended to be so many. So now it is time to convert them to metadata terms. I have written a PowerShell script which copies all the choices from a field to a termset. The script uses Client Side Object Model (CSOM) to get the choice values and it uses Server Object Model to write data to the termset. [sourcecode language=“PowerShell”] <# .Synopsis Use MigrateChoices.ps1 to migrate choices from a field to managed metadata. The source can be a contenttype field from SharePoint 2010 or from SharePoint 2013. .Description This script uses client object model to get the list items from the old environment. Then it uses the Server Object Model to create new terms and termsets (if needed) in the new environment. This script doesn’t override anything. The reason why we use it, is that importing feature isnt easy It creates a new, instead of adding new terms to old ones. It is very hard to create an csv file for that purpose. .Example MigrateChoices.ps1 -Source http://sp2010.contoso.com -Target https://sp2013.contoso.com .Notes Name: MigrateChoices.ps1 Author: Anatoly Mironov Last Edit: 2013-09-04 Keywords: CSOM, Field, FieldChoice, Metadata, Termset .Links http://chuvash.eu .Inputs The script takes Source parameter, it is url for the root web in the Source Site Collection The script takes Target parameter, it is url for the root web in the Target Site Collection .Outputs None #Requires -Version 2.0 #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)][System.String]$Source = $(Read-Host -prompt “Source site Url”), [Parameter(Mandatory=$true)][System.String]$Target = $(Read-Host -prompt “Target site Url”), [Parameter(Mandatory=$false)][System.String]$TermGroupName = “My group”, [Parameter(Mandatory=$false)][System.String]$TermGroupId, [Parameter(Mandatory=$false)][System.String]$TermSetName = “My termset”, [Parameter(Mandatory=$false)][System.String]$TermSetId, [Parameter(Mandatory=$false)][System.String]$FieldName = $(Read-Host -prompt “Field Choice Name”) ) if(-not(gsnp | ? { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { asnp Microsoft.SharePoint.PowerShell } # try to instantiate the target site, if it fails, then it does not run in the right environment $targetSite = get-spsite $Target # predefined termset guids: $guids = @{ “group” = if ($TermGroupId) {New-Object system.guid $TermGroupId } else { [system.guid]::NewGuid() } “termset” = if ($TermSetId) {New-Object system.guid $TermSetId } else { [system.guid]::NewGuid() } } function GetChoices() { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Source) $field = $ctx.Web.Fields.GetByInternalNameOrTitle($FieldName) $ctx.Load($field) $ctx.ExecuteQuery() return ([xml]$field.SchemaXml).Field.Choices.Choice } function New-Term { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermSetItem]$parent, [Parameter(Mandatory=$true)][System.String]$name ) if (!$parent) { throw new-object System.ArgumentException $parent } if (!$name) { throw new-object System.ArgumentException $name } $term = $parent[$name] if (!$term) { $parent.CreateTerm($name, 1033) | out-null } } function CreateTerms() { $taxSession = Get-SPTaxonomySession -Site $targetSite $termStore = $taxSession.DefaultSiteCollectionTermStore $group = $termstore.Groups[$TermGroupName] if (!$group) { $group = $termStore.CreateGroup($TermGroupName, $guids.group) } $termSet = $group.TermSets[$TermsetName] if (!$termset) { $termset = $group.CreateTermSet($SecurityClassificationTermSetName, $guids.termset, 1033) } GetChoices | % { New-Term $termSet $_ } $termStore.CommitAll() $targetSite.Dispose() write-host -ForegroundColor Green “The term sets have been created” } CreateTerms [/sourcecode]
Tag: Termset
PowerShell: Migrate field choices to a termset
In my current project we are migrating a custom sharepoint solution from SharePoint 2010 to SharePoint 2013. One of the improvements is that we migrate custom field choices to Managed Metadata. Choice Fields were not intended to be so many. So now it is time to convert them to metadata terms. I have written a PowerShell script which copies all the choices from a field to a termset. The script uses Client Side Object Model (CSOM) to get the choice values and it uses Server Object Model to write data to the termset. [sourcecode language=“PowerShell”] <# .Synopsis Use MigrateChoices.ps1 to migrate choices from a field to managed metadata. The source can be a contenttype field from SharePoint 2010 or from SharePoint 2013. .Description This script uses client object model to get the list items from the old environment. Then it uses the Server Object Model to create new terms and termsets (if needed) in the new environment. This script doesn’t override anything. The reason why we use it, is that importing feature isnt easy It creates a new, instead of adding new terms to old ones. It is very hard to create an csv file for that purpose. .Example MigrateChoices.ps1 -Source http://sp2010.contoso.com -Target https://sp2013.contoso.com .Notes Name: MigrateChoices.ps1 Author: Anatoly Mironov Last Edit: 2013-09-04 Keywords: CSOM, Field, FieldChoice, Metadata, Termset .Links http://chuvash.eu .Inputs The script takes Source parameter, it is url for the root web in the Source Site Collection The script takes Target parameter, it is url for the root web in the Target Site Collection .Outputs None #Requires -Version 2.0 #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)][System.String]$Source = $(Read-Host -prompt “Source site Url”), [Parameter(Mandatory=$true)][System.String]$Target = $(Read-Host -prompt “Target site Url”), [Parameter(Mandatory=$false)][System.String]$TermGroupName = “My group”, [Parameter(Mandatory=$false)][System.String]$TermGroupId, [Parameter(Mandatory=$false)][System.String]$TermSetName = “My termset”, [Parameter(Mandatory=$false)][System.String]$TermSetId, [Parameter(Mandatory=$false)][System.String]$FieldName = $(Read-Host -prompt “Field Choice Name”) ) if(-not(gsnp | ? { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { asnp Microsoft.SharePoint.PowerShell } # try to instantiate the target site, if it fails, then it does not run in the right environment $targetSite = get-spsite $Target # predefined termset guids: $guids = @{ “group” = if ($TermGroupId) {New-Object system.guid $TermGroupId } else { [system.guid]::NewGuid() } “termset” = if ($TermSetId) {New-Object system.guid $TermSetId } else { [system.guid]::NewGuid() } } function GetChoices() { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Source) $field = $ctx.Web.Fields.GetByInternalNameOrTitle($FieldName) $ctx.Load($field) $ctx.ExecuteQuery() return ([xml]$field.SchemaXml).Field.Choices.Choice } function New-Term { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermSetItem]$parent, [Parameter(Mandatory=$true)][System.String]$name ) if (!$parent) { throw new-object System.ArgumentException $parent } if (!$name) { throw new-object System.ArgumentException $name } $term = $parent[$name] if (!$term) { $parent.CreateTerm($name, 1033) | out-null } } function CreateTerms() { $taxSession = Get-SPTaxonomySession -Site $targetSite $termStore = $taxSession.DefaultSiteCollectionTermStore $group = $termstore.Groups[$TermGroupName] if (!$group) { $group = $termStore.CreateGroup($TermGroupName, $guids.group) } $termSet = $group.TermSets[$TermsetName] if (!$termset) { $termset = $group.CreateTermSet($SecurityClassificationTermSetName, $guids.termset, 1033) } GetChoices | % { New-Term $termSet $_ } $termStore.CommitAll() $targetSite.Dispose() write-host -ForegroundColor Green “The term sets have been created” } CreateTerms [/sourcecode]
Tag: Powershel
PowerShell: Get version and ProductId from an .app package
In my project I deploy some apps directly through the ObjectModel directly with PowerShell. The apps are built with TFS I have a script that installs or updates apps if there is a new version of the app. Previously I used Import-SPAppPackage to compare the version and productid with an existing app instance, but often I get this error:
The provided App differs from another App with the same version and product ID.
Count lines of code with PowerShell
Today I got a question:
How many lines of code are there in our SharePoint solution?
After a little search, I found that PowerShell is really a nice tool to count lines of code:
I wanted to count lines for different types of code:
- Code Behind written in C#, the files have .cs file extension
- JavaScript code (except jQuery, angular or knockout frameworks)
- PowerShell files (.ps1 and psm1)
- Xml files (all the SharePoint .xml files)
Here is the powershell code that counts lines of code: [code language=“powershell”] # go to the solution folder cd #count lines in .cs files ls -include *.cs -recurse | select-string . | measure | select count #count lines in our .js files ls -include *.js -recurse ` -exclude *min.js, jquery*, _*, jsrender*, CamlBuilder*, knockout* ` | select-string . ` | measure ` | select Count #count lines in our powershell scripts ls -include *.xml -recurse | select-string . | measure | select count #count lines in our powershell scripts ls -include *.ps1, *.psm1 -recurse | select-string . | measure | select count [/code] Just a curious fact, I can’t tell you how many lines of code we have in our solution, but I can reveal the proportions. If I used the flexible box model in css3, it would look like this: There are as many lines of code written in javascript as it is in C#. The main reason that for the big js code base are the SharePoint hosted apps. The PowerShell scripts are as big the javascript code base. Xml files are 4 times bigger than C# code, and it is even bigger than the sum of all lines of code written in C#, JavaScript and PowerShell. It isn’t strange that xml is dominating, almost everything in SharePoint is defined in xml. Fortunately, there are less cases where you have to write raw xml in Visual Studio 2012/2013 and SharePoint 2013. How does it look in your project? What language is dominating in your SharePoint project?
scriptcs and SharePoint. How SharePoint can benefit?
Last Saturday I attended Leetspeak. Among many awesome speeches and presentations I discovered scriptcs. scriptcs lets you write C# code directly in the console, or execute scripts written with just your favourite editor. Please see more about it on the site. What I thought during Justin Rusbatch’s session at Leetspeak:
Can we use scriptcs in SharePoint?
Technically there is no limitations in SharePoint for scriptcs. Any .NET code can be registered, imported and invoked in a console or in a standalone script. Here is the simple code for instantiating a site collection and disposing it: [code language=“csharp”] #r Microsoft.SharePoint; using Microsoft.SharePoint; var site = new SPSite(“http://dev”); site.Url site.Dispose(); [/code] The code above does not do anything, it is just there to demonstrate how you can register the SharePoint assembly (“Microsoft.SharePoint”) and import it into the script: [code language=“csharp”] using Microsoft.SharePoint; [/code] The example shows even that you in scriptcs no longer need the necessary “boilerplate” (compared to a console application): namespace, Program, Main()… You can just directly write your code. The rest is the same as in a C# application. The code samples for scriptcs can be any code written in C# for SharePoint, code from custom console applications, from feature receivers, you name it. So my next question is:
A quick guide to configuring the Loopback check
Great tutorial how to configure the loopback check on a dev machine. Exactly what I needed for a month ago. Pity that this article came after that. :-) Here is the command to disable it completeley:
\# Disable Loopback check http://support.microsoft.com/kb/896861 #
New-ItemProperty HKLM:\\System\\CurrentControlSet\\Control\\Lsa -Name "DisableLoopbackCheck" -Value "1" -PropertyType dword
Determine the build version of Sharepoint
Sometimes you need to know what version of Sharepoint is installed on your machine. Perhaps when you want to restore a .bak-file (a backup done on another machine and you get error message like:
Restore-SPSite : Your backup is from a different version of Microsoft SharePoint Foundation and cannot be restored to a
server running the current version. The backup file should be restored to a server with version '14.0.0.6109' or later
To find out your build version you can do it in UI: go to Central Administration -> System Settings -> Manage servers in this farm -> Configuration database version. Or you can do in Powershell running:
Tag: Xml
Count lines of code with PowerShell
Today I got a question:
How many lines of code are there in our SharePoint solution?
After a little search, I found that PowerShell is really a nice tool to count lines of code:
I wanted to count lines for different types of code:
- Code Behind written in C#, the files have .cs file extension
- JavaScript code (except jQuery, angular or knockout frameworks)
- PowerShell files (.ps1 and psm1)
- Xml files (all the SharePoint .xml files)
Here is the powershell code that counts lines of code: [code language=“powershell”] # go to the solution folder cd #count lines in .cs files ls -include *.cs -recurse | select-string . | measure | select count #count lines in our .js files ls -include *.js -recurse ` -exclude *min.js, jquery*, _*, jsrender*, CamlBuilder*, knockout* ` | select-string . ` | measure ` | select Count #count lines in our powershell scripts ls -include *.xml -recurse | select-string . | measure | select count #count lines in our powershell scripts ls -include *.ps1, *.psm1 -recurse | select-string . | measure | select count [/code] Just a curious fact, I can’t tell you how many lines of code we have in our solution, but I can reveal the proportions. If I used the flexible box model in css3, it would look like this: There are as many lines of code written in javascript as it is in C#. The main reason that for the big js code base are the SharePoint hosted apps. The PowerShell scripts are as big the javascript code base. Xml files are 4 times bigger than C# code, and it is even bigger than the sum of all lines of code written in C#, JavaScript and PowerShell. It isn’t strange that xml is dominating, almost everything in SharePoint is defined in xml. Fortunately, there are less cases where you have to write raw xml in Visual Studio 2012/2013 and SharePoint 2013. How does it look in your project? What language is dominating in your SharePoint project?
javascript: serialize as xml
Why should we need to serialize javascript objects as XML. I don’t know. It is of course more a server side need. And there actually a need for javascript serialization as xml in node.js. To serialize as json is very simple: JSON.stringify(myobjects). I was just curious if there was a tool for xml serialization in javascript. There is a nice javascript tool called XMLWriter, developed by Ariel Flesler. Consider you have articles and want to serialize them as xml, let’s create a function for serializing:
XMLHttpRequest the hard way
$.ajax is great, it hides much of the complexity. But sometimes we need to work with “raw” javascript :) So let’s look behind the scenes. The XMLHttpRequest (or just XHR) is used to open a connection to a server without a page reload. Internet Explorer calls it ActiveXObject and it differs in IE versions. Wikipedia article gives a good example how to create one constructor for all browsers: [sourcecode language=“javascript”]if (typeof XMLHttpRequest == “undefined”) XMLHttpRequest = function () { try { return new ActiveXObject(“Msxml2.XMLHTTP.6.0”); } catch (e) {} try { return new ActiveXObject(“Msxml2.XMLHTTP.3.0”); } catch (e) {} try { return new ActiveXObject(“Microsoft.XMLHTTP”); } catch (e) {} //Microsoft.XMLHTTP points to Msxml2.XMLHTTP and is redundant throw new Error(“This browser does not support XMLHttpRequest.”); };[/sourcecode] The remainder is more or less the same among the browsers. We open a connection defining the HTTP verb, URI and async mode (true or false): [sourcecode language=“javascript”]var xhr = new XMLHttpRequest(); xhr.open(“GET”, “/_vti_bin/listdata.svc”, true); xhr.onreadystatechange = onStateChange; xhr.send(null);[/sourcecode] Pay attention to onreadystatechange (only lower case letters). If we choose async=false, the UI waits for the response which is not so kind to users, but maybe it is easier to write a program. Well, there is actually no option but to have async=true. To provide the callback for success and error we can write the responding function onreadystatechange. This function will be called every time the state is changed. There are 5 states:
Ändra content i ContentEditorWebPart
Det finns ett exempel här.
//defaultAspx är sidan (SPListItem i Sidor)
//måste checkas ut först
//mgr är WebPartManager
//wp är contentEditorWebPart
web.AllowUnsafeUpdates = true;
XmlDocument xmlDoc = new XmlDocument();
XmlElement xmlElement = xmlDoc.CreateElement("Content");
xmlElement.InnerText = ((Microsoft.SharePoint.WebPartPages.ContentEditorWebPart)wp).Content.InnerText.ToString();
xmlElement.InnerText = xmlElement.InnerText.ToString().Replace("#HEADING#", "Welcome for welcome");
wp.Content = xmlElement;
mgr.SaveChanges(wp);
defaultAspx.File.CheckIn("");
defaultAspx.File.Publish("");
web.AllowUnsafeUpdates = false;
```Man måste skapa nytt XmlDocument och XmlElement, om man försöker skriva direkt till wp.Content.InnerText kommer det inte uppdateras. I det här fallet, byter vi ut #HEADING# mot något mer passande.
Formatera export xml av wordpress
Ville spara min blogg som en dagbok för utskrift. Exporterade hela bloggen som xml. Inga problem. Sedan var det dock nästan omöjligt att enkelt skriva in det i Word / OpenOffice. Jag har skrivit en liten css-fil som formaterar det lite så att man kan skriva ut. Lägg till:
<?xml-stylesheet type = "text/css" href="wordpress.css"?>
direkt efter:
<?xml version="1.0" encoding="UTF-8" ?>
Lägg filen “wordpress.com” i samma mapp. Här är wordpress.css
channel title {
font-size:3em;
}
channel description {
color:green;
margin-bottom:1em;
}
item title {
font-size:2em;
font-family:Arial;
margin-top:1em;
}
creator {
color:green;
}
creator:before {
content:"Skrivet av: ";
color:black;
font-style:italic;
font-size:0.8em;
}
post\_date:before {
content:"Datum: ";
}
comment {
margin-left:3em;
}
comment\_author:before {
content:"Kommentar av: ";
font-style:italic;
color:black;
}
comment\_author {
color:green;
}
comment\_date:before {
content:"(";
}
comment\_date:after {
content:"):";
}
/\* Ska inte visas\*/
link, channel language, pubDate,
guid, author, base\_site\_url,
base\_blog\_url, wxr\_version, generator,
post\_id, is\_sticky, post\_type, post\_name,
status, comment\_status, menu\_order,
post\_parent, ping\_status, post\_date\_gmt,
category, postmeta,
comment\_id, comment\_author\_email,
comment\_author\_IP, comment\_date\_gmt,
comment\_approved, comment\_type,
comment\_user\_id, comment\_parent {
display:none;
}
/\* block style \*/
title, description, post\_date, comment {
display:block;
}
Tag: Bug
Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)
I have had a strange bug. The comment text box in a OOB SharePoint 2013 blog doesn’t appear. It only says: “There are no comments for this post.” In this blog post I’ll tell you how I found the bug and I’ll show you how you can temporarily bring the commenting to life. I have had luck. While it doesn’t work on the Test Environment, it does actually work on my development machine. The comments text box is rendered as an OnPostRender action in the blog comments display template. After debugging the javascript in hours and comparing the two environments, I just could confirm that displaytemplates are the same. There are two main javascript files that are involved:
Tag: Cumulative Update
Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)
I have had a strange bug. The comment text box in a OOB SharePoint 2013 blog doesn’t appear. It only says: “There are no comments for this post.” In this blog post I’ll tell you how I found the bug and I’ll show you how you can temporarily bring the commenting to life. I have had luck. While it doesn’t work on the Test Environment, it does actually work on my development machine. The comments text box is rendered as an OnPostRender action in the blog comments display template. After debugging the javascript in hours and comparing the two environments, I just could confirm that displaytemplates are the same. There are two main javascript files that are involved:
Tag: Log
Log to ULS using javascript
The more javascript code is produced in SharePoint solutions, the more need we have to log information and possible errors to a central logging place in SharePoint: ULS. This blog post is about logging to ULS from javascript. For a while ago I read a blog post:
The author @avishnyakov mentions the ability log to ULS from javascript. I want to dive deeper. [sourcecode language=“javascript”] ULS.enable = true ULSOnError(“Hello from javascript”, location.href, 0); [/sourcecode] What this function actually does, is that it calls a web service called _vti_bin/diagnostics.asmx
We can follow the function in the init.debug.js [sourcecode language=“javascript”] function ULSOnError(msg, url, line) { return ULSSendExceptionImpl(msg, url, line, ULSOnError.caller); } [/sourcecode] ULSOnError invokes ULSSendExceptionImpl: [sourcecode language=“javascript”] function ULSSendExceptionImpl(msg, url, line, oCaller) { if (Boolean(ULS) && ULS.enable) { ULS.enable = false; window.onerror = ULS.OriginalOnError; ULS.WebServiceNS = “http://schemas.microsoft.com/sharepoint/diagnostics/"; try { ULS.message = msg; if (url.indexOf(’?’) != -1) url = url.substr(0, url.indexOf(’?’)); ULS.file = url.substr(url.lastIndexOf(’/’) + 1); ULS.line = line; ULS.teamName = “”; ULS.originalFile = “”; ULS.callStack = ‘\n’ + ULSGetCallstack(oCaller) + ‘’; ULS.clientInfo = ‘\n’ + ULSGetClientInfo() + ‘’; ULSSendReport(true); } catch (e) { } } if (Boolean(ULS) && Boolean(ULS.OriginalOnError)) return ULS.OriginalOnError(msg, url, String(line)); else return false; } [/sourcecode] ULSSendExceptionImpl invokes ULSSendReport: [sourcecode language=“javascript”] function ULSSendReport(async) { ULS.request = new XMLHttpRequest(); ULS.request.onreadystatechange = ULSHandleWebServiceResponse; ULS.request.open(“POST”, ULSGetWebServiceUrl(), async); ULS.request.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”); ULS.request.setRequestHeader(“SOAPAction”, ULS.WebServiceNS + “SendClientScriptErrorReport”); ULS.request.send(’’ + ‘<soap:Envelope xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=“http://www.w3.org/2001/XMLSchema" xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/">' + ‘soap:Body’ + ‘’ + ‘’ + ULSEncodeXML(ULS.message) + ‘’ + ‘’ + ULSEncodeXML(ULS.file) + ‘’ + ‘’ + String(ULS.line) + ‘’ + ‘’ + ULSEncodeXML(ULS.callStack) + ‘’ + ‘’ + ULSEncodeXML(ULS.clientInfo) + ‘’ + ‘’ + ULSEncodeXML(ULS.teamName) + ‘’ + ‘’ + ULSEncodeXML(ULS.originalFile) + ‘’ + ‘’ + ‘</soap:Body>’ + ‘</soap:Envelope>’); } [/sourcecode]
clearInterval in Chrome doesn't work on window blur
If you want to reset all interval jobs when a browser tab is inactive, the best way would be to use clearInterval on window blur. But unfortunately Chrome fires window focus and window blur two times. Here is an embryo to a solution:
var M = window.M || {};
M.counter = 0;
M.focused = true;
M.tick = function() {
if (M.focused) {
console.log("tic tac " + ++M.counter);
}
};
M.start = function(e) {
console.log("starting...");
M.focused = true;
};
M.stop = function(e) {
console.log("stopping...");
M.focused = false;
};
$(window).on({
focus: M.start,
blur: M.stop
});
M.ticker = window.setInterval(M.tick, 1000);
cross browser console.log
console.log
is the best tool for debugging javascript. In Firefox Firebug and Chrome Dev Tools you can even log objects which are represented as tree nodes of properties. If Firebug or Dev Tools in Chrome and IE9 are not opened, all these messages are ignored. But IE8 doesn’t understand console (if Dev Tools are closed) and raises an error: To avoid these errors, just declare an empty function just for IE8–:
Do an unsafe update in a unified manner
Recently I talked about a WithWeb-pattern as described in Jonas Nilssons blog where you can isolate the disposal logic in one place. Another thing is to isolate unsafe updates:
public static class SPWebExtension
{
public static void UnsafeUpdate(this SPWeb web, Action<SPWeb> action)
{
try
{
Log.Info("Trying to do an unsafe update on a web: " + web.Title);
web.AllowUnsafeUpdates = true;
action(web);
}
catch (Exception e)
{
Log.Error(e);
}
finally
{
web.AllowUnsafeUpdates = false;
}
}
}
```The Log class is my own class which I presented in [my previous post](https://sharepointkunskap.wordpress.com/2011/09/19/a-simple-log/).
## Comments from Wordpress.com
####
[WithWeb-pattern of Jonas Nilsson « Sharepoint. Kunskap. Upptäckter på resan.](https://sharepointkunskap.wordpress.com/2011/09/15/withweb-pattern-of-jonas-nilsson/ "") - <time datetime="2011-09-21 17:28:23">Sep 3, 2011</time>
\[...\] Here I use another fancy way to consolidate the unsafe updates. \[...\]
<hr />
A simple Log for ULS
Do an unsafe update in a unified manner « Sharepoint. Kunskap. Upptäckter på resan. - Sep 3, 2011
[…] Log class is my own class which I presented in my previous post. Like this:GillaBli först att gilla denna […]
A simple Log for ULS
Here is a simple log which has been inspired of Android Log. It logs to ULS which you can open with ULSViewer, SharePoint Log Viewer.
using System;
using Microsoft.SharePoint.Administration;
namespace Contoso.Intranet.Portal.Utilities
{
public class Log
{
private static readonly string \_CATEGORYNAME = "CONTOSO";
private static readonly SPDiagnosticsCategory \_ERROR\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Unexpected, EventSeverity.Error);
private static readonly SPDiagnosticsCategory \_WARNING\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.High, EventSeverity.Warning);
private static readonly SPDiagnosticsCategory \_VERBOSE\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Verbose, EventSeverity.Verbose);
private static readonly SPDiagnosticsCategory \_INFO\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Medium, EventSeverity.Information);
private static void WriteTrace(SPDiagnosticsCategory category, string message, string trace)
{
SPDiagnosticsService.Local.WriteTrace(0, category, category.DefaultTraceSeverity, message, trace);
}
public static void Error(Exception ex)
{
WriteTrace(\_ERROR\_CATEGORY, ex.Message, ex.StackTrace);
}
public static void Warning(string message)
{
WriteTrace(\_WARNING\_CATEGORY, message, "");
}
public static void Verbose(string message)
{
WriteTrace(\_VERBOSE\_CATEGORY, message, "");
}
public static void Info(string message)
{
WriteTrace(\_INFO\_CATEGORY, message, "");
}
}
}
A possible improvement can be a custom Area. See an example of ThorstenHans on Github: CustomLogger.cs EDIT: I found an interesting article: How to log to the SharePoint ULS Logs: Clean Debugging and Error Logging broken down into steps written by Philip Stathis.
uls logger
Det finns ett intressant projekt på codeplex: ULS Logger. Är absolut värt att testa.
Sharepoint Log Viewer
Mycket bra verktyg för att debugga din sharepoint applikation är Sharepoint Log Viewer som är Open Source och finns att hämta på codeplex.com Det går att öppna en logg-fil, det går att köra live monitoring och att exportera. Det sköna är att det är lätt att söka efter correlations-id. Rekommenderar verktyget!
Comments from Wordpress.com
Sharepoint + OpenSource = Sant « Sharepoint. Kunskap. Upptäckter på resan. - Mar 3, 2011
Tag: ULS
Log to ULS using javascript
The more javascript code is produced in SharePoint solutions, the more need we have to log information and possible errors to a central logging place in SharePoint: ULS. This blog post is about logging to ULS from javascript. For a while ago I read a blog post:
The author @avishnyakov mentions the ability log to ULS from javascript. I want to dive deeper. [sourcecode language=“javascript”] ULS.enable = true ULSOnError(“Hello from javascript”, location.href, 0); [/sourcecode] What this function actually does, is that it calls a web service called _vti_bin/diagnostics.asmx
We can follow the function in the init.debug.js [sourcecode language=“javascript”] function ULSOnError(msg, url, line) { return ULSSendExceptionImpl(msg, url, line, ULSOnError.caller); } [/sourcecode] ULSOnError invokes ULSSendExceptionImpl: [sourcecode language=“javascript”] function ULSSendExceptionImpl(msg, url, line, oCaller) { if (Boolean(ULS) && ULS.enable) { ULS.enable = false; window.onerror = ULS.OriginalOnError; ULS.WebServiceNS = “http://schemas.microsoft.com/sharepoint/diagnostics/"; try { ULS.message = msg; if (url.indexOf(’?’) != -1) url = url.substr(0, url.indexOf(’?’)); ULS.file = url.substr(url.lastIndexOf(’/’) + 1); ULS.line = line; ULS.teamName = “”; ULS.originalFile = “”; ULS.callStack = ‘\n’ + ULSGetCallstack(oCaller) + ‘’; ULS.clientInfo = ‘\n’ + ULSGetClientInfo() + ‘’; ULSSendReport(true); } catch (e) { } } if (Boolean(ULS) && Boolean(ULS.OriginalOnError)) return ULS.OriginalOnError(msg, url, String(line)); else return false; } [/sourcecode] ULSSendExceptionImpl invokes ULSSendReport: [sourcecode language=“javascript”] function ULSSendReport(async) { ULS.request = new XMLHttpRequest(); ULS.request.onreadystatechange = ULSHandleWebServiceResponse; ULS.request.open(“POST”, ULSGetWebServiceUrl(), async); ULS.request.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”); ULS.request.setRequestHeader(“SOAPAction”, ULS.WebServiceNS + “SendClientScriptErrorReport”); ULS.request.send(’’ + ‘<soap:Envelope xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=“http://www.w3.org/2001/XMLSchema" xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/">' + ‘soap:Body’ + ‘’ + ‘’ + ULSEncodeXML(ULS.message) + ‘’ + ‘’ + ULSEncodeXML(ULS.file) + ‘’ + ‘’ + String(ULS.line) + ‘’ + ‘’ + ULSEncodeXML(ULS.callStack) + ‘’ + ‘’ + ULSEncodeXML(ULS.clientInfo) + ‘’ + ‘’ + ULSEncodeXML(ULS.teamName) + ‘’ + ‘’ + ULSEncodeXML(ULS.originalFile) + ‘’ + ‘’ + ‘</soap:Body>’ + ‘</soap:Envelope>’); } [/sourcecode]
A simple Log for ULS
Do an unsafe update in a unified manner « Sharepoint. Kunskap. Upptäckter på resan. - Sep 3, 2011
[…] Log class is my own class which I presented in my previous post. Like this:GillaBli först att gilla denna […]
A simple Log for ULS
Here is a simple log which has been inspired of Android Log. It logs to ULS which you can open with ULSViewer, SharePoint Log Viewer.
using System;
using Microsoft.SharePoint.Administration;
namespace Contoso.Intranet.Portal.Utilities
{
public class Log
{
private static readonly string \_CATEGORYNAME = "CONTOSO";
private static readonly SPDiagnosticsCategory \_ERROR\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Unexpected, EventSeverity.Error);
private static readonly SPDiagnosticsCategory \_WARNING\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.High, EventSeverity.Warning);
private static readonly SPDiagnosticsCategory \_VERBOSE\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Verbose, EventSeverity.Verbose);
private static readonly SPDiagnosticsCategory \_INFO\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Medium, EventSeverity.Information);
private static void WriteTrace(SPDiagnosticsCategory category, string message, string trace)
{
SPDiagnosticsService.Local.WriteTrace(0, category, category.DefaultTraceSeverity, message, trace);
}
public static void Error(Exception ex)
{
WriteTrace(\_ERROR\_CATEGORY, ex.Message, ex.StackTrace);
}
public static void Warning(string message)
{
WriteTrace(\_WARNING\_CATEGORY, message, "");
}
public static void Verbose(string message)
{
WriteTrace(\_VERBOSE\_CATEGORY, message, "");
}
public static void Info(string message)
{
WriteTrace(\_INFO\_CATEGORY, message, "");
}
}
}
A possible improvement can be a custom Area. See an example of ThorstenHans on Github: CustomLogger.cs EDIT: I found an interesting article: How to log to the SharePoint ULS Logs: Clean Debugging and Error Logging broken down into steps written by Philip Stathis.
Tag: Leetspeak
scriptcs and SharePoint. How SharePoint can benefit?
Last Saturday I attended Leetspeak. Among many awesome speeches and presentations I discovered scriptcs. scriptcs lets you write C# code directly in the console, or execute scripts written with just your favourite editor. Please see more about it on the site. What I thought during Justin Rusbatch’s session at Leetspeak:
Can we use scriptcs in SharePoint?
Technically there is no limitations in SharePoint for scriptcs. Any .NET code can be registered, imported and invoked in a console or in a standalone script. Here is the simple code for instantiating a site collection and disposing it: [code language=“csharp”] #r Microsoft.SharePoint; using Microsoft.SharePoint; var site = new SPSite(“http://dev”); site.Url site.Dispose(); [/code] The code above does not do anything, it is just there to demonstrate how you can register the SharePoint assembly (“Microsoft.SharePoint”) and import it into the script: [code language=“csharp”] using Microsoft.SharePoint; [/code] The example shows even that you in scriptcs no longer need the necessary “boilerplate” (compared to a console application): namespace, Program, Main()… You can just directly write your code. The rest is the same as in a C# application. The code samples for scriptcs can be any code written in C# for SharePoint, code from custom console applications, from feature receivers, you name it. So my next question is:
Tag: Scriptcs
scriptcs and SharePoint. How SharePoint can benefit?
Last Saturday I attended Leetspeak. Among many awesome speeches and presentations I discovered scriptcs. scriptcs lets you write C# code directly in the console, or execute scripts written with just your favourite editor. Please see more about it on the site. What I thought during Justin Rusbatch’s session at Leetspeak:
Can we use scriptcs in SharePoint?
Technically there is no limitations in SharePoint for scriptcs. Any .NET code can be registered, imported and invoked in a console or in a standalone script. Here is the simple code for instantiating a site collection and disposing it: [code language=“csharp”] #r Microsoft.SharePoint; using Microsoft.SharePoint; var site = new SPSite(“http://dev”); site.Url site.Dispose(); [/code] The code above does not do anything, it is just there to demonstrate how you can register the SharePoint assembly (“Microsoft.SharePoint”) and import it into the script: [code language=“csharp”] using Microsoft.SharePoint; [/code] The example shows even that you in scriptcs no longer need the necessary “boilerplate” (compared to a console application): namespace, Program, Main()… You can just directly write your code. The rest is the same as in a C# application. The code samples for scriptcs can be any code written in C# for SharePoint, code from custom console applications, from feature receivers, you name it. So my next question is:
Tag: Authentication
Apps can only call the OOB CSOM and REST endpoints
As a SharePoint architect or a SharePoint developer, you must have been thinking about the benefits/limitations of SharePoint apps a lot. I want to point out one of them today, which is very important: using custom webservices deployed to SharePoint inside apps. That is impossible and it is designed to be so due to the security architecture in the sharepoint app framework. I have read much about SharePoint apps (books, whitepapers, blog posts) and stumbled over these two contradictive statements:
Tag: Permission
Apps can only call the OOB CSOM and REST endpoints
As a SharePoint architect or a SharePoint developer, you must have been thinking about the benefits/limitations of SharePoint apps a lot. I want to point out one of them today, which is very important: using custom webservices deployed to SharePoint inside apps. That is impossible and it is designed to be so due to the security architecture in the sharepoint app framework. I have read much about SharePoint apps (books, whitepapers, blog posts) and stumbled over these two contradictive statements:
OOTB permission levels in SharePoint
There are much info about standard permission levels in SharePoint. Here is my visualization for that. Just a little bit easier to find out the right permission level. Enjoy:
Full Control (FullMask)
Design
Contribute
Read
Limited Access
Restricted Reader
Manage Hierarchy
Approve
ViewListItems
x
x
x
x
x
x
AddListItems
x
x
x
x
EditListItems
x
x
x
x
DeleteListItems
x
x
x
x
ApproveItems
x
x
OpenItems
x
x
x
x
x
x
ViewVersions
x
x
x
x
x
DeleteVersions
x
x
x
x
CancelCheckout
x
x
x
ManagePersonalViews
x
x
x
x
ManageLists
x
x
ViewFormPages
x
x
x
x
x
x
Open
x
x
x
x
x
x
x
ViewPages
x
x
x
x
x
x
AddAndCustomizePages
x
x
ApplyThemeAndBorder
x
ApplyStyleSheets
x
ViewUsageData
x
CreateSSCSite
x
x
x
x
x
ManageSubWebs
x
CreateGroups
ManagePermissions
x
BrowseDirectories
x
x
x
x
BrowseUserInfo
x
x
x
x
x
x
AddDelPrivateWebParts
x
x
x
x
UpdatePersonalWebParts
x
x
x
x
ManageWeb
x
UseClientIntegration
Hide my site link with css
Want to hide my site link without disabling social features. Well, the simplest way to do it is to use css:
#mp1\_0\_0\_Anchor { display: none; }
```If you want to hide my profile instead, just hide #mp1\_0\_1\_Anchor:
#mp1_0_1_Anchor { display: none; }
.ms-MenuUIUL li[text=‘My Site’] { display: none;}
##### Disable the my profile feature An even better solution is maybe to disable the ability to change the profiles. [Just remove the permission to "user personalization..." for All authenticated users in User Profile Service](http://blog.libinuko.com/2010/10/10/sharepoint-2010-howto-disable-my-site-and-my-profile-link/).
## Comments from Wordpress.com
####
[John]( "johnandrewdavies@hotmail.com") - <time datetime="2012-03-07 00:15:32">Mar 3, 2012</time>
Be careful this cannot be used, the classes for pop up menus are generated dynamically on the page, and that class can be applied to a number of menus I assume depending on the order which they load on the page, which isnt the same every time, so for instance this hides something in the site actions menu, or the new button on a library sometimes.
<hr />
####
[Brett Anderson](http://sharepoint2020.wordpress.com "brettando@live.com.au") - <time datetime="2012-05-02 06:13:05">May 3, 2012</time>
Hi, The amended solution does not work in IE7.
<hr />
####
[Fredrik]( "fredrik.eriksson234@gmail.com") - <time datetime="2012-03-09 15:27:24">Mar 5, 2012</time>
Thank you Anatoly, that worked perfectly in all browsers! I had problems with the first suggested solution, because it would hide other menu items, like "edit this page" from the site settings dropdown!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:10:36">Mar 3, 2012</time>
You are totally right, John! I realized that too. Fortunately, I didn't need that then. But while using that I saw that sometimes Site Actions -Edit Page disappeared. These IDs are really generated dynamically. Thanks for your comment. I'll update my post.
<hr />
####
[vishal]( "vishals.shivan@gmail.com") - <time datetime="2012-03-07 07:27:54">Mar 3, 2012</time>
Hi Anatoly. Thanks for the solution. but the problem we are facing one problem after implementing this. Once we make this change and when login to the portal next time, the "Edit Page" link under site action menu is not getting displayed and the My Site Link is getting displyed. any suggestion?
<hr />
####
[Material SharePoint » Hide ‘My Site’ Link from Welcome User Dropdown Control](http://sharepoint.jsturges.com/2012/05/hide-my-site-link-from-welcome-user-dropdown-control/ "") - <time datetime="2012-05-12 17:45:13">May 6, 2012</time>
\[...\] of my enterprise level clients that we usually hide it all together! To do this, you can use an awesome CSS trick I learned from Anatoly \[...\]
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:24:39">Mar 3, 2012</time>
Hi Vishal. Unfortunately we cannot rely on these IDs, as John in previous comment mentioned, because these IDs are generated dynamically. I'll update my post. One possible solution would be use attribute selectors... Something like .ms-MenuUIUL li\[text='My Site'\] { display: none;}
<hr />
####
[jim]( "jim.omara@gmail.com") - <time datetime="2014-02-12 17:38:05">Feb 3, 2014</time>
.ms-welcomeMenu #mp1\_0\_0{ display:none; } .ms-welcomeMenu #mp1\_0\_1{ display:none; } .ms-welcomeMenu #mp1\_0\_2{ display:none; } .ms-welcomeMenu #mp1\_0\_3{ display:none; } .ms-welcomeMenu #mp1\_0\_4{ display:none; } .ms-welcomeMenu #mp1\_0\_8{ display:none; } .ms-welcomeMenu #mp1\_0\_9{ display:none; } these work for me.
<hr />
####
[Anatoly Mironov](http://chuvash.eu "mirontoli@gmail.com") - <time datetime="2014-02-12 23:20:59">Feb 3, 2014</time>
Thank you for sharing your solution. Appreciate.
<hr />
Tag: Ribbon
javascript: Alert Me on a Page
Recently I needed to add an Alert Me link on Pages. Alert Me is a well known SharePoint functionality for notifying users about changes in list or list items. It is availabe in OOB SharePoint as a command in Ribbon if you go to a list view: When you click on this ribbon command, SharePoint opens a modal dialog and takes you to layouts page: SubNew.aspx. To open a modal dialog and load a page is not a rocket science. So a custom “Alert Me” link is doable. As the first step I copied the html markup from the ribbon and adjusted it a little bit. [sourcecode language=“html”] Alert Me [/sourcecode] Then the javascript code which gets the List ID and Page ID is very simple because this information is there in the magic _spPageContextInfo: [sourcecode language=“javascript”] var takana = window.takana || {}; takana.alertMe = function () { var url = String.format("{0}/{1}/SubNew.aspx?List={2}&ID={3}" , _spPageContextInfo.webAbsoluteUrl , _spPageContextInfo.layoutsUrl , encodeURI(_spPageContextInfo.pageListId) , _spPageContextInfo.pageItemId); OpenPopUpPage(url); } [/sourcecode] This code will open a modal dialog in exactly the same way as the ribbon command in OOB SharePoint and let you subscribe to changes on that page. In this code I use String.format which is available on SharePoint pages and _spPageContextInfo which has existed since SharePoint 2010 and has been extended with more useful information about the current context.
spribbon fluent
Ett mycket intressant projekt för att skapa ribbon-anpassningar. Som så här:
new ButtonDefinition()
{
Id = "New",
Title = "Start new game",
CommandJavaScript = "window.location.reload();",
Image = new ImageDefinition()
{
Url16 = "/\_layouts/images/ChessWebPart/new16.png",
Url32 = "/\_layouts/images/ChessWebPart/new32.png"
}
}
```Så blir resultatet: ![spribbong](http://markeev.com/sharepoint/ribbon/media/buttonSample.png)
Tag: @Page
javascript: Remove illegal characters in url
Recently I needed to create valid urls for pages using javascript. Also this time I thought it must be some out-of-the-box code for that in SharePoint. The first thing I came up was the “Add page” dialog. I found that the actual dialog was in the _layouts virtual folder:
/\_layouts/15/CreatePublishingPageDialog.aspx
```Bingo, it does the validation in the client side. This is the responsible javascript function that resides directly in the page: \[sourcecode language="javascript"\] function UpdateUrl() { LoadTermContextInfo(); var hiddenPageUrlLabelExtensionClientId = "<%=hiddenPageUrlLabelExtension.ClientID%>"; var hiddenPageUrlLabelExtension = document.getElementById(hiddenPageUrlLabelExtensionClientId); var pageNamePreviewUrlLabelClientId = "<%=pageNamePreviewUrlLabel.ClientID%>"; var pageNamePreviewUrlLabel = document.getElementById(pageNamePreviewUrlLabelClientId); if( pageNamePreviewUrlLabel != null ) { var nameInputTextBoxClientId = "<%=nameInput.ClientID%>"; var nameInputTextBox = document.getElementById(nameInputTextBoxClientId); var allowSpaces = false; if( GetInnerText(hiddenPageUrlLabelExtension) != "" ) { var suggestUrlValue = ""; for (var i=0; i < nameInputTextBox.value.length; i++) { var currentChar = nameInputTextBox.value.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } UpdatePreviewUrl( suggestUrlValue ); } else { if( g\_timerId != 0 ) { window.clearTimeout(g\_timerId); } g\_timerId = window.setTimeout(OnFriendlyUrlNameChanged, 500); } } } \[/sourcecode\] This function iterates through all the characters in the page url and removes the illegal characters. The space, plus sign and the dot become a hyphen. To determine if a character is illegal, it relies on another javascript function called: `IndexOfIllegalCharInUrlLeafName`. This function can be found in the init.js or init.debug.js: \[sourcecode language="javascript"\] function IndexOfIllegalCharInUrlLeafName(strLeafName) { for (var i = 0; i < strLeafName.length; i++) { var ch = strLeafName.charCodeAt(i); if (strLeafName.charAt(i) == '.' && (i == 0 || i == strLeafName.length - 1)) return i; if (ch < 160 && (strLeafName.charAt(i) == '/' || !LegalUrlChars\[ch\])) return i; } return -1; } \[/sourcecode\] This function checks a char against an array of all characters: `LegalUrlChars` from the same file: init.js. [![ill_002](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png)](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png) To use this UpdateUrl function, we have to remove the references to the fields from the Add Page Dialog. Of course, we won't overwrite this original function, we don't want to break the SharePoint OOB functionality. Here is how my new function looks like: \[sourcecode language="javascript"\] var takana = {}; function takana.updateUrl(url) { var allowSpaces = false; if( url ) { var suggestUrlValue = ""; var length = url.length; for (var i=0; i < length; i++) { var currentChar = url.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } } } \[/sourcecode\]
#### Server Side
For those of you who want run this operation on the server, here is the code written in C#: \[sourcecode language="csharp"\] //" # % & \* : < > ? \\ / { } ~ | var illegalChars = @"\[""#%&\\\*:\\<\\>\\?\\\\\\/\\{\\}~\\|\]"; pageName = Regex.Replace(pageName, illegalChars, string.Empty); var punctuation = @"\[\\s\\.;\\+\]"; pageName = Regex.Replace(pageName, punctuation, "-"); //remove "--" pageName = Regex.Replace(pageName, @"\\-{2,}", "-"); pageName = string.Format("{0}.aspx", pageName); //do it like the built-in dialog, lower case pageName = pageName.ToLower(); \[/sourcecode\] Don't forget to leave a comment if you find this post useful.
## Comments from Wordpress.com
####
[Johannes Milling](http://discoveringsharepoint.wordpress.com "johannesmilling@hotmail.com") - <time datetime="2013-08-23 09:53:30">Aug 5, 2013</time>
Good post! :)
<hr />
Provisioning multiple pages with one source file
I found an easy way to provision multiple pages. Create a module. Add an aspx.file (e.g. default.aspx). In the elements file define nodes for every page. Path should be the same for all pages, but the Url should be your destination page. The “default.aspx” (name doesn’t matter) can contain content, or just one @Page directive if Publishing feature is available:
<%@ Page Inherits="Microsoft.SharePoint.Publishing.TemplateRedirectionPage,Microsoft.SharePoint.Publishing,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
```In the Element.xml define all your pages: [![](https://sharepointkunskap.files.wordpress.com/2011/10/abunchofpages-elements.png "abunchofpages-elements")](https://sharepointkunskap.files.wordpress.com/2011/10/abunchofpages-elements.png) In every File node you can add webparts, here is an example:
<![CDATA[ Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c Microsoft.SharePoint.WebPartPages.ContentEditorWebPart About cars Test None true Lorem ipsum dolor sit amet ]]>
~masterurl/default.master & ~masterurl/custom.master
Läser “SharePoint 2010 as a Development Platform”. Kan verkligen rekommendera den. Idag har jag förståt vad default.master och custom.master innebär. De pekar på de master-filer som är inställda på web-nivå. Så det är ingen idé att ändra DynamicMasterUrl i @Page-direktivet till sin egen (om du inte vill ha någon helt annan master än i resten av portalen).
Tag: Character
javascript: Remove illegal characters in url
Recently I needed to create valid urls for pages using javascript. Also this time I thought it must be some out-of-the-box code for that in SharePoint. The first thing I came up was the “Add page” dialog. I found that the actual dialog was in the _layouts virtual folder:
/\_layouts/15/CreatePublishingPageDialog.aspx
```Bingo, it does the validation in the client side. This is the responsible javascript function that resides directly in the page: \[sourcecode language="javascript"\] function UpdateUrl() { LoadTermContextInfo(); var hiddenPageUrlLabelExtensionClientId = "<%=hiddenPageUrlLabelExtension.ClientID%>"; var hiddenPageUrlLabelExtension = document.getElementById(hiddenPageUrlLabelExtensionClientId); var pageNamePreviewUrlLabelClientId = "<%=pageNamePreviewUrlLabel.ClientID%>"; var pageNamePreviewUrlLabel = document.getElementById(pageNamePreviewUrlLabelClientId); if( pageNamePreviewUrlLabel != null ) { var nameInputTextBoxClientId = "<%=nameInput.ClientID%>"; var nameInputTextBox = document.getElementById(nameInputTextBoxClientId); var allowSpaces = false; if( GetInnerText(hiddenPageUrlLabelExtension) != "" ) { var suggestUrlValue = ""; for (var i=0; i < nameInputTextBox.value.length; i++) { var currentChar = nameInputTextBox.value.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } UpdatePreviewUrl( suggestUrlValue ); } else { if( g\_timerId != 0 ) { window.clearTimeout(g\_timerId); } g\_timerId = window.setTimeout(OnFriendlyUrlNameChanged, 500); } } } \[/sourcecode\] This function iterates through all the characters in the page url and removes the illegal characters. The space, plus sign and the dot become a hyphen. To determine if a character is illegal, it relies on another javascript function called: `IndexOfIllegalCharInUrlLeafName`. This function can be found in the init.js or init.debug.js: \[sourcecode language="javascript"\] function IndexOfIllegalCharInUrlLeafName(strLeafName) { for (var i = 0; i < strLeafName.length; i++) { var ch = strLeafName.charCodeAt(i); if (strLeafName.charAt(i) == '.' && (i == 0 || i == strLeafName.length - 1)) return i; if (ch < 160 && (strLeafName.charAt(i) == '/' || !LegalUrlChars\[ch\])) return i; } return -1; } \[/sourcecode\] This function checks a char against an array of all characters: `LegalUrlChars` from the same file: init.js. [![ill_002](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png)](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png) To use this UpdateUrl function, we have to remove the references to the fields from the Add Page Dialog. Of course, we won't overwrite this original function, we don't want to break the SharePoint OOB functionality. Here is how my new function looks like: \[sourcecode language="javascript"\] var takana = {}; function takana.updateUrl(url) { var allowSpaces = false; if( url ) { var suggestUrlValue = ""; var length = url.length; for (var i=0; i < length; i++) { var currentChar = url.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } } } \[/sourcecode\]
#### Server Side
For those of you who want run this operation on the server, here is the code written in C#: \[sourcecode language="csharp"\] //" # % & \* : < > ? \\ / { } ~ | var illegalChars = @"\[""#%&\\\*:\\<\\>\\?\\\\\\/\\{\\}~\\|\]"; pageName = Regex.Replace(pageName, illegalChars, string.Empty); var punctuation = @"\[\\s\\.;\\+\]"; pageName = Regex.Replace(pageName, punctuation, "-"); //remove "--" pageName = Regex.Replace(pageName, @"\\-{2,}", "-"); pageName = string.Format("{0}.aspx", pageName); //do it like the built-in dialog, lower case pageName = pageName.ToLower(); \[/sourcecode\] Don't forget to leave a comment if you find this post useful.
## Comments from Wordpress.com
####
[Johannes Milling](http://discoveringsharepoint.wordpress.com "johannesmilling@hotmail.com") - <time datetime="2013-08-23 09:53:30">Aug 5, 2013</time>
Good post! :)
<hr />
Tag: Validate
javascript: Remove illegal characters in url
Recently I needed to create valid urls for pages using javascript. Also this time I thought it must be some out-of-the-box code for that in SharePoint. The first thing I came up was the “Add page” dialog. I found that the actual dialog was in the _layouts virtual folder:
/\_layouts/15/CreatePublishingPageDialog.aspx
```Bingo, it does the validation in the client side. This is the responsible javascript function that resides directly in the page: \[sourcecode language="javascript"\] function UpdateUrl() { LoadTermContextInfo(); var hiddenPageUrlLabelExtensionClientId = "<%=hiddenPageUrlLabelExtension.ClientID%>"; var hiddenPageUrlLabelExtension = document.getElementById(hiddenPageUrlLabelExtensionClientId); var pageNamePreviewUrlLabelClientId = "<%=pageNamePreviewUrlLabel.ClientID%>"; var pageNamePreviewUrlLabel = document.getElementById(pageNamePreviewUrlLabelClientId); if( pageNamePreviewUrlLabel != null ) { var nameInputTextBoxClientId = "<%=nameInput.ClientID%>"; var nameInputTextBox = document.getElementById(nameInputTextBoxClientId); var allowSpaces = false; if( GetInnerText(hiddenPageUrlLabelExtension) != "" ) { var suggestUrlValue = ""; for (var i=0; i < nameInputTextBox.value.length; i++) { var currentChar = nameInputTextBox.value.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } UpdatePreviewUrl( suggestUrlValue ); } else { if( g\_timerId != 0 ) { window.clearTimeout(g\_timerId); } g\_timerId = window.setTimeout(OnFriendlyUrlNameChanged, 500); } } } \[/sourcecode\] This function iterates through all the characters in the page url and removes the illegal characters. The space, plus sign and the dot become a hyphen. To determine if a character is illegal, it relies on another javascript function called: `IndexOfIllegalCharInUrlLeafName`. This function can be found in the init.js or init.debug.js: \[sourcecode language="javascript"\] function IndexOfIllegalCharInUrlLeafName(strLeafName) { for (var i = 0; i < strLeafName.length; i++) { var ch = strLeafName.charCodeAt(i); if (strLeafName.charAt(i) == '.' && (i == 0 || i == strLeafName.length - 1)) return i; if (ch < 160 && (strLeafName.charAt(i) == '/' || !LegalUrlChars\[ch\])) return i; } return -1; } \[/sourcecode\] This function checks a char against an array of all characters: `LegalUrlChars` from the same file: init.js. [![ill_002](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png)](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png) To use this UpdateUrl function, we have to remove the references to the fields from the Add Page Dialog. Of course, we won't overwrite this original function, we don't want to break the SharePoint OOB functionality. Here is how my new function looks like: \[sourcecode language="javascript"\] var takana = {}; function takana.updateUrl(url) { var allowSpaces = false; if( url ) { var suggestUrlValue = ""; var length = url.length; for (var i=0; i < length; i++) { var currentChar = url.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } } } \[/sourcecode\]
#### Server Side
For those of you who want run this operation on the server, here is the code written in C#: \[sourcecode language="csharp"\] //" # % & \* : < > ? \\ / { } ~ | var illegalChars = @"\[""#%&\\\*:\\<\\>\\?\\\\\\/\\{\\}~\\|\]"; pageName = Regex.Replace(pageName, illegalChars, string.Empty); var punctuation = @"\[\\s\\.;\\+\]"; pageName = Regex.Replace(pageName, punctuation, "-"); //remove "--" pageName = Regex.Replace(pageName, @"\\-{2,}", "-"); pageName = string.Format("{0}.aspx", pageName); //do it like the built-in dialog, lower case pageName = pageName.ToLower(); \[/sourcecode\] Don't forget to leave a comment if you find this post useful.
## Comments from Wordpress.com
####
[Johannes Milling](http://discoveringsharepoint.wordpress.com "johannesmilling@hotmail.com") - <time datetime="2013-08-23 09:53:30">Aug 5, 2013</time>
Good post! :)
<hr />
Validera din form på klienten
Det finns ett mycket bra jQuery-tillägg som kan validera din data i en formulär på ett enkelt sätt. Se en demo. Referera till validate.js och ange rätt css-klasser på dina inputs: “required”, “error”, “url”, “valid”. Mycket smidigt.
Tag: Validation
javascript: Remove illegal characters in url
Recently I needed to create valid urls for pages using javascript. Also this time I thought it must be some out-of-the-box code for that in SharePoint. The first thing I came up was the “Add page” dialog. I found that the actual dialog was in the _layouts virtual folder:
/\_layouts/15/CreatePublishingPageDialog.aspx
```Bingo, it does the validation in the client side. This is the responsible javascript function that resides directly in the page: \[sourcecode language="javascript"\] function UpdateUrl() { LoadTermContextInfo(); var hiddenPageUrlLabelExtensionClientId = "<%=hiddenPageUrlLabelExtension.ClientID%>"; var hiddenPageUrlLabelExtension = document.getElementById(hiddenPageUrlLabelExtensionClientId); var pageNamePreviewUrlLabelClientId = "<%=pageNamePreviewUrlLabel.ClientID%>"; var pageNamePreviewUrlLabel = document.getElementById(pageNamePreviewUrlLabelClientId); if( pageNamePreviewUrlLabel != null ) { var nameInputTextBoxClientId = "<%=nameInput.ClientID%>"; var nameInputTextBox = document.getElementById(nameInputTextBoxClientId); var allowSpaces = false; if( GetInnerText(hiddenPageUrlLabelExtension) != "" ) { var suggestUrlValue = ""; for (var i=0; i < nameInputTextBox.value.length; i++) { var currentChar = nameInputTextBox.value.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } UpdatePreviewUrl( suggestUrlValue ); } else { if( g\_timerId != 0 ) { window.clearTimeout(g\_timerId); } g\_timerId = window.setTimeout(OnFriendlyUrlNameChanged, 500); } } } \[/sourcecode\] This function iterates through all the characters in the page url and removes the illegal characters. The space, plus sign and the dot become a hyphen. To determine if a character is illegal, it relies on another javascript function called: `IndexOfIllegalCharInUrlLeafName`. This function can be found in the init.js or init.debug.js: \[sourcecode language="javascript"\] function IndexOfIllegalCharInUrlLeafName(strLeafName) { for (var i = 0; i < strLeafName.length; i++) { var ch = strLeafName.charCodeAt(i); if (strLeafName.charAt(i) == '.' && (i == 0 || i == strLeafName.length - 1)) return i; if (ch < 160 && (strLeafName.charAt(i) == '/' || !LegalUrlChars\[ch\])) return i; } return -1; } \[/sourcecode\] This function checks a char against an array of all characters: `LegalUrlChars` from the same file: init.js. [![ill_002](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png)](https://sharepointkunskap.files.wordpress.com/2013/06/ill_002.png) To use this UpdateUrl function, we have to remove the references to the fields from the Add Page Dialog. Of course, we won't overwrite this original function, we don't want to break the SharePoint OOB functionality. Here is how my new function looks like: \[sourcecode language="javascript"\] var takana = {}; function takana.updateUrl(url) { var allowSpaces = false; if( url ) { var suggestUrlValue = ""; var length = url.length; for (var i=0; i < length; i++) { var currentChar = url.charAt(i); if (IndexOfIllegalCharInUrlLeafName(currentChar) == -1 && !(currentChar == ' ' && allowSpaces == false) && currentChar != '.' && currentChar != '+') { suggestUrlValue += currentChar; } else if (currentChar == ' ' || currentChar == '+' || (currentChar == '.' && i > 0 && i < (nameInputTextBox.value.length - 1))) { suggestUrlValue += '-'; } } } } \[/sourcecode\]
#### Server Side
For those of you who want run this operation on the server, here is the code written in C#: \[sourcecode language="csharp"\] //" # % & \* : < > ? \\ / { } ~ | var illegalChars = @"\[""#%&\\\*:\\<\\>\\?\\\\\\/\\{\\}~\\|\]"; pageName = Regex.Replace(pageName, illegalChars, string.Empty); var punctuation = @"\[\\s\\.;\\+\]"; pageName = Regex.Replace(pageName, punctuation, "-"); //remove "--" pageName = Regex.Replace(pageName, @"\\-{2,}", "-"); pageName = string.Format("{0}.aspx", pageName); //do it like the built-in dialog, lower case pageName = pageName.ToLower(); \[/sourcecode\] Don't forget to leave a comment if you find this post useful.
## Comments from Wordpress.com
####
[Johannes Milling](http://discoveringsharepoint.wordpress.com "johannesmilling@hotmail.com") - <time datetime="2013-08-23 09:53:30">Aug 5, 2013</time>
Good post! :)
<hr />
Tag: Expressjs
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
Tag: Heroku
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
Hello world in node.js
I know, node.js has been present for a while. But I actually had no time to try it. I was surprised that now it is very straight forward to start with node.js. Allright, everything begins with Hello world. Eventhough it is available for allmost all combinations of operating systems and servers, the easiest way to test it was actually Ubuntu. To install just run:
sudo apt-get install nodejs
```Then make a new directory and create the hello.js:
mkdir hello cd hello vi hello.js
Tag: Mongodb
Convert any web app to a SharePoint app
Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app. This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps. Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart. A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site. For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:
Hello world in node.js
I know, node.js has been present for a while. But I actually had no time to try it. I was surprised that now it is very straight forward to start with node.js. Allright, everything begins with Hello world. Eventhough it is available for allmost all combinations of operating systems and servers, the easiest way to test it was actually Ubuntu. To install just run:
sudo apt-get install nodejs
```Then make a new directory and create the hello.js:
mkdir hello cd hello vi hello.js
MongoDB shell, learn directly in browser
Are you also curious about NoSQL databases. Well, MongoDB is one of the most known ones. MongoDB has a javascript syntax (json), I like it. Try out the interactive shell at the mongodb site.
Quickstart on Ubuntu
To test it on Ubuntu, just install an existing apt-package:
sudo apt-get install mongodb
Tag: Regedit
Set IE Proxy Server with PowerShell
Today just a quick one-liner tip for PowerShell. Use this script to set a proxy server in IE Settings. I got the inspiration from Aymeric’s blog: Scripting : Toggle proxy server in IE settings with PowerShell: [sourcecode language=“PowerShell”] sp AutoConfigUrl “http://proxy.contoso.com” ` -Path “HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings” [/sourcecode] By the way sp
is just alias for Set-ItemProperty cmdlet: This corresponds these settings in IE (Tools - Internet Options - Connections - Lan Settings): It can be useful if you have want to automate this.
Tag: Grunt
SharePoint Apps: "Provider Hosted First" Approach
Recently I had an exciting mail conversation with Thomas Deutsch. He came up with an idea how to fasten the development of apps. This smart approach is called “Provider Hosted First”. See Thomas’ original blog post. Here are some highlights: What you actually do is a local website which runs in grunt server
:
localhost:9000
```Then a SharePoint-hosted app is created with an SPAppIframe that refers to that local app site. Genious!!! Some key features of this approach:
* This local app contains a livereload script. Your sharepoint app is updated every time you save your css, js, html file in your IDE
* Grunt minifies, bundles your assets
* Grunt runs your tests automatically when your content is modified
* The SharePoint app can be on Premises, on Office 365, wherever you want it.
#### Video
\[caption id="attachment\_2808" align="alignnone" width="630"\][![See the video how it looks like to develop using this approach](https://sharepointkunskap.files.wordpress.com/2013/07/sp-app-002.png?w=630)](http://www.screenr.com/LA8H) See the video how it looks like to develop using this approach\[/caption\]
## Comments from Wordpress.com
####
[Paul Tavares](http://paultavares.wordpress.com "paultavares1@gmail.com") - <time datetime="2013-07-10 02:59:34">Jul 3, 2013</time>
This is pretty cool and very similar to my current setup for developing javascript applications for SharePoint. I use a script to "deploy" updates from my PC to the folder in a document library. I'll try this out when I get around to playing with SP2013.
<hr />
####
[Björn]( "bjorn.roberg@bool.se") - <time datetime="2013-07-02 11:07:08">Jul 2, 2013</time>
Awesome! I'm gonna try that out!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2013-07-02 15:31:33">Jul 2, 2013</time>
Great! When you go to Thomas Deutsch blog, you can download the source code for the solution.
<hr />
Tag: Minimal Download Strategy
Make javascript code work with Minimal Download Strategy Part 2
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
Minimal Download Strategy (MDS) is an important feature in SharePoint 2013. It lets you download only a page delta, only changes. There is still issues with the MDS and custom scripts and almost no documentation on msdn or technet. In this blog post I want to learn more about adjusting custom scripts for MDS. As in my previous post, I want to take a real problem and try to solve it. The goal is to find a solution, not nececerilly the most optimal solution, at least for now.
Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
Tag: Code Sample
Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
A simple Log for ULS
Do an unsafe update in a unified manner « Sharepoint. Kunskap. Upptäckter på resan. - Sep 3, 2011
[…] Log class is my own class which I presented in my previous post. Like this:GillaBli först att gilla denna […]
A simple Log for ULS
Here is a simple log which has been inspired of Android Log. It logs to ULS which you can open with ULSViewer, SharePoint Log Viewer.
using System;
using Microsoft.SharePoint.Administration;
namespace Contoso.Intranet.Portal.Utilities
{
public class Log
{
private static readonly string \_CATEGORYNAME = "CONTOSO";
private static readonly SPDiagnosticsCategory \_ERROR\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Unexpected, EventSeverity.Error);
private static readonly SPDiagnosticsCategory \_WARNING\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.High, EventSeverity.Warning);
private static readonly SPDiagnosticsCategory \_VERBOSE\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Verbose, EventSeverity.Verbose);
private static readonly SPDiagnosticsCategory \_INFO\_CATEGORY =
new SPDiagnosticsCategory(\_CATEGORYNAME, TraceSeverity.Medium, EventSeverity.Information);
private static void WriteTrace(SPDiagnosticsCategory category, string message, string trace)
{
SPDiagnosticsService.Local.WriteTrace(0, category, category.DefaultTraceSeverity, message, trace);
}
public static void Error(Exception ex)
{
WriteTrace(\_ERROR\_CATEGORY, ex.Message, ex.StackTrace);
}
public static void Warning(string message)
{
WriteTrace(\_WARNING\_CATEGORY, message, "");
}
public static void Verbose(string message)
{
WriteTrace(\_VERBOSE\_CATEGORY, message, "");
}
public static void Info(string message)
{
WriteTrace(\_INFO\_CATEGORY, message, "");
}
}
}
A possible improvement can be a custom Area. See an example of ThorstenHans on Github: CustomLogger.cs EDIT: I found an interesting article: How to log to the SharePoint ULS Logs: Clean Debugging and Error Logging broken down into steps written by Philip Stathis.
Tag: JQuery UI
Make javascript code work with Minimal Download Strategy Part 1
I have a newer blog post about MDS, that provides a much simpler solution. Please check it before reading further.
This is a part 1 of the blog post about Minimal Download Strategy and javascript adjustments for user code. What I initially thought should be enough for one post, is not enough, so I see it as a part 1. I wrote this post after I had read Chris O’Brien’s post about JSLink Here I want investigate how we can get his accordion list view working with MDS. Minimal Dowload Strategy or MDS is a new feature in SharePoint 2013. By now, if you read this post, you already know about it. The simplest way to see if MDS is enabled on your site, you can recognize it on the “ugly” urls. I don’t think they are so ugly. But it is a matter of taste and habit. No matter if you like MDS or not, MDS is enabled on many site templates and is a huge step towards a faster, more responsive architecture in SharePoint, I would say, towards the Single Page Application concept in SharePoint (but it is a long way to go). We have to keep the MDS in mind, when we write our customizations in javascript. SharePoint 2013 loves javascript and the probability is high that you write a lot of javascript. If it doesn’t work with MDS, your code breaks and the user doesn’t see the functionality, or the site owner must disable the Minimal Download Strategy feature. I wouldn’t like to have disabling of an improvement feature as a prerequisite for my code. In this blog post I want to dig into the techniques for getting the javascript code working with MDS. For a while ago I read a wonderful blog post in Chris O’Brien’s blog:
angular jQuery UI autocomplete
Angular JS is one of the most developed MVC frameworks in the javascript world. Angular UI is a huge UI-centric extension of AngularJS (it is more or less like jQuery UI to the jQuery). It uses much jQuery UI and Twitter Bootstrap and provides many own components like modal dialogs, maps, tooltips, masked inputs and much more. And all this is easy to implement in your code just by adding a directive: [sourcecode language=“html”][/sourcecode] Much cleaner than listening on $(document).ready, traversing the DOM and appending the datepicker in your code: [sourcecode language=“html”][/sourcecode] [sourcecode language=“javascript”]$(document).ready(function() { var input = $("#myDate"); input.datepicker(); });[/sourcecode] All this code is invoked but outside your app code.
javascript toolkit on text file
Referencing javascript libraries from Content Delivery Networks (CDN) like jQuery can have many benefits. The self-hosted javascript files are on the other hand give you more control. But in one situation it is much better with cdns: the development. Like Marc D Anderson pointed:
I didn’t realize it at the time, but this txt file has become a standard part of my toolkit already. I’ve added it to three client environments just since last week. It’s the A #1 fastest way to get something up and running, even if you know you’re going to host the files locally later.
jQuery UI Datepicker
As an alternative to asp:Calendar we can use the fancy jQuery UI Datepicker:
$(document).ready(function () {
$.datepicker.setDefaults($.datepicker.regional\["sv"\]);
$("#").datepicker({
changeMonth: true,
changeYear: true,
yearRange: "-120:+0"
});
});
```I found this a much simple and best solution for an [birthdate input](http://stackoverflow.com/questions/339956/whats-the-best-ui-for-entering-date-of-birth). We can set [international options](http://stackoverflow.com/questions/1865091/jquery-datepicker-language-problem), [year range](http://stackoverflow.com/questions/269545/jquery-datepicker-years-shown), [year](http://stackoverflow.com/questions/3164898/jquery-ui-datepicker-next-and-previous-year) and [month navigation](http://jqueryui.com/demos/datepicker/dropdown-month-year.html). Other options I have tried are asp:Calendar, ajaxtoolkit:CalendarExtender and DateJs. jQuery UI is the most simple much more than datepicker and works smoothily with SharePoint.
Tag: Loopback
A quick guide to configuring the Loopback check
Great tutorial how to configure the loopback check on a dev machine. Exactly what I needed for a month ago. Pity that this article came after that. :-) Here is the command to disable it completeley:
\# Disable Loopback check http://support.microsoft.com/kb/896861 #
New-ItemProperty HKLM:\\System\\CurrentControlSet\\Control\\Lsa -Name "DisableLoopbackCheck" -Value "1" -PropertyType dword
Tag: Ie
Styling suiteBar and IE8
Today I want to share little css tip for styling the suiteBar in SharePoint 2013 and making it work even in IE8. I needed to apply a green color to the suiteBar (#005128). It worked in all browsers except IE8: The reason why is a special css rule (in corev15.css) that only IE8 understands: [sourcecode language=“css”] .ms-core-needIEFilter #suiteBarLeft { filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=#ff0072c6,endColorstr=#ff0072c6); } [/sourcecode] I found this answer in an blog post written by Trace Armstrong: SharePoint 2013 – Branding the Top Bar and the Importance of Browser Testing. You could override this css rule with your colors, just dig into the msdn documentation. What I needed though, was just a plain color, so I didn’t want to dig into that old progid-definitions. There is actually a simpler solution on social.msdn.microsoft.com. A guy called avshinnikov just overrides the “filter” rule by setting it to none. If you apply it only with id selector (#suiteBarLeft) then you have to put “!important” after that. Fortunately I allready had my own css class on html tag which is a sort of a “namespace” for my selectors: [sourcecode language=“css”] .takana-html #suiteBarLeft { background-color: #005128; filter: none; } [/sourcecode] The class .takana-html can have any name, of course, and it can be a class on a closer parent element to the suiteBar. The only goal for that is to make your css rules more important in your design in a natural way (and avoiding the “!important”). Eventhough many people use this principle without thinking about it, I’ve not found any info regarding this principle. I only heard Jeremy Foster and Michael Palermo talking about it and referring to it as “css namespaces” in a video course: Developing in HTML5 with JavaScript and CSS3 Jump Start. Of course, the name isn’t unique, there is another thing called css namespaces. But the concept is really good.
Using javascript objects passed from closed popup
It is not a rocket science to pass objects from child window (popup) to main window. The problem I encountered today was IE and passing complex objects. So it is just an IE issue as far as I know. The problem occurs when you pass some object (not a simple String or Number) to main window:
window.opener.takeAnObjectFromChild = {
title: "Should even be available when I close the child"
};
and you then close the child window, next time the main window tries to access the passed object:
fallback for html5 placeholders
Placeholders are very handy in html5, we don’t need to fool with input values. But in SharePoint and IE we must provide fallback for placeholders if we want use them in other browsers. Here is an jQuery extension to do that:
(function ($) {
$.fn.extend({
ensurePlaceholders: function () {
var input = document.createElement('input');
var placeholderSupported = ('placeholder' in input);
if (placeholderSupported) {
return;
}
function setHints(elem) {
var $elem = $(elem);
var value = $elem.val();
if (value == "") {
var placeholder = $elem.attr("placeholder");
$elem.val(placeholder);
$elem.addClass("empty-text");
}
}
function removeHints(elem) {
var $elem = $(elem);
$elem.removeClass("empty-text");
var value = $elem.val();
var placeholder = $elem.attr("placeholder");
if (value == placeholder) {
$elem.val("");
}
}
this.find("\[placeholder\]").each(function() {
setHints(this);
});
this.on("focus", "\[placeholder\]", function(e) {
removeHints(this);
});
this.on("blur", "\[placeholder\]", function(e) {
setHints(this);
});
}
});
})(jQuery);
```Then "ensure placeholders" by running this function on a wrapper element which contains fields with the placeholder attribute:
jQuery("#form-wrapper").ensurePlaceholders();
Enable Save in IE9 mode
Wouldn’t it be nice to use html5 and css3 in SharePoint? No problems, there is actually v5 master out there, created by Kyle Schaefer. Or just use h5ml5 and css3 right away in your webparts and pages. But there is a big problem. It doesn’t work in IE9–. One of the issues (even listed by Kyle) is that “save” doesn’t work in modal dialogs where Rich Text Editor is used. Especialy it is for modal dialogs. The problem is not IE9, neither html5 and css3. After some digging in javascript code which is shipped with SharePoint I found out that the problem is some legacy javascript code which is not supported by IE9 but in IE8– (and compatibility mode). When we set IE9 mode in IE9 Dev Tools (F12) and go to Tasks list and try to create a task, we’ll get an error: It is RTE_GetEditorIFrame from init.js:
Tag: SuiteBar
Styling suiteBar and IE8
Today I want to share little css tip for styling the suiteBar in SharePoint 2013 and making it work even in IE8. I needed to apply a green color to the suiteBar (#005128). It worked in all browsers except IE8: The reason why is a special css rule (in corev15.css) that only IE8 understands: [sourcecode language=“css”] .ms-core-needIEFilter #suiteBarLeft { filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=#ff0072c6,endColorstr=#ff0072c6); } [/sourcecode] I found this answer in an blog post written by Trace Armstrong: SharePoint 2013 – Branding the Top Bar and the Importance of Browser Testing. You could override this css rule with your colors, just dig into the msdn documentation. What I needed though, was just a plain color, so I didn’t want to dig into that old progid-definitions. There is actually a simpler solution on social.msdn.microsoft.com. A guy called avshinnikov just overrides the “filter” rule by setting it to none. If you apply it only with id selector (#suiteBarLeft) then you have to put “!important” after that. Fortunately I allready had my own css class on html tag which is a sort of a “namespace” for my selectors: [sourcecode language=“css”] .takana-html #suiteBarLeft { background-color: #005128; filter: none; } [/sourcecode] The class .takana-html can have any name, of course, and it can be a class on a closer parent element to the suiteBar. The only goal for that is to make your css rules more important in your design in a natural way (and avoiding the “!important”). Eventhough many people use this principle without thinking about it, I’ve not found any info regarding this principle. I only heard Jeremy Foster and Michael Palermo talking about it and referring to it as “css namespaces” in a video course: Developing in HTML5 with JavaScript and CSS3 Jump Start. Of course, the name isn’t unique, there is another thing called css namespaces. But the concept is really good.
Tag: Autospinstaller
AutoSPInstaller: error while stopping the default web site in IIS
During an installation with AutoSPInstaller on my development machine I ran into a strange issue. I got the following error:
System.IO.FileNotFoundException: Could not load file or assembly ‘Microsoft.IIS.PowerShell.Framework’ or one of its dependencies
I haven’t found any other people having the same problem with the AutoSPInstaller, but I found a similar report on another forum: help.octopusdeploy.com. Maybe I am the only one who gets this error in AutoSPInstaller, if not it can be useful to write the solution down. The error occurs when the default web site in IIS is stopped. For some reason Get-WebSite cmdlet throws an exception the first time you invoke it, but not the second time. To get it working I followed the tip from the help.octopusdeploy.com and wrapped the Get-Website code in a try-and-catch, where the same cmdlet was in try and in catch. This line: [sourcecode language=“powershell”] $defaultWebsite = Get-Website | Where-Object {$_.Name -eq “Default Web Site” -or $_.ID -eq 1 -or $_.physicalPath -eq “%SystemDrive%\inetpub\wwwroot”} # Try different ways of identifying the Default Web Site, in case it has a different name (e.g. localized installs)[/sourcecode] becomes this code (the lines in try and catch are identical): [sourcecode language=“powershell”] Try{ $defaultWebsite = Get-Website | Where-Object {$_.Name -eq “Default Web Site” -or $_.ID -eq 1 -or $_.physicalPath -eq “%SystemDrive%\inetpub\wwwroot”} # Try different ways of identifying the Default Web Site, in case it has a different name (e.g. localized installs) } Catch [System.IO.FileNotFoundException]{ $defaultWebsite = Get-Website | Where-Object {$_.Name -eq “Default Web Site” -or $_.ID -eq 1 -or $_.physicalPath -eq “%SystemDrive%\inetpub\wwwroot”} Break }[/sourcecode] With this fix I was able to run the whole AutoSPInstaller script. My development machine was a fresh installed Windows Server 2008 R2 SP1 (without any updates). Leave a comment if you run into the same issue. If so, I’ll try to send a patch to the AutoSPInstaller code.
Tag: Internalization
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Minority
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Tag: Windows8
On Windows keyboard layouts for minority languages in Russia
I can’t write in Chuvash in Windows 8 (and all the previous Windows releases). Chuvash is a minority language in Russian Federation. In this blog post I want to summarize the status of the keyboard layout support of the minority languages of Russia and find a way to improve this situation.
Languages and Microsoft
There are thousands of languages. Of course it is hard to support them all. As per 2012-02-21 Windows 8 supports 109 (!) languages. In december 2012 the support for Cheerokee language was added.
Windows 8: shutdown button on your start and desktop
If you think that “Go to corner” -> Settings -> Power -> Shut down are three steps to much if you just want to shutdown your Windows 8 machine, than do as I did: create a shortcut on you desktop and a tile on your start screen. Create a shortcut as usual: Write in the location field:
shutdown /s /t 0
Name it something, why not “shutdown”? Change the default icon: There it is. Now we can pin it to Start: Done. Now, if you want to shutdown, you have to click only once: Enjoy!
Develop for SharePoint on Windows 8
Do you like Windows 8 user expirience, as me? Well than you want to try developing sharepoint solutions in Windows 8. Here I will show what I found out.
Environment
I installed Windows 8 Release Preview as a VMWare machine. Then I installed Visual Studio 2012 RC. Then I followed the steps for installing SharePoint on Windows 8 which are more or less the same as for Windows 7 client install. But then I encountered an error I haven’t found solution for yet. In my standalone sharepoint installation there were some permission problems:
Tag: AAM
Error: Sorry, we're having trouble reaching the server
I ran into a an issue today. When I tried to add a user to a site in my SharePoint 2013 site, I got this error:
Sorry, we’re having trouble reaching the server
A google search gave these two possible solutions:
I know it can almost everything that can cause this error. Here are my two öre :) I found that when I tried to add a user, an ajax call was made. And this was the error:
The right URL regardless AAM zone
For a while ago my colleague gave me a nice tip of getting the right absolute url regardless sharepoint zone in Alternate Access Mappings. I want to share it, because it is brilliant:
var url = SPUtility.AlternateServerUrlFromHttpRequestUrl(new Uri(value)).AbsoluteUri;
Tag: Angular Ui
SharePoint Modal Dialog as AngularJS directive
It has already become a series of posts in my blog about the combination of AngularJS and SharePoint:
- AngularJS: prevent form validation in Page Edit Mode
- angular jQuery UI autocomplete
- AngularJS: sync $location.search with an input value
And it will be more. Some of them are a pure angular stuff, some of them are really for SharePoint. In this post post I’ll show how to create a directive for a sharepoint modal dialog (SP.UI.ModalDialog). There is already a modal dialog implementation in the Angular UI project, but it uses the bootstrap modal dialog. But it custom attributes for angular">is not that hard to create an own directive for showing sharepoint modal dialogs. I’ve called the new directive ng-sp-modal
(ngSpModal). Here is this: [sourcecode language=“javascript”] var ngSpModal = function() { link: function (scope, element, attrs, controller) { var dialog, defaults = { html: element.get(0), showClose: false }, getOptions = function () { var options = scope.$eval(attrs.ngSpModal); return angular.extend(defaults, options); }; fireSpModal: function (value) { if (value) { var opts = getOptions(); dialog = SP.UI.ModalDialog.showModalDialog(opts); } else { dialog && dialog.close(); } }; // Watch for changes to the directives options scope.$watch(attrs.ngShow, fireSpModal, true); } return { require: ‘?ngShow’, link: link }; }; window.myApp = angular.module(‘myApp’, [‘ui.directives’]); myApp.directive(’ngSpModal’, [ngSpModal]); [/sourcecode] The new ng-sp-modal directive depends on ng-show. When your expression or value for ng-show for your html area is true, then a sharepoint modal dialog will open. This is achieved through a $watch command. The html area which is used to create will be copied to the modal dialog. I have used it for forms. To use it, just place this directive into your html element that you want be shown in a modal dialog. Here is a simple example to achieve what it is shown in the screenshot pasted above. [sourcecode language=“html”] Here is the html markup for your modal dialog [/sourcecode] Here is the very simple angular controller to let it work: [sourcecode language=“javascript”] function someCtrl($scope) { $scope.modalOptions = { height: 100, width: 300, title: “Yeah” }; } [/sourcecode]
angular jQuery UI autocomplete
Angular JS is one of the most developed MVC frameworks in the javascript world. Angular UI is a huge UI-centric extension of AngularJS (it is more or less like jQuery UI to the jQuery). It uses much jQuery UI and Twitter Bootstrap and provides many own components like modal dialogs, maps, tooltips, masked inputs and much more. And all this is easy to implement in your code just by adding a directive: [sourcecode language=“html”][/sourcecode] Much cleaner than listening on $(document).ready, traversing the DOM and appending the datepicker in your code: [sourcecode language=“html”][/sourcecode] [sourcecode language=“javascript”]$(document).ready(function() { var input = $("#myDate"); input.datepicker(); });[/sourcecode] All this code is invoked but outside your app code.
Tag: Angularjs
SharePoint Modal Dialog as AngularJS directive
It has already become a series of posts in my blog about the combination of AngularJS and SharePoint:
- AngularJS: prevent form validation in Page Edit Mode
- angular jQuery UI autocomplete
- AngularJS: sync $location.search with an input value
And it will be more. Some of them are a pure angular stuff, some of them are really for SharePoint. In this post post I’ll show how to create a directive for a sharepoint modal dialog (SP.UI.ModalDialog). There is already a modal dialog implementation in the Angular UI project, but it uses the bootstrap modal dialog. But it custom attributes for angular">is not that hard to create an own directive for showing sharepoint modal dialogs. I’ve called the new directive ng-sp-modal
(ngSpModal). Here is this: [sourcecode language=“javascript”] var ngSpModal = function() { link: function (scope, element, attrs, controller) { var dialog, defaults = { html: element.get(0), showClose: false }, getOptions = function () { var options = scope.$eval(attrs.ngSpModal); return angular.extend(defaults, options); }; fireSpModal: function (value) { if (value) { var opts = getOptions(); dialog = SP.UI.ModalDialog.showModalDialog(opts); } else { dialog && dialog.close(); } }; // Watch for changes to the directives options scope.$watch(attrs.ngShow, fireSpModal, true); } return { require: ‘?ngShow’, link: link }; }; window.myApp = angular.module(‘myApp’, [‘ui.directives’]); myApp.directive(’ngSpModal’, [ngSpModal]); [/sourcecode] The new ng-sp-modal directive depends on ng-show. When your expression or value for ng-show for your html area is true, then a sharepoint modal dialog will open. This is achieved through a $watch command. The html area which is used to create will be copied to the modal dialog. I have used it for forms. To use it, just place this directive into your html element that you want be shown in a modal dialog. Here is a simple example to achieve what it is shown in the screenshot pasted above. [sourcecode language=“html”] Here is the html markup for your modal dialog [/sourcecode] Here is the very simple angular controller to let it work: [sourcecode language=“javascript”] function someCtrl($scope) { $scope.modalOptions = { height: 100, width: 300, title: “Yeah” }; } [/sourcecode]
AngularJS: prevent form validation in Page Edit Mode
I work on a cool project where AngularJS is used for rendering of business data in a SharePoint portal. One of the beautiful parts of AngularJS is the client validation. AngularJS understands the new html5 attributes like “required” and pattern, which makes the markup and javascript concise and semantic. Recently I ran into a problem: The SharePoint webparts which had html forms with required fields were impossible to add to a page in the web browser, neither was it possible to edit the pages with these webparts. When I clicked on “Save”, the page tried to validate and failed. The solution for this is very elegant, like much of the AngularJS. If you don’t show your angular form, it won’t validate. So just use any method to detect the edit mode on a SharePoint page. I created a helper function for that. [sourcecode language=“javascript”] function isEditMode() { var publishingEdit = window.g_disableCheckoutInEditMode, form = document.forms[MSOWebPartPageFormName], input = form.MSOLayout_InDesignMode || form._wikiPageMode; return !!(publishingEdit || (input && input.value)); } [/sourcecode] In the angular controller, just define the part of it which shouldn’t be there when you are editing a page, by using ng-hide="editMode"
: [sourcecode language=“html”] [/sourcecode] editMode
is a $scope variable in your controller. So the last thing to do is to get the editMode value by invoking the previously defined isEditMode
function: [sourcecode language=“javascript”] function PhoneCallCtrl($scope, $http) { $scope.editMode = isEditMode(); } [/sourcecode]
angular jQuery UI autocomplete
Angular JS is one of the most developed MVC frameworks in the javascript world. Angular UI is a huge UI-centric extension of AngularJS (it is more or less like jQuery UI to the jQuery). It uses much jQuery UI and Twitter Bootstrap and provides many own components like modal dialogs, maps, tooltips, masked inputs and much more. And all this is easy to implement in your code just by adding a directive: [sourcecode language=“html”][/sourcecode] Much cleaner than listening on $(document).ready, traversing the DOM and appending the datepicker in your code: [sourcecode language=“html”][/sourcecode] [sourcecode language=“javascript”]$(document).ready(function() { var input = $("#myDate"); input.datepicker(); });[/sourcecode] All this code is invoked but outside your app code.
AngularJS: sync $location.search with an input value
I have used AngularJS for a while and to me this seems to be the best MVC javascript framework. Today I wanted to implement a search which uses an input and a hash query string like in google. The input value and url have to be synced like:
index.html#?term=something
To do this we have to inject $location
into our angular control. See the Angular Guide about $location. Then we have to observe both the $scope.term (which is bound to the input value) and $location.search().
Tag: ModalDialog
SharePoint Modal Dialog as AngularJS directive
It has already become a series of posts in my blog about the combination of AngularJS and SharePoint:
- AngularJS: prevent form validation in Page Edit Mode
- angular jQuery UI autocomplete
- AngularJS: sync $location.search with an input value
And it will be more. Some of them are a pure angular stuff, some of them are really for SharePoint. In this post post I’ll show how to create a directive for a sharepoint modal dialog (SP.UI.ModalDialog). There is already a modal dialog implementation in the Angular UI project, but it uses the bootstrap modal dialog. But it custom attributes for angular">is not that hard to create an own directive for showing sharepoint modal dialogs. I’ve called the new directive ng-sp-modal
(ngSpModal). Here is this: [sourcecode language=“javascript”] var ngSpModal = function() { link: function (scope, element, attrs, controller) { var dialog, defaults = { html: element.get(0), showClose: false }, getOptions = function () { var options = scope.$eval(attrs.ngSpModal); return angular.extend(defaults, options); }; fireSpModal: function (value) { if (value) { var opts = getOptions(); dialog = SP.UI.ModalDialog.showModalDialog(opts); } else { dialog && dialog.close(); } }; // Watch for changes to the directives options scope.$watch(attrs.ngShow, fireSpModal, true); } return { require: ‘?ngShow’, link: link }; }; window.myApp = angular.module(‘myApp’, [‘ui.directives’]); myApp.directive(’ngSpModal’, [ngSpModal]); [/sourcecode] The new ng-sp-modal directive depends on ng-show. When your expression or value for ng-show for your html area is true, then a sharepoint modal dialog will open. This is achieved through a $watch command. The html area which is used to create will be copied to the modal dialog. I have used it for forms. To use it, just place this directive into your html element that you want be shown in a modal dialog. Here is a simple example to achieve what it is shown in the screenshot pasted above. [sourcecode language=“html”] Here is the html markup for your modal dialog [/sourcecode] Here is the very simple angular controller to let it work: [sourcecode language=“javascript”] function someCtrl($scope) { $scope.modalOptions = { height: 100, width: 300, title: “Yeah” }; } [/sourcecode]
Callouts in SharePoint 2013 Preview
While ModalDialog is not default for editing list items in SharePoint 2013 Preview, there is a new “popup” element in SharePoint - callout or popover. I would like to recommend these two blogs when you want discover more: Andrey Markeev: Callouts (popovers) в SharePoint 2013 Preview (in Russian) Alex Boev: a three part series: 1. Custom Callouts in the SharePoint 2013 Metro UI: Part 1: Basics 2. Custom Callouts in the SharePoint 2013 Metro UI, Part 2: Actions 3. Custom Callouts in the SharePoint 2013 Metro UI, Part 3: CalloutManager To get introduced with callouts in SharePoint 2013, you can run this code (from Andrey Markeev’s blog):
SP.UI.Notify in Modal Dialog
If you open a custom page (not a list item form) in a modal dialog, your notification won’t be shown. The reason is that the notification area (#notificationArea) is inside a hidden div (#s4-ribbonrow). To show this notificationArea we must display the notification area:
var $ribbon = jQuery("#s4-ribbonrow");
if ($ribbon.is(":hidden")) {
$ribbon.css({"min-height": 0, "height": "0px"})
.show().children().hide()
.filter("#notificationArea").show()
}
Comments from Wordpress.com
Jens Malmberg - Jan 3, 2013
Run javascript code except it is inside a modal dialog
Want to run some javascript code everywhere, but not in a modal dialog. Because errors are occured, or this code is unnecessary i dialogs. Well here is a solution I have found after some experiments:
$(document).ready(function() {
if (!window.location.href.match(/isdlg=1/i)) {
onDocumentReadyExceptItIsInDialog();
}
});
function onDocumentReadyExceptItIsInDialog() {}
```This code checks with Regular Expressions if the url of the parent window contains IsDlg=1, if so nothing happens. In the usual case (not inside a dialog), the javascript code runs. EDIT: after I wrote this I actually found that this is the way SharePoint itself does: [![](https://sharepointkunskap.files.wordpress.com/2012/01/isdlg.png "isdlg")](https://sharepointkunskap.files.wordpress.com/2012/01/isdlg.png) So now I update the previous function to this:
$(document).ready(function() { if (window.location.search.match(/[?&]isdlg=1/i)) { return; } onDocumentReadyExceptItIsInDialog(); });
Pass arguments from/to Modal Dialog
To pass arguments from a ModalDialog is easy. Provide some buttons and invoke close function:
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, someValue);
```The first argument is result, [it is a enumeration with three alternatives](http://msdn.microsoft.com/en-us/library/ff409060.aspx): cancel, invalid and OK. The value you pass back to the main window can be a simple string, or a complex javascript object. In this example I'll create a html element which is hidden (id="modal-form" [class="s4-die"](/2011/10/14/s4-die/)):
Pass arguments to Modal Dialog and use it
In options you pass to SP.UI.ModalDialog.showModalDialog you can define args property. It can be any object with any complexity.
styra css för modaldialog
Säg du har application page med samma master page som resten av portalen. Men vad göra om du vill ändra css bara om den är i modal dialog. Overrida dina css-regler genom att lägga till .ms-dialog. .ms-dialog är css-klassen som läggs på html-taggen om sidan laddas i modaldialog:
html.ms-dialog body {
background-color:white;
}
Använd inbyggd ModalDialog
Vill du visa någon formulär, eller längre information kan du använda en snygg (snygg och snygg?) ruta som är default i Sharepoint. Den är i alla fall användbar. Här är ett litet enkelt exempel, för att illustrera:
var options = {
url: "http://sverigesradio.se",
width: 800,
height: 600,
allowMaximize: false
};
SP.UI.ModalDialog.showModalDialog(options);
Det finns även möjlighet att ha OK-knappen, alltså som alert i javascript. Kolla den här länken.
Tag: Resources
JavaScript Localization in SharePoint
Yesterday Waldek Mastykarz published a cool post: Globalizing JavaScript in SharePoint 2013. This is a very cool technique to localize your client code in javascript and reuse your resx files in Server Side and Client Side. This is actually not new for SharePoint 2013 despite it has become more needed with the huge client focus in the new SharePoint. I have used this in SharePoint 2010 for a long time. In my blog post: ScriptResx.ashx in SharePoint I told about that technique. What I didn’t know that you can define your javascript namespace directly in the resx file. Waldek wrote in his comment that SP.Publishing.Resources.en-US.resx automatically are SP.Publishing.Resources in javascript. That was not the case for my own localization files. A simple look at SP.Publishing.Resources.en-US.resx helped: [sourcecode language=“xml”] true SP.Publishing.Resources [/sourcecode] This results in: [sourcecode language=“javascript”] _EnsureJSNamespace(‘SP.Publishing’); [/sourcecode] So what we have to do for our custom resx file is to add classFullName resheader: [sourcecode language=“xml”] Takana.Res [/sourcecode]
ResxCrunch: Localization tool
If your solution has two or more languages to support, I can recommend an open source tool ResxCrunch. Btw, you can even use ResxCrunch for localization of Android applications.
Hämta lokaliserad sträng från App_GlobalResources
Om man har en sträng i App_GlobalResources som man vill hämta ifrån koden, kör:
string text = HttpContext.GetGlobalResourceObject("MyProject\_Global", "submit\_label") as string;
Tag: Edit Mode
AngularJS: prevent form validation in Page Edit Mode
I work on a cool project where AngularJS is used for rendering of business data in a SharePoint portal. One of the beautiful parts of AngularJS is the client validation. AngularJS understands the new html5 attributes like “required” and pattern, which makes the markup and javascript concise and semantic. Recently I ran into a problem: The SharePoint webparts which had html forms with required fields were impossible to add to a page in the web browser, neither was it possible to edit the pages with these webparts. When I clicked on “Save”, the page tried to validate and failed. The solution for this is very elegant, like much of the AngularJS. If you don’t show your angular form, it won’t validate. So just use any method to detect the edit mode on a SharePoint page. I created a helper function for that. [sourcecode language=“javascript”] function isEditMode() { var publishingEdit = window.g_disableCheckoutInEditMode, form = document.forms[MSOWebPartPageFormName], input = form.MSOLayout_InDesignMode || form._wikiPageMode; return !!(publishingEdit || (input && input.value)); } [/sourcecode] In the angular controller, just define the part of it which shouldn’t be there when you are editing a page, by using ng-hide="editMode"
: [sourcecode language=“html”] [/sourcecode] editMode
is a $scope variable in your controller. So the last thing to do is to get the editMode value by invoking the previously defined isEditMode
function: [sourcecode language=“javascript”] function PhoneCallCtrl($scope, $http) { $scope.editMode = isEditMode(); } [/sourcecode]
Tag: Autocomplete
angular jQuery UI autocomplete
Angular JS is one of the most developed MVC frameworks in the javascript world. Angular UI is a huge UI-centric extension of AngularJS (it is more or less like jQuery UI to the jQuery). It uses much jQuery UI and Twitter Bootstrap and provides many own components like modal dialogs, maps, tooltips, masked inputs and much more. And all this is easy to implement in your code just by adding a directive: [sourcecode language=“html”][/sourcecode] Much cleaner than listening on $(document).ready, traversing the DOM and appending the datepicker in your code: [sourcecode language=“html”][/sourcecode] [sourcecode language=“javascript”]$(document).ready(function() { var input = $("#myDate"); input.datepicker(); });[/sourcecode] All this code is invoked but outside your app code.
Autocomplete för sökruta i Sharepoint
Ett mycket trevligt projekt: Search As You Type på Codeplex. Ladda ner textfilen och lägg till javascript och css från den filen till masterpage. Så enkelt är det. Jag har testat det genom att direkt stoppa in koden i Chrome Console.
Tag: Datepicker
angular jQuery UI autocomplete
Angular JS is one of the most developed MVC frameworks in the javascript world. Angular UI is a huge UI-centric extension of AngularJS (it is more or less like jQuery UI to the jQuery). It uses much jQuery UI and Twitter Bootstrap and provides many own components like modal dialogs, maps, tooltips, masked inputs and much more. And all this is easy to implement in your code just by adding a directive: [sourcecode language=“html”][/sourcecode] Much cleaner than listening on $(document).ready, traversing the DOM and appending the datepicker in your code: [sourcecode language=“html”][/sourcecode] [sourcecode language=“javascript”]$(document).ready(function() { var input = $("#myDate"); input.datepicker(); });[/sourcecode] All this code is invoked but outside your app code.
Tag: Ellipsis
javascript: show only a part of a long string (ellipsis)
Ellipsis (…) is a character which indicates that the content is to wide. There are many solutions to truncate the text and show an ellipsis: in javascript and css. I want to share my humble function which extends the String.prototype: [sourcecode language=“javascript”]String.prototype.ellipsize = function(maxLength) { maxLength = maxLength || 100; if (this.length <= maxLength) { return this; } var text = this.toString().replace(/[\r\n]/g, “”), max = maxLength, min = maxLength - 20, elipsized, tryExtract = function () { var regex = new RegExp("^.{" + min + “,” + max + “}\\s”), match = text.match(regex); if (match) { elipsized = match[0].replace(/\.?\s$/, ‘…’); } else { //well, there were no \s between min and max min = min - 20; tryExtract(); } }; if (min <= 0) { return text; } tryExtract(); return elipsized || text; };[/sourcecode] To use it, just call the function from a string property in your favorite templating engine: Angular, jsRender, Knockout….: [sourcecode language=“javascript”]order.description.ellipsize();[/sourcecode] This function takes an argument maxLength
(default 100 chars). It doesn’t cut your text in the middle of a word, that’s why it looks after a whitespace in range of maxLength-20 and maxLength.
Tag: Prototype
javascript: show only a part of a long string (ellipsis)
Ellipsis (…) is a character which indicates that the content is to wide. There are many solutions to truncate the text and show an ellipsis: in javascript and css. I want to share my humble function which extends the String.prototype: [sourcecode language=“javascript”]String.prototype.ellipsize = function(maxLength) { maxLength = maxLength || 100; if (this.length <= maxLength) { return this; } var text = this.toString().replace(/[\r\n]/g, “”), max = maxLength, min = maxLength - 20, elipsized, tryExtract = function () { var regex = new RegExp("^.{" + min + “,” + max + “}\\s”), match = text.match(regex); if (match) { elipsized = match[0].replace(/\.?\s$/, ‘…’); } else { //well, there were no \s between min and max min = min - 20; tryExtract(); } }; if (min <= 0) { return text; } tryExtract(); return elipsized || text; };[/sourcecode] To use it, just call the function from a string property in your favorite templating engine: Angular, jsRender, Knockout….: [sourcecode language=“javascript”]order.description.ellipsize();[/sourcecode] This function takes an argument maxLength
(default 100 chars). It doesn’t cut your text in the middle of a word, that’s why it looks after a whitespace in range of maxLength-20 and maxLength.
javascript: Umbrella pattern
There are two great patterns for organizing javascript code: Prototype and Module pattern. More about them later in this post. But in reality I still see much of spagghetti Just an example: SharePoint 101 code samples. They are indeed very simple and isolated examples. And many projects use this simple way in mind when they begin. But when javascript code grows, it becomes a monster. Have you seen this biest? How is this monster created? Through good intentions (like everything else) in form of KISS mantra, to little time and the “commit and run”-behavior, or the worst: “I am c#-er, not Front-End-Developer”-spirit. In this post I’ll introduce a kind of compromise the Umbrella pattern. But before that, let’s see how to recognize the spagghetti monster in javascript:
javascript Module pattern
Want organize your js code in a kind of namespaces, or modules, then use the module pattern. I’ll take the dummy example for getting the current anchor. Let’s look how it would be if the prototype based approach is used:
var Contoso.Utils = function() {};
Contoso.Utils.prototype = {
getCurrentAnchor: function() {
var url = window.location;
var anchor=url.hash; //anchor with the # character
var anchor2=url.hash.substring(1); //anchor without the # character
return anchor2;
}
};
var util = new Contoso.Utils();
var anchor = util.getCurrentAnchor();
```The [prototype pattern](http://weblogs.asp.net/dwahlin/archive/2011/08/01/techniques-strategies-and-patterns-for-structuring-javascript-code-the-prototype-pattern.aspx) reminds the classic object oriented programming. Now, how would it look in the module pattern:
var Contoso = Contoso || {}; Contoso.Utils = function() { //private var invokeCounter = 0; var logInvokeCounter = function() { invokeCounter++; console.log(“invoked: " + invokeCounter + " times”); } //public return { getCurrentAnchor: function() { var url = window.location; var anchor=url.hash; //anchor with the # character var anchor2=url.hash.substring(1); //anchor without the # character logInvokeCounter(); return anchor2; } } }(); var anchor = Contoso.Utils.getCurrentAnchor();
Tag: String
javascript: show only a part of a long string (ellipsis)
Ellipsis (…) is a character which indicates that the content is to wide. There are many solutions to truncate the text and show an ellipsis: in javascript and css. I want to share my humble function which extends the String.prototype: [sourcecode language=“javascript”]String.prototype.ellipsize = function(maxLength) { maxLength = maxLength || 100; if (this.length <= maxLength) { return this; } var text = this.toString().replace(/[\r\n]/g, “”), max = maxLength, min = maxLength - 20, elipsized, tryExtract = function () { var regex = new RegExp("^.{" + min + “,” + max + “}\\s”), match = text.match(regex); if (match) { elipsized = match[0].replace(/\.?\s$/, ‘…’); } else { //well, there were no \s between min and max min = min - 20; tryExtract(); } }; if (min <= 0) { return text; } tryExtract(); return elipsized || text; };[/sourcecode] To use it, just call the function from a string property in your favorite templating engine: Angular, jsRender, Knockout….: [sourcecode language=“javascript”]order.description.ellipsize();[/sourcecode] This function takes an argument maxLength
(default 100 chars). It doesn’t cut your text in the middle of a word, that’s why it looks after a whitespace in range of maxLength-20 and maxLength.
Tag: 2012
2012 in review
The WordPress.com stats helper monkeys prepared a 2012 annual report for this blog.
Here’s an excerpt:
4,329 films were submitted to the 2012 Cannes Film Festival. This blog had 54,000 views in 2012. If each view were a film, this blog would power 12 Film Festivals
Click here to see the complete report.
Comments from Wordpress.com
Justin Cooney - Jan 3, 2013
Tag: Review
2012 in review
The WordPress.com stats helper monkeys prepared a 2012 annual report for this blog.
Here’s an excerpt:
4,329 films were submitted to the 2012 Cannes Film Festival. This blog had 54,000 views in 2012. If each view were a film, this blog would power 12 Film Festivals
Click here to see the complete report.
Comments from Wordpress.com
Justin Cooney - Jan 3, 2013
Tag: Copy
PowerShell: Copy an entire document library from SharePoint 2007 to disk
For a while ago I needed to copy all files from a document library within a SharePoint 2007 site to the hard drive. So I didn’t need to copy files from SharePoint to SharePoint so I couldn’t use the stsadm -o export command or Chris O’Brien’s nice SharePoint Content Deployment Wizard. I came across the SPIEFolder application which should work with SharePoint 2007 and 2010. It has a site on codeplex: spiefolder.codeplex.com, but neither the binary nor the source code can be downloaded from there. After some searching I found the binary in the author’s skydrive. The fact that the source code was not available seemed as an disanvantage because I could not know what code was run. Nevertheless I tried it out and it didn’t work:
Clone javascript objects
In javascript, if we copy objects or their properties, the reference still remains and by changing the new object the old one is changed, too. To clone or do a clean copy of an object I found a very useful solution by Jan Turoň on StackOverflow:
Object.prototype.clone = function() {
if(this.cloneNode) return this.cloneNode(true);
var copy = this instanceof Array ? \[\] : {};
for(var attr in this) {
if(typeof this\[attr\] == "function" || this\[attr\]==null || !this\[attr\].clone)
copy\[attr\] = this\[attr\];
else if(this\[attr\]==this) copy\[attr\] = copy;
else copy\[attr\] = this\[attr\].clone();
}
return copy;
}
Date.prototype.clone = function() {
var copy = new Date();
copy.setTime(this.getTime());
return copy;
}
Number.prototype.clone =
Boolean.prototype.clone =
String.prototype.clone = function() {
return this;
}
Tag: SPDocumentLibrary
PowerShell: Copy an entire document library from SharePoint 2007 to disk
For a while ago I needed to copy all files from a document library within a SharePoint 2007 site to the hard drive. So I didn’t need to copy files from SharePoint to SharePoint so I couldn’t use the stsadm -o export command or Chris O’Brien’s nice SharePoint Content Deployment Wizard. I came across the SPIEFolder application which should work with SharePoint 2007 and 2010. It has a site on codeplex: spiefolder.codeplex.com, but neither the binary nor the source code can be downloaded from there. After some searching I found the binary in the author’s skydrive. The fact that the source code was not available seemed as an disanvantage because I could not know what code was run. Nevertheless I tried it out and it didn’t work:
Tag: SPList
PowerShell: Copy an entire document library from SharePoint 2007 to disk
For a while ago I needed to copy all files from a document library within a SharePoint 2007 site to the hard drive. So I didn’t need to copy files from SharePoint to SharePoint so I couldn’t use the stsadm -o export command or Chris O’Brien’s nice SharePoint Content Deployment Wizard. I came across the SPIEFolder application which should work with SharePoint 2007 and 2010. It has a site on codeplex: spiefolder.codeplex.com, but neither the binary nor the source code can be downloaded from there. After some searching I found the binary in the author’s skydrive. The fact that the source code was not available seemed as an disanvantage because I could not know what code was run. Nevertheless I tried it out and it didn’t work:
Delete all list items with jsom
Today I needed to “clean” a list, meaning to remove all list items. For some time ago I wrote a post about different ways of removing list items in bulk: Server Object Model, SPLinq and RPC. This time I had only the web browser. So I tried the jsom way. By the way, the javascript documentation for jsom on msdn is getting really good. Don’t miss that: How to: Complete basic operations using JavaScript library code in SharePoint 2013. Now here comes theworking code I used to remove all items in my list:
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
Add Comments column to your sharepoint list
If you have used Issue tracking list template in SharePoint you must have marked that the comments are added and marked with author name and datetime. It is handy to have these micro “discussion boards” on items. The comment-formed communication can help to fine-tune task definitions. By the way, have you seen Trello? So the question is how we can create this column in other lists? Here is a little tutorial how to create “append-only comments”, as they are called:
ListUrl on EventReceiver
When you create an eventreceiver, you get the ListTemplateId attribute. It works fine. But if you want the eventreceiver to trigger on one particular list, just replace ListTemplateId attribute with ListUrl. For Pages you can use:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Receivers **ListUrl="$Resources:cmscore,List\_Pages\_UrlName;"**\>
<Receiver>
<Name>NewsPageEventReceiverItemUpdated</Name>
<Type>ItemUpdated</Type>
<Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
<Class>Contoso.EventReceivers.NewsPageEventReceiver.NewsPageEventReceiver</Class>
<SequenceNumber>1000</SequenceNumber>
</Receiver>
</Receivers>
</Elements>
TryGetList
How do we get a list? Perhaps like that:
var list = web.Lists\[listname"\];
```But we must be aware of exceptions that can appear and we must handle them. A better way to get a list is to use [TryGetList](http://sharepoint.stackexchange.com/questions/18035/custom-webpart-being-rendered-twice-on-layout-page):
var list = web.Lists.TryGetList(listname);
WithWeb-pattern of Jonas Nilsson
Jonas Nilsson shows an interesting approach for working with SPSite and SPWeb which must be disposed. Create a helper method WithWeb and send an Action parameter:
public void WithWeb(string uri, Action<SPWeb> action)
{
using (SPSite site = new SPSite(uri))
{
using (SPWeb web = site.OpenWeb())
{
action(web);
}
}
}
```Here is my implementation of this pattern:
public static class DisposalService { public static void WithWeb(string uri, Action action) { using (var site = new SPSite(uri)) { using (var web = site.OpenWeb()) { web.UnsafeUpdate(action); } } } public static void WithElevatedWeb(string uri, Action action) { SPSecurity.RunWithElevatedPrivileges(() => WithWeb(uri, action)); } }
Se om det är en tråd eller inlägg i diskussionsforum
Diskussioner sparas i en vanlig lista. En ny tråd sparas som en folder. Alla svar sparas som SPListItem i den foldern. En folder är så klart också en SPListItem, fast har en annan typ. För att se om det är en tråd, kan man jämföra ett fält som har ett guid som man kommer åt via SPBuiltInFieldId.FSObjType.
var item = properties.ListItem;
var type = Convert.ToInt32(item\[SPBuiltInFieldId.FSObjType\]);
var foldertype = (int) SPFileSystemObjectType.Folder;
if (type == foldertype)
{
//Yes, this is the thread head
var body = item\["Body"\].ToString();
}
AfterProperties kräver InternalName
AfterProperties kommer inte leda till Exception, men de kommer returnera bara null, om du använder DisplayName. Man måste ha InternalName. Här är ett litet exempel på hur man kan få ut värden före och efter uppdateringen. Exemplet har testats i ItemUpdated-eventreceiver.
var before = properties.BeforeProperties;
var after = properties.AfterProperties;
var contentDisplayName = "News Content";
var list = properties.List;
var contentInternalName = list.Fields\[contentDisplayName\].InternalName;
var contentBefore = before\[contentInternalName\];
var contentAfter = after\[contentInternalName\];
ID på befintliga kolumner
Det finns en fin lista över id på kolumner som man kan lägga till. Här är ett exempel hur man kan använda det. Här är ett exempel på två extra kolumner i contenttype:
<FieldRefs>
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
<!-- Enterprise Keywords-->
<FieldRef ID="{3de94b06-4120-41a5-b907-88773e493458}"/>
<!-- PublishingImage-->
</FieldRefs>
Interna fältnamn i SPList
Här är en väldigt bra lista över fältnamn, eller denna lista, till och med bättre i SPList, både Display Name, Internal Name och GUID. En annan bra länk är förklaringen om hur interna fältnamn är uppbyggda av Marc Anderson. För att se interna namnet kan man klicka på kolumnrubriken (för att sortera) så ser man det i URL:en. EDIT: den här tyckte jag mycket om.
Bläddra i Sharepoint från Android
Det finns en app som heter Quick Browser för Android från SPElements. Med den kan man bläddra i olika bibliotek och listor i en sharepoint direkt från mobilen. Mycket smidigt. Den aktuella versionen är 0.2.8. Den uppdateras rätt så ofta och blir bättre och bättre. Den enda nackdelen jag tycker är att man får alla element i ett bibliotek bara som en lista. Om det är image library så måste man long-klicka på ett element för att “download and view”. Mycket smidigare hade det varit om bilder visades i en Gallery.
Komma åt Title-kolumnen i SPList
Vad gör man om man vill lägga till Title-kolumnen till en ny vy? SPField fieldTitle = scheduleList.Fields["Title"];
Det kommer funka, men Title kommer vara bara text, utan en länk till SPListItem. Kolla på den koden: SPField fieldTitle = scheduleList.Fields[**SPBuiltInFieldId.LinkTitle**];
Här hämtar vi kolumnen som heter i Sharepoint “Title linked with item menu”. Det finns fler sådana “inbygda” kolumner.
Hämta schema från en befintlig SPList
Ibland är det så att man vill ha en speciell mall för en SPList, man har redan skapat en mall manuellt på sajten. Då är det enklaste sättet att hämta schema.xml och Windows SharePoint Services 3.0 Tools. När man installerat det så startar man Sharepoint Solution Generator 2008. Sedan måste man hitta sin lista, eller dokumentbiblioteket och exportera. Sedan är det bara att importera till sitt projekt i Visual Studio.
Ändra query på en SPView i koden
När man vill ändra hur data ska visas i en SPView i SPList, då måste man ändra CAML-Query. Det enklaste sättet att skapa en CAML Query är att använda ett program som heter CAML Query Builder. Ta bara bort och för att de behövs inte. Sedan är det bara att loopa igenom alla vyer man behöver.
private void UpdateQueryInGroupViews(SPList list)
{
for (int i = 1; i < 11; i++)
{
string viewname = String.Format("Group {0:D2}", i);
SPView view = list.Views\[viewname\];
string query =
String.Format(
"<Where><Or><Contains><FieldRef Name='Group' />"
+ "<Value Type='Text'>{0:D2}</Value></Contains>"
+ "<IsNull><FieldRef Name='Group' /></IsNull></Or></Where>"
+ "<OrderBy><FieldRef Name='EventDate' Ascending='True' />"
+ "</OrderBy>", i);
view.Query = query;
view.Update();
}
}
I denna query sorterar vi efter Start Date och visar bara händelser för sin grupp.
Radera en specifik sida i en site
Om man vill radera någon specifik sida som finns på flera siter, så måste man loopa igenom alla SPList objekt som finns i ett SPWeb objekt. På ett SPList som heter “Pages” ska man loopa igenom alla SPListItem och radera den som har Title som man är ute efter. Jag raderar alla sidor som heter “schedule.aspx”:
private void DeleteScheduleAspx(SPWeb web)
{
bool found = false;
foreach (SPList list in web.Lists)
{
if (list.Title.Equals("Pages")
&& list is SPDocumentLibrary)
{
foreach(SPListItem item in list.Items)
{
if(item.Name.Equals("schedule.aspx"))
{
item.Delete();
list.Update();
found = true;
break;
}
}
}
if (found)
{
break;
}
}
}
Tag: SPSite
PowerShell: Copy an entire document library from SharePoint 2007 to disk
For a while ago I needed to copy all files from a document library within a SharePoint 2007 site to the hard drive. So I didn’t need to copy files from SharePoint to SharePoint so I couldn’t use the stsadm -o export command or Chris O’Brien’s nice SharePoint Content Deployment Wizard. I came across the SPIEFolder application which should work with SharePoint 2007 and 2010. It has a site on codeplex: spiefolder.codeplex.com, but neither the binary nor the source code can be downloaded from there. After some searching I found the binary in the author’s skydrive. The fact that the source code was not available seemed as an disanvantage because I could not know what code was run. Nevertheless I tried it out and it didn’t work:
WithWeb-pattern of Jonas Nilsson
Jonas Nilsson shows an interesting approach for working with SPSite and SPWeb which must be disposed. Create a helper method WithWeb and send an Action parameter:
public void WithWeb(string uri, Action<SPWeb> action)
{
using (SPSite site = new SPSite(uri))
{
using (SPWeb web = site.OpenWeb())
{
action(web);
}
}
}
```Here is my implementation of this pattern:
public static class DisposalService { public static void WithWeb(string uri, Action action) { using (var site = new SPSite(uri)) { using (var web = site.OpenWeb()) { web.UnsafeUpdate(action); } } } public static void WithElevatedWeb(string uri, Action action) { SPSecurity.RunWithElevatedPrivileges(() => WithWeb(uri, action)); } }
Tag: SPWeb
PowerShell: Copy an entire document library from SharePoint 2007 to disk
For a while ago I needed to copy all files from a document library within a SharePoint 2007 site to the hard drive. So I didn’t need to copy files from SharePoint to SharePoint so I couldn’t use the stsadm -o export command or Chris O’Brien’s nice SharePoint Content Deployment Wizard. I came across the SPIEFolder application which should work with SharePoint 2007 and 2010. It has a site on codeplex: spiefolder.codeplex.com, but neither the binary nor the source code can be downloaded from there. After some searching I found the binary in the author’s skydrive. The fact that the source code was not available seemed as an disanvantage because I could not know what code was run. Nevertheless I tried it out and it didn’t work:
Add global navigation links in Powershell and Feature Receiver
I think, powershell is the best way to do configurations you have to do once. Adding some links to global (top) navigation is one of them:
asnp microsoft.sharepoint.powershell
$w = get-spweb http://takana
$l = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Smells like team spirit", "/pages/teamspirit.aspx")
$w.Navigation.TopNavigationBar.AddAsLast($l)
Feature receiver
The alternative is to create a web scoped feature and provide properties:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
var web = properties.Feature.Parent as SPWeb;
var prop = properties.Feature.Properties\["MyGlobalLinks"\];
var links = prop.Value.Split(new\[\] { ";#" },
StringSplitOptions.RemoveEmptyEntries);
foreach (var item in links)
{
var newLink = item.Split(new\[\] { ";" },
StringSplitOptions.RemoveEmptyEntries);
var newMenuItem =
new SPNavigationNode(newLink\[0\], newLink\[1\]);
web.Navigation.TopNavigationBar.AddAsLast(newMenuItem);
}
}
```This feature can be prefereably hidden. The properties are passed in onet:
NavBarLink
I found even a third way to add links to global navigation: NavBarLink
Working with web.Properties
Sometimes one may need more properties to track on a SPWeb beside Title and Description. One of the possibilities is to create a custom list (maybe a hidden one) with keys and values (Title and Value). It works fine. The good thing with it is also the possibility to change the key-value pair directly in the web interface. Another approach is to use web.Properties which is a Dictionary with key-values pairs. A simpler and neater solution: Here is a good motivation from the best sharepoint book Sharepoint as a Development Platform (p. 1043):
Do an unsafe update in a unified manner
Recently I talked about a WithWeb-pattern as described in Jonas Nilssons blog where you can isolate the disposal logic in one place. Another thing is to isolate unsafe updates:
public static class SPWebExtension
{
public static void UnsafeUpdate(this SPWeb web, Action<SPWeb> action)
{
try
{
Log.Info("Trying to do an unsafe update on a web: " + web.Title);
web.AllowUnsafeUpdates = true;
action(web);
}
catch (Exception e)
{
Log.Error(e);
}
finally
{
web.AllowUnsafeUpdates = false;
}
}
}
```The Log class is my own class which I presented in [my previous post](https://sharepointkunskap.wordpress.com/2011/09/19/a-simple-log/).
## Comments from Wordpress.com
####
[WithWeb-pattern of Jonas Nilsson « Sharepoint. Kunskap. Upptäckter på resan.](https://sharepointkunskap.wordpress.com/2011/09/15/withweb-pattern-of-jonas-nilsson/ "") - <time datetime="2011-09-21 17:28:23">Sep 3, 2011</time>
\[...\] Here I use another fancy way to consolidate the unsafe updates. \[...\]
<hr />
TryGetList
How do we get a list? Perhaps like that:
var list = web.Lists\[listname"\];
```But we must be aware of exceptions that can appear and we must handle them. A better way to get a list is to use [TryGetList](http://sharepoint.stackexchange.com/questions/18035/custom-webpart-being-rendered-twice-on-layout-page):
var list = web.Lists.TryGetList(listname);
WithWeb-pattern of Jonas Nilsson
Jonas Nilsson shows an interesting approach for working with SPSite and SPWeb which must be disposed. Create a helper method WithWeb and send an Action parameter:
public void WithWeb(string uri, Action<SPWeb> action)
{
using (SPSite site = new SPSite(uri))
{
using (SPWeb web = site.OpenWeb())
{
action(web);
}
}
}
```Here is my implementation of this pattern:
public static class DisposalService { public static void WithWeb(string uri, Action action) { using (var site = new SPSite(uri)) { using (var web = site.OpenWeb()) { web.UnsafeUpdate(action); } } } public static void WithElevatedWeb(string uri, Action action) { SPSecurity.RunWithElevatedPrivileges(() => WithWeb(uri, action)); } }
Uppdatera web med js
Här är ett litet exempel:
function updateTitle() {
var ctx = new SP.ClientContext.get\_current();
this.web = ctx.get\_web();
web.set\_title('Examensarbete 2011');
this.web.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onUpdate),
Function.createDelegate(this, this.onFail)); }
function onUpdate(sender, args) {
alert('title updated');
}
function onFail(sender, args) {
alert('failed to update title. Error:'+args.get\_message());
}
Ge andra rättigheter på default.aspx
Om man inte vill medlemmarna på SPWeb rättighet att redigera första sidan hur som helst, måste man bryta arvet på Sidor/default.aspx. Lätt att göra det manuellt (Site Actions - Show all Content - Pages - default.aspx - dokumenträttigheter). I koden kan man göra det så här:
//first find SPListItem defaultAspx
//then find SPGroup members (perhaps via web.AssociatedMemberGroup
defaultAspx.BreakRoleInheritance(true);
defaultAspx.RoleAssignments.RemoveFromCurrentScopeOnly(members);
SPRoleAssignment roles = new SPRoleAssignment(members);
SPRoleDefinition perms = web.RoleDefinitions.GetByType(SPRoleType.Reader);
roles.RoleDefinitionBindings.Add(perms);
defaultAspx.RoleAssignments.Add(roles);
~masterurl/default.master & ~masterurl/custom.master
Läser “SharePoint 2010 as a Development Platform”. Kan verkligen rekommendera den. Idag har jag förståt vad default.master och custom.master innebär. De pekar på de master-filer som är inställda på web-nivå. Så det är ingen idé att ändra DynamicMasterUrl i @Page-direktivet till sin egen (om du inte vill ha någon helt annan master än i resten av portalen).
Tag: App.config
Run web.config-dependant code in PowerShell
PowerShell is a great tool. It helps in SharePoint administration and tasks automation. Today I needed to provision a webpart on many similar pages. This third-party webpart’s constructor instantiates a dataaccess service and uses a connectionstring which is stored in the web.config file. So the webpart creation failed until I found a way to load the configuration into powershell. First you can create a simple file powershell.exe.config
, put it into $pshome
(C:\Windows\System32\WindowsPowerShell\v1.0). In that file you can specify the connectionstring in the same way like in the web.config (or app.config). But it is not secure: the connectionstring can be changed in the future, and you really don’t want to copy your connectionstrings around. So there is a better way: Check out Ohad Israeli’s blog post about how a configuration file can be bound dynamically in a .net assembly: Binding to a custom App.Config file. In PowerShell you can do the same, all we need is to modify the syntax: StackOverflow: Powershell Calling .NET Assembly that uses App.config:
Ändra properties i efterhand
Ibland ändras vissa variabler. Man vill så klart inte kompilera varje gång man ändrar ApplicationName eller connectionString. I mitt förra inlägg har jag visat hur man använder app.config, hur man lägger till ett värde och hur man hämtar det i programmet. Nu vill jag visa hur man ändrar det efter kompileringen. I mappen var projektet finns gå in på bin -> Debug. Där finns både .exe-filen och en fil som heter samma som .exe-filen fast har en filändelse .config. Om man bara kör .exe-filen eller om man inte har .config-filen så finns properties ändå, såklart. Fast då är de “inkompilerade”. Finns config-filen så är det bara att öppna i Notepad och ändra värden till de aktuella.
app.config
app.config kan användas till mycket. Här är ett litet exempel hur man använder den. Så kan app.config se ut:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ApplicationName" value="SharePoint - 80" />
</appSettings>
</configuration>
```Sedan i programmet måste vi importera:
using System.Configuration
appName = ConfigurationSettings .AppSettings[“ApplicationName”] .ToString();
## Comments from Wordpress.com
####
[Ändra properties i efterhand « Sharepoint. Huvudvärk och smärtstillande.](http://sharepointheadache.wordpress.com/2010/10/31/andra-properties-i-efterhand/ "") - <time datetime="2010-10-31 23:12:43">Oct 0, 2010</time>
\[...\] Man vill så klart inte kompilera varje gång man ändrar ApplicationName eller connectionString. I mitt förra inlägg har jag visat hur man använder app.config, hur man lägger till ett värde och hur man hämtar det \[...\]
<hr />
Tag: Configuration
Run web.config-dependant code in PowerShell
PowerShell is a great tool. It helps in SharePoint administration and tasks automation. Today I needed to provision a webpart on many similar pages. This third-party webpart’s constructor instantiates a dataaccess service and uses a connectionstring which is stored in the web.config file. So the webpart creation failed until I found a way to load the configuration into powershell. First you can create a simple file powershell.exe.config
, put it into $pshome
(C:\Windows\System32\WindowsPowerShell\v1.0). In that file you can specify the connectionstring in the same way like in the web.config (or app.config). But it is not secure: the connectionstring can be changed in the future, and you really don’t want to copy your connectionstrings around. So there is a better way: Check out Ohad Israeli’s blog post about how a configuration file can be bound dynamically in a .net assembly: Binding to a custom App.Config file. In PowerShell you can do the same, all we need is to modify the syntax: StackOverflow: Powershell Calling .NET Assembly that uses App.config:
Tag: ConnectionString
Run web.config-dependant code in PowerShell
PowerShell is a great tool. It helps in SharePoint administration and tasks automation. Today I needed to provision a webpart on many similar pages. This third-party webpart’s constructor instantiates a dataaccess service and uses a connectionstring which is stored in the web.config file. So the webpart creation failed until I found a way to load the configuration into powershell. First you can create a simple file powershell.exe.config
, put it into $pshome
(C:\Windows\System32\WindowsPowerShell\v1.0). In that file you can specify the connectionstring in the same way like in the web.config (or app.config). But it is not secure: the connectionstring can be changed in the future, and you really don’t want to copy your connectionstrings around. So there is a better way: Check out Ohad Israeli’s blog post about how a configuration file can be bound dynamically in a .net assembly: Binding to a custom App.Config file. In PowerShell you can do the same, all we need is to modify the syntax: StackOverflow: Powershell Calling .NET Assembly that uses App.config:
Tag: Database
Run web.config-dependant code in PowerShell
PowerShell is a great tool. It helps in SharePoint administration and tasks automation. Today I needed to provision a webpart on many similar pages. This third-party webpart’s constructor instantiates a dataaccess service and uses a connectionstring which is stored in the web.config file. So the webpart creation failed until I found a way to load the configuration into powershell. First you can create a simple file powershell.exe.config
, put it into $pshome
(C:\Windows\System32\WindowsPowerShell\v1.0). In that file you can specify the connectionstring in the same way like in the web.config (or app.config). But it is not secure: the connectionstring can be changed in the future, and you really don’t want to copy your connectionstrings around. So there is a better way: Check out Ohad Israeli’s blog post about how a configuration file can be bound dynamically in a .net assembly: Binding to a custom App.Config file. In PowerShell you can do the same, all we need is to modify the syntax: StackOverflow: Powershell Calling .NET Assembly that uses App.config:
Settings in Sharepoint_config database instead of appSettings
An alternative to store key-value paired properties in appSettings in web.config we can use Sharepoint_config database by creating our own SPPersistedObject. First we have to create a class which inherits from SPPersistedObject and decorate its properties with [Persisted]:
namespace Takana.SharePoint
{
public class Settings: SPPersistedObject
{
\[Persisted\]
public string DbConString;
public LinkCheckerPersistedSettings() { }
public LinkCheckerPersistedSettings(string name, SPPersistedObject parent) : base(name, parent) { }
}
}
```Then we must create such an object. Let's do it in Powershell:
if(-not(Get-PSSnapin | Where { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { Add-PSSnapin Microsoft.SharePoint.PowerShell }
Shrink sharepoint database
A Sharepoint Database can become big and have unused spaces. To shrink database go to CA-> Health Analyzer: http://takana:1337/Lists/HealthReports/AllItems.aspx See if there is a list item about unused space in db under the Availability. Click on Repair Automatically in the opened Modal Dialog:
MongoDB shell, learn directly in browser
Are you also curious about NoSQL databases. Well, MongoDB is one of the most known ones. MongoDB has a javascript syntax (json), I like it. Try out the interactive shell at the mongodb site.
Quickstart on Ubuntu
To test it on Ubuntu, just install an existing apt-package:
sudo apt-get install mongodb
Återskapa koppling till login i DB efter restore
Om du har kört restore på en databas, så kan det hända att det inte går att ändra rättigheter, och den login du använt inte kan se databasen. SQL Server spottar ut felmeddelandet med kod 15023:
The database is not accessible. (Object Explorer)
Om det är WebService som i sin tur anropar databasen, kan det komma ett sådant felmeddelande:
The underlying provider failed on Open.
Lösningen är att uppdatera kopplingen. Hämtat från denna blog.
Tag: Inetpub
Run web.config-dependant code in PowerShell
PowerShell is a great tool. It helps in SharePoint administration and tasks automation. Today I needed to provision a webpart on many similar pages. This third-party webpart’s constructor instantiates a dataaccess service and uses a connectionstring which is stored in the web.config file. So the webpart creation failed until I found a way to load the configuration into powershell. First you can create a simple file powershell.exe.config
, put it into $pshome
(C:\Windows\System32\WindowsPowerShell\v1.0). In that file you can specify the connectionstring in the same way like in the web.config (or app.config). But it is not secure: the connectionstring can be changed in the future, and you really don’t want to copy your connectionstrings around. So there is a better way: Check out Ohad Israeli’s blog post about how a configuration file can be bound dynamically in a .net assembly: Binding to a custom App.Config file. In PowerShell you can do the same, all we need is to modify the syntax: StackOverflow: Powershell Calling .NET Assembly that uses App.config:
Tag: Web.config
Run web.config-dependant code in PowerShell
PowerShell is a great tool. It helps in SharePoint administration and tasks automation. Today I needed to provision a webpart on many similar pages. This third-party webpart’s constructor instantiates a dataaccess service and uses a connectionstring which is stored in the web.config file. So the webpart creation failed until I found a way to load the configuration into powershell. First you can create a simple file powershell.exe.config
, put it into $pshome
(C:\Windows\System32\WindowsPowerShell\v1.0). In that file you can specify the connectionstring in the same way like in the web.config (or app.config). But it is not secure: the connectionstring can be changed in the future, and you really don’t want to copy your connectionstrings around. So there is a better way: Check out Ohad Israeli’s blog post about how a configuration file can be bound dynamically in a .net assembly: Binding to a custom App.Config file. In PowerShell you can do the same, all we need is to modify the syntax: StackOverflow: Powershell Calling .NET Assembly that uses App.config:
Settings in Sharepoint_config database instead of appSettings
An alternative to store key-value paired properties in appSettings in web.config we can use Sharepoint_config database by creating our own SPPersistedObject. First we have to create a class which inherits from SPPersistedObject and decorate its properties with [Persisted]:
namespace Takana.SharePoint
{
public class Settings: SPPersistedObject
{
\[Persisted\]
public string DbConString;
public LinkCheckerPersistedSettings() { }
public LinkCheckerPersistedSettings(string name, SPPersistedObject parent) : base(name, parent) { }
}
}
```Then we must create such an object. Let's do it in Powershell:
if(-not(Get-PSSnapin | Where { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { Add-PSSnapin Microsoft.SharePoint.PowerShell }
SPWebConfigModification
SPWebConfigModification. Some links to start with: http://panvega.wordpress.com/2009/09/02/using-spwebconfigmodification-within-a-feature-receiver/ http://www.onedotnetway.com/get-name-of-current-executing-assembly-in-c/ http://blogs.devhorizon.com/reza/?p=459 http://ikarstein.wordpress.com/2010/09/02/add-web-config-modification-with-powershell-spwebconfigmodification/ http://msdn.microsoft.com/en-us/library/bb861909.aspx
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
var webapp = parent as SPWebApplication;
if (webapp != null)
{
var mod1 = GetWebControlsConfigMod();
webapp.WebConfigModifications.Add(mod1);
var mod2 = GetConStringConfigMod();
webapp.WebConfigModifications.Add(mod2);
SaveChanges(webapp);
}
else
{
Log.Warning("no modifications to webapp are done");
}
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
var webapp = parent as SPWebApplication;
if (webapp != null)
{
var mod = GetWebControlsConfigMod();
var modsCollection = webapp.WebConfigModifications;
var modToDelete =
(from m in modsCollection
where m.Value.Equals(mod.Value, StringComparison.InvariantCultureIgnoreCase)
select m).FirstOrDefault();
if (modToDelete != null)
{
modsCollection.Remove(modToDelete);
SaveChanges(webapp);
}
}
}
private static void SaveChanges(SPPersistedObject webapp)
{
var service = webapp.Farm.Services.GetValue();
service.ApplyWebConfigModifications();
webapp.Update();
}
private static SPWebConfigModification GetWebControlsConfigMod()
{
var assembly = System.Reflection.Assembly.GetAssembly(typeof(WebControls.OfficeEditor));
var ass = assembly.FullName;
var @namespace = assembly.GetName().Name + ".WebControls";
var value = string.Format("", ass,
@namespace);
const string path = "configuration/SharePoint/SafeControls";
var mod = new SPWebConfigModification
{
Path = path,
Name = "JustaName1",
Sequence = 0,
Owner = @namespace,
Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
Value = value
};
return mod;
}
private static SPWebConfigModification GetConStringConfigMod()
{
const string name = "ContosoConString";
const string conString =
"Data Source=db.contoso.com;Initial Catalog=contoso\_db;Persist Security Info=True;User ID=contoso\_Contributor;Password=contoso";
var mod = new SPWebConfigModification
{
Name = "JustaName2",
Path = "configuration/connectionStrings",
Owner = "contoso\_connectionstrings",
Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
Value = String.Format("", name, conString)
};
return mod;
}
```Powershell:
#ADDING asnp microsoft.sharepoint.powershell $url = “http://contoso” $app = Get-SPWebApplication $url $name = “ContosoConString”; $conString = “Data Source=db.contoso.com;Initial Catalog=contoso_db;Persist Security Info=True;User ID=contoso_Contributor;Password=contoso”; $mod = new-object Microsoft.SharePoint.Administration.SPWebConfigModification $mod.Name = “JustName2” $mod.Path = “configuration/connectionStrings” $mod.Owner = “User Name” $mod.Type = 0 #for the enum value “SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode” $mod.Value = ‘’ -f $name, $conString $app.WebConfigModifications.Add($mod) $service = [Microsoft.SharePoint.Administration.SPWebService]::ContentService $service.ApplyWebConfigModifications() $app.Update() #ADDING snapin asnp microsoft.sharepoint.powershell
Tag: Hash
AngularJS: sync $location.search with an input value
I have used AngularJS for a while and to me this seems to be the best MVC javascript framework. Today I wanted to implement a search which uses an input and a hash query string like in google. The input value and url have to be synced like:
index.html#?term=something
To do this we have to inject $location
into our angular control. See the Angular Guide about $location. Then we have to observe both the $scope.term (which is bound to the input value) and $location.search().
Tag: Jslib
AngularJS: sync $location.search with an input value
I have used AngularJS for a while and to me this seems to be the best MVC javascript framework. Today I wanted to implement a search which uses an input and a hash query string like in google. The input value and url have to be synced like:
index.html#?term=something
To do this we have to inject $location
into our angular control. See the Angular Guide about $location. Then we have to observe both the $scope.term (which is bound to the input value) and $location.search().
Determine if Silverlight is installed (javascript)
For a while ago I needed to provide an alternative solution when Silverlight isn’t installed. I searched for javascript code for this and found this:
- A blog post about that: Piotr Puszkiewicz’s Silverlight Blog. Determining if Silverlight is installed using Javascript.
- A more advanced javascript function which can even determine the version of the Silerlight can be pulled from Silverlight.js library.
I didn’t need to determine the version of Silverlight, so I wrote a simplified js function (but it works in all browsers): [sourcecode language=“javascript”] var isSilverlightInstalled = function() { var installed = false; try { installed = !!navigator.plugins[“Silverlight Plug-In”] || !!(window.ActiveXObject && new ActiveXObject(‘AgControl.AgControl’)); } catch (e) {} return installed; };[/sourcecode] This function first checks if a Silverlight plugin is installed in almost all web browsers except IE, then if it is not it tries to create an ActiveXObject (IE) for Silverlight. If an error occurs, the function returns false and indicates that Silverlight is not available.
Masked Inputs
Just a quick tip today. If you are looking after masked inputs like the old ASP.NET Ajax Control Toolkit MaskedEdit, you can try jQuery plugin called Masked Input from DigitalBush or even better jquery.inputmask.
Tag: Silverlight
Determine if Silverlight is installed (javascript)
For a while ago I needed to provide an alternative solution when Silverlight isn’t installed. I searched for javascript code for this and found this:
- A blog post about that: Piotr Puszkiewicz’s Silverlight Blog. Determining if Silverlight is installed using Javascript.
- A more advanced javascript function which can even determine the version of the Silerlight can be pulled from Silverlight.js library.
I didn’t need to determine the version of Silverlight, so I wrote a simplified js function (but it works in all browsers): [sourcecode language=“javascript”] var isSilverlightInstalled = function() { var installed = false; try { installed = !!navigator.plugins[“Silverlight Plug-In”] || !!(window.ActiveXObject && new ActiveXObject(‘AgControl.AgControl’)); } catch (e) {} return installed; };[/sourcecode] This function first checks if a Silverlight plugin is installed in almost all web browsers except IE, then if it is not it tries to create an ActiveXObject (IE) for Silverlight. If an error occurs, the function returns false and indicates that Silverlight is not available.
Tag: SPListItem
Delete all list items with jsom
Today I needed to “clean” a list, meaning to remove all list items. For some time ago I wrote a post about different ways of removing list items in bulk: Server Object Model, SPLinq and RPC. This time I had only the web browser. So I tried the jsom way. By the way, the javascript documentation for jsom on msdn is getting really good. Don’t miss that: How to: Complete basic operations using JavaScript library code in SharePoint 2013. Now here comes theworking code I used to remove all items in my list:
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
ListUrl on EventReceiver
When you create an eventreceiver, you get the ListTemplateId attribute. It works fine. But if you want the eventreceiver to trigger on one particular list, just replace ListTemplateId attribute with ListUrl. For Pages you can use:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Receivers **ListUrl="$Resources:cmscore,List\_Pages\_UrlName;"**\>
<Receiver>
<Name>NewsPageEventReceiverItemUpdated</Name>
<Type>ItemUpdated</Type>
<Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
<Class>Contoso.EventReceivers.NewsPageEventReceiver.NewsPageEventReceiver</Class>
<SequenceNumber>1000</SequenceNumber>
</Receiver>
</Receivers>
</Elements>
Server Relative Url of an SPListItem
The easiest way to get the server relative url of an SPListItem is to retrieve the property “ServerUrl”.
SPListItem item...
var url = item\["ServerUrl"\];
Se om det är en tråd eller inlägg i diskussionsforum
Diskussioner sparas i en vanlig lista. En ny tråd sparas som en folder. Alla svar sparas som SPListItem i den foldern. En folder är så klart också en SPListItem, fast har en annan typ. För att se om det är en tråd, kan man jämföra ett fält som har ett guid som man kommer åt via SPBuiltInFieldId.FSObjType.
var item = properties.ListItem;
var type = Convert.ToInt32(item\[SPBuiltInFieldId.FSObjType\]);
var foldertype = (int) SPFileSystemObjectType.Folder;
if (type == foldertype)
{
//Yes, this is the thread head
var body = item\["Body"\].ToString();
}
AfterProperties kräver InternalName
AfterProperties kommer inte leda till Exception, men de kommer returnera bara null, om du använder DisplayName. Man måste ha InternalName. Här är ett litet exempel på hur man kan få ut värden före och efter uppdateringen. Exemplet har testats i ItemUpdated-eventreceiver.
var before = properties.BeforeProperties;
var after = properties.AfterProperties;
var contentDisplayName = "News Content";
var list = properties.List;
var contentInternalName = list.Fields\[contentDisplayName\].InternalName;
var contentBefore = before\[contentInternalName\];
var contentAfter = after\[contentInternalName\];
Interna fältnamn i SPList
Här är en väldigt bra lista över fältnamn, eller denna lista, till och med bättre i SPList, både Display Name, Internal Name och GUID. En annan bra länk är förklaringen om hur interna fältnamn är uppbyggda av Marc Anderson. För att se interna namnet kan man klicka på kolumnrubriken (för att sortera) så ser man det i URL:en. EDIT: den här tyckte jag mycket om.
Komma åt Title-kolumnen i SPList
Vad gör man om man vill lägga till Title-kolumnen till en ny vy? SPField fieldTitle = scheduleList.Fields["Title"];
Det kommer funka, men Title kommer vara bara text, utan en länk till SPListItem. Kolla på den koden: SPField fieldTitle = scheduleList.Fields[**SPBuiltInFieldId.LinkTitle**];
Här hämtar vi kolumnen som heter i Sharepoint “Title linked with item menu”. Det finns fler sådana “inbygda” kolumner.
Radera en specifik sida i en site
Om man vill radera någon specifik sida som finns på flera siter, så måste man loopa igenom alla SPList objekt som finns i ett SPWeb objekt. På ett SPList som heter “Pages” ska man loopa igenom alla SPListItem och radera den som har Title som man är ute efter. Jag raderar alla sidor som heter “schedule.aspx”:
private void DeleteScheduleAspx(SPWeb web)
{
bool found = false;
foreach (SPList list in web.Lists)
{
if (list.Title.Equals("Pages")
&& list is SPDocumentLibrary)
{
foreach(SPListItem item in list.Items)
{
if(item.Name.Equals("schedule.aspx"))
{
item.Delete();
list.Update();
found = true;
break;
}
}
}
if (found)
{
break;
}
}
}
Tag: Sharepoitn
TypeScript in SharePoint
By now TypeScript shouldn’t be something one has to introduce.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
If you haven’t already done it, go and see the intro video for TypeScript, check out a tutorial and visit the typescript playground. There are other javascript libraries which extend javascript and are compatible/compile to javascript: Dart and CoffeeScript. To be honest I had never time to try those. The fact that TypeScript is well integrated into Visual Studio which I happen to work within all the days (intellisense, compilation checks and more) did me curious. This post is actually not about TypeScript itself, but a test to use it in SharePoint. In this short “lab” I even had Web Essentials 2012 which automatically compile typescript files into plain javascript files on save. This is what I did: Install TypeScript and Web Essentials 2012 Create a SharePoint-hosted app: Create a new TypeScript file in the autogenerated “Scripts”-module and call it “Greeter.ts” Just save the file as it is. The new file is created: Greeter.js Now we don’t need to copy this file to the app, so remove Greeter.ts from the Elements.xml file (or comment it out): Open the Default.aspx from the Pages module and add the reference to the new javascript file:
javascript: developing for performance
Many words have been said about the importance of performance when working with javascript files. Here I want to summarize what developers can do to increase the performance related to javascript. I found many tips on blogs. Here comes my aggregated list of actions one can do to speed up sharepoint (and not only) sites with focus on javascript:
1. Load only sharepoint stuff you need
Use prefetch option to only load sharepoint javascript files that needed. To see the difference, just add ?prefetch=0
to your sharepoint url in the browser. The downside of this lazy loading is that you wrap all sharepoint related javascript into ExecuteOrDelayUntilScriptLoaded otherwise you maybe invoke some of javascript objects and functions that are not loaded. So the prize of this huge performance improvement is a high awareness by a developer when and which scripts are loaded and run.
Tag: Vs2012
TypeScript in SharePoint
By now TypeScript shouldn’t be something one has to introduce.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
If you haven’t already done it, go and see the intro video for TypeScript, check out a tutorial and visit the typescript playground. There are other javascript libraries which extend javascript and are compatible/compile to javascript: Dart and CoffeeScript. To be honest I had never time to try those. The fact that TypeScript is well integrated into Visual Studio which I happen to work within all the days (intellisense, compilation checks and more) did me curious. This post is actually not about TypeScript itself, but a test to use it in SharePoint. In this short “lab” I even had Web Essentials 2012 which automatically compile typescript files into plain javascript files on save. This is what I did: Install TypeScript and Web Essentials 2012 Create a SharePoint-hosted app: Create a new TypeScript file in the autogenerated “Scripts”-module and call it “Greeter.ts” Just save the file as it is. The new file is created: Greeter.js Now we don’t need to copy this file to the app, so remove Greeter.ts from the Elements.xml file (or comment it out): Open the Default.aspx from the Pages module and add the reference to the new javascript file:
.tfignore - ".gitignore" for TFS
I haven’t used TFS so much. But I like it so far. It works smoothly, both TFS 2012 (on premises) and TFS Preview (online). I really appreciate that Microsoft has been inspired from git - the world’s best VCS :). For example .tfignore which works exactly like the .gitignore file. It is nice that the non-classic Microsoft dot notation convention for naming the hidden files is chosen. So if you have any files to ignore just do it like you did in your git projects. Here is a .tfignore which I use in my SharePoint project for now. I suppose it will be extended soon:
The original Visual Web Part template is missing in Visual Studio 2012
Today I encountered a weird issue, the classic Visual Web Part template was gone in Visual Studio 2012. When I created a Visual WebPart, a webpart was created with a generated .g.cs file, like the sandboxed visual webparts. I am not exactly sure why it happened. According to the MSDN guide Creating Web Parts for SharePoint, the structure of Visual Webparts should be the same as in Visual Studio 2010. It could have happened after I installed the power tools. However, if someone runs into the same issue, here is the solution: Copy this zip file from a computer with VS2010 installed:
Develop for SharePoint on Windows 8
Do you like Windows 8 user expirience, as me? Well than you want to try developing sharepoint solutions in Windows 8. Here I will show what I found out.
Environment
I installed Windows 8 Release Preview as a VMWare machine. Then I installed Visual Studio 2012 RC. Then I followed the steps for installing SharePoint on Windows 8 which are more or less the same as for Windows 7 client install. But then I encountered an error I haven’t found solution for yet. In my standalone sharepoint installation there were some permission problems:
Tag: Geolocation
GeoLocation Field in SharePoint 2013
In SharePoint 2013 Preview there is a new type of field: GeoLocation which is, like the old SPUrlField, a pair of values. The geolocation is described as longitude and latitude. Unfortunately you can’t add this field in list settings. You have to create this in code. In the provided link you can find the code C# code which uses the Client Object Model. In another link you can find an example how to create the geolocation file using Server Object Model (in FeatureActivated EventReceiver). If you know me, you might already know that I will propose a JavaScript solution. Here is the code to create a geolocation field in an existing list using JSOM:
Tag: Callout
Callouts in SharePoint 2013 Preview
While ModalDialog is not default for editing list items in SharePoint 2013 Preview, there is a new “popup” element in SharePoint - callout or popover. I would like to recommend these two blogs when you want discover more: Andrey Markeev: Callouts (popovers) в SharePoint 2013 Preview (in Russian) Alex Boev: a three part series: 1. Custom Callouts in the SharePoint 2013 Metro UI: Part 1: Basics 2. Custom Callouts in the SharePoint 2013 Metro UI, Part 2: Actions 3. Custom Callouts in the SharePoint 2013 Metro UI, Part 3: CalloutManager To get introduced with callouts in SharePoint 2013, you can run this code (from Andrey Markeev’s blog):
Tag: Popover
Callouts in SharePoint 2013 Preview
While ModalDialog is not default for editing list items in SharePoint 2013 Preview, there is a new “popup” element in SharePoint - callout or popover. I would like to recommend these two blogs when you want discover more: Andrey Markeev: Callouts (popovers) в SharePoint 2013 Preview (in Russian) Alex Boev: a three part series: 1. Custom Callouts in the SharePoint 2013 Metro UI: Part 1: Basics 2. Custom Callouts in the SharePoint 2013 Metro UI, Part 2: Actions 3. Custom Callouts in the SharePoint 2013 Metro UI, Part 3: CalloutManager To get introduced with callouts in SharePoint 2013, you can run this code (from Andrey Markeev’s blog):
Tag: Popup
Callouts in SharePoint 2013 Preview
While ModalDialog is not default for editing list items in SharePoint 2013 Preview, there is a new “popup” element in SharePoint - callout or popover. I would like to recommend these two blogs when you want discover more: Andrey Markeev: Callouts (popovers) в SharePoint 2013 Preview (in Russian) Alex Boev: a three part series: 1. Custom Callouts in the SharePoint 2013 Metro UI: Part 1: Basics 2. Custom Callouts in the SharePoint 2013 Metro UI, Part 2: Actions 3. Custom Callouts in the SharePoint 2013 Metro UI, Part 3: CalloutManager To get introduced with callouts in SharePoint 2013, you can run this code (from Andrey Markeev’s blog):
Using javascript objects passed from closed popup
It is not a rocket science to pass objects from child window (popup) to main window. The problem I encountered today was IE and passing complex objects. So it is just an IE issue as far as I know. The problem occurs when you pass some object (not a simple String or Number) to main window:
window.opener.takeAnObjectFromChild = {
title: "Should even be available when I close the child"
};
and you then close the child window, next time the main window tries to access the passed object:
javascript: passing arguments from popup to main window
To show a popup, we just have to invoke “window.open”, and provide some options to prevent opening this in a new tab:
var wnd = window.open('', '\_blank', 'width=750, height=400, location=no, resizable=1, menubar=0, scrollbars=0');
wnd.document.write('');
wnd.document.close(); wnd.document.close(); wnd.focus();
To communicate between parent and child we can refer to parent as window.opener. We can even invoke a function from parent window. Let’s create the most useful function:
Visa en popup-ruta
Visst är det fint med en formulär eller ruta som dyker upp medan ursprungssidan blir mörklagd. I grunden så ändras opacity på hela sidan, blir mörkare. En iframe med högre z-index dyker upp. I den iframe finns en annan sida. Hur gör man för att ta fram den rutan? Här berättar jag lite om det:
Tag: Gitignore
.tfignore - ".gitignore" for TFS
I haven’t used TFS so much. But I like it so far. It works smoothly, both TFS 2012 (on premises) and TFS Preview (online). I really appreciate that Microsoft has been inspired from git - the world’s best VCS :). For example .tfignore which works exactly like the .gitignore file. It is nice that the non-classic Microsoft dot notation convention for naming the hidden files is chosen. So if you have any files to ignore just do it like you did in your git projects. Here is a .tfignore which I use in my SharePoint project for now. I suppose it will be extended soon:
.gitignore for android
.gitignore is very important. This file tells git which files not to care about. I found a good template for android .gitignore: .metadata tmp/** .DS_Store *.tmp *.bak tmp/**/* *.swp *~.nib Thumbs.db Desktop.ini *~ *.apk bin gen local.properties *.jar **.classpath**
The only thing I have added is the last row: .classpath.
Comments from Wordpress.com
J. Pablo Fernández - Apr 2, 2011
Tag: Tfignore
.tfignore - ".gitignore" for TFS
I haven’t used TFS so much. But I like it so far. It works smoothly, both TFS 2012 (on premises) and TFS Preview (online). I really appreciate that Microsoft has been inspired from git - the world’s best VCS :). For example .tfignore which works exactly like the .gitignore file. It is nice that the non-classic Microsoft dot notation convention for naming the hidden files is chosen. So if you have any files to ignore just do it like you did in your git projects. Here is a .tfignore which I use in my SharePoint project for now. I suppose it will be extended soon:
Tag: Tfs
.tfignore - ".gitignore" for TFS
I haven’t used TFS so much. But I like it so far. It works smoothly, both TFS 2012 (on premises) and TFS Preview (online). I really appreciate that Microsoft has been inspired from git - the world’s best VCS :). For example .tfignore which works exactly like the .gitignore file. It is nice that the non-classic Microsoft dot notation convention for naming the hidden files is chosen. So if you have any files to ignore just do it like you did in your git projects. Here is a .tfignore which I use in my SharePoint project for now. I suppose it will be extended soon:
Team Explorer
Until now I have only worked with svn and git. So I am very curious about the Team Foundation Server and Team Explorer which all talk much about. The best thing is the integration with the issue tracking. I can see all work item, or just my work items. Another fine feature, at leat if you use codeplex, is the Team Explorer Everywhere.
The Team Explorer Everywhere client works on Windows, Linux, Mac, or Solaris. It provides a command line client and plug-in for Eclipse to access Team Foundation Server. For information on obtaining the client and connecting to the Team Foundation Server please read the Team Explorer Everywhere Client wiki page. You will need the information on the right to connect to the Team Foundation Server in Team Explorer Everywhere.
Tag: Input
Masked Inputs
Just a quick tip today. If you are looking after masked inputs like the old ASP.NET Ajax Control Toolkit MaskedEdit, you can try jQuery plugin called Masked Input from DigitalBush or even better jquery.inputmask.
Tag: Mask
Masked Inputs
Just a quick tip today. If you are looking after masked inputs like the old ASP.NET Ajax Control Toolkit MaskedEdit, you can try jQuery plugin called Masked Input from DigitalBush or even better jquery.inputmask.
Tag: Module
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
javascript: Umbrella pattern
There are two great patterns for organizing javascript code: Prototype and Module pattern. More about them later in this post. But in reality I still see much of spagghetti Just an example: SharePoint 101 code samples. They are indeed very simple and isolated examples. And many projects use this simple way in mind when they begin. But when javascript code grows, it becomes a monster. Have you seen this biest? How is this monster created? Through good intentions (like everything else) in form of KISS mantra, to little time and the “commit and run”-behavior, or the worst: “I am c#-er, not Front-End-Developer”-spirit. In this post I’ll introduce a kind of compromise the Umbrella pattern. But before that, let’s see how to recognize the spagghetti monster in javascript:
javascript Module pattern
Want organize your js code in a kind of namespaces, or modules, then use the module pattern. I’ll take the dummy example for getting the current anchor. Let’s look how it would be if the prototype based approach is used:
var Contoso.Utils = function() {};
Contoso.Utils.prototype = {
getCurrentAnchor: function() {
var url = window.location;
var anchor=url.hash; //anchor with the # character
var anchor2=url.hash.substring(1); //anchor without the # character
return anchor2;
}
};
var util = new Contoso.Utils();
var anchor = util.getCurrentAnchor();
```The [prototype pattern](http://weblogs.asp.net/dwahlin/archive/2011/08/01/techniques-strategies-and-patterns-for-structuring-javascript-code-the-prototype-pattern.aspx) reminds the classic object oriented programming. Now, how would it look in the module pattern:
var Contoso = Contoso || {}; Contoso.Utils = function() { //private var invokeCounter = 0; var logInvokeCounter = function() { invokeCounter++; console.log(“invoked: " + invokeCounter + " times”); } //public return { getCurrentAnchor: function() { var url = window.location; var anchor=url.hash; //anchor with the # character var anchor2=url.hash.substring(1); //anchor without the # character logInvokeCounter(); return anchor2; } } }(); var anchor = Contoso.Utils.getCurrentAnchor();
Tag: Paging
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
Tag: Patterns
Paging with JSOM
If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model - Resources and Real World Examples posted by David Mann and published on Aptilon Blog. There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition() I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:
Singleton vs static
Have you wondered what to use a singleton object or a class with static methods. Well, here is an awesome comparision of these techniques. Static methods and classes are easy to use, but you can’t them as objects, implement interfaces and have constructors with parameters.
Tag: Less
Simplify js and css development with Web Essentials (Visual Studio Extension)
If you develop much javascript and css, this is the exension to Visual Studio you just can’t live without: Web Essentials (It is even released for VS2012). You can do many things with it. Here are two examples for simple but very useful functions: 1. Show which browsers support a css attribute: 2. Collapse javascript functions and create #region areas like in C# code: There is much more, like less and coffeescript parsing. Just check the documentation. And it is fully appliable in SharePoint development.
Tag: Web Essentials
Simplify js and css development with Web Essentials (Visual Studio Extension)
If you develop much javascript and css, this is the exension to Visual Studio you just can’t live without: Web Essentials (It is even released for VS2012). You can do many things with it. Here are two examples for simple but very useful functions: 1. Show which browsers support a css attribute: 2. Collapse javascript functions and create #region areas like in C# code: There is much more, like less and coffeescript parsing. Just check the documentation. And it is fully appliable in SharePoint development.
Tag: Libraries
Toastr.js and SharePoint
Have you used SharePoint javascript Notifications (SP.UI.Notify)? Are you looking for something new and fresh? Well then check out the Toastr.js - a simple, beautiful, fully responsive and light-weight javascript lib for notifications, developed by John Papa and Hans Fjällemark and released under the MIT License. By the way, toastr was one of many things I discovered and learned on John Papa’s online course by pluralsight: Single Page Apps with HTML5, Web API, Knockout and jQuery. It is a really awesome course, where you learn how to create an amazing SPA. Well, how’s about SharePoint. While whatching the course videos about toastr, I thought: Can we use it in SharePoint? Yes we can! Just load the toastr css and js and start using it:
JSOM: Last Modified Date of a List
The data transfer between server and client can heavily affect the performance. One of the measures to reduce the amount data transferred from the server to the client is storing data on the client. In many modern browsers we can use html5 localStorage. Even in older browsers there are ways to store data. I would recommend a nice js lib called amplify.js. The interface is much easier, then:
amplify.store("key", { title: "value" });
```It comes in nicely, if we have much data which we get with JSOM. But we have to care about eventual changes to list items done after we got them the last time. So we have to store the [last modified date](http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.lastitemmodifieddate.aspx). This property is also available in JSOM:
var ctx = SP.ClientContext.get_current(); var web = ctx.get_web(); var lists = web.get_lists(); var list = lists.getByTitle(“Tasks”); ctx.load(list, “LastItemModifiedDate”); ctx.executeQueryAsync( function() { var lastmodified = list.get_lastItemModifiedDate(); }, function() {} );
Version 0.2.2: Added libraries
Libraries are now present on the LUSites map. The list of Lund University Libraries was taken from the official site. Committed on Github, but not published on Market. Here is the coordinates of the libraries, their addresses and the CSV-file which is located in /res/raw/libraries_utf8.csv in the LUSites project. Archaeological Library Visiting address: Sandgatan 1 Telephone: 046 2223187, HS: 24 (55.70594904569557, 13.19543570280075) Architecture and Design, Library Visiting address: Sölvegatan 39 Building: Kemicentrum, floor: 1 Telephone: 046 2227244, HS: 2 (55.71589492312098, 13.210244178771973) Art Academy Library, Malmö Visiting address: Föreningsgatan 42 Telephone: 040 325722, HS: 45 Asia Library Visiting address: Scheelevägen 15 B Telephone: 046 222 3043, HS: 61 (55.71405764996187, 13.214406967163086) Astronomy, Libr. Visiting address: Sölvegatan 27 Building: Astronomihuset, floor: 2 Telephone: 046 222 7304, HS: 25 (55.71171258368761, 13.204450607299805) Biology Library Visiting address: Sölvegatan 37 Building: Ekologihuset, floor: Bottenpl Telephone: 046 222 3812, HS: 50 (55.71420995359545, 13.20809125812957) Campus Helsingborg, Libr. Visiting address: Universitetsplatsen 2 Building: C, floor: 2 Telephone: 042 356580 Chemistry and Chemical Engineering, Libr. Visiting address: Sölvegatan 39 Telephone: 046 2228339, HS: 1 (55.71594327124769, 13.21033000946045) Civil Engineering Library Visiting address: John Ericssons Väg 1 Building: V-huset, floor: Entré Telephone: 046 2227937, HS: 3 (55.71258293399021, 13.211137354373932) Geolibrary Visiting address: Sölvegatan 12 Building: Geocentrum II Telephone: 046 222 39 60, HS: 16 (55.709346220780546, 13.201250731945038) History, Libr. Visiting address: Magle stora kyrkogata 12 A Telephone: 046 222 79 47, HS: 23 (55.702935467932335, 13.198925256729126) Languages and Literature, Libr. Visiting address: Helgonabacken 12 Telephone: 046 222 32 20, HS: 20 (55.70907723814732, 13.199536800384521) Law Library Visiting address: Lilla Gråbrödersgatan 4 Telephone: 046 2221007, HS: 56 (55.7052478126403, 13.19107174873352) Library of the E-huset, LTH Visiting address: Ole Römers Väg 3 Building: E-huset, floor: entré Telephone: 046 2220477, HS: 7 (55.71109607382483, 13.210394382476807) LTHs Studiecentrum Visiting address: John Ericssonsväg 4 Telephone: 046 2224825, HS: 8 (55.71152521407211, 13.209450244903564) Lund University Libraries, Head Office Visiting address: Tornavägen 9 A,B Building: Tegelstenen, floor: 1 och 3 Telephone: 046 222 00 00, HS: 51 (55.70848486536929, 13.208152055740356) Mathematics, Libr. Visiting address: Sölvegatan 18 Building: Matematikhuset, floor: 2 Telephone: 046 222 74 89, HS: 6 (55.71076968231173, 13.20681095123291) Medical Faculty Library at Vårdvetenskapens hus, Lund Visiting address: Baravägen 3 Building: Health Sciences Centre, floor: plan 2 Telephone: 046 222 18 00, HS: 65 (55.71724260473777, 13.193110227584839) Medical Library at UsiL, Lund Visiting address: Getingevägen 4 Building: Universitetssjukhuset, Centralblocket, floor: plan 1 Telephone: 046 222 18 55, HS: 32 (55.71244996505999, 13.196607828140259) Medical Library in CRC, Malmö Visiting address: Ingång 72 Univeristetssjukhuset MAS, UMAS Building: Clinical Research Centre, CRC, floor: entrevån Telephone: 040 39 15 00, HS: 33 Music Library, Malmö Visiting address: Ystadvägen 25 Telephone: 040 325446, HS: 42 Philosophy, Libr. Visiting address: Kungshuset Telephone: 046 2223675, HS: 30 (55.706012518756204, 13.19507360458374) Physics, Libr. Visiting address: Professorsgatan 1 Building: Fysicum Hus H, floor: Entré Telephone: 046 2227779, HS: 14 (55.71031031185903, 13.204643726348877) Political Science Library Visiting address: Paradisgatan 5 Building: Hus H; Eden, floor: 2 Telephone: 046 222 36 91, HS: 35 (55.70677418744201, 13.194794654846191) Raoul Wallenberg Institute Library Visiting address: Lilla Gråbrödersgatan 3 B Telephone: 046 2221215, 2221230, HS: 56 (55.705216075501774, 13.191157579421997) School of Economics and Management Library Visiting address: Tycho Brahes väg 1 Building: Holger Crafoords Ekonomicentrum 1, floor: 1 Telephone: 046 2229445, HS: 10 (55.709627290542365, 13.212937116622925) Social and behavioural Sciences, Libr. Visiting address: Allhelgona kyrkogata 14 Building: hus J Telephone: 046 2220990, HS: 31 (55.708493932367254, 13.194451332092285) The IIIEE Library Visiting address: Tegnérsplatsen 4 Telephone: 046 222 02 38, HS: 53 (55.704229188760834, 13.195728063583374) Theology and Religious studies, Libr. Visiting address: Allhelgona Kyrkogata 8 Telephone: 046 222 90 39, HS: 36 (55.70868433883831, 13.194515705108643) Theoretical Physics Library Visiting address: Sölvegatan 14A Building: Fysicum Hus K, floor: 200 Telephone: 046 2220432 / 2227779, HS: 14A (55.710902656961046, 13.203780055046082) University Library Visiting address: Helgonabacken 1 Telephone: 046 222 00 00, HS: 19 (55.709059104420014, 13.197294473648071) Wrangel, Libr. Visiting address: Biskopsgatan 5 Building: Wrangel, floor: 1 Telephone: 046 222 33 52, HS: 59 (55.706695603264485, 13.199906945228577) /res/raw/libraries_utf8.csv: 13.19543570280075,55.70594904569557,"Archaeological Library","Sandgatan 1, Telephone: 046 2223187" 13.210244178771973,55.71589492312098,"Architecture and Design, Library","Sölvegatan 39, Building: Kemicentrum, floor: 1" 13.214406967163086,55.71405764996187,"Asia Library","Scheelevägen 15 B, Telephone: 046 222 3043" 13.204450607299805,55.71171258368761,"Astronomy Library","Sölvegatan 27, Building: Astronomihuset, floor: 2, Telephone: 046 222 7304" 13.20809125812957,55.71420995359545,"Biology Library","Sölvegatan 37, Building: Ekologihuset, floor: Bottenpl, Telephone: 046 222 3812" 13.21033000946045,55.71594327124769,"Chemistry and Chemical Engineering Library","Sölvegatan 39, Telephone: 046 2228339" 13.211137354373932,55.71258293399021,"Civil Engineering Library","John Ericssons Väg 1, Building: V-huset, floor: Entré, Telephone: 046 2227937" 13.201250731945038,55.709346220780546,"Geolibrary","Sölvegatan 12, Building: Geocentrum II, Telephone: 046 222 39 60" 13.198925256729126,55.702935467932335,"History Library","Magle stora kyrkogata 12 A, Telephone: 046 222 79 47" 13.199536800384521,55.70907723814732,"Languages and Literature Library","Helgonabacken 12, Telephone: 046 222 32 20" 13.19107174873352,55.7052478126403,"Law Library","Lilla Gråbrödersgatan 4, Telephone: 046 2221007" 13.210394382476807,55.71109607382483,"Library of the E-huset, LTH","Ole Römers Väg 3, Building: E-huset, floor: entré, Telephone: 046 2220477" 13.209450244903564,55.71152521407211,"LTHs Studiecentrum","John Ericssonsväg 4, Telephone: 046 2224825" 13.208152055740356,55.70848486536929,"Lund University Libraries, Head Office","Tornavägen 9 A,B. Building: Tegelstenen, floor: 1 och 3. Telephone: 046 222 00 00" 13.20681095123291,55.71076968231173,"Mathematics Library","Sölvegatan 18. Building: Matematikhuset, floor: 2. Telephone: 046 222 74 89" 13.193110227584839,55.71724260473777,"Medical Faculty Library at Vårdvetenskapens hus","Baravägen 3. Building: Health Sciences Centre, floor: plan 2. Telephone: 046 222 18 00" 13.196607828140259,55.71244996505999,"Medical Library at UsiL","Getingevägen 4. Building: Universitetssjukhuset, Centralblocket, floor: plan 1. Telephone: 046 222 18 55" 13.19507360458374,55.706012518756204,"Philosophy Library","Kungshuset, Lundagård. Telephone: 046 2223675" 13.204643726348877,55.71031031185903,"Physics Library","Professorsgatan 1. Building: Fysicum Hus H, floor: Entré. Telephone: 046 2227779" 13.194794654846191,55.70677418744201,"Political Science Library","Paradisgatan 5. Building: Hus H; Eden, floor: 2. Telephone: 046 222 36 91" 13.191157579421997,55.705216075501774,"Raoul Wallenberg Institute Library","Lilla Gråbrödersgatan 3 B. Telephone: 046 2221215, 046 2221230" 13.212937116622925,55.709627290542365,"School of Economics and Management Library","Tycho Brahes väg 1. Building: Holger Crafoords Ekonomicentrum 1, floor: 1. Telephone: 046 2229445" 13.194451332092285,55.708493932367254,"Social and behavioural Sciences Library","Allhelgona kyrkogata 14. Building: hus J. Telephone: 046 2220990" 13.195728063583374,55.704229188760834,"The IIIEE Library","Tegnérsplatsen 4. Telephone: 046 222 02 38" 13.194515705108643,55.70868433883831,"Theology and Religious studies Library","Allhelgona Kyrkogata 8. Telephone: 046 222 90 39" 13.203780055046082,55.710902656961046,"Theoretical Physics Library","Sölvegatan 14A Building: Fysicum Hus K, floor: 200. Telephone: 046 2220432 / 2227779" 13.197294473648071,55.709059104420014,"University Library","Helgonabacken 1. Telephone: 046 222 00 00" 13.199906945228577,55.706695603264485,"Wrangel Library","Biskopsgatan 5. Building: Wrangel, floor: 1. Telephone: 046 222 33 52"
Tag: Notification
Toastr.js and SharePoint
Have you used SharePoint javascript Notifications (SP.UI.Notify)? Are you looking for something new and fresh? Well then check out the Toastr.js - a simple, beautiful, fully responsive and light-weight javascript lib for notifications, developed by John Papa and Hans Fjällemark and released under the MIT License. By the way, toastr was one of many things I discovered and learned on John Papa’s online course by pluralsight: Single Page Apps with HTML5, Web API, Knockout and jQuery. It is a really awesome course, where you learn how to create an amazing SPA. Well, how’s about SharePoint. While whatching the course videos about toastr, I thought: Can we use it in SharePoint? Yes we can! Just load the toastr css and js and start using it:
SP.UI.Notify in Modal Dialog
If you open a custom page (not a list item form) in a modal dialog, your notification won’t be shown. The reason is that the notification area (#notificationArea) is inside a hidden div (#s4-ribbonrow). To show this notificationArea we must display the notification area:
var $ribbon = jQuery("#s4-ribbonrow");
if ($ribbon.is(":hidden")) {
$ribbon.css({"min-height": 0, "height": "0px"})
.show().children().hide()
.filter("#notificationArea").show()
}
Comments from Wordpress.com
Jens Malmberg - Jan 3, 2013
Loading notification
When you load some data with ajax, you will probably want to show the users in some way, that data is loading. To show the text “loading…” would be enough. Another, very common way to do it to show a spinner, a rotating image. In sharepoint we can use the built-in gif which can be found in /_layouts/images/loading16.gif. Well, it is actually not so good, because this image is not so beautiful. A better way is to create your own gif image which is exactly suited for our needs. Or even better: don’t use any images. Use the light-weight javascript library called spin.js for creating spinners. It is fully customizable, compatible with older browsers. You can customize it interactively on the spin.js homepage.
Tag: Contenttype
JSOM: Alter a column's ShowInDisplayForm property
When you create a content type, you can define if your fields will be shown in DisplayForm, EditForm, NewForm. You can hide or show them, just as Yaroslav Pentsarsky says. If your list is already provisioned, you can change them with Server Object Model, why not in PowerShell: Technet: Setting ShowInDisplayForm, ShowInEditForm, ShowInNewForm properties with powershell. If you don’t have access to the server, then the same can be done with JSOM. Here is the code:
Content Type Id for Image, Audio and Video
After debugging I have found the Content Type Ids for Image, Audio and Video in the assets library. These content type ids are not present in SPBuiltInContentTypeId.
public class SPBuiltInContentTypeIdExtension
{
public static SPContentTypeId Video =
new SPContentTypeId
("0x0101009148F5A04DDD49CBA7127AADA5FB792B00291D173ECE694D56B19D111489C4369D");
public static SPContentTypeId Audio =
new SPContentTypeId
("0x0101009148F5A04DDD49CBA7127AADA5FB792B006973ACD696DC4858A76371B2FB2F439A");
public static SPContentTypeId Image =
new SPContentTypeId
("0x0101009148F5A04DDD49CBA7127AADA5FB792B00AADE34325A8B49CDA8BB4DB53328F214");
}
These three asset content types inherit from Document CT (“0x0101”) and have “0x0101009148F5A04DDD49CBA7127AADA5FB792B” in common, which is the content type id for multimedia content type. So if you want to check if it is a multimedia, use this id. You can see the content type id when you go to Site Actions - Site Settings - Content Types. Click on a content type you interested in. In the address bar of your browser find ?ctype=.
Videokurs om Web Content Management
På microsoft.com finns en ny videokurs om web content management. Där kan du lära dig om hur man implementerar cms-funktionalitet med sharepoint, bl.a.: content types, page layouts med mera. Tack för tipset, deutschsprachige Sharepoint-Community.
Lägga till Företagsnyckelord
Det är enkelt att lägga till kolumnen företagsnyckelord. Skapa egen contenttype och lägg till fieldref.
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
Funkar utmärkt t.ex. om du ärver ContentTypen från Announcements. Lite svårare är det med Dokument. I själva verket läggs till fler kolumner för att det ska fungera. I Announcements finns de redan. Men i dokument måste du lägga till dem extra:
<!-- Enterprise Keywords-->
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
<!-- in order keywords to work, two additional fields have to be created-->
<!-- TaxKeywordTaxHTField -->
<FieldRef ID="{1390a86a-23da-45f0-8efe-ef36edadfb39}"/>
<!-- TaxCatchAll -->
<FieldRef ID="{f3b0adf9-c1a2-4b02-920d-943fba4b3611}"/>
Utan TaxKeywordTaxHTField uppstår fel av typen: “Kan inte hämta värdet från kolumnen {00000000…}”.
Tag: SPField
JSOM: Alter a column's ShowInDisplayForm property
When you create a content type, you can define if your fields will be shown in DisplayForm, EditForm, NewForm. You can hide or show them, just as Yaroslav Pentsarsky says. If your list is already provisioned, you can change them with Server Object Model, why not in PowerShell: Technet: Setting ShowInDisplayForm, ShowInEditForm, ShowInNewForm properties with powershell. If you don’t have access to the server, then the same can be done with JSOM. Here is the code:
AfterProperties kräver InternalName
AfterProperties kommer inte leda till Exception, men de kommer returnera bara null, om du använder DisplayName. Man måste ha InternalName. Här är ett litet exempel på hur man kan få ut värden före och efter uppdateringen. Exemplet har testats i ItemUpdated-eventreceiver.
var before = properties.BeforeProperties;
var after = properties.AfterProperties;
var contentDisplayName = "News Content";
var list = properties.List;
var contentInternalName = list.Fields\[contentDisplayName\].InternalName;
var contentBefore = before\[contentInternalName\];
var contentAfter = after\[contentInternalName\];
field type
Här är en hel lista över olika typer som Field kan få i Content Type. Type=“File” motsvarar SPFieldFile
ID på befintliga kolumner
Det finns en fin lista över id på kolumner som man kan lägga till. Här är ett exempel hur man kan använda det. Här är ett exempel på två extra kolumner i contenttype:
<FieldRefs>
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
<!-- Enterprise Keywords-->
<FieldRef ID="{3de94b06-4120-41a5-b907-88773e493458}"/>
<!-- PublishingImage-->
</FieldRefs>
Komma åt Title-kolumnen i SPList
Vad gör man om man vill lägga till Title-kolumnen till en ny vy? SPField fieldTitle = scheduleList.Fields["Title"];
Det kommer funka, men Title kommer vara bara text, utan en länk till SPListItem. Kolla på den koden: SPField fieldTitle = scheduleList.Fields[**SPBuiltInFieldId.LinkTitle**];
Här hämtar vi kolumnen som heter i Sharepoint “Title linked with item menu”. Det finns fler sådana “inbygda” kolumner.
Tag: Cmd
Windows 8: shutdown button on your start and desktop
If you think that “Go to corner” -> Settings -> Power -> Shut down are three steps to much if you just want to shutdown your Windows 8 machine, than do as I did: create a shortcut on you desktop and a tile on your start screen. Create a shortcut as usual: Write in the location field:
shutdown /s /t 0
Name it something, why not “shutdown”? Change the default icon: There it is. Now we can pin it to Start: Done. Now, if you want to shutdown, you have to click only once: Enjoy!
Tag: Shutdown
Windows 8: shutdown button on your start and desktop
If you think that “Go to corner” -> Settings -> Power -> Shut down are three steps to much if you just want to shutdown your Windows 8 machine, than do as I did: create a shortcut on you desktop and a tile on your start screen. Create a shortcut as usual: Write in the location field:
shutdown /s /t 0
Name it something, why not “shutdown”? Change the default icon: There it is. Now we can pin it to Start: Done. Now, if you want to shutdown, you have to click only once: Enjoy!
Tag: Tooltip
Using SharePoint tooltips
I found a great post about using sharepoint tooltips on Andrey Markeev’s (@amarkeev, omlin) blog: JavaScript ToolTip’ы для SharePoint. He describes how he found the standard sharepoint tooltips and how they can be reused. The best part of it his “research”. Andrey’s conclusion is to create an own, simplified javascript class which enables “sharepoint” tooltips. I modified it somewhat. I think there is no need to instantiate a TooltipManager…
var Takana = window.Takana || {};
Takana.ToolTipManager = function () {
var \_divId = "my\_tooltip";
var \_innerDivId = "my\_tooltip\_inner";
function createTitleAndDescriptionHtml(title, description) {
return String.format(
'<div>{0}</div><div>{1}</div>',
title,
description);
}
function showTooltip(element, rawHtml) {
var tooltipDiv = $get(\_divId);
if (tooltipDiv == null)
tooltipDiv = createTooltip();
$get(\_innerDivId).innerHTML = rawHtml;
displayTooltipNextToElement(tooltipDiv, element);
}
function displayTooltipNextToElement(tooltipDiv, element) {
tooltipDiv.style.display = '';
var loc = Sys.UI.DomElement.getLocation(element);
tooltipDiv.style.left = loc.x + 'px';
tooltipDiv.style.top = loc.y + element.offsetHeight + 2 + 'px';
if (tooltipDiv.curTimeout != null)
clearTimeout(tooltipDiv.curTimeout);
}
function createTooltip() {
var mainDiv = document.createElement('span')
mainDiv.id = \_divId;
mainDiv.className = 'ms-cui-tooltip';
mainDiv.style.width = 'auto';
mainDiv.style.position = 'absolute';
var bodyDiv = document.createElement('div');
bodyDiv.className = 'ms-cui-tooltip-body';
bodyDiv.style.width = 'auto';
var innerDiv = document.createElement('div');
innerDiv.id = \_innerDivId;
innerDiv.className = 'ms-cui-tooltip-glow';
innerDiv.style.width = 'auto';
bodyDiv.appendChild(innerDiv);
mainDiv.appendChild(bodyDiv);
document.body.appendChild(mainDiv);
return mainDiv;
}
function hideDiv() {
$get(\_divId).style.display = 'none';
}
var manager = {};
manager.attachToolTip = function (element, title, description) {
$addHandler(element, 'mouseover', function (e) {
showTooltip(element, createTitleAndDescriptionHtml(title, description));
});
$addHandler(element, 'mouseout', hideDiv);
}
manager.attachToolTipRaw = function (element, rawHtml) {
$addHandler(element, 'mouseover', function (e) {
showTooltip(element, rawHtml);
});
$addHandler(element, 'mouseout', hideDiv);
}
return manager;
}();
Now a manager is created on a page per default. To add a tooltip, just use the TooltipManager:
Tag: Date
Chuvash localization of moment.js
For three months ago I added Chuvash localization of moment.js. For 16 days ago moment.js 1.7.0 was officially released which included the Chuvash translation.
Wait a sec… What is moment.js?
moment.js is the best datetime tool for javascript. It supports many languages (now even Chuvash) for displaying date and time. Another very handy functionality is showing relative time which has a simple interface: fromNow().
Here is a simple example from a web browser console:
moment.js - the best javascript tool for working with dates
Just look at moment.js. Everybody who have worked with dates in javascript are going to love it.
Comments from Wordpress.com
Justin Cooney - Mar 3, 2012
Interesting, I hadn’t heard of moment.js. I’m taking a look at the site right now; it looks to have some very handy functionality for date manipulation!
The great thing with moment.js is e.g. that one can create a date object from asp.net date format like /Date(123543534)/
Kalendae - new javascript utility for calendars
An alternative to jQuery UI datepicker is Kalendae. (MIT License). Highly customizable and no dependencies to other javascript libraries. Here is the highlights:
Kalendae is an attempt to do something that nobody has yet been able to do: make a date picker that doesn’t suck. Kalendae provides the following features:
- Fully portable, no dependencies. No jQuery, no Prototype, no MooTools; just add the script and the stylesheet and you’re good to go.
- Fully and easily skinable. The default theme uses only one image file (a mask for the previous and next buttons), everything else is styled using CSS.
- Supports all modern browsers and IE8.
- Support single day, multiple day, or day range selection.
- Configurable number of months to be displayed at once.
- Can be displayed on the page as an inline widget, or attached to one or more input fields as a popup control.
- Can be attached to any page element, not just named elements.
- Configurable blackouts, defined either as an array of dates or via a callback function
- Output selected dates in a variety of formats
- Leverages moment.js for smart and easy date parsing.
Found through daily.js
format javascript date in ISO 8601
There is a solution in StackOverflow:
/\* use a function for the exact format desired... \*/
function ISODateString(d){
function pad(n){return n<10 ? '0'+n : n}
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'}
var d = new Date();
print(ISODateString(d)); // prints something like 2009-09-28T19:03:12Z
```But there is already a function for this: toISOString, it came with ecmascript 5. [Unfortunately, not all browsers support this](http://kangax.github.com/es5-compat-table/ "See the best comparision for ecmascript 5 support"), to solve this problem, we can provide our own prototype function for Date if it doesn't exist:
if (!Date.prototype.toISOString) { Date.prototype.toISOString = function() { function pad(n) { return n < 10 ? ‘0’ + n : n } return this.getUTCFullYear() + ‘-’ + pad(this.getUTCMonth() + 1) + ‘-’ + pad(this.getUTCDate()) + ‘T’ + pad(this.getUTCHours()) + ‘:’ + pad(this.getUTCMinutes()) + ‘:’ + pad(this.getUTCSeconds()) + ‘Z’; }; }
Tag: Datetime
Chuvash localization of moment.js
For three months ago I added Chuvash localization of moment.js. For 16 days ago moment.js 1.7.0 was officially released which included the Chuvash translation.
Wait a sec… What is moment.js?
moment.js is the best datetime tool for javascript. It supports many languages (now even Chuvash) for displaying date and time. Another very handy functionality is showing relative time which has a simple interface: fromNow().
Here is a simple example from a web browser console:
jQuery UI Datepicker
As an alternative to asp:Calendar we can use the fancy jQuery UI Datepicker:
$(document).ready(function () {
$.datepicker.setDefaults($.datepicker.regional\["sv"\]);
$("#").datepicker({
changeMonth: true,
changeYear: true,
yearRange: "-120:+0"
});
});
```I found this a much simple and best solution for an [birthdate input](http://stackoverflow.com/questions/339956/whats-the-best-ui-for-entering-date-of-birth). We can set [international options](http://stackoverflow.com/questions/1865091/jquery-datepicker-language-problem), [year range](http://stackoverflow.com/questions/269545/jquery-datepicker-years-shown), [year](http://stackoverflow.com/questions/3164898/jquery-ui-datepicker-next-and-previous-year) and [month navigation](http://jqueryui.com/demos/datepicker/dropdown-month-year.html). Other options I have tried are asp:Calendar, ajaxtoolkit:CalendarExtender and DateJs. jQuery UI is the most simple much more than datepicker and works smoothily with SharePoint.
Visa i hur länge sedan något hänt
Säg du vill visa när något har skapats. Att visa datum funkar. Ännu bättre är att visa det i stil: “För tre dagar sedan” eller så. Det finns en bra metod i SPUtility:
SPUtility.TimeDeltaAsString(Published, DateTime.Now);
Tag: Moment.js
Chuvash localization of moment.js
For three months ago I added Chuvash localization of moment.js. For 16 days ago moment.js 1.7.0 was officially released which included the Chuvash translation.
Wait a sec… What is moment.js?
moment.js is the best datetime tool for javascript. It supports many languages (now even Chuvash) for displaying date and time. Another very handy functionality is showing relative time which has a simple interface: fromNow().
Here is a simple example from a web browser console:
Tag: UI
Chuvash translation of Wikipedia Mobile
The official Wikipedia mobile app is now translated into Chuvash language and available to use:
What does Chuvash mean?
I am Chuvash. Chuvash is the name of an ethnicity which counts up to 2 milions peoply (mostly in Russia). Chuvashes talk the Chuvash language which is also an official language in Chuvash Republic (besides Russian). Chuvash language is a Turkic language and has a status “Vulnerable” in the UNESCO list of languages in danger. There is a Chuvash Wikipedia cv.wikipedia.org.
Version 0.2.8: UI improvements
A new version is published. As one can see on the github, this version has some UI improvements: Changed library pins to green: in order not to be confusing with the highlighted pins (the red dotted ones), Updated the Swedish localization strings.
Version 0.1.6: Hide keyboard after search
This version improves User Interface. After search you probably don’t want to see the keyboard which takes half a display. So now it is hiding after search. To do this I used a code provided androidguys: InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); mgr.hideSoftInputFromWindow(findField.getWindowToken(), 0);
This version is not published at Market. Commit details on Github.
Tag: Wiki
Chuvash translation of Wikipedia Mobile
The official Wikipedia mobile app is now translated into Chuvash language and available to use:
What does Chuvash mean?
I am Chuvash. Chuvash is the name of an ethnicity which counts up to 2 milions peoply (mostly in Russia). Chuvashes talk the Chuvash language which is also an official language in Chuvash Republic (besides Russian). Chuvash language is a Turkic language and has a status “Vulnerable” in the UNESCO list of languages in danger. There is a Chuvash Wikipedia cv.wikipedia.org.
Set up the Lusites development environment
There is a very good wiki page which describes how to set up the environment. If you think something is missing there, just leave a comment here. Much of that was inspired by a useful tutorial from doityourselfandroid.com
Lusites wiki created
Now there is a wiki on github for LUSites to be able to collaborate.
Tag: Wikipedia
Chuvash translation of Wikipedia Mobile
The official Wikipedia mobile app is now translated into Chuvash language and available to use:
What does Chuvash mean?
I am Chuvash. Chuvash is the name of an ethnicity which counts up to 2 milions peoply (mostly in Russia). Chuvashes talk the Chuvash language which is also an official language in Chuvash Republic (besides Russian). Chuvash language is a Turkic language and has a status “Vulnerable” in the UNESCO list of languages in danger. There is a Chuvash Wikipedia cv.wikipedia.org.
Tag: Lab
Multiple instances of javascript webparts on the same page
Javascript has become popular among many SharePoint developers thanks to easy and fast jQuery, CSOM, SPServices and many other javascript libraries. That can make solutions modern and fast. On the other hand developers should be aware of more things (some of them at Bamboo Team Blog). One of those is scoping of javascript webparts. The problem a developer has to consider: what happens if a user creates two or more instances of the same beautiful webpart on the page? Let’s go and lab :) I’ll create a solution for this lab: sp-lend-id.ikkelen. This time it will be a sandboxed solution. This solution contains a webpart:
Web Application Properties as JSON
I saw an interesting question on sharepoint.stackexchange: How to access a Web application/Farm level property bag via jQuery/Javascript/ClientContext. Some time ago I tested a custom http handler, so I wanted to try a custom httphandler for this as well. It worked. Here more details: Just deploy sp-lend-id.tupsam from the solution. If you don’t have any properties in your web application, just add some:
asnp microsoft.sharepoint.powershell
$app = get-spwebapplication http://dev
$app.Properties.Add("Santa", "Claus")
$app.Properties.Add("Ded", "Moroz")
$app.Properties.Add("Hel", "Muci")
$app.Update()
Then just to test open the httphandler directly in the browser:
nodeunit and SharePoint: unit tests in javascript
nodeunit is a (relatively) new test framework for javascript, mainly for node, but it can be run in a browser as well. The most popular framework for testing javascript is Qunit, but I’ll lab with it another time. I found nodeunit tests in moment.js - the best date handling framework for javascript and it worked very well. So first of all, why should we test? The best answer is actually: Life is to short for manual testing (it was actually the slogan at the Google London Test Automation Conference 2007.
Enable Save in IE9 mode
Wouldn’t it be nice to use html5 and css3 in SharePoint? No problems, there is actually v5 master out there, created by Kyle Schaefer. Or just use h5ml5 and css3 right away in your webparts and pages. But there is a big problem. It doesn’t work in IE9–. One of the issues (even listed by Kyle) is that “save” doesn’t work in modal dialogs where Rich Text Editor is used. Especialy it is for modal dialogs. The problem is not IE9, neither html5 and css3. After some digging in javascript code which is shipped with SharePoint I found out that the problem is some legacy javascript code which is not supported by IE9 but in IE8– (and compatibility mode). When we set IE9 mode in IE9 Dev Tools (F12) and go to Tasks list and try to create a task, we’ll get an error: It is RTE_GetEditorIFrame from init.js:
Tag: Sandbox
Multiple instances of javascript webparts on the same page
Javascript has become popular among many SharePoint developers thanks to easy and fast jQuery, CSOM, SPServices and many other javascript libraries. That can make solutions modern and fast. On the other hand developers should be aware of more things (some of them at Bamboo Team Blog). One of those is scoping of javascript webparts. The problem a developer has to consider: what happens if a user creates two or more instances of the same beautiful webpart on the page? Let’s go and lab :) I’ll create a solution for this lab: sp-lend-id.ikkelen. This time it will be a sandboxed solution. This solution contains a webpart:
Tag: Spservices
Three ways to get the id of last created SPListItem
An interesting question came on SharePoint StackExchange: How to retrieve the guid of the last uploaded file. It is only possible in CSOM as far as I know. But if we simplify the task, how to get the id of the last item, the we can compare three ways of getting them: SPServices, jQuery + listdata.svc and CSOM.
SPServices
The most easiest way, but not available in async:
$().SPServices.SPGetLastItemId({
listName: "Documents"
});
listdata.svc
Just combine some query strings and try in the browsers address bar:
javascript toolkit on text file
Referencing javascript libraries from Content Delivery Networks (CDN) like jQuery can have many benefits. The self-hosted javascript files are on the other hand give you more control. But in one situation it is much better with cdns: the development. Like Marc D Anderson pointed:
I didn’t realize it at the time, but this txt file has become a standard part of my toolkit already. I’ve added it to three client environments just since last week. It’s the A #1 fastest way to get something up and running, even if you know you’re going to host the files locally later.
$().SPServices is best for SOAP
SPServices is a great tool, really nice work, Marc Anderson (@sympmarc). It has been there all the time I have developed for SharePoint. But the fact that you work with XML and you must parse the attributes (!) was the reason why I prefered listdata.svc and Client Object Model, where you get objects in JSON or you have a nice API to get objects and their properties. But there is an area where SPServices are really the best tool: SharePoint Web Services which only understand SOAP like SocialDataService.asmx.
Tag: HttpHandler
Web Application Properties as JSON
I saw an interesting question on sharepoint.stackexchange: How to access a Web application/Farm level property bag via jQuery/Javascript/ClientContext. Some time ago I tested a custom http handler, so I wanted to try a custom httphandler for this as well. It worked. Here more details: Just deploy sp-lend-id.tupsam from the solution. If you don’t have any properties in your web application, just add some:
asnp microsoft.sharepoint.powershell
$app = get-spwebapplication http://dev
$app.Properties.Add("Santa", "Claus")
$app.Properties.Add("Ded", "Moroz")
$app.Properties.Add("Hel", "Muci")
$app.Update()
Then just to test open the httphandler directly in the browser:
ScriptResx.ashx in SharePoint
In my previous post I showed a little proof-of-concept for an httphandler which I want to use to dynamically get the localization resources from SharePoint as javascript object. But wait a moment. How does SharePoint handle localization on client? When you look in Script tab in Chrome dev tools, you’ll find:
ScriptResource.axd
It is added to the server when deployed. See a good introduction to WebResource.axd and ScriptResource.axd by Brian Chavez.
Custom HttpHandler in SharePoint for getting dynamic javascript code
Sometimes I want to add some dynamic javascript code. E.g. I had an idea to get javascript code for localization dynamically. Kirk Evan provides a very clean approach to add ASP.NET HttpHandler to SharePoint. This is just a little lab: Create a SharePoint empty project. I call it Jerkelle. Create a class called Resx2JsHandler and implement the IHttpHandler interface Add the mapped folder Layouts and create Jerkelle.ashx file Here is the project. I probably will publish it on my github account: The Jerkelle.ashx file is very simple, it references to the code file (Resx2JsHandler.cs):
Tag: Clone
Using javascript objects passed from closed popup
It is not a rocket science to pass objects from child window (popup) to main window. The problem I encountered today was IE and passing complex objects. So it is just an IE issue as far as I know. The problem occurs when you pass some object (not a simple String or Number) to main window:
window.opener.takeAnObjectFromChild = {
title: "Should even be available when I close the child"
};
and you then close the child window, next time the main window tries to access the passed object:
Clone javascript objects
In javascript, if we copy objects or their properties, the reference still remains and by changing the new object the old one is changed, too. To clone or do a clean copy of an object I found a very useful solution by Jan Turoň on StackOverflow:
Object.prototype.clone = function() {
if(this.cloneNode) return this.cloneNode(true);
var copy = this instanceof Array ? \[\] : {};
for(var attr in this) {
if(typeof this\[attr\] == "function" || this\[attr\]==null || !this\[attr\].clone)
copy\[attr\] = this\[attr\];
else if(this\[attr\]==this) copy\[attr\] = copy;
else copy\[attr\] = this\[attr\].clone();
}
return copy;
}
Date.prototype.clone = function() {
var copy = new Date();
copy.setTime(this.getTime());
return copy;
}
Number.prototype.clone =
Boolean.prototype.clone =
String.prototype.clone = function() {
return this;
}
Tag: Development
javascript: developing for performance
Many words have been said about the importance of performance when working with javascript files. Here I want to summarize what developers can do to increase the performance related to javascript. I found many tips on blogs. Here comes my aggregated list of actions one can do to speed up sharepoint (and not only) sites with focus on javascript:
1. Load only sharepoint stuff you need
Use prefetch option to only load sharepoint javascript files that needed. To see the difference, just add ?prefetch=0
to your sharepoint url in the browser. The downside of this lazy loading is that you wrap all sharepoint related javascript into ExecuteOrDelayUntilScriptLoaded otherwise you maybe invoke some of javascript objects and functions that are not loaded. So the prize of this huge performance improvement is a high awareness by a developer when and which scripts are loaded and run.
Set up the Lusites development environment
There is a very good wiki page which describes how to set up the environment. If you think something is missing there, just leave a comment here. Much of that was inspired by a useful tutorial from doityourselfandroid.com
Tag: Test
nodeunit and SharePoint: unit tests in javascript
nodeunit is a (relatively) new test framework for javascript, mainly for node, but it can be run in a browser as well. The most popular framework for testing javascript is Qunit, but I’ll lab with it another time. I found nodeunit tests in moment.js - the best date handling framework for javascript and it worked very well. So first of all, why should we test? The best answer is actually: Life is to short for manual testing (it was actually the slogan at the Google London Test Automation Conference 2007.
Tag: Publish
Develop for SharePoint on Windows 8
Do you like Windows 8 user expirience, as me? Well than you want to try developing sharepoint solutions in Windows 8. Here I will show what I found out.
Environment
I installed Windows 8 Release Preview as a VMWare machine. Then I installed Visual Studio 2012 RC. Then I followed the steps for installing SharePoint on Windows 8 which are more or less the same as for Windows 7 client install. But then I encountered an error I haven’t found solution for yet. In my standalone sharepoint installation there were some permission problems:
Publish upgrade on Market - checklist
Here comes my checklist about what has to be done in order to publish an upgrade on Market.
- get all code from github (git pull origin master)
- Test the application
- Change version number in AndroidManifest.xml
- Commit “version x.x.” and push
- (Change google map api key in res/layout/main.xml to the prod key)
- In Eclipse: Project → Clean
- Right-click on project → Android tools → Export signed… (~/Skrivbord/LUSites-unaligned.apk)
- Zipalign (e.g.: zipalign -v 4 LUSites-unaligned.apk LUSites-v0.2.7.apk)
- Publish upgrade on market
- Save the apk to the archive
Tag: Cms
$ in cmssitemanager.js conflicts with $ in jQuery
In SharePoint 2010 if CMSSiteManager.js library is loaded besides jQuery, then much of stuff stops working. The reason is that the dollar sign ($) is used in cmssitemanager.js as well which conflicts with jQuery. Mostly it appears on pages where you load jQuery and have an image library with thumbnails. To avoid this, just replace all $ with jQuery in your custom scripts. A more crazy situation is when avoiding $ isn’t enough. It is when you load jQuery to page head automatically on all pages. The Asset picker (AssetPortalBrowser.aspx) invokes $ itself and gets with jQuery in conflict without you write a single line of custom javascript code. You usually get the following error:
Videokurs om Web Content Management
På microsoft.com finns en ny videokurs om web content management. Där kan du lära dig om hur man implementerar cms-funktionalitet med sharepoint, bl.a.: content types, page layouts med mera. Tack för tipset, deutschsprachige Sharepoint-Community.
Tag: Solution
$ in cmssitemanager.js conflicts with $ in jQuery
In SharePoint 2010 if CMSSiteManager.js library is loaded besides jQuery, then much of stuff stops working. The reason is that the dollar sign ($) is used in cmssitemanager.js as well which conflicts with jQuery. Mostly it appears on pages where you load jQuery and have an image library with thumbnails. To avoid this, just replace all $ with jQuery in your custom scripts. A more crazy situation is when avoiding $ isn’t enough. It is when you load jQuery to page head automatically on all pages. The Asset picker (AssetPortalBrowser.aspx) invokes $ itself and gets with jQuery in conflict without you write a single line of custom javascript code. You usually get the following error:
Tag: Toolkit
javascript toolkit on text file
Referencing javascript libraries from Content Delivery Networks (CDN) like jQuery can have many benefits. The self-hosted javascript files are on the other hand give you more control. But in one situation it is much better with cdns: the development. Like Marc D Anderson pointed:
I didn’t realize it at the time, but this txt file has become a standard part of my toolkit already. I’ve added it to three client environments just since last week. It’s the A #1 fastest way to get something up and running, even if you know you’re going to host the files locally later.
ASP.NET Ajax Toolkit
To integrate ASP.NET Ajax Toolkit is not the most straight forward task in SharePoint. If you want to take the risk, “Inspired by Technology” provides the best guide so far.
Tag: JQuery Mobile
jQuery mobile and SharePoint
In this post I want to explore how to build a mobile app using jQuery mobile. Recently I discovered two great blog posts about this:
- Building SharePoint web apps using Sencha Touch by Luc Stakenborg
- jQuery mobile and SharePoint by Chris Quick
In my post I’ll use their findings and share some of mine thougts. I’ll focus mostly on how to get started with jQuery mobile and SharePoint. So go ahead and create your jQuery mobile app, just drag’n’drop some controls: Download it and yout get an “app.html” file and “my.css”. For now ignore my.css. app.html is something like that:
Tag: Android
Install android sdk and eclipse in Ubuntu 12.04
Download and unpack the Android SDK, move it to your home folder. I prefer to set a point in front of the directory folder to make it be hidden so that my home directoy still looks tidy: .android-sdk-linux
. Then add this to your path:
export PATH=${PATH}:~/.android-sdk-linux/tools:~/.android-sdk-linux/platform-tools
.android-sdk-tools is for running android
command, and .android-sdk-tools/platform-tools is for running adb
command And add it to your .bashrc-file so that this path is loaded automatically when you log on.
Android: Asynchronously download images
In the Malmöfestivalen for Android where I participate we wanted to show thumbnails of events in lists. We have urls of thumbnails from Malmofestivalen API. This information is stored in a sqlite database and a SimpleCursorAdapter is used for getting the events from the database. It is possible to bind the urls to ImageView objects (by downloading the stream: 1, 2, 3). The problem is in a listactivity with many images it will freeze. So it must be an AsyncTask, and it should be some kind of local cache to avoid loading same images over and over again. Fortunately there is already ImageDownloader class provided in the android blog post: Multithreading For Performance . The next step is to create custom adapter and extend from SimpleCursorAdapter: EventCursorAdapter, like described on Android-er and and SP-Technolab: [sourcecode language=“java”]public class EventCursorAdapter extends SimpleCursorAdapter { private final ImageDownloader imageDownloader = new ImageDownloader(); public EventCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { super(context, layout, c, from, to); imageDownloader.setMode(ImageDownloader.Mode.NO_DOWNLOADED_DRAWABLE); } @Override public View getView(int position, View convertView, ViewGroup parent) { View row = super.getView(position, convertView, parent); Cursor cursor = getCursor(); cursor.moveToPosition(position); ImageView iv = (ImageView) row.findViewById(R.id.eventitemrowimage); String url = cursor.getString(cursor.getColumnIndex(EventProvider.EVENT_KEY_URISMALLIIMAGE)); if (url.length() > 0) { imageDownloader.download(url, iv); } String start = cursor.getString(cursor.getColumnIndex(EventProvider.EVENT_KEY_STARTDATE)); String end = cursor.getString(cursor.getColumnIndex(EventProvider.EVENT_KEY_ENDDATE)); String dateString = DateHelper.createShortDateResume(start, end); TextView tv = (TextView) row.findViewById(R.id.eventitemrowtimeresume); tv.setText(dateString); return row; } }[/sourcecode] In this code the view is created by the super class and then it is modified, the alternative is to “inflate the view” completely self. The result is an event list which opens directly and loads thumbnails asynchronously: listactivity with images
ResxCrunch: Localization tool
If your solution has two or more languages to support, I can recommend an open source tool ResxCrunch. Btw, you can even use ResxCrunch for localization of Android applications.
Publish upgrade on Market - checklist
Here comes my checklist about what has to be done in order to publish an upgrade on Market.
- get all code from github (git pull origin master)
- Test the application
- Change version number in AndroidManifest.xml
- Commit “version x.x.” and push
- (Change google map api key in res/layout/main.xml to the prod key)
- In Eclipse: Project → Clean
- Right-click on project → Android tools → Export signed… (~/Skrivbord/LUSites-unaligned.apk)
- Zipalign (e.g.: zipalign -v 4 LUSites-unaligned.apk LUSites-v0.2.7.apk)
- Publish upgrade on market
- Save the apk to the archive
LUSites now available for lower API levels
If your smartphone runs Android 2.1 or lower, now you can find LUSites on Market, too. When I created LUSites I developed for Froyo (Android 2.2). But LUSites does nothing that hasn’t existed in previous Android releases (API levels). So I set API level 3 as minimal SDK version. I hope it works on your android phones. If not, please leave a comment here.
Bläddra i Sharepoint från Android
Det finns en app som heter Quick Browser för Android från SPElements. Med den kan man bläddra i olika bibliotek och listor i en sharepoint direkt från mobilen. Mycket smidigt. Den aktuella versionen är 0.2.8. Den uppdateras rätt så ofta och blir bättre och bättre. Den enda nackdelen jag tycker är att man får alla element i ett bibliotek bara som en lista. Om det är image library så måste man long-klicka på ett element för att “download and view”. Mycket smidigare hade det varit om bilder visades i en Gallery.
Tag: Eclipse
Install android sdk and eclipse in Ubuntu 12.04
Download and unpack the Android SDK, move it to your home folder. I prefer to set a point in front of the directory folder to make it be hidden so that my home directoy still looks tidy: .android-sdk-linux
. Then add this to your path:
export PATH=${PATH}:~/.android-sdk-linux/tools:~/.android-sdk-linux/platform-tools
.android-sdk-tools is for running android
command, and .android-sdk-tools/platform-tools is for running adb
command And add it to your .bashrc-file so that this path is loaded automatically when you log on.
Good beginners' tutorial on android, eclipse and git
Smashing magazine has a pretty good tutorial how to start programming for android using git, github, eclipse and datastorage. I recommend: Get Started Developing For Android With Eclipse, Reloaded
New files in Eclipse
If there are new classes or files in the project (say you have got the latest version from github into existing workspace in Eclipse). In order for Eclipse to see them, right click on the package and press “Refresh”.
Tag: Java
Install android sdk and eclipse in Ubuntu 12.04
Download and unpack the Android SDK, move it to your home folder. I prefer to set a point in front of the directory folder to make it be hidden so that my home directoy still looks tidy: .android-sdk-linux
. Then add this to your path:
export PATH=${PATH}:~/.android-sdk-linux/tools:~/.android-sdk-linux/platform-tools
.android-sdk-tools is for running android
command, and .android-sdk-tools/platform-tools is for running adb
command And add it to your .bashrc-file so that this path is loaded automatically when you log on.
Android: Asynchronously download images
In the Malmöfestivalen for Android where I participate we wanted to show thumbnails of events in lists. We have urls of thumbnails from Malmofestivalen API. This information is stored in a sqlite database and a SimpleCursorAdapter is used for getting the events from the database. It is possible to bind the urls to ImageView objects (by downloading the stream: 1, 2, 3). The problem is in a listactivity with many images it will freeze. So it must be an AsyncTask, and it should be some kind of local cache to avoid loading same images over and over again. Fortunately there is already ImageDownloader class provided in the android blog post: Multithreading For Performance . The next step is to create custom adapter and extend from SimpleCursorAdapter: EventCursorAdapter, like described on Android-er and and SP-Technolab: [sourcecode language=“java”]public class EventCursorAdapter extends SimpleCursorAdapter { private final ImageDownloader imageDownloader = new ImageDownloader(); public EventCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { super(context, layout, c, from, to); imageDownloader.setMode(ImageDownloader.Mode.NO_DOWNLOADED_DRAWABLE); } @Override public View getView(int position, View convertView, ViewGroup parent) { View row = super.getView(position, convertView, parent); Cursor cursor = getCursor(); cursor.moveToPosition(position); ImageView iv = (ImageView) row.findViewById(R.id.eventitemrowimage); String url = cursor.getString(cursor.getColumnIndex(EventProvider.EVENT_KEY_URISMALLIIMAGE)); if (url.length() > 0) { imageDownloader.download(url, iv); } String start = cursor.getString(cursor.getColumnIndex(EventProvider.EVENT_KEY_STARTDATE)); String end = cursor.getString(cursor.getColumnIndex(EventProvider.EVENT_KEY_ENDDATE)); String dateString = DateHelper.createShortDateResume(start, end); TextView tv = (TextView) row.findViewById(R.id.eventitemrowtimeresume); tv.setText(dateString); return row; } }[/sourcecode] In this code the view is created by the super class and then it is modified, the alternative is to “inflate the view” completely self. The result is an event list which opens directly and loads thumbnails asynchronously: listactivity with images
New files in Eclipse
If there are new classes or files in the project (say you have got the latest version from github into existing workspace in Eclipse). In order for Eclipse to see them, right click on the package and press “Refresh”.
Tag: Jdk
Install android sdk and eclipse in Ubuntu 12.04
Download and unpack the Android SDK, move it to your home folder. I prefer to set a point in front of the directory folder to make it be hidden so that my home directoy still looks tidy: .android-sdk-linux
. Then add this to your path:
export PATH=${PATH}:~/.android-sdk-linux/tools:~/.android-sdk-linux/platform-tools
.android-sdk-tools is for running android
command, and .android-sdk-tools/platform-tools is for running adb
command And add it to your .bashrc-file so that this path is loaded automatically when you log on.
Tag: Sdk
Install android sdk and eclipse in Ubuntu 12.04
Download and unpack the Android SDK, move it to your home folder. I prefer to set a point in front of the directory folder to make it be hidden so that my home directoy still looks tidy: .android-sdk-linux
. Then add this to your path:
export PATH=${PATH}:~/.android-sdk-linux/tools:~/.android-sdk-linux/platform-tools
.android-sdk-tools is for running android
command, and .android-sdk-tools/platform-tools is for running adb
command And add it to your .bashrc-file so that this path is loaded automatically when you log on.
Tag: SOAP
Implement public wcf service in SharePoint
If you have an external web service reference in your sharepoint solution, you can use web.config configuration like:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding\_ISuperService" >
<security mode="None">
<message clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://super.domain/SuperService.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding\_ISuperService"
contract="ISuperService"
name="SuperServiceEndpoint">
</endpoint>
</client>
</system.serviceModel>
```security mode is set to "None". Then in code just get this configuration:
var proxy = new SuperServiceClient(“SuperServiceEndpoint”); var result = proxy.GetSomething();
var binding = new WSHttpBinding(); binding.Security.Mode = SecurityMode.None; var endpoint = new EndpointAddress(“http://super.domain/SuperService.svc"); var proxy = new ExternalServices.DreamServiceClient(binding, endpoint); var result = proxy.GetSomething();
Tag: Wcf
Implement public wcf service in SharePoint
If you have an external web service reference in your sharepoint solution, you can use web.config configuration like:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding\_ISuperService" >
<security mode="None">
<message clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://super.domain/SuperService.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding\_ISuperService"
contract="ISuperService"
name="SuperServiceEndpoint">
</endpoint>
</client>
</system.serviceModel>
```security mode is set to "None". Then in code just get this configuration:
var proxy = new SuperServiceClient(“SuperServiceEndpoint”); var result = proxy.GetSomething();
var binding = new WSHttpBinding(); binding.Security.Mode = SecurityMode.None; var endpoint = new EndpointAddress(“http://super.domain/SuperService.svc"); var proxy = new ExternalServices.DreamServiceClient(binding, endpoint); var result = proxy.GetSomething();
Tag: Reflection
Creating custom powershell cmdlet
Why
I need to to activate a feature in PowerShell and specify some properties. Simple? Yes. Possible? No. In the default Enable-SPFeature cmdlet you can’t specify any properties:
Enable-SPFeature –Identity "b5eef7d1-f46f-44d1-b53e-410f62032846" -URL http://dev
We can of course easily add properties when activating features in onet.xml:
<!-- Publishing Resources -->
<Feature ID="AEBC918D-B20F-4a11-A1DB-9ED84D79C87E">
<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<Property Key="AllowRss" Value="false" />
<Property Key="SimplePublishing" Value="false" />
</Properties>
</Feature>
So I went to SharePoint StackExchange and asked the question. Then I realized: the standard Sharepoin API doesn’t support this neither. The methods of SPFeatureCollection which have SPFeatureProperties as parameter are internal. So the only way is to use Reflection like Hristo Pavlov (2008) and Yaroslav Pentsarsky (2010) suggest. So why not to try to create a cmdlet?
Tag: Tutorial
Creating custom powershell cmdlet
Why
I need to to activate a feature in PowerShell and specify some properties. Simple? Yes. Possible? No. In the default Enable-SPFeature cmdlet you can’t specify any properties:
Enable-SPFeature –Identity "b5eef7d1-f46f-44d1-b53e-410f62032846" -URL http://dev
We can of course easily add properties when activating features in onet.xml:
<!-- Publishing Resources -->
<Feature ID="AEBC918D-B20F-4a11-A1DB-9ED84D79C87E">
<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<Property Key="AllowRss" Value="false" />
<Property Key="SimplePublishing" Value="false" />
</Properties>
</Feature>
So I went to SharePoint StackExchange and asked the question. Then I realized: the standard Sharepoin API doesn’t support this neither. The methods of SPFeatureCollection which have SPFeatureProperties as parameter are internal. So the only way is to use Reflection like Hristo Pavlov (2008) and Yaroslav Pentsarsky (2010) suggest. So why not to try to create a cmdlet?
Add Comments column to your sharepoint list
If you have used Issue tracking list template in SharePoint you must have marked that the comments are added and marked with author name and datetime. It is handy to have these micro “discussion boards” on items. The comment-formed communication can help to fine-tune task definitions. By the way, have you seen Trello? So the question is how we can create this column in other lists? Here is a little tutorial how to create “append-only comments”, as they are called:
Good beginners' tutorial on android, eclipse and git
Smashing magazine has a pretty good tutorial how to start programming for android using git, github, eclipse and datastorage. I recommend: Get Started Developing For Android With Eclipse, Reloaded
Tag: Gridview
Out-Gridview in PowerShell
Did you know that we can pipe the output from PowerShell into a graphical GridView? I have used PowerShell for one year and only now I discovered this nice feature. You can add filter criteria, you can filter by typing in a textbox:
Other useful output cmdlets
- out-file
- out-clip
- out-null
Tag: Spuser
Access User Profile Properties from Powershell
To use only SPUser objects isn’t always sufficient. To get other properties we have to retrieve user profiles. Giles Hamson gives an example how to get and how to update user profile properties with powershell. Here is an example how to get all work phones:
$url = "http://intranet/"
$site = Get-SPSite $url
$context = Get-SPServiceContext $site
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$profiles = $profileManager.GetEnumerator()
while ($profiles.MoveNext()) {
$userProfile = $profiles.Current
$name = $userProfile.DisplayName
$phone = $userProfile\["WorkPhone"\]
$line = '{0};{1}' -f $name, $phone
write $line
}
If you are not sure what properties are called, see the whole list by typing:
Get Distinguished Name for a user
To get the distinguished name for a user, it isn’t enough to get an SPUser object. The distinguished name is the unique string for identifying a user in Active Directory (eg. CN=BeforeDAfter,OU=Test,DC=North America,DC=Fabrikam,DC=COM) Even using UserProfile object is not that clear. The distinguished name can be found in a property which can be retrieved with brackets: up[PropertyConstants.DistinguishedName]
public static string GetDistinguishedName(string login)
{
var dn = "";
UserProfile up;
using (var site = new SPSite("http://dev"))
{
var serviceContext = SPServiceContext.GetContext(site);
var upm = new UserProfileManager(serviceContext);
var exists = upm.UserExists(login);
if (!exists)
upm.CreateUserProfile(login);
if (exists)
{
up = upm.GetUserProfile(login);
dn = up\[PropertyConstants.DistinguishedName\].Value.ToString();
}
}
return dn;
}
```The code is simplified and doesn't contain any error handling. And a better handling of upm.UserExists must be implemented: If upm.CreateUserProfile(login) runs, it doesn't make it so quickly and the next step won't run (upm.GetUserProfile). If you are not working in SP Context, you can see the distinguished name for a user in Powershell:
import-module activedirectory $u = get-aduser administrator $u.DistinguishedName
Configure User Profile Service Application
Today I have struggled with User Profile Service Application. I should have followed this awesome tutorial by ShareponitGeorge. And many thanks to my friend David for the great assistance! One important thing to beware about: Forefront Identity Manager Service must be running. Otherwise you don’t see the existing synchronization connections and you can’t add new connections. You can ensure that this service is running by running services.msc (just press Windows button and write services). Or you can do in powershell:
Check if user is in group
Use LINQ to check if user is in a group. Create an extension method.
public static bool InGroup(this SPUser user, SPGroup group)
{
return user.Groups.Cast<SPGroup>()
.Any(g => g.ID == group.ID);
}
```EDIT 2011-01-22: There is a shortcoming of this method. You won't get a user which is in group through a AD group. You'll get only users and ad groups. [But there is another method to check if a user is inside an AD group](/2012/01/16/check-if-a-user-is-in-a-ou/ "See my post about how to retrieve users from AD groups with PrincipalSearcher"). How could we combine them?... I think we must start from group this time, not from user:
public static bool HasUser(this SPGroup user, SPUser user) { var users = group.Users.Cast(); var samAccount = Regex.Replace(user.LoginName, @".*\\(.*)", “$1”, RegexOptions.None); var exists = users.Any(u => u.LoginName.Equals(user.LoginName)); if (!exists) { var ctx = new PrincipalContext(ContextType.Domain); foreach (var u in users) { var login = u.LoginName; var groupName = Regex.Replace(login, @".*\\(.*)", “$1”, RegexOptions.None); var grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName); if (grp == null) continue; var principals = grp.GetMembers(true); exists = principals.Any(p => p.SamAccountName.Equals(samAccount, StringComparison.InvariantCultureIgnoreCase)); if (exists) break; } } return exists; }
Tag: User
Access User Profile Properties from Powershell
To use only SPUser objects isn’t always sufficient. To get other properties we have to retrieve user profiles. Giles Hamson gives an example how to get and how to update user profile properties with powershell. Here is an example how to get all work phones:
$url = "http://intranet/"
$site = Get-SPSite $url
$context = Get-SPServiceContext $site
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$profiles = $profileManager.GetEnumerator()
while ($profiles.MoveNext()) {
$userProfile = $profiles.Current
$name = $userProfile.DisplayName
$phone = $userProfile\["WorkPhone"\]
$line = '{0};{1}' -f $name, $phone
write $line
}
If you are not sure what properties are called, see the whole list by typing:
Get current user and handle a success callback
In my previous post I needed the accound id of the current user for posting new list items. To retrieve the id, we can push this to the client from the code behind, or get the current user using Client Object Model. To provide a more generic way we can write a js function which get the current user. But we must even provide some callback functionality, otherwise we don’t know if the operation was successful or not. Let’s be inspired by success and error properties in $.ajax:
Hide my site link with css
Want to hide my site link without disabling social features. Well, the simplest way to do it is to use css:
#mp1\_0\_0\_Anchor { display: none; }
```If you want to hide my profile instead, just hide #mp1\_0\_1\_Anchor:
#mp1_0_1_Anchor { display: none; }
.ms-MenuUIUL li[text=‘My Site’] { display: none;}
##### Disable the my profile feature An even better solution is maybe to disable the ability to change the profiles. [Just remove the permission to "user personalization..." for All authenticated users in User Profile Service](http://blog.libinuko.com/2010/10/10/sharepoint-2010-howto-disable-my-site-and-my-profile-link/).
## Comments from Wordpress.com
####
[John]( "johnandrewdavies@hotmail.com") - <time datetime="2012-03-07 00:15:32">Mar 3, 2012</time>
Be careful this cannot be used, the classes for pop up menus are generated dynamically on the page, and that class can be applied to a number of menus I assume depending on the order which they load on the page, which isnt the same every time, so for instance this hides something in the site actions menu, or the new button on a library sometimes.
<hr />
####
[Brett Anderson](http://sharepoint2020.wordpress.com "brettando@live.com.au") - <time datetime="2012-05-02 06:13:05">May 3, 2012</time>
Hi, The amended solution does not work in IE7.
<hr />
####
[Fredrik]( "fredrik.eriksson234@gmail.com") - <time datetime="2012-03-09 15:27:24">Mar 5, 2012</time>
Thank you Anatoly, that worked perfectly in all browsers! I had problems with the first suggested solution, because it would hide other menu items, like "edit this page" from the site settings dropdown!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:10:36">Mar 3, 2012</time>
You are totally right, John! I realized that too. Fortunately, I didn't need that then. But while using that I saw that sometimes Site Actions -Edit Page disappeared. These IDs are really generated dynamically. Thanks for your comment. I'll update my post.
<hr />
####
[vishal]( "vishals.shivan@gmail.com") - <time datetime="2012-03-07 07:27:54">Mar 3, 2012</time>
Hi Anatoly. Thanks for the solution. but the problem we are facing one problem after implementing this. Once we make this change and when login to the portal next time, the "Edit Page" link under site action menu is not getting displayed and the My Site Link is getting displyed. any suggestion?
<hr />
####
[Material SharePoint » Hide ‘My Site’ Link from Welcome User Dropdown Control](http://sharepoint.jsturges.com/2012/05/hide-my-site-link-from-welcome-user-dropdown-control/ "") - <time datetime="2012-05-12 17:45:13">May 6, 2012</time>
\[...\] of my enterprise level clients that we usually hide it all together! To do this, you can use an awesome CSS trick I learned from Anatoly \[...\]
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:24:39">Mar 3, 2012</time>
Hi Vishal. Unfortunately we cannot rely on these IDs, as John in previous comment mentioned, because these IDs are generated dynamically. I'll update my post. One possible solution would be use attribute selectors... Something like .ms-MenuUIUL li\[text='My Site'\] { display: none;}
<hr />
####
[jim]( "jim.omara@gmail.com") - <time datetime="2014-02-12 17:38:05">Feb 3, 2014</time>
.ms-welcomeMenu #mp1\_0\_0{ display:none; } .ms-welcomeMenu #mp1\_0\_1{ display:none; } .ms-welcomeMenu #mp1\_0\_2{ display:none; } .ms-welcomeMenu #mp1\_0\_3{ display:none; } .ms-welcomeMenu #mp1\_0\_4{ display:none; } .ms-welcomeMenu #mp1\_0\_8{ display:none; } .ms-welcomeMenu #mp1\_0\_9{ display:none; } these work for me.
<hr />
####
[Anatoly Mironov](http://chuvash.eu "mirontoli@gmail.com") - <time datetime="2014-02-12 23:20:59">Feb 3, 2014</time>
Thank you for sharing your solution. Appreciate.
<hr />
Tag: Userprofile
Access User Profile Properties from Powershell
To use only SPUser objects isn’t always sufficient. To get other properties we have to retrieve user profiles. Giles Hamson gives an example how to get and how to update user profile properties with powershell. Here is an example how to get all work phones:
$url = "http://intranet/"
$site = Get-SPSite $url
$context = Get-SPServiceContext $site
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$profiles = $profileManager.GetEnumerator()
while ($profiles.MoveNext()) {
$userProfile = $profiles.Current
$name = $userProfile.DisplayName
$phone = $userProfile\["WorkPhone"\]
$line = '{0};{1}' -f $name, $phone
write $line
}
If you are not sure what properties are called, see the whole list by typing:
Get Distinguished Name for a user
To get the distinguished name for a user, it isn’t enough to get an SPUser object. The distinguished name is the unique string for identifying a user in Active Directory (eg. CN=BeforeDAfter,OU=Test,DC=North America,DC=Fabrikam,DC=COM) Even using UserProfile object is not that clear. The distinguished name can be found in a property which can be retrieved with brackets: up[PropertyConstants.DistinguishedName]
public static string GetDistinguishedName(string login)
{
var dn = "";
UserProfile up;
using (var site = new SPSite("http://dev"))
{
var serviceContext = SPServiceContext.GetContext(site);
var upm = new UserProfileManager(serviceContext);
var exists = upm.UserExists(login);
if (!exists)
upm.CreateUserProfile(login);
if (exists)
{
up = upm.GetUserProfile(login);
dn = up\[PropertyConstants.DistinguishedName\].Value.ToString();
}
}
return dn;
}
```The code is simplified and doesn't contain any error handling. And a better handling of upm.UserExists must be implemented: If upm.CreateUserProfile(login) runs, it doesn't make it so quickly and the next step won't run (upm.GetUserProfile). If you are not working in SP Context, you can see the distinguished name for a user in Powershell:
import-module activedirectory $u = get-aduser administrator $u.DistinguishedName
Hide my site link with css
Want to hide my site link without disabling social features. Well, the simplest way to do it is to use css:
#mp1\_0\_0\_Anchor { display: none; }
```If you want to hide my profile instead, just hide #mp1\_0\_1\_Anchor:
#mp1_0_1_Anchor { display: none; }
.ms-MenuUIUL li[text=‘My Site’] { display: none;}
##### Disable the my profile feature An even better solution is maybe to disable the ability to change the profiles. [Just remove the permission to "user personalization..." for All authenticated users in User Profile Service](http://blog.libinuko.com/2010/10/10/sharepoint-2010-howto-disable-my-site-and-my-profile-link/).
## Comments from Wordpress.com
####
[John]( "johnandrewdavies@hotmail.com") - <time datetime="2012-03-07 00:15:32">Mar 3, 2012</time>
Be careful this cannot be used, the classes for pop up menus are generated dynamically on the page, and that class can be applied to a number of menus I assume depending on the order which they load on the page, which isnt the same every time, so for instance this hides something in the site actions menu, or the new button on a library sometimes.
<hr />
####
[Brett Anderson](http://sharepoint2020.wordpress.com "brettando@live.com.au") - <time datetime="2012-05-02 06:13:05">May 3, 2012</time>
Hi, The amended solution does not work in IE7.
<hr />
####
[Fredrik]( "fredrik.eriksson234@gmail.com") - <time datetime="2012-03-09 15:27:24">Mar 5, 2012</time>
Thank you Anatoly, that worked perfectly in all browsers! I had problems with the first suggested solution, because it would hide other menu items, like "edit this page" from the site settings dropdown!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:10:36">Mar 3, 2012</time>
You are totally right, John! I realized that too. Fortunately, I didn't need that then. But while using that I saw that sometimes Site Actions -Edit Page disappeared. These IDs are really generated dynamically. Thanks for your comment. I'll update my post.
<hr />
####
[vishal]( "vishals.shivan@gmail.com") - <time datetime="2012-03-07 07:27:54">Mar 3, 2012</time>
Hi Anatoly. Thanks for the solution. but the problem we are facing one problem after implementing this. Once we make this change and when login to the portal next time, the "Edit Page" link under site action menu is not getting displayed and the My Site Link is getting displyed. any suggestion?
<hr />
####
[Material SharePoint » Hide ‘My Site’ Link from Welcome User Dropdown Control](http://sharepoint.jsturges.com/2012/05/hide-my-site-link-from-welcome-user-dropdown-control/ "") - <time datetime="2012-05-12 17:45:13">May 6, 2012</time>
\[...\] of my enterprise level clients that we usually hide it all together! To do this, you can use an awesome CSS trick I learned from Anatoly \[...\]
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:24:39">Mar 3, 2012</time>
Hi Vishal. Unfortunately we cannot rely on these IDs, as John in previous comment mentioned, because these IDs are generated dynamically. I'll update my post. One possible solution would be use attribute selectors... Something like .ms-MenuUIUL li\[text='My Site'\] { display: none;}
<hr />
####
[jim]( "jim.omara@gmail.com") - <time datetime="2014-02-12 17:38:05">Feb 3, 2014</time>
.ms-welcomeMenu #mp1\_0\_0{ display:none; } .ms-welcomeMenu #mp1\_0\_1{ display:none; } .ms-welcomeMenu #mp1\_0\_2{ display:none; } .ms-welcomeMenu #mp1\_0\_3{ display:none; } .ms-welcomeMenu #mp1\_0\_4{ display:none; } .ms-welcomeMenu #mp1\_0\_8{ display:none; } .ms-welcomeMenu #mp1\_0\_9{ display:none; } these work for me.
<hr />
####
[Anatoly Mironov](http://chuvash.eu "mirontoli@gmail.com") - <time datetime="2014-02-12 23:20:59">Feb 3, 2014</time>
Thank you for sharing your solution. Appreciate.
<hr />
Tag: Reference
Clone javascript objects
In javascript, if we copy objects or their properties, the reference still remains and by changing the new object the old one is changed, too. To clone or do a clean copy of an object I found a very useful solution by Jan Turoň on StackOverflow:
Object.prototype.clone = function() {
if(this.cloneNode) return this.cloneNode(true);
var copy = this instanceof Array ? \[\] : {};
for(var attr in this) {
if(typeof this\[attr\] == "function" || this\[attr\]==null || !this\[attr\].clone)
copy\[attr\] = this\[attr\];
else if(this\[attr\]==this) copy\[attr\] = copy;
else copy\[attr\] = this\[attr\].clone();
}
return copy;
}
Date.prototype.clone = function() {
var copy = new Date();
copy.setTime(this.getTime());
return copy;
}
Number.prototype.clone =
Boolean.prototype.clone =
String.prototype.clone = function() {
return this;
}
Tag: Stackoverflow
Clone javascript objects
In javascript, if we copy objects or their properties, the reference still remains and by changing the new object the old one is changed, too. To clone or do a clean copy of an object I found a very useful solution by Jan Turoň on StackOverflow:
Object.prototype.clone = function() {
if(this.cloneNode) return this.cloneNode(true);
var copy = this instanceof Array ? \[\] : {};
for(var attr in this) {
if(typeof this\[attr\] == "function" || this\[attr\]==null || !this\[attr\].clone)
copy\[attr\] = this\[attr\];
else if(this\[attr\]==this) copy\[attr\] = copy;
else copy\[attr\] = this\[attr\].clone();
}
return copy;
}
Date.prototype.clone = function() {
var copy = new Date();
copy.setTime(this.getTime());
return copy;
}
Number.prototype.clone =
Boolean.prototype.clone =
String.prototype.clone = function() {
return this;
}
Sharepoint Overflow
Alla känner nog till stackoverflow.com. Det finns även sådant för enbart Sharepoint Overflow. Värt att testa.
Tag: Blur
clearInterval in Chrome doesn't work on window blur
If you want to reset all interval jobs when a browser tab is inactive, the best way would be to use clearInterval on window blur. But unfortunately Chrome fires window focus and window blur two times. Here is an embryo to a solution:
var M = window.M || {};
M.counter = 0;
M.focused = true;
M.tick = function() {
if (M.focused) {
console.log("tic tac " + ++M.counter);
}
};
M.start = function(e) {
console.log("starting...");
M.focused = true;
};
M.stop = function(e) {
console.log("stopping...");
M.focused = false;
};
$(window).on({
focus: M.start,
blur: M.stop
});
M.ticker = window.setInterval(M.tick, 1000);
Tag: Chrome
clearInterval in Chrome doesn't work on window blur
If you want to reset all interval jobs when a browser tab is inactive, the best way would be to use clearInterval on window blur. But unfortunately Chrome fires window focus and window blur two times. Here is an embryo to a solution:
var M = window.M || {};
M.counter = 0;
M.focused = true;
M.tick = function() {
if (M.focused) {
console.log("tic tac " + ++M.counter);
}
};
M.start = function(e) {
console.log("starting...");
M.focused = true;
};
M.stop = function(e) {
console.log("stopping...");
M.focused = false;
};
$(window).on({
focus: M.start,
blur: M.stop
});
M.ticker = window.setInterval(M.tick, 1000);
Tag: Focus
clearInterval in Chrome doesn't work on window blur
If you want to reset all interval jobs when a browser tab is inactive, the best way would be to use clearInterval on window blur. But unfortunately Chrome fires window focus and window blur two times. Here is an embryo to a solution:
var M = window.M || {};
M.counter = 0;
M.focused = true;
M.tick = function() {
if (M.focused) {
console.log("tic tac " + ++M.counter);
}
};
M.start = function(e) {
console.log("starting...");
M.focused = true;
};
M.stop = function(e) {
console.log("stopping...");
M.focused = false;
};
$(window).on({
focus: M.start,
blur: M.stop
});
M.ticker = window.setInterval(M.tick, 1000);
Tag: Window
clearInterval in Chrome doesn't work on window blur
If you want to reset all interval jobs when a browser tab is inactive, the best way would be to use clearInterval on window blur. But unfortunately Chrome fires window focus and window blur two times. Here is an embryo to a solution:
var M = window.M || {};
M.counter = 0;
M.focused = true;
M.tick = function() {
if (M.focused) {
console.log("tic tac " + ++M.counter);
}
};
M.start = function(e) {
console.log("starting...");
M.focused = true;
};
M.stop = function(e) {
console.log("stopping...");
M.focused = false;
};
$(window).on({
focus: M.start,
blur: M.stop
});
M.ticker = window.setInterval(M.tick, 1000);
javascript: passing arguments from popup to main window
To show a popup, we just have to invoke “window.open”, and provide some options to prevent opening this in a new tab:
var wnd = window.open('', '\_blank', 'width=750, height=400, location=no, resizable=1, menubar=0, scrollbars=0');
wnd.document.write('');
wnd.document.close(); wnd.document.close(); wnd.focus();
To communicate between parent and child we can refer to parent as window.opener. We can even invoke a function from parent window. Let’s create the most useful function:
Tag: Pattern
private variables in javascript
Found a nice post about private variables and “methods” in javascript. Consider this example:
function Pizza() {
var price = 0;
this.setPrice = function(p) {
price = p;
};
this.getPrice = function() {
return price;
};
}
```Every variable and function inside the main function is private unless it is appended to "this".
javascript: Umbrella pattern
There are two great patterns for organizing javascript code: Prototype and Module pattern. More about them later in this post. But in reality I still see much of spagghetti Just an example: SharePoint 101 code samples. They are indeed very simple and isolated examples. And many projects use this simple way in mind when they begin. But when javascript code grows, it becomes a monster. Have you seen this biest? How is this monster created? Through good intentions (like everything else) in form of KISS mantra, to little time and the “commit and run”-behavior, or the worst: “I am c#-er, not Front-End-Developer”-spirit. In this post I’ll introduce a kind of compromise the Umbrella pattern. But before that, let’s see how to recognize the spagghetti monster in javascript:
Tag: Pizza
javascript: Umbrella pattern
There are two great patterns for organizing javascript code: Prototype and Module pattern. More about them later in this post. But in reality I still see much of spagghetti Just an example: SharePoint 101 code samples. They are indeed very simple and isolated examples. And many projects use this simple way in mind when they begin. But when javascript code grows, it becomes a monster. Have you seen this biest? How is this monster created? Through good intentions (like everything else) in form of KISS mantra, to little time and the “commit and run”-behavior, or the worst: “I am c#-er, not Front-End-Developer”-spirit. In this post I’ll introduce a kind of compromise the Umbrella pattern. But before that, let’s see how to recognize the spagghetti monster in javascript:
Tag: Spagghetti
javascript: Umbrella pattern
There are two great patterns for organizing javascript code: Prototype and Module pattern. More about them later in this post. But in reality I still see much of spagghetti Just an example: SharePoint 101 code samples. They are indeed very simple and isolated examples. And many projects use this simple way in mind when they begin. But when javascript code grows, it becomes a monster. Have you seen this biest? How is this monster created? Through good intentions (like everything else) in form of KISS mantra, to little time and the “commit and run”-behavior, or the worst: “I am c#-er, not Front-End-Developer”-spirit. In this post I’ll introduce a kind of compromise the Umbrella pattern. But before that, let’s see how to recognize the spagghetti monster in javascript:
Tag: Umbrella
javascript: Umbrella pattern
There are two great patterns for organizing javascript code: Prototype and Module pattern. More about them later in this post. But in reality I still see much of spagghetti Just an example: SharePoint 101 code samples. They are indeed very simple and isolated examples. And many projects use this simple way in mind when they begin. But when javascript code grows, it becomes a monster. Have you seen this biest? How is this monster created? Through good intentions (like everything else) in form of KISS mantra, to little time and the “commit and run”-behavior, or the worst: “I am c#-er, not Front-End-Developer”-spirit. In this post I’ll introduce a kind of compromise the Umbrella pattern. But before that, let’s see how to recognize the spagghetti monster in javascript:
Tag: Appharbor
Hello world in node.js
I know, node.js has been present for a while. But I actually had no time to try it. I was surprised that now it is very straight forward to start with node.js. Allright, everything begins with Hello world. Eventhough it is available for allmost all combinations of operating systems and servers, the easiest way to test it was actually Ubuntu. To install just run:
sudo apt-get install nodejs
```Then make a new directory and create the hello.js:
mkdir hello cd hello vi hello.js
Tag: Hello World
Hello world in node.js
I know, node.js has been present for a while. But I actually had no time to try it. I was surprised that now it is very straight forward to start with node.js. Allright, everything begins with Hello world. Eventhough it is available for allmost all combinations of operating systems and servers, the easiest way to test it was actually Ubuntu. To install just run:
sudo apt-get install nodejs
```Then make a new directory and create the hello.js:
mkdir hello cd hello vi hello.js
Tag: Request
Hello world in node.js
I know, node.js has been present for a while. But I actually had no time to try it. I was surprised that now it is very straight forward to start with node.js. Allright, everything begins with Hello world. Eventhough it is available for allmost all combinations of operating systems and servers, the easiest way to test it was actually Ubuntu. To install just run:
sudo apt-get install nodejs
```Then make a new directory and create the hello.js:
mkdir hello cd hello vi hello.js
Tag: Response
Hello world in node.js
I know, node.js has been present for a while. But I actually had no time to try it. I was surprised that now it is very straight forward to start with node.js. Allright, everything begins with Hello world. Eventhough it is available for allmost all combinations of operating systems and servers, the easiest way to test it was actually Ubuntu. To install just run:
sudo apt-get install nodejs
```Then make a new directory and create the hello.js:
mkdir hello cd hello vi hello.js
Tag: Firebug
cross browser console.log
console.log
is the best tool for debugging javascript. In Firefox Firebug and Chrome Dev Tools you can even log objects which are represented as tree nodes of properties. If Firebug or Dev Tools in Chrome and IE9 are not opened, all these messages are ignored. But IE8 doesn’t understand console (if Dev Tools are closed) and raises an error: To avoid these errors, just declare an empty function just for IE8–:
Tag: Tools
cross browser console.log
console.log
is the best tool for debugging javascript. In Firefox Firebug and Chrome Dev Tools you can even log objects which are represented as tree nodes of properties. If Firebug or Dev Tools in Chrome and IE9 are not opened, all these messages are ignored. But IE8 doesn’t understand console (if Dev Tools are closed) and raises an error: To avoid these errors, just declare an empty function just for IE8–:
My favorite tools
When you code, you can save a lot of time and nerves if you have good tools. Here are my favorites: Programmer’s notepad ULS Log Viewer Resharper t4toolbox HTML5 and CSS3 standards
Tag: Serialization
javascript: serialize as xml
Why should we need to serialize javascript objects as XML. I don’t know. It is of course more a server side need. And there actually a need for javascript serialization as xml in node.js. To serialize as json is very simple: JSON.stringify(myobjects). I was just curious if there was a tool for xml serialization in javascript. There is a nice javascript tool called XMLWriter, developed by Ariel Flesler. Consider you have articles and want to serialize them as xml, let’s create a function for serializing:
Tag: Ie9
Enable Save in IE9 mode
Wouldn’t it be nice to use html5 and css3 in SharePoint? No problems, there is actually v5 master out there, created by Kyle Schaefer. Or just use h5ml5 and css3 right away in your webparts and pages. But there is a big problem. It doesn’t work in IE9–. One of the issues (even listed by Kyle) is that “save” doesn’t work in modal dialogs where Rich Text Editor is used. Especialy it is for modal dialogs. The problem is not IE9, neither html5 and css3. After some digging in javascript code which is shipped with SharePoint I found out that the problem is some legacy javascript code which is not supported by IE9 but in IE8– (and compatibility mode). When we set IE9 mode in IE9 Dev Tools (F12) and go to Tasks list and try to create a task, we’ll get an error: It is RTE_GetEditorIFrame from init.js:
Tag: Listdata.svc
$().SPServices is best for SOAP
SPServices is a great tool, really nice work, Marc Anderson (@sympmarc). It has been there all the time I have developed for SharePoint. But the fact that you work with XML and you must parse the attributes (!) was the reason why I prefered listdata.svc and Client Object Model, where you get objects in JSON or you have a nice API to get objects and their properties. But there is an area where SPServices are really the best tool: SharePoint Web Services which only understand SOAP like SocialDataService.asmx.
$select in listdata.svc
Sure you don’t want to load all the properties of listitems, like ContenTypeId and so on. We cannot avoid __metadata property :), but we can let listdata.svc to send only properties we want. By the way, the best tool for building listdata.svc queries is linqpad. Just write a usual Linq and linqpad converts it to web service url query: Another great stuff is $count, just add ?$count and you get only the count of items, no other junk.
Update list items with listdata.svc
In one of my previous posts I showed how to retrieve data from listdata.svc with jQuery $.getJSON method. Getting data is very simple, listdata.svc provides a powerful restful interface with filtering, expanding and other features. Read the best and short introduction to listdata.svc by Suneet Sharma or a more detailed and technical article about filters, functions and operators by Mike Flasko at Microsoft with short examples here. Now back to listdata.svc in the SharePoint environment. Corey Roth provides a good images and sample results. For REST the “http verbs” are very important: GET, POST, PUT, DELETE.. SharePoint RESTful interface defines these verbs like that:
$.getJSON, jQuery.tmpl and _vti_bin
Javascript is very fast, responsive and unburdens the cpu at the server. Here I show a little example how to use jQuery.getJSON, jQuery.tmpl (wonderful plugin for rendering repeating data, repo hosted on Github) and REST-based service listdata.svc from /_layouts/_vti_bin/ folder. For this example I created a generic list “Contacts”, added two text fields Name and Phone. Add some phone numbers and try to go to /_vti_bin/ListData.svc/Contacts If you get 404-error, install a ADO.NET Data Services v1.5 CTP2, as described at dotnetmafia. If you want to know more about how to sort and filter, skip and limit results, read more at nothingbutsharepoint. If you encounter problems, follow Michaël’s blog post and download and install Windows6.1-KB976127-v6-x64.msu (if you have Windows Server 2008 R2), or NDP35SP1-KB976126-v2-x64.exe (if you have Windows Server 2008). After installing the version of the System.Data.Services.dll file is 3.5.30729.5004 (Windows Server 2008 R2), and 3.5.30729.4466 (Windows Server 2008). Allright, the remainder is pure javascript. In order to get it working you have to run the script from the same domain, meaning you can’t run javascript to retrieve the data from a html-file from your home folder. Create a webpart and add it to your page.
Tag: Checkbox
onchange isn't firing in IE
I don’t know why, but (not always, just sometimes) IE doesn’t fire the onchange event (which is added as an attribute on an html element). A better “workaround” is to add an eventlistener in javascript. Or a lazy workaround is to use the onclick event even for checkboxes.
Tag: Loading
Loading notification
When you load some data with ajax, you will probably want to show the users in some way, that data is loading. To show the text “loading…” would be enough. Another, very common way to do it to show a spinner, a rotating image. In sharepoint we can use the built-in gif which can be found in /_layouts/images/loading16.gif. Well, it is actually not so good, because this image is not so beautiful. A better way is to create your own gif image which is exactly suited for our needs. Or even better: don’t use any images. Use the light-weight javascript library called spin.js for creating spinners. It is fully customizable, compatible with older browsers. You can customize it interactively on the spin.js homepage.
Tag: Spinner
Loading notification
When you load some data with ajax, you will probably want to show the users in some way, that data is loading. To show the text “loading…” would be enough. Another, very common way to do it to show a spinner, a rotating image. In sharepoint we can use the built-in gif which can be found in /_layouts/images/loading16.gif. Well, it is actually not so good, because this image is not so beautiful. A better way is to create your own gif image which is exactly suited for our needs. Or even better: don’t use any images. Use the light-weight javascript library called spin.js for creating spinners. It is fully customizable, compatible with older browsers. You can customize it interactively on the spin.js homepage.
Tag: Serialize
Push a copy of Resources to client in javascript
In one of my previous posts I told about pushing a copy of an object into client. Now I’ll try to copy my resource values into client. The problem is often that we must create multiple localization resources: first as resx-file. If we use much ajax and client side rendering, we must provide some localization there, too. If they are different subsets of localization resources, it isn’t a problem. But when you get overlapping, it becomes more difficult to manage and sync them. See how Microsoft Ajax Library provides some strings: What if we just copy the values from resx file into client? If there are not business constraint it can make the development much easier. Let’s try it. For that we need Reflection. We start with changing the access modifiers on resx file to public: Then we must get all static properties of the auto-generated class (ResXFileCodeGenerator):
Push a copy of an object to client
To reduce postbacks and database calls, a copy of the current object(s) can be pushed down to the client in JSON format. Say a webpart renders information about a person, another webpart shows related information which is retrieved dynamically (like web services). Instead of getting the current person from the database in the second webpart again, we can reuse the same person object from the first webpart. To do so we must provide a DataContract for the Person class:
json serializer in Sharepoint
There is a very handy JSON lib for serializing javascript objects. It is hosted on github under douglas crockford. Download json2.js and serialize with JSON.stringify function: EDIT: There is actually this function in core javascript. It exists since javascript 1.7 and ecmascript 5. So you don’t have to add anything to get this functionality:
var t = { name: "dev", city: "new york" };
JSON.stringify(t);
```There are actually built-in goodies for serializing javascript objects in [ASP.NET](http://msdn.microsoft.com/en-us/library/bb310857.aspx): Sys.Serialization.JavaScriptSerializer.serialize
var t = { name: “dev”, city: “new york” }; Sys.Serialization.JavaScriptSerializer.serialize(t);
Tag: Simple
Simple select unselect all
I have a simple html table, every row in tbody has a checkbox. thead has a checkbox. When it is checked/unchecked, all checkboxes have to be selected/ unselected. Here is a very simple javascript to achieve this:
$("#mytable thead :checkbox").live({
change: function () {
var checked = $(this).is(":checked");
$("#mytable tbody :checkbox").attr("checked", checked);
}
});
Tag: JQuery Tmpl
Nested templates in jQuery.tmpl
I have used jQuery tmpl for a while and it is really awesome. Now I want to use some nested templates. And the thing is: it is very simple to do it: Here is the code to achieve this:
<div onclick="doo()">test</div>
<div id="container"></div>
<script id="parent-template" type="text/html">
<li>
{{tmpl t }}
</li>
</script>
<script id="red" type="text/html">
<span style="color:red">{{= title}}</span>
</script>
<script id="green" type="text/html">
<span style="color:green">{{= title}}</span>
</script>
<script type="text/javascript">
var d = \[\];
d.push({ title: "one", t: "red" });
d.push({ title: "two", t: "green" });
$.template("red", $("#red").template());
$.template("green", $("#green").template());
function doo() {
$("#parent-template").tmpl(d).appendTo("#container");
}
</script>
Simplifying jQuery tmpl interface
In one of my previous posts I showed a simple example how to retrieve data from a web service and render it with jQuery tmpl. To render this I used an id for a template and the container:
<script id="contactTemplate" type="text/html">
<div>
Name: {{= Name }} <br>
Phone: {{= Phone }}
</div>
</script>
<div id="contactContainer"></div>
```To render we select the template and container with jQuery selectors:
function onSuccess(data) { $("#contactTemplate").tmpl(data.d.results).appendTo("#contactContainer"); }
(function ($, undefined) { if ($ === undefined) { throw “Dependency: jQuery is not defined. Please check javascript imports.”; } $.extend($.expr[’:’], { // :template(name) template: function (current, index, metadata, elements) { var arg = metadata[3], d = $(current).data(“template-for”); if (d === undefined) { return false; } return arg ? arg === d : true; }, // :container(name) container: function (current, index, metadata, elements) { var arg = metadata[3], d = $(current).data(“container-for”); if (d === undefined) { return false; } return arg ? arg === d : true; } }); } (jQuery));
String.format for javascript
sprintf is actually the best javascript implementation of sprintf (string.format). But wait, shouldn’t it be some more .NET-like stuff in SharePoint environment? Indeed there is! (Well, not only in SP, but ASP.NET) String.format(“Hello {0}”, “world”) does exactly the same thing as on server side. Wow, it opens for many opportunities, e.g. in jQuery tmpl: String.format validates arguments, and if all is OK, it invokes another function String._toFormattedString:
function String$\_toFormattedString(useLocale, args) {
var result = '';
var format = args\[0\];
for (var i=0;;) {
var open = format.indexOf('{', i);
var close = format.indexOf('}', i);
if ((open < 0) && (close < 0)) {
result += format.slice(i);
break;
}
if ((close > 0) && ((close < open) || (open < 0))) {
if (format.charAt(close + 1) !== '}') {
throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
}
result += format.slice(i, close + 1);
i = close + 2;
continue;
}
result += format.slice(i, open);
i = open + 1;
if (format.charAt(i) === '{') {
result += '{';
i++;
continue;
}
if (close < 0) throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
var brace = format.substring(i, close);
var colonIndex = brace.indexOf(':');
var argNumber = parseInt((colonIndex < 0)? brace : brace.substring(0, colonIndex), 10) + 1;
if (isNaN(argNumber)) throw Error.argument('format', Sys.Res.stringFormatInvalid);
var argFormat = (colonIndex < 0)? '' : brace.substring(colonIndex + 1);
var arg = args\[argNumber\];
if (typeof(arg) === "undefined" || arg === null) {
arg = '';
}
if (arg.toFormattedString) {
result += arg.toFormattedString(argFormat);
}
else if (useLocale && arg.localeFormat) {
result += arg.localeFormat(argFormat);
}
else if (arg.format) {
result += arg.format(argFormat);
}
else
result += arg.toString();
i = close + 1;
}
return result;
}
```By the way, take a look at summary part of String.format:
/// /// /// ///
this.data in jQuery tmpl
In jQuery tmpl we can render properties with {{= SomeProperty }}. Here is an example:
<script type="text/javascript">
Writer = function (firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
Writer.prototype = {
getFullName: function () {
return this.firstName + " " + this.lastName;
}
};
$(document).ready(function () {
var writers = \[\];
writers.push(new Writer("Gennady", "Ajgi"));
writers.push(new Writer("Mišši", "Şeşpĕl"));
writers.push(new Writer("Ille", "Tuktaš"));
writers.push(new Writer("Kĕştenttin", "Ivanov"));
$("#tmpl").tmpl(writers).appendTo("#writers");
});
</script>
<script id="tmpl" type="text/html">
<li>
{{= firstName }} {{= lastName }}
</li>
</script>
<div id="writers"></div>
```It will render like:
* Gennady Ajgi
* Mišši Şeşpĕl
* Ille Tuktaš
* Kĕştenttin Ivanov
But what if we want to access the object itself, not one of the properties. Say, you want to pass the object from the array into a js function as a parameter to decide how it will be rendered, or if you want show a "calculated" property. The key word is...: this.data. this.data has the current object. After it has been rendered, we can access this object with $(this).tmplItem().data.
jQuery tmplItem and no ids
tmplItem() works even without ids. To get the current data:
$(this).tmplItem().data;
```If you want to remove, just invoke the ajax and remove with [$.parents](http://api.jquery.com/parents/):
$(this).parents(“li”).remove();
##### Updating data inside tmplItems
If you want to achieve some fancy dependency tracking, consider [knockout.js](http://knockoutjs.com/). But if you just want to update the data object inside a tmplItem, just change the object and call update:
var t = $(this).tmplItem(); var obj = t.data; obj.Address = “hello avenue”; t.update();
Tag: Extending JQuery
jQuery: select elements with a specific text
There are situations when you want to select only dom elements which only have a specific content. jQuery provides a beautiful selector :contains:
$("a:contains(Pages)")
```But what if it isn't enough to just get all the elements which contain some word? Let's check what we get if we traverse all anchors on http://sv.wikipedia.org containing "wiki":
$(“a:contains(wiki)”).each(function(i) { console.log($(this).text()); });
[![](https://sharepointkunskap.files.wordpress.com/2012/02/jquery-contains-wiki.png "jquery-contains-wiki")](https://sharepointkunskap.files.wordpress.com/2012/02/jquery-contains-wiki.png) There is another, a generic way, to filter out elements, and it is called "filter". So a little regex check will do the trick.
$(“a”).filter(function() { return /look_for/i.test($(this).text()); }
Tag: Knockout
Tag: CA
Add links to Global Navigation in My Sites
Oliver Wirkus shows how to add links to Global Navigation in My Sites. Just go to: Central Administration Applicaiton Management Manage Service Applications User Profile Service Application Configure Personalization Site
Comments from Wordpress.com
Lroth - Feb 4, 2015
There is no “configure personalization site” link. What is in the tea you are drinking?
It is actually coffee…Just kidding. This is an instruction for SharePoint 2010.
Shrink sharepoint database
A Sharepoint Database can become big and have unused spaces. To shrink database go to CA-> Health Analyzer: http://takana:1337/Lists/HealthReports/AllItems.aspx See if there is a list item about unused space in db under the Availability. Click on Repair Automatically in the opened Modal Dialog:
Change CA port number
In order to change port number for the Central Administration site, run this cmdlet:
Set-SPCentralAdministration -Port 1337
You can set any number between 1023 and 32767 except 443.
Get all comments
If you try to get comments quantity for a url, you may wonder, why there is only quantity of the comments which the current user has posted:
public int GetNumberOfNewsPageComments
(SPSite currentSite, string pageUrl, int max)
{
var serviceContext =
SPServiceContext.GetContext(currentSite);
var socialCommentManager =
new SocialCommentManager(serviceContext);
var comments = socialCommentManager
.GetComments(new Uri(pageUrl), max);
if (comments != null)
{
return comments.Length;
}
return -1;
}
```The solution is to impersonate the SPSite object with an account who has the rights to manage social data. Give this permission to the account in CA - Application Management - Service Applications - User Profile Service. [![](https://sharepointkunskap.files.wordpress.com/2011/09/manage-social-data.png?w=284 "manage-social-data")](https://sharepointkunskap.files.wordpress.com/2011/09/manage-social-data.png)
Tag: Mysite
Add links to Global Navigation in My Sites
Oliver Wirkus shows how to add links to Global Navigation in My Sites. Just go to: Central Administration Applicaiton Management Manage Service Applications User Profile Service Application Configure Personalization Site
Comments from Wordpress.com
Lroth - Feb 4, 2015
There is no “configure personalization site” link. What is in the tea you are drinking?
It is actually coffee…Just kidding. This is an instruction for SharePoint 2010.
Creating custom my site template
Here are some links to start creating a custom my site template:
If you want to take the default templates take a look at **{SharepointRoot}\TEMPLATE\SiteTempates\SPMSITE **(the site template for “my content” - an individual site collection rootweb template, and first of all {SharepointRoot}\TEMPLATE\SiteTempates\SPMSITEHOST, the host site template for my sites. They include pages and onet.xml. Both use mysite.master which can be found at:
Tag: Cookies
Tag: Parameter
Parameterize a javascript object and create url
If you want to add some parameters to an url which you want to open, you can use jQuery.param function:
var url = "some\_url";
var params = {
name: "Setner",
email: "setner@narspi.name",
mobile: "123456789"
};
var search = "?" + $.param(p);
url += search;
```It is handy, indeed. In an environment without jQuery (are there some?:) ) you can just iterate an object and join properties:
var url = “some_url”; var params = { name: “Setner”, email: “setner@narspi.name”, mobile: “123456789” }; if (url.match("/\?/g") == null) { url += “?”; } else { url += “&”; } var search = “”; for(var p in params) { search += [p, params[p]].join("="); } url += search;
Tag: SP.js
Parameterize a javascript object and create url
If you want to add some parameters to an url which you want to open, you can use jQuery.param function:
var url = "some\_url";
var params = {
name: "Setner",
email: "setner@narspi.name",
mobile: "123456789"
};
var search = "?" + $.param(p);
url += search;
```It is handy, indeed. In an environment without jQuery (are there some?:) ) you can just iterate an object and join properties:
var url = “some_url”; var params = { name: “Setner”, email: “setner@narspi.name”, mobile: “123456789” }; if (url.match("/\?/g") == null) { url += “?”; } else { url += “&”; } var search = “”; for(var p in params) { search += [p, params[p]].join("="); } url += search;
Pass arguments from/to Modal Dialog
To pass arguments from a ModalDialog is easy. Provide some buttons and invoke close function:
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, someValue);
```The first argument is result, [it is a enumeration with three alternatives](http://msdn.microsoft.com/en-us/library/ff409060.aspx): cancel, invalid and OK. The value you pass back to the main window can be a simple string, or a complex javascript object. In this example I'll create a html element which is hidden (id="modal-form" [class="s4-die"](/2011/10/14/s4-die/)):
Pass arguments to Modal Dialog and use it
In options you pass to SP.UI.ModalDialog.showModalDialog you can define args property. It can be any object with any complexity.
Vänta tills sp.js laddats
Här är en funktion som man kan använda för att vänta till sp.js laddats och köra sin funktion:
ExecuteOrDelayUntilScriptLoaded(myjsfucntion, "sp.js");
Eftersom det kan vara så att sp.js laddas med lazy loading:
<SharePoint:ScriptLink Name="SP.js"
runat="server" OnDemand="true"
Localizable="false"
Uppdatera web med js
Här är ett litet exempel:
function updateTitle() {
var ctx = new SP.ClientContext.get\_current();
this.web = ctx.get\_web();
web.set\_title('Examensarbete 2011');
this.web.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onUpdate),
Function.createDelegate(this, this.onFail)); }
function onUpdate(sender, args) {
alert('title updated');
}
function onFail(sender, args) {
alert('failed to update title. Error:'+args.get\_message());
}
javascript API i Sharepoint
Det är supersmidigt. Här är ett exempel:
function createAnnouncement(title, body) {
var ctx = new SP.ClientContext.get\_current();
var list = ctx.get\_web().get\_lists().getByTitle('Meddelanden');
var itemCreationInfo = new SP.ListItemCreationInformation();
this.newListItem = list.addItem(itemCreationInfo);
this.newListItem.set\_item("Title", title);
this.newListItem.set\_item("Body", body);
this.newListItem.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onSucceededCallback), Function.createDelegate(this, this.onFailedCallback));
}
function onSucceededCallback(sender, args) {
SP.UI.Status.addStatus("Info", "It worked!",true);
}
function onFailedCallback(sender, args) {
SP.UI.Status.addStatus("Info", "It didn't work!",true);
}
Comments from Wordpress.com
westerdaled - Feb 0, 2013
Tag: Branding
Erik Swensson's book about Sharepoint Branding
Today Erik Swensson’s book Practical SharePoint 2010 Branding and Customization came to our company. I am looking forward to read it. It’s about time to see alternatives to Randy’s starters.
Tag: DOM
Save an excel sheet as a clean table
To save an excel sheet as a html table is very easy. Just select the needed area, then go to Save as and check the selection and choose html as output format. It works fine. It even looks like it did in Excel. But what if you don’t want all this junk, you want only the plain html table (e.g. for pasting into WP). When I saved my permission levels to html, I used this javascript code. First open the html page which Excel has created in Chrome, open the Dev Tools console, load the latest jQuery into the page, and remove all unnecessary attributes and styling, remove the comments, after that you can just copy the outerHTML of the table and paste into a text editor:
Remove links to user profiles on list with javascript
Well, if you need remove links to user profiles, you can iterate all td-elements with class ms-vb-user using jQuery each function and remove a elements. Here is a little script:
$(document).ready(function() {
$(".ms-vb-user a").each(function() {
var text = $(this).text();
var span = document.createElement("span");
var user = document.createTextNode(text);
span.appendChild(user);
var parent = $(this).parent()\[0\];
parent.removeChild(this);
parent.appendChild(span);
});
});
```EDIT 2012-02-05 A much more better way to do it is [to use replaceWith in jQuery](http://stackoverflow.com/a/2409163/632117 "See a similar question and an answer on StackOverflow"):
$(".ms-vb-user a").each(function() { $(this).replaceWith(this.childNodes); });
Tag: Hierarchy
OOTB permission levels in SharePoint
There are much info about standard permission levels in SharePoint. Here is my visualization for that. Just a little bit easier to find out the right permission level. Enjoy:
Full Control (FullMask)
Design
Contribute
Read
Limited Access
Restricted Reader
Manage Hierarchy
Approve
ViewListItems
x
x
x
x
x
x
AddListItems
x
x
x
x
EditListItems
x
x
x
x
DeleteListItems
x
x
x
x
ApproveItems
x
x
OpenItems
x
x
x
x
x
x
ViewVersions
x
x
x
x
x
DeleteVersions
x
x
x
x
CancelCheckout
x
x
x
ManagePersonalViews
x
x
x
x
ManageLists
x
x
ViewFormPages
x
x
x
x
x
x
Open
x
x
x
x
x
x
x
ViewPages
x
x
x
x
x
x
AddAndCustomizePages
x
x
ApplyThemeAndBorder
x
ApplyStyleSheets
x
ViewUsageData
x
CreateSSCSite
x
x
x
x
x
ManageSubWebs
x
CreateGroups
ManagePermissions
x
BrowseDirectories
x
x
x
x
BrowseUserInfo
x
x
x
x
x
x
AddDelPrivateWebParts
x
x
x
x
UpdatePersonalWebParts
x
x
x
x
ManageWeb
x
UseClientIntegration
Tag: Ootb
OOTB permission levels in SharePoint
There are much info about standard permission levels in SharePoint. Here is my visualization for that. Just a little bit easier to find out the right permission level. Enjoy:
Full Control (FullMask)
Design
Contribute
Read
Limited Access
Restricted Reader
Manage Hierarchy
Approve
ViewListItems
x
x
x
x
x
x
AddListItems
x
x
x
x
EditListItems
x
x
x
x
DeleteListItems
x
x
x
x
ApproveItems
x
x
OpenItems
x
x
x
x
x
x
ViewVersions
x
x
x
x
x
DeleteVersions
x
x
x
x
CancelCheckout
x
x
x
ManagePersonalViews
x
x
x
x
ManageLists
x
x
ViewFormPages
x
x
x
x
x
x
Open
x
x
x
x
x
x
x
ViewPages
x
x
x
x
x
x
AddAndCustomizePages
x
x
ApplyThemeAndBorder
x
ApplyStyleSheets
x
ViewUsageData
x
CreateSSCSite
x
x
x
x
x
ManageSubWebs
x
CreateGroups
ManagePermissions
x
BrowseDirectories
x
x
x
x
BrowseUserInfo
x
x
x
x
x
x
AddDelPrivateWebParts
x
x
x
x
UpdatePersonalWebParts
x
x
x
x
ManageWeb
x
UseClientIntegration
Tag: Visualization
OOTB permission levels in SharePoint
There are much info about standard permission levels in SharePoint. Here is my visualization for that. Just a little bit easier to find out the right permission level. Enjoy:
Full Control (FullMask)
Design
Contribute
Read
Limited Access
Restricted Reader
Manage Hierarchy
Approve
ViewListItems
x
x
x
x
x
x
AddListItems
x
x
x
x
EditListItems
x
x
x
x
DeleteListItems
x
x
x
x
ApproveItems
x
x
OpenItems
x
x
x
x
x
x
ViewVersions
x
x
x
x
x
DeleteVersions
x
x
x
x
CancelCheckout
x
x
x
ManagePersonalViews
x
x
x
x
ManageLists
x
x
ViewFormPages
x
x
x
x
x
x
Open
x
x
x
x
x
x
x
ViewPages
x
x
x
x
x
x
AddAndCustomizePages
x
x
ApplyThemeAndBorder
x
ApplyStyleSheets
x
ViewUsageData
x
CreateSSCSite
x
x
x
x
x
ManageSubWebs
x
CreateGroups
ManagePermissions
x
BrowseDirectories
x
x
x
x
BrowseUserInfo
x
x
x
x
x
x
AddDelPrivateWebParts
x
x
x
x
UpdatePersonalWebParts
x
x
x
x
ManageWeb
x
UseClientIntegration
Tag: Active Directory
Remove protected Organizational Units from AD
To remove a protected OU, go to ADUC (Active Directory Users and Computers), select the domain and enable “Advanced Features” in View. When Advanced Features are enabled, just right click you OU go to Properties -> Object and uncheck “Protect against accidential deletion”. Disable Advanced Features after that. By the way. When Advanced Features are enabled you can even see the distinguished Name of objects directly in ADUC UI.
Adding organizational units to AD through powershell
Want to create some organizational structure in AD, I suppose it is specifically useful in a development environment, well the best solution is powershell then. Mastering Powershell by and Powershell.nu by Niklas Goude provide examples how to do this.
$domain = \[ADSI\]""
$ou = $domain.Create("organizationalUnit", "OU=Administration")
$ou.SetInfo()
```Be sure you write "organizationalUnit" in lower case. Otherwise you'll get "Exception calling "SetInfo" with "0" argument(s): "The specified directory service attribute or value does not exist" when you invoke **$ou.setinfo()**. If you want to create an OU under another OU, just create $domain and specify the location: \[code language="powershell"\] $domain = \[ADSI\]"OU=Administration, dc=takana, dc=local" $company = $domain.Create("organizationalUnit", "OU=Accounting") $company.SetInfo()</pre> To save some other properties: <pre>$ou.put("Description", "this is a dummy ou") $ou.SetInfo() \[/code\]
#### Update 2013-12-10
In PowerShell V3 you have a built-in cmdlet for doing that once you add the Active Directory role in your server. It simple as that: \[code language="powershell"\] New-ADOrganizationalUnit "Accounting" -Path "dc=takana, dc=local" \[/code\]
Find the current Active Directory Domain
While working with Active Directory within SharePoint we probably don’t need to specify the domain or the root container. We can the current values. Here is a simple method from a console application just to demonstrate:
internal static void GetDomain()
{
var context = new DirectoryContext(DirectoryContextType.Domain);
var domain = Domain.GetDomain(context);
Console.WriteLine("Full domain:");
Console.WriteLine(domain.Name); //takana.local
Console.WriteLine();
Console.WriteLine("root container");
var parts = domain.Name.Split(new\[\] {"."}, StringSplitOptions.RemoveEmptyEntries);
var dcParts = parts.Select(n => "dc=" + n).ToArray();
var d = string.Join(",", dcParts); //dc=takana, dc=local
Console.WriteLine(d);
}
First we get get the full domain, then we split and join them again.
Check if a user is in a OU
To get all users from an AD group is very simple:
groupName = "an\_ad\_group";
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName);
var principals = grp.GetMembers(true);
```But what about an OU? There is no OrganizationUnitPrincipal... [Well, there is a solution: to instantiate a context for your OU](http://stackoverflow.com/a/1927476/632117 "See the solution on Stack Overflow"): So if you want to check if a user in a OU:
internal static bool IsUserInOu(string ou, string name) { var domain = “takana.local”; var container = string.Format(“OU={0}, DC=takana, DC=local”, ou); var ctx = new PrincipalContext(ContextType.Domain, domain, container); var up = new UserPrincipal(ctx); var ps = new PrincipalSearcher(up);
Powershell scripts for AD
A tip for all who want to administer AD with powershell: Idera Powershell scripts. Just sign up and get the free scripts for AD, SQL, Exchange and Sharepoint. I personally prefer to user modules, so I change the file extension from ps1 to psm1 and then I can use import functions as modules. Here is a simple example for creating for domain users:
import-module .\\New-IADUser1.psm1
function Add-User($name) {
New-IADUser -Name $name
-sAMAccountname $name
-ParentContainer 'CN=Users, DC=contoso, DC=com'
-Password 'SvenskaAkademien1786'
-EnableAccount -PasswordNeverExpires
}
Add-User "user01"
Add-User "user02"
Add-User "user03"
Add-User "user04"
update 2012-03-15: nice script from Ryan
Ryan Dennis has created a very handy script for creating random users. In PowerShell v3.0 there is a cmdlet for creating users: New-ADUser. So the function above can be rewritten like that: [code language=“powershell”] Import-Module ActiveDirectory -ErrorAction SilentlyContinue function Add-User($name) { $password = ConvertTo-SecureString ‘SvenskaAkademien1786’ -AsPlainText -Force New-ADUser -Name $name -sAMAccountname $name -Path ‘CN=Users, DC=contoso, DC=com’ -AccountPassword $password -Enabled $true -PasswordNeverExpires $true } Add-User “user01” Add-User “user02” Add-User “user03” Add-User “user04” [/code]
Get Distinguished Name for a user
To get the distinguished name for a user, it isn’t enough to get an SPUser object. The distinguished name is the unique string for identifying a user in Active Directory (eg. CN=BeforeDAfter,OU=Test,DC=North America,DC=Fabrikam,DC=COM) Even using UserProfile object is not that clear. The distinguished name can be found in a property which can be retrieved with brackets: up[PropertyConstants.DistinguishedName]
public static string GetDistinguishedName(string login)
{
var dn = "";
UserProfile up;
using (var site = new SPSite("http://dev"))
{
var serviceContext = SPServiceContext.GetContext(site);
var upm = new UserProfileManager(serviceContext);
var exists = upm.UserExists(login);
if (!exists)
upm.CreateUserProfile(login);
if (exists)
{
up = upm.GetUserProfile(login);
dn = up\[PropertyConstants.DistinguishedName\].Value.ToString();
}
}
return dn;
}
```The code is simplified and doesn't contain any error handling. And a better handling of upm.UserExists must be implemented: If upm.CreateUserProfile(login) runs, it doesn't make it so quickly and the next step won't run (upm.GetUserProfile). If you are not working in SP Context, you can see the distinguished name for a user in Powershell:
import-module activedirectory $u = get-aduser administrator $u.DistinguishedName
Retrieve information from AD
Here is a a link you can start with. To test AD, install AD. Then we canplay with it. Take a look those examples, too.
PrincipalSearcher vs. DirectorySearcher
What is the difference?
OU
Here are two examples (one for PrincipalSearcher and the other for DirectorySearcher) to retrieve users from an OU:
//PrincipalSearcher
internal static void ListPrincipalsFromOu()
{
using(var ctx = new PrincipalContext(ContextType.Domain, "takana.local", "OU=SOME\_OU ,DC=takana, DC=local"))
{
using (var up = new UserPrincipal(ctx))
{
using (var ps = new PrincipalSearcher(up))
{
using (var res = ps.FindAll())
{
foreach (var p in res)
{
Console.WriteLine(p.SamAccountName);
}
}
}
}
}
}
//DirectorySearcher
internal static void ListAdEntriesFromOu()
{
const string property = "sAMAccountName";
var ldapcon = new DirectoryEntry("takana.local") {
Path = "LDAP://OU=SOME\_OU,DC=takana,DC=local"
};
var search = new DirectorySearcher(ldapcon);
search.PropertiesToLoad.Add(property);
using (var results = search.FindAll())
{
foreach (System.DirectoryServices.SearchResult result in results)
{
using (var entry = result.GetDirectoryEntry())
{
if (entry.Properties\[property\].Count > 0)
{
Console.WriteLine(entry.Properties\[property\]\[0\]);
}
}
}
}
}
Tag: AD
Remove protected Organizational Units from AD
To remove a protected OU, go to ADUC (Active Directory Users and Computers), select the domain and enable “Advanced Features” in View. When Advanced Features are enabled, just right click you OU go to Properties -> Object and uncheck “Protect against accidential deletion”. Disable Advanced Features after that. By the way. When Advanced Features are enabled you can even see the distinguished Name of objects directly in ADUC UI.
Find the current Active Directory Domain
While working with Active Directory within SharePoint we probably don’t need to specify the domain or the root container. We can the current values. Here is a simple method from a console application just to demonstrate:
internal static void GetDomain()
{
var context = new DirectoryContext(DirectoryContextType.Domain);
var domain = Domain.GetDomain(context);
Console.WriteLine("Full domain:");
Console.WriteLine(domain.Name); //takana.local
Console.WriteLine();
Console.WriteLine("root container");
var parts = domain.Name.Split(new\[\] {"."}, StringSplitOptions.RemoveEmptyEntries);
var dcParts = parts.Select(n => "dc=" + n).ToArray();
var d = string.Join(",", dcParts); //dc=takana, dc=local
Console.WriteLine(d);
}
First we get get the full domain, then we split and join them again.
Check if a user is in a OU
To get all users from an AD group is very simple:
groupName = "an\_ad\_group";
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName);
var principals = grp.GetMembers(true);
```But what about an OU? There is no OrganizationUnitPrincipal... [Well, there is a solution: to instantiate a context for your OU](http://stackoverflow.com/a/1927476/632117 "See the solution on Stack Overflow"): So if you want to check if a user in a OU:
internal static bool IsUserInOu(string ou, string name) { var domain = “takana.local”; var container = string.Format(“OU={0}, DC=takana, DC=local”, ou); var ctx = new PrincipalContext(ContextType.Domain, domain, container); var up = new UserPrincipal(ctx); var ps = new PrincipalSearcher(up);
Powershell scripts for AD
A tip for all who want to administer AD with powershell: Idera Powershell scripts. Just sign up and get the free scripts for AD, SQL, Exchange and Sharepoint. I personally prefer to user modules, so I change the file extension from ps1 to psm1 and then I can use import functions as modules. Here is a simple example for creating for domain users:
import-module .\\New-IADUser1.psm1
function Add-User($name) {
New-IADUser -Name $name
-sAMAccountname $name
-ParentContainer 'CN=Users, DC=contoso, DC=com'
-Password 'SvenskaAkademien1786'
-EnableAccount -PasswordNeverExpires
}
Add-User "user01"
Add-User "user02"
Add-User "user03"
Add-User "user04"
update 2012-03-15: nice script from Ryan
Ryan Dennis has created a very handy script for creating random users. In PowerShell v3.0 there is a cmdlet for creating users: New-ADUser. So the function above can be rewritten like that: [code language=“powershell”] Import-Module ActiveDirectory -ErrorAction SilentlyContinue function Add-User($name) { $password = ConvertTo-SecureString ‘SvenskaAkademien1786’ -AsPlainText -Force New-ADUser -Name $name -sAMAccountname $name -Path ‘CN=Users, DC=contoso, DC=com’ -AccountPassword $password -Enabled $true -PasswordNeverExpires $true } Add-User “user01” Add-User “user02” Add-User “user03” Add-User “user04” [/code]
Get Distinguished Name for a user
To get the distinguished name for a user, it isn’t enough to get an SPUser object. The distinguished name is the unique string for identifying a user in Active Directory (eg. CN=BeforeDAfter,OU=Test,DC=North America,DC=Fabrikam,DC=COM) Even using UserProfile object is not that clear. The distinguished name can be found in a property which can be retrieved with brackets: up[PropertyConstants.DistinguishedName]
public static string GetDistinguishedName(string login)
{
var dn = "";
UserProfile up;
using (var site = new SPSite("http://dev"))
{
var serviceContext = SPServiceContext.GetContext(site);
var upm = new UserProfileManager(serviceContext);
var exists = upm.UserExists(login);
if (!exists)
upm.CreateUserProfile(login);
if (exists)
{
up = upm.GetUserProfile(login);
dn = up\[PropertyConstants.DistinguishedName\].Value.ToString();
}
}
return dn;
}
```The code is simplified and doesn't contain any error handling. And a better handling of upm.UserExists must be implemented: If upm.CreateUserProfile(login) runs, it doesn't make it so quickly and the next step won't run (upm.GetUserProfile). If you are not working in SP Context, you can see the distinguished name for a user in Powershell:
import-module activedirectory $u = get-aduser administrator $u.DistinguishedName
Tag: OU
Remove protected Organizational Units from AD
To remove a protected OU, go to ADUC (Active Directory Users and Computers), select the domain and enable “Advanced Features” in View. When Advanced Features are enabled, just right click you OU go to Properties -> Object and uncheck “Protect against accidential deletion”. Disable Advanced Features after that. By the way. When Advanced Features are enabled you can even see the distinguished Name of objects directly in ADUC UI.
Check if a user is in a OU
To get all users from an AD group is very simple:
groupName = "an\_ad\_group";
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName);
var principals = grp.GetMembers(true);
```But what about an OU? There is no OrganizationUnitPrincipal... [Well, there is a solution: to instantiate a context for your OU](http://stackoverflow.com/a/1927476/632117 "See the solution on Stack Overflow"): So if you want to check if a user in a OU:
internal static bool IsUserInOu(string ou, string name) { var domain = “takana.local”; var container = string.Format(“OU={0}, DC=takana, DC=local”, ou); var ctx = new PrincipalContext(ContextType.Domain, domain, container); var up = new UserPrincipal(ctx); var ps = new PrincipalSearcher(up);
Retrieve information from AD
Here is a a link you can start with. To test AD, install AD. Then we canplay with it. Take a look those examples, too.
PrincipalSearcher vs. DirectorySearcher
What is the difference?
OU
Here are two examples (one for PrincipalSearcher and the other for DirectorySearcher) to retrieve users from an OU:
//PrincipalSearcher
internal static void ListPrincipalsFromOu()
{
using(var ctx = new PrincipalContext(ContextType.Domain, "takana.local", "OU=SOME\_OU ,DC=takana, DC=local"))
{
using (var up = new UserPrincipal(ctx))
{
using (var ps = new PrincipalSearcher(up))
{
using (var res = ps.FindAll())
{
foreach (var p in res)
{
Console.WriteLine(p.SamAccountName);
}
}
}
}
}
}
//DirectorySearcher
internal static void ListAdEntriesFromOu()
{
const string property = "sAMAccountName";
var ldapcon = new DirectoryEntry("takana.local") {
Path = "LDAP://OU=SOME\_OU,DC=takana,DC=local"
};
var search = new DirectorySearcher(ldapcon);
search.PropertiesToLoad.Add(property);
using (var results = search.FindAll())
{
foreach (System.DirectoryServices.SearchResult result in results)
{
using (var entry = result.GetDirectoryEntry())
{
if (entry.Properties\[property\].Count > 0)
{
Console.WriteLine(entry.Properties\[property\]\[0\]);
}
}
}
}
}
Tag: AppSettings
Settings in Sharepoint_config database instead of appSettings
An alternative to store key-value paired properties in appSettings in web.config we can use Sharepoint_config database by creating our own SPPersistedObject. First we have to create a class which inherits from SPPersistedObject and decorate its properties with [Persisted]:
namespace Takana.SharePoint
{
public class Settings: SPPersistedObject
{
\[Persisted\]
public string DbConString;
public LinkCheckerPersistedSettings() { }
public LinkCheckerPersistedSettings(string name, SPPersistedObject parent) : base(name, parent) { }
}
}
```Then we must create such an object. Let's do it in Powershell:
if(-not(Get-PSSnapin | Where { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { Add-PSSnapin Microsoft.SharePoint.PowerShell }
Tag: Settings
Settings in Sharepoint_config database instead of appSettings
An alternative to store key-value paired properties in appSettings in web.config we can use Sharepoint_config database by creating our own SPPersistedObject. First we have to create a class which inherits from SPPersistedObject and decorate its properties with [Persisted]:
namespace Takana.SharePoint
{
public class Settings: SPPersistedObject
{
\[Persisted\]
public string DbConString;
public LinkCheckerPersistedSettings() { }
public LinkCheckerPersistedSettings(string name, SPPersistedObject parent) : base(name, parent) { }
}
}
```Then we must create such an object. Let's do it in Powershell:
if(-not(Get-PSSnapin | Where { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { Add-PSSnapin Microsoft.SharePoint.PowerShell }
Version 0.2.6: Settings improvement
Now a user can choose what to see on the map. Maybe only bike pumps or everything. To do that I created a new class ListPreferenceMultiSelect extends ListPreference which is more or less taken from DroidWeb tutorial. The source ListPreferenceMultiSelect.java was improved a little bit: The constructor checks if entries are not empty before creating indices. For the second a new method was added: prepareValueToStore, the opposite one of parseStoredValue. Here is my ListPreferenceMultiSelect.java and in the version 0.2.6. This version was published on the Market and committed to the repository.
Tag: Sharepoint_config
Settings in Sharepoint_config database instead of appSettings
An alternative to store key-value paired properties in appSettings in web.config we can use Sharepoint_config database by creating our own SPPersistedObject. First we have to create a class which inherits from SPPersistedObject and decorate its properties with [Persisted]:
namespace Takana.SharePoint
{
public class Settings: SPPersistedObject
{
\[Persisted\]
public string DbConString;
public LinkCheckerPersistedSettings() { }
public LinkCheckerPersistedSettings(string name, SPPersistedObject parent) : base(name, parent) { }
}
}
```Then we must create such an object. Let's do it in Powershell:
if(-not(Get-PSSnapin | Where { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { Add-PSSnapin Microsoft.SharePoint.PowerShell }
Tag: PowerShell V3
Adding organizational units to AD through powershell
Want to create some organizational structure in AD, I suppose it is specifically useful in a development environment, well the best solution is powershell then. Mastering Powershell by and Powershell.nu by Niklas Goude provide examples how to do this.
$domain = \[ADSI\]""
$ou = $domain.Create("organizationalUnit", "OU=Administration")
$ou.SetInfo()
```Be sure you write "organizationalUnit" in lower case. Otherwise you'll get "Exception calling "SetInfo" with "0" argument(s): "The specified directory service attribute or value does not exist" when you invoke **$ou.setinfo()**. If you want to create an OU under another OU, just create $domain and specify the location: \[code language="powershell"\] $domain = \[ADSI\]"OU=Administration, dc=takana, dc=local" $company = $domain.Create("organizationalUnit", "OU=Accounting") $company.SetInfo()</pre> To save some other properties: <pre>$ou.put("Description", "this is a dummy ou") $ou.SetInfo() \[/code\]
#### Update 2013-12-10
In PowerShell V3 you have a built-in cmdlet for doing that once you add the Active Directory role in your server. It simple as that: \[code language="powershell"\] New-ADOrganizationalUnit "Accounting" -Path "dc=takana, dc=local" \[/code\]
Tag: Sptimerjob
Install a custom timer job in Powershell
First we have to create a class for our timer job which inherits SPTimerJobDefinition, build it and deploy it.
public class TakanaTimer : SPJobDefinition
{
public TakanaTimer(){}
public TakanaTimer(string jobName, SPService service,
SPServer server, SPJobLockType targetType)
: base(jobName, service, server, targetType) { }
public TakanaTimer(string jobName, SPWebApplication webapp)
: base(jobName, webapp, null, SPJobLockType.ContentDatabase)
{
Title = jobName;
}
public override void Execute(Guid contentDbId)
{
Log.Info("Running Takana Timer");
}
}
There is a powershell example for this, but it has not been updated since MOSS.
Tag: Db
Shrink sharepoint database
A Sharepoint Database can become big and have unused spaces. To shrink database go to CA-> Health Analyzer: http://takana:1337/Lists/HealthReports/AllItems.aspx See if there is a list item about unused space in db under the Availability. Click on Repair Automatically in the opened Modal Dialog:
MongoDB shell, learn directly in browser
Are you also curious about NoSQL databases. Well, MongoDB is one of the most known ones. MongoDB has a javascript syntax (json), I like it. Try out the interactive shell at the mongodb site.
Quickstart on Ubuntu
To test it on Ubuntu, just install an existing apt-package:
sudo apt-get install mongodb
Återskapa koppling till login i DB efter restore
Om du har kört restore på en databas, så kan det hända att det inte går att ändra rättigheter, och den login du använt inte kan se databasen. SQL Server spottar ut felmeddelandet med kod 15023:
The database is not accessible. (Object Explorer)
Om det är WebService som i sin tur anropar databasen, kan det komma ett sådant felmeddelande:
The underlying provider failed on Open.
Lösningen är att uppdatera kopplingen. Hämtat från denna blog.
Tag: LINQ
Set ObjectTrackingEnabled = false when reading
In LINQ 2 SP we work with a data context. By default a data context has the property ObjectTrackingEnabled = true. This property is crucial for all other operations in CRUD except Read. I performed a mini experiment. I created 20 000 items in my task list. Every seventh item contains “pärla”. Allright, here is what I found out:
2857 / 20 000 items
ObjectTrackingEnabled = true
Increase performance while retrieving data with LINQ to SP
If you are just intrested in getting data, not writing to the source like SubmitChange, you can disable ObjectTracking and increase the performance.
context.ObjectTrackingEnabled = false;
```I found this tip on page 248 in the book "[Sharepoint 2010 as a development platform](http://www.apress.com/9781430227069)"
Komma åt andra tabeller via foreign keys i LINQ
I stället för att köra join-statements i LINQ som jag visat i ett av mina tidigare inlägg, kan man utnyttja inbyggda möjligheter att komma åt saker via foreign keys. Jfr de här två:
var q = from s in ctx.Staffs
join si in context.StaffOnCourseInstances
on s.uid equals si.uid
where si.CourseInstanceId == 1435
select new { s.adAccount };
```och
var q = from c in context.StaffOnCourseInstances where c.CourseInstanceId == 1435 select new { c.Staff.adAccount };
join i LINQ
LINQ är ett kraftfullt verktyg. Det som kan vara lite krångligt är join. Men om man gör rätt blir det bra. Låt oss titta på det sql-exemplet:
SELECT s.adAccount
FROM Staff s join StaffOnCourseInstance si
ON s.uid = si.uid
WHERE si.CourseInstanceId = 1435
För att köra motsvarande LINQ måste vi vara väldigt noga med on:
var testQuery = (from s in ctx.Staffs
join si in ctx.StaffOnCourseInstances
on s.uid equals si.uid
where si.CourseInstanceId == 1435
select new { s.adAccount });
```Edit 20101031: Det finns ett smidigare sätt att komma åt information i relaterade tabeller. Se mitt inlägg från 20101031 om [LINQ och foreign keys](https://sharepointkunskap.wordpress.com/2010/10/31/komma-at-andra-tabeller-via-foreign-keys-i-linq/).
Tag: LINQ to SP
Set ObjectTrackingEnabled = false when reading
In LINQ 2 SP we work with a data context. By default a data context has the property ObjectTrackingEnabled = true. This property is crucial for all other operations in CRUD except Read. I performed a mini experiment. I created 20 000 items in my task list. Every seventh item contains “pärla”. Allright, here is what I found out:
2857 / 20 000 items
ObjectTrackingEnabled = true
Increase performance while retrieving data with LINQ to SP
If you are just intrested in getting data, not writing to the source like SubmitChange, you can disable ObjectTracking and increase the performance.
context.ObjectTrackingEnabled = false;
```I found this tip on page 248 in the book "[Sharepoint 2010 as a development platform](http://www.apress.com/9781430227069)"
Tag: ObjectTrackingEnabled
Set ObjectTrackingEnabled = false when reading
In LINQ 2 SP we work with a data context. By default a data context has the property ObjectTrackingEnabled = true. This property is crucial for all other operations in CRUD except Read. I performed a mini experiment. I created 20 000 items in my task list. Every seventh item contains “pärla”. Allright, here is what I found out:
2857 / 20 000 items
ObjectTrackingEnabled = true
Tag: Stopwatch
Set ObjectTrackingEnabled = false when reading
In LINQ 2 SP we work with a data context. By default a data context has the property ObjectTrackingEnabled = true. This property is crucial for all other operations in CRUD except Read. I performed a mini experiment. I created 20 000 items in my task list. Every seventh item contains “pärla”. Allright, here is what I found out:
2857 / 20 000 items
ObjectTrackingEnabled = true
Simple stopwatch in javascript
If some javascript code takes too much time to execute, you probably want to see what time your code or a part of the code takes to run. I found an idea in Dave Cranes Ajax in Action. The book is a little bit old and the code provided below has been changed and simplified:
var stopwatch = {};
stopwatch.watches = \[\];
stopwatch.getWatch = function(id, startNow) {
var watch = stopwatch.watches\[id\];
if (!watch) {
watch = new stopwatch.StopWatch(id);
}
if (startNow) {
watch.start();
}
return watch;
};
stopwatch.StopWatch = function (id) {
this.id = id;
stopwatch.watches\[id\] = this;
this.events = \[\];
this.total = 0;
this.count = 0;
};
stopwatch.StopWatch.prototype.start = function() {
this.current = new stopwatch.TimedEvent();
};
stopwatch.StopWatch.prototype.stop = function() {
if (this.current) {
this.current.stop();
this.events.push(this.current);
this.count++;
this.total += this.current.duration;
this.current = null;
}
};
stopwatch.TimedEvent = function () {
this.start = new Date();
this.duration = 0;
};
stopwatch.TimedEvent.prototype.stop = function() {
var stop = new Date();
this.duration = stop - this.start;
};
Tag: Domain
Find the current Active Directory Domain
While working with Active Directory within SharePoint we probably don’t need to specify the domain or the root container. We can the current values. Here is a simple method from a console application just to demonstrate:
internal static void GetDomain()
{
var context = new DirectoryContext(DirectoryContextType.Domain);
var domain = Domain.GetDomain(context);
Console.WriteLine("Full domain:");
Console.WriteLine(domain.Name); //takana.local
Console.WriteLine();
Console.WriteLine("root container");
var parts = domain.Name.Split(new\[\] {"."}, StringSplitOptions.RemoveEmptyEntries);
var dcParts = parts.Select(n => "dc=" + n).ToArray();
var d = string.Join(",", dcParts); //dc=takana, dc=local
Console.WriteLine(d);
}
First we get get the full domain, then we split and join them again.
Tag: Coding
qoutes in @ strings
I use @-prefixed strings very often. You can use line breaks as much as you want. Very useful e.g. when I must create an xml in code. One thing I didn’t know was that you CAN use quotation marks inside @-strings. But you must write double quoutes like:
var t = @"säg ""hej""
och ""hå""";
Tag: Duration
Simple stopwatch in javascript
If some javascript code takes too much time to execute, you probably want to see what time your code or a part of the code takes to run. I found an idea in Dave Cranes Ajax in Action. The book is a little bit old and the code provided below has been changed and simplified:
var stopwatch = {};
stopwatch.watches = \[\];
stopwatch.getWatch = function(id, startNow) {
var watch = stopwatch.watches\[id\];
if (!watch) {
watch = new stopwatch.StopWatch(id);
}
if (startNow) {
watch.start();
}
return watch;
};
stopwatch.StopWatch = function (id) {
this.id = id;
stopwatch.watches\[id\] = this;
this.events = \[\];
this.total = 0;
this.count = 0;
};
stopwatch.StopWatch.prototype.start = function() {
this.current = new stopwatch.TimedEvent();
};
stopwatch.StopWatch.prototype.stop = function() {
if (this.current) {
this.current.stop();
this.events.push(this.current);
this.count++;
this.total += this.current.duration;
this.current = null;
}
};
stopwatch.TimedEvent = function () {
this.start = new Date();
this.duration = 0;
};
stopwatch.TimedEvent.prototype.stop = function() {
var stop = new Date();
this.duration = stop - this.start;
};
Tag: Snapin
Add Sharepoint Snap-in if needed
Just include it in your script or function:
if(-not(Get-PSSnapin |
Where { $_.Name -eq "Microsoft.SharePoint.PowerShell"})) {
Add-PSSnapin Microsoft.SharePoint.PowerShell}
By the way, I found it in PowerShell for Microsoft SharePoint 2010 Administrators by Niklas Goude and Mattias Karlsson. Powershell for Sharepoint Administrators. UPDATE: I found a better way to check a variable for null: Thomas Maurer. Powershell: check variable for null. It is like in javascript, just put it in the if-statement to test if it exists or not:
Tag: Core.js
Reload page in js: RefreshPage
There are many ways to reload / refresh a page in javascript. One of them is as in discoveringsharepoint.wordpress.com describes:
window.location.reload()
```Today I found some tools which are shipped with ASP.NET/SharePoint to reload a page. The big advantage of them they are designed to work with SharePoint and take all possible aspects of page life cycle into account. The javascript function to refresh a page is just called, guess..: **RefreshPage** and it resides in init.js:
//init.js: function RefreshPageTo(evt, url, bForceSubmit) {ULSA13:; CoreInvoke(’_RefreshPageTo’, evt, url, bForceSubmit); }
Tag: Postback
Reload page in js: RefreshPage
There are many ways to reload / refresh a page in javascript. One of them is as in discoveringsharepoint.wordpress.com describes:
window.location.reload()
```Today I found some tools which are shipped with ASP.NET/SharePoint to reload a page. The big advantage of them they are designed to work with SharePoint and take all possible aspects of page life cycle into account. The javascript function to refresh a page is just called, guess..: **RefreshPage** and it resides in init.js:
//init.js: function RefreshPageTo(evt, url, bForceSubmit) {ULSA13:; CoreInvoke(’_RefreshPageTo’, evt, url, bForceSubmit); }
Undvika postback i button
Äntligen har jag kommit på hur man kan skippa oönskad postback i button. Det finns många olika lösningar. Här är ett intressant inlägg på stackoverflow om det. Men det enklaste sättet är egentligen bara lägga till
return false;
```i onclick... Här är lösningen
using System.Web.UI.HtmlControls;
…
HtmlButton HtmlButtonSendMail;
protected override void CreateChildControls()
{
…
#region Configure Send Email
HtmlButtonSendMail = new HtmlButton();
HtmlButtonSendMail.InnerText = “Send Email”;
HtmlButtonSendMail.ID = “HtmlButtonSendMail”;
string script = “”;
script += “SP.UI.Notify.addNotification(‘Loading..’, false);”;
script += “var options = {”;
script += " url: \"../_layouts/Toolbox/SendMail.aspx\",";
script += " width: 800,";
script += " height: 680,";
script += " allowMaximize: false";
script += “};”;
script += “SP.UI.ModalDialog.showModalDialog(options);”;
script += “return false;”;
HtmlButtonSendMail.Attributes.Add(“onclick”, script);
HtmlButtonSendMail.Attributes.Add(“title”,
“Skicka mail till\r\nde här personerna”);
Controls.Add(HtmlButtonSendMail);
#endregion
…
}
…
protected override void Render(HtmlTextWriter writer)
{
…
writer.RenderBeginTag(HtmlTextWriterTag.Div);
HtmlButtonSendMail.RenderControl(writer);
writer.RenderEndTag();//div
…
}
… other javascript stuff needed to work with your ajax solution
Tag: Reload
Reload page in js: RefreshPage
There are many ways to reload / refresh a page in javascript. One of them is as in discoveringsharepoint.wordpress.com describes:
window.location.reload()
```Today I found some tools which are shipped with ASP.NET/SharePoint to reload a page. The big advantage of them they are designed to work with SharePoint and take all possible aspects of page life cycle into account. The javascript function to refresh a page is just called, guess..: **RefreshPage** and it resides in init.js:
//init.js: function RefreshPageTo(evt, url, bForceSubmit) {ULSA13:; CoreInvoke(’_RefreshPageTo’, evt, url, bForceSubmit); }
Tag: IIS
Tag: Format
String.format for javascript
sprintf is actually the best javascript implementation of sprintf (string.format). But wait, shouldn’t it be some more .NET-like stuff in SharePoint environment? Indeed there is! (Well, not only in SP, but ASP.NET) String.format(“Hello {0}”, “world”) does exactly the same thing as on server side. Wow, it opens for many opportunities, e.g. in jQuery tmpl: String.format validates arguments, and if all is OK, it invokes another function String._toFormattedString:
function String$\_toFormattedString(useLocale, args) {
var result = '';
var format = args\[0\];
for (var i=0;;) {
var open = format.indexOf('{', i);
var close = format.indexOf('}', i);
if ((open < 0) && (close < 0)) {
result += format.slice(i);
break;
}
if ((close > 0) && ((close < open) || (open < 0))) {
if (format.charAt(close + 1) !== '}') {
throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
}
result += format.slice(i, close + 1);
i = close + 2;
continue;
}
result += format.slice(i, open);
i = open + 1;
if (format.charAt(i) === '{') {
result += '{';
i++;
continue;
}
if (close < 0) throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
var brace = format.substring(i, close);
var colonIndex = brace.indexOf(':');
var argNumber = parseInt((colonIndex < 0)? brace : brace.substring(0, colonIndex), 10) + 1;
if (isNaN(argNumber)) throw Error.argument('format', Sys.Res.stringFormatInvalid);
var argFormat = (colonIndex < 0)? '' : brace.substring(colonIndex + 1);
var arg = args\[argNumber\];
if (typeof(arg) === "undefined" || arg === null) {
arg = '';
}
if (arg.toFormattedString) {
result += arg.toFormattedString(argFormat);
}
else if (useLocale && arg.localeFormat) {
result += arg.localeFormat(argFormat);
}
else if (arg.format) {
result += arg.format(argFormat);
}
else
result += arg.toString();
i = close + 1;
}
return result;
}
```By the way, take a look at summary part of String.format:
/// /// /// ///
Tag: NavBarLink
Add global navigation links in Powershell and Feature Receiver
I think, powershell is the best way to do configurations you have to do once. Adding some links to global (top) navigation is one of them:
asnp microsoft.sharepoint.powershell
$w = get-spweb http://takana
$l = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Smells like team spirit", "/pages/teamspirit.aspx")
$w.Navigation.TopNavigationBar.AddAsLast($l)
Feature receiver
The alternative is to create a web scoped feature and provide properties:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
var web = properties.Feature.Parent as SPWeb;
var prop = properties.Feature.Properties\["MyGlobalLinks"\];
var links = prop.Value.Split(new\[\] { ";#" },
StringSplitOptions.RemoveEmptyEntries);
foreach (var item in links)
{
var newLink = item.Split(new\[\] { ";" },
StringSplitOptions.RemoveEmptyEntries);
var newMenuItem =
new SPNavigationNode(newLink\[0\], newLink\[1\]);
web.Navigation.TopNavigationBar.AddAsLast(newMenuItem);
}
}
```This feature can be prefereably hidden. The properties are passed in onet:
NavBarLink
I found even a third way to add links to global navigation: NavBarLink
Tag: SPFeature
Add global navigation links in Powershell and Feature Receiver
I think, powershell is the best way to do configurations you have to do once. Adding some links to global (top) navigation is one of them:
asnp microsoft.sharepoint.powershell
$w = get-spweb http://takana
$l = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Smells like team spirit", "/pages/teamspirit.aspx")
$w.Navigation.TopNavigationBar.AddAsLast($l)
Feature receiver
The alternative is to create a web scoped feature and provide properties:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
var web = properties.Feature.Parent as SPWeb;
var prop = properties.Feature.Properties\["MyGlobalLinks"\];
var links = prop.Value.Split(new\[\] { ";#" },
StringSplitOptions.RemoveEmptyEntries);
foreach (var item in links)
{
var newLink = item.Split(new\[\] { ";" },
StringSplitOptions.RemoveEmptyEntries);
var newMenuItem =
new SPNavigationNode(newLink\[0\], newLink\[1\]);
web.Navigation.TopNavigationBar.AddAsLast(newMenuItem);
}
}
```This feature can be prefereably hidden. The properties are passed in onet:
NavBarLink
I found even a third way to add links to global navigation: NavBarLink
Retention policies
Ziegler provides a cool intro, implementation sample and much more. When deployed we can apply this policy to a contenttype in the UI, or in code. To create our own expiration logic we have to implement IExpirationFormula and its ComputeExpireDate:
public class TaskExpiration : IExpirationFormula
{
public DateTime? ComputeExpireDate(SPListItem item,
XmlNode parametersData)
{
if (!item\["Status"\].Equals("Completed"))
{
return null;
}
var dt = (DateTime) item\["Modified"\];
return dt.AddDays(30);
}
}
```In order to see IExpirationFormula, add a reference to Microsoft.Office.Policy (and maybe Microsoft.Office.DocumentManagement): [![](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png "policy-dll")](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png) To see our custom retention policy, we have to register it in xml, we can do it in Feature Receiver like [Yaroslav](http://www.sharemuch.com/2011/01/10/creation-custom-retention-policies-for-sharepoint-2010-libraries/):
public override void FeatureActivated(SPFeatureReceiverProperties properties) { const string xmlManifest = “<PolicyResource xmlns=‘urn:schemas-microsoft-com:office:server:policy’” + " id = ‘Takana.TaskRetentionPolicy’" + " featureId=‘Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration’" + " type = ‘DateCalculator’>" + " Takana Task Retention Policy" + “Tasks expire 30 days after they have been completed” + “Takana.SharePoint, Version=1.0.0.0, Culture=neutral, " + “PublicKeyToken=920c0327f8b01d97” + “Takana.SharePoint.Policies.TaskExpiration” + “”; PolicyResourceCollection.Add(xmlManifest); }
Uninstall custom features in a batch
A funny powershell command I came upon today together with my colleague. Remove all your custom features (which start with something, say contoso):
Get-SPFeature
| Where { $\_.DisplayName.StartsWith("Contoso.") }
| ForEach { Uninstall-SPFeature $\_.Id -confirm:0 -force }
Have fun!
Tag: Onet
Can't add a global site navigation link
If you encounter problems while customizing global site navigation in a custom site definition for SharePoint 2010, you probably can solve it by adding the necessary navbar element in navbars section of the onet.xml:
<NavBar Name="$Resources:core,category\_Top;"
Separator="&nbsp;&nbsp;&nbsp;"
Body="<a ID='onettopnavbar#LABEL\_ID#' href='#URL#' accesskey='J'>#LABEL#</a>"
ID="1002" />
It solved the problems for me :).
Comments from Wordpress.com
Chilly - Nov 3, 2012
How did you edit the Onet.XML file? What if this is only happening on one site in a whole site colleciton will this help this site as well. Thanks for any help you can give. This problem is bugging me on one of my sites.
Tag: Document Management
Retention policies
Ziegler provides a cool intro, implementation sample and much more. When deployed we can apply this policy to a contenttype in the UI, or in code. To create our own expiration logic we have to implement IExpirationFormula and its ComputeExpireDate:
public class TaskExpiration : IExpirationFormula
{
public DateTime? ComputeExpireDate(SPListItem item,
XmlNode parametersData)
{
if (!item\["Status"\].Equals("Completed"))
{
return null;
}
var dt = (DateTime) item\["Modified"\];
return dt.AddDays(30);
}
}
```In order to see IExpirationFormula, add a reference to Microsoft.Office.Policy (and maybe Microsoft.Office.DocumentManagement): [![](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png "policy-dll")](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png) To see our custom retention policy, we have to register it in xml, we can do it in Feature Receiver like [Yaroslav](http://www.sharemuch.com/2011/01/10/creation-custom-retention-policies-for-sharepoint-2010-libraries/):
public override void FeatureActivated(SPFeatureReceiverProperties properties) { const string xmlManifest = “<PolicyResource xmlns=‘urn:schemas-microsoft-com:office:server:policy’” + " id = ‘Takana.TaskRetentionPolicy’" + " featureId=‘Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration’" + " type = ‘DateCalculator’>" + " Takana Task Retention Policy" + “Tasks expire 30 days after they have been completed” + “Takana.SharePoint, Version=1.0.0.0, Culture=neutral, " + “PublicKeyToken=920c0327f8b01d97” + “Takana.SharePoint.Policies.TaskExpiration” + “”; PolicyResourceCollection.Add(xmlManifest); }
Tag: Policy
Retention policies
Ziegler provides a cool intro, implementation sample and much more. When deployed we can apply this policy to a contenttype in the UI, or in code. To create our own expiration logic we have to implement IExpirationFormula and its ComputeExpireDate:
public class TaskExpiration : IExpirationFormula
{
public DateTime? ComputeExpireDate(SPListItem item,
XmlNode parametersData)
{
if (!item\["Status"\].Equals("Completed"))
{
return null;
}
var dt = (DateTime) item\["Modified"\];
return dt.AddDays(30);
}
}
```In order to see IExpirationFormula, add a reference to Microsoft.Office.Policy (and maybe Microsoft.Office.DocumentManagement): [![](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png "policy-dll")](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png) To see our custom retention policy, we have to register it in xml, we can do it in Feature Receiver like [Yaroslav](http://www.sharemuch.com/2011/01/10/creation-custom-retention-policies-for-sharepoint-2010-libraries/):
public override void FeatureActivated(SPFeatureReceiverProperties properties) { const string xmlManifest = “<PolicyResource xmlns=‘urn:schemas-microsoft-com:office:server:policy’” + " id = ‘Takana.TaskRetentionPolicy’" + " featureId=‘Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration’" + " type = ‘DateCalculator’>" + " Takana Task Retention Policy" + “Tasks expire 30 days after they have been completed” + “Takana.SharePoint, Version=1.0.0.0, Culture=neutral, " + “PublicKeyToken=920c0327f8b01d97” + “Takana.SharePoint.Policies.TaskExpiration” + “”; PolicyResourceCollection.Add(xmlManifest); }
Tag: Retention Policy
Retention policies
Ziegler provides a cool intro, implementation sample and much more. When deployed we can apply this policy to a contenttype in the UI, or in code. To create our own expiration logic we have to implement IExpirationFormula and its ComputeExpireDate:
public class TaskExpiration : IExpirationFormula
{
public DateTime? ComputeExpireDate(SPListItem item,
XmlNode parametersData)
{
if (!item\["Status"\].Equals("Completed"))
{
return null;
}
var dt = (DateTime) item\["Modified"\];
return dt.AddDays(30);
}
}
```In order to see IExpirationFormula, add a reference to Microsoft.Office.Policy (and maybe Microsoft.Office.DocumentManagement): [![](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png "policy-dll")](https://sharepointkunskap.files.wordpress.com/2011/12/policy-dll.png) To see our custom retention policy, we have to register it in xml, we can do it in Feature Receiver like [Yaroslav](http://www.sharemuch.com/2011/01/10/creation-custom-retention-policies-for-sharepoint-2010-libraries/):
public override void FeatureActivated(SPFeatureReceiverProperties properties) { const string xmlManifest = “<PolicyResource xmlns=‘urn:schemas-microsoft-com:office:server:policy’” + " id = ‘Takana.TaskRetentionPolicy’" + " featureId=‘Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration’" + " type = ‘DateCalculator’>" + " Takana Task Retention Policy" + “Tasks expire 30 days after they have been completed” + “Takana.SharePoint, Version=1.0.0.0, Culture=neutral, " + “PublicKeyToken=920c0327f8b01d97” + “Takana.SharePoint.Policies.TaskExpiration” + “”; PolicyResourceCollection.Add(xmlManifest); }
Tag: Batch
Batch remove
To add items to a list in bulk, or remove them in bulk. Well to do that you can use SPLinq, Server Object Model and … web.ProcessBatchData, which is the most effective. I did an experiment today. I created 1000 tasks in my task list three times and removed all items in three different ways and took time. First I put 1000 items with ajax and listdata.svc:
function pad(n) {
if (n >= 10000) return n;
if (n >= 1000) return '0' + n;
if (n >= 100) return '00' + n;
if (n >= 10) return '000' + n;
return '0000' + n;
}
var s;
var counter = 0;
var title = "task "
function foo() {
counter++;
if (counter > 10000) {
window.clearInterval(s);
}
else {
var value = {};
value.title = title + pad(counter);
createNewTask(value);
}
}
s = setInterval(foo, 200);
Then I ran three different scenarios. Here is the resut for VMWare machine Windows Server 2008 R2, 4GB RAM, SharePoint 2010 SP1:
Tag: Object Model
Batch remove
To add items to a list in bulk, or remove them in bulk. Well to do that you can use SPLinq, Server Object Model and … web.ProcessBatchData, which is the most effective. I did an experiment today. I created 1000 tasks in my task list three times and removed all items in three different ways and took time. First I put 1000 items with ajax and listdata.svc:
function pad(n) {
if (n >= 10000) return n;
if (n >= 1000) return '0' + n;
if (n >= 100) return '00' + n;
if (n >= 10) return '000' + n;
return '0000' + n;
}
var s;
var counter = 0;
var title = "task "
function foo() {
counter++;
if (counter > 10000) {
window.clearInterval(s);
}
else {
var value = {};
value.title = title + pad(counter);
createNewTask(value);
}
}
s = setInterval(foo, 200);
Then I ran three different scenarios. Here is the resut for VMWare machine Windows Server 2008 R2, 4GB RAM, SharePoint 2010 SP1:
Tag: Setinterval
Batch remove
To add items to a list in bulk, or remove them in bulk. Well to do that you can use SPLinq, Server Object Model and … web.ProcessBatchData, which is the most effective. I did an experiment today. I created 1000 tasks in my task list three times and removed all items in three different ways and took time. First I put 1000 items with ajax and listdata.svc:
function pad(n) {
if (n >= 10000) return n;
if (n >= 1000) return '0' + n;
if (n >= 100) return '00' + n;
if (n >= 10) return '000' + n;
return '0000' + n;
}
var s;
var counter = 0;
var title = "task "
function foo() {
counter++;
if (counter > 10000) {
window.clearInterval(s);
}
else {
var value = {};
value.title = title + pad(counter);
createNewTask(value);
}
}
s = setInterval(foo, 200);
Then I ran three different scenarios. Here is the resut for VMWare machine Windows Server 2008 R2, 4GB RAM, SharePoint 2010 SP1:
Tag: Stsadm
Add stsadm folder to PATH in cmd
Tired to see C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN\stsadm.exe? Wouldn’t be nice to run stsadm directly without going the 14 bin folder, or permanently changing %PATH%, well add this line to your script:
PATH=%PATH%;C:\\Program Files\\Common Files\\Microsoft Shared\\Web Server Extensions\\14\\BIN\\
Tag: ISO
format javascript date in ISO 8601
There is a solution in StackOverflow:
/\* use a function for the exact format desired... \*/
function ISODateString(d){
function pad(n){return n<10 ? '0'+n : n}
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'}
var d = new Date();
print(ISODateString(d)); // prints something like 2009-09-28T19:03:12Z
```But there is already a function for this: toISOString, it came with ecmascript 5. [Unfortunately, not all browsers support this](http://kangax.github.com/es5-compat-table/ "See the best comparision for ecmascript 5 support"), to solve this problem, we can provide our own prototype function for Date if it doesn't exist:
if (!Date.prototype.toISOString) { Date.prototype.toISOString = function() { function pad(n) { return n < 10 ? ‘0’ + n : n } return this.getUTCFullYear() + ‘-’ + pad(this.getUTCMonth() + 1) + ‘-’ + pad(this.getUTCDate()) + ‘T’ + pad(this.getUTCHours()) + ‘:’ + pad(this.getUTCMinutes()) + ‘:’ + pad(this.getUTCSeconds()) + ‘Z’; }; }
Tag: Accessibility
accesskey
accesskey provides keyboard shortcuts. The restriction is that accesskey works well only with anchors. To bind keyboard shortcuts to other html elements, follow Scott Klarr. Here is an example of binding Alt and L:
var isAlt = false;
function addShortcuts() {
//add keyboard shortcut
document.onkeyup = function (e) {
if (e.which == 18) isAlt = false;
};
document.onkeydown = function (e) {
if (e.which == 18) isAlt = true;
// Alt-L
if (e.which == 76 && isAlt == true) {
$("#add-item").click();
return false;
}
};
}
Tag: Context
Get current user and handle a success callback
In my previous post I needed the accound id of the current user for posting new list items. To retrieve the id, we can push this to the client from the code behind, or get the current user using Client Object Model. To provide a more generic way we can write a js function which get the current user. But we must even provide some callback functionality, otherwise we don’t know if the operation was successful or not. Let’s be inspired by success and error properties in $.ajax:
Tag: Current
Get current user and handle a success callback
In my previous post I needed the accound id of the current user for posting new list items. To retrieve the id, we can push this to the client from the code behind, or get the current user using Client Object Model. To provide a more generic way we can write a js function which get the current user. But we must even provide some callback functionality, otherwise we don’t know if the operation was successful or not. Let’s be inspired by success and error properties in $.ajax:
Tag: Autoresize
The cleanest auto resize for a textarea
The cleanest way to auto-resize a textarea while typing (like wall post on Facebook) is George Papadakis solution. It uses only standard javascript and provides eventlisteners for IE (attachEvent) and other browsers (addEventListener): [sourcecode language=“javascript”] window.onload = function() { var t = document.getElementsByTagName(’textarea’)[0]; var offset= !window.opera ? (t.offsetHeight - t.clientHeight) : (t.offsetHeight + parseInt(window.getComputedStyle(t, null).getPropertyValue(‘border-top-width’))) ; var resize = function(t) { t.style.height = ‘auto’; t.style.height = (t.scrollHeight + offset ) + ‘px’; } t.addEventListener && t.addEventListener(‘input’, function(event) { resize(t); }); t[‘attachEvent’] && t.attachEvent(‘onkeyup’, function() { resize(t); }); } [/sourcecode] Other solutions are <a href=“https://github.com/padolsey/jQuery.fn.autoResize/blob/master/jquery.autoresize.js, jQuery.autogrow, elastic
Tag: Textarea
The cleanest auto resize for a textarea
The cleanest way to auto-resize a textarea while typing (like wall post on Facebook) is George Papadakis solution. It uses only standard javascript and provides eventlisteners for IE (attachEvent) and other browsers (addEventListener): [sourcecode language=“javascript”] window.onload = function() { var t = document.getElementsByTagName(’textarea’)[0]; var offset= !window.opera ? (t.offsetHeight - t.clientHeight) : (t.offsetHeight + parseInt(window.getComputedStyle(t, null).getPropertyValue(‘border-top-width’))) ; var resize = function(t) { t.style.height = ‘auto’; t.style.height = (t.scrollHeight + offset ) + ‘px’; } t.addEventListener && t.addEventListener(‘input’, function(event) { resize(t); }); t[‘attachEvent’] && t.attachEvent(‘onkeyup’, function() { resize(t); }); } [/sourcecode] Other solutions are <a href=“https://github.com/padolsey/jQuery.fn.autoResize/blob/master/jquery.autoresize.js, jQuery.autogrow, elastic
Tag: Risk
ASP.NET Ajax Toolkit
To integrate ASP.NET Ajax Toolkit is not the most straight forward task in SharePoint. If you want to take the risk, “Inspired by Technology” provides the best guide so far.
Tag: Picker
Custom Picker in Sharepoint
PeopleEditor is a nice webcontrol for picking people. To add it to your webpart or page is easy: But there is more we can do with pickers in Sharepoin. We can define our own pickers. Jeremy Luerkens gives one such example and a code sample (!). Another example can be found in Sharepoint as a Development Platform (p. 661), even though it misses the important class BookQueryControl. Just to start I made a book picker (I simplified and changed the idea provided in the book). Here is the working result, for simplicity the whole code is in one file: [sourcecode language=“csharp”] public partial class WPBookPickerUserControl : UserControl { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { pnlBook.Controls.Add(new BookEditor() { Width = Unit.Pixel(200), MultiSelect = false}); } } } public class Book { public string Title { get; set; } public string Author { get; set; } public string Price { get; set; } public string Publisher { get; set; } } public class BookDataManager { private static Book[] _books = { new Book {Title = “SP”, Author = “John”, Price = “2€”, Publisher = “Amazon”}, new Book {Title = “JS”, Author = “David”, Price = “3€”, Publisher = “Amazon”} }; private static DataTable GetDataTable(IEnumerable books) { var table = new DataTable(); table.Columns.Add(“Title”, typeof(string)); table.Columns.Add(“Author”, typeof(string)); table.Columns.Add(“Price”, typeof(string)); table.Columns.Add(“Publisher”, typeof(string)); foreach (var b in books) { table.LoadDataRow(new string[] { b.Title, b.Author, b.Price, b.Publisher }, true); } return table; } public static DataTable ValidateBook(string key) { var books = _books.Where(c => c.Title == key).ToArray(); return GetDataTable(books); } public static DataTable SearchForBooks(string keyword) { var books = _books.Where(c => c.Title.Contains(keyword)).ToArray(); return GetDataTable(books); } public static PickerEntity ConvertFromDataRow(DataRow dr, PickerEntity pi) { pi = pi ?? new PickerEntity(); var t = dr[“Title”].ToString(); var a = dr[“Author”].ToString(); var p = dr[“Price”].ToString(); var l = dr[“Publisher”].ToString(); pi.Key = t; pi.DisplayText = string.Format("{0} ({1}), {2}", t, a, p); pi.EntityData = new Hashtable(); foreach(DataColumn col in dr.Table.Columns) { pi.EntityData[col.ColumnName] = dr[col.ColumnName]; } return pi; } } public class BookEditor : EntityEditorWithPicker { public BookEditor() { PickerDialogType = typeof (BookPickerDialog); ValidatorEnabled = true; } public override PickerEntity ValidateEntity(PickerEntity needsValidation) { var tblItem = BookDataManager.ValidateBook(needsValidation.Key); needsValidation.IsResolved = false; if (tblItem != null && tblItem.Rows.Count > 0) { needsValidation = BookDataManager.ConvertFromDataRow(tblItem.Rows[0], needsValidation); needsValidation.IsResolved = true; } return needsValidation; } } public class BookQueryControl : PickerQueryControlBase { public TableResultControl ResultControl { get { return (TableResultControl)base.PickerDialog.ResultControl; } } public BookEditor EditorControl { get { return (BookEditor)base.PickerDialog.EditorControl; } } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); base.ColumnList.Visible = false; } private DataTable CreateDataTable() { // Method variables DataColumn column; // Init data table DataTable table = new DataTable(); table.Locale = CultureInfo.InvariantCulture; // Loop visible column names foreach (string columnName in ResultControl.ColumnNames) { column = new DataColumn {DataType = typeof (string), ColumnName = columnName}; table.Columns.Add(column); } // Return table return table; } public override PickerEntity GetEntity(DataRow dr) { // No datarow provided if (dr == null) return null; var pi = new PickerEntity(); var t = dr[“Title”].ToString(); var a = dr[“Author”].ToString(); var p = dr[“Price”].ToString(); var l = dr[“Publisher”].ToString(); pi.Key = t; pi.DisplayText = string.Format("{0} ({1}), {2}", t, a, p); pi.IsResolved = true; pi.EntityData = new Hashtable(); foreach (DataColumn col in dr.Table.Columns) { pi.EntityData[col.ColumnName] = dr[col.ColumnName]; } return pi; } protected override int IssueQuery(string search, string group, int pageIndex, int pageSize) { search = (search != null) ? search.Trim() : null; if (string.IsNullOrEmpty(search)) { PickerDialog.ErrorMessage = “No search provided”; return 0; } var table = BookDataManager.SearchForBooks(search); if (table == null || table.Rows.Count == 0) { PickerDialog.ErrorMessage = “No matching books found.”; return 0; } PickerDialog.Results = table; PickerDialog.ResultControl.PageSize = table.Rows.Count; return table.Rows.Count; } } public class BookPickerDialog : PickerDialog { public BookPickerDialog() : base(new BookQueryControl(), new TableResultControl(), new BookEditor()) { DialogTitle = “Custom Book Picker Dialog”; Description = “Please select one or more books”; MultiSelect = false; } protected override void OnPreRender(EventArgs e) { var resultControl = (TableResultControl) ResultControl; var columnDisplayNames = resultControl.ColumnDisplayNames; var columnNames = resultControl.ColumnNames; var columnWidths = resultControl.ColumnWidths; columnDisplayNames.Clear(); columnNames.Clear(); columnWidths.Clear(); var cols = new string[] {“Title”, “Author”, “Price”, “Publisher”}; columnDisplayNames.AddRange(cols); columnNames.AddRange(cols); columnWidths.AddRange(new string[] { “40%”, “20%”, “10%”, “30%”}); base.OnPreRender(e); } } [/sourcecode] Of course the best way is to create separate files for each class, but don’t forget to add Safecontrol to web.config.
Tag: Delegatectontrol
Google Analytics in Sharepoint
Google Analytics is a popular and mature tool for monitoring network activities on your site. Why not use it in Sharepoint? Dave Coleman and Mike Knowles provide good guides for doing that. There is a promising plugin to SP SPGoogleAnalytics which integrates both and provides an easy interface to put GA to your SharePoint installation and see the data directly on your intranet. It comes from codeplex: What do you think about spgoogleanalytics.codeplex? When I recently had to turn on Google Analytics on an intranet, I had no time for evaluating SPGoogleAnalytics, so I did the harder way: just put ga script in the end of a master page, just before ending tag. But what if one has multiple masterpages? Is there a way to put GA in one step? Maybe a user control like Knowles suggests?
Change the layout of Search Box without custom delegate control
The surest way to customize Search box in Sharepoint is to create a delegate control. In Sharepoint.Stackexchange there are many links to resources about this. But if you don’t have access to server or can’t deploy, the easiest way to do it is to style it with css. Thanks Steve Ottenad.
.s4-search .ms-sbgo a {
background:url(../images/search\_btn.png) no-repeat;
width:27px;
height:22px;
display:block;
}
.s4-search .srch-gosearchimg, .s4-search .ms-sbgo span {
display:none;
}
First we hide the the default image and then we add our image for search button as background.
Create own delegate control
In this post I’ll show how to create a simple (but own) delegate control. A short intro and links on delegate controls can be found on sharepointoverflow. Take a look on master page. There are already many delegate controls. The delegate control with id AdditionalPageHead can be used for adding your script or jQuery library.:
<SharePoint:DelegateControl
runat="server"
ControlId="AdditionalPageHead"
AllowMultipleControls="true"/>
You can also override existing controls like searchbox. But what if you want to add some content in the master page where no delegate controls are present. Of course, you can add it directly to the master page. Perhaps not on all webs? You can use placeholders to manage it. But do you want to update all the page layouts? So the solution is to use delegate controls, for adding multiple pieces of content or overriding using Sequence. In this example I’ll add some new content to the quicklaunch bottom area:
Tag: Google
Google Analytics in Sharepoint
Google Analytics is a popular and mature tool for monitoring network activities on your site. Why not use it in Sharepoint? Dave Coleman and Mike Knowles provide good guides for doing that. There is a promising plugin to SP SPGoogleAnalytics which integrates both and provides an easy interface to put GA to your SharePoint installation and see the data directly on your intranet. It comes from codeplex: What do you think about spgoogleanalytics.codeplex? When I recently had to turn on Google Analytics on an intranet, I had no time for evaluating SPGoogleAnalytics, so I did the harder way: just put ga script in the end of a master page, just before ending tag. But what if one has multiple masterpages? Is there a way to put GA in one step? Maybe a user control like Knowles suggests?
Tag: Google Analytics
Google Analytics in Sharepoint
Google Analytics is a popular and mature tool for monitoring network activities on your site. Why not use it in Sharepoint? Dave Coleman and Mike Knowles provide good guides for doing that. There is a promising plugin to SP SPGoogleAnalytics which integrates both and provides an easy interface to put GA to your SharePoint installation and see the data directly on your intranet. It comes from codeplex: What do you think about spgoogleanalytics.codeplex? When I recently had to turn on Google Analytics on an intranet, I had no time for evaluating SPGoogleAnalytics, so I did the harder way: just put ga script in the end of a master page, just before ending tag. But what if one has multiple masterpages? Is there a way to put GA in one step? Maybe a user control like Knowles suggests?
Tag: Webservices
$.getJSON, jQuery.tmpl and _vti_bin
Javascript is very fast, responsive and unburdens the cpu at the server. Here I show a little example how to use jQuery.getJSON, jQuery.tmpl (wonderful plugin for rendering repeating data, repo hosted on Github) and REST-based service listdata.svc from /_layouts/_vti_bin/ folder. For this example I created a generic list “Contacts”, added two text fields Name and Phone. Add some phone numbers and try to go to /_vti_bin/ListData.svc/Contacts If you get 404-error, install a ADO.NET Data Services v1.5 CTP2, as described at dotnetmafia. If you want to know more about how to sort and filter, skip and limit results, read more at nothingbutsharepoint. If you encounter problems, follow Michaël’s blog post and download and install Windows6.1-KB976127-v6-x64.msu (if you have Windows Server 2008 R2), or NDP35SP1-KB976126-v2-x64.exe (if you have Windows Server 2008). After installing the version of the System.Data.Services.dll file is 3.5.30729.5004 (Windows Server 2008 R2), and 3.5.30729.4466 (Windows Server 2008). Allright, the remainder is pure javascript. In order to get it working you have to run the script from the same domain, meaning you can’t run javascript to retrieve the data from a html-file from your home folder. Create a webpart and add it to your page.
Tag: Cache
Reset favicon cache
Favicon is one of the hardest. Ctrl-F5 doesn’t help. You can of course see the source, find the location of the favicon, click on it (if you use Firefox or Chrome), otherwise copy the url and paste it in the address bar. When you load it separately, the favicon cache is renewed. It works. But if you want to make it easier for your users, set a version to your favicon file in the masterpage:
Tag: Favicon
Reset favicon cache
Favicon is one of the hardest. Ctrl-F5 doesn’t help. You can of course see the source, find the location of the favicon, click on it (if you use Firefox or Chrome), otherwise copy the url and paste it in the address bar. When you load it separately, the favicon cache is renewed. It works. But if you want to make it easier for your users, set a version to your favicon file in the masterpage:
Custom favicon
It is easy to use a custom favicon, put a ico image into a mapped folder Images and then locate this line in your master page:
<SharePoint:SPShortcutIcon runat="server" IconUrl="/\_layouts/images/favicon.ico" />
```And replace it with your ico:
<SharePoint:SPShortcutIcon runat=“server” IconUrl="/_layouts/images/CONTOSO/favicon.ico" />
Tag: Onet.xml
Show files first in view
When you create an own view in schema.xml it is easy to show files first (Scope). It is quite useful if you want to show only few items on start page in xsltlistviewwebpart:
Scope="Recursive"
```Though there is a problem when you provision this list instance. Thanks to [a great post of Koen van der Linden about how to show files recursively](http://kvdlinden.blogspot.com/2010/04/schemaxml-onetxml-and-baseview-doesnt.html) it is no big deal to solve it. Just add the same scope to View element in the module in onet, which provisions your site:
<View List="$Resources:core,shareddocuments_Folder;" BaseViewID=“41” WebPartZoneID=“Middle” WebPartOrder=“2” Scope=“Recursive” />
Provisioning multiple pages with one source file
I found an easy way to provision multiple pages. Create a module. Add an aspx.file (e.g. default.aspx). In the elements file define nodes for every page. Path should be the same for all pages, but the Url should be your destination page. The “default.aspx” (name doesn’t matter) can contain content, or just one @Page directive if Publishing feature is available:
<%@ Page Inherits="Microsoft.SharePoint.Publishing.TemplateRedirectionPage,Microsoft.SharePoint.Publishing,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
```In the Element.xml define all your pages: [![](https://sharepointkunskap.files.wordpress.com/2011/10/abunchofpages-elements.png "abunchofpages-elements")](https://sharepointkunskap.files.wordpress.com/2011/10/abunchofpages-elements.png) In every File node you can add webparts, here is an example:
<![CDATA[ Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c Microsoft.SharePoint.WebPartPages.ContentEditorWebPart About cars Test None true Lorem ipsum dolor sit amet ]]>
Link to Home on Top Navigation Bar
If you have a custom site definition and want to have a link to RootWeb, just add NavBarPage to your module:
<Module Name="OrklaRootBlank" Url="" Path="">
<File Url="default.aspx">
<NavBarPage Name="$Resources:core,nav\_Home;"
Url="~site" ID="1002" Position="Start" />
</File>
</Module>
Custom Title on built-in webpart
What to do if you want to change the title in the built-in webpart like Tasks or so. Your own title or just to avoid tasks (1) and tasks (2) if you add two views of them to a page. In onet.xml you add them as view:
<View
List="$Resources:core,lists\_Folder;/$Resources:core,tasks\_Folder;"
BaseViewID="7" WebPartZoneID="Middle"
WebPartOrder="6"/>
```The solution is to add [cdata element and webpart tag within it](http://www.novolocus.com/2011/06/14/set-the-title-of-a-listviewwebpart/). So now replace this with:
<![CDATA[ Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c Microsoft.SharePoint.WebPartPages.XsltListViewWebPart Task Title as I want it ]]>
Länkar på quicklaunchen
Det är en skum grej: Länkar (listor och bibliotek, kalender och dylikt) visas inte. När jag har ändrat Navigation properties i min konfiguration i onet.xml, då funkar det:
<WebFeatures>
...
<!-- Navigation Properties -->
<Feature ID="541F5F57-C847-4e16-B59A-B31E90E6F9EA">
<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<Property Key="InheritGlobalNavigation" Value="true"/>
**<Property Key="ShowSiblings" Value="false"/>**
<Property Key="IncludeSubSites" Value="true" />
<Property Key="IncludePages" Value="false" />
</Properties>
</Feature>
</WebFeatures>
HelpUrl i WebPart
Man kan lägga till HelpUrl i en WebPart, för att användare kan klicka och få instruktioner eller hjälp med just denna webpart. För att göra det manuellt, ska man klicka på pilen, välja “modify this web part”, och sedan i “Advanced” skriva url-länken i “HelpUrl”-fältet. För att lägga till HelpUrl ifrån början, när sajter skapas, måste man ange den egenskapen i onet.xml i Module för din sajt. Man måste hitta , och ändra den: <property name="HelpUrl" type="string">http://sr.se</property>
Så ser hela biten ut i onet.xml:
Tag: Schema.xml
Show files first in view
When you create an own view in schema.xml it is easy to show files first (Scope). It is quite useful if you want to show only few items on start page in xsltlistviewwebpart:
Scope="Recursive"
```Though there is a problem when you provision this list instance. Thanks to [a great post of Koen van der Linden about how to show files recursively](http://kvdlinden.blogspot.com/2010/04/schemaxml-onetxml-and-baseview-doesnt.html) it is no big deal to solve it. Just add the same scope to View element in the module in onet, which provisions your site:
<View List="$Resources:core,shareddocuments_Folder;" BaseViewID=“41” WebPartZoneID=“Middle” WebPartOrder=“2” Scope=“Recursive” />
Hämta schema från en befintlig SPList
Ibland är det så att man vill ha en speciell mall för en SPList, man har redan skapat en mall manuellt på sajten. Då är det enklaste sättet att hämta schema.xml och Windows SharePoint Services 3.0 Tools. När man installerat det så startar man Sharepoint Solution Generator 2008. Sedan måste man hitta sin lista, eller dokumentbiblioteket och exportera. Sedan är det bara att importera till sitt projekt i Visual Studio.
Tag: Attribute
Hide my site link with css
Want to hide my site link without disabling social features. Well, the simplest way to do it is to use css:
#mp1\_0\_0\_Anchor { display: none; }
```If you want to hide my profile instead, just hide #mp1\_0\_1\_Anchor:
#mp1_0_1_Anchor { display: none; }
.ms-MenuUIUL li[text=‘My Site’] { display: none;}
##### Disable the my profile feature An even better solution is maybe to disable the ability to change the profiles. [Just remove the permission to "user personalization..." for All authenticated users in User Profile Service](http://blog.libinuko.com/2010/10/10/sharepoint-2010-howto-disable-my-site-and-my-profile-link/).
## Comments from Wordpress.com
####
[John]( "johnandrewdavies@hotmail.com") - <time datetime="2012-03-07 00:15:32">Mar 3, 2012</time>
Be careful this cannot be used, the classes for pop up menus are generated dynamically on the page, and that class can be applied to a number of menus I assume depending on the order which they load on the page, which isnt the same every time, so for instance this hides something in the site actions menu, or the new button on a library sometimes.
<hr />
####
[Brett Anderson](http://sharepoint2020.wordpress.com "brettando@live.com.au") - <time datetime="2012-05-02 06:13:05">May 3, 2012</time>
Hi, The amended solution does not work in IE7.
<hr />
####
[Fredrik]( "fredrik.eriksson234@gmail.com") - <time datetime="2012-03-09 15:27:24">Mar 5, 2012</time>
Thank you Anatoly, that worked perfectly in all browsers! I had problems with the first suggested solution, because it would hide other menu items, like "edit this page" from the site settings dropdown!
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:10:36">Mar 3, 2012</time>
You are totally right, John! I realized that too. Fortunately, I didn't need that then. But while using that I saw that sometimes Site Actions -Edit Page disappeared. These IDs are really generated dynamically. Thanks for your comment. I'll update my post.
<hr />
####
[vishal]( "vishals.shivan@gmail.com") - <time datetime="2012-03-07 07:27:54">Mar 3, 2012</time>
Hi Anatoly. Thanks for the solution. but the problem we are facing one problem after implementing this. Once we make this change and when login to the portal next time, the "Edit Page" link under site action menu is not getting displayed and the My Site Link is getting displyed. any suggestion?
<hr />
####
[Material SharePoint » Hide ‘My Site’ Link from Welcome User Dropdown Control](http://sharepoint.jsturges.com/2012/05/hide-my-site-link-from-welcome-user-dropdown-control/ "") - <time datetime="2012-05-12 17:45:13">May 6, 2012</time>
\[...\] of my enterprise level clients that we usually hide it all together! To do this, you can use an awesome CSS trick I learned from Anatoly \[...\]
<hr />
####
[Anatoly Mironov]( "mirontoli@gmail.com") - <time datetime="2012-03-07 09:24:39">Mar 3, 2012</time>
Hi Vishal. Unfortunately we cannot rely on these IDs, as John in previous comment mentioned, because these IDs are generated dynamically. I'll update my post. One possible solution would be use attribute selectors... Something like .ms-MenuUIUL li\[text='My Site'\] { display: none;}
<hr />
####
[jim]( "jim.omara@gmail.com") - <time datetime="2014-02-12 17:38:05">Feb 3, 2014</time>
.ms-welcomeMenu #mp1\_0\_0{ display:none; } .ms-welcomeMenu #mp1\_0\_1{ display:none; } .ms-welcomeMenu #mp1\_0\_2{ display:none; } .ms-welcomeMenu #mp1\_0\_3{ display:none; } .ms-welcomeMenu #mp1\_0\_4{ display:none; } .ms-welcomeMenu #mp1\_0\_8{ display:none; } .ms-welcomeMenu #mp1\_0\_9{ display:none; } these work for me.
<hr />
####
[Anatoly Mironov](http://chuvash.eu "mirontoli@gmail.com") - <time datetime="2014-02-12 23:20:59">Feb 3, 2014</time>
Thank you for sharing your solution. Appreciate.
<hr />
Tag: Quicklaunch
Check if an html element is hidden using jQuery
Well, sometimes we need to calculate width and so on. In my next post I will write about how to fix auto-resize on fixed sized master pages. But now: a very nice stuff: how to check if an element is hidden or not:
$("#s4-leftpanel").is(":visible")
```It is a pure poetry. It reminds me of the beauty of [symbols in Ruby](http://rubylearning.com/satishtalim/ruby_symbols.html).
Länkar på quicklaunchen
Det är en skum grej: Länkar (listor och bibliotek, kalender och dylikt) visas inte. När jag har ändrat Navigation properties i min konfiguration i onet.xml, då funkar det:
<WebFeatures>
...
<!-- Navigation Properties -->
<Feature ID="541F5F57-C847-4e16-B59A-B31E90E6F9EA">
<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<Property Key="InheritGlobalNavigation" Value="true"/>
**<Property Key="ShowSiblings" Value="false"/>**
<Property Key="IncludeSubSites" Value="true" />
<Property Key="IncludePages" Value="false" />
</Properties>
</Feature>
</WebFeatures>
Tag: Page Layout
Add article content and editing to your Page Layout
If you work with Sharepoint Designer, use your own page layouts and want to have them for a page in a publishing site, you have to put in some controls in order to see th page content in you custom page layout. Put in a appropriate place in you page layout ( taken from ArticleLeft.aspx):
<div>
<PublishingWebControls:EditModePanel runat="server" CssClass="edit-mode-panel">
<SharePoint:TextField runat="server" FieldName="Title"/>
</PublishingWebControls:EditModePanel>
<div class="captioned-image">
<div class="image">
<PublishingWebControls:RichImageField FieldName="PublishingPageImage" runat="server"/>
</div>
<div class="caption">
<PublishingWebControls:RichHtmlField FieldName="PublishingImageCaption"
AllowTextMarkup="false" AllowTables="false" AllowLists="false"
AllowHeadings="false" AllowStyles="false" AllowFontColorsMenu="false"
AllowParagraphFormatting="false" AllowFonts="false" PreviewValueSize="Small"
AllowInsert="false" runat="server"/>
</div>
</div>
<div class="article-header">
<div class="date-line">
<SharePoint:DateTimeField FieldName="ArticleStartDate" runat="server"/>
</div>
<div class="by-line">
<SharePoint:TextField FieldName="ArticleByLine" runat="server"/>
</div>
</div>
<div class="article-content">
<PublishingWebControls:RichHtmlField FieldName="PublishingPageContent"
HasInitialFocus="True" MinimumEditHeight="400px" runat="server"/>
</div>
<PublishingWebControls:EditModePanel runat="server" CssClass="edit-mode-panel roll-up">
<PublishingWebControls:RichImageField FieldName="PublishingRollupImage"
AllowHyperLinks="false" runat="server" />
<asp:Label text="<%$Resources:cms,Article\_rollup\_image\_text%>" runat="server" />
</PublishingWebControls:EditModePanel>
</div>
Comments from Wordpress.com
Renate - May 1, 2014
Custom PlaceHolder
You want some custom content in your site and it is different from page to page. Well, I wrote how to achieve this with delegate controls. Another approach is to use PlaceHolders. Maybe you can use some existing placeholders. There are so many unused placeholders in v4.master. Like PlaceHolderLeftActions. If you use starter master pages from Randy Drisgill, you must move these from invisible panel. To create custom placeholder is very easy: Just copy an existing placeholder in the master page and name it som appropriate like:
Show Title on Page
If you want to show the page title in another part than defined in your master page just add this tag to your page layout.
<SharePoint:ProjectProperty
Property="Title" runat="server" />
```It must be within <asp:Content> tag
Webparts on a layoutpage which is provisioned several times
It is pretty easy to add webparts to a layout page. Just define the webparts in the corresponding Elements.xml file. Like you do in onet.xml. It works fine if you provision just a single page with this layout on a web. If you have multiple pages that use the same page layout (e.g. in WCM). The trick is to use the attribute IgnoreIfAlreadyExists in the File tag:
IgnoreIfAlreadyExists="True"
Comments from Wordpress.com
Webpart in a reusable user control « Sharepoint. Kunskap. Upptäckter på resan. - Sep 1, 2011
Tag: Drisgill
Add TreeView to Site
For all of who use Randy Drisgill’s starter masters, it won’t help if you go to Site Actions TreView and just enable it, because the DelegateControl is in a hidden panel. To really restore the original treeview you have to copy this xml from v4.master:
<Sharepoint:UIVersionedContent runat="server" UIVersion="4">
<ContentTemplate>
<Sharepoint:SPNavigationManager
id="TreeViewNavigationManagerV4"
runat="server"
ContainedControl="TreeView"
CssClass="s4-treeView"
>
<SharePoint:SPLinkButton runat="server"
NavigateUrl="~site/\_layouts/viewlsts.aspx"
id="idNavLinkSiteHierarchyV4"
Text="<%$Resources:wss,treeview\_header%>"
accesskey="<%$Resources:wss,quiklnch\_allcontent\_AK%>"
CssClass="s4-qlheader" />
<div class="ms-treeviewouter">
<SharePoint:DelegateControl runat="server" ControlId="TreeViewAndDataSource">
<Template\_Controls>
<SharePoint:SPHierarchyDataSourceControl
runat="server"
id="TreeViewDataSourceV4"
RootContextObject="Web"
IncludeDiscussionFolders="true"
/>
<SharePoint:SPRememberScroll runat="server"
id="TreeViewRememberScrollV4"
onscroll="javascript:_spRecordScrollPositions(this);"
style="overflow: auto;height: 400px;width: 155px; ">
<Sharepoint:SPTreeView
id="WebTreeViewV4"
runat="server"
ShowLines="false"
DataSourceId="TreeViewDataSourceV4"
ExpandDepth="0"
SelectedNodeStyle-CssClass="ms-tvselected"
NodeStyle-CssClass="ms-navitem"
SkipLinkText=""
NodeIndent="12"
ExpandImageUrl="/_layouts/images/tvclosed.png"
ExpandImageUrlRtl="/_layouts/images/tvclosedrtl.png"
CollapseImageUrl="/_layouts/images/tvopen.png"
CollapseImageUrlRtl="/_layouts/images/tvopenrtl.png"
NoExpandImageUrl="/_layouts/images/tvblank.gif"
>
</Sharepoint:SPTreeView>
</Sharepoint:SPRememberScroll>
</Template_Controls>
</SharePoint:DelegateControl>
</div>
</Sharepoint:SPNavigationManager>
</ContentTemplate>
</SharePoint:UIVersionedContent>
and paste it before:
Tag: Nosql
MongoDB shell, learn directly in browser
Are you also curious about NoSQL databases. Well, MongoDB is one of the most known ones. MongoDB has a javascript syntax (json), I like it. Try out the interactive shell at the mongodb site.
Quickstart on Ubuntu
To test it on Ubuntu, just install an existing apt-package:
sudo apt-get install mongodb
Tag: Unix
MongoDB shell, learn directly in browser
Are you also curious about NoSQL databases. Well, MongoDB is one of the most known ones. MongoDB has a javascript syntax (json), I like it. Try out the interactive shell at the mongodb site.
Quickstart on Ubuntu
To test it on Ubuntu, just install an existing apt-package:
sudo apt-get install mongodb
Tag: Modules
Provisioning multiple pages with one source file
I found an easy way to provision multiple pages. Create a module. Add an aspx.file (e.g. default.aspx). In the elements file define nodes for every page. Path should be the same for all pages, but the Url should be your destination page. The “default.aspx” (name doesn’t matter) can contain content, or just one @Page directive if Publishing feature is available:
<%@ Page Inherits="Microsoft.SharePoint.Publishing.TemplateRedirectionPage,Microsoft.SharePoint.Publishing,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
```In the Element.xml define all your pages: [![](https://sharepointkunskap.files.wordpress.com/2011/10/abunchofpages-elements.png "abunchofpages-elements")](https://sharepointkunskap.files.wordpress.com/2011/10/abunchofpages-elements.png) In every File node you can add webparts, here is an example:
<![CDATA[ Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c Microsoft.SharePoint.WebPartPages.ContentEditorWebPart About cars Test None true Lorem ipsum dolor sit amet ]]>
Tag: Issue Tracking
Team Explorer
Until now I have only worked with svn and git. So I am very curious about the Team Foundation Server and Team Explorer which all talk much about. The best thing is the integration with the issue tracking. I can see all work item, or just my work items. Another fine feature, at leat if you use codeplex, is the Team Explorer Everywhere.
The Team Explorer Everywhere client works on Windows, Linux, Mac, or Solaris. It provides a command line client and plug-in for Eclipse to access Team Foundation Server. For information on obtaining the client and connecting to the Team Foundation Server please read the Team Explorer Everywhere Client wiki page. You will need the information on the right to connect to the Team Foundation Server in Team Explorer Everywhere.
Tag: Placeholder
Custom PlaceHolder
You want some custom content in your site and it is different from page to page. Well, I wrote how to achieve this with delegate controls. Another approach is to use PlaceHolders. Maybe you can use some existing placeholders. There are so many unused placeholders in v4.master. Like PlaceHolderLeftActions. If you use starter master pages from Randy Drisgill, you must move these from invisible panel. To create custom placeholder is very easy: Just copy an existing placeholder in the master page and name it som appropriate like:
Tag: Xslt
Tag: EventReceiver
ListUrl on EventReceiver
When you create an eventreceiver, you get the ListTemplateId attribute. It works fine. But if you want the eventreceiver to trigger on one particular list, just replace ListTemplateId attribute with ListUrl. For Pages you can use:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Receivers **ListUrl="$Resources:cmscore,List\_Pages\_UrlName;"**\>
<Receiver>
<Name>NewsPageEventReceiverItemUpdated</Name>
<Type>ItemUpdated</Type>
<Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
<Class>Contoso.EventReceivers.NewsPageEventReceiver.NewsPageEventReceiver</Class>
<SequenceNumber>1000</SequenceNumber>
</Receiver>
</Receivers>
</Elements>
AfterProperties kräver InternalName
AfterProperties kommer inte leda till Exception, men de kommer returnera bara null, om du använder DisplayName. Man måste ha InternalName. Här är ett litet exempel på hur man kan få ut värden före och efter uppdateringen. Exemplet har testats i ItemUpdated-eventreceiver.
var before = properties.BeforeProperties;
var after = properties.AfterProperties;
var contentDisplayName = "News Content";
var list = properties.List;
var contentInternalName = list.Fields\[contentDisplayName\].InternalName;
var contentBefore = before\[contentInternalName\];
var contentAfter = after\[contentInternalName\];
Tag: Hide
Hide Site Actions
The easiest way to hide Site Actions for a specific audience is to wrap this into a SPSecuritityTrimmingControl. Locate in your master page. Paste this before span element:
<SharePoint:SPSecurityTrimmedControl runat="server" Permissions="ManageLists">
Find the ending element and paste:
</SharePoint:SPSecurityTrimmedControl>
jQuery hide
Jag har alltid använt hide-funktionen i jQuery för att gömma vissa element som inte behövs i början. Det kan resultera att användaren ser skymningen av dem i laddningen av sidan. Vilket inte är så bra. Men det har visat sig, att hide behöver inte köras av jQuery. Bara göm dem med hjälp av css. jQuery show kommer funka ändå.
Tag: Rättigheter
Hide Site Actions
The easiest way to hide Site Actions for a specific audience is to wrap this into a SPSecuritityTrimmingControl. Locate in your master page. Paste this before span element:
<SharePoint:SPSecurityTrimmedControl runat="server" Permissions="ManageLists">
Find the ending element and paste:
</SharePoint:SPSecurityTrimmedControl>
Vilka rättigheter står bakom olika roller
Här är en lista. För att få fram den listan kan man köra kod:
StringBuilder sb = new StringBuilder();
using (SPSite site = new SPSite("http://wss"))
{
using (SPWeb web = site.OpenWeb())
{
SPRoleDefinitionCollection roleDefinitions = web.RoleDefinitions;
foreach (SPRoleDefinition roleDefinition in roleDefinitions)
{
sb.Append(System.Environment.NewLine + System.Environment.NewLine +
"Role Definition: " + roleDefinition.Name + System.Environment.NewLine +
"==================================================" +
System.Environment.NewLine);
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(roleDefinition.Xml);
XmlNode nodes = xmldoc.DocumentElement;
sb.Append(nodes.Attributes\["BasePermissions"\].Value);
}
textBox1.Text = sb.ToString();
}
}
Viss hjälpinnehåll
Om det strular med att visa hjälpinnehåll, följ denna beskrivning för att lösa det. Du måste ge rättigheter på procedure som heter proc_EnumResourcesAtScope på Sharepoint-AdminContent-databasen:
GRANT EXECUTE ON " proc\_EnumResourcesAtScope" TO "contoso\\SP\_Apppool"
Rättigheter på CustomAction
Om man vill begränsa vem so kan se kan man lägga till “Rights”-attribut på CustomAction. Ett exempel: Hela listan finns på msdn.
Ge andra rättigheter på default.aspx
Om man inte vill medlemmarna på SPWeb rättighet att redigera första sidan hur som helst, måste man bryta arvet på Sidor/default.aspx. Lätt att göra det manuellt (Site Actions - Show all Content - Pages - default.aspx - dokumenträttigheter). I koden kan man göra det så här:
//first find SPListItem defaultAspx
//then find SPGroup members (perhaps via web.AssociatedMemberGroup
defaultAspx.BreakRoleInheritance(true);
defaultAspx.RoleAssignments.RemoveFromCurrentScopeOnly(members);
SPRoleAssignment roles = new SPRoleAssignment(members);
SPRoleDefinition perms = web.RoleDefinitions.GetByType(SPRoleType.Reader);
roles.RoleDefinitionBindings.Add(perms);
defaultAspx.RoleAssignments.Add(roles);
SPSecurityTrimmedControl
Ett mycket bra inlägg från Tom Puleos blogg om SPSecurityTrimmedControl. Måste absolut testa det.
Tag: Preview
Windows 8 preview
I have tested the Windows 8 developer preview. VMWare player 3 didn’t manage it, so I installed VirtualBox and it ran very well. One thing I did was to enable full screen on VirtualBox. Here is the list of features you get if you install the developer preview:
- Windows SDK for Metro style apps
- Microsoft Visual Studio 11 Express for Windows Developer Preview
- Microsoft Expression Blend 5 Developer Preview
- 28 Metro style apps including the BUILD Conference app
Tag: Allmän Programmering
Singleton vs static
Have you wondered what to use a singleton object or a class with static methods. Well, here is an awesome comparision of these techniques. Static methods and classes are easy to use, but you can’t them as objects, implement interfaces and have constructors with parameters.
Rensa text från html-taggar
Ett bra exempel finns här.
using System.Text.RegularExpressions;
...
const string HTML\_TAG\_PATTERN = "<.\*?>";
static string StripHTML (string inputString)
{
return Regex.Replace(inputString, HTML\_TAG\_PATTERN, string.Empty);
}
ForEach-metod i List
En intressant variant av foreach är ForEach-metoden i List. Titta på det lilla exemplet:
private static void SavePlacesToDB(SQLiteConnection cnn,
List<dynamic> places)
{
places.ForEach(obj => SavePlaceToDB(obj, cnn));
}
```Här används även det nya objektet [dynamic](http://msdn.microsoft.com/en-us/library/dd264736.aspx) som har kommit i Visual Studio 2010, samt en [lambda expression (=>)](http://msdn.microsoft.com/en-us/library/bb397687.aspx).
kort variant av if-else
Inget speciellt egentligen med detta men vill skriva upp det här för att jag brukar glömma det. Det är samma syntax som i många andra språk:
bool value = "dit" == "dat" ? true : false;
Motsvarar:
bool value;
if ("dit" == "dat")
{
value = true;
}
else
{
value = false;
}
Tag: Time
1DayLater.com - the best time tracking
I discovered a great tool for time tracking: 1DayLater. So far I am very pleased. You can add activities, write hash tagged descriptions, get an overview over you consultant hours and much more
Tag: Usercontrol
Webpart in a reusable user control
In my previous post I wrote about using IgnoreIfAlreadyExists=“True” for preventing of adding webparts multiple times. It works fine until you redeploy your project. Another approach is to use a user control with you webpart. Add mapped folder CONTROLTEMPLATES. Create a new user control, add you assembly and your webpart. Then you can add this user control wherever you need it.
<%@ Register
tagprefix="SPSWC"
Namespace="Microsoft.SharePoint.Portal.WebControls"
Assembly="Microsoft.SharePoint.Portal, Version=14.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<SPSWC:SocialCommentWebPart runat="server"
AllowEdit="True"
AllowConnect="True"
ConnectionID="00000000-0000-0000-0000-000000000000"
Title="Note Board"
IsIncluded="True"
Dir="Default"
PartImageLarge=""
IsVisible="True"
AllowMinimize="True"
ZoneID=""
ID="g\_5937b022\_83bb\_40cb\_b68f\_bd565bf96885"
FrameState="Normal"
ExportMode="All"
TitleLocIdNum="0"
AllowHide="True"
SuppressWebPartChrome="False"
DetailLink=""
ChromeType="None"
DescriptionLocId="Null"
TitleLocId="Null"
MissingAssembly="Cannot import this Web Part."
PartImageSmall=""
AllowRemove="True"
HelpMode="Modeless"
FrameType="None"
AllowZoneChange="True"
PartOrder="1"
Description="Enable users to leave short, publicly-viewable notes about this page."
HelpLink=""
DescriptionLocIdNum="0"
ExportControlledProperties="True"
IsIncludedFilter=""
\_\_MarkupType="vsattributemarkup"
\_\_WebPartId="{5937b022-83bb-40cb-b68f-bd565bf96885}"
WebPart="true"
Height=""
Width="">
</SPSWC:SocialCommentWebPart>
```Then add your user control into page layout like this:
<%@ Register Tagprefix=“CONTOSO” TagName=“SocialComment” Src="~/_CONTROLTEMPLATES/CONTOSO/SocialCommentUserControl.ascx" %> <CONTOSO:SocialComment id=“SocialComment” runat=“server” />
Tag: OpenSource
Sharepoint repos on github
You may think all interesting open source Sharepoint projects on codeplex. Well it is true, but there are some interesting projects on github as well. There are 17 projects for now. From a matrix to RichControls.
Sharepoint + OpenSource = Sant
Om man söker på Sharepoint i codeplex.com får man 729 projekt som är alltså öppna. Det är inte illa. Bland dem finns till exempel Sharepoint Log Viewer. Till det kommer 713 öppna projekt som är taggade ASP.NET som kan användas väldigt mycket i Sharepoint-utveckling. Bland ASP.NET-taggade finns smidiga Telerik Extensions. Powershell är också absolut en tag som man ska söka på i codeplex. codeplex.com är Microsofts officiella OpenSource-portal. Det måste finnas andra sidor där öppna projekt inom Sharepoint och ASP.NET samlas. Tipsa gärna i kommentarer.
Tag: Dispose
WithWeb-pattern of Jonas Nilsson
Jonas Nilsson shows an interesting approach for working with SPSite and SPWeb which must be disposed. Create a helper method WithWeb and send an Action parameter:
public void WithWeb(string uri, Action<SPWeb> action)
{
using (SPSite site = new SPSite(uri))
{
using (SPWeb web = site.OpenWeb())
{
action(web);
}
}
}
```Here is my implementation of this pattern:
public static class DisposalService { public static void WithWeb(string uri, Action action) { using (var site = new SPSite(uri)) { using (var web = site.OpenWeb()) { web.UnsafeUpdate(action); } } } public static void WithElevatedWeb(string uri, Action action) { SPSecurity.RunWithElevatedPrivileges(() => WithWeb(uri, action)); } }
Tag: Spgroup
Check if user is in group
Use LINQ to check if user is in a group. Create an extension method.
public static bool InGroup(this SPUser user, SPGroup group)
{
return user.Groups.Cast<SPGroup>()
.Any(g => g.ID == group.ID);
}
```EDIT 2011-01-22: There is a shortcoming of this method. You won't get a user which is in group through a AD group. You'll get only users and ad groups. [But there is another method to check if a user is inside an AD group](/2012/01/16/check-if-a-user-is-in-a-ou/ "See my post about how to retrieve users from AD groups with PrincipalSearcher"). How could we combine them?... I think we must start from group this time, not from user:
public static bool HasUser(this SPGroup user, SPUser user) { var users = group.Users.Cast(); var samAccount = Regex.Replace(user.LoginName, @".*\\(.*)", “$1”, RegexOptions.None); var exists = users.Any(u => u.LoginName.Equals(user.LoginName)); if (!exists) { var ctx = new PrincipalContext(ContextType.Domain); foreach (var u in users) { var login = u.LoginName; var groupName = Regex.Replace(login, @".*\\(.*)", “$1”, RegexOptions.None); var grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName); if (grp == null) continue; var principals = grp.GetMembers(true); exists = principals.Any(p => p.SamAccountName.Equals(samAccount, StringComparison.InvariantCultureIgnoreCase)); if (exists) break; } } return exists; }
Tag: Internal Name
PublishingRollupImage
The internal name of Rollup Image or Upplyft bild is PublishingRollupImage
Interna fältnamn i SPList
Här är en väldigt bra lista över fältnamn, eller denna lista, till och med bättre i SPList, både Display Name, Internal Name och GUID. En annan bra länk är förklaringen om hur interna fältnamn är uppbyggda av Marc Anderson. För att se interna namnet kan man klicka på kolumnrubriken (för att sortera) så ser man det i URL:en. EDIT: den här tyckte jag mycket om.
Tag: Regex
Rensa text från html-taggar
Ett bra exempel finns här.
using System.Text.RegularExpressions;
...
const string HTML\_TAG\_PATTERN = "<.\*?>";
static string StripHTML (string inputString)
{
return Regex.Replace(inputString, HTML\_TAG\_PATTERN, string.Empty);
}
Tag: Licenser
lästips om sharepoint-licenser
Känns licenser för Sharepoint är ett djungel. Läs det här bloginlägget.
Tag: Sharepoint.stackexchange
less.js
Det finns ett intressant projekt som kan hjälpa att strukturera css-filer. Du skriver regler i en kombination av css och javascript. Det omvandlas med hjälp av js till css. Projektet heter less.js, läs mer om detta på sharepointoverflow.
Tag: ViewState
ViewState
Om du vill behålla dina värden på variabler mellan postbacks, använd ViewState:
if (ViewState\["MaxNumberOfArticles"\] != null)
{
MaxNumberOfArticles = (int) ViewState\["MaxNumberOfArticles"\];
}
MaxNumberOfArticles += 10;
ViewState.Add("MaxNumberOfArticles", MaxNumberOfArticles);
RenderNews();
Tag: Lifecycle
Webpart Livscykel
http://nishantrana.wordpress.com/2009/02/14/understanding-web-part-life-cycle/ OnInit – Configuration values set using WebBrowsable properties and those in web part task pane are loaded into the web part. LoadViewState – The view state of the web part is populated over here. CreateChildControls – All the controls specified are created and added to controls collection. When the page is being rendered for the first time the method generally occurs after the OnLoad() event. In case of postback, it is called before the OnLoad() event. We can make use of EnsureChildControls() - It checks to see if the CreateChildControls method has yet been called, and if it has not, calls it. OnLoad User Generated Event – for e.g. button click on the web part. OnPreRender – Here we can change any of the web part properties before the control output is drawn. RenderContents – Html Output is generated. SaveViewState - View state of the web part is serialized and saved. Dispose UnLoad.
Tag: Resharper
resharper
Bara att rekommendera. Dagens: Ctrl-Shift-Backspace: Go to last edit. http://www.jetbrains.com/resharper/webhelp/Reference__Keyboard_Shortcuts.html http://blog.drorhelper.com/2009/05/15-resharper-keyboard-shortcuts-you.html
Aktivera intellisense för javascript i VS
Det finns ett sätt att aktivera intellisense för javascript i VS: Klistra in det i ditt js-fil eller aspx:
/// <reference name="MicrosoftAjax.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.core.debug.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.debug.js" />
```Men tyvärr [kommer det inte funka om du har installerat Resharper](http://devnet.jetbrains.net/thread/297493). Eller lägg till vanliga script-taggar som beskrivet i boken Sharepoint As Developer Platform:
<asp:PlaceHolder ID=“PlaceHolder1” runat=“server” Visible=“false”> </asp:PlaceHolder>
Tag: Peopleeditor
commaseparatedaccounts
om du lägger till commaseparatedaccounts i PeopleEditor, använd ett komma, inte semikolon, som man kan tro…
PeopleEditor med ifyllt värde
I vissa fall är det bra att ha ett ifyllt värde i PeoplePicker, till exempel, namn på personen som kör koden. Det finns olika beskrivningar om hur man gör det. Allmänt, och mer specifikt för webparts. Jag har även testat kod från boken Sharepoint 2010 as a Development Platform:
private PeopleEditor peopleEditor;
private void EnsureChildControls()
{
peopleEditor = new PeopleEditor();
peopleEditor.AutoPostBack = true;
peopleEditor.ID = "MyPeopleEditor";
peopleEditor.AllowEmpty = false;
peopleEditor.MultiSelect = true;
peopleEditor.SelectionSet = "User,SPGroup" ;
MyPanel.Controls.Add(peopleEditor);
}
protected void initPeopleEditor()
{
PickerEntity entity = new PickerEntity();
entity.Key = SPContext.Current.Web.CurrentUser.LoginName;
// Make sure the entity is correct
entity = peopleEditor.ValidateEntity(entity);
ArrayList entityArrayList = new ArrayList();
entityArrayList.Add(entity);
peopleEditor.UpdateEntities(entityArrayList);
}
```Problemet med denna kod är att man får felet "Ingen exakt matchning" och man kan inte submitta. I application pages kan man enkelt fylla i aktuella användaren genom att ändra **CommaSeparatedAccounts** property i **Page\_Load**\-metoden.
peopleEditor.CommaSeparatedAccounts = SPContext.Current.Web.CurrentUser.LoginName;
Tag: Validate AspnetForm
jQuery validation with asp.net
De kan var lite jobbigt att få till jQuery validate att funka ihop med aspnetForm…
$(document).ready(function () {
newsLetterForm = $("#aspnetForm");
newsLetterForm.validate({
onsubmit: false,
rules: {
"<%= emailTextBox.UniqueID %>": {
required: true,
email: true
}
}
});
$("#<%= sendButton.ClientID %>").live("click", function {
var isValid = newsLetterForm.valid();
if (!isValid) {
e.preventDefault();
}
});
});
jQuery validate kräver name på elementen inuti formen. För att ta reda på name, måste man använda Control.UniqueId För att det ska fungera måste du köra preventDefault()
Tag: Sharepointprogram
Sharepoint Manager 2010
Ett ytterligare grym verktyg från codeplex-lägret: Sharepoint Manager.
Sharepoint Log Viewer
Mycket bra verktyg för att debugga din sharepoint applikation är Sharepoint Log Viewer som är Open Source och finns att hämta på codeplex.com Det går att öppna en logg-fil, det går att köra live monitoring och att exportera. Det sköna är att det är lätt att söka efter correlations-id. Rekommenderar verktyget!
Comments from Wordpress.com
Sharepoint + OpenSource = Sant « Sharepoint. Kunskap. Upptäckter på resan. - Mar 3, 2011
Hämta schema från en befintlig SPList
Ibland är det så att man vill ha en speciell mall för en SPList, man har redan skapat en mall manuellt på sajten. Då är det enklaste sättet att hämta schema.xml och Windows SharePoint Services 3.0 Tools. När man installerat det så startar man Sharepoint Solution Generator 2008. Sedan måste man hitta sin lista, eller dokumentbiblioteket och exportera. Sedan är det bara att importera till sitt projekt i Visual Studio.
Tag: Show
jQuery hide
Jag har alltid använt hide-funktionen i jQuery för att gömma vissa element som inte behövs i början. Det kan resultera att användaren ser skymningen av dem i laddningen av sidan. Vilket inte är så bra. Men det har visat sig, att hide behöver inte köras av jQuery. Bara göm dem med hjälp av css. jQuery show kommer funka ändå.
Tag: Databas
Viss hjälpinnehåll
Om det strular med att visa hjälpinnehåll, följ denna beskrivning för att lösa det. Du måste ge rättigheter på procedure som heter proc_EnumResourcesAtScope på Sharepoint-AdminContent-databasen:
GRANT EXECUTE ON " proc\_EnumResourcesAtScope" TO "contoso\\SP\_Apppool"
Återskapa koppling till login i DB efter restore
Om du har kört restore på en databas, så kan det hända att det inte går att ändra rättigheter, och den login du använt inte kan se databasen. SQL Server spottar ut felmeddelandet med kod 15023:
The database is not accessible. (Object Explorer)
Om det är WebService som i sin tur anropar databasen, kan det komma ett sådant felmeddelande:
The underlying provider failed on Open.
Lösningen är att uppdatera kopplingen. Hämtat från denna blog.
Tag: Konton
Viss hjälpinnehåll
Om det strular med att visa hjälpinnehåll, följ denna beskrivning för att lösa det. Du måste ge rättigheter på procedure som heter proc_EnumResourcesAtScope på Sharepoint-AdminContent-databasen:
GRANT EXECUTE ON " proc\_EnumResourcesAtScope" TO "contoso\\SP\_Apppool"
Tag: Procedure
Viss hjälpinnehåll
Om det strular med att visa hjälpinnehåll, följ denna beskrivning för att lösa det. Du måste ge rättigheter på procedure som heter proc_EnumResourcesAtScope på Sharepoint-AdminContent-databasen:
GRANT EXECUTE ON " proc\_EnumResourcesAtScope" TO "contoso\\SP\_Apppool"
Tag: Feature
Registrera javascript i feature
Om det inte passar att javascript i masterpage eller egen webpart, registrera det som customaction och aktivera feature. Läs mer här. Här är ett exempel:
<CustomAction
Location="ScriptLink"
ScriptSrc="~sitecollection/\_layouts/MyProject/awesome.js"
Sequence="101">
</CustomAction>
Tag: Default.aspx
Ge andra rättigheter på default.aspx
Om man inte vill medlemmarna på SPWeb rättighet att redigera första sidan hur som helst, måste man bryta arvet på Sidor/default.aspx. Lätt att göra det manuellt (Site Actions - Show all Content - Pages - default.aspx - dokumenträttigheter). I koden kan man göra det så här:
//first find SPListItem defaultAspx
//then find SPGroup members (perhaps via web.AssociatedMemberGroup
defaultAspx.BreakRoleInheritance(true);
defaultAspx.RoleAssignments.RemoveFromCurrentScopeOnly(members);
SPRoleAssignment roles = new SPRoleAssignment(members);
SPRoleDefinition perms = web.RoleDefinitions.GetByType(SPRoleType.Reader);
roles.RoleDefinitionBindings.Add(perms);
defaultAspx.RoleAssignments.Add(roles);
Tag: Scope
Sök på hela SPSite
När man skapar en egen searchbox, kan det vara lite meckigt att få till söken rätt. För att kunna söka på hela SPSite, oberoende var man är (subsite), ange property:
<Property Name="DropDownMode">**HideDD\_useDefaultScope**</Property>
Det kan hända att du måste skapa en egen scope.
Tag: Sök
Sök på hela SPSite
När man skapar en egen searchbox, kan det vara lite meckigt att få till söken rätt. För att kunna söka på hela SPSite, oberoende var man är (subsite), ange property:
<Property Name="DropDownMode">**HideDD\_useDefaultScope**</Property>
Det kan hända att du måste skapa en egen scope.
Tag: Sökruta
Sök på hela SPSite
När man skapar en egen searchbox, kan det vara lite meckigt att få till söken rätt. För att kunna söka på hela SPSite, oberoende var man är (subsite), ange property:
<Property Name="DropDownMode">**HideDD\_useDefaultScope**</Property>
Det kan hända att du måste skapa en egen scope.
Autocomplete för sökruta i Sharepoint
Ett mycket trevligt projekt: Search As You Type på Codeplex. Ladda ner textfilen och lägg till javascript och css från den filen till masterpage. Så enkelt är det. Jag har testat det genom att direkt stoppa in koden i Chrome Console.
Tag: Application Page
PeopleEditor med ifyllt värde
I vissa fall är det bra att ha ett ifyllt värde i PeoplePicker, till exempel, namn på personen som kör koden. Det finns olika beskrivningar om hur man gör det. Allmänt, och mer specifikt för webparts. Jag har även testat kod från boken Sharepoint 2010 as a Development Platform:
private PeopleEditor peopleEditor;
private void EnsureChildControls()
{
peopleEditor = new PeopleEditor();
peopleEditor.AutoPostBack = true;
peopleEditor.ID = "MyPeopleEditor";
peopleEditor.AllowEmpty = false;
peopleEditor.MultiSelect = true;
peopleEditor.SelectionSet = "User,SPGroup" ;
MyPanel.Controls.Add(peopleEditor);
}
protected void initPeopleEditor()
{
PickerEntity entity = new PickerEntity();
entity.Key = SPContext.Current.Web.CurrentUser.LoginName;
// Make sure the entity is correct
entity = peopleEditor.ValidateEntity(entity);
ArrayList entityArrayList = new ArrayList();
entityArrayList.Add(entity);
peopleEditor.UpdateEntities(entityArrayList);
}
```Problemet med denna kod är att man får felet "Ingen exakt matchning" och man kan inte submitta. I application pages kan man enkelt fylla i aktuella användaren genom att ändra **CommaSeparatedAccounts** property i **Page\_Load**\-metoden.
peopleEditor.CommaSeparatedAccounts = SPContext.Current.Web.CurrentUser.LoginName;
masterpage i application page
Om det inte funkar att ändra masterpage genom DynamicMasterPageFile:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CreateNews.aspx.cs" Inherits="MyProject.Layouts.MyProject.CreateNews"
DynamicMasterPageFile="~masterurl/default.master" %>
Kör det här
<script type="text/C#" runat="server">
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
this.MasterPageFile = "/\_catalogs/masterpage/my-custom.master";
}
</script>
Tag: Page_load
PeopleEditor med ifyllt värde
I vissa fall är det bra att ha ett ifyllt värde i PeoplePicker, till exempel, namn på personen som kör koden. Det finns olika beskrivningar om hur man gör det. Allmänt, och mer specifikt för webparts. Jag har även testat kod från boken Sharepoint 2010 as a Development Platform:
private PeopleEditor peopleEditor;
private void EnsureChildControls()
{
peopleEditor = new PeopleEditor();
peopleEditor.AutoPostBack = true;
peopleEditor.ID = "MyPeopleEditor";
peopleEditor.AllowEmpty = false;
peopleEditor.MultiSelect = true;
peopleEditor.SelectionSet = "User,SPGroup" ;
MyPanel.Controls.Add(peopleEditor);
}
protected void initPeopleEditor()
{
PickerEntity entity = new PickerEntity();
entity.Key = SPContext.Current.Web.CurrentUser.LoginName;
// Make sure the entity is correct
entity = peopleEditor.ValidateEntity(entity);
ArrayList entityArrayList = new ArrayList();
entityArrayList.Add(entity);
peopleEditor.UpdateEntities(entityArrayList);
}
```Problemet med denna kod är att man får felet "Ingen exakt matchning" och man kan inte submitta. I application pages kan man enkelt fylla i aktuella användaren genom att ändra **CommaSeparatedAccounts** property i **Page\_Load**\-metoden.
peopleEditor.CommaSeparatedAccounts = SPContext.Current.Web.CurrentUser.LoginName;
Tag: Mas
~masterurl/default.master & ~masterurl/custom.master
Läser “SharePoint 2010 as a Development Platform”. Kan verkligen rekommendera den. Idag har jag förståt vad default.master och custom.master innebär. De pekar på de master-filer som är inställda på web-nivå. Så det är ingen idé att ändra DynamicMasterUrl i @Page-direktivet till sin egen (om du inte vill ha någon helt annan master än i resten av portalen).
Tag: Funktioner
Flaggor i powershellfunktioner
Har länge letat efter möjligheten att skriva funktioner med egna flaggor på ett enkelt sätt. “Flaggor” (flags) är namngivna parametrar. Följande kommando har flaggor: -Identity, -WebApplication och -GACDeployment.
Install-SPSolution -Identity contoso.portal.wsp -WebApplication http://contoso -GACDeployment
```Låt oss titta på ett gammalt exempel:
function hello($firstname, $lastname) { Write “Hello $firstname $lastname” }
hello -firstname Gregor -lastname Samsa
hello -lastname Samsa -firstname Gregor
function helloInColor($firstname, $lastname, [switch]$red = $false, [switch]$green = $false) { $greeting = “Hello, $firstname $lastname” if($red) { Write-Host -ForegroundColor Red $greeting } if($green) { Write-Host -ForegroundColor Green $greeting } }
Tag: Inparametrar
Flaggor i powershellfunktioner
Har länge letat efter möjligheten att skriva funktioner med egna flaggor på ett enkelt sätt. “Flaggor” (flags) är namngivna parametrar. Följande kommando har flaggor: -Identity, -WebApplication och -GACDeployment.
Install-SPSolution -Identity contoso.portal.wsp -WebApplication http://contoso -GACDeployment
```Låt oss titta på ett gammalt exempel:
function hello($firstname, $lastname) { Write “Hello $firstname $lastname” }
hello -firstname Gregor -lastname Samsa
hello -lastname Samsa -firstname Gregor
function helloInColor($firstname, $lastname, [switch]$red = $false, [switch]$green = $false) { $greeting = “Hello, $firstname $lastname” if($red) { Write-Host -ForegroundColor Red $greeting } if($green) { Write-Host -ForegroundColor Green $greeting } }
defaultvärde på parametern i powershellfunktioner
Läser ett intressant inlägg om deployskript i powershell. Har upptäckt att man kan stoppa in ett defaultvärde i funktionens parameter. Så i stället för
function hello($name) {
Write-Host $name
}
Kan man köra:
function hello($name = "Gregor") {
Write-Host $name
}
```Mycket smidigt.
Polymorfi och javascript
En skräckscenario: du använder två javascript-bibliotek. Men de har var sin funktion som har samma namn. Det spelar även ingen roll om antalet inparametrar är olika. Så det blir samma sak som myfunc(param1, param2) och myfunc(param1). Grejen är att funktionen som laddas sist är den som kommer köras. Katastrof! Men det finns lösningar. Börja läsa här om hur man kan simulera polymorfi i javascript på about.com. Säg vi har en funktion som heter MoveToDate(strdate, ctxid) den ingår i init.debug.js (som används av Sharepoint kalenderwebpart). Sedan har vi något annat javascript-bibliotek som också har MoveToDate(param). Låt oss göra det polymorfiskt. Här är koden:
Tag: Switch
Flaggor i powershellfunktioner
Har länge letat efter möjligheten att skriva funktioner med egna flaggor på ett enkelt sätt. “Flaggor” (flags) är namngivna parametrar. Följande kommando har flaggor: -Identity, -WebApplication och -GACDeployment.
Install-SPSolution -Identity contoso.portal.wsp -WebApplication http://contoso -GACDeployment
```Låt oss titta på ett gammalt exempel:
function hello($firstname, $lastname) { Write “Hello $firstname $lastname” }
hello -firstname Gregor -lastname Samsa
hello -lastname Samsa -firstname Gregor
function helloInColor($firstname, $lastname, [switch]$red = $false, [switch]$green = $false) { $greeting = “Hello, $firstname $lastname” if($red) { Write-Host -ForegroundColor Red $greeting } if($green) { Write-Host -ForegroundColor Green $greeting } }
Tag: Upptäckt
Flaggor i powershellfunktioner
Har länge letat efter möjligheten att skriva funktioner med egna flaggor på ett enkelt sätt. “Flaggor” (flags) är namngivna parametrar. Följande kommando har flaggor: -Identity, -WebApplication och -GACDeployment.
Install-SPSolution -Identity contoso.portal.wsp -WebApplication http://contoso -GACDeployment
```Låt oss titta på ett gammalt exempel:
function hello($firstname, $lastname) { Write “Hello $firstname $lastname” }
hello -firstname Gregor -lastname Samsa
hello -lastname Samsa -firstname Gregor
function helloInColor($firstname, $lastname, [switch]$red = $false, [switch]$green = $false) { $greeting = “Hello, $firstname $lastname” if($red) { Write-Host -ForegroundColor Red $greeting } if($green) { Write-Host -ForegroundColor Green $greeting } }
Tag: Administration
Lägg till en annan administrator på site collection
Man kan göra det i CA (Application Mgmnt - Change Site Cltn Admins). Det kan man också snabbt göra med powershell:
Set-SPSite http://contoso -SecondaryOwnerAlias contoso\\admin2
Tag: Konfiguration
Lägg till en annan administrator på site collection
Man kan göra det i CA (Application Mgmnt - Change Site Cltn Admins). Det kan man också snabbt göra med powershell:
Set-SPSite http://contoso -SecondaryOwnerAlias contoso\\admin2
Tag: Videokurs
Videokurs om Web Content Management
På microsoft.com finns en ny videokurs om web content management. Där kan du lära dig om hur man implementerar cms-funktionalitet med sharepoint, bl.a.: content types, page layouts med mera. Tack för tipset, deutschsprachige Sharepoint-Community.
Tag: Wcm
Videokurs om Web Content Management
På microsoft.com finns en ny videokurs om web content management. Där kan du lära dig om hur man implementerar cms-funktionalitet med sharepoint, bl.a.: content types, page layouts med mera. Tack för tipset, deutschsprachige Sharepoint-Community.
Tag: Säkerhet
SPSecurityTrimmedControl
Ett mycket bra inlägg från Tom Puleos blogg om SPSecurityTrimmedControl. Måste absolut testa det.
Tag: Powershell_ise
powershell_ise
Powershell ISE (Integrated Scripting Environment) är ett bra verktyg för att skriva powershell-skript med färgmarkering och möjligheten att testköra det. Synd bara att det inte är aktiverat ifrån början i Server 2008. För att [aktivera](Import-Module ServerManager 2 Add-Windowsfeature PowerShell-ISE ) kör följande kommandon i powershell:
Import-Module ServerManager
Add-Windowsfeature PowerShell-ISE
För att sedan starta powershell kör:
powershell\_ise
Tag: Serverinstallation
powershell_ise
Powershell ISE (Integrated Scripting Environment) är ett bra verktyg för att skriva powershell-skript med färgmarkering och möjligheten att testköra det. Synd bara att det inte är aktiverat ifrån början i Server 2008. För att [aktivera](Import-Module ServerManager 2 Add-Windowsfeature PowerShell-ISE ) kör följande kommandon i powershell:
Import-Module ServerManager
Add-Windowsfeature PowerShell-ISE
För att sedan starta powershell kör:
powershell\_ise
Problem med Sharepoint efter installation av SQL Server
Jag installerade Sharepoint först vilket skapade nödvändiga databaser. Sedan installerade jag SQL Server och angav det som default instance. Efter det gick det inte att använda Sharepoint. Felmeddelandet som spottades ut var “Cannot connect to the configuration database”. Alla försök att starta SQL Server med instansen “Sharepoint” var verkningslösa. Den enda lösningen var att avinstallera Sharepoint, alla Web Sites (i IIS administration) och installera Sharepoint på nytt, ange den nya SQL Server som standard för denna Sharepoint-installation.
Installera viktiga program på Windows Server
Nu när vi kommit så långt med installationen, så kan vi installera viktiga program.
- Alcohol 52 för att mounta .iso-filer.
- Visual Studio 2010 Ultimate. Klicka på “Custom” under installationen och välj bort komponenter man inte intresserad av. Jag valde bort Visual Basic, C++, F#, SQL Server Express.
- SQL Server 2008 R2 Enterprise.
- Silverlight 4 Tools for Visual Studio 2010
- TortoiseSVN, klienten för Subversion
- AnkhSVN, plugin till Visual Studio för versionhantering.
Comments from Wordpress.com
timswe - May 4, 2011
Installera Sharepoint Server
Nu när du installerat Windows Server, så kan du installera Sharepoint Server. 1. Skaffa Sharepoint. Som student kan du få licensnyckeln från MSDNAA på ditt universitet. Ladda ner Sharepoint Server (Trial Version). Som version, välj “Enterprise Client Access License features”.
Läs i min serie om server installation:
- Installera Windows Server
- Konfigurera backup
- Installera Sharepoint Server
2. Kör den nerladdade SharePointServer.exe-filen. Klicka på “Install software prerequisites”. Tar en stund (10 för mig). Efter det krävs det omstart. Efter omstart fortsätter den installera program. (Det tog 10 minter till). 3. Klicka på “Install Sharepoint Server”. Välj Standalone. Ange din licensnyckel från MSDNAA eller trial du fått. 4. Kör “SharePoint Products Configuration Wizard” (inga val att göra).
Windows Server Backup
Följ denna instruktion för att köra backup. Lägg till Feature: Windows Server Backup. När det är installerat expandera Storage under Server Manager. Klicka på Backup Once till höger. Välj helst Full Server (då sparas hela hårddisken). Destinationshårddisken ska vara formaterad som NTFS.
Restore
Har inte provat köra restore än. Så fort jag kört det kommer jag rapportera om det.
Installera Windows Server på fysisk hårddisk
Det bästa är att installera Windows Server och Sharepoint på en virtuell hårddisk. Följ denna instruktion och installera det. Men om man har en äldre dator (som är mitt fall) och ändå vill testa saker och kunna utveckla, så är det lönt att installera på en riktig hårddisk. Det bästa är att använda en SSD-hårddisk. Sedan är det möjligt att installera Windows Server på en VHD och boota från den (mer info kommer senare förhoppningsvis). Om man har installerat på en riktig hårddisk, kan man omvandla det till VHD med hjälp av till exempel Disk2VHD (mer info om det kommer senare förhoppningsvis). 1. Välj Svenska som locale. När installationen av Windows Swerver 2010 R2 är klar ombeds du att “Press CTRL + ALT + DELETE” för att logga in. 2. Tryck på “OK” för att byta lösenord för administratörskontot. Välj ett lösenord, bekräfta det och tryck på Enter (eller pilen till höger). Tryck på OK för att bekräfta att lösenordet är bytt. Du kommer nu in på skrivbordet. 3. Tryck på “Provide computer name and domain”. I system properties, fliken Computer Name, tryck på Change och ge din dator ett bättre namn exempelvis “SharePoint”. Tryck på OK och “Restart Later”. 4. Aktivera trådlöst: Tryck på “Add feature”. Bocka i Wireless. 5. Tryck på “Download and install updates” och i “Windows Update”, tryck på “Turn on automatic updates”. Tryck på “Install updates” när Windows har letat fram de du behöver. Starta om datorn. 6. Logga in igen som administratör och välj “Add features” under avdelning 3 i “Initial Configuration Tasks”. Kicka på “Desktop Experience” (som gör Windows Server mer användare vänligt) och “Add requered features”. Därefter Next och Install. Starta om datorn. I “Shutdown Event Tracker”, skriv vad som helst i “Comment” och tryck OK. 7. När du har loggat in igen så tryck Close för att avsluta konfigurationen av “Desktop Experience”. Du är nu klar med “Initial Configuration Tasks”. Syns den fortfarande kan du klicka i “Do not show this window at logon” och trycka close. Saknar du den kan du få tillbaka den genom att trycka på Start och skriva OOBE.EXE. 8. Du skall nu in i “Server Manager” som bör ha startat. Om inte, klicka på symbolen till höger om Start-knappen (dator med väska). Se till att “Server Manager” är markerad i vänster kolumn. För att slippa att IE blockerar alla webbplatser så klicka på “Configure IE ESC” under “Security Information”. Klicka Off för både administratörer och användare. 9. Om du vill slippa ge en kommentar varje gång du stänger av eller startar om den virtuella maskinen i “Spåra händelser i samband med avstängning” (“Shutdown Event Tracker”) kan du göra såhär: Tryck Start och skriv gpedit.msc och tryck Enter. Expandera Datorkonfiguration (“Computer Configuration”) och Administrativa mallar (“Administrative Templates”) och välj “System”. I höger kolumn, dubbelklicka på Visa spåraren av avstängningshändelser (“Display Shutdown Event Tracker”), klicka Inaktiverad (“Disabled”) och OK. 10. Konfigurationen av Windows Server är nu klar. Du bör stänga en restore point.’ Nu är Windows Server installerad. Fortsätt med: Konfigurera backup Installera Sharepoint Server …
Aktivera trådlöst i Windows Server
Om man installerat Windows Server på fysisk hårddisk på din bärbara så vill man säkert använda trådlöst nätverk. Här är en guide med bilder hur man aktiverar denna feature.
Tag: FieldRef
Lägga till Företagsnyckelord
Det är enkelt att lägga till kolumnen företagsnyckelord. Skapa egen contenttype och lägg till fieldref.
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
Funkar utmärkt t.ex. om du ärver ContentTypen från Announcements. Lite svårare är det med Dokument. I själva verket läggs till fler kolumner för att det ska fungera. I Announcements finns de redan. Men i dokument måste du lägga till dem extra:
<!-- Enterprise Keywords-->
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
<!-- in order keywords to work, two additional fields have to be created-->
<!-- TaxKeywordTaxHTField -->
<FieldRef ID="{1390a86a-23da-45f0-8efe-ef36edadfb39}"/>
<!-- TaxCatchAll -->
<FieldRef ID="{f3b0adf9-c1a2-4b02-920d-943fba4b3611}"/>
Utan TaxKeywordTaxHTField uppstår fel av typen: “Kan inte hämta värdet från kolumnen {00000000…}”.
ID på befintliga kolumner
Det finns en fin lista över id på kolumner som man kan lägga till. Här är ett exempel hur man kan använda det. Här är ett exempel på två extra kolumner i contenttype:
<FieldRefs>
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
<!-- Enterprise Keywords-->
<FieldRef ID="{3de94b06-4120-41a5-b907-88773e493458}"/>
<!-- PublishingImage-->
</FieldRefs>
Tag: SPUtility
Visa i hur länge sedan något hänt
Säg du vill visa när något har skapats. Att visa datum funkar. Ännu bättre är att visa det i stil: “För tre dagar sedan” eller så. Det finns en bra metod i SPUtility:
SPUtility.TimeDeltaAsString(Published, DateTime.Now);
Tag: Guid
ID på befintliga kolumner
Det finns en fin lista över id på kolumner som man kan lägga till. Här är ett exempel hur man kan använda det. Här är ett exempel på två extra kolumner i contenttype:
<FieldRefs>
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"/>
<!-- Enterprise Keywords-->
<FieldRef ID="{3de94b06-4120-41a5-b907-88773e493458}"/>
<!-- PublishingImage-->
</FieldRefs>
Tag: Ecmascript
Aktivera intellisense för javascript i VS
Det finns ett sätt att aktivera intellisense för javascript i VS: Klistra in det i ditt js-fil eller aspx:
/// <reference name="MicrosoftAjax.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.core.debug.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.debug.js" />
```Men tyvärr [kommer det inte funka om du har installerat Resharper](http://devnet.jetbrains.net/thread/297493). Eller lägg till vanliga script-taggar som beskrivet i boken Sharepoint As Developer Platform:
<asp:PlaceHolder ID=“PlaceHolder1” runat=“server” Visible=“false”> </asp:PlaceHolder>
Tag: Intellisense
Aktivera intellisense för javascript i VS
Det finns ett sätt att aktivera intellisense för javascript i VS: Klistra in det i ditt js-fil eller aspx:
/// <reference name="MicrosoftAjax.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.core.debug.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.debug.js" />
```Men tyvärr [kommer det inte funka om du har installerat Resharper](http://devnet.jetbrains.net/thread/297493). Eller lägg till vanliga script-taggar som beskrivet i boken Sharepoint As Developer Platform:
<asp:PlaceHolder ID=“PlaceHolder1” runat=“server” Visible=“false”> </asp:PlaceHolder>
Tag: Plugin
Validera din form på klienten
Det finns ett mycket bra jQuery-tillägg som kan validera din data i en formulär på ett enkelt sätt. Se en demo. Referera till validate.js och ange rätt css-klasser på dina inputs: “required”, “error”, “url”, “valid”. Mycket smidigt.
Tag: Cloud9
cloud9 web ide
Skapa javascript-appar i din webbläsare. Mycket smidigt. Direkt kontakt till github.
Tag: Ide
cloud9 web ide
Skapa javascript-appar i din webbläsare. Mycket smidigt. Direkt kontakt till github.
Tag: Coderun
Tag: Php
Tag: Amrein
Gratis webparts från Amrein
Finns gratis webparts från Amrein Engineering. Fått tips från sharepoint.stackexchange.com. Testat AELightBox. Men det är rätt så krångligt med inställningar. Den kräver att man skriver in vilken vy och så vidare. Vyn ska ha “title” och den kräver även kolumner så som ImageWidth och ImageHeight. Detta känns lite mindre användbart eftersom de här värdena kunde man hämta från bilden själv och anpassa till skärmens upplösning. [caption id=“attachment_405” align=“aligncenter” width=“291” caption=“Amrein Lightbox”][/caption]
Tag: Treeview
TreeNode
Ibland vill man visa data i TreeView. Här är ett litet exempel på koden:
using (SPWeb web = SPContext.Current.Web)
{
foreach (SPWeb topWeb in web.GetSubwebsForCurrentUser())
{
TreeNode tn = new TreeNode(topWeb.Name);
tn.NavigateUrl = topWeb.ServerRelativeUrl;
this.treeviewProjects.Nodes.Add(tn);
if (topWeb.Webs.Count > 0)
{
foreach (SPWeb subWeb in topWeb.GetSubwebsForCurrentUser())
{
TreeNode childNode = new TreeNode(subWeb.Name);
childNode.NavigateUrl = subWeb.ServerRelativeUrl;
tn.ChildNodes.Add(childNode);
subWeb.Dispose();
}
}
topWeb.Dispose();
}
}
Tag: ForEach
ForEach-metod i List
En intressant variant av foreach är ForEach-metoden i List. Titta på det lilla exemplet:
private static void SavePlacesToDB(SQLiteConnection cnn,
List<dynamic> places)
{
places.ForEach(obj => SavePlaceToDB(obj, cnn));
}
```Här används även det nya objektet [dynamic](http://msdn.microsoft.com/en-us/library/dd264736.aspx) som har kommit i Visual Studio 2010, samt en [lambda expression (=>)](http://msdn.microsoft.com/en-us/library/bb397687.aspx).
Tag: Lambda
ForEach-metod i List
En intressant variant av foreach är ForEach-metoden i List. Titta på det lilla exemplet:
private static void SavePlacesToDB(SQLiteConnection cnn,
List<dynamic> places)
{
places.ForEach(obj => SavePlaceToDB(obj, cnn));
}
```Här används även det nya objektet [dynamic](http://msdn.microsoft.com/en-us/library/dd264736.aspx) som har kommit i Visual Studio 2010, samt en [lambda expression (=>)](http://msdn.microsoft.com/en-us/library/bb397687.aspx).
Tag: Market
Chuvash Keyboard for Android
Now there is a Chuvash keyboard for Android. The little program uses AnySoftKeyboard application, gives the ability to write in Cyrillic and Latin. All kinds of feedback are appreciated. Chuvash Keyboard for Android is open source like AnySoftKeyboard.
Bobusos. Rövarspråk translator
I have published my old app “Rövarspråksöversättare”, an assignment on the android course. Rövarspråket is the Swedish language game. Of course Bobusos (“bus” - en:prank in Rövarspråket) is open source and can be found on Github.
Publish upgrade on Market - checklist
Here comes my checklist about what has to be done in order to publish an upgrade on Market.
- get all code from github (git pull origin master)
- Test the application
- Change version number in AndroidManifest.xml
- Commit “version x.x.” and push
- (Change google map api key in res/layout/main.xml to the prod key)
- In Eclipse: Project → Clean
- Right-click on project → Android tools → Export signed… (~/Skrivbord/LUSites-unaligned.apk)
- Zipalign (e.g.: zipalign -v 4 LUSites-unaligned.apk LUSites-v0.2.7.apk)
- Publish upgrade on market
- Save the apk to the archive
Tag: Refactoring
Version 0.3.0: Move to SD card feature
In the version 0.3.0 issues #5 (refactoring of the main layout file) and #6 (move to sd-card) issues are solved.
Version 0.1.8: Cleaning code
Cleaned OverlayMediator. Moved strings to /res/values/strings.xml Solved the bug with disappearing OverlayItems. The actual reason was the caching of OverlayMediator object. The instance variable “activity” was the old one, and the getOverlays from the activity’s lusitesMap were old. So it couldn’t work. The solution is to force OverlayMediator to renew its instance variable LUSitesActivity activity each time the static method getInstance is called: public static OverlayMediator getInstance(Context context) { if (singleton == null) { singleton = new OverlayMediator(); } singleton.setActivity((LUSitesActivity) context); return singleton; }
I also have started to use selectors in order to change Markers automatically. This version is not published on Market, but committed on Github.
Version 0.1.7: Refactoring of OverlayMediator
OverlayController is actually more Mediator. It keeps track of current OverlayItem and triggers toggling of marker highlighting. In order to provide clear code the name has been changed to OverlayMediator. The singleton variable now is called singleton. And static method getOverlayController is now getInstance(). Commit details on Github: Version 0.1.7 + Added OverlayMediator
Tag: Sdcard
Version 0.3.0: Move to SD card feature
In the version 0.3.0 issues #5 (refactoring of the main layout file) and #6 (move to sd-card) issues are solved.
Tag: Versions
Version 0.3.0: Move to SD card feature
In the version 0.3.0 issues #5 (refactoring of the main layout file) and #6 (move to sd-card) issues are solved.
Version 0.2.9: Nations' news feed added
This version has a news feed from Studentlund, just a simple list for now. See the commit on Github.
Version 0.2.8: UI improvements
A new version is published. As one can see on the github, this version has some UI improvements: Changed library pins to green: in order not to be confusing with the highlighted pins (the red dotted ones), Updated the Swedish localization strings.
Version 0.2.7: Nations added. Ready for release
It is my pleasure to announce that a new version is ready for release. The biggest news are the nations which are now on the map. Other improvements are spelling error corrections. Great thanks to Kigsz. You can read about adding nations to the map on Lusites wiki.
Version 0.2.6: Settings improvement
Now a user can choose what to see on the map. Maybe only bike pumps or everything. To do that I created a new class ListPreferenceMultiSelect extends ListPreference which is more or less taken from DroidWeb tutorial. The source ListPreferenceMultiSelect.java was improved a little bit: The constructor checks if entries are not empty before creating indices. For the second a new method was added: prepareValueToStore, the opposite one of parseStoredValue. Here is my ListPreferenceMultiSelect.java and in the version 0.2.6. This version was published on the Market and committed to the repository.
Version 0.2.5: Added library markers
LUSites has now all markers, images to show places and images with dots to show a place you tap on or search. Github commit. This is even published to Market.
Version 0.2.4: Refactoring of Overlays
The content in the constructors of LUSiteOverlay subclasses is now moved to the superclass. The invokation of the abstract method initLUSites is working due to polymorphism. The details of the commit on Github.
Version 0.2.3: Updated highlighted marker for bike pumps
Red arrow isn’t so user-friendly. So the new highlighted marker for bike pumps is the bike pump marker with a red dot on it, like the auditoriums. The consistency is important. Committed on Github, but not Market.
Version 0.2.2: Added libraries
Libraries are now present on the LUSites map. The list of Lund University Libraries was taken from the official site. Committed on Github, but not published on Market. Here is the coordinates of the libraries, their addresses and the CSV-file which is located in /res/raw/libraries_utf8.csv in the LUSites project. Archaeological Library Visiting address: Sandgatan 1 Telephone: 046 2223187, HS: 24 (55.70594904569557, 13.19543570280075) Architecture and Design, Library Visiting address: Sölvegatan 39 Building: Kemicentrum, floor: 1 Telephone: 046 2227244, HS: 2 (55.71589492312098, 13.210244178771973) Art Academy Library, Malmö Visiting address: Föreningsgatan 42 Telephone: 040 325722, HS: 45 Asia Library Visiting address: Scheelevägen 15 B Telephone: 046 222 3043, HS: 61 (55.71405764996187, 13.214406967163086) Astronomy, Libr. Visiting address: Sölvegatan 27 Building: Astronomihuset, floor: 2 Telephone: 046 222 7304, HS: 25 (55.71171258368761, 13.204450607299805) Biology Library Visiting address: Sölvegatan 37 Building: Ekologihuset, floor: Bottenpl Telephone: 046 222 3812, HS: 50 (55.71420995359545, 13.20809125812957) Campus Helsingborg, Libr. Visiting address: Universitetsplatsen 2 Building: C, floor: 2 Telephone: 042 356580 Chemistry and Chemical Engineering, Libr. Visiting address: Sölvegatan 39 Telephone: 046 2228339, HS: 1 (55.71594327124769, 13.21033000946045) Civil Engineering Library Visiting address: John Ericssons Väg 1 Building: V-huset, floor: Entré Telephone: 046 2227937, HS: 3 (55.71258293399021, 13.211137354373932) Geolibrary Visiting address: Sölvegatan 12 Building: Geocentrum II Telephone: 046 222 39 60, HS: 16 (55.709346220780546, 13.201250731945038) History, Libr. Visiting address: Magle stora kyrkogata 12 A Telephone: 046 222 79 47, HS: 23 (55.702935467932335, 13.198925256729126) Languages and Literature, Libr. Visiting address: Helgonabacken 12 Telephone: 046 222 32 20, HS: 20 (55.70907723814732, 13.199536800384521) Law Library Visiting address: Lilla Gråbrödersgatan 4 Telephone: 046 2221007, HS: 56 (55.7052478126403, 13.19107174873352) Library of the E-huset, LTH Visiting address: Ole Römers Väg 3 Building: E-huset, floor: entré Telephone: 046 2220477, HS: 7 (55.71109607382483, 13.210394382476807) LTHs Studiecentrum Visiting address: John Ericssonsväg 4 Telephone: 046 2224825, HS: 8 (55.71152521407211, 13.209450244903564) Lund University Libraries, Head Office Visiting address: Tornavägen 9 A,B Building: Tegelstenen, floor: 1 och 3 Telephone: 046 222 00 00, HS: 51 (55.70848486536929, 13.208152055740356) Mathematics, Libr. Visiting address: Sölvegatan 18 Building: Matematikhuset, floor: 2 Telephone: 046 222 74 89, HS: 6 (55.71076968231173, 13.20681095123291) Medical Faculty Library at Vårdvetenskapens hus, Lund Visiting address: Baravägen 3 Building: Health Sciences Centre, floor: plan 2 Telephone: 046 222 18 00, HS: 65 (55.71724260473777, 13.193110227584839) Medical Library at UsiL, Lund Visiting address: Getingevägen 4 Building: Universitetssjukhuset, Centralblocket, floor: plan 1 Telephone: 046 222 18 55, HS: 32 (55.71244996505999, 13.196607828140259) Medical Library in CRC, Malmö Visiting address: Ingång 72 Univeristetssjukhuset MAS, UMAS Building: Clinical Research Centre, CRC, floor: entrevån Telephone: 040 39 15 00, HS: 33 Music Library, Malmö Visiting address: Ystadvägen 25 Telephone: 040 325446, HS: 42 Philosophy, Libr. Visiting address: Kungshuset Telephone: 046 2223675, HS: 30 (55.706012518756204, 13.19507360458374) Physics, Libr. Visiting address: Professorsgatan 1 Building: Fysicum Hus H, floor: Entré Telephone: 046 2227779, HS: 14 (55.71031031185903, 13.204643726348877) Political Science Library Visiting address: Paradisgatan 5 Building: Hus H; Eden, floor: 2 Telephone: 046 222 36 91, HS: 35 (55.70677418744201, 13.194794654846191) Raoul Wallenberg Institute Library Visiting address: Lilla Gråbrödersgatan 3 B Telephone: 046 2221215, 2221230, HS: 56 (55.705216075501774, 13.191157579421997) School of Economics and Management Library Visiting address: Tycho Brahes väg 1 Building: Holger Crafoords Ekonomicentrum 1, floor: 1 Telephone: 046 2229445, HS: 10 (55.709627290542365, 13.212937116622925) Social and behavioural Sciences, Libr. Visiting address: Allhelgona kyrkogata 14 Building: hus J Telephone: 046 2220990, HS: 31 (55.708493932367254, 13.194451332092285) The IIIEE Library Visiting address: Tegnérsplatsen 4 Telephone: 046 222 02 38, HS: 53 (55.704229188760834, 13.195728063583374) Theology and Religious studies, Libr. Visiting address: Allhelgona Kyrkogata 8 Telephone: 046 222 90 39, HS: 36 (55.70868433883831, 13.194515705108643) Theoretical Physics Library Visiting address: Sölvegatan 14A Building: Fysicum Hus K, floor: 200 Telephone: 046 2220432 / 2227779, HS: 14A (55.710902656961046, 13.203780055046082) University Library Visiting address: Helgonabacken 1 Telephone: 046 222 00 00, HS: 19 (55.709059104420014, 13.197294473648071) Wrangel, Libr. Visiting address: Biskopsgatan 5 Building: Wrangel, floor: 1 Telephone: 046 222 33 52, HS: 59 (55.706695603264485, 13.199906945228577) /res/raw/libraries_utf8.csv: 13.19543570280075,55.70594904569557,"Archaeological Library","Sandgatan 1, Telephone: 046 2223187" 13.210244178771973,55.71589492312098,"Architecture and Design, Library","Sölvegatan 39, Building: Kemicentrum, floor: 1" 13.214406967163086,55.71405764996187,"Asia Library","Scheelevägen 15 B, Telephone: 046 222 3043" 13.204450607299805,55.71171258368761,"Astronomy Library","Sölvegatan 27, Building: Astronomihuset, floor: 2, Telephone: 046 222 7304" 13.20809125812957,55.71420995359545,"Biology Library","Sölvegatan 37, Building: Ekologihuset, floor: Bottenpl, Telephone: 046 222 3812" 13.21033000946045,55.71594327124769,"Chemistry and Chemical Engineering Library","Sölvegatan 39, Telephone: 046 2228339" 13.211137354373932,55.71258293399021,"Civil Engineering Library","John Ericssons Väg 1, Building: V-huset, floor: Entré, Telephone: 046 2227937" 13.201250731945038,55.709346220780546,"Geolibrary","Sölvegatan 12, Building: Geocentrum II, Telephone: 046 222 39 60" 13.198925256729126,55.702935467932335,"History Library","Magle stora kyrkogata 12 A, Telephone: 046 222 79 47" 13.199536800384521,55.70907723814732,"Languages and Literature Library","Helgonabacken 12, Telephone: 046 222 32 20" 13.19107174873352,55.7052478126403,"Law Library","Lilla Gråbrödersgatan 4, Telephone: 046 2221007" 13.210394382476807,55.71109607382483,"Library of the E-huset, LTH","Ole Römers Väg 3, Building: E-huset, floor: entré, Telephone: 046 2220477" 13.209450244903564,55.71152521407211,"LTHs Studiecentrum","John Ericssonsväg 4, Telephone: 046 2224825" 13.208152055740356,55.70848486536929,"Lund University Libraries, Head Office","Tornavägen 9 A,B. Building: Tegelstenen, floor: 1 och 3. Telephone: 046 222 00 00" 13.20681095123291,55.71076968231173,"Mathematics Library","Sölvegatan 18. Building: Matematikhuset, floor: 2. Telephone: 046 222 74 89" 13.193110227584839,55.71724260473777,"Medical Faculty Library at Vårdvetenskapens hus","Baravägen 3. Building: Health Sciences Centre, floor: plan 2. Telephone: 046 222 18 00" 13.196607828140259,55.71244996505999,"Medical Library at UsiL","Getingevägen 4. Building: Universitetssjukhuset, Centralblocket, floor: plan 1. Telephone: 046 222 18 55" 13.19507360458374,55.706012518756204,"Philosophy Library","Kungshuset, Lundagård. Telephone: 046 2223675" 13.204643726348877,55.71031031185903,"Physics Library","Professorsgatan 1. Building: Fysicum Hus H, floor: Entré. Telephone: 046 2227779" 13.194794654846191,55.70677418744201,"Political Science Library","Paradisgatan 5. Building: Hus H; Eden, floor: 2. Telephone: 046 222 36 91" 13.191157579421997,55.705216075501774,"Raoul Wallenberg Institute Library","Lilla Gråbrödersgatan 3 B. Telephone: 046 2221215, 046 2221230" 13.212937116622925,55.709627290542365,"School of Economics and Management Library","Tycho Brahes väg 1. Building: Holger Crafoords Ekonomicentrum 1, floor: 1. Telephone: 046 2229445" 13.194451332092285,55.708493932367254,"Social and behavioural Sciences Library","Allhelgona kyrkogata 14. Building: hus J. Telephone: 046 2220990" 13.195728063583374,55.704229188760834,"The IIIEE Library","Tegnérsplatsen 4. Telephone: 046 222 02 38" 13.194515705108643,55.70868433883831,"Theology and Religious studies Library","Allhelgona Kyrkogata 8. Telephone: 046 222 90 39" 13.203780055046082,55.710902656961046,"Theoretical Physics Library","Sölvegatan 14A Building: Fysicum Hus K, floor: 200. Telephone: 046 2220432 / 2227779" 13.197294473648071,55.709059104420014,"University Library","Helgonabacken 1. Telephone: 046 222 00 00" 13.199906945228577,55.706695603264485,"Wrangel Library","Biskopsgatan 5. Building: Wrangel, floor: 1. Telephone: 046 222 33 52"
Version 0.2.1: Adjusted positions
Positions for Paln & Palnö at Palaestra and DC-Shö at IKDC have been adjusted. It is committed on Github, but not published on Market.
Version 0.2.0: Swedish localization
Well, it is time to localize. The first language has been added: Swedish, of course. To localize is pretty simple in Android. All you have to do is to create a new folder /res/values-xx
where xx is the language code. sv is Swedish. In this folder create an xml file called strings.xml and copy all the content from /res/values/strings.xml
. Replace all the strings from your default language into the language you want to localize to. There is a graphical wizzard in Eclipse+Android for creating the right folder: Right click on your project → Android tools → Create a new Resource file → Choose Language → Follow your intution.
Version 0.1.9: Stable version
This version works good. There are only bike pumps and auditoriums. But you see when you tap on them, or you can search. Published on Market and committed on Github.
Version 0.1.8: Cleaning code
Cleaned OverlayMediator. Moved strings to /res/values/strings.xml Solved the bug with disappearing OverlayItems. The actual reason was the caching of OverlayMediator object. The instance variable “activity” was the old one, and the getOverlays from the activity’s lusitesMap were old. So it couldn’t work. The solution is to force OverlayMediator to renew its instance variable LUSitesActivity activity each time the static method getInstance is called: public static OverlayMediator getInstance(Context context) { if (singleton == null) { singleton = new OverlayMediator(); } singleton.setActivity((LUSitesActivity) context); return singleton; }
I also have started to use selectors in order to change Markers automatically. This version is not published on Market, but committed on Github.
Version 0.1.7: Refactoring of OverlayMediator
OverlayController is actually more Mediator. It keeps track of current OverlayItem and triggers toggling of marker highlighting. In order to provide clear code the name has been changed to OverlayMediator. The singleton variable now is called singleton. And static method getOverlayController is now getInstance(). Commit details on Github: Version 0.1.7 + Added OverlayMediator
Version 0.1.6: Hide keyboard after search
This version improves User Interface. After search you probably don’t want to see the keyboard which takes half a display. So now it is hiding after search. To do this I used a code provided androidguys: InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); mgr.hideSoftInputFromWindow(findField.getWindowToken(), 0);
This version is not published at Market. Commit details on Github.
Version 0.1.5 Bug solved
Highlighted Marker doesn’t appear after restart « A Chuvash Guy @ Android - Jan 4, 2011
[…] bug is solved in the version 0.1.5 and released as update in the Android […]
Actually the bug was solved completely in version 0.1.8
Version 0.1.5 Bug solved
The bug where the highlighting of current item didn’t work is now solved. In this version the LUSiteOverlayItem has been implemented. toggleHighlight(), @override Drawable getMarker() have been added. This version is published to the Market.
Version 0.1.4: Refactoring
In this version the code has been refactored. The new subclass of OverlayItem was added: LUSiteOverlayItem. It has not been published to Android Market.
Tag: Utvecklingsmiljö
Förenkla skapandet av utvecklingsmiljön till SharePoint 2010
Jag är fortfarande i mitt sökande efter den perfekta (för mig) utvecklingsmiljön för SharePoint 2010. Fram tills nu har jag arbetat med en virtuell (VMware) maskin som kollegor till mig har konfigurerat. Men jag vill ha kunskapen att göra det själv. Än så länge har jag bara stött på procedurer som är relativt långdragna, fram tills idag. Se på videon på sidan jag länkat nedan. Jag ska testa det och sen förhoppningsvis komma med resultat här. Mitt mål är att lätt komma igång med en maskin som körs som VHD eller native dualboot. Men jag börjar med en virtuell VMware maskin. Ett dygn senare: Igår lät jag skriptet köra (utan config ändringar) och efter många timmar är allt installerat och klart. Dock trailversioner. Men gör man det en natt efter 2 veckor eller när trailen är slut, då kan man börja på en ny maskin igen. Jag gillar skarpt detta skript! Ännu bättre blir det nog när man konfigurerar det att fixa en VHD. Kommer mer om det när det är testat! Länksamling Film från Channel 9 Ladda ner Scriptet här Skriptskaparnas bloggar http://blogs.msdn.com/b/cjohnson/archive/2010/10/28/announcing-sharepoint-easy-setup-for-developers.aspx http://blogs.msdn.com/b/pstubbs/archive/2010/10/27/sharepoint-2010-easy-setup-script.aspx
Tag: VHD
Förenkla skapandet av utvecklingsmiljön till SharePoint 2010
Jag är fortfarande i mitt sökande efter den perfekta (för mig) utvecklingsmiljön för SharePoint 2010. Fram tills nu har jag arbetat med en virtuell (VMware) maskin som kollegor till mig har konfigurerat. Men jag vill ha kunskapen att göra det själv. Än så länge har jag bara stött på procedurer som är relativt långdragna, fram tills idag. Se på videon på sidan jag länkat nedan. Jag ska testa det och sen förhoppningsvis komma med resultat här. Mitt mål är att lätt komma igång med en maskin som körs som VHD eller native dualboot. Men jag börjar med en virtuell VMware maskin. Ett dygn senare: Igår lät jag skriptet köra (utan config ändringar) och efter många timmar är allt installerat och klart. Dock trailversioner. Men gör man det en natt efter 2 veckor eller när trailen är slut, då kan man börja på en ny maskin igen. Jag gillar skarpt detta skript! Ännu bättre blir det nog när man konfigurerar det att fixa en VHD. Kommer mer om det när det är testat! Länksamling Film från Channel 9 Ladda ner Scriptet här Skriptskaparnas bloggar http://blogs.msdn.com/b/cjohnson/archive/2010/10/28/announcing-sharepoint-easy-setup-for-developers.aspx http://blogs.msdn.com/b/pstubbs/archive/2010/10/27/sharepoint-2010-easy-setup-script.aspx
Omvandla en partition till VHD
Som nämnts tidigare så kan man omvandla en fysisk hårddiskpartition till VHD. Använd Disk2VHD. [caption id="" align=“aligncenter” width=“313” caption=“Taget från Disk2VHDs hemsida.”] “disk2vhd screenshot”[/caption] Problemet med detta är att det inte går att köra vhd:n. “Missing operating system” spottar VirtualPC ut. Medan den fysiska ikopplad, går det inte heller att mounta vhd:n. Även om man valt bara en partition så syns alla partitioner (som nu blir tomma). Partitionens alla filer är dock på plats och är åtkomliga. Orsaken är nog att jag har partitionerat hårddisken. Edit 2010-12-11: Det funkar att köra VHD:n i Virtual PC. Man måste dock inkludera partitionen som skapades automatiskt under Windows-Server-installationen som heter “System Reserved” (Jag installerade till allokerat ställe i hårddisken, så det skapades två partitioner av det). Denna “System Reserved”-partition har bland annat mappen “boot”, så den är viktig. Dock går det inte att köra. Även om det finns operativsystem där, så visas “Windows is loading files”. Sedan startas det om och om igen. Förmodar problemet är att det är annorlunda “hårdvara” då.
Konvertera vmdk till vhd
VMWare har massor med fördelar som jag inte går in på här. VMDK:s (VMWares hårddisk-filändelse) Windows Virtual PC:s motsvarighet heter VHD. VHD har en stor fördel att den är integrerad med Windows. Det går bland annat att mounta VHD-avbildning som en extra disk och se och kopiera filer. Det går att boota direkt till VHD. Det går att skapa varianter av VHD där bara ändringar sparas i nya och på det sättet sparas plats. För att konvertera från vmdk till vhd rekommenderas StarWind Free V2V Converter.
Installera Windows Server på fysisk hårddisk
Det bästa är att installera Windows Server och Sharepoint på en virtuell hårddisk. Följ denna instruktion och installera det. Men om man har en äldre dator (som är mitt fall) och ändå vill testa saker och kunna utveckla, så är det lönt att installera på en riktig hårddisk. Det bästa är att använda en SSD-hårddisk. Sedan är det möjligt att installera Windows Server på en VHD och boota från den (mer info kommer senare förhoppningsvis). Om man har installerat på en riktig hårddisk, kan man omvandla det till VHD med hjälp av till exempel Disk2VHD (mer info om det kommer senare förhoppningsvis). 1. Välj Svenska som locale. När installationen av Windows Swerver 2010 R2 är klar ombeds du att “Press CTRL + ALT + DELETE” för att logga in. 2. Tryck på “OK” för att byta lösenord för administratörskontot. Välj ett lösenord, bekräfta det och tryck på Enter (eller pilen till höger). Tryck på OK för att bekräfta att lösenordet är bytt. Du kommer nu in på skrivbordet. 3. Tryck på “Provide computer name and domain”. I system properties, fliken Computer Name, tryck på Change och ge din dator ett bättre namn exempelvis “SharePoint”. Tryck på OK och “Restart Later”. 4. Aktivera trådlöst: Tryck på “Add feature”. Bocka i Wireless. 5. Tryck på “Download and install updates” och i “Windows Update”, tryck på “Turn on automatic updates”. Tryck på “Install updates” när Windows har letat fram de du behöver. Starta om datorn. 6. Logga in igen som administratör och välj “Add features” under avdelning 3 i “Initial Configuration Tasks”. Kicka på “Desktop Experience” (som gör Windows Server mer användare vänligt) och “Add requered features”. Därefter Next och Install. Starta om datorn. I “Shutdown Event Tracker”, skriv vad som helst i “Comment” och tryck OK. 7. När du har loggat in igen så tryck Close för att avsluta konfigurationen av “Desktop Experience”. Du är nu klar med “Initial Configuration Tasks”. Syns den fortfarande kan du klicka i “Do not show this window at logon” och trycka close. Saknar du den kan du få tillbaka den genom att trycka på Start och skriva OOBE.EXE. 8. Du skall nu in i “Server Manager” som bör ha startat. Om inte, klicka på symbolen till höger om Start-knappen (dator med väska). Se till att “Server Manager” är markerad i vänster kolumn. För att slippa att IE blockerar alla webbplatser så klicka på “Configure IE ESC” under “Security Information”. Klicka Off för både administratörer och användare. 9. Om du vill slippa ge en kommentar varje gång du stänger av eller startar om den virtuella maskinen i “Spåra händelser i samband med avstängning” (“Shutdown Event Tracker”) kan du göra såhär: Tryck Start och skriv gpedit.msc och tryck Enter. Expandera Datorkonfiguration (“Computer Configuration”) och Administrativa mallar (“Administrative Templates”) och välj “System”. I höger kolumn, dubbelklicka på Visa spåraren av avstängningshändelser (“Display Shutdown Event Tracker”), klicka Inaktiverad (“Disabled”) och OK. 10. Konfigurationen av Windows Server är nu klar. Du bör stänga en restore point.’ Nu är Windows Server installerad. Fortsätt med: Konfigurera backup Installera Sharepoint Server …
Mounta VHD
Det kan vara ett helvete att köra en virtuell maskin på en slö dator. En lösning kan vara att boota direkt till VHD utan värdsystemet. Det enklaste sättet är att använda EasyBCD. Testa gärna med en färdig VHD. Edit 2010-12-10. EasyBCD funkar bara med Windows7-vhd för tillfället. Kolla mer om hur man får vhd att boota.
Tag: Bobusos
Bobusos. Rövarspråk translator
I have published my old app “Rövarspråksöversättare”, an assignment on the android course. Rövarspråket is the Swedish language game. Of course Bobusos (“bus” - en:prank in Rövarspråket) is open source and can be found on Github.
Tag: Translator
Bobusos. Rövarspråk translator
I have published my old app “Rövarspråksöversättare”, an assignment on the android course. Rövarspråket is the Swedish language game. Of course Bobusos (“bus” - en:prank in Rövarspråket) is open source and can be found on Github.
Tag: Ideas
Improvement ideas
Now, to organize it a little bit, all improvement ideas will be placed in project issues on the github and tagged as “improvement ideas”. It is much better to collaborate this way. You can track the status of a improvement idea, comment it. Every time it is changed, all the involved developers will be announced.
Tag: Improvement
Improvement ideas
Now, to organize it a little bit, all improvement ideas will be placed in project issues on the github and tagged as “improvement ideas”. It is much better to collaborate this way. You can track the status of a improvement idea, comment it. Every time it is changed, all the involved developers will be announced.
Version 0.2.8: UI improvements
A new version is published. As one can see on the github, this version has some UI improvements: Changed library pins to green: in order not to be confusing with the highlighted pins (the red dotted ones), Updated the Swedish localization strings.
Tag: Issues
Improvement ideas
Now, to organize it a little bit, all improvement ideas will be placed in project issues on the github and tagged as “improvement ideas”. It is much better to collaborate this way. You can track the status of a improvement idea, comment it. Every time it is changed, all the involved developers will be announced.
Tag: LUSites
Improvement ideas
Now, to organize it a little bit, all improvement ideas will be placed in project issues on the github and tagged as “improvement ideas”. It is much better to collaborate this way. You can track the status of a improvement idea, comment it. Every time it is changed, all the involved developers will be announced.
Version 0.2.7: Nations added. Ready for release
It is my pleasure to announce that a new version is ready for release. The biggest news are the nations which are now on the map. Other improvements are spelling error corrections. Great thanks to Kigsz. You can read about adding nations to the map on Lusites wiki.
Set up the Lusites development environment
There is a very good wiki page which describes how to set up the environment. If you think something is missing there, just leave a comment here. Much of that was inspired by a useful tutorial from doityourselfandroid.com
Lusites wiki created
Now there is a wiki on github for LUSites to be able to collaborate.
Coming events from student nations wanted
I got a comment on android market: by Johan (November 7, 2010) Skulle vara bra om man såg vad som hände på de olika nationerna, likt lth-appen till iphone. Would be great to do it. I am saving it as a wish
LUSites now available for lower API levels
If your smartphone runs Android 2.1 or lower, now you can find LUSites on Market, too. When I created LUSites I developed for Froyo (Android 2.2). But LUSites does nothing that hasn’t existed in previous Android releases (API levels). So I set API level 3 as minimal SDK version. I hope it works on your android phones. If not, please leave a comment here.
LUSites goes Open
Lund University Sites is from now open source. Everybody is welcome to download, use it and contribute. Please, check out the LUSites open repository at github.
Tag: Checklist
Publish upgrade on Market - checklist
Here comes my checklist about what has to be done in order to publish an upgrade on Market.
- get all code from github (git pull origin master)
- Test the application
- Change version number in AndroidManifest.xml
- Commit “version x.x.” and push
- (Change google map api key in res/layout/main.xml to the prod key)
- In Eclipse: Project → Clean
- Right-click on project → Android tools → Export signed… (~/Skrivbord/LUSites-unaligned.apk)
- Zipalign (e.g.: zipalign -v 4 LUSites-unaligned.apk LUSites-v0.2.7.apk)
- Publish upgrade on market
- Save the apk to the archive
Tag: Nations
Version 0.2.7: Nations added. Ready for release
It is my pleasure to announce that a new version is ready for release. The biggest news are the nations which are now on the map. Other improvements are spelling error corrections. Great thanks to Kigsz. You can read about adding nations to the map on Lusites wiki.
Tag: Overlay
Version 0.2.7: Nations added. Ready for release
It is my pleasure to announce that a new version is ready for release. The biggest news are the nations which are now on the map. Other improvements are spelling error corrections. Great thanks to Kigsz. You can read about adding nations to the map on Lusites wiki.
Tag: Spelling
Version 0.2.7: Nations added. Ready for release
It is my pleasure to announce that a new version is ready for release. The biggest news are the nations which are now on the map. Other improvements are spelling error corrections. Great thanks to Kigsz. You can read about adding nations to the map on Lusites wiki.
Tag: Setup
Set up the Lusites development environment
There is a very good wiki page which describes how to set up the environment. If you think something is missing there, just leave a comment here. Much of that was inspired by a useful tutorial from doityourselfandroid.com
Tag: Egit
Update from git
So if you have an existing copy of the project, just type: git pull origin master
Or in Egit in Eclipse, right-click on repo and run “Fetch from upstream”.
Tag: Update
Update from git
So if you have an existing copy of the project, just type: git pull origin master
Or in Egit in Eclipse, right-click on repo and run “Fetch from upstream”.
Tag: Collaboration
Lusites wiki created
Now there is a wiki on github for LUSites to be able to collaborate.
Tag: Meta
Ny skribent
Jag är mycket glad att det finns en ny skribent på den här bloggen: timswe. Det här är en kille som har mycket att berätta om Sharepoint och om andra tekniker.
Tag: Textredigerare
Programmers notepad
De flesta känner nog till Notepad++. Det finns en annan väldigt duktig textredigerare: Programmers notepad. Den är väldigt bra. code highlighting, filnavigering direkt i programmet mm. Testa gärna.
Tag: Ebook
Powershell med tysk precision
Master Powershell ebookDe som har missat Powershell, läser nog andra sorts bloggar än denna. Så rak på sak: det finns en lovande ebook om Powershell, skriven av Tobias Weltner. Ska absolut läsa den. Ni som har läst, vad tycker ni om den? Master-PowerShell | With Dr. Tobias Weltner i html
Tag: Radgrid
Få alla items i Telerik Radgrid
Jag har haft följande problem: I Telerik Radgrid var Paging aktiverat. I varje Page visades 15 items, alltså när jag försökte hämta Items, så fick jag bara 15. Jag ville dock ta ut alla för att kunna skicka värden till en annan funktion på hemsidan (ModalDialog - om det i ett annat inlägg). Efter mycket googlande har jag hittat en lösning:
grid.MasterTableView.AllowPaging = false;
grid.MasterTableView.Rebind();
```Observera att man det måste vara grid.MasterTableView... Förresten, du behöver inte ändra det tillbaka (AllowPaging = true och Rebind). Det kommer inte påverka själva griden. Lite konstigt, men det funkar. Här är ett litet exempel. Detta är en Property som hämtar alla items i grid:
private List ItemIds { get { List list = new List(); grid.MasterTableView.AllowPaging = false; grid.MasterTableView.Rebind(); foreach (GridDataItem item in grid.MasterTableView.Items) { string id = item[“Id”].Text.Trim(); int itemtId = Convert.ToInt32(id); list.Add(itemId); } return list; } }
Tag: Telerik
Få alla items i Telerik Radgrid
Jag har haft följande problem: I Telerik Radgrid var Paging aktiverat. I varje Page visades 15 items, alltså när jag försökte hämta Items, så fick jag bara 15. Jag ville dock ta ut alla för att kunna skicka värden till en annan funktion på hemsidan (ModalDialog - om det i ett annat inlägg). Efter mycket googlande har jag hittat en lösning:
grid.MasterTableView.AllowPaging = false;
grid.MasterTableView.Rebind();
```Observera att man det måste vara grid.MasterTableView... Förresten, du behöver inte ändra det tillbaka (AllowPaging = true och Rebind). Det kommer inte påverka själva griden. Lite konstigt, men det funkar. Här är ett litet exempel. Detta är en Property som hämtar alla items i grid:
private List ItemIds { get { List list = new List(); grid.MasterTableView.AllowPaging = false; grid.MasterTableView.Rebind(); foreach (GridDataItem item in grid.MasterTableView.Items) { string id = item[“Id”].Text.Trim(); int itemtId = Convert.ToInt32(id); list.Add(itemId); } return list; } }
Tag: Jsfiddle
Tag: Shortcut
Ctrl-Shift-J is the shit
devtools i google chrome underlättar så enormt. Lägg Ctrl-Shift-J på minnet. För då kommer du direkt till konsolen i devtools och kan testa.
Om man till exempel bara vill omdefiniera en funktion så kan man göra det direkt i webbläsarens addressruta: Inled det med javascript:function till exempel: javascript:function shout_out(greeting) {alert(greeting);};
Tag: Polymorfi
Polymorfi och javascript
En skräckscenario: du använder två javascript-bibliotek. Men de har var sin funktion som har samma namn. Det spelar även ingen roll om antalet inparametrar är olika. Så det blir samma sak som myfunc(param1, param2) och myfunc(param1). Grejen är att funktionen som laddas sist är den som kommer köras. Katastrof! Men det finns lösningar. Börja läsa här om hur man kan simulera polymorfi i javascript på about.com. Säg vi har en funktion som heter MoveToDate(strdate, ctxid) den ingår i init.debug.js (som används av Sharepoint kalenderwebpart). Sedan har vi något annat javascript-bibliotek som också har MoveToDate(param). Låt oss göra det polymorfiskt. Här är koden:
Tag: Migreging
migrera svn till git
Ja, hur gör man om man vill migrera till git? Låt oss säga, man vill använda github. Jag ska berätta hur man kan göra det. Jag gör det i Linux, förmodar samma gäller Mac. Det finns en bra manual om hur man migrerar svn till git. Vi ska gå igenom steg för steg. Skapa en fil som heter users.txt på ditt Skrivbord:
jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>
VisualSVN Server = server <server@server.com>
Det sista är nödvändigt. Eftersom om du har skapat en repository från VisualSVN, kommer det krävas en användarmappning för det med. Installera git-svn:
Tag: Svn
migrera svn till git
Ja, hur gör man om man vill migrera till git? Låt oss säga, man vill använda github. Jag ska berätta hur man kan göra det. Jag gör det i Linux, förmodar samma gäller Mac. Det finns en bra manual om hur man migrerar svn till git. Vi ska gå igenom steg för steg. Skapa en fil som heter users.txt på ditt Skrivbord:
jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>
VisualSVN Server = server <server@server.com>
Det sista är nödvändigt. Eftersom om du har skapat en repository från VisualSVN, kommer det krävas en användarmappning för det med. Installera git-svn:
Tag: Versionshantering
migrera svn till git
Ja, hur gör man om man vill migrera till git? Låt oss säga, man vill använda github. Jag ska berätta hur man kan göra det. Jag gör det i Linux, förmodar samma gäller Mac. Det finns en bra manual om hur man migrerar svn till git. Vi ska gå igenom steg för steg. Skapa en fil som heter users.txt på ditt Skrivbord:
jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>
VisualSVN Server = server <server@server.com>
Det sista är nödvändigt. Eftersom om du har skapat en repository från VisualSVN, kommer det krävas en användarmappning för det med. Installera git-svn:
Installera Subversion på klienten
För att komma igång med versionhanteringen när man utvecklar i Visual Studio, måste man installera tortoisesvn, sedan AnkhSVN. TortoiseSVN är själva klienten, medan VisualSVN är ett tillägg för Visual Studio. Gå in på C:\ i Windows. Högerklicka och välj SVN Checkout. Sedan ange din svn-server och mappen där du vill ha en working copy: [caption id=“attachment_97” align=“aligncenter” width=“300” caption=“subversion uppgifter”][/caption] Logga in [caption id=“attachment_99” align=“aligncenter” width=“300” caption=“subversion login”][/caption] AnkhSVN måhända inte syns direkt i Visual Studio. Bara öppna View > Other Windows > Pending Changes. Om man inte ser ändringar, gå in på File - Open from SVN - och tryck på Cancel. Nu måste allting fungera.
Subversion mappstruktur
Subversion verkar väldigt smidigt och användbart när man jobbar flera stycken med samma projekt. Är det ett litet program hjälper Dropbox tillräckligt. Vill man ha kolla på alla ändringar och ha möjlighet att backa till äldre versioner är Subversion det bästa alternativet. Det kan underlätta mycket om man har en riktig mappstruktur ifrån början:
main
trunk
branches
tags
trunk används för löpande utveckling. Vill man testa saker eller lösa några buggar, används branches. tags används för att spika fast olika versioner.
Tag: Klient
Ändra utseendet på sidan direkt i webbläsaren
I förra inlägget har jag berättat om devtools i Google Chrome. Ett ytterligare tips för att hålla på med klient-delen är att använda Optimizely.com. Det är väldigt smidigt. Gå in på optimizely.com och skriv in adressen till din sharepoint-applikation. Eller se denna video. [youtube http://www.youtube.com/watch?v=0S0IrbwpfzE&rel=0&hl=en_US&feature=player_embedded&version=3]
Tag: Webb
Ändra utseendet på sidan direkt i webbläsaren
I förra inlägget har jag berättat om devtools i Google Chrome. Ett ytterligare tips för att hålla på med klient-delen är att använda Optimizely.com. Det är väldigt smidigt. Gå in på optimizely.com och skriv in adressen till din sharepoint-applikation. Eller se denna video. [youtube http://www.youtube.com/watch?v=0S0IrbwpfzE&rel=0&hl=en_US&feature=player_embedded&version=3]
Tag: SP.UI
Använd inbyggd ModalDialog
Vill du visa någon formulär, eller längre information kan du använda en snygg (snygg och snygg?) ruta som är default i Sharepoint. Den är i alla fall användbar. Här är ett litet enkelt exempel, för att illustrera:
var options = {
url: "http://sverigesradio.se",
width: 800,
height: 600,
allowMaximize: false
};
SP.UI.ModalDialog.showModalDialog(options);
Det finns även möjlighet att ha OK-knappen, alltså som alert i javascript. Kolla den här länken.
Tag: Wordpress
Formatera export xml av wordpress
Ville spara min blogg som en dagbok för utskrift. Exporterade hela bloggen som xml. Inga problem. Sedan var det dock nästan omöjligt att enkelt skriva in det i Word / OpenOffice. Jag har skrivit en liten css-fil som formaterar det lite så att man kan skriva ut. Lägg till:
<?xml-stylesheet type = "text/css" href="wordpress.css"?>
direkt efter:
<?xml version="1.0" encoding="UTF-8" ?>
Lägg filen “wordpress.com” i samma mapp. Här är wordpress.css
channel title {
font-size:3em;
}
channel description {
color:green;
margin-bottom:1em;
}
item title {
font-size:2em;
font-family:Arial;
margin-top:1em;
}
creator {
color:green;
}
creator:before {
content:"Skrivet av: ";
color:black;
font-style:italic;
font-size:0.8em;
}
post\_date:before {
content:"Datum: ";
}
comment {
margin-left:3em;
}
comment\_author:before {
content:"Kommentar av: ";
font-style:italic;
color:black;
}
comment\_author {
color:green;
}
comment\_date:before {
content:"(";
}
comment\_date:after {
content:"):";
}
/\* Ska inte visas\*/
link, channel language, pubDate,
guid, author, base\_site\_url,
base\_blog\_url, wxr\_version, generator,
post\_id, is\_sticky, post\_type, post\_name,
status, comment\_status, menu\_order,
post\_parent, ping\_status, post\_date\_gmt,
category, postmeta,
comment\_id, comment\_author\_email,
comment\_author\_IP, comment\_date\_gmt,
comment\_approved, comment\_type,
comment\_user\_id, comment\_parent {
display:none;
}
/\* block style \*/
title, description, post\_date, comment {
display:block;
}
Tag: Gadget
Skapa en egen gadget i Google för att lägga till i Sharepoint
Ibland vill man visa saker som kommer utifrån din sharepoint-installation. Du vill kanske sortera det, ändra det. Man får jättegärna använda javascript. Använd gärna GGE (Google Gadget Editor)
Tag: Bridged
Browsa från din host
Visst är det skönt att slippa gå in på sidan på Internet Explorer på den virtuella maskinen. Kolla upp ip-adressen på den virtuella maskinen och på din riktiga maskinen: Start -> Skriv cmd -> ipconfig Hitta adresser som har samma tre tal i början, typ 192.168.10.1 och 192.168.10.147 Om den virtuella har 192.168.10.147, ändra hosts filen så att namnet på din sharepoint-applikation pekar på den adressen. Hosts låter sig inte uppdateras med ett vanligt konto. Öppna cmd som Administrator (högerklicka på cmd i startmenyn och “kör som Administrator”). Navigera till
Tag: Hosts
Browsa från din host
Visst är det skönt att slippa gå in på sidan på Internet Explorer på den virtuella maskinen. Kolla upp ip-adressen på den virtuella maskinen och på din riktiga maskinen: Start -> Skriv cmd -> ipconfig Hitta adresser som har samma tre tal i början, typ 192.168.10.1 och 192.168.10.147 Om den virtuella har 192.168.10.147, ändra hosts filen så att namnet på din sharepoint-applikation pekar på den adressen. Hosts låter sig inte uppdateras med ett vanligt konto. Öppna cmd som Administrator (högerklicka på cmd i startmenyn och “kör som Administrator”). Navigera till
local dns
Hur gör man om man vill ha två olika internet-adresser för olika inloggningar. Om man har DNS inställt rätt - inga problem. Men hur gör man för att testa det på sin lokala maskin. Man kan ändra dns-information på sin maskin. För detta ska filen [hosts](http://en.wikipedia.org/wiki/Hosts_%28file% 29#Content_and_location) uppdateras. I Windows tryck på Start och i sökrutan skriv:
%SystemRoot%\\system32\\drivers\\etc\\hosts
Den här filen är raka motsvarigheten till /etc/hosts i Linux. I filen som öppnas lägg till följande rader som sist:
Tag: NAT
Browsa från din host
Visst är det skönt att slippa gå in på sidan på Internet Explorer på den virtuella maskinen. Kolla upp ip-adressen på den virtuella maskinen och på din riktiga maskinen: Start -> Skriv cmd -> ipconfig Hitta adresser som har samma tre tal i början, typ 192.168.10.1 och 192.168.10.147 Om den virtuella har 192.168.10.147, ändra hosts filen så att namnet på din sharepoint-applikation pekar på den adressen. Hosts låter sig inte uppdateras med ett vanligt konto. Öppna cmd som Administrator (högerklicka på cmd i startmenyn och “kör som Administrator”). Navigera till
Tag: VMWare
Browsa från din host
Visst är det skönt att slippa gå in på sidan på Internet Explorer på den virtuella maskinen. Kolla upp ip-adressen på den virtuella maskinen och på din riktiga maskinen: Start -> Skriv cmd -> ipconfig Hitta adresser som har samma tre tal i början, typ 192.168.10.1 och 192.168.10.147 Om den virtuella har 192.168.10.147, ändra hosts filen så att namnet på din sharepoint-applikation pekar på den adressen. Hosts låter sig inte uppdateras med ett vanligt konto. Öppna cmd som Administrator (högerklicka på cmd i startmenyn och “kör som Administrator”). Navigera till
Tag: DroidWeb
Version 0.2.6: Settings improvement
Now a user can choose what to see on the map. Maybe only bike pumps or everything. To do that I created a new class ListPreferenceMultiSelect extends ListPreference which is more or less taken from DroidWeb tutorial. The source ListPreferenceMultiSelect.java was improved a little bit: The constructor checks if entries are not empty before creating indices. For the second a new method was added: prepareValueToStore, the opposite one of parseStoredValue. Here is my ListPreferenceMultiSelect.java and in the version 0.2.6. This version was published on the Market and committed to the repository.
Tag: ListPreference
Version 0.2.6: Settings improvement
Now a user can choose what to see on the map. Maybe only bike pumps or everything. To do that I created a new class ListPreferenceMultiSelect extends ListPreference which is more or less taken from DroidWeb tutorial. The source ListPreferenceMultiSelect.java was improved a little bit: The constructor checks if entries are not empty before creating indices. For the second a new method was added: prepareValueToStore, the opposite one of parseStoredValue. Here is my ListPreferenceMultiSelect.java and in the version 0.2.6. This version was published on the Market and committed to the repository.
Tag: Multichoice
Version 0.2.6: Settings improvement
Now a user can choose what to see on the map. Maybe only bike pumps or everything. To do that I created a new class ListPreferenceMultiSelect extends ListPreference which is more or less taken from DroidWeb tutorial. The source ListPreferenceMultiSelect.java was improved a little bit: The constructor checks if entries are not empty before creating indices. For the second a new method was added: prepareValueToStore, the opposite one of parseStoredValue. Here is my ListPreferenceMultiSelect.java and in the version 0.2.6. This version was published on the Market and committed to the repository.
Tag: Marker
Version 0.2.5: Added library markers
LUSites has now all markers, images to show places and images with dots to show a place you tap on or search. Github commit. This is even published to Market.
Version 0.2.3: Updated highlighted marker for bike pumps
Red arrow isn’t so user-friendly. So the new highlighted marker for bike pumps is the bike pump marker with a red dot on it, like the auditoriums. The consistency is important. Committed on Github, but not Market.
Tag: Polymorphism
Version 0.2.4: Refactoring of Overlays
The content in the constructors of LUSiteOverlay subclasses is now moved to the superclass. The invokation of the abstract method initLUSites is working due to polymorphism. The details of the commit on Github.
Tag: Bike Pumps
Version 0.2.3: Updated highlighted marker for bike pumps
Red arrow isn’t so user-friendly. So the new highlighted marker for bike pumps is the bike pump marker with a red dot on it, like the auditoriums. The consistency is important. Committed on Github, but not Market.
Tag: Consistency
Version 0.2.3: Updated highlighted marker for bike pumps
Red arrow isn’t so user-friendly. So the new highlighted marker for bike pumps is the bike pump marker with a red dot on it, like the auditoriums. The consistency is important. Committed on Github, but not Market.
Tag: Singleton
Version 0.1.8: Cleaning code
Cleaned OverlayMediator. Moved strings to /res/values/strings.xml Solved the bug with disappearing OverlayItems. The actual reason was the caching of OverlayMediator object. The instance variable “activity” was the old one, and the getOverlays from the activity’s lusitesMap were old. So it couldn’t work. The solution is to force OverlayMediator to renew its instance variable LUSitesActivity activity each time the static method getInstance is called: public static OverlayMediator getInstance(Context context) { if (singleton == null) { singleton = new OverlayMediator(); } singleton.setActivity((LUSitesActivity) context); return singleton; }
I also have started to use selectors in order to change Markers automatically. This version is not published on Market, but committed on Github.
Tag: Bugs
Highlighted Marker doesn't appear after restart
For some reason when you restarted the LUSites, the red arrow didn’t appear as it should be. The bug is solved in the version 0.1.5 and released as update in the Android Market. The technical explanation: Before the marker was sent to the LUSiteOverlay as parameter. Now all the markers are controlled by the LUSiteOverlayItem which is a subclass. The LUSiteOverlayItem has defaultMarker and highlightedMarker as instance variables and toggles them. This was inspired by commonsguy’s sample roject NooYawk.
Tag: Solved Bugs
Highlighted Marker doesn't appear after restart
For some reason when you restarted the LUSites, the red arrow didn’t appear as it should be. The bug is solved in the version 0.1.5 and released as update in the Android Market. The technical explanation: Before the marker was sent to the LUSiteOverlay as parameter. Now all the markers are controlled by the LUSiteOverlayItem which is a subclass. The LUSiteOverlayItem has defaultMarker and highlightedMarker as instance variables and toggles them. This was inspired by commonsguy’s sample roject NooYawk.
Tag: Wishes
Coming events from student nations wanted
I got a comment on android market: by Johan (November 7, 2010) Skulle vara bra om man såg vad som hände på de olika nationerna, likt lth-appen till iphone. Would be great to do it. I am saving it as a wish
Tag: Subversion
Återgå till en tidigare version i SVN
Tänk om du vill återgå till en tidigare version. Vill strunta i de sista ändringarna, eller lägga dem på is så länge. Att uppdatera till en tidigare version hjälper inte så mycket eftersom det kommer inte gå att commita vidare ändringar. För att det ska funka måste man reverta till en specifik version, commita direkt, göra ändringar och commita igen. Högercklicka på filen i Visual Studio -> Subversion -> Show history -> Högerklicka på en revision som du vill återskapa -> Revert to this revision. Commita sedan direkt Nu kan du göra ändringar och commita dem också.
Merge en fil i taget
Om man vill testa någonting, så är det bra att isolera det till en branch. En branch kan inte skapas för en fil. Det måste vara en mapp. Hitta den minimala mappen, så att man inte branchar hela projektet. Högerklicka -> Subversion -> Branch. Sedan måste man byta till sin branch. Högerklicka på samma mapp -> Subversion -> Switch. Välj din mapp i branches. Det gör ingenting om mappen inte heter samma. Nu har du hela solution och alla dina projekt, medan någon del inte är från trunken utan är en branch, fritt fram att testa. När du är klar med improviserandet, tycker att det funkar, det går att deploya. Då kan man merga med trunken. Det går att mergea en fil i taget, om man vill på säkra sidan. För att göra det så måste man göra switch tillbaka till master, alltså Högerklicka på mappen -> Subversion -> Switch. Välj den riktiga mappen i trunken. Efter det så högerklicka på din fil -> Subversion -> Merge. Välj filen från din branch och följ wizzarden. Allt detta kan göras direkt ifrån Visual Studio. När du är färdig med din branch så kan man radera det.
Installera Subversion på klienten
För att komma igång med versionhanteringen när man utvecklar i Visual Studio, måste man installera tortoisesvn, sedan AnkhSVN. TortoiseSVN är själva klienten, medan VisualSVN är ett tillägg för Visual Studio. Gå in på C:\ i Windows. Högerklicka och välj SVN Checkout. Sedan ange din svn-server och mappen där du vill ha en working copy: [caption id=“attachment_97” align=“aligncenter” width=“300” caption=“subversion uppgifter”][/caption] Logga in [caption id=“attachment_99” align=“aligncenter” width=“300” caption=“subversion login”][/caption] AnkhSVN måhända inte syns direkt i Visual Studio. Bara öppna View > Other Windows > Pending Changes. Om man inte ser ändringar, gå in på File - Open from SVN - och tryck på Cancel. Nu måste allting fungera.
Subversion mappstruktur
Subversion verkar väldigt smidigt och användbart när man jobbar flera stycken med samma projekt. Är det ett litet program hjälper Dropbox tillräckligt. Vill man ha kolla på alla ändringar och ha möjlighet att backa till äldre versioner är Subversion det bästa alternativet. Det kan underlätta mycket om man har en riktig mappstruktur ifrån början:
main
trunk
branches
tags
trunk används för löpande utveckling. Vill man testa saker eller lösa några buggar, används branches. tags används för att spika fast olika versioner.
Tag: API Level
LUSites now available for lower API levels
If your smartphone runs Android 2.1 or lower, now you can find LUSites on Market, too. When I created LUSites I developed for Froyo (Android 2.2). But LUSites does nothing that hasn’t existed in previous Android releases (API levels). So I set API level 3 as minimal SDK version. I hope it works on your android phones. If not, please leave a comment here.
Tag: Open Source
LUSites goes Open
Lund University Sites is from now open source. Everybody is welcome to download, use it and contribute. Please, check out the LUSites open repository at github.
Tag: Restore
Återskapa koppling till login i DB efter restore
Om du har kört restore på en databas, så kan det hända att det inte går att ändra rättigheter, och den login du använt inte kan se databasen. SQL Server spottar ut felmeddelandet med kod 15023:
The database is not accessible. (Object Explorer)
Om det är WebService som i sin tur anropar databasen, kan det komma ett sådant felmeddelande:
The underlying provider failed on Open.
Lösningen är att uppdatera kopplingen. Hämtat från denna blog.
Tag: Backup
Windows Server Backup
Följ denna instruktion för att köra backup. Lägg till Feature: Windows Server Backup. När det är installerat expandera Storage under Server Manager. Klicka på Backup Once till höger. Välj helst Full Server (då sparas hela hårddisken). Destinationshårddisken ska vara formaterad som NTFS.
Restore
Har inte provat köra restore än. Så fort jag kört det kommer jag rapportera om det.
Tag: Disk2vhd
Omvandla en partition till VHD
Som nämnts tidigare så kan man omvandla en fysisk hårddiskpartition till VHD. Använd Disk2VHD. [caption id="" align=“aligncenter” width=“313” caption=“Taget från Disk2VHDs hemsida.”] “disk2vhd screenshot”[/caption] Problemet med detta är att det inte går att köra vhd:n. “Missing operating system” spottar VirtualPC ut. Medan den fysiska ikopplad, går det inte heller att mounta vhd:n. Även om man valt bara en partition så syns alla partitioner (som nu blir tomma). Partitionens alla filer är dock på plats och är åtkomliga. Orsaken är nog att jag har partitionerat hårddisken. Edit 2010-12-11: Det funkar att köra VHD:n i Virtual PC. Man måste dock inkludera partitionen som skapades automatiskt under Windows-Server-installationen som heter “System Reserved” (Jag installerade till allokerat ställe i hårddisken, så det skapades två partitioner av det). Denna “System Reserved”-partition har bland annat mappen “boot”, så den är viktig. Dock går det inte att köra. Även om det finns operativsystem där, så visas “Windows is loading files”. Sedan startas det om och om igen. Förmodar problemet är att det är annorlunda “hårdvara” då.
Tag: Partitionering
Omvandla en partition till VHD
Som nämnts tidigare så kan man omvandla en fysisk hårddiskpartition till VHD. Använd Disk2VHD. [caption id="" align=“aligncenter” width=“313” caption=“Taget från Disk2VHDs hemsida.”] “disk2vhd screenshot”[/caption] Problemet med detta är att det inte går att köra vhd:n. “Missing operating system” spottar VirtualPC ut. Medan den fysiska ikopplad, går det inte heller att mounta vhd:n. Även om man valt bara en partition så syns alla partitioner (som nu blir tomma). Partitionens alla filer är dock på plats och är åtkomliga. Orsaken är nog att jag har partitionerat hårddisken. Edit 2010-12-11: Det funkar att köra VHD:n i Virtual PC. Man måste dock inkludera partitionen som skapades automatiskt under Windows-Server-installationen som heter “System Reserved” (Jag installerade till allokerat ställe i hårddisken, så det skapades två partitioner av det). Denna “System Reserved”-partition har bland annat mappen “boot”, så den är viktig. Dock går det inte att köra. Även om det finns operativsystem där, så visas “Windows is loading files”. Sedan startas det om och om igen. Förmodar problemet är att det är annorlunda “hårdvara” då.
Partitionera hårddisk
Det bästa och det snabbaste sättet jag kommit fram till är att använda Ubuntu LiveCD och dess inbyggda GParted. Hög nivå av affordance. Det behövs egentligen inte några förklaringar.
Tag: Vmdk
Konvertera vmdk till vhd
VMWare har massor med fördelar som jag inte går in på här. VMDK:s (VMWares hårddisk-filändelse) Windows Virtual PC:s motsvarighet heter VHD. VHD har en stor fördel att den är integrerad med Windows. Det går bland annat att mounta VHD-avbildning som en extra disk och se och kopiera filer. Det går att boota direkt till VHD. Det går att skapa varianter av VHD där bara ändringar sparas i nya och på det sättet sparas plats. För att konvertera från vmdk till vhd rekommenderas StarWind Free V2V Converter.
Tag: Easy BCD
Mounta VHD
Det kan vara ett helvete att köra en virtuell maskin på en slö dator. En lösning kan vara att boota direkt till VHD utan värdsystemet. Det enklaste sättet är att använda EasyBCD. Testa gärna med en färdig VHD. Edit 2010-12-10. EasyBCD funkar bara med Windows7-vhd för tillfället. Kolla mer om hur man får vhd att boota.
Tag: WPF
Binda Data till ListView i WPF
Det är väldigt smidigt att koppla datakälla till en ListView i WPF. Man skriver kod i XAML. Och i koden bakom anger man: myListView.ItemsSource = myList;
Tag: By Reference
out ref
Om en metod har en inparameter med out framför sig. så innebär det att man skickar en referens till ett objekt. Alltså om det är out string param, så kommer det inte funka att skicka “någonting” direkt. Utan man måste instansiera först. string hej = “någonting”; CallTheMethod(ref hej); http://msdn.microsoft.com/en-us/library/t3c3bfhx(VS.80).aspx
Tag: Shorthand
kort variant av if-else
Inget speciellt egentligen med detta men vill skriva upp det här för att jag brukar glömma det. Det är samma syntax som i många andra språk:
bool value = "dit" == "dat" ? true : false;
Motsvarar:
bool value;
if ("dit" == "dat")
{
value = true;
}
else
{
value = false;
}
Tag: Properties
Ändra properties i efterhand
Ibland ändras vissa variabler. Man vill så klart inte kompilera varje gång man ändrar ApplicationName eller connectionString. I mitt förra inlägg har jag visat hur man använder app.config, hur man lägger till ett värde och hur man hämtar det i programmet. Nu vill jag visa hur man ändrar det efter kompileringen. I mappen var projektet finns gå in på bin -> Debug. Där finns både .exe-filen och en fil som heter samma som .exe-filen fast har en filändelse .config. Om man bara kör .exe-filen eller om man inte har .config-filen så finns properties ändå, såklart. Fast då är de “inkompilerade”. Finns config-filen så är det bara att öppna i Notepad och ändra värden till de aktuella.
app.config
app.config kan användas till mycket. Här är ett litet exempel hur man använder den. Så kan app.config se ut:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ApplicationName" value="SharePoint - 80" />
</appSettings>
</configuration>
```Sedan i programmet måste vi importera:
using System.Configuration
appName = ConfigurationSettings .AppSettings[“ApplicationName”] .ToString();
## Comments from Wordpress.com
####
[Ändra properties i efterhand « Sharepoint. Huvudvärk och smärtstillande.](http://sharepointheadache.wordpress.com/2010/10/31/andra-properties-i-efterhand/ "") - <time datetime="2010-10-31 23:12:43">Oct 0, 2010</time>
\[...\] Man vill så klart inte kompilera varje gång man ändrar ApplicationName eller connectionString. I mitt förra inlägg har jag visat hur man använder app.config, hur man lägger till ett värde och hur man hämtar det \[...\]
<hr />
Tag: Tortoisesvn
Installera Subversion på klienten
För att komma igång med versionhanteringen när man utvecklar i Visual Studio, måste man installera tortoisesvn, sedan AnkhSVN. TortoiseSVN är själva klienten, medan VisualSVN är ett tillägg för Visual Studio. Gå in på C:\ i Windows. Högerklicka och välj SVN Checkout. Sedan ange din svn-server och mappen där du vill ha en working copy: [caption id=“attachment_97” align=“aligncenter” width=“300” caption=“subversion uppgifter”][/caption] Logga in [caption id=“attachment_99” align=“aligncenter” width=“300” caption=“subversion login”][/caption] AnkhSVN måhända inte syns direkt i Visual Studio. Bara öppna View > Other Windows > Pending Changes. Om man inte ser ändringar, gå in på File - Open from SVN - och tryck på Cancel. Nu måste allting fungera.
Tag: VisualSVN
Installera Subversion på klienten
För att komma igång med versionhanteringen när man utvecklar i Visual Studio, måste man installera tortoisesvn, sedan AnkhSVN. TortoiseSVN är själva klienten, medan VisualSVN är ett tillägg för Visual Studio. Gå in på C:\ i Windows. Högerklicka och välj SVN Checkout. Sedan ange din svn-server och mappen där du vill ha en working copy: [caption id=“attachment_97” align=“aligncenter” width=“300” caption=“subversion uppgifter”][/caption] Logga in [caption id=“attachment_99” align=“aligncenter” width=“300” caption=“subversion login”][/caption] AnkhSVN måhända inte syns direkt i Visual Studio. Bara öppna View > Other Windows > Pending Changes. Om man inte ser ändringar, gå in på File - Open from SVN - och tryck på Cancel. Nu måste allting fungera.
Tag: HelpUrl
HelpUrl i WebPart
Man kan lägga till HelpUrl i en WebPart, för att användare kan klicka och få instruktioner eller hjälp med just denna webpart. För att göra det manuellt, ska man klicka på pilen, välja “modify this web part”, och sedan i “Advanced” skriva url-länken i “HelpUrl”-fältet. För att lägga till HelpUrl ifrån början, när sajter skapas, måste man ange den egenskapen i onet.xml i Module för din sajt. Man måste hitta , och ändra den: <property name="HelpUrl" type="string">http://sr.se</property>
Så ser hela biten ut i onet.xml:
Tag: Site Definition
HelpUrl i WebPart
Man kan lägga till HelpUrl i en WebPart, för att användare kan klicka och få instruktioner eller hjälp med just denna webpart. För att göra det manuellt, ska man klicka på pilen, välja “modify this web part”, och sedan i “Advanced” skriva url-länken i “HelpUrl”-fältet. För att lägga till HelpUrl ifrån början, när sajter skapas, måste man ange den egenskapen i onet.xml i Module för din sajt. Man måste hitta , och ändra den: <property name="HelpUrl" type="string">http://sr.se</property>
Så ser hela biten ut i onet.xml:
Tag: SPView
Komma åt Title-kolumnen i SPList
Vad gör man om man vill lägga till Title-kolumnen till en ny vy? SPField fieldTitle = scheduleList.Fields["Title"];
Det kommer funka, men Title kommer vara bara text, utan en länk till SPListItem. Kolla på den koden: SPField fieldTitle = scheduleList.Fields[**SPBuiltInFieldId.LinkTitle**];
Här hämtar vi kolumnen som heter i Sharepoint “Title linked with item menu”. Det finns fler sådana “inbygda” kolumner.
Ändra query på en SPView i koden
När man vill ändra hur data ska visas i en SPView i SPList, då måste man ändra CAML-Query. Det enklaste sättet att skapa en CAML Query är att använda ett program som heter CAML Query Builder. Ta bara bort och för att de behövs inte. Sedan är det bara att loopa igenom alla vyer man behöver.
private void UpdateQueryInGroupViews(SPList list)
{
for (int i = 1; i < 11; i++)
{
string viewname = String.Format("Group {0:D2}", i);
SPView view = list.Views\[viewname\];
string query =
String.Format(
"<Where><Or><Contains><FieldRef Name='Group' />"
+ "<Value Type='Text'>{0:D2}</Value></Contains>"
+ "<IsNull><FieldRef Name='Group' /></IsNull></Or></Where>"
+ "<OrderBy><FieldRef Name='EventDate' Ascending='True' />"
+ "</OrderBy>", i);
view.Query = query;
view.Update();
}
}
I denna query sorterar vi efter Start Date och visar bara händelser för sin grupp.
Tag: Sharepoint Solution Generator
Hämta schema från en befintlig SPList
Ibland är det så att man vill ha en speciell mall för en SPList, man har redan skapat en mall manuellt på sajten. Då är det enklaste sättet att hämta schema.xml och Windows SharePoint Services 3.0 Tools. När man installerat det så startar man Sharepoint Solution Generator 2008. Sedan måste man hitta sin lista, eller dokumentbiblioteket och exportera. Sedan är det bara att importera till sitt projekt i Visual Studio.