asp.netvb.netforms

ASPX Page Submission but Retain Form Values


I have an ASPX page with a form that drives a user through selections. First selection enables a form field and loads the field with data specific to the first selection. A selection in that field sets the third field and so on. Form is 37 fields. So the form is unique to the situation being recorded. If you submit the form, it works great.

Client is now asking for the ability to Submit the form and essentially reload it with the same selections except two fields. This is so the user does not have to work through the form a second time, making all the same selections except the two fields they want the user to change and save again. If the user wants to change any other field, they want the ability to. So my option to lock fields to specific values and not have to reload combos and lists, has been denied.

PostBack appears to be the issue. After the first save, the form is present, the combo boxes and everything are still loaded according to the selections. When you attempt to change a field, the postback flag, having been triggered by the first submit, now causes the form to submit on each change. I am now aware that I can not change the postback flag dynamically according to multiple sources. If true, I am bummed because I think if I could change that flag, my issue would be resolved.

I am currently thinking my only way to resolve this is the programmatically reload the page and loop through the form, 1 field at a time to load the forms field options and set default values. Besides being tedious for me to program, I won't know until I try it to know if there is much delay in reloading the page for the user.

I have looked at cross-page posting, but it closes the old page and the the postback flag was still changed on the button click if I tried to go back to the page.

I have not been able to find any samples of code that allows me to run server side code to save the record without the postback flag being altered.

Anyone know another way that I have not found yet? Please?

Adding Some Code as requested -------

    <form id="frmMain" runat="server">
    <table style="border-width: 0px; padding: 0px; margin: 0px; width: 100%; border-spacing: 0px;">
       <tr id="trCallDate" style="background-color: #FFFFCC" hidden="hidden">
            <td style="color: #FF0000; width: 28%;">Date/Time of Call:</td>
            <td style="width: 66%">
                <asp:TextBox ID="txtCallDate" runat="server" style="width: 97%" ReadOnly="True"></asp:TextBox>
            </td>
            <td style="width: 6%">&nbsp;</td>
        </tr>
        <tr id="trDivision" style="background-color: #FFFFCC;">
            <td style="color: #FF0000; font-size: 11pt; width:28%">Division Called:</td>
            <td colspan="2" style="width: 72%">
                <table style="width: 75%">
                    <tr>
                        <td>
                            <asp:RadioButton ID="radCo1" runat="server" value="AK" GroupName="radDivision" text=" Company1" style="font-size: 11pt;" AutoPostBack="True" OnCheckedChanged="radDivision_OnChanged" />
                        </td>
                        <td>
                            <asp:RadioButton ID="radCo2" runat="server" value="UM" GroupName="radDivision" text=" Company2" style="font-size: 11pt;" AutoPostBack="True" OnCheckedChanged="radDivision_OnChanged" />
                        </td>
                        <td>
                            <asp:RadioButton ID="radCo3" runat="server" value="US" GroupName="radDivision" text=" Company3" style="font-size: 11pt;" AutoPostBack="True" OnCheckedChanged="radDivision_OnChanged" />
                        </td>
                    </tr>
                </table>

            </td>
        </tr>
        <tr id="trService" style="background-color: #FFFFCC">
            <td style="color: #FF0000; font-size: 11pt; width: 28%">Service:</td>
            <td style="width: 66%">
                <asp:dropdownlist runat="server" ID="cboSvc" OnSelectedIndexChanged="cboSvc_OnChanged" AutoPostBack="True" style="width: 100%"></asp:dropdownlist>
            </td>
            <td style="width: 6%">&nbsp;</td>
        </tr>
        <tr id="trFacility" style="background-color: #FFFFCC">
            <td style="color: #FF0000; font-size: 11pt; width: 28%">Facility:</td>
            <td style="width: 66%">
                <asp:DropDownList runat="server" ID="cboFacility" OnSelectedIndexChanged="cboFacility_OnChanged" AutoPostBack="True" style="width: 100%"></asp:DropDownList>
            </td>
            <td style="width: 6%">
                <asp:Button runat="server" ID="cmdFacility" Text="Details" style="background-color: navy; color: #FFFFFF; font-size: x-small;" OnClientClick="gotoFacView()" Enabled="False" />
                <input id="txtFacility" name="txtFacility" hidden="hidden" />
            </td>
        </tr>
        <tr id="trConMet" style="background-color: #FFFFCC">
            <td style="color: #FF0000; font-size: 11pt; width: 28%">Contact Method:</td>
            <td style="width: 66%">
                <asp:DropDownList runat="server" ID="cboConMet" OnSelectedIndexChanged="cboConMet_OnChanged" AutoPostBack="True" style="width: 100%">
                    <asp:ListItem Text="--Pick One--" Value="0"></asp:ListItem>
                    <asp:ListItem Text="Phone" Value="P"></asp:ListItem>
                    <asp:ListItem Text="Fax" Value="F"></asp:ListItem>
                    <asp:ListItem Text="Email" Value="E"></asp:ListItem>
                    <asp:ListItem Text="Text" Value="T"></asp:ListItem>
                </asp:DropDownList>
            </td>
            <td style="width: 6%">&nbsp;</td>
        </tr>
        <tr id="trReqBy" style="background-color: #FFFFCC">
            <td style="color: #FF0000; font-size: 11pt; width: 28%">Requested By:</td>
            <td style="width: 66%">
                <asp:TextBox ID="cboReqBy" runat="server" AutoPostBack="True" style="width: 96%"></asp:TextBox>
            </td>
            <td style="width: 6%">&nbsp;</td>
        </tr>
                    <tr><td colspan="3">&nbsp;</td></tr>

                    <tr>
                        <td colspan="3">
                            <table width="99%">
                                <tr>
                                    <td align="center" width="33%">
                                        <asp:Button ID="cmdAddCancel" runat="server" Text="Cancel" style="background-color: navy; color: #FFFFFF; width: 125px;" OnClientClick="gotoDashBoard2()" />
                                    </td>
                                    <td align="center" width="34%">
                                        <asp:Button ID="cmdAddSaveN" runat="server" Text="Save \ New Appt" style="background-color: navy; color: #FFFFFF; width: 125px;" OnClientClick="PostMe_SA()"  />
                                    </td>
                                    <td align="center" width="33%">
                                        <asp:Button ID="cmdAddSave" runat="server" Text="Save \ Completed" style="background-color: navy; color: #FFFFFF; width: 125px;" OnClientClick="PostMe_SD()" />
                                    </td>
                                </tr>
                            </table>
                        </td>
                    </tr>

               </table>

