Skip to main content

Multiple-Iteration Tables

Multiple-iteration tables are a special kind of FormObject that allow for multiple RowObjects.

There are some constraints when working with multiple-iteration tables.

  • Cannot be the first FormObject in an OptionObject.
  • RowObjects cannot share the same RowId.
  • The ParentRowId is to be set with the RowId assigned to the primary FormObject's CurrentRow.

The AvatarScriptLink.NET library helps with managing these constraints by:

  • Throwing an exception when attempting to add additional RowObjects to a non-multiple-iteration FormObject.
  • Automatically setting the RowAction.
  • Automatically assigning RowIds to prevent duplicates.
  • Automatically adds new RowObjects to OtherRows when CurrentRow is already set.
  • Helping look up the ParentRowId.

Reading RowObjects​

How we read RowObjects may vary by use specific needs. For example, if you need all values from a single FieldNumber:

Read all values of a single field
var clone = _optionObject.Clone();

var miFormId = "123";
List<string> values = optionObject.GetFieldValues(miFormId);

// work with values

return clone.ToReturnOptionObject();

If you need to interact with multiple FieldObjects in each RowObject (e.g., validating values).

Read RowObjects in a multiple-iteration table
var clone = _optionObject.Clone();

var miFormId = "123";

foreach (FormObject formObject in clone.Forms)
{
if (formObject.FormId == secondFormId)
{
var selectedRow = formObject.CurrentRow;
// read RowObject
foreach (RowObject rowObject in formObject.OtherRows)
{
// read other RowObjects
}
}
}

return clone.ToReturnOptionObject();

Adding RowObjects​

warning

At this time we want to avoid using the RowObject Builder to build the RowObjects as it requires setting the RowId instead of allowing the AddRowObject method to auto-assign it. This may change in a future update.

To take advantage of the library features described above, we want to use the AddRowObject method exclusively to add the new rows.

Add multiple RowObjects to a multiple-iteration table
var clone = _optionObject.Clone();

var parentFormId = "110";
var miFormId = "123";
var parentRowId = clone.GetCurrentRowId(parentFormId);

var firstRow = new RowObject();
firstRow.RowAction = RowAction.Add;
firstRow.ParentRowId = parentRowId;
firstRow.AddFieldObject(new FieldObject("123.45", "Test #1"));
clone.AddRowObject(miFormId, firstRow);

var secondRow = new RowObject();
secondRow.RowAction = RowAction.Add;
secondRow.ParentRowId = parentRowId;
secondRow.AddFieldObject(new FieldObject("123.45", "Test #2"));
clone.AddRowObject(miFormId, secondRow);

return clone.ToReturnOptionObject();

Editing RowObjects​

Editing rows in a multiple-iteration table can be tricky. It is recommended to do plenty of testing and validation to ensure the user experience is as expected.

Set a value on all rows in a multiple-iteration table
var clone = _optionObject.Clone();

var miFormId = "123";

foreach (FormObject formObject in clone.Forms)
{
if (formObject.FormId == secondFormId)
{
var selectedRow = formObject.CurrentRow;
// Using the SetFieldValue method automatically sets the RowAction to EDIT
selectedRow.SetFieldValue("234.56", "Edited by ScriptLink API");

foreach (RowObject rowObject in formObject.OtherRows)
{
rowObject.SetFieldValue("234.56", "Edited by ScriptLink API");
}
}
}

return clone.ToReturnOptionObject();

Deleting RowObjects​

Deleting RowObject is accomplished by setting the RowAction to DELETE. This can be accomplished a couple ways. The first is the most straightforward but requires RowId of the RowObject to delete.

Delete a RowObject by RowId
var clone = _optionObject.Clone();

var rowIdToDelete = "123||4";
clone.DeleteRowObject(rowIdToDelete);

return clone.ToReturnOptionObject();

In most cases, the RowId of the RowObject(s) will not be fixed or known when the API is called.

Delete all rows in a multiple-iteration table
var clone = _optionObject.Clone();

var miFormId = "123";

foreach (FormObject formObject in clone.Forms)
{
if (formObject.FormId == secondFormId)
{
if (formObject.CurrentRow != null && formObject.CurrentRow.RowId)
formObject.DeleteRowObject(formObject.CurrentRow.RowId);
foreach (RowObject rowObject in formObject.OtherRows)
{
if (rowObject.RowId != null)
formObject.DeleteRowObject(rowObject.RowId);
}
}
}

return clone.ToReturnOptionObject();

Handling Exceptions​

Two of the most common errors that can occur include:

This can be handled with conditionals and exception handling.

Handling exceptions with if/else and try/catch
var clone = _optionObject.Clone();

var parentFormId = "110";
var miFormId = "123";

if (clone.IsFormPresent(parentFormId))
{
try
{
var parentRowId = clone.GetCurrentRowId(parentFormId);
if (!clone.IsFormPresent(miFormId))
{
clone.AddFormObject(miFormId, true);
}

var firstRow = new RowObject();
firstRow.RowAction = RowAction.Add;
firstRow.ParentRowId = parentRowId;
firstRow.AddFieldObject(new FieldObject("123.45", "Test #1"));
clone.AddRowObject(miFormId, firstRow);

var secondRow = new RowObject();
secondRow.RowAction = RowAction.Add;
secondRow.ParentRowId = parentRowId;
secondRow.AddFieldObject(new FieldObject("123.45", "Test #2"));
clone.AddRowObject(miFormId, secondRow);

return clone.ToReturnOptionObject();
}
catch (ArgumentException ex) {
return clone.ToReturnOptionObject(ErrorCode.Error, ex.Message);
}
}
return clone.ToReturnOptionObject(ErrorCode.Error, "Could not find expected multiple-iteration form.");