build widgets

24
Lets Build Some Widgets!

Upload: scottw

Post on 18-Dec-2014

2.604 views

Category:

Technology


5 download

DESCRIPTION

These are the slides I used at the JTEL winterschool to describe how to create widgets for use in Wookie.

TRANSCRIPT

Page 1: Build Widgets

Lets Build Some Widgets!

Page 2: Build Widgets

Anatomy of a Widget

• Config.xml <- W3C Widgets P&C Spec• icon.png• index.html <- HTML start file• JavaScript code, CSS

• Zip it up, change ext to .wgt, and you’redone

Page 3: Build Widgets

Widget metadata• Id• Height, Width• Name• Description• Version• Features• Author info• License

Page 4: Build Widgets

A Silly Example: config.xml<?xml version="1.0" encoding="utf-8"?><widget xmlns="http://www.w3.org/ns/widgets"

id="http://www.getwookie.org/widgets/tea"version="1.0” height="150” width="125"><name>Tea</name><description>A silly Tea widget</description><author>Scott Wilson</author>

</widget>

Page 5: Build Widgets

A Silly Example: index.html<html>

<body><img src="tea.jpg" /><p>Time for a break, mate</p>

</body></html>

Page 6: Build Widgets

Make your own basic widget

1. Make an index.html file2. Make a config.xml file3. Zip them up, and change suffix to “.wgt”4. Upload to a wookie server

Page 7: Build Widgets

Uploading

• Go to http://192.168.2.161/wookie• Click “admin”• Login with java/java• Click “add new widget”• Find your .wgt file• OK!

Page 8: Build Widgets

Previewing a widget

• Go to 192.168.2.161:8080/wookie• Click “View Widget Gallery”• Click the “demo” link under your widget• Your widget will show

Page 9: Build Widgets

Preferences

• You can store preferences for an instance ofa widget using:

widget.preferences.setItem(“key”, “value”)widget.preferences.getItem(“key”)

Page 10: Build Widgets

Collaborative Widgets

• State and Participants

• State is shared across widgets with the sameIRI in the same shared context.

• State is propagated to related widgets usingan event callback

• State is set by submitting deltas

Page 11: Build Widgets

State examplewave.setStateCallback(stateUpdated);

stateUpdated = function(){ var keys = wave.getState().getKeys(); for (var i = 0; i < keys.length; i++) {

alert(wave.getState().get(keys[i])); }};

wave.getState().submitValue(“key”, “value”);

Page 12: Build Widgets

Participants

• Register callbacks with:wave.setParticipantCallback(myfunction);

• Methods:– getViewer() - get the current user– getParticipants() - get map of all participants

• Model:– getId(), getDisplayName(), getThumbnailUrl()

Page 13: Build Widgets

Making a collaborative app

• This requires some more planning

1. Draw up a design2. Create a working test page3. Implement models, action handlers and

event handlers4. Create the config.xml, icon.png, zip it up

and run it

Page 14: Build Widgets

Design

• Start with the view - what the widget lookslike

• Create the model - what are the objects inthe state model?

• Add the actions - how you interact with it• Wire it all up…

Page 15: Build Widgets
Page 16: Build Widgets

Prototyping

• Make a regular html page to test out yourview. Populate it with fake model, and don’twire up the actions yet

• You can reuse this for the real widget - justtake out your fake state info sections

Page 17: Build Widgets

Implementing

• Create a “Model” object for your statemodel

• Create a “Controller” object, and a methodin it for each action

• Register the participant and state eventhandlers with an “update view” method thatpopulates the view when running

Page 18: Build Widgets

function Task(id,name,status,assigned){ this.task_id = id; this.name = name; this.status = status; this.assigned_to = assigned;}Task.prototype.save = function(){wave.getState().submitValue(this.task_id, JSON.stringify(this));}

Models• Models can be implemented in typical “bean” fashion• Save/Find methods need to access wave state• Can use JSON (e.g. with json.js) or just plain strings for storage

Page 19: Build Widgets

Task.create = function(json){ var obj = JSON.parse(json); var task = new Task(obj.task_id,

obj.name,obj.status,obj.assigned_to); return task;}

Task.find = function(task_id){ var keys = wave.getState().getKeys(); for (var i = 0; i < keys.length; i++) { var key = keys[i]; if (key == task_id){ return Task.create(task_id, wave.getState().get(key)); } } return null;}

Task.findAll = function(){ var tasks = {}; var keys = wave.getState().getKeys(); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var task = Task.create(key, wave.getState().get(key)); tasks[key] = task; } return tasks;}

Static model methods

• Typically needmethods to turn statestrings back intomodel instances

• Also finder methods toget a particular modelobject

• This isn’t the only wayto do this, but is anOK pattern

Page 20: Build Widgets

/** * The Controller object * This is used to wire up the view and model with actions */var Controller = {

// Action handlers

// Toggle task state between completed and to-do toggleTask: function(task_id){ },

// Create a new task newTask: function(){ },

// Abandon task for someone else to do abandonTask: function(task_id){ },

// Claim a task (assign to self) claimTask: function(task_id){ }}

Controllers

• Methods for eachaction, makingchanges to the model

• You usually don’tneed to do any codethat interacts withHTML, as the eventhandlers should dothat

Page 21: Build Widgets

// Update the view when state has been updated stateUpdated: function(){ var tasks = Task.findAll(); if (tasks && tasks != null){ var tasklist = ""; for (key in tasks) { var task = tasks[key]; tasklist += // the task stuff to show dwr.util.setValue("tasklist", tasklist, {

escapeHtml:false }); var objDiv = document.getElementById("tasklist"); objDiv.scrollTop = objDiv.scrollHeight; } }, participantsUpdated: function(){ Controller.updateUser(); }

Event HandlersThese fire whenever the state or participants

are updated (e.g. by another instance).

Event handlers need to be registered like so:

wave.setStateCallback(Controller.stateUpdated);wave.setParticipantCallback(Controller.participantsUpdated);

Also useful to have these methods calledfrom onLoad() in an init() function tocreate initial view

You can import JQuery if you like forsetting the view content, or do it usingDOM

Page 22: Build Widgets

Packaging

You need to add this to your config.xml to tellWookie to include the Wave Gadget APImethods:

<featurename="http://wave.google.com"required="true"/>

Page 23: Build Widgets

Uploading, debugging and testing

• You need acollaborativeenvironment to testyour widget properly

• I’ve set up a Moodleinstance at:

192.168.2.XXX

Login as ws1,ws2,ws3,or ws4

Page 24: Build Widgets

Other stuff…

• AJAXIf you want to call

external sites fromwithin the widget, callmyurl =widget.proxify(url)first to call it via proxy.Also need to add thesite to the serverwhitelist.

• Camera accessIf you want to access the

user’s camera from awidget, there is anexample of how to dothis in the moodlecourse (topic 3)