0

I have a need to check for duplicate data in the database before insert and if a duplicate is detected, give the user a choice to either continue the save operation or make changes to what is being saved and try again. I have tried using Windows.Forms.MessageBox.Show but I found that will not work for what I was trying to do. A little later, I found this code

If Not Page.ClientScript.IsStartupScriptRegistered(Me.GetType(), "confirm") Then Page.ClientScript.RegisterStartupScript(Me.GetType, "confirm", "confirm('" & Message & "');", True) End If

from this post Call javascript from vb.net code behind and gave it a try. But I was never able to get to the confirm dialog to show. I was trying to build the message string using String.Concat() and pass it in with the call but it still wasn't working so I ended up taking the constructed string out and replacing it with a hard coded one. After that, I was able to get the message to show. But what happens is that the dialog is displayed after all of the lines in the method have executed. I need to be able to display this message during code execution and I need to be able to use the value that is returned from it for further processing. Can anyone help me with the following: Why do the dialogs display only after the code has been executed? How can I build and display the string that is displayed in the confirm dialog?

billy_blanks
  • 105
  • 1
  • 3
  • 12

1 Answers1

0

Why do the dialogs display only after the code has been executed?

Because you don't grasp how the web and asp.net works.

Your code behind CAN NOT , and DOES not, and NEVER interacts directly with the user.

your code behind in a web site ONLY runs AFTER the user does action, and the web page travels up to the server. the code behind can the ONLY modify the web page - not interact with the user. When ALL OF your code behind is done then the WHOLE web page is now sent back down to the end user. As a result, if your code behind stops, or waits, or halts, then the web page is STILL stuck up on the server.

ONLY after your code runs, and the WHOLE PAGE is sent back down to to the client side, the browser then re-loads re-plots and now the web page is back sitting on the customers desktop computer. The web server?

It blows up, blows out and destroys the form variables, destroys the web page, and now the web server is just waiting for ANY of the say 20 users who have some web page on their desktop. The web server does NOT have 20 different pages loaded.

The web server does NOT have 20 sets of variables. NOTHING exists server side.

Now, when one of the 20 users clicks on a button on their web page?

it is posted, or travels up to the web server. The web server processes the incoming web page, loads the correct web page. The values and MORE important all of the code and variables in that web page are RE-CREATED. They start OVER EACH time. (else how would one web server handle many users?). I mean, you can type at your monitor - but you can't have 20 people do that, can you? So each request is a new process for that web page.

Now, your code runs (the user waiting on the other end with their web browser). When you code is done, or even modifies a simple text box? The end user SITLL does not see those changes. When (and ONLY when the code behind is done), then the web page finishes rendering. and then the WHOLE web page is now sent back down to the client side (and it over-writes what they were looking at!!!).

So, this so called round trip looks like this:

A web page is sitting on their users desktop. So you have this:

enter image description here

NOTE very careful - no web page is LOADED on the server side. Your textboxes, and C#/vb.net code behind is NOT even loaded!!! - no values or variables exist!!!

So the user say clicks on a button.

So this happens:

enter image description here

So the page is posted - traveling up the web server.

So now we have this:

enter image description here

So the web server now goes gets the correct web page. It loads, ALL the code and variables in that page are re-created from scratch!!!

Then and ONLY then does the code behind start to run. That code can modify text boxes, do whatever. However, ZERO interaction to the user can occur here.

Now, there is NO way for the code behind to halt, or wait for user input. The code can ONLY run, and can ONLY modify the page - (the users web page is not changing, they do NOT see ANY code run, and even as you modify text boxes etc., the user does NOT see those changes).

Now when all your code is done making changes to the web page?

Then the web page is NOW send back to the user.

enter image description here

