Friday, March 28, 2014

Loading JavaScript Libraries only when needed – SharePoint

With the current trend of moving to client side scripting, we can see so many lines of custom scripts are written in SharePoint applications. When comes to SharePoint Online environments, sometimes only practical option to implement some custom functionality is client-side scripting.

Usually most of the custom scripts written are required or used in few pages. This means there is no need for the script to be put on the master page. Of cause we can add these script references to the page layouts. But with so many scripted custom controls we will have to maintain lot of page layouts.

On the other hand there are so many SharePoint script files and we cannot say when and where we will use them.

Therefore it is really good if there is a technique that can be used to keep amount of scripts loading down to an acceptable level on page basis.

We can use ScriptLink in master page with OnDemand attribute set to true to register scripts. Then on a page, script can be requested to execute by using SP.SOD.execute or SP.SOD.executeFunc methods.

.html master page:
<!--MS:<SharePoint:ScriptLink language="javascript" name="SP.Search.js" OnDemand="true" runat="server" Localizable="false">-->
<!--ME:</SharePoint:ScriptLink>-->

.master master page:
<SharePoint:ScriptLink language="javascript" name="SP.Search.js" OnDemand="true" runat="server" Localizable="false">
</SharePoint:ScriptLink>

Page that require the script:
$("#MySearchButton").click(function () {
   SP.SOD.executeFunc('SP.Search.js', 'Microsoft.SharePoint.Client.Search.Query', SetSearchSettings);
});

var SetSearchSettings = function () {
   // search settings
};

Here SP.SOD.executeFunc ensures that the SP.Search.js file that contains the Microsoft.SharePoint.Client.Search.Query function is loaded and then runs the specified callback function SetSearchSettings. SetSearchSettings function is where I write my custom code.

Custom Script Files:
Use Script Editor webpart to add scripts/script references to the page without the need of changing the MasterPage or Page Layout. (Scripts added directly in page content will get removed automatically upon page save)
Script Editor webpart content:
<script src="/_catalogs/masterpage/myproject/js/custom-search-control.js" type="text/javascript"></script>

Wednesday, March 26, 2014

Get OOB Document Type Icon Using SharePoint JavaScript Client Object Model

SP.Web.mapToIcon method in sp.js file returns the name of the icon that is used to represent a specified document. By default, these icons are stored in the SharePoint hive /TEMPLATE/IMAGES folder. Therefore by appending to the _layouts/images/, we can form the URL of these images.

<script type="text/javascript">
  var iconName;

  function getDocumentTypeIcon() {
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();
    iconName = web.mapToIcon('test1.docx', '', SP.Utilities.IconSize.Size16);
    context.executeQueryAsync(Function.createDelegate(this, this.onSuccessMethod), Function.createDelegate(this, this.onFailureMethod));
  }

  function onSuccessMethod(sender, args) {
    var iconUrl = _spPageContextInfo.siteAbsoluteUrl + "/_layouts/images/" + iconName.m_value;
    alert(iconUrl);
  }

  function onFailureMethod(sender, args) {
    alert("Error: " + args.get_message());
  }

  ExecuteOrDelayUntilScriptLoaded(getDocumentTypeIcon, 'sp.js');
</script>

Document type icon names take the form of IC<Document Type>.gif (Ex: icdocx.gif). The information about which icon is displayed for which document type in stored in the DOCICON.XML file stored in /TEMPLATE/XML folder in the SharePoint hive.

Tuesday, March 25, 2014

SharePoint - Get Current SiteCollection URL with _spPageContextInfo JavaScript Object

To get the URL of current site collection or current web of a SharePoint site in Javascript, we can use _spPageContextInfo object.

_spPageContextInfo is a simple object that we can find on every SharePoint 2010 or 2013 page, and in SharePoint 2013 it will have the following information on it:


