erdem erdem commented on Aug 5, 2014

Re: Tutorial: Introduction to XPages - Exercise 23

how can we get value of fields?

ex:view_id1:fieldGroup:0:color or view_id1:fieldGroup:1:color?

Ivan Sharov commented on Sep 18, 2013

Could not find button icons - here is work around

put this as a computed icon : "/.ibmxspres/domino/icons/actn096.gif"

also it is possible to reference standard Domino view icons like so:

"/.ibmxspres/domino/icons/vwicn002.gif"

Berksan Ateş commented on Nov 13, 2012

Re: Tutorial: Introduction to XPages - Exercise 23

Fully working code of table walker javascript library - one row reading and writing problems solved ...

/**

*

* The table walker helps to manage collections of multi-value fields

* that form a table inside a notes document

* Modified 10/24/2012 by Berksan Ates

*

**/

var tableWalker = {

variableName : "variable",

dataName : "data",

fieldName : "fields",

fieldCount : 0,

fieldArray : new Array(),

// Set the variable names for the variables we use in the context

// We might get away without them once we can make sure we have stable JSON storage

setVariableNames : function(vname) {

this.variableName = vname;

this.dataName = vname+"_data";

this.fieldName = vname+"_fields";

},

// The fields for this datasource

setFieldList : function(fList:String) {

if (fList == null || fList == "") {

this.fieldList = viewScope.get(this.fieldName)

} else {

// We overwrite the field list

viewScope.put(this.fieldName,fList);

this.fieldList = fList

}

this.fieldArray = this.fieldList.split(",");

this.fieldCount = this.fieldArray.length

},

/**

* getDataSource retrieves a collection of multivalue fields as datasource

* If the variable already exists in the viewScope that variable is used

* otherwise the field values are pulled from the given Domino document

* doc: the NotesDocument

* fieldList: a string with all the fieldName

* variableName: under wich name will that field be stored into the viewScope

* there will be 2 variables one [name]_data and one [name]_fields

* e.g. if variableName is abc the data is abc_data and the fieldnames is abc_fields

* if the caller is sure, that the source exists only the variable name is needed

* same applies if the caller is sure that the fieldList is already in the scope

*

**/

getDataSource : function (variableName:String, doc:NotesXspDocument, fieldList:String) {

// Capture the variables

this.setVariableNames(variableName);

// Now we need to retrieve the field names

this.setFieldList(fieldList)

// Try to get valid data from the viewScope

var theDataWeWant:Array = viewScope.get(this.dataName);

if ( theDataWeWant != null) {

// We have existing content and are done

return theDataWeWant

}

// Now we check if we have a valid document, we would need that

if (doc == null || typeof doc === "undefined") {

print("Document was null");

return null //We don't have data here

}

// And the data... using an existing function

return this.storeDataSourceInViewScope(doc)

},

/**

* storeDataSourceInViewScope extracts a set of multi value fields into an array and stores that into

* the viewContext for later retrieval

* doc: the NotesDocument

* fieldList: a string with all the fieldName

* variableName: under wich name will that field be stored into the viewScope

* there will be 2 variables one [name]_data and one [name]_fields

* e.g. if variableName is abc the data is abc_data and the fieldnames is abc_fields

**/

storeDataSourceInViewScope : function(doc:NotesXspDocument) {

var theDataWeWant = new Array(); // Our matrix with field values

// get a 2 dimensional array with rows=fields, cols=field values

var fieldValueArray:Array = this.getListWithValues(doc);

var firstFieldSet = fieldValueArray[0]; // The first column, we use to determine row count

var rowCount = firstFieldSet.length; // How many rows with values

var colCount = this.fieldCount; // How many unique fields = columns

// now transpose that array to cols = fields and rows= field values

for (var row = 0; row < rowCount; row++) {

// Array that holds one value row

var rowWithValues = new Array();

// Loop through all properties a.k.a columns

for (var col = 0; col < colCount; col++) {

// remember: in the source array it row and col are mixed up

rowWithValues.push(fieldValueArray[col][row]);

}

// Assign the new Object to the result

theDataWeWant.push(rowWithValues);

}

// Store our results into the viewContext

viewScope.put(this.dataName,theDataWeWant);

// Return the array for direct use

return theDataWeWant

},

// Retrieves a list of field values into an array, one element (row) per field, the

// elements are arrays (columns) of values

getListWithValues : function(doc:NotesXspDocument) {

var result = new Array(); // the resulting array

for (var i = 0; i < this.fieldCount; i++) {

// NotesItem values come back as Vectors

var rawResult = doc.getValue(this.fieldArray[i]);

var curResult = new Array();

// Loop through the resulting values, works for array and vector and is

// neutral to the data type

if (rawResult != null) {

if((typeof rawResult) != "string") { // Array normal execution

for(curVal in rawResult) {

curResult.push(curVal)

}

} else { // Single value just push in

if(rawResult != "") { // If string is empty do not pus h anything

curResult.push(rawResult)

}

}

}

// This adds one field

result.push(curResult);

}

return result

},

/**

*

* addRow adds a row to an existing array that is bound to controls

* variableName = name of viewScope variable to hold the Array

* rowNumberToInsertBefore = where to insert, if omitted -> append a row

**/

addRow : function (variableName:String, insertArray, rowNumberToInsertBefore) {

//Get the current array

var theDataWeWant:Array = this.getDataSource(variableName);

if (theDataWeWant == null) {

//Nothing to add on

print("Function addRow: DataArray is empty")

return null

}

if(insertArray == null) { // If there is no array to insert create an empty array

var newArray = new Array(this.fieldCount); // Empty array

} else {

var newArray = insertArray; // Arrray that we give

}

//Now append that to the existing array

if (rowNumberToInsertBefore == null) {

theDataWeWant.push(newArray)

} else {

//Splice doesn't seem to work with with two dimensional arrays

//theDataWeWant.splice(rowNumberToInsertBefore,0,emptyArray)

var curRowCount = theDataWeWant.length; // How much data do we have

var insertComplete = false; // To handle too high insert rows

var newDataWeWant = new Array();

// Move all rows to new array. Insert where appropriate

for (var i = 0 ; i < curRowCount; i++) {

if (rowNumberToInsertBefore == i && !insertComplete) {

newDataWeWant.push(emptyArray);

insertComplete = true

}

newDataWeWant.push(theDataWeWant[i])

}

if (!insertComplete) {

// We don't have a new line, so we append one

newDataWeWant.push(emptyArray);

}

// Store it back

viewScope.put(this.dataName,newDataWeWant);

return newDataWeWant

}

return theDataWeWant

},

/**

*

* removeRow adds a row to an existing array that is bound to controls

* variableName = name of viewScope variable to hold the Array

* rowNumberToDelete = which row needs deletion

**/

removeRow : function (variableName:String, rowNumberToDelete) {

var theDataWeWant:Array = this.getDataSource(variableName);

if (theDataWeWant == null) {

//Nothing to add on

print("Function removeRow: DataArray is empty")

return null

}

var curRowCount = theDataWeWant.length;

if (curRowCount > 1) {

// We only proceed if we have more than one row left

// Splice doesn't seem to work with 2 dimensional arrays

// theDataWeWant.splice(rowNumberToDelete,1)

if (rowNumberToDelete == (curRowCount - 1)) {

theDataWeWant.pop() //Last row, just pop it away

} else {

// We need to rescue the stack

var newDataWeWant = new Array();

// Move all rows to the rescue array

for (var i = 0 ; i < curRowCount; i++) {

if (!(rowNumberToDelete == i)) {

newDataWeWant.push(theDataWeWant[i])

}

}

// Store it back

viewScope.put(this.dataName,newDataWeWant);

return newDataWeWant

}

} else {

var newDataWeWant = new Array(); // Empty Array

// Store it back

viewScope.put(this.dataName,newDataWeWant);

return newDataWeWant

}

return theDataWeWant

},

/**

*

* updateDocument writes the field value back into the Notes document

* typically in a QueryDocumentSave event

*

*/

updateDocument : function updateDocument(variableName:String, doc:NotesXspDocument) {

var fieldData:Array = this.getDataSource(variableName);

if ( fieldData == null) {

// No data in the array, nothing to do

print("No fieldData found in updateDocument");

return null

}

// We need to pick for every field the column value from the array

// TODO: make this more efficient!

for (var i = 0; i < this.fieldArray.length; i++) {

var curFieldName = this.fieldArray[i];

var curData = new Array();

// get the field value for

for(dataRow in fieldData) {

curData.push(dataRow[i])

}

doc.replaceItemValue(curFieldName,curData);

}

},

// retrieve the number of rows

rowCount : function(variableName:String) {

var fieldData:Array = this.getDataSource(variableName);

if ( fieldData == null) {

return 0;

}

return fieldData.length

}

}

