I made you a fixed example (with stuff slightly reworked to not require the rules / constant on your environment) which handles the saving of the local array into the rule input in the appropriate place (in the submit button) and properly handles intialization of the local array / etc.
(note I turned of the requiredness of the file upload field temporarily just to allow easier testing of the saveinto on the submit button click, which for now saves into a fake local variable called "exampleOutput", but in your real interface you'll change to save back into your Rule Input array).
a!localVariables(
local!documentTypes: {
{
description: "doc 1",
documenttypekey: 1
},
{
description: "doc 2",
documenttypekey: 2
}
},
/*rule!LCM_getDocumentTypes(documentTypeKey: null()),*/
local!intakedocuments: {},
local!itemscount: count(local!intakedocuments),
local!blankRow:
/*'type!{urn:com:appian:types:LCM}LCM_IntakeDocuments'(),*/
a!map(
DocKey: null(),
IntakeHeaderKey: null(),
documentid: null(),
documenttitle: "",
documenttypekey: null(),
uploadedby: loggedInUser(),
dateuploaded: now()
),
local!exampleOutput: {},
a!formLayout(
label: "Document Details",
contents: {
a!gridLayout(
totalCount: count(local!intakedocuments),
headerCells: {
a!gridLayoutHeaderCell(label: "Document Type"),
a!gridLayoutHeaderCell(label: "Document Title"),
a!gridLayoutHeaderCell(label: "Document"),
/* For the "Remove" column */
a!gridLayoutHeaderCell(label: "")
},
columnConfigs: {
a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 1),
a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 1),
a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 1),
a!gridLayoutColumnConfig(width: "ICON")
},
rows: a!forEach(
items: local!intakedocuments,
expression: a!gridRowLayout(
id: fv!index,
contents: {
a!dropdownField(
label: "DocumentType " & fv!index,
placeholder: "-- Select -- ",
choiceLabels: index(local!documentTypes, "description", ""),
choiceValues: index(
local!documentTypes,
"documenttypekey",
""
),
value: fv!item.documenttypekey,
saveInto: {
fv!item.documenttypekey,
/*a!save(*/
/*ri!lcmIntakeDocuments,*/
/*a!forEach(*/
/*items: local!intakedocuments,*/
/*expression: {*/
/*documentid: fv!item.documentid,*/
/*documenttitle: fv!item.documenttitle,*/
/*documenttypekey: fv!item.documenttypekey,*/
/*uploadedby: loggedInUser(),*/
/*dateuploaded: now()*/
/*}*/
/*)*/
/*)*/
},
required: if(
or(
a!isNotNullOrEmpty(fv!item.documenttitle),
a!isNotNullOrEmpty(fv!item.documentid)
),
true(),
false()
)
),
a!textField(
label: "DocumentTitle" & fv!index,
value: fv!item.documenttitle,
saveInto: {
fv!item.documenttitle,
/*a!save(*/
/*ri!lcmIntakeDocuments,*/
/*a!forEach(*/
/*items: local!intakedocuments,*/
/*expression: {*/
/*documentid: fv!item.documentid,*/
/*documenttitle: fv!item.documenttitle,*/
/*documenttypekey: fv!item.documenttypekey,*/
/*uploadedby: loggedInUser(),*/
/*dateuploaded: now()*/
/*}*/
/*)*/
/*)*/
},
required: if(
or(
a!isNotNullOrEmpty(fv!item.documenttypekey),
a!isNotNullOrEmpty(fv!item.documentid)
),
true(),
false()
)
),
a!fileUploadField(
label: "Attach LCM Document(s)" & fv!index,
/*target: cons!LCMDOCUMENTS,*/
maxSelections: 1,
value: fv!item.documentid,
saveInto: {
fv!item.DocumentID,
/*a!save(*/
/*ri!lcmIntakeDocuments,*/
/*a!forEach(*/
/*items: local!intakedocuments,*/
/*expression: {*/
/*documentid: fv!item.documentid,*/
/*documenttitle: fv!item.documenttitle,*/
/*documenttypekey: fv!item.documenttypekey,*/
/*uploadedby: loggedInUser(),*/
/*dateuploaded: now()*/
/*}*/
/*)*/
/*)*/
},
buttonStyle: "STANDARD",
required: if(
or(
a!isNotNullOrEmpty(fv!item.documenttypekey),
a!isNotNullOrEmpty(fv!item.documenttitle)
),
/*true(),*/ false(),
false()
)
),
/* For the Removal Column*/
a!richTextDisplayField(
value: a!richTextIcon(
icon: "close",
altText: "Delete ",
caption: "Delete ",
link: a!dynamicLink(
value: fv!index,
saveInto: {
a!save(
local!intakedocuments,
remove(local!intakedocuments, save!value)
),
/*a!save(*/
/*ri!lcmIntakeDocuments,*/
/*remove(ri!lcmIntakeDocuments, save!value)*/
/*)*/
},
),
linkStyle: "STANDALONE",
color: "NEGATIVE"
)
)
}
)
),
addRowlink: a!dynamicLink(
label: "Add Document",
saveInto: {
a!save(
local!intakedocuments,
append(local!intakedocuments, local!blankRow),
),
/*a!save(*/
/*local!itemscount,*/
/*count(ri!lcmIntakeDocuments)*/
/*)*/
}
),
spacing: "DENSE",
rowHeader: 1
)
},
buttons: a!buttonLayout(
primaryButtons: {
a!buttonWidget(
label: "Submit" & local!itemscount,
submit: true,
style: "PRIMARY",
saveInto: {
a!save(
/*ri!lcmIntakeDocuments,*/ local!exampleOutput,
a!forEach(
items: local!intakedocuments,
expression: {
documentid: fv!item.documentid,
documenttitle: fv!item.documenttitle,
documenttypekey: fv!item.documenttypekey,
uploadedby: loggedInUser(),
dateuploaded: now()
}
)
)
}
)
},
secondaryButtons: {
a!buttonWidget(
label: "Cancel",
value: true,
/*saveInto: ri!cancel,*/
submit: true(),
style: "NORMAL",
validate: false
)
}
)
)
)

Let me know if any questions.