The true power of LightSwitch lies in its combination of Access-like ease of use and quick ramp-up, while also remaining attractive for complex coding scenarios. The new LightSwitch HTML Client allows you to build modern apps in a couple of minutes, deploy them to online services like SharePoint and Azure and access them from a variety of mobile devices.
You already learned about the basic usage of the new LightSwitch HTML Application project type and screen templates in our previous blog posts. We also introduced you to some of our more powerful concepts. We discussed the new HTML Client APIs, such as Event Handling and Promises, showed you how to use them to write your own custom controls that bind to data and how to integrate existing jQueryMobile controls.
In this blog post we will dig even deeper into code and show you how to implement a custom collection control that shows a map. While LightSwitch already provides two collection controls out of the box, namely the List and Tile List controls, location based data is usually visualized using a map. This is especially useful on mobile devices and LightSwitch provides an API that allows you to write your own collection controls.
We will use the familiar Northwind database in this article. Instead of downloading it, we will just connect to an existing OData endpoint on the web. The Northwind database comes with a list of customers and their addresses. We will simply display those customers as pins on Bing Maps and allow users to drill into the details by clicking on one of the pins. In addition to that, we will limit the number of customers displayed on the list by implementing a paging mechanism.
Before we start you should make sure that you have the latest LightSwitch HTML Preview 2 installed on your machine. You can download the LightSwitch HTML Client Preview 2 here. We will go through the basic steps very quickly. If you are not familiar with those you should first walk through our previous tutorials.
Creating a project and connecting to existing data
We will start with a new “LightSwitch HTML Application” project. After creating the project select “Attach to external Data Source”, choose “OData Service” and put in the following endpoint address: “http://services.odata.org/Northwind/Northwind.svc”. Select “None” for the Authentication Type and proceed to the next screen. Check the box to include all Entities and close the dialog by clicking “Finish”. After those preparation steps your project should look similar to the following screenshot:
Building the basic screen
Our small sample application only needs one Screen. We will start with the “Browse” Screen Template. Right click the “Client” node in the Solution Explorer, select “Add Screen…”, use the “Browse Data Screen” and select the “NorthwindEntitiesData.Customers” Entity. This will create a Screen with a list of all customer names that are in the database.
Now we will enhance this Screen to show some more information when selecting a customer. Add a new Dialog to the Screen by dragging the “Selected Item” property of the “Customers” Query into the Dialogs node. Then select the Rows Layout and set “Use read-only controls” in the Properties Window. Finally, select the List and change the “Item Tap” action in the Properties Window to show the created Dialog.
The result should look similar to the following screenshot:
Running (F5) the application will show you a list of all customers and selecting one will open a dialog with all the details.
Implementing the Control
Now we are ready to replace the built-in List control with our custom maps control. Go back to the Screen Designer and change the List into a Custom Control. Now that we have a Custom Control we have to actually implement the code to render it.
Adding the lightswitch.bing-maps control
First we need to add the lightswitch.bing-maps control to our Solution. It will provide a wrapper around the Bing Maps SDK that can be used in your LightSwitch application. We already used a similar wrapper in the Contoso Moving walkthrough. This one is slightly enhanced to provide some additional functionality like adding multiple pins. Switch to the “File View” in the Solution Explorer and add the lightswitch.bing-maps.js (attached to the end of this blog post) to the “Scripts” folder of the Client project. Then open default.htm and add the following line at the beginning of the script block:
<script type="text/javascript" charset="utf8"
src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0">script>
And this one at the end of the script block:
<script type="text/javascript" charset="utf8" src="Scripts/lightswitch.bing-maps.js">script>
Implementing the custom control
Let’s implement the code of the actual control now. Select the Custom Control in the Screen Designer and select “Edit Render Code” from the Properties Window. This will open the BrowseCustomers.js file.
In there, replace the prepopulated code with the following one:
///var mapDiv;var current = 0;var step = 15; myapp.BrowseCustomers.Customer_render = function (element, contentItem) { mapDiv = $('').appendTo($(element)); $(mapDiv).lightswitchBingMapsControl();var visualCollection = contentItem.value;if (visualCollection.isLoaded) { showItems(current, step, contentItem.screen); } else { visualCollection.addChangeListener("isLoaded", function () {
showItems(current, step, contentItem.screen); }); visualCollection.load(); } };function showItems(start, end, screen) { $(mapDiv).lightswitchBingMapsControl("resetMap"); $.each(screen.Customers.data, function (i, customer) {if (i >= start && i <= end) { $(mapDiv).lightswitchBingMapsControl("addPinAsync", customer.Address,
customer.City, customer.Country, i + 1, function () { screen.Customers.selectedItem = customer; screen.showDialog("Details"); }); } }); };
This code will basically initialize the Bing Maps control and then add pins for the first 15 items in the list. Running the application will now no longer show a list, but a map with 15 pins. Clicking one of the pins will open a details dialog again.
The code explained
In order to understand the code we first have to understand the Visual Collection and its API. The Visual Collection is used as proxy between queries and the UI and provides various properties and methods, amongst them:
- visualCollection.isLoaded: This property tells you to whether the data has already been loaded.
- visualCollection.data: This property gives you to access to the loaded data.
- visualCollection.load(): This method will start to load the data.
- visualCollection.selectedItem: This property gives you access to the currently selected item.
In the render method we initialize the lightswitch.bing-maps control and append it to the DOM tree. We will then check whether the visualCollection is already loaded. If that is the case, we add the customers to the list. Otherwise we add a change listener which will call showItems() as soon as the data has been loaded.
In the showItems() method we first clear the map. Then we iterate over the list of customers and add the first 15 items to the map. We also pass a callback function which will open the details dialog as soon as a pin is been clicked.
Adding support for Paging
At the moment the map only shows 15 customers. We do not want hundreds of pins to be displayed on the map at once, this would look very chaotic. But we want to be able to look at the next 15 customers. Therefore we are going to implement a paging mechanism.
We are going to add support for going to the next 15 items and back again using two buttons. First add a New Group below the Custom Control, change it to a Columns Layout and set its “Height” to “Fit to Contents” in the Properties Window. Then add two Buttons inside of it (+Add, New Button). In the Add Button dialog select the “Write my own method” option. Name the methods “PreviousItems” and “NextItems”.
Right-click on the NextItem button and select “Edit execute code” and add the following code:
myapp.BrowseCustomers.NextItems_execute = function (screen) { current = current + step;if (current + step > screen.Customers.count) {if (screen.Customers.canLoadMore) { screen.Customers.loadMore().then(function (result) { showItems(current, current + step, screen); }); } } else { showItems(current, current + step, screen); } }; myapp.BrowseCustomers.PreviousItems_execute = function (screen) { current = current - step; showItems(current, current + step, screen); };
Running the application will now give you the following screen with a working paging mechanism:
The code explained
In order to implement the paging mechanism we fist have to understand the built-in query paging mechanism of LightSwitch. In order to save bandwidth LightSwitch will only load a limited number of items at once. It is not important to know how many items are actually loaded just the fact that not all items are loaded at once. The Visual Collection offers two properties and one method for dealing with paging:
- visualCollection.count: This property tells you the number of currently loaded items. It is important to notice that this is not the total number of items.
- visualCollection.canLoadMore: This property tells you whether there are more items that can be loaded.
- visualCollection.loadMore(): This will load more items.
In the execute method of the NextItems button we first check whether we already have enough items loaded to be displayed. If that is not the case we will check whether we can actually load more items and then load them. Using a Promise object, which we explained in our previous API post, we then show the newly loaded items using the showItems() method that we already implemented before.
Wrapping it up
That’s it! One screen, an external control and a few lines of glue code is all you need. The simple yet powerful API of LightSwitch makes it easier than ever to leverage the existing HTML ecosystem.
Please also note that if you want to use the Bing Maps control in a production environment you have to acquire your own API key. You can get the code on the Bing Maps SDK webpage. After you have the code you need to replace our test code in lightswitch.bing-maps.js with your own one.
I hope you will play around with some of the more advanced capabilities of our LightSwitch HTML Client Preview 2 and provide us with feedback in the MSDN Forums. We are always eager to learn more about what you are trying to accomplish using LightSwitch.
- Heinrich Wendel, Program Manager LightSwitch Team