PDA

View Full Version : Wizard like dialog



tinezorko
28 Dec 2006, 6:08 AM
I am desperately trying to implement a dialog which would act like a wizard. The dialog should be capable of capturing user keyboard input on certain pages. Pages should be based on pre-defined templates.

BTW: User interface must be highly customizable since the application is intended to be used on touch screens.

I am looking for a better and / or easier approach. I am not very comfortable with JS OOP paradigm yet.

This is an excerpt of what I have done:

function CardReaderDlg(id)
{
//private vars
var dlg;
var readBuffer;
var pinRetries = 0;
var isReading = "";
var authURL = "auth.php";

//constructor
{
readBuffer = "";
step = 1;

dlg = new YAHOO.widget.Panel
(
id,
{
width: "450px",
height: "280px",
fixedcenter: true,
constraintoviewport: true,
overlay: "shadow",
close: false,
visible: false,
draggable: false,
modal: true,
effect:
{
effect: YAHOO.widget.ContainerEffect.FADE,
duration: 0.5
}
}
);
dlg.render();

}

this.getId = function() { return dlg.id; }

this.open = function()
{
this.readCard();
dlg.show();
}

this.close = function()
{
dlg.hide();
}

var setPage = function(pageNum, obj)
{
switch (pageNum)
{
default:
pageNum = 1;
dlg.setBody(App.getPreLoadedTemplate(dlg.id).applyTemplate(
{
image : '',
prompt : 'Pristavite kartico k čitalcu!'
})); break;
case 2:
dlg.setBody(App.getPreLoadedTemplate(dlg.id).applyTemplate(
{
image : '<input type="password" class="input" id="' + dlg.id + '_input"/>',
prompt : 'Vnesite pin!'
}));
var el = document.getElementById("_tmp");
el.focus();
break;
case 3:
dlg.setBody(App.getPreLoadedTemplate(dlg.id).applyTemplate(
{
imgage : '',
prompt : 'Napačen pin! ?tevilo preostalih poizkusov: ' + pinRetries
})); break;
}
dlg.render();
}

this.readCard = function()
{
setPage(1, this);
startReading("card", this);
}

this.readPin = function()
{
setPage(2, this);
startReading("pin", this);
}

var onKeyUp = function(evt, obj)
{
if (evt.keyCode == 13 && readBuffer.length > 0)
{
var buff = readBuffer;
var type = isReading;
stopReading(obj);
switch(type)
{
case "card":
setTimeout(function() { obj.onCardRead(buff, obj); }, 0);
break;
case "pin":
setTimeout(function() { obj.onPinRead(buff, obj); }, 0);
break;
}
} else if (evt.keyCode == 27)
{
obj.close();
}
else if (evt.keyCode != 13)
{
readBuffer += String.fromCharCode(evt.keyCode);
}
}

var stopReading = function(obj)
{
if (isReading == "")
return;
isReading = "";
YAHOO.util.Event.removeListener(document, "keyup", onKeyUp);
}

var startReading = function(what, obj)
{
if (isReading != "")
return;
readBuffer = "";
isReading = what;
YAHOO.util.Event.addListener(document, "keyup", onKeyUp, obj, true);
}

this.onCardRead = function(cardId, dlg)
{
alert("Card read on dlg '" + dlg.getId() + "': " + cardId);
dlg.readPin();
}

this.onPinRead = function(pinCode, dlg)
{
alert("PIN read on dlg '" + dlg.getId() + "': " + pinCode);
dlg.close();
}
}

function Authentication()
{
var handleSuccess = function(o)
{
this.onAuthenticationComplete(o.responseXML.getElementsByTagName("response")[0]);
};

var handleFailure = function(o)
{
alert("Failure: " + o);
};

this.onAuthenticationComplete = function(responseXMLNode)
{
var code = responseXMLNode.childNodes[0].textContent;
var text = responseXMLNode.childNodes[1].textContent;
alert("Code: " + code + ", Text: " + text);
};

this.startRequest = function(authURL, cid, pin)
{
YAHOO.util.Connect.asyncRequest('POST', authURL,
{
success: handleSuccess,
faulure: handleFailure,
scope: this,
timeout: 5000
}, "cid=" + cid + "&pin=" + pin);
}
}