Kevin T Urbanek commented on Oct 16, 2012

Re: Tutorial: Introduction to XPages - Exercise 23 - Fix

I am a Notes Admin doing some coding (please be kind) and I came up with this solution to the problem that Ryan pointed out. I changed the following subroutine in the TableWalker.js

The problem occurs if the result is not an array. So the code checks this and then if necessary turns the result into an array.

// Retrieves a list of field values into an array, one element (row) per field, the

// elements are arrays (columns) of values

getListWithValues : function(doc:NotesXspDocument) {

var result = new Array(); // the resulting array

var rawResult = new Array(); // the resulting array

var oneResult = new Array(); // the resulting array

for (var i = 0; i < this.fieldCount; i++) {

// NotesItem values come back as Vectors

rawResult = doc.getValue(this.fieldArray[i]);

var curResult = new Array();

// Loop through the resulting values, works for array and vector and is

// neutral to the data type

if (rawResult != null) {

if( typeof rawResult === 'undefined' || rawResult === null ){

rawResult = "";

}else if( typeof rawResult.toArray == 'undefined' ){

oneResult[0] = rawResult;

}

if (oneResult.length == 1) {

curResult.push(oneResult[0]);

}else{

print(typeof rawResult);

for(curVal in rawResult) {

curResult.push(curVal)

}

}

}

// This adds one field

result.push(curResult);

}

return result

},

