Wednesday, July 10, 2013

Cascading drop-downs with Cross-site Lookup For SharePoint 2013 and Office 365

In the previous entries I showed how to configure Cross-site Lookup column and how to modify the template of the lookup result set. Now I'm going to demonstrate how to use Cross-site Lookup with Forms Designer and build dependent columns and cascading dropdown in particular with this complex solution. Please, note, Cross-site Lookup is supported by Forms Designer starting from version 2.6.4930.

Let's imagine that our company has offices in multiple countries and we have to create a ticket system. In the ticket form users have to specify their office. In order to simplify this task we can also add a country field to the ticket form. So, when the user chooses a country in the form the dropdown of offices is automatically filtered by the selected country. This behavior is called cascading dropdowns.

Ok, I will use lists from my previous articles: Countries and Target. I added a new list called Offices to the same site where Countries list is located. Then I created a simple lookup field in Offices and set Countries as its source list. So, now we can specify the country for each office. Here is a new Office form:

SharePoint 2013 lookup

Let's imagine that our Target list is the list of tickets from my previous example. We have already created Cross-site Lookup column for country in Target list. Now we have to create Office lookup field that is linked to Offices list. The both lookups do not allow multiple values. Now we have to use Forms Designer to place both of these fields into the form. Forms Designer is required in this scenario because we will use its JavaScript framework.

Here is a new Target form:

SharePoint 2013 cascading lookups

Now let's open Cross-site Lookup management window and select Office field there. Expand Additional settings. Here we have to modify 'Request items' template to load only those offices which belong to the selected country. Here is my template:

function (term, page) {
  // Getting the selected country
  var countryId = fd.field('Country').value();
  if (!countryId) {
    countryId = 0;
  }
  
  // Filtering by the selected country
  if (!term || term.length == 0) {
    return "{WebUrl}/_api/web/lists('{ListId}')/items?$select=Id,{LookupField},Country/Id&$orderby=Created desc&$expand=Country/Id&$filter=Country/Id eq " + countryId + "&$top=10";
  }
  return "{WebUrl}/_api/web/lists('{ListId}')/items?$select=Id,{LookupField},Country/Id&$orderby={LookupField}&$expand=Country/Id&$filter=startswith({LookupField}, '" + term + "') and Country/Id eq " + countryId + "&$top=10";
}

First I get the selected country field with Forms Designer's JavaScript framework. Then I use it in requests as additional filter. Pay attention to the requests. Firstly, to use a field in the filter you have to add it into the select part of the query. Secondly, if you use lookup column in the filter you have to use required $expand operator. You can find detailed info on using lookup column in SharePoint 2013 REST API in the following article: http://www.andrewconnell.com/blog/Applying-Filters-to-Lookup-Fields-with-the-SP2013-REST-API

Now, when we choose a country in the form, the drop down list of offices is automatically filtered by the selected country:

Cascading lookups in SharePoint 2013 and Office 365

The last thing we have to do is to clear Office field when Country is changed. Open Forms Designer and go to its JS-editor. Put the following code there and save the layout for edit and new forms:

fd.field('Country').change(function() {
  fd.field('Office').value(0);
});

As you can see Forms Designer's JavaScript framework supports Cross-site Lookup field like any standard field. So, you can dynamically get and set values, handle value changing events, make selection controls readonly and etc.

Setting up the view of results in Cross-site Lookup column for SharePoint 2013 and Office 365

In the previous entry I demonstrated how to create Cross-site Lookup Columns. Now I will show how to use Advanced section fields of Cross-site Lookup column management dialog and how to modify the template of the result set in particular. With our Cross-site Lookup you can add extra fields to the result set to simplify search and navigation through the large lists. Here is illustration from the official website:

SharePoint 2013 cross-site lookup people with photos

I will use the same environment that I created in the previous entry: Countries list in the root site of the root site collection and Target list in the nested site collection.

Here I will show how to place the flag near the country name in the lookup result set. First, I added Hyperlink or Picture column and called it Flag. Next, I set flags for all the countries in my list:

SharePoint 2013 cross-site lookup: list of countries with flags

Now, go to Target list and open Cross-site lookup management window. Select Country field and expand Advanced settings at the bottom of the dialog.

