I am building a web application to construct a document. The document has paragraphs (outer repeater) and subparagraphs (inner repeater). What I'm looking for is a way to add a blank subparagraph to an existing document.
My markup:
<asp:Repeater ID="ParagraphRepeater" runat="server"
OnItemDataBound="ParagraphRepeater_ItemDataBound" >
<ItemTemplate>
<asp:TextBox ID="ParagraphTitleTextBox" runat="server" Font-Bold="true" Width="300px"
Text='<%# Eval("ParagraphTitle") %>'></asp:TextBox>
<br />
<asp:TextBox ID="ParagraphTextTextBox" runat="server" TextMode="MultiLine" Wrap="true"
width="1100px" Height="50px" Text='<%# Eval("ParagraphText") %>'></asp:TextBox>
<asp:Button ID="DeleteParagraphButton" runat="server" Text="Delete" OnClick="DeleteParagraphButton_Click" />
<asp:Repeater ID="SubParagraphRepeater" runat="server" DataSourceID="SubParagraphSqlDataSource">
<ItemTemplate>
<div style="margin-left: 30px">
<asp:TextBox ID="SubParagraphTitleTextBox" runat="server" Font-Underline="true" Width="200px"
Text='<%# Eval("SubParagraphTitle") %>'></asp:TextBox>
<br />
<asp:TextBox ID="SubParagraphTextTextBox" runat="server" TextMode="MultiLine" Wrap="true"
Width="1050px" Height="50px" Text='<%# Eval("SubParagraphText") %>'></asp:TextBox>
<asp:Button ID="DeleteSubParagraphButton" runat="server" Text="Delete"
OnClick="DeleteSubParagraphButton_Click" />
<br />
</div>
</ItemTemplate>
</asp:Repeater>
<br />
<br />
<br />
</ItemTemplate>
My code:
protected void MultiView1_ActiveViewChanged(object sender, EventArgs e)
{
if (MultiView1.GetActiveView() == InputView)
{
BuildParagraphDataTable();
BuildSubParagraphDataTable();
if (RevisionsDropDownList.SelectedValue == "0")
{
// User is creating a new document
// Call method to create a datatable for the form row
SetFormRow();
// Call method to create a datatable for the paragraph row
AddParagraph();
DataTable dt = (DataTable)ViewState["ParagraphTable"];
ParagraphRepeater.DataSource = dt;
ParagraphRepeater.DataBind();
}
else
{
// User is opening an existing document
// Get the formId and save it to ViewState
int formId = Convert.ToInt32(RevisionsDropDownList.SelectedValue);
ViewState["FormId"] = formId.ToString();
// Bind the Paragraph repeater to its sqlDataSource
ParagraphRepeater.DataSource = ParagraphSqlDataSource;
ParagraphRepeater.DataBind();
}
}
}
protected void AddParagraph()
{
int paragraphId;
DataTable dt = (DataTable)ViewState["ParagraphTable"];
DataRow dr = dt.NewRow();
if (ViewState["ParagraphId"] != null)
paragraphId = Convert.ToInt32(ViewState["ParagraphId"]);
else
paragraphId = 0;
paragraphId--;
int formId = Convert.ToInt32(ViewState["FormId"]);
dr["ParagraphId"] = paragraphId;
dr["FormId"] = formId;
dr["ParagraphTitle"] = string.Empty;
dr["ParagraphText"] = string.Empty;
dr["CreatorId"] = string.Empty;
dr["RevisorId"] = string.Empty;
dt.Rows.Add(dr);
ViewState["ParagraphTable"] = dt;
ViewState["ParagraphId"] = paragraphId;
}
protected void AddSubParagraph()
{
DataTable dt = (DataTable)ViewState["SubParagraphTable"];
DataRow dr = dt.NewRow();
int paragraphId = Convert.ToInt32(ViewState["ParagraphId"]);
dr["ParagraphId"] = paragraphId;
dr["SubParagraphTitle"] = string.Empty;
dr["SubParagraphText"] = string.Empty;
dr["CreatorId"] = string.Empty;
dr["RevisorId"] = string.Empty;
dt.Rows.Add(dr);
ViewState["SubParagraphTable"] = dt;
}
protected void ParagraphRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
AddParagraph();
DataTable parentDataTable = (DataTable)ViewState["ParagraphTable"];
DataRow lastDTRow = parentDataTable.Rows[parentDataTable.Rows.Count - 1];
int paragraphId = (int)ViewState["ParagraphId"];
DataRowView thisParagraphRowView = (DataRowView)e.Item.DataItem;
paragraphId = (int)thisParagraphRowView.Row["ParagraphId"];
lastDTRow["ParagraphId"] = thisParagraphRowView.Row["ParagraphId"];
lastDTRow["FormId"] = thisParagraphRowView.Row["FormId"];
lastDTRow["ParagraphTitle"] = thisParagraphRowView.Row["ParagraphTitle"];
lastDTRow["ParagraphText"] = thisParagraphRowView.Row["ParagraphText"];
ViewState["ParagraphTable"] = parentDataTable;
ViewState["ParagraphId"] = paragraphId.ToString();
DataTable childDataTable;
DataRowView thisSubParagraphRowView;
Repeater childRepeater = (Repeater)e.Item.FindControl("SubParagraphRepeater");
foreach (RepeaterItem item in childRepeater.Items)
{
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
thisSubParagraphRowView = (DataRowView)item.DataItem;
if (thisSubParagraphRowView != null)
{
AddSubParagraph();
childDataTable = (DataTable)ViewState["SubParagraphTable"];
lastDTRow = childDataTable.Rows[childDataTable.Rows.Count - 1];
lastDTRow["ParagraphId"] = thisSubParagraphRowView.Row["ParagraphId"];
lastDTRow["SubParagraphTitle"] = thisSubParagraphRowView.Row["SubParagraphTitle"];
lastDTRow["SubParagraphText"] = thisSubParagraphRowView.Row["SubParagraphText"];
ViewState["SubParagraphTable"] = childDataTable;
}
}
}
}
}
When the user opens an existing form, the itemDataBound code populates the datatables for the paragraphs and subparagraphs. (These datatables will be used in the update to the database.)
When the user creates a new form, the setForm() and addParagraph() methods are called to create the form ID and add a blank paragraph. No blank subparagraph is added - the user must click a button to do so.
As for the data model, there is one Form (the user selects it from a ddl). A Form can have 1 to many paragraphs, and paragraphs can have zero to many subparagraphs.
I need to create a blank row in the inner repeater for a particular row in the outer repeater (the paragraph that the cursor is currently located in, or if the cursor is located in a subparagraph, the parent paragraph). How do I do that? I've done a ton of digging on Google but cannot find an entry that addresses this issue. Thanks.