Dynamic table and postback

G

Gregory Gadow

If there is a more appropriate forum, please let me know and I will post
there.

Our field reps can go on to our website and select from several sets of
data to create the address we then provide to their clients in company
correspondence. Using just name as an example, one rep might have a
choice between "James Smith", "James Smith MS, CFP, MBA" and "Jimmy
Smith" while a different rep might have only "Elizabeth Jones" and "Liz
Jones." Similar options exist for address, telephone numbers, etc.,
again with different variations: Smith might have one telephone number
and one fax number, while Jones might have a telephone, cell phone and
two faxes from which to choose.

The current page, written in classic ASP, uses VBScript to open a
database and write out the input controls that are needed. These are
rendered in several tables: one for name, one for address, and so on.
When a rep makes a choice, the form data is submitted to a second ASP
page which records the changes, then returns the user to the page he
just left, adding a note that the changes have been saved.

I am trying to switch this process over to ASP.net 2.0, and it is near
driving me to suicide. My first attempt was to basically cut-n-paste the
existing code into two pages and tidy it all up to work as ASPX, but I
kept getting viewstate errors just loading the code page. I then tried
moving the code to a static module in the app_code folder, but couldn't
figure out how to pass the form values.

So I figured I would rewrite the page from scratch in .NET and
dynamically generate the form fields I needed. The resulting page has a
base table structure, like this:

******
<asp:Table ID="NameTable" runat="server">
<asp:TableRow>
<asp:TableHeaderCell ColumnSpan="3">Name</asp:TableHeaderCell>
</asp:TableRow>
</asp:Table>
******

In the Page.PreRender sub, I pull the existing data out of our database
into a datarow object named Dr, then execute this:

******
i=0
If Dr("Name0").ToString <> String.Empty Then
i = ((I + 1) Mod 2)
Tr = New TableRow
Tr.CssClass = String.Format("color{0}", i)

Tc = New TableCell
Tc.Text = "Formal 1:"
Tr.Cells.Add(Tc)

Tc = New TableCell
Tc.CssClass = "item"
Rb = New RadioButton
Rb.ID = "RepName0"
Rb.GroupName = "RepName"
If CInt(Dr("NameToClients")) = 0 Then Rb.Checked = True
Tc.Controls.Add(Rb)
Tr.Cells.Add(Tc)

Tc = New TableCell
Tc.CssClass = "description"
Tc.Text = Dr("Name0").ToString
Tr.Cells.Add(Tc)
NameTable.Rows.Add(Tr)
End If

If Dr("Name1").ToString <> String.Empty Then.... etc.
******

Already on the page is the submit button, coded as

******
<asp:Button ID="SubmitDataButton" runat="server" Text="Submit"
OnClick="SubmitDataButton_Click"></asp:Button>
******

My problem is that on postback (ie when SubmitDataButton is clicked),
the rows I added programmatically no longer exist, which makes it a tad
difficult to retrieve the data. I have run out of ideas and really,
really could use some pointers. What can I do?
 
R

Rob MacFadyen

Gregory,

It's a bit difficult to picture what you're trying.

Maybe what you want is a something like this (with a "select" being a link):

+--------------------------------------+
| select | Jon Smith Esq |
| | 17 Any Lane, AnyTown, USA |
|--------+-----------------------------+
| select | Johan Smith, Phd |
| | 99 Business Blvd |
+--------+-----------------------------+

Clicking the select link beside the individual record initiates a post back
where you can do what ever you need to next.

You could do that with a gridview and a form view (or maybe just a literal
that you do the binding for directly).... does that sort look like what you
want?

With more work you could replace the "select" link with a radio button and
then add a "Next" button outside the grid.

Is that the sort of thing you mean?

Regards,

Rob
 
G

Gregory Gadow

Rob said:
Gregory,

It's a bit difficult to picture what you're trying.

Maybe what you want is a something like this (with a "select" being a link):

+--------------------------------------+
| select | Jon Smith Esq |
| | 17 Any Lane, AnyTown, USA |
|--------+-----------------------------+
| select | Johan Smith, Phd |
| | 99 Business Blvd |
+--------+-----------------------------+

Clicking the select link beside the individual record initiates a post back
where you can do what ever you need to next.

You could do that with a gridview and a form view (or maybe just a literal
that you do the binding for directly).... does that sort look like what you
want?

With more work you could replace the "select" link with a radio button and
then add a "Next" button outside the grid.

Is that the sort of thing you mean?\

There are five different data items (name, address, telephone, email and web
address), with each item having anywhere between two and six different choices.
Assembling all of the possible combinations and allowing the reps to select one
is probably not the best option.

This shouldn't be difficult to implement, but danged if I can figure it out.
 
G

Gregory Gadow

I have found out that there is no solution for what I want to do: Microsoft
has seen fit NOT to preserve the viewstate of a dynamically generated table.
The only way something like this can be done is either to use a static table
with individual elements hidden, or manually maintain the viewstate myself.
 
R

Rob MacFadyen

Gregory,

The view state is persisted... you're likely running into the classic
"dynamically created controls" problem.

If I understand correctly... by the time Page_Load is called the view state
has been loaded. If you're creating controls, then you need to create them
in the page_init event (that fires before view state is loaded).

Essentially the root of the problem is that when a page goes to load view
state it expects (rightly so) that the page's control tree (page.controls
and descendants) have been created and are ready to load view state. With
dynamically generated controls special care has to be taken to make sure
this is so.

Search of "dynamically creating columns datagrid"... that'll get you close
to a better description (commonly experienced problem for datagrids).

As to your UI problem... I think I understand your problem better... are all
the address elements related? For example if a user chooses Phone Number #2
then there is a corresponding email address they have to choose?

Or is it totally freeform? User could choose phone number #2, email #1, web
address #3?

If the first option... do you have a consistent datasource (eg. select
Name,Email,Phone,WebAddress from UserContactInfo ... one row per choice)? If
so then use a Repeater/DataGrid/GridView and data binding.

Without a consistent datasource (eg. select Name1, Name2, Name3, Email1,
EMail2, Email3 from UserContactInfo ... only one row returned ever) you're
kind of stuck generating the table. Or maybe change the SQL to make the
results one contact info per selected row... will likely require UNION.

If the second option... can you use dropdown lists and data binding. More or
less one dropdown for names, one dropdown for emails, one for web addresses.
The data binding part may well need consitant data source (as above).

Hope that helps,

Rob MacFadyen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top