import mx.collections.ArrayCollection;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import packages.DominoUtilities.*;
import packages.SQLFunctions;
import spark.components.View;
import views.PB_QBookStoreDetails;
import views.PB_QBookStoreHome;
/***
* project specific declarations
***/
/*
NOTE:
-----
This is _NOT_ the declarations set which is implemented in the productive demos you can download at our homepage.
It should just show you a set of the related information which you need in your development.
Please make sure you set the foreslash ("/" in _WSRVDB) in front of your Webservice database path, but _NOT_ in front of your
designated source database (_DOMSRCDB).
*/
[Bindable] public var _ROOTURL :String = "http://domino.flexdomino.net";
[Bindable] public var _WSRVDB :String = "/soapgateQ.nsf";
[Bindable] public var _DOMSRV :String = "SERVERNAME/CERTIFIER";
[Bindable] public var _DOMSRCDB :String = "demo.nsf";
[Bindable] public var _USER :String = "demo";
[Bindable] public var _PASSW :String = "demo";
[Bindable] public var _DATA :ArrayCollection;
/***
* webservice / component specific declarations
***/
[Bindable] public var DBUTIL :DominoDBUtilities;
[Bindable] public var DBWSRV :DominoWebService;
[Bindable] public var DBFORM :DominoFormUtilities;
[Bindable] public var DBVIEW :DominoViewUtilities;
/***
* local objects
***/
[Bindable] public var VIEWDATA_AC :ArrayCollection;
[Bindable] public var VIEWDATA_XML :XMLList;
public var coverURL :String;
public var UnID :String;
public var dataArrColl :ArrayCollection;
public var firstAppCall :Boolean = true;
public var lastView :Class;
[Bindable] public var ITEM :Array;
[Bindable] public var FORMDATA :Array = [
"Book_Title",
"Book_Author",
"Book_Year",
"Book_Genre",
"Book_Price",
"Book_Summary"
];
[Bindable] public var infoText:String ="This application is based on\nAdobe AIR 2.5.\n\n" +
"It uses the SoapgateQ! Webservice API for Domino.\n\n" +
"This Bookstore-Demo shows you the functionality of the SoapgateQ! Webservice API in association with our Adobe Flex libaries.\n"+
"Visit www.qkom.net to see more demos.";
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="PB_QBookStoreSplashscreen">
<fx:Script source="../scripts/Globals.as"/>
<s:Image source="../img/Bookstore.png"
x="0" y="0"
width="100%" height="100%"/>
<s:Button click="{navigator.pushView(PB_QBookStoreHome)}"
x="134" y="252"
width="290" height="71"
label="Load application"/>
<s:Label fontSize="18"
x="665" y="125"
width="320"
height="250"
fontFamily="_sans"
text="{infoText}" />
</s:View>
<?xml version="1.0" encoding="utf-8"?>
<!--
/***
* RIM Blackberry Tablet OS
* PlayBook Demo
* - /tschweitzer@qkom.de
* - /dley@qkom.de
*
* Q!kom - www.qkom.de
* Flexdomino - www.flexdomino.net
*
* Copyright (c) 2010 - QKom GmbH
***/
-->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="initSessView()">
<fx:Script >
<![CDATA[
import mx.rpc.events.InvokeEvent;
include "../scripts/Globals.as";
private var selecteItem:Object;
private var rowAC:ArrayCollection;
private var tempAC:ArrayCollection = new ArrayCollection();
private var UniqueID:String;
/************************************************************************************
* Function will be excecuted on creationComplete-Event of this view.<br>
* If "data" is null, the application/view is started for the first time and the
* webservice will be called.
* <br><br>
* "data" is not null means this view was called from the "PB_QBookStoreDetails"-view
* and contains the listdata (result from dbColumnX)
************************************************************************************/
public function initSessView():void
{
if(data != null)
{ //if data is not null, webservice will be called
//without authentification
loadViaWebService(false,getViewData);
}
else
{ //if data is null, webservice will be called
//with authentification
loadViaWebService(true,initApplication);
}
}
/************************************************************************************
* Function to load the webservice-object.
* @param authent - indicates if webservice should authent against the server or not
* @param callbackFunction - the function called when the webservice is initialized
************************************************************************************/
private function loadViaWebService(authent:Boolean, callbackFunction:Function):void
{
DBWSRV = new DominoWebService(
_ROOTURL,
_ROOTURL + _WSRVDB,
false,
authent,
_USER,
_PASSW,
callbackFunction,
operationFaultHandler,
null,
10
);
}
/************************************************************
*If application was started for the first time, we need to
*grab data from domino.
***********************************************************/
private function initApplication(event:Event):void
{
DBUTIL = new DominoDBUtilities();
DBUTIL.wsrv = DBWSRV;
DBUTIL.customfaulthandler = operationFaultHandler as Function;
DBUTIL.customlistener = getViewData;
DBUTIL.dbcolumnx
(
_DOMSRV,
_DOMSRCDB,
"books.flat",
["0","1","2","3","4","5","6"],
true,
0,
true,
"",
0
);
}
/********************************************************************************************
* If the data-object is null this function serves as result-handler
* for our dbcolumnx call.<br><br>
*
* If data is not null, it checks if the user clicked the save-button(in the details-view)
* to save changed formfields/details.
********************************************************************************************/
private function getViewData(event:Event = null, e:Event = null):void
{
if (!data)
{
tempAC = DBUTIL.resultAC;
setListData();
}
else
{
DBUTIL = new DominoDBUtilities();
DBUTIL.wsrv = DBWSRV;
tempAC = data[0]["resultACReturn"] as ArrayCollection;
/*checks if the user clicked the save-button
if yes the function "saveDocFields" will be called
if not the list will be filled with the old dbcolumnx-return*/
(data[0]["savedocFieldReturn"]!="nosave")?saveDocFields():setListData();
}
}
/*********************************************************
* This function will fill our list with data.<br><br>
* <b>Either</b> <br>
* with a new dbcolumnx-return <br>
* <b>or</b> <br>
* with an old dbcolumnx-return <br>
* <b>or</b> <br>
* with a "userchanged" dbcolumnx-return
********************************************************/
private function setListData():void
{
VIEWDATA_AC = new ArrayCollection();
var ACarray:Array;
tempAC.refresh();
var i:int;
for(i=0; i<tempAC.length; i++)
{
ACarray = tempAC[i] as Array;
VIEWDATA_AC.addItem
({
"title": ACarray[3].toString(),
"category": ACarray[0].toString(),
"year": ACarray[1].toString(),
"author": ACarray[2].toString(),
"unid": ACarray[8].toString(),
"coverURL": ACarray[6].toString().replace("booking.esemalta.com","flashdomino.de")
});
}
VIEWDATA_AC.refresh();
}
/**********************************************************
* Sets the global variable "coverURL" to the cover-url
* from the selected item. <br><br>
*
* After that the function "listClickHandler" will called
* which gets the unique-ID of the selected/clicked entry.
**********************************************************/
private function setItem():void
{
if(booksList.selectedItem != null && selecteItem == null)
{
selecteItem = booksList.selectedItem;
if(String(selecteItem.unid).length > 1)
{
coverURL = selecteItem.coverURL;
listClickHandler(selecteItem.unid);
}
}
}
/******************************************************
* Calls the dbreaddocfields method.<br>
* The form, we want to read out, will be identified
* by the selected UNID(unique id).
* @param UNID - The unique id of the selected entry
******************************************************/
public function listClickHandler(UNID:String):void
{
UnID = UNID;
//if dbreaddocfields succeded, this "customlistener-function" will be called.
DBUTIL.customlistener = readDocFieldsResult as Function;
DBUTIL.customfaulthandler = operationFaultHandler as Function;
DBUTIL.dbreaddocfields
(
_DOMSRV,
_DOMSRCDB,
"books.flat",
UNID, //selected unique-id
FORMDATA //list of fields, to be read
);
}
/************************************************************************************
* If dbreaddocfields succeded, this function will be called.<br><br>
* It adds the selected unique-id, <br>
* the selected cover-url,<br>
* the dbreaddocfields result and the dbcolumnx result to an arraycollection <br>
* and passes this collection to the details-view, which will be pushed.
************************************************************************************/
public function readDocFieldsResult(event:ResultEvent):void
{
//result from dbreaddocfields
var resultObject:ArrayCollection = event.result.DBREADDOCFIELDSReturn as ArrayCollection;
//arraycollection which will be passed to th edetailsview
var dataToPush:ArrayCollection = new ArrayCollection();
resultObject.addItem(coverURL);
resultObject.addItem(UnID);
dataToPush.addItem({
"docfieldResult":resultObject,
"mainResult":tempAC
});
navigator.pushView(PB_QBookStoreDetails,dataToPush);
selecteItem = null;
}
/********************************************************************************************
* Function to save the changed document fields.<br>
* It will be called if the user clicked the "save-button" in the detailsview.<br><br>
* "dataArrCall" will get values of all textinput´s in the detailsview.<br>
* The "dbsavedocfields" method will save this values into the same form we read out before.
********************************************************************************************/
public function saveDocFields():void
{
//return from the detailsview
dataArrColl = data[0]["savedocFieldReturn"] as ArrayCollection;
if(dataArrColl.length > 1)
{
var dataArr:Array = dataArrColl.getItemAt(0) as Array;
DBUTIL.customlistener = callRowX;//If we changed the title || genre,
//we have to update the row in our list.
//the selected unique id, we passed into the detailsview before
UniqueID = dataArrColl[1].toString();
DBUTIL.dbsavedocfields
(
_DOMSRV,
_DOMSRCDB,
UniqueID,
FORMDATA,
[1280,1280,1280,1280,1280,1280],
dataArr,//Formfields to save
"Book",
true,
""
);
}
}
/****************************************************************************
* This function will call a dbrowx to get values of <b>one</b> row.<br>
* In this case we have to update the row which details were changed.<br>
****************************************************************************/
private function callRowX(event:ResultEvent):void//and again our selected unique id
{
DBUTIL.customlistener = rowxReturn;
DBUTIL.dbrowx(_DOMSRV,_DOMSRCDB,"books.flat",["0","3"],true,0,UniqueID);
}
/*******************************************************************
* The result from dbrowx will parsed into an arraycollection.
*****************************************************************/
private function rowxReturn(event:ResultEvent):void
{
rowAC = event.result.DBROWXReturn as ArrayCollection;
updateRow();
}
/********************************************************
* This will replace the title && genre of the rowentry
* which needs to be updated.
********************************************************/
private function updateRow():void
{
var u:int;
for(u=0; u<tempAC.length; u++)
{
if(rowAC != null && rowAC.length > 1)
{
//tempAC[u] = one row in our list.
//tempAC[u][7] = the unique id of row u.
if(tempAC[u][8].toString() == rowAC[3].toString())//rowAC[2] = unique id of the row
{ //need to be updated
tempAC[u][0] = rowAC[0];
tempAC[u][3] = rowAC[1];
}
}
}
//and now the function to fill the list will be called.
setListData();
}
/****************************************************************
* Function to trace the error message, if something went wrong.
****************************************************************/
private function operationFaultHandler(event:FaultEvent):void
{
trace("[ERROR] "+event.fault.faultString);
}
/******************************************************************************
* Searchfunction<br>
* It will check the index of title && genre/category (from each listentry)
* for the string the user typed into the searchfield.<br>
* Index > 1 means the searchstring was found.
* <br><br>
* For more details check Adobe´s "arraycollection-filterFunction".
****************************************************************************/
private function AC_Filter(item:Object):Boolean
{
var searchString:String;
searchString = inputSearch.text.toLowerCase();
var searchStringFound:Boolean =
(item.title.toString().toLowerCase().indexOf(searchString)>-1)
||
(item.category.toString().toLowerCase().indexOf(searchString)>-1);
return searchStringFound;
}
]]>
</fx:Script>
<!-- - - - - - - - - - - - - UI components - - - - - - - - - - - - - - - - - - - - -->
<s:Panel id="homePanel"
left="10" right="10"
top="10" bottom="10"
backgroundColor="#3F3F3F"
fontSize="16"
title="Book store:">
<!-- Search inputfield-->
<s:TextInput id="inputSearch"
y="8"
left="10" right="10"
change="VIEWDATA_AC.filterFunction = AC_Filter; VIEWDATA_AC.refresh()"
click="VIEWDATA_AC.filterFunction = AC_Filter; inputSearch.text = ''"
enabled="true"
fontStyle="normal"
fontWeight="normal"
text="Search term"/>
<s:HGroup left="10" right="10" top="63" bottom="10">
<s:List borderColor="0x000000"
click="setItem()"
borderVisible="true"
width="100%"
height="100%"
id="booksList"
fontSize="12"
textAlign="left"
selectionColor="#42596c"
dataProvider="{VIEWDATA_AC}" >
<!-- An itemrenderer to style the listentrys -->
<s:itemRenderer >
<fx:Component><!-- For mobile devices you need a "MobileIconRenderer" -->
<s:MobileIconItemRenderer height="100" fontSize="16" fontFamily="Verdana" messageFunction="setMyMsg" labelFunction="setMyLabel">
<fx:Script>
/*
* A MobileIconRenderer has two functions to label your listentrys:
* - the messageFunction
* - the labelFunction
*/
[Bindable] private var bookTitle :String;
[Bindable] private var bookCategory :String;
[Bindable] private var bookCoverUrl :String;
//In this case the label will be the booktitle
public function setMyLabel(value:Object):String
{
bookTitle = value.title;
return bookTitle;
}
//and the message will be the book-genre / -category
public function setMyMsg(o:Object):String
{
return o.category;
}
</fx:Script>
</s:MobileIconItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:List>
</s:HGroup>
<s:Label id="infoLabel"
y="-30"
right="0"
width="504" height="27"
textAlign="right"
verticalAlign="middle"/>
</s:Panel>
</s:View>
<?xml version="1.0" encoding="utf-8"?>
<!--
/***
* RIM Blackberry Tablet OS
* PlayBook Prototype
* - /tschweitzer@qkom.de
* - /dley@qkom.de
*
* Q!kom - www.qkom.de
* Flexdomino - www.flexdomino.net
*
* Copyright (c) 2010 - QKom GmbH
*
***/
-->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" viewActivate="activateHandler()">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var docfieldReturn:ArrayCollection;
private var tempDATA:ArrayCollection
[Bindable] private var trimmedCoverURL:String;
private var mainReturn:ArrayCollection = new ArrayCollection();
protected function activateHandler():void
{
if(data)
{
tempDATA = data as ArrayCollection;
docfieldReturn = tempDATA[0]["docfieldResult"] as ArrayCollection;
trimmedCoverURL = docfieldReturn[12].toString().replace("booking.esemalta.com","flashdomino.de");
}
else
{
trace("[ERROR] No data-object!");
}
}
protected function closeView(save:Boolean=false):void
{
if(save)
{
var changedText:Array = new Array();
var returnForSavedoc:ArrayCollection = new ArrayCollection();
changedText.push(infoTitle.text);
changedText.push(infoAuthor.text);
changedText.push(infoYear.text);
changedText.push(infoGenre.text);
changedText.push(infoPrice.text);
changedText.push(infoSummary.text);
returnForSavedoc.addItem(changedText);
returnForSavedoc.addItem(docfieldReturn.getItemAt(13));
mainReturn.addItem({
"savedocFieldReturn":returnForSavedoc,
"resultACReturn" :tempDATA[0]["mainResult"]
});
navigator.pushView(PB_QBookStoreHome,mainReturn);
}
else
{
mainReturn.addItem
({
"resultACReturn" :tempDATA[0]["mainResult"],
"savedocFieldReturn":"nosave"
});
navigator.pushView(PB_QBookStoreHome, mainReturn);
}
}
]]>
</fx:Script>
<fx:Script source="../scripts/Main.as"/>
<s:titleContent>
<s:Image
left="10"
source="img/qkom-logo.png"/>
</s:titleContent>
<s:Panel
id="detailPanel"
left="10"
right="10"
top="10"
bottom="10"
backgroundColor="#3F3F3F"
fontSize="16"
title="Details:">
<s:controlBarContent/>
<!-- Title -->
<s:Label
x="10"
y="19"
width="100"
height="35"
color="#CCFF00"
text="Title:"
textAlign="right"
verticalAlign="middle"/>
<s:TextInput
text="{docfieldReturn.getItemAt(0)}"
id="infoTitle"
x="122"
y="19"
height="35"
fontSize="12"
enabled="true"/>
<!-- Author -->
<s:Label
x="10"
y="62"
width="100"
height="35"
color="#CCFF00"
text="Author:"
textAlign="right"
verticalAlign="middle"/>
<s:TextInput id="infoAuthor"
x="122" y="62"
height="35"
enabled="true"
fontSize="12"
text="{docfieldReturn.getItemAt(1)}"/>
<!-- Year -->
<s:Label
x="10"
y="105"
width="100"
height="35"
color="#CCFF00"
text="Year:"
textAlign="right"
verticalAlign="middle"/>
<s:TextInput id="infoYear"
x="122" y="105"
height="35"
enabled="true"
fontSize="12"
text="{docfieldReturn.getItemAt(2)}"/>
<!-- Genre -->
<s:Label
x="10"
y="148"
width="100"
height="35"
color="#CCFF00"
text="Genre:"
textAlign="right"
verticalAlign="middle"/>
<s:TextInput id="infoGenre"
x="122" y="148"
height="35"
enabled="true"
fontSize="12"
text="{docfieldReturn.getItemAt(3)}"/>
<!-- Price -->
<s:Label
x="10"
y="191"
width="100"
height="35"
color="#CCFF00"
text="Price:"
textAlign="right"
verticalAlign="middle"/>
<s:TextInput id="infoPrice"
x="122" y="191"
height="35"
enabled="true"
fontSize="12"
text="{docfieldReturn.getItemAt(4)}"/>
<!-- Cover -->
<s:Image id="infoCover"
x="572" y="19"
width="308" height="323"
scaleMode="stretch"
source="{trimmedCoverURL}"/>
<!-- Summary -->
<s:Label
x="14"
y="234"
width="100"
height="35"
color="#CCFF00"
text="Summary:"
textAlign="right"
verticalAlign="middle"/>
<s:TextArea id="infoSummary"
x="122" y="230"
height="202"
text="{docfieldReturn.getItemAt(5)}"/>
<s:Button x="570" y="387"
width="91" height="45"
label="Save"
click="closeView(true)"
fontFamily="_sans"
fontWeight="normal"/>
<s:Button x="669" y="387"
width="91" height="45"
label="Close"
click="closeView(false)"
fontFamily="_sans" fontWeight="normal"/>
</s:Panel>
</s:View>
QKom GmbH
Bahnhofstraße 80
56330 Kobern-Gondorf
Deutschland
Telefon 0 26 07 - 10 12