SlideShare a Scribd company logo
Lets Build Some 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’re
  done
Widget metadata
•   Id
•   Height, Width
•   Name
•   Description
•   Version
•   Features
•   Author info
•   License
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>
A Silly Example: index.html
<html>
  <body>
     <img src="tea.jpg" />
     <p>Time for a break, mate</p>
  </body>
</html>
Make your own basic widget
1.   Make an index.html file
2.   Make a config.xml file
3.   Zip them up, and change suffix to “.wgt”
4.   Upload to a wookie server
Uploading
•   Go to http://192.168.2.161/wookie
•   Click “admin”
•   Login with java/java
•   Click “add new widget”
•   Find your .wgt file
•   OK!
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
Preferences
• You can store preferences for an instance of
  a widget using:

widget.preferences.setItem(“key”, “value”)
widget.preferences.getItem(“key”)
Collaborative Widgets
• State and Participants

• State is shared across widgets with the same
  IRI in the same shared context.
• State is propagated to related widgets using
  an event callback
• State is set by submitting deltas
State example
wave.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”);
Participants
• Register callbacks with:
  wave.setParticipantCallback(myfunction);

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

• Model:
   – getId(), getDisplayName(), getThumbnailUrl()
Making a collaborative app
•   This requires some more planning

1. Draw up a design
2. Create a working test page
3. Implement models, action handlers and
   event handlers
4. Create the config.xml, icon.png, zip it up
   and run it
Design
• Start with the view - what the widget looks
  like
• Create the model - what are the objects in
  the state model?
• Add the actions - how you interact with it
• Wire it all up…
Build Widgets
Prototyping
• Make a regular html page to test out your
  view. Populate it with fake model, and don’t
  wire up the actions yet
• You can reuse this for the real widget - just
  take out your fake state info sections
Implementing
• Create a “Model” object for your state
  model
• Create a “Controller” object, and a method
  in it for each action
• Register the participant and state event
  handlers with an “update view” method that
  populates the view when running
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

    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));
    }
Static model methods
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;
                                                                   • Typically need
}
                                                                     methods to turn state
Task.find = function(task_id){
    var keys = wave.getState().getKeys();
    for (var i = 0; i < keys.length; i++) {
                                                                     strings back into
       var key = keys[i];
       if (key == task_id){
                                                                     model instances
          return Task.create(task_id, wave.getState().get(key));

    }
       }                                                           • Also finder methods to
}
    return null;
                                                                     get a particular model
Task.findAll = function(){                                           object
  var tasks = {};
     var keys = wave.getState().getKeys();
     for (var i = 0; i < keys.length; i++) {                       • This isn’t the only way
     var key = keys[i];
     var task = Task.create(key, wave.getState().get(key));
     tasks[key] = task;
                                                                     to do this, but is an
  }
  return tasks;
                                                                     OK pattern
}
Controllers
/**
 * The Controller object
 * This is used to wire up the view and model with actions
                                                             • Methods for each
 */