OnChange events Rebinds data to a combo box based on prior selection and shows/hides form fields. PostME_SA run client validation code and if all passes, posts

        function PostMe_SA() {
        //*****Post Single Appointment, Reopen to save again
        //alert("hi");
        var myCheck
        myCheck = CheckMe()

        switch (myCheck) {
            case "B":
                alert("Failed Validation");
                return;
            case "G":
                //alert("Passed Validation");
                frmMain.method = "Post"
                frmMain.action = 'Intake_New.aspx?myrun=SA';
                frmMain.submit();
                return;
        }
        return true;
    }

There is an OnLoad that processes the form for first time load and when saving

    Private Sub Page_Load(ByVal Sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim myRun As String = Request.QueryString("myRun")
    txtMyRun.Text = myRun

    If Not IsPostBack Then
        txtCallDate.Text = Now()
        txtAddDate.Text = Today.ToShortDateString
        cboSvc.DataSource = Nothing
        cboSvc.Enabled = False
        cboFacility.DataSource = Nothing
        cboFacility.Enabled = False
        cmdFacility.Enabled = False
    Else
        Select Case txtMyRun.Text
            Case "SD"       '*****Add Single Appt, Send to Confirm
                Add_Appt()
                Response.Redirect("ConfirmSave.asp")
            Case "SA"       '*****Add Single Appt, Return form to edit and Add New
                Add_Appt()
        End Select
    End If
End Sub

Solution

  • I just don't see the issue here at all.

    Your first rule, and that is the WHOLE foundation of a asp.net page?

    It should not have ONE SLIGHT BIT of a issue to have, and allow post backs. It should not care. If you page blows up due to post-backs, then you simply built that page all wrong, and have adopted a design pattern that does not make sense.

    We can have a boatload of controls.

    To load those controls, maybe you do this on the first page load. That "assume" would make sense say if you coming a previous page that lets you "select" or "search" or "find" or "pick" some row of data to edit.

    However, it REALLY does not matter. The issue here is you have a page that now "cares" about a post-back, and it should not care.

    If you design things correctly, then you should NEVER care that a post back is occurring. it simply should not matter.

    I mean, keep in mind that you might place "several" buttons on the page. Each one of those can and will cause a post-back.

    Remember, ANY button on the form will:

    Trigger page load, AND THEN run the button stub.

    Now, given the above assumption, then such pages "should just" work, and work without issue until such time you hit some "save" button.

    So, now let's address the use of PostBack = false.

    That means we are on the first page load - that is NOW our event we can use to load up controls, setup defaults, walk the dog, and display our data.

    And of course since Not Postback only occurs on the "real" first page load, then we don't care about additional post backs, since our startup page load, the "real" first page load code will not run again. Since that code does not run again, then all that "load up" and "set up" of controls does not run again, and thus again we don't care, do we?

    All controls such as a drop down list (combo box), or even text boxes will NOT lose their current values.

    So, any and all buttons on the form, or even a drop down with auto-post back will trigger page load event OVER and OVER. But, as noted, we don't care, since our all important "real" first page load code is inside of our Not Postback stub where we "one time" setup what we need for that page to work.

    So a simple button click will trigger page load event, AND THEN runs our button code stub behind. But, since we made the CORRECT design assumption here, then we are free to have lots and many buttons on the form that do all kinds of things - whatever floats our boat.

    Then of course I would assume you have some kind of save button. That save button is like any other code stub:

    As noted, this suggests that you might have 2 buttons:

     Save     Save And Add new
    

    And, it DOES look like that's what you have so far.

    So, let's setup a simple edit example.

    We will load up a grid of data (ONLY first time!!!).

    User will hit edit row (post back).

    I'll hide the grid, simple show a "div" with some controls to edit the hotel.

    So, on our first page load, then we will load up the (our data). After that, we we don't have to re-load the data (unless we want to).

    So, say I have some markup like this:

    <div id="GridArea" runat="server">
        <h3>Hotels</h3>
        <asp:GridView ID="GridView1" runat="server" Width="40%"
            AutoGenerateColumns="False" DataKeyNames="ID"
            CssClass="table table-hover table-striped">
            <Columns>
                <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
                <asp:BoundField DataField="LastName" HeaderText="LastName" />
                <asp:BoundField DataField="HotelName" HeaderText="HotelName" />
                <asp:BoundField DataField="City" HeaderText="City" />
                <asp:BoundField DataField="Description" HeaderText="Description" />
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:Button ID="cmdEdit" runat="server" Text="Edit"
                            CssClass="btn myshadow"
                            OnClick="cmdEdit_Click" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    </div>
    

    And right below above, say a div to edit some data:

            <div id="EditRecord" runat="server"
                style="float: left; border: solid 2px; padding: 12px; border-radius: 12px">
    
    
                <h3>Edit Hotel</h3>
                <div style="float: left" class="iForm">
                    <label>HotelName</label>
                    <asp:TextBox ID="TextBox1" runat="server" f="HotelName" Width="280" />
                    <br />
                    <label>First Name</label>
                    <asp:TextBox ID="tFN" runat="server" f="FirstName" Width="140" />
                    <br />
         etc. etc. etc.
    

    And say right below that "edit" area, I have a div with some markup to pick a city.

    Say like this:

        <div id="citypick" runat="server" >
    
                <div style="float: left">
                    <h4>Region</h4>
                    <asp:ListBox ID="cboRegion" runat="server"
                        DataTextField="Region"
                        AutoPostBack="true"
                        OnSelectedIndexChanged="cboRegion_SelectedIndexChanged"
                        Height="200px" Width="150px"></asp:ListBox>
                </div>
    
                <div style="float: left; margin-left: 25px">
                    <h4>Country</h4>
                    <asp:ListBox ID="cboCountry" runat="server"
                        DataTextField="Country"
                        AutoPostBack="true"
                        OnSelectedIndexChanged="cboCountry_SelectedIndexChanged"
                        Width="250px" Height="400px"></asp:ListBox>
    
                </div>
    
      etc. etc. etc.
    

    So, now my page load:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
        If Not IsPostBack Then
            LoadData()
            EditRecord.Visible = False  ' hide record edit area
            citypick.Visible = False
    
        End If
    
    End Sub
    
    
    Sub LoadData()
    
        Dim strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName"
        Dim cmdSQL As New SqlCommand(strSQL)
        GridView1.DataSource = MyrstP(cmdSQL)
        GridView1.DataBind()
    
    End Sub
    

    So, I load up the grid.

    We now have this:

    enter image description here

    Note how I have post-backs left, right and center.

    For example, when I hit edit on the grid row button. I have this code:

    Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)
    
        Dim btn As Button = sender
        Dim gRow As GridViewRow = btn.NamingContainer
        Dim intPK As Integer = GridView1.DataKeys(gRow.RowIndex).Item("ID")
    
        Dim cmdSQL = New SqlCommand("SELECT * FROM tblHotelsA WHERE ID = @ID")
        cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = intPK
        Dim rstHotel As DataTable = MyrstP(cmdSQL)
    
        ViewState("PKID") = intPK
        fLoader(EditRecord, rstHotel.Rows(0))
    
        GridArea.Visible = False       ' Hide GV
        EditRecord.Visible = True       ' show edit area
    
    End Sub
    

    So, above is a post-back. It gets the database row PK id. Pulls that data, and then I call a handy helper routine (all that does is take the one row of data, and fill out the controls for me (we don't code that kind of task over and over - do we???).

    So, user is free to edit.

    However, I tossed in even more code (and more post-packs) to select a city.

    The city selector button does this:

    Protected Sub cmdGetCity_ServerClick(sender As Object, e As EventArgs)
    
        EditRecord.Visible = False
        citypick.Visible = True
    
        Dim cmdSQL =
                New SqlCommand("SELECT region from vRegion ORDER BY region")
    
        Dim rstData = MyrstP(cmdSQL,, My.Settings.Countries)
        cboRegion.DataSource = rstData
        cboRegion.DataBind()
    
    
    End Sub
    

    Again, we now hide the "edit div area", and run some code to load up the listbox of "regions", and let the user "have at it".

    The save button for the edit area is this:

    Protected Sub cmdSave_ServerClick(sender As Object, e As EventArgs)
    
        Dim intPK As Integer = ViewState("PKID")
    
        Call fWriter(Me.EditRecord, intPK, "tblHotelsA", GetConstr)
    
        LoadData()      ' refresh grid to show edits
        GridArea.Visible = True
        EditRecord.Visible = False
    
    End Sub
    

    So, again, I am free as a bird to write code, drop in EVER more buttons and add EVER more code to that form. Note how I never gave one bit of concern for any post-backs. And the REASON I don't care is due to having coded the page to never care in the first place.

    Now, I suppose, we could add an extra button to the save.

    It could be a Save + new button. All that would do is save the current record, and then clear out most of the fields, and let me edit and now hit save again.

    See the point? We don't care about post-backs, and the controls on the page keep their values - they are retained automatic for you.

    EVEN the visible state of the 3 div areas (grid, edit, city pick) also persisted automatic for me, and I did not even have to save or manage the state of those 3 major areas I have on the form. And ALL of them had buttons that I was free as a bird to just drop in wee little code stubs based on post-backs.

    So, you have to move things around on your form, and your page load event ONLY job is to load up first data on that first REAL page load.

    After that, you drop in as many save, or buttons to do whatever the heck you want, including saving of data, or maybe a save data, and then "clear out" some of the form controls for adding the new record.

    If you wish, I'll add a 4th button to the "edit area" that saves current record, clears out some controls, and thus I am now adding a new record with some of the data carried over. And I bet I can add that feature in WELL under 5 minutes, and it will amount to me just dropping in another plain Jane asp.net button with a client event - and I again get to enjoy only having to write a little code stub with a VERY small bit of code.

    That's the power of event-driven code, and what makes web forms so very amazing is that desktop "simple" approach can be carried over to web forms.

    Edit 2: NO, we are not navigating to another page

    Here is another screen cap. The above edit button from the GV is posted above AS IS, and I do NOT navigate to another page.

    This screen cap shows this working with the URL in plain view.

    enter image description here