// FUNCTIONS

// Helpers
function hasAttribute(obj, attribute)
{
return (obj.attributes[attribute]);
}

// MAIN
var App = new function()
{
var cardReaderDlg;
var authDlgContent = new Array();
var authDlgPage = "";
var preLoadedImages = new Array();
var preLoadedTemplates = new Array();
var authData = { id: "", pin: ""};
var authProc = new Authentication();

this.getCardReaderDlg = function() { return cardReaderDlg; }

this.preLoadImage = function(name, src)
{
preLoadedImages["name"] = new Image();
preLoadedImages["name"].src = src;
}

this.preLoadImages = function(imgs)
{
for (var i=0; i<imgs.length; i++)
this.preLoadImage(imgs[i].name, imgs[i].src);
}

this.getPreLoadedImage = function(name) { return preLoadedImages[name]; }

this.preLoadTemplates = function()
{
var root = this.preLoadTemplates.arguments.length >= 2 ? preLoadTemplates.arguments[1] : document.body;
var compile = this.preLoadTemplates.arguments.length >= 2 ? preLoadTemplates.arguments[2] : false;

var tmplObjs = YAHOO.util.Dom.getElementsBy(function(obj) { return hasAttribute(obj, "template"); }, "div", root);
for (var i=0; i<tmplObjs.length; i++)
{
var name = tmplObjs[i].attributes["template"].value;
preLoadedTemplates[name] = new YAHOO.ext.DomHelper.Template(tmplObjs[i].innerHTML);
if (compile) preLoadedTemplates[name].compile();
//hide template object
//YAHOO.util.Dom.setStyle(tmplObjs[i], "visibility", "hidden");
}
}

this.getPreLoadedTemplate = function(name) { return preLoadedTemplates[name]; }

var onAuthenticationComplete = function(responseXMLNode)
{
var token = responseXMLNode.getElementsByTagName("token")[0].textContent;
if (token)
{
alert(token);
cardReaderDlg.close();
} else
{
alert("Napačni podatki!");
cardReaderDlg.readCard();
}
}

this.main = function(evt, args)
{
//preloading and compiling templates
App.preLoadTemplates();

//authentication
authProc.onAuthenticationComplete = function(responseXMLNode)
{
onAuthenticationComplete(responseXMLNode);
}

//card reader dlg

cardReaderDlg = new CardReaderDlg(args["cardReaderDlgId"]);
cardReaderDlg.onCardRead = function(cardId, dlg)
{
authData.id = cardId;
dlg.readPin(dlg);
};
cardReaderDlg.onPinRead = function(pin, dlg)
{
authData.pin = pin;
authProc.startRequest("auth.php", authData.id, authData.pin);
};
cardReaderDlg.open();
}
};

------------------------------ HTML ----------------------------------
<div id="cardreaderdlg"></div>
<div template="cardreaderdlg">
<table border="0" width="100%" height="100%">
<tr height="100%"><td align="center" colspan="2">
{image}
</td></tr><tr><td width="100%">
{prompt}
</td><td>
<input type="button" value="Prekliči" onClick="App.getCardReaderDlg().close()"/>
</td></tr>
</table>
</div>

------------------------------- CSS ----------------------------------
#cardreaderdlg.panel
{
border: 2px solid #999;
padding: 1em;
-moz-border-radius: 1em;
background: #FFF;
}

.panel-container.shadow .underlay
{
-moz-border-radius: 1em;
top:3px;left:-3px;
}

div[template]
{
visibility: hidden;
z-index: 99999;
position: absolute;
}