Blog


How To Remove a Custom Action At Web Level With JSOM in SharePoint

var ideaCtx = SP.ClientContext.get_current();
var web = ideaCtx.get_web();
var oCustomActions = web.get_userCustomActions();
ideaCtx.load(oCustomActions);
ideaCtx.executeQueryAsync(
function () {
    var enumerator = oCustomActions.getEnumerator();
    while (enumerator.moveNext()) {
        // first log all Custom Actions to identify the one you want to delete
        console.log(enumerator.get_current().get_title() + " -> " + enumerator.get_current().get_location());                
    }
    var ca = oCustomActions.getItemAtIndex(theRightIndex); // choose this after 
    //console.log(ca);
    ca.deleteObject()
    ideaCtx.executeQueryAsync(
    function () { console.log('CA deleted successfully'); },
    function (sender, args) { console.log(args.get_message()); }
    )
},
function (sender, args) { console.log(args.get_message()); });

How To Enforce Uniqueness of Records Based on Two or More Columns in SharePoint

Applies to: SharePoint 2013, SharePoint Online (Office 365) wave 15 and 16.

As you probably already know, you can set one field at a time to be unique.

If you require records to be unique based on more columns, there’s no build in way of checking this option either in UI or declaratively, and while you could code some event receiver to check for uniqueness and cancel new items, we’ll show you a  much simpler way of doing it which will stand for both new items and updating items.

All you have to do is create a new calculated column which is based on the required columns and set it as unique. You won’t be able to do this in the UI if the columns you want to based the calculated column are lookup columns, so you would need to do it declaratively in Visual Studio or with code: JS in page or C# in a feature receiver.

The message that the user gets when trying to create an item that is not unique is “Cannot create item because field [Calculated-Field-Name] is not unique”. Unfortunately, users get this message only when trying to add a new item in datasheet mode, so if you need to warn users on the new form, additional checks must be done, as at the moment, SharePoint doesn’t throw any warning, it simply doesn’t add the record.


SharePoint 2013 – How to Change the text of the First Link in Global Navigation

If you’re using the global navigation in SharePoint, you noticed that the first link is always named after the name of the site and links to home. There’s no way you can change the text of this link to say for example “Home” or “Homepage” or “Landing” from the UI without changing the name of the site. Problem is that if you change the name of the site to “Homepage” for example, you’ll end up receiving notification e-mails which appear to come from Homepage <noreply@tenant.sharepoint.com> which is weird at least.

What you can do instead is use CSS to hide the name of the site and show whatever text you need.

This is the CSS:

your-css-file.css

/* Change the Home link in Global Navigation*/
#DeltaTopNavigation>div>ul>li:first-of-type>a>span:first-of-type>span:first-of-type {
  font-size: 0px;
}

#DeltaTopNavigation>div>ul>li:first-of-type>a>span:first-of-type>span:first-of-type::after {
  font-size: 13px;
  content: "Homepage";
}

and you can apply it in a feature receiver like this:

using (SPWeb web = properties.Feature.Parent as SPWeb)
{
  string linkBase = web.Url + "/";
  linkBase = linkBase.Substring(linkBase.IndexOf("/", 8));
  // alternate CSS
  web.AlternateCssUrl = linkBase + "SiteAssets/your-css-file.css";
  web.Update();
}

How To edit the Group Quick Launch in SharePoint 2013 (and SharePoint Online)

If you’re customizing your SharePoint groups from C# code, like creating role definitions, sharepoint groups and role assignments, you’re likely that you need to put those new groups in the left navigation area, also called Group Quick Launch so that users can add users / AD groups to them when going to Site Settings -> People and Groups.

Seems that in SharePoint 2013 and the 2013 wave of SharePoint online there’s no direct way to manipulate the Group Quick Launch programmatically, other than directly manipulating the “vti_associategroups” web property.

Here’s how you can do it in a feature receiver:

if (web.AllProperties.ContainsKey("vti_associategroups"))
{
   string tempValue = web.AllProperties["vti_associategroups"] + ";" + currentGroup.ID.ToString();
   web.DeleteProperty("vti_associategroups");
   web.AddProperty("vti_associategroups", tempValue);
   web.Update();
}
else
{
   web.AddProperty("vti_associategroups", "currentGroup.Id");
   web.Update();
}