However we can’t access _spPageContextInfo object from the App pages. But in that case most of these values can be accessed by using URLstrings and tokens in apps for SharePoint.

Wednesday, March 19, 2014

Settings up an Android Application Project Developed on One PC on Another – For Beginner

Recently I wanted to add couple of new features to an Android application which was developed some time ago. I’m new to the Android development and here I’m listing down all the issues that I had to face and how I resolved them, in my attempt to set up the project in my development environment.

First I wanted to open up half way developed Android project, which was developed using Android Developer Tools (ADT). There was no obvious option like ‘open project’ in my ADT menu. Instead I had to use one of the options below which will open up Import Projects window.

With either approach, we should not copy our project into the workspace. Copy it elsewhere and let the Eclipse copy it into the workspace by selecting ‘Copy projects into workspace’ checkbox in the Import Projects window.

1. File -> New -> Project... -> Android Project from Existing Code
2. File -> Import -> Android -> Existing Android Code Into Workspace


Then my project was loaded in ADT Package Explorer. But I could see couple of errors in the Console saying:
Unable to resolve target 'android-17' Android Target Problem

Reason turned out to be that the SDK version using by me is different from the original version used in the project. I could found the SDK version set to 17 in application manifest file (AndroidManifest.xml), which resides in the project folder inside the workspace folder.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.shighway"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />


So I tried to fix the issue by manually updating the SDK version to 18, which my environment was using. (We can find the Android version and related API number in Developer Dashboards.)

Then the Target resolving problem was gone and I got a new error:
File is Out of sync

Then I figured out that there are actually two AndroidManifest.xml files. Second one was in the ‘bin’ folder. Updating that file and setting SDK version to 18 in that AndroidManifest.xml cleared out all the errors.

Note: Changes to AndroidManifest.xml file took effect only after I close and open the ADT.

Build an Android project in ADT
In order to be sure, I was wondering whether there is an option in ADT to rebuild the project. Then I learnt that there is no menu option to do that. But if we are developing in Eclipse, the ADT plugin incrementally builds the project as we make changes to the source code. Also it outputs an .apk file automatically to the bin folder of the project.

Now I’m sure my project is building and it is targeting the 4.3 Jelly Bean version. But how about the support for pervious Android versions? There is a setting for that in the AndroidManifest.xml file. Setting is android:minSdkVersion, which specifies the minimum API Level required  for the application to run. I specified 8 which means 2.2 Froyo.

Then I used Run -> Run from ADT menu to run my application in an emulator. Yes, it was running, but emulator took while to load in the first run and it was not that fast in later runs as well.

Next task was to run the app in my Android device, which is running on 4.3 Jelly Bean. So I plugged my device and wanted to enable “USB debugging” in my phone from the Developer options. But developer options were not there in the Settings as Developer options is hidden by default on 4.3 and I had to enable it by:

Settings -> More -> About device -> tap "Build number" 7 times

Now USB debugging is enabled and when I run my application it was still running on the emulator.

I had to go to the Run -> Run Configurations... -> Target from ADT menu to set to prompt always to pick a device when running.


After that when I invoked Run form the menu I got Android Device Chooser window to select the device.


Even though the window pops out, my device was not listed in there. I had to update device driver software. In Windows 7, I did the following:
  • Go to Computer Management (Right click Computer -> Manage).
  • Under Device Manager, expand Portable Devices.
  • Select the phone and update driver software (Phone needs to be connected).
  • I let it search in the Internet and updated the driver.

With the updated driver, when I run my application I could see a device was listed, but it didn’t let me select it. Then I noticed that phone State is offline and Target is unknown for the listed device.


Therefore I disabled and re-enabled USB debugging on the phone and it fixed the issue. Later I learned that rebooting the phone is required in some cases.

Also there was a popup coming in the phone asking ‘Allow USB Debugging?’ with the device id. Accepting that listed the phone in Android Device Manager and it was available for selection.


And it deployed the application on my phone.