
![]() |
This tutorial will assist you with the steps of the widget development process using a simple widget. Step 1: Preparation Step 2: Basic Widget Functionality Step 3: Advanced Applications |
Lesson 8: Adding a search function
Let's add a search function like we saw in the completed simple widget.

Download Sample7.mylow from here
widgetPackage.xml
It would be strange if the height of the widget was resizable after the search box is added, so we're going to make it so that only the widget's width can be changed.
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright 2008 Sony Electronics Inc. --> <widgetPackage xmlns="http://xmlns.sony.net/mylo/widget" version="1.0"> <info> <packageName>Sample Widget 7</packageName> <author>Sony Electronics Inc.</author> <abstract>This is Sample 7 from the tutorial</abstract> <version>1.0</version> <locale>US</locale> <engine>1.0</engine> <updateURL></updateURL> <siteURL>http://www.sony.com/mylo</siteURL> <minWidth>21</minWidth> <maxWidth>66</maxWidth> <defWidth>21</defWidth> <defHeight>17</defHeight> <createDate>2008-02-02</createDate> </info> </widgetPackage>
myloConfig.xml
Here we'll add the setting of the searchURL (hidden) and the search category. Since the searchURL is too long, it is omitted below. However, please note that is important to use "&" instead of "&" in your preference files, otherwise the Widget Setting mode may not function correctly.
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright 2008 Sony Electronics Inc. --> <config xmlns="http://xmlns.sony.net/mylo/widget" version="1.0"> <item name="searchURL" type="text" visible="off"> <value>http://www.google.com/</value> </item> <item title="Search Category" name="cat" type="select" comment="Select the search category"> <option value="search">Web</option> <option value="images">Images</option> <option value="books">Books</option> <option value="products">Products</option> <option value="maps">Maps</option> <option value="news">News</option> <value>Web</value> <default>Web</default> </item> <item title="Update Interval" name="frequency" type="select" comment="Set the banner image update interval"> <option value="60000">1 Minute</option> <option value="300000">5 Minutes</option> <option value="600000">10 Minutes</option> <option value="1800000">30 Minutes</option> <option value="3600000">1 Hour</option> <option value="0">Do not update automatically</option> <value>1 Minute</value> <default>1 Minute</default> </item> </config>
index.html
Add the text box for search, category display, and a DIV for the search button.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="copyright" content="Copyright 2008 Sony Electronics Inc."> <title>Google Banner</title> <!-- mylo screen library --> <script type="text/javascript" src="/js/lib/WidgetLibrary.js"></script> <script type="text/javascript" src="/js/lib/ExtensionLibrary.js"></script> <script type="text/javascript" src="/js/lib/PreferencesLibrary.js"></script> <!-- mylo screen library --> <script type="text/javascript" src="code.js"></script> <link rel="stylesheet" href="style.css" type="text/css" /> </head> <body onload="init();"> <div id="baseAll"> <div id="baseTopLeft"></div> <div id="baseTopCenter"></div> <div id="baseTopRight"></div> <div id="baseMiddleLeft"></div> <div id="baseMiddleCenter"></div> <div id="baseMiddleRight"></div> <div id="baseBottomLeft"></div> <div id="baseBottomCenter"></div> <div id="baseBottomRight"></div> <div id="searchTitle"></div> <input type="text" id="textBox" size="5" maxlength="128"> <input type="image" id="searchButton" src='images/bt_search_disable.png'> <img id="baseImg" src="images/google1.png" onclick="extension.openWeb(searchURL);"> </div> </body> </html>
style.css
Here we set the attributes for each DIV element with our stylesheet. We will be changing these attributes of the stylesheet from the Javascript code to resize the widget.
/*
* Copyright 2008 Sony Electronics Inc.
*/
body{
top: 0px;
left: 0px;
margin: 0px;
padding: 0px;
}
#baseImg {
margin: 0px;
position: absolute;
top: 12px;
left: 12px;
}
#baseAll {
margin: 0px;
position: absolute;
top: 0px;
left: 0px;
visibility: hidden;
}
#baseTopLeft {
background-repeat: no-repeat;
background-color: transparent;
background-image:url(images/base_top_left.png);
margin: 0px;
position: absolute;
top: 0px;
left: 0px;
height: 12px;
width: 12px;
}
#baseTopCenter {
background-repeat: repeat-x;
background-color: transparent;
background-image:url(images/base_top_center.png);
margin: 0px;
position: absolute;
top: 0px;
left: 12px;
height: 12px;
width: 0px;
}
#baseTopRight {
background-repeat: no-repeat;
background-color: transparent;
background-image:url(images/base_top_right.png);
margin: 0px;
position: absolute;
top: 0px;
left: 12px;
height: 12px;
width: 12px;
}
#baseMiddleLeft {
background-repeat: repeat-y;
background-color: transparent;
background-image:url(images/base_middle_left.png);
margin: 0px;
position: absolute;
top: 12px;
left: 0px;
height: 0px;
width: 12px;
}
#baseMiddleCenter {
background-repeat: repeat;
background-color: #FFFFFF;
margin: 0px;
position: absolute;
top: 12px;
left: 12px;
height: 0px;
width: 0px;
}
#baseMiddleRight {
background-repeat: repeat-y;
background-color: transparent;
background-image:url(images/base_middle_right.png);
margin: 0px;
position: absolute;
top: 12px;
left: 12px;
height: 0px;
width: 12px;
}
#baseBottomLeft {
background-repeat: no-repeat;
background-color: transparent;
background-image:url(images/base_bottom_left.png);
margin: 0px;
position: absolute;
top: 12px;
left: 0px;
height: 12px;
width: 12px;
}
#baseBottomCenter {
background-repeat: repeat-x;
background-color: transparent;
background-image:url(images/base_bottom_center.png);
margin: 0px;
position: absolute;
top: 12px;
left: 12px;
height: 12px;
width: 0px;
}
#baseBottomRight {
background-repeat: no-repeat;
background-color: transparent;
background-image:url(images/base_bottom_right.png);
margin: 0px;
position: absolute;
top: 12px;
left: 12px;
height: 12px;
width: 12px;
}
#searchTitle {
background-color: #FFFFFF;
font-size: 20px;
text-align: center;
color: black;
overflow: hidden;
margin: 0px;
position: absolute;
top: 12px;
left: 12px;
height: 36px;
}
#searchButton {
background-repeat: no-repeat;
background-color: transparent;
background-image:url(images/bt_search_disable.png);
margin: 0px;
position: absolute;
}
#textBox {
font-size: 20px;
color: #333333;
background-color: #ffffff;
border:none;
margin: 0px;
position: absolute;
left: 12px;
height: 32px;
}
code.js
Write the behavior of the widget when it enters Focus mode by defining "inFocus()" and "outFocus()" functions. In this widget, the search button is grayed out in Active mode. The search function is activated only when it is focused. When it is out of focus, the textbox will be cleared out and the button will be grayed out.
/*
* Copyright 2008 Sony Electronics Inc.
*/
var extension = new Extension();
var jumpURL;
var searchURL;
var catName;
var frequency = 0;
var currentImg = 0;
var searchCategory;
var foregroundTimer;
var backgroundTimer;
var baseAll;
var baseTopLeft;
var baseTopCenter;
var baseTopRight;
var baseMiddleLeft;
var baseMiddleCenter;
var baseMiddleRight;
var baseBottomLeft;
var baseBottomCenter;
var baseBottomRight;
var baseImg;
var searchTitle;
var textBox;
var searchButton;
var numImage = 4;
/**
* Initialization
*/
var init = function() {
prefObject = new Preferences(prefCallback);
baseAll = document.getElementById('baseAll');
baseTopLeft = document.getElementById('baseTopLeft');
baseTopCenter = document.getElementById('baseTopCenter');
baseTopRight = document.getElementById('baseTopRight');
baseMiddleLeft = document.getElementById('baseMiddleLeft');
baseMiddleCenter = document.getElementById('baseMiddleCenter');
baseMiddleRight = document.getElementById('baseMiddleRight');
baseBottomLeft = document.getElementById('baseBottomLeft');
baseBottomCenter = document.getElementById('baseBottomCenter');
baseBottomRight = document.getElementById('baseBottomRight');
baseImg = document.getElementById('baseImg');
searchTitle = document.getElementById('searchTitle');
searchButton = document.getElementById('searchButton');
textBox = document.getElementById('textBox');
textBox.maxLength = 128;
setWindow();
baseAll.style.visibility = 'visible';
notifyReadyWidget();
}
/**
* Acquire preferences
*/
var prefCallback = function() {
var _i;
var _frequency;
var _cat;
var _prevTimer;
_prevTimer = frequency;
jumpURL = prefObject.getValueByName('jumpURL');
searchURL = prefObject.getValueByName('searchURL');
catName = prefObject.getValueByName('cat');
searchTitle.innerHTML = catName;
_cat = prefObject.getItemByName('cat');
for (_i = 0; _i < _cat.options.length; _i++) {
if (catName == _cat.options[_i].text) {
searchCategory = _cat.options[_i].value;
}
}
_frequency = prefObject.getItemByName('frequency');
for (_i = 0; _i < _frequency.options.length; _i++) {
if (prefObject.getValueByName('frequency') == _frequency.options[_i].text) {
frequency = parseInt(_frequency.options[_i].value);
}
}
if (_prevTimer != frequency) {
unsetTimers();
if (frequency > 0) {
setTimers();
}
}
textFieldClear();
notifyReadyWidget();
return prefObject;
};
/**
* When the preference starts, run the callback
*/
var getPreferenceObject = function() {
return prefObject;
}
/**
* When the preference ends, run the callback
*/
var changePreference = function(prefObject, updateFlag) {
if (updateFlag == true){
extension.saveFile(Extension.fileType.CONFIG, saveCallback, prefObject.save());
prefCallback();
}
return;
}
/**
* When the preference is saved, run the callback
*/
var saveCallback = function() {};
/**
* Resize handler
*/
var widgetResize = function() {
setWindow();
}
/**
* Deactivate/cancel the timer
*/
var unsetTimers = function() {
if(foregroundTimer) {
clearInterval(foregroundTimer);
foregroundTimer = undefined;
}
if(backgroundTimer) {
clearBackgroundInterval(backgroundTimer);
backgroundTimer = undefined;
}
};
/**
* Set the timer
*/
var setTimers = function() {
unsetTimers();
foregroundTimer = setInterval(callbackForegroundTimer, frequency);
backgroundTimer = setBackgroundInterval(callbackBackgroundTimer, frequency);
};
/**
* Foreground timer arrangement/process
*/
var callbackForegroundTimer = function() {
redrawBanner();
};
/**
* Background timer arrangement/process
*/
var callbackBackgroundTimer = function() {
redrawBanner();
};
/**
* Widget Resize
*/
var setWindow = function() {
baseTopCenter.style.width = (windowWidth - 24) + 'px';
baseMiddleCenter.style.width = (windowWidth - 24) + 'px';
baseBottomCenter.style.width = (windowWidth - 24) + 'px';
baseMiddleLeft.style.height = (windowHeight - 24) + 'px';
baseMiddleCenter.style.height = (windowHeight - 24) + 'px';
baseMiddleRight.style.height = (windowHeight - 24) + 'px';
baseTopRight.style.left = (windowWidth - 12) + 'px';
baseMiddleRight.style.left = (windowWidth - 12) + 'px';
baseBottomRight.style.left = (windowWidth - 12) + 'px';
baseBottomLeft.style.top = (windowHeight - 12) + 'px';
baseBottomCenter.style.top = (windowHeight - 12) + 'px';
baseBottomRight.style.top = (windowHeight - 12) + 'px';
baseImg.style.left = (windowWidth / 2 - 78) + 'px';
baseImg.style.top = (windowHeight / 2 - 45) + 'px';
searchTitle.style.width = (windowWidth - 24) + 'px';
searchButton.style.top = (windowHeight - 48) + 'px';
searchButton.style.left = (windowWidth - 86) + 'px';
textBox.style.top = (windowHeight - 48) + 'px';
textBox.style.width = (windowWidth - 100) + 'px';
};
/**
* Redraw banner
*/
var redrawBanner = function() {
if (++currentImg >= numImage) {
currentImg = 0;
}
switch (currentImg) {
case 0:
baseImg.src = 'images/goog1e1.png';
break;
case 1:
baseImg.src = 'images/goog1e2.png';
break;
case 2:
baseImg.src = 'images/goog1e3.png';
break;
case 3:
baseImg.src = 'images/goog1e4.png';
break;
}
};
/**
* Key handler
*/
var widgetKeyDown = function(evt, key) {
switch (key) {
case mylo.KeyCode.EXE:
searchAndOpenWindow();
textFieldClear();
return false;
break;
case mylo.KeyCode.BACK:
textFieldClear();
return true;
break;
}
}
/**
* When the widget is in focus
*/
var inFocus = function() {
readyInput();
}
/**
* When it is out of focus
*/
var outFocus = function() {
textFieldClear();
}
/**
* Clear out the textbox
*/
var textFieldClear = function() {
textBox.blur();
textBox.value = '';
searchButton.src = 'images/bt_search_disable.png';
searchButton.onclick = function(){return true};
searchButton.onmousedown = function(){};
searchButton.onmouseup = function(){};
searchButton.style.backgroundImage = 'url("images/bt_search_disable.png")';
}
/**
* Ready for entering words in the textbox
*/
var readyInput = function() {
searchButton.src = 'images/bt_search_normal.png';
searchButton.onclick = function(){
searchAndOpenWindow();
return false;
};
searchButton.onmousedown = function(){
this.src='images/bt_search_push.png';
searchButton.style.backgroundImage = 'url("images/bt_search_normal.png")';
};
searchButton.onmouseup = function(){
this.src='images/bt_search_normal.png';
};
textBox.focus();
}
/**
* The process when the form is submitted, search and display the new window
*/
var searchAndOpenWindow = function() {
var _text = textBox.value;
if (_text.length > 128) {
_text = _text.substring(0,128);
}
var _url = searchURL + searchCategory + '?q=' + _text;
if (_text.length > 0) {
extension.openWeb(_url);
}
}