Howto use a Virtualbox virtual disk file as a template

It turns out a Macbook Pro is a brilliant machine event when you need to do some code development on SharePoint. In short, create a Windows Server 2008 R2 Server in Virtualbox, install SharePoint and it boots and works faster than on a traditional server with spindle disks, thanks to its fast SSD.

Now you might need to keep some backup copies (read templates) of your fresh Windows installs, in order to reuse them for different projects / customers. In order to be able to use the copy for a new vm, you need to change the uuid of the vdi file, or otherwise Virtualbox will complain for the duplicate and won’t let you use it.

The command is:
VBoxManage internalcommands sethduuid {path-to-vdi}.vdi

Google Feels That E-mail Has to Evolve

If you’re (only) looking for a Google Inbox invite, you can skip to filling-in the form below.IMG_8351.PNG

As you probably know already, Google has launched a new front end for Gmail, called Inbox. It offers a simplified take on email, though one oriented to managing tasks.
You can set any message as a task so it will stick on top of your Inbox messages or you can seamlessly create new tasks. Then, you can easily postpone a message or task for later so you keep your Inbox focused on what you need to to next. Any postponed message or task will come back to Inbox after its snooze times out.
As simple as it may look, it’s a very good alternative to looking at an Inbox that just gets filled with new email and lets potentially important stuff to go down in the list.

To be able to use Inbox with your personal Google account, you need an invite. As they are limited for the time being, I’ll happily share one with you. Just answer the one question poll.



How To Integrate or link Facebook Groups with Google Groups

Suppose you need to communicate with a group of people out of which most have Facebook accounts  but some don’t and wish they needn’t create one.
Would it be possible to easily communicate with all of them? The answer is yes, although not both ways.
The solution that I am proposing to you offers the ability to fully communicate between members with Facebook accounts and partially with those that only have e-mail. The later will only receive communication but will not be able to interact (respond, like, post new discussions).
I assume you already have a Facebook group created and invited users with Facebook accounts. You can do that without having to friend all people, you just need their e-mail address.
The following steps are:

  1. Create a google group of type E-mail List (https://groups.google.com)
  2. Set permissions for Public to post to the group (otherwise communication from Facebook won’t get through)
  3. Create a Facebook account using the group’s e-mail address. Set it not to accept friend requests and to be as stealth as possible in order to minimize e-mails sent to your people and administrative work.
  4. From this new Facebook account search for the Facebook group I assumed you had already created and join it. 
  5. Switch to your Facebook account and approve the join request
  6. Test by making a new post in the Facebook group. You should see the post on the group page.
  7. Add the email addresses of the people without Facebook accounts to the Google group by the “Direct Add Members” option.
Happy grouping!

How to Use a Simple SSL Certificate for Exchange (Without SAN or Wildcard)

The usual recommendation for configuring Microsoft Exchange Server was to use a public CA, SAN certificate or UC certificate in order to avoid issues with Outlook and mobile clients. While that works, I think it’s not very efficient as the typical SAN certificate is in the ~$300 per year range. A cheaper way to configure Exchange, starting from Exchange 2010 and working for Exchange 2013 also is to set internal URLs the same as the external ones (ex: mail.company.com) and to publish the autodiscover service through the same mail.company.com hostname. While this currently throws a warning if using the Exchange Connectivity Test from Microsoft, it works just fine with Outlook and mobile clients (no issue whatsoever with OWA).

In order to change the internal URLs, you can use the following PowerShell commands:

$urlpath = Read-Host "Type internal Client Access FQDN starting with http:// or https://" 
Set-ClientAccessServer –Identity * –AutodiscoverServiceInternalUri “$urlpath/autodiscover/autodiscover.xml” 
Set-webservicesvirtualdirectory –Identity * –internalurl “$urlpath/ews/exchange.asmx”
Set-oabvirtualdirectory –Identity * –internalurl “$urlpath/oab”
Set-owavirtualdirectory –Identity * –internalurl “$urlpath/owa”
Set-ecpvirtualdirectory –Identity * –internalurl “$urlpath/ecp”
Set-ActiveSyncVirtualDirectory -Identity * -InternalUrl "$urlpath/Microsoft-Server-Activ

Finally, you can purchase a simple SSL certificate which should be three to four times cheaper per year.

Don’t forget to Share and Like.

Thanks!