var Controller = {
                                                               action, making
    // Action handlers                                         changes to the model
    // Toggle task state between completed and to-do
    toggleTask: function(task_id){
                                                             • You usually don’t
    },
                                                               need to do any code
    // Create a new task
    newTask: function(){
    },
                                                               that interacts with
    // Abandon task for someone else to do
                                                               HTML, as the event
    abandonTask: function(task_id){
    },                                                         handlers should do
    // Claim a task (assign to self)
    claimTask: function(task_id){
                                                               that
    }
}
Event Handlers
// Update the view when state has been updated               These fire whenever the state or participants
   stateUpdated: function(){                                    are updated (e.g. by another instance).
      var tasks = Task.findAll();
      if (tasks && tasks != null){
         var tasklist = "";                                  Event handlers need to be registered like so:
         for (key in tasks) {
            var task = tasks[key];                           wave.setStateCallback(Controller.stateUpdated);
                                                             wave.setParticipantCallback(Controller.participantsUpdated);
            tasklist += // the task stuff to show
         dwr.util.setValue("tasklist", tasklist, {
       escapeHtml:false });                                  Also useful to have these methods called
         var objDiv = document.getElementById("tasklist");       from onLoad() in an init() function to
         objDiv.scrollTop = objDiv.scrollHeight;                 create initial view
      }
   },
   participantsUpdated: function(){                          You can import JQuery if you like for
      Controller.updateUser();                                  setting the view content, or do it using
   }                                                            DOM
Packaging
You need to add this to your config.xml to tell
 Wookie to include the Wave Gadget API
 methods:



<feature
 name="http://wave.google.com"
 required="true"/>
Uploading, debugging and testing
• You need a             • I’ve set up a Moodle
  collaborative            instance at:
  environment to test
  your widget properly   192.168.2.XXX

                         Login as ws1,ws2,ws3,
                           or ws4
Other stuff…
• AJAX                         • Camera access
If you want to call            If you want to access the
   external sites from            user’s camera from a
   within the widget, call        widget, there is an
   myurl =
                                  example of how to do
   widget.proxify(url)
   first to call it via proxy.    this in the moodle
   Also need to add the           course (topic 3)
   site to the server
   whitelist.

More Related Content

PDF
React lecture
PPT
Advanced Silverlight
PDF
Javascript Module Patterns
PDF
Simplified Android Development with Simple-Stack
PPTX
The Many Ways to Build Modular JavaScript
PPTX
Java script advance-auroskills (2)
PPTX
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
PDF
Persisting Data on SQLite using Room
React lecture
Advanced Silverlight
Javascript Module Patterns
Simplified Android Development with Simple-Stack
The Many Ways to Build Modular JavaScript
Java script advance-auroskills (2)
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Persisting Data on SQLite using Room

What's hot (20)

PDF
Quick start with React | DreamLab Academy #2
PPTX
Typescript barcelona
PDF
"Angular.js Concepts in Depth" by Aleksandar Simović
PPT
Angular In Depth
PDF
Integrating React.js with PHP projects
PDF
Aggregation and Awareness or How to Reduce the Amount of your FrontEnd Code ...
PDF
13 advanced-swing
PDF
The state of hooking into Drupal - DrupalCon Dublin
PDF
Architectures in the compose world
PDF
Workshop 23: ReactJS, React & Redux testing
PDF
Distributing information on iOS
PDF
React, Redux and es6/7
PDF
Basic Tutorial of React for Programmers
PPTX
JavaScript Promises
PDF
Best Practices in Qt Quick/QML - Part IV
 
PDF
Hooks and Events in Drupal 8
PPTX
Basics of AngularJS
PDF
Workshop 20: ReactJS Part II Flux Pattern & Redux
PPTX
Architecting Single Activity Applications (With or Without Fragments)
PDF
What's new in jQuery 1.5
Quick start with React | DreamLab Academy #2
Typescript barcelona
"Angular.js Concepts in Depth" by Aleksandar Simović
Angular In Depth
Integrating React.js with PHP projects
Aggregation and Awareness or How to Reduce the Amount of your FrontEnd Code ...
13 advanced-swing
The state of hooking into Drupal - DrupalCon Dublin
Architectures in the compose world
Workshop 23: ReactJS, React & Redux testing
Distributing information on iOS
React, Redux and es6/7
Basic Tutorial of React for Programmers
JavaScript Promises
Best Practices in Qt Quick/QML - Part IV
 
Hooks and Events in Drupal 8
Basics of AngularJS
Workshop 20: ReactJS Part II Flux Pattern & Redux
Architecting Single Activity Applications (With or Without Fragments)
What's new in jQuery 1.5
Ad

Viewers also liked (20)

PPT
Hayley Designers
PPT
Wdie 8 Sem2
PPT
Blogs For Moms
PDF
Usevertising, czyli reklama spotyka Design Thinking i co z tego wynika.
PPT
Building Windmills 2009: Personal Learning Networks
PPTX
Computer Games Based Learning in Schools: BETT 2010
PPT
Integratsioon mat. ja loodusained
PPT
$15 per Month Answering Service
PDF
Consultation on Zero Waste Regulations
PPT
The Awaited Savior
PPT
Cit 2008 Kindle I Phone Sdk
PPT
AOC Personalisation
PPT
Kokkuvõte 1
PPT
Jaka wartosc ma tresc blogow?
PPT
The Roles Of Scientists
PPT
恐龍愛玩耍 戴浩政
PPT
LACA Foundation in El Salvador
PPT
KeyNote Ulster
PPT
Fours And Fives
PPT
Mimas
Hayley Designers
Wdie 8 Sem2
Blogs For Moms
Usevertising, czyli reklama spotyka Design Thinking i co z tego wynika.
Building Windmills 2009: Personal Learning Networks
Computer Games Based Learning in Schools: BETT 2010
Integratsioon mat. ja loodusained
$15 per Month Answering Service
Consultation on Zero Waste Regulations
The Awaited Savior
Cit 2008 Kindle I Phone Sdk
AOC Personalisation
Kokkuvõte 1
Jaka wartosc ma tresc blogow?
The Roles Of Scientists
恐龍愛玩耍 戴浩政
LACA Foundation in El Salvador
KeyNote Ulster
Fours And Fives
Mimas
Ad

Similar to Build Widgets (20)

PDF
MVC pattern for widgets
PDF
Javascript MVC & Backbone Tips & Tricks
PPTX
Show Some Spine!
PDF
Viking academy backbone.js
PDF
Backbone.js: Run your Application Inside The Browser
PPTX
Taming that client side mess with Backbone.js
KEY
User Interface Development with jQuery
PPTX
Why react is different
PDF
mobl - model-driven engineering lecture
PPTX
Highload JavaScript Framework without Inheritance
PDF
Backbone
PDF
Introduction to Backbone.js
PDF
Architecting non-trivial browser applications (Jazoon 2012)
PDF
Rich Internet Applications con JavaFX e NetBeans
PPTX
Willow, the interaction tour by Maxi Tabacman
PPTX
Writing HTML5 Web Apps using Backbone.js and GAE
PPTX
Owl: The New Odoo UI Framework
PDF
YUI3 Modules
PDF
mobl presentation @ IHomer
PDF
Willow, the interaction tour
MVC pattern for widgets
Javascript MVC & Backbone Tips & Tricks
Show Some Spine!
Viking academy backbone.js
Backbone.js: Run your Application Inside The Browser
Taming that client side mess with Backbone.js
User Interface Development with jQuery
Why react is different
mobl - model-driven engineering lecture
Highload JavaScript Framework without Inheritance
Backbone
Introduction to Backbone.js
Architecting non-trivial browser applications (Jazoon 2012)
Rich Internet Applications con JavaFX e NetBeans
Willow, the interaction tour by Maxi Tabacman
Writing HTML5 Web Apps using Backbone.js and GAE
Owl: The New Odoo UI Framework
YUI3 Modules
mobl presentation @ IHomer
Willow, the interaction tour

More from scottw (20)

PPT
Getting the Maximum Benefit from Free and Open Source Software
PPT
How to engage students in real open source projects
PPT
Free, Libre and Open Source Software and Further Education
PDF
Open Forges and App Stores
PPT
Delivering Web To Mobile
PPT
Creating mobile web apps
PDF
Widgets and Mashups for Personal and Institutional Technologies
PDF
Open Source Junction: Apache Wookie and W3C Widgets
PDF
Dissemination beyond academic circles
PDF
Android
PDF
Wookie Intro
PPT
Wookie Meetup
PPT
Wookie Meetup
PPT
Life of a Wookie
PPT
CRM & HE
PDF
Presence
PDF
FeedForward at RSP
PPT
Boxcri
PDF
Widgets And Wookies
PPT
Widgets - the Wookie project
Getting the Maximum Benefit from Free and Open Source Software
How to engage students in real open source projects
Free, Libre and Open Source Software and Further Education
Open Forges and App Stores
Delivering Web To Mobile
Creating mobile web apps
Widgets and Mashups for Personal and Institutional Technologies
Open Source Junction: Apache Wookie and W3C Widgets
Dissemination beyond academic circles
Android
Wookie Intro
Wookie Meetup
Wookie Meetup
Life of a Wookie
CRM & HE
Presence
FeedForward at RSP
Boxcri
Widgets And Wookies
Widgets - the Wookie project

Recently uploaded (20)

PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
AI And Its Effect On The Evolving IT Sector In Australia - Elevate
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
cuic standard and advanced reporting.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPTX
Cloud computing and distributed systems.
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
madgavkar20181017ppt McKinsey Presentation.pdf
PDF
Chapter 2 Digital Image Fundamentals.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
KodekX | Application Modernization Development
PPTX
Understanding_Digital_Forensics_Presentation.pptx
“AI and Expert System Decision Support & Business Intelligence Systems”
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
AI And Its Effect On The Evolving IT Sector In Australia - Elevate
CIFDAQ's Market Insight: SEC Turns Pro Crypto
cuic standard and advanced reporting.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
Spectral efficient network and resource selection model in 5G networks
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Cloud computing and distributed systems.
The Rise and Fall of 3GPP – Time for a Sabbatical?
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
NewMind AI Monthly Chronicles - July 2025
madgavkar20181017ppt McKinsey Presentation.pdf
Chapter 2 Digital Image Fundamentals.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
KodekX | Application Modernization Development
Understanding_Digital_Forensics_Presentation.pptx

Build Widgets

  • 1. Lets Build Some Widgets!
  • 2. 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’re done
  • 3. Widget metadata • Id • Height, Width • Name • Description • Version • Features • Author info • License
  • 4. 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>
  • 5. A Silly Example: index.html <html> <body> <img src="tea.jpg" /> <p>Time for a break, mate</p> </body> </html>
  • 6. Make your own basic widget 1. Make an index.html file 2. Make a config.xml file 3. Zip them up, and change suffix to “.wgt” 4. Upload to a wookie server
  • 7. Uploading • Go to http://192.168.2.161/wookie • Click “admin” • Login with java/java • Click “add new widget” • Find your .wgt file • OK!
  • 8. 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
  • 9. Preferences • You can store preferences for an instance of a widget using: widget.preferences.setItem(“key”, “value”) widget.preferences.getItem(“key”)
  • 10. Collaborative Widgets • State and Participants • State is shared across widgets with the same IRI in the same shared context. • State is propagated to related widgets using an event callback • State is set by submitting deltas
  • 11. State example wave.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”);
  • 12. Participants • Register callbacks with: wave.setParticipantCallback(myfunction); • Methods: – getViewer() - get the current user – getParticipants() - get map of all participants • Model: – getId(), getDisplayName(), getThumbnailUrl()
  • 13. Making a collaborative app • This requires some more planning 1. Draw up a design 2. Create a working test page 3. Implement models, action handlers and event handlers 4. Create the config.xml, icon.png, zip it up and run it
  • 14. Design • Start with the view - what the widget looks like • Create the model - what are the objects in the state model? • Add the actions - how you interact with it • Wire it all up…
  • 16. Prototyping • Make a regular html page to test out your view. Populate it with fake model, and don’t wire up the actions yet • You can reuse this for the real widget - just take out your fake state info sections
  • 17. Implementing • Create a “Model” object for your state model • Create a “Controller” object, and a method in it for each action • Register the participant and state event handlers with an “update view” method that populates the view when running
  • 18. 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 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)); }
  • 19. Static model methods 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; • Typically need } methods to turn state Task.find = function(task_id){ var keys = wave.getState().getKeys(); for (var i = 0; i < keys.length; i++) { strings back into var key = keys[i]; if (key == task_id){ model instances return Task.create(task_id, wave.getState().get(key)); } } • Also finder methods to } return null; get a particular model Task.findAll = function(){ object var tasks = {}; var keys = wave.getState().getKeys(); for (var i = 0; i < keys.length; i++) { • This isn’t the only way var key = keys[i]; var task = Task.create(key, wave.getState().get(key)); tasks[key] = task; to do this, but is an } return tasks; OK pattern }
  • 20. Controllers /** * The Controller object * This is used to wire up the view and model with actions • Methods for each */ var Controller = { action, making // Action handlers changes to the model // Toggle task state between completed and to-do toggleTask: function(task_id){ • You usually don’t }, need to do any code // Create a new task newTask: function(){ }, that interacts with // Abandon task for someone else to do HTML, as the event abandonTask: function(task_id){ }, handlers should do // Claim a task (assign to self) claimTask: function(task_id){ that } }
  • 21. Event Handlers // Update the view when state has been updated These fire whenever the state or participants stateUpdated: function(){ are updated (e.g. by another instance). var tasks = Task.findAll(); if (tasks && tasks != null){ var tasklist = ""; Event handlers need to be registered like so: for (key in tasks) { var task = tasks[key]; wave.setStateCallback(Controller.stateUpdated); wave.setParticipantCallback(Controller.participantsUpdated); tasklist += // the task stuff to show dwr.util.setValue("tasklist", tasklist, { escapeHtml:false }); Also useful to have these methods called var objDiv = document.getElementById("tasklist"); from onLoad() in an init() function to objDiv.scrollTop = objDiv.scrollHeight; create initial view } }, participantsUpdated: function(){ You can import JQuery if you like for Controller.updateUser(); setting the view content, or do it using } DOM
  • 22. Packaging You need to add this to your config.xml to tell Wookie to include the Wave Gadget API methods: <feature name="http://wave.google.com" required="true"/>
  • 23. Uploading, debugging and testing • You need a • I’ve set up a Moodle collaborative instance at: environment to test your widget properly 192.168.2.XXX Login as ws1,ws2,ws3, or ws4
  • 24. Other stuff… • AJAX • Camera access If you want to call If you want to access the external sites from user’s camera from a within the widget, call widget, there is an myurl = example of how to do widget.proxify(url) first to call it via proxy. this in the moodle Also need to add the course (topic 3) site to the server whitelist.