The browser now re-loads that WHOLE page!!! (it often don't look like it, but the WHOLE page is re-created now).

And on the server side? That web page is now tossed out, removed from memory, and all the variables you had in code are destroyed and removed from memory. The web server is now ready to process any new web page posted from ANY of your many users.

So, you can't halt code and wait for input, can you?

I mean, say on the desktop, we have a button, and two text boxes. When we click on the button, I will ask you for TextBox1 value, and then for TextBox2 value.

We have this:

enter image description here

And we can prompt (and have code HALT/WAIT) with this:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    ' ask for Text Box 1 value

    TextBox1.Text = InputBox("Enter Value for Text box 1")

    TextBox2.Text = InputBox("Enter value for Text box 2")

End Sub

So, when we run, we get this:

enter image description here

So, the code halts, waits for input, and then gets shoved into the text box.

However, now, lets try this with the web.

Button, two text boxes like this:

enter image description here

So, I can now double click on the button and write this code:

Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    TextBox1.Text = "hello"

End Sub

Now, the above works, since the WHOLE page is posted.

Lets now say I want to "confirm" the above button. ASK the user before I set the text to hello?

Well, I can't do this with code behind. And re-view the above grapic images. And review then 100 times until you grasp this. You MUST grasp that post-back or so called round trip concept.

So, how could we prompt? Well, lets do the easy idea.

To prompt the user interactive? We can NOT use code behind!!!

So, what I could do is this for the button:

We have to introduce client side code - we have to GET USER input from the CLIENT SIDE - we can't use code behind!!!

So, I could do this:

        <asp:Button ID="Button1" runat="server" Text="Button" Width="85px"
            OnClientClick="return myask();"  />

        <script>
            function myask()
            {
                return confirm("Do you want hello in the text box?")
            }
        </script>

So button is SAME as before, but we now prompt. When we run above web page we get this:

enter image description here

So we are running code CLIENT side - the server could at this point even be un-plugged. We NOT posted back the button click.

Now it turns out, if you drop a button into a web page, then wire up a client event, you can ADD the OnClientClick to the above!!!! And if you return true, the buttion click fires, and if you return false the button click does not fire.

So note again, we can't write or create a server side loop to prompt over and over. However, we COULD create a client side one!!!!

However, since we would have to display that information anyway? Then display the information in a grid have some check box for each row, user clicks on each check box, and then has ONE submit and you accept or reject all the choices in ONE shot.

If you don't do the above (which is much less pain and suffering for your users), and you really needed a prompt/yes/no for each choice? You would STILL have to package up the code, package up the markup, package up the information and STILL send it down to the client side. And as noted this is due to that code behind NEVER interacts with the user - but ONLY can make changes to the web page. And only make change WHILE that web page is up on the server being processed by code behind.

So, in place of a series of yes/no prompts (which will torture your users to death), then you need to take that data, or whatever in question. Render it in some grid, and then send the whole thingy down to the client side. At that point they can use a UI to make their choices, and THEN and ONLY then can you now pass those many choices back up to the server.

So, say I want to process some reocrds?

Since I can NOT use a server side loop, halt code, prompt user?

Well, then I suppose I could pagage up all the informtion, send it down to the browser, and then loop/ask the user. but you would STILL have to send all the information down to the client side for those yes/no responses.

So, you better off to display the information - add some check box row say like a grid for example:

    <div style="width:40%;padding:25px">
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID" 
            CssClass="table">
            <Columns>
                <asp:BoundField DataField="Firstname" HeaderText="Firstname"  />
                <asp:BoundField DataField="LastName" HeaderText="LastName"  />
                <asp:BoundField DataField="City" HeaderText="City"  />
                <asp:BoundField DataField="HotelName" HeaderText="HotelName"  />
                <asp:BoundField DataField="Description" HeaderText="Description"  />
                <asp:TemplateField HeaderText="Confirm" ItemStyle-HorizontalAlign="Center">
                    <ItemTemplate>
                        <asp:CheckBox ID="CheckBox1" runat="server" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>

        </asp:GridView>
        <br />
        <asp:Button ID="cmdConfirm" runat="server" Text="Confirm and process" />

So, code to load could be this:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then LoadGrid() End If End Sub

Sub LoadGrid()

    Dim strSQL As String =
        "SELECT TOP 5 P.ID, P.Firstname, P.LastName, tblHotels.City,
        tblHotels.HotelName, Description FROM People AS P
        LEFT JOIN tblHotels ON P.Hotel_ID = tblHotels.ID"

    GridView1.DataSource = MyRst(strSQL)
    GridView1.DataBind()

End Sub

And we now have this:

enter image description here

So NOW in place of say 5 yes/no/confirm prompts. we SEND the whole deal down to the browser. User can select which records to process or confirm, and we have ONE button for this.

So, in web land, you have to "package up" what you want to ask. Send down to user. User makes choices, and THEN you send the whole deal and lot back up to the server.

In effect, you MUST change your approach to coding, and UI.

In fact, one of the reason that users often love web software?

Becase the developer can't torture them to dealth with a zillion yes/no prommpts - it not really even possbile. As a result, you the developer now have to take extra time, and cook up a UI that allows the user to make all those yes/no choices with GREAT ease, and in fact MUST present the choices first, and then let user make their choices and then in one single button, you send those choices back to server side for process.

Not only does this prevent torture and abuse of human beings, it also tends to result in a better user experience anyway.

So, don't' crack and hit and abuse your users with baseball bats, and constant whack and damage your users by hitting them over the head with a whole bunch of yes/no prompts in a loop. Your users will be more happy, mankind and humans will be more happy, and you over all be forced to do some extra work on your part so you don't abuse and hurt your users with all those prompts - which you can't practical do anyway!!!

So, in above, to process the selected rows of choices, then this code behind the buttion:

Protected Sub cmdConfirm_Click(sender As Object, e As EventArgs) Handles cmdConfirm.Click

    ' process each row of grid - get check box rows only

    For Each gRow As GridViewRow In GridView1.Rows
        Dim ckBox As CheckBox = gRow.FindControl("CheckBox1")

        If ckBox.Checked Then
            ' get PK row 
            Dim pkID As Integer = GridView1.DataKeys(gRow.RowIndex).Item("ID")
            ' do whatever based on PK row ID from database
            Debug.Print("To process ID = " & pkID)
        End If

    Next
End Sub

So, note back up - we CAN introduce a "confirm" to a button that say will delete data etc. And we can "intercept" a button click to prompt with JavaScript confirm to execute (click) the button, or not based on that dialog.

But, what we CAN NOT do is run some loop server side, and halt code, and have a prompt in that loop for server side code (due to the nature of how code behind runs - it never really interacts directly with the user like with desktop software. It can only interact AFTER the user done something, and the WHOLE web page is then posted back up to the server for that code behind to run and process WHAT the user did on that web page.

Now, it would be in theory possible to loop and prompt yes/no in 100% client side software (JavaScript). But that would force you to send down all the choices down to the browser in one shot for that processing. Since we have to "gather up" all that choice information? Then as above shows, might as well build some grid, or other type of web UI that presents all the choices all at once anyway, since those choices no matter what solution you choose will involve sending the choices DOWN to the client side for user to pick/choose, and THEN a post-back to the server for code behind to process those choices.

Albert D. Kallal
  • 42,205
  • 3
  • 34
  • 51