Shannon Crowder commented on Apr 4, 2012

Re: Tutorial: Introduction to XPages - Exercise 23

Is there a modified version of the TableWalker that fixes the problem submitted by Ryan Buening? There is an issue when adding only one row of fields on the XPage. The fields do not show on re-open when only one row is saved. You are not able to view or edit any of the fields because the table is blank. It works fine when more than 1 row is added. Please advise.....

Robert F Harwood commented on Jan 13, 2012

Re: Tutorial: Introduction to XPages - Exercise 23

checked

Ryan Buening commented on Apr 20, 2011

Re: Tutorial: Introduction to XPages - Exercise 23

I've come across an issue when trying to add only one row of fields on the XPage, saving, and then re-opening the XPage. The fields do not show on re-open when only one row is saved. On re-open of the XPage, the viewScope variable "group_data", which holds the field data, is blank which consequently prevents any of the edit box controls from displaying any data. The fields display fine when more than 1 row is added.

Anyone have any ideas?

Atul Saxena commented on May 25, 2010

Tutorial: Introduction to XPages - Exercise 23

It work for both clients. Only we have to keep the Save button out of table. Great Example

Deanna Drschiwiski commented on Aug 6, 2009

Resources available

{ Link }

Wesley Guisso commented on Jul 31, 2009

Not found file

Not found file "tableWalker.txt" of item 4.