I started with a web research and found a helpfull blog from Jesse here, explaining how to build a PlugIn. What I was missing in his blog, was how to return a value from the plugin. And there where some additional stumbling blocks to build this first PlugIn.
So lets start. First I created a new PhoneGap project in Visual Studio with the standard template (Visual Studio and PhoneGap is already installed).
In the next step I build the PlugIn class written in C#. The PlugIn should read my appointments and return them to the html page. So I added a new class AppointmentProvider in the Plugins folder of my project. This class must be
- in the namespace WP7GapClassLib.PhoneGap.Commands
- inherit from the BaseCommand base class
The rest of the code is more or less normal WP7 C# code.
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Microsoft.Phone.UserData;
// The namespace must point to the phonegap commands
namespace WP7GapClassLib.PhoneGap.Commands
{
// Use the phonegap base class
public class AppointmentProvider : BaseCommand
{
// Start appointment search with parameters
public void Get(string args)
{
// Check the availability of the args
if (string.IsNullOrWhiteSpace(args))
throw new ArgumentNullException();
// Deserialize the args to the ListArgs class
var arguments = JSON.JsonHelper.Deserialize<ListArgs>(args);
var appts = new Appointments();
appts.SearchCompleted +=
new EventHandler<AppointmentsSearchEventArgs>(appointments_SearchCompleted);
// Set the parameters
var start = DateTime.Now;
var end = start.AddDays(int.Parse(arguments.Days));
var max = int.Parse(arguments.Number);
// Start the asynchronous search
appts.SearchAsync(start, end, max, null);
}
// Get the result and pass it to the javascript code
private void appointments_SearchCompleted(object sender, AppointmentsSearchEventArgs e)
{
// Build the result
var apmts = new List<AptmResult>();
foreach (var item in e.Results)
{
apmts.Add(new AptmResult() {
Text = string.Format("{0} {1}-{2}<br>{3}",
item.StartTime.ToShortDateString(),
item.StartTime.ToShortTimeString(),
item.EndTime.ToShortTimeString(),
string.IsNullOrWhiteSpace(item.Subject) ? "Privat" : item.Subject)
});
}
var result = new PluginResult(PluginResult.Status.OK, apmts);
// Return the result
DispatchCommandResult(result);
}
// Argument class to be serialized
public class ListArgs
{
[DataMember]
public string Number;
[DataMember]
public string Days;
}
// Argument class to be serialized
public class AptmResult
{
[DataMember]
public string Text;
}
}
}
Wow, my first PhoneGap PlugIn is finished :)
Now I need some html to show the results and some JavaScript code to call the PlugIn. The html is easy, just a button and a list.
<div>
<button onclick="getAppointments();">
Get Appointments</button>
</div>
<div>
<ul id="apmtResults">
</ul>
</div>
Then I need the JavaScript code to call the PlugIn. I did all the explanation in the code, so you can hopefully follow on what I did. One point I did not get is why a reference to a local jQuery lib does not work... and now when I'm writing this, I realize that I should have made an entry in the GapSourceDictionary.xml file. So this problem is solved as well.
<!-- Local reference to the jQuery lib does not work!? -->
<script type="text/javascript" charset="utf-8" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript" charset="utf-8" src="phonegap-1.4.1.js"></script>
<script type="text/javascript">
// Wait for PhoneGap to connect with the device
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is ready to be used!
function onDeviceReady() {
// Nothing to do for me
}
// APPOINTMENT PLUGIN
// Call the AppointmentProvider plugin
function getAppointments() {
window.plugins.apmtProvider.showApmtProvider("10", "30");
}
// Create the class
function ApmtProvider() {
this.resultCallback = null;
}
ApmtProvider.prototype.showApmtProvider = function (number, days) {
var args = {};
if (number)
args.Number = number;
if (days)
args.Days = days;
PhoneGap.exec(onApmtOk, onApmtError, "AppointmentProvider", "Get", args);
}
// Create an instance of the class
PhoneGap.addConstructor(function () {
if (!window.plugins) {
window.plugins = {};
}
window.plugins.apmtProvider = new ApmtProvider();
});
// Callback to handle the ok event
function onApmtOk(result) {
// Use jQuery to add the result to the div
var apmts = [];
// Clear the list first
$("#apmtResults").empty();
// Prepare the result by building an array
$.each(result, function (i, item) {
apmts.push('<li>' + item.Text + '</li>');
});
// Add the result array
$("#apmtResults").append(apmts.join(''));
}
// Callback to handle the error event
function onApmtError(result) {
navigator.notification.alert(result, null, "Error");
}
</script>
We are done, but when I start the project it fails. First I need to know that I can't use the emulator, because there are no appointments. I need to run the project on a real device.
Still not working. It took me a while till I figured out, that in the WMAppManifest.xml file the entry
<Capability Name="ID_CAP_APPOINTMENTS"/>
was missing. After adding this everthing worked fine!
Please note that this is just a sample and error handling is missing ;-)
No comments:
Post a Comment