Here you can find two templates. The first one 'Request items' is used to request items from the source list through SharePoint 2013 rest service. Here we can define sorting, additional filtering and searching criteria for result sets. We have to insert our Flag column into select statement to retrieve it from the server and build it into the item template which is used in the result set.

Here is my 'Request Items' template:

function (term, page) {
  if (!term || term.length == 0) {
    return "{WebUrl}/_api/web/lists('{ListId}')/items?$select=Id,{LookupField},Flag&$orderby=Created desc&$top=10";
  }
  return "{WebUrl}/_api/web/lists('{ListId}')/items?$select=Id,{LookupField},Flag&$orderby={LookupField}&$filter=startswith({LookupField}, '" + term + "')&$top=10";
}

The second template 'Item format' defines the view of an item in the result set. Here we will use our Flag field that will be returned from the server by the request defined in the first template. Here is my 'Item format' template:

function(item) {
  return '
' + item["{LookupField}"] + '
'; }

Now let's see what our Country field looks like in the forms:

SharePoint 2013 cross-site lookup with extended results

Excellent! In the following article I will show how to use Cross-site Lookup with Forms Designer and create dependent columns including cascading dropdowns.

Cross-site Lookup column for SharePoint 2013 and SharePoint Online in Office 365

In this article I would like to present our new solution Cross-site Lookup for SharePoint 2013 and SharePoint Online in Office 365. With help of this feature you can create lookup columns with quick search and asynchronous loading of results for lists and libraries to link data from any sites within a site collection.

First, I would like to cover the technical aspects of this solution. Our lookup is not a custom field because custom fields can be deployed only as part of farm solutions which are not available for Office 365. So, we made it as a number of JavaScript templates (view, edit, new and display) for standard Lookup field. We used JSLink property of SPField class to inject these templates and Select2 control with some modifications as control for searching and navigating through the source list.

Now I will demonstrate our solution in action. In the root web of the root site collection I created a list of countries. Next I created a new site collection in the same web application and added a custom list to its root site and named it Target. Ok, let's create a new lookup column in Target list which links to Countries list in the root site collection.

Open the view of Target list and click 'Plumsail Lookup ' button in 'List' tab of the ribbon.

SharePoint 2013 Cross-site Lookup

If you don't have the existing lookup column in your list you will see a dialog for creating a new lookup field. Enter the name of this field in text box and click Ok.

Create cross-site lookup in SharePoint 2013

After the field has been successfully added you can configure it. First, let's change the source list. Click 'Change ' link near the web url to specify the web of your source link. I clear this field because my source list is located in the root site of the root site collection. Ok.

Now select the source list in the next dropdown and the field of the source list which will be shown in the target list. In my case the source list is Countries and the field is Title. Ok.

Cross-site lookup column for SharePoint 2013 settings

By checking appropriate options you can enable multiple values for your lookup and add 'New Item' link which allows users to add new items to the source list directly from the form.

If you check Add 'New Item' link you will see the following options:

SharePoint 2013 lookup with add new item link option

In the first field you can specify the title of the new item link. The second one is for default content type ID. When the user clicks the new item link they will see a form for the specified content type. If you leave this field empty, users will see a form for the default content type of the source list.

Here is what this link looks like in the form:

SharePoint 2013 lookup with add new item link

I will cover Advanced section fields in the next article. Now, let's see what our lookup field looks like in forms and list views.

Lookup column with a single value:

SharePoint 2013 lookup with single value

Lookup column with multiple values:

SharePoint 2013 cross-site lookup with multiple values

List view:

SharePoint 2013 cross-site lookup in the list view

Display form:

SharePoint 2013 cross-site lookup in display form

Looks perfect. In the next articles I will demonstrate how to change the template of the result set in the select box of Cross-site Lookup Column, how to use Lookup and Forms Designer together and create dependent columns and cascading dropdowns.

Friday, May 3, 2013

Reservation of resources in SharePoint 2013 and SharePoint 2013 Online in Office 365

SharePoint 2010

I suppose, many of you know about a great calendar feature in SharePoint 2010 called resource reservation. It enables organization of meetings in useful interface that allows to select multiple resources such as meeting rooms, projector and other facilities and required participants, and next the time frame that is free for all participants and facilities in the calendar view. You can switch between week and day views. Here is a screenshot of the calendar with resource reservation and member scheduling features:

Meeting organizer in SharePoint 2010

You can change resources and participants in the form of your meeting, find free time frames in the diagram and check double booking:

Create meeting in SharePoint 2010

There are two ways to add the resource reservation feature into SharePoint 2010 calendar:

  1. Enable web feature 'Group Work Lists', add calendar and go to its settings. Click 'Title, description and navigation' link in 'General settings' section. Here check 'Use this calendar to share member's schedule?' and 'Use this calendar for Resource Reservation?'
  2. Create a site based on 'Group Work Site' template.

Here is the detailed instructions: http://office.microsoft.com/en-us/sharepoint-server-help/enable-reservation-of-resources-in-a-calendar-HA101810595.aspx

SharePoint 2013 on-premise

After migration to SharePoint 2013 I discovered that these features were excluded from the new platform and saved only as backward compatibility. So, you can migrate your application with installed booking calendar from SharePoint 2010 to SharePoint 2013 and you will keep functionality of resource reservation but you cannot activate it on a new SharePoint 2013 application through default interface.

Microsoft officially explained these restrictions by unpopularity of the resource reservation feature: http://technet.microsoft.com/en-us/library/ff607742(v=office.15).aspx#section1

First, I found a solution for SharePoint 2013 on-premise. It is possible to display the missing site templates including 'Group Work Site'. Then you just need to create a site based on this template and you will get the calendar of resources.

Go to C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\TEMPLATE\1033\XML, open WEBTEMP.XML file, find an element with 'Group Work Site' title attribute and change its Hidden attribute from FALSE to TRUE.

SharePoint 2013 Online in Office 365

Perfect, now we can use free SharePoint booking system based on the standard calendar. But what about SharePoint Online in Office 365? We do not have an access to WEBTEMP.XML in its file system.

After some research I developed a sandbox solution that enables hidden 'Group Work Lists' feature and adds calendar with resource reservation and member scheduling features. Please, download it and follow the instructions to install:

  1. Go to the site collection settings.
  2. Open 'Solutions' area from 'Web Designer Galleries' section.
  3. Upload CalendarWithResources.wsp package and activate it.
  4. Now, navigate into the site where you wish to add the calendar with the enabled resource reservation feature.
  5. Open site settings -> site features.
  6. Activate 'Calendar With Resources' feature.

Great, now you have Group Calendar with an ability to book resources and schedule meetings. This solution works for SharePoint 2013 on-premise as well, so you can use it instead of WEBTEMP.XML file modification.

Meeting organizer in SharePoint 2013

The form of the meeting:

Create meeting in SharePoint 2013

How it works

I have attached source project to this entry. CalendarWithResources feature is dependent on feature with GUID: 9c03e124-eef7-4dc6-b5eb-86ccd207cb87. This is 'Group Work Lists' web feature that exists for backward compatibility but is hidden from the list of features. So, it is the only way to enable it.

Also solution contains a calendar list with a custom schema. I added EnableResourceSelector="TRUE" and EnablePeopleSelector="TRUE" attributes into the definition. These properties turn on the resource reservation and member scheduling settings of the calendar.

Links:

CalendarWithResources.wsp
Sources of CalendarWithResources

Thursday, April 11, 2013

SharePoint 2013 form with related items list (part 2)

Note: This entry is outdated. The current version of Forms Designer contains 'Related Items' control which can be distributed anywhere in the form and quickly configured via its properties. Please, see our article about this new functionality. And of course, if you already have a license you can upgrade it to the latest version for free.

I have started a series of posts about creating forms with related items. In the previous post I described how to do that in a display form. Now I will demonstrate how to place related items into an edit form and edit them directly in it.

Like in the case of a display form, we have to place additional web part with the list of related items into an edit form . Navigate to the parent list, select List tab in the ribbon and select (Item) Edit Form in the drop down menu of the Form Web Part:

SharePoint Form Web Parts

Click 'Add a Web Part' link at the top of a page and select related items list in the web parts dialog. You can see the following text at the top of the inserted list:

SharePoint 2013 Quick Edit

We have to disable in-place editing because if the user adds a new item in this mode they have manually fill order number. Here is the illustration:

SharePoint 2013 Quick Edit

So, we will remove in-place editing from this list and I will show how to fill order number automatically in the new form of a related item. Generally, I recommend you to minimize the number of ways of editing related items, because you can get stuck with many issues related to the ribbon, automatic redirection from the parent form and etc.

Now, let's remove in-place editing link. Save the form, go to the list of related items, open its settings page. Click Advanced Settings and disable Quick edit:

SharePoint 2013 Quick Edit

Return to the parent list and open its editing form in edit mode as we did above. As you can see there is only one link at the top of the related items: 'new item'. Great, now open properties of this web part and click 'Edit the current view' link. Like in the case of the display form, lets remove 'Product Name (linked to item with edit menu)' column from the view and replace it with 'Product Name (linked to item)'. Next, uncheck 'Allow individual item checkboxes' in the Tabular View section.

This way we disable the context menu and ribbon and leave an only way for editing items: user has to open them in a dialog window and remove or edit them from its ribbon.

Also remove 'OrderNum' column from the view, because there will be items related to the current order only. Like in the case of display form I have added total price into my view.

Save view and the edit form and go to Forms Designer. Select Edit Form, open JavaScript editor and past the same script like in the case of Display form:

var wp0 = $('div[id^="MSOZoneCell_WebPartWPQ"]:eq(0)');
wp0.detach().appendTo('#fd_tabcontrol-0-tab-4');
wp0.attr("onmouseup", "").attr("onkeyup", "");

I will not comment on it, you can find the description in the first post. Apart from this, we have to add the current order number into the 'new item' link of the list of related items to prefill it automatically in the new form of an item. Add the following JavaScript into editor:

var newItem = wp0.find('.ms-list-addnew a');
// getting query string hash
var queryString = SP.ScriptHelpers.getDocumentQueryPairs();
// adding get-parameter 'order' into new item link
newItem.attr('onclick', 'NewItem2(event, "' + newItem.attr('href') + '&order=' + queryString['ID'] + '"); return false;')

Save the form and close Forms Designer. Now open SharePoint Designer and add filtration to the related items by the current order as described for the Display form.

Finally, we have to modify a new item form to automatically fill 'OrderNum' column based on the provided get-parameter. Open the new form in the Form Designer, distribute fields in the form and open JavaScript editor. Paste the following code there:

// getting query string hash
var queryString = SP.ScriptHelpers.getDocumentQueryPairs();
// fill order number
fd.field('OrderNum').control().value(queryString['order']);

Now, when I click a 'new item' link from the Edit form of the order, the 'OrderNum' field is prefilled automatically with the current order number:

SharePoint edit form with list of related items

Tuesday, April 9, 2013

SharePoint 2013 form with related items list (part 1)

Note: This entry is outdated. The current version of Forms Designer contains 'Related Items' control which can be distributed anywhere in the form and quickly configured via its properties. Please, see our article about this new functionality. And of course, if you already have a license you can upgrade it to the latest version for free.

One of the usual cases of our customers is to create a form with related items, e. g. an order form with the list of items of the order. I will demonstrate how to place related items in the separate tab of the parent form and add or edit them directly in the current tab. I divided this manual into 3 parts:

  1. Display form
  2. Edit form
  3. New form

In this entry I will show how to create a display form with tabs and place related items into the separate tab. I created the list of orders and the list of order items with the following columns: Product Name (renamed Title), Weight, Width, Height, Depth, Quantity and Total price. I added lookup field OrderNum into the list of order items to link items with the order.

First, I designed forms of an order with Forms Designer, added tabs 'Customer', 'Billing Info', 'Shipping Info' and 'Items'. I will put related items in the 'Items' tab, which is now empty. Here is my form:

SharePoint form with tabs

Next, I changed the order items list setting to open forms in a dialog window. So users will be able to edit order items directly from the order form without leaving it. The described option is located here: List Settings -> Advanced settings -> Launch forms in a dialog

Now, go to the orders list and select List tab in the ribbon. Choose Form Web Parts drop down and select (Item) Display Form:

SharePoint form web parts

Click 'Add a Web Part' and select Order Items list. In the web part menu select 'Edit Web Part' item.

SharePoint edit web part

We will not allow users to edit the list of items in the display form of an order. So, first of all we have to disable links 'new item' and 'edit' on the top of the list. Change Toolbar Type to 'No Toolbar' in the settings window.

Next, click 'Edit the current view' link:

SharePoint edit current view

Here remove 'Product Name (linked to item with edit menu)' column from the view and replace it with Product Name (linked to item). Now users will not see an order item's context menu.

In the 'Totals' section I added the sum of Total Price to display it for the selected order. Ok, save the view. Next, we have to move the list of order items into the 'Items' tab and filter them by the current order.

Open Forms Designer editor for Orders list and select Display Form. Open JavaScript editor. The following JavaScript takes the first web part and replaces it into the fourth tab:

var wp0 = $('div[id^="MSOZoneCell_WebPartWPQ"]:eq(0)');
wp0.detach().appendTo('#fd_tabcontrol-0-tab-4');

When user clicks anywhere on the table of items, new tabs appear in the ribbon: Items and List. We have to disable this functionality to forbid users to edit the list of order items from a display form of an order. Paste the following row into JavaScript editor to disable mouse and keyboard events:

wp0.attr("onmouseup", "").attr("onkeyup", "");

Ok, save the display form, close Forms Designer and open any order in the display mode. Now you can see that the order items list appears in the 'Items' tab. The last thing we have to do is to filter this list by the current order. Open our display form in SharePoint Designer. Files generated with Forms Designer start with fd_{Content Type Name}_{Form Type}. So, my display form is called fd_Item_Display.aspx.

Find XsltListViewWebPart that renders Order Items list. Add a new binding parameter into ParameterBindings section:

<ParameterBinding Name="OrderId" Location="QueryString(ID)" DefaultValue="0"/>

Here we bound OrderId to get-parameter ID that contains the current order id value. You can find more info about parameter bindings here:
http://blogs.msdn.com/b/joshuag/archive/2009/04/06/dataformwebpart-parameters-and-parameterbindings.aspx

Now we can use 'OrderId' parameter in CAML-query:

<Where>
  <Eq>
    <FieldRef Name="OrderNum" LookupId="TRUE"/>
    <Value Type="Lookup">{OrderId}</Value>
  </Eq>
</Where>

'OrderNum' is an internal name of my lookup field. Place the code above into Query section and save the page.

Now on the display form of an order we can see order items related to the current order only. Here is my final display form:

SharePoint form with the list of related items

When users click on product name they see display form of an item in a dialog window:

SharePoint related item form

Friday, April 5, 2013

Redirect after SharePoint form submission

In this article I will demonstrate how to handle a form submission event with Forms Designer tool and particularly how to redirect the user to the specific page.

Many of our clients request an option to redirect the user to the 'Thank you' page after creating a new item. Just paste the following script into the Forms Designer JavaScript editor and your users will be redirected to '/SitePages/ThankYou.aspx' page on the submission and to '/SitePages/Cancel.aspx' on the cancellation:

fd.cancel().click(function(){ STSNavigate('/SitePages/Cancel.aspx');return false; });
fd.onsubmit(function (){
    $("#aspnetForm").attr('action',location.pathname+'?Source=/SitePages/ThankYou.aspx');
    return true;
});

Ok, another popular request is to allow users to add multiple items without closing a new form. We suggest to confirm with the user whether they want to add a new item after the submission of the current one. If they want so, the new form will be refreshed. Otherwise the user will be redirected to the 'Thank you' page. I have extended the previous script with the described functionality:

fd.cancel().click(function(){ STSNavigate('/SitePages/Cancel.aspx');return false; });
fd.onsubmit(function (){
  if (confirm('Would you like to add a next item?')) {
    $("#aspnetForm").attr('action',location.pathname+'?Source=' + location.pathname);
  } else {
    $("#aspnetForm").attr('action',location.pathname+'?Source=/SitePages/ThankYou.aspx');
  }
  return true;
});

As you can see it is very easy to extend functionality of your form with Forms Designer JavaScript framework. You can find the full description of fd-object on the official website.