0

As a pseudo follow up from my previous question.

My current code looks similar to the following:

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="MyPage.aspx.vb" Inherits="Project.MyPage" EnableEventValidation="false" %>
<head>...</head>
<body id="Body" class="Window" runat="server">
<form id="MyForm" runat="server" defaultbutton="SubmitLinkButton">
    <!-- Markup for a the SubmitLinkButton and DropDownList -->
    <!--    to pick which Table is shown                    -->
    <asp:Table ID="Table1" runat="server">
        <asp:TableRow class="row" runat="server">
            <asp:TableCell runat="server">
                <pre>    Some Input1    </pre>
                <pre>___________________</pre>
                <pre>|___<asp:Textbox ID="Textbox1" runat="server"></asp:Textbox>____|</pre>
                <pre>|_________________|</pre>
            </asp:TableCell>
        </asp:TableRow>
    </asp:Table>
    <asp:Table ID="Table2" runat="server">
        <asp:TableRow class="row" runat="server">
            <asp:TableCell runat="server">
                <pre>    Some Input2    </pre>
                <pre>___________________</pre>
                <pre>|___<asp:Textbox ID="Textbox2" runat="server"></asp:Textbox>____|</pre>
                <pre>|_________________|</pre>
            </asp:TableCell>
        </asp:TableRow>
    </asp:Table>
</form>
</body>

The method that matters...

Public Sub SubmitLinkButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SubmitLinkButton.Click
    Dim result As String = vbNull

    Dim sw As New StringWriter
    Dim htmlWriter As New HtmlTextWriter(sw)

    If (DropDownList.SelectedValue IsNot "") Then
        Try
            Select Case DropDownList.SelectedValue
                Case "Table1"
                    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Table)
                    Table1.RenderControl(htmlWriter)
                Case "Table2"
                    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Table)
                    Table2.RenderControl(htmlWriter)
            End Select

            htmlWriter.RenderEndTag()
            htmlWriter.Flush()

            result = sw.ToString()
        Finally
            htmlWriter.Close()
            sw.Close()
        End Try

        With New [Reference To A Class]
            .SendMyEmail("Email Header", result) 'Email(header, body)
        End With
    Else
        'Do something else that isn't important right now
    End If
End Sub

Public Overrides Sub VerifyRenderingInServerForm(control As Control)
    'No code necessary
End Sub

All of this stuff works! I takes the form, renders the html to the result variable, and sends it off in an email! Awesome!

My current issues are:

A) When any user input is empty, the empty input renders as [ ] exactly. [, 10 spaces, then ]. Unfortunately, this messes up the formatting of the form. It's written out to look like an ASCII-like table. Is there a way for no user input to be displayed as solely the empty space allowed by the input element? (E.g. <asp:Textbox ... Columns="8" ...></asp:Textbox> only showing as (eight spaces).)

B) On submit, I get the email, but the webpage shows an "A page can have only one server-side Form tag." error message. There is only one Form tag. The markup you see in the example code above is accurate even though it isn't detailed.

C) The user needs to be able to print this form out. There are specific page-breaks setup in the CSS, but once this is emailed, those page breaks don't exist. How can I get this form to print out the way the user wants?

EDIT: One fix I can think of would be to send the HTML form printed somehow. Do something like printing to PDF and send the PDF in the email instead of the Rendered HTML Form. Any help would be awesome!

EDIT: I changed the SubmitLinkButton_Click code to look at each table specifically rather than the entire form.

brettwbyron
  • 95
  • 12
  • Is there anything preventing you from programmatically checking for no input and setting the textbox's value to " "? Regarding the extra form tag, that's probably a part of what the htmlWriter adds. – Mahendran Nadesan Oct 21 '17 at 21:43
  • I fixed the extra form tag by changing my `SubmitLinkButton_Click` code. I will make an edit showing my change. It now looks at each table using `Select Case` rather than the entire form. How would you suggest checking for no input? If I did replace an empty input, it would have to be for the maximum amount of characters allowed for each input. So, in my example above, it'd replace the empty input with `Columns="8"` with " " (eight spaces), not " " (one space). – brettwbyron Oct 23 '17 at 11:43

1 Answers1

1

You should be able to retrieve and set the text value of the control from code-behind with something like (from https://stackoverflow.com/a/4674181/2953322):

' Function to find controls
Public Shared Function FindControlRecursive(ByVal list As List(Of Control), ByVal parent As Control, ByVal ctrlType As System.Type) As List(Of Control)
    If parent Is Nothing Then 
        Return list
    If parent.GetType Is ctrlType Then
        list.Add(parent)
    End If
    For Each child As Control In parent.Controls
        FindControlRecursive(list, child, ctrlType)
    Next
    Return list
End Function

Your code:

Case "Table1"

    Dim allInputs As New List(Of Control)
    For Each txtBox As TextBox In FindControlRecursive(allInputs, Me, GetType(TextBox))
        If String.IsNullOrEmpty(txtBox.Text) Then
            txtBox.Text = "        "
        End If
    Next

    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Table)
    Table1.RenderControl(htmlWriter)

Case "Table2"

'Rest of your code

By the way, I had put 8 spaces in my comment, it obviously got formatted into " ".

  • Oh, I see. The problem with that, and the reason why I am rendering the the html to the email like this, is due to the fact that there are a significant amount of inputs. To do that to each input in each form would take at least a day. If there were a way to do that without needing to call each specific input, but instead generalize it (some type of loop where `"Textbox1"` would be `"nth_input"`), that could potentially work. – brettwbyron Oct 23 '17 at 12:20
  • If you look here: https://stackoverflow.com/a/4674181/2953322 you will see how you can iterate through the controls in your form and grab all the textboxes. All you do then is do a check for an empty input in your loop. If you need assistance with that, I will edit my answer to reflect that. Let me know. – Mahendran Nadesan Oct 23 '17 at 12:24
  • For this thread's sake, could you please edit your answer to show how it could be done in a situation like this? – brettwbyron Oct 23 '17 at 12:32
  • So, rather than having a hardcoded eight space string. Could I grab the `MaxLength` value and use that number to create a string of spaces with a length of the `MaxLength` value? – brettwbyron Oct 23 '17 at 13:20
  • What you could do is grab `MaxLength` and do `Dim spaces = New String(" ", MaxLength)`. `FindControlRecursive` is a custom function that looks for controls of the type specified (we used `GetType(TextBox)`) and adds the control to a list you pass in. You can put it in your current page, or in a custom code page for your general methods. – Mahendran Nadesan Oct 23 '17 at 13:28
  • Great! That worked out perfectly. Very helpful, thank you. – brettwbyron Oct 23 '17 at 13:35