postback in asp doesn't refresh control value - asp.net

I have a div(runat=server) that contain repeater,this repeater is getting is value from datatable
when the datatable is empty I do this line of code in asp .net function
divname.innerHTML="<img src="...>"
on this page there is also a asp:button that fill the datatable with values.
when pressing the button ,the above line isn't excute,the page offcourse is doing postback, but the div content isn't changing back to his original value(the repeater).
What do I have to do in the postback in order to force the div to get his original values?
This is code example:
sub page_load(..
if ispostback=false then
run_div()
end if
end sub
sub run_div()
if datatable.Rows.Count=0 then
divname.innerHTML="<img src="...>"
end if
end sub
sub filldata(....
fill datatable
repeater.datasource=...
repeater.databind
run_div()
end sub
html look like this
<div runat=servver id=divname><asp:repeater>.....
<asp:button onclick="filldata">
Thanks for any help

Assuming the variable named datatable is a System.Data.DataTable, remember that it only exists and had data in the context of a sibgle run of the page lifecycle. if the page is re-generated (whether it's via a postback or an initial load of the page) the DataTable is empty until it's loaded.
However, the Repeater object is stored in teh ViewState. IT will have values on a postback if there were rows on the previous load.
Instead of looking at the number of rows in the table, you should be looking at the Repteater.Items.Count.
If repeater.Items.Count = 0 Then
divname.innerHTML="<img src="...>"
Else
...
End If

Related

dropdownlist selectedvalue doesnt change

I have this dropdownlist, this one load with the data that I get from a store procedure, as you can see the load is correct, but when I change the selected value in the debug the selected value doesnt change, it stays in the first loaded value, which in this case is 1. What can I do?
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim adaptador As New SqlDataAdapter
Dim datos As New DataTable
Dim ord As SqlDataReader
Conexiones.AbrirConexion()
Conexiones.Cnn.Open()
Dim cmd As SqlCommand = New SqlCommand("sp_devolver_empresas", Conexiones.Cnn)
cmd.CommandType = CommandType.StoredProcedure
ord = cmd.ExecuteReader
datos.Load(ord)
cbEmpresas.DataSource = datos
cbEmpresas.DataTextField = "Nombre"
cbEmpresas.DataValueField = "Identificador"
cbEmpresas.DataBind()
Conexiones.Cnn.Close()
End Sub
For EVERY web page that you build and write to the end of time?
You MUST always put the load and setup code inside of a check for post back.
every button, every drop down list, and EVERY time you click on a button or do anything, the page load will ALWAYS fire and run. Thus if you change a value, you will lose that value since the page setup and loading of say control (in this case your dropdown list) will fire EACH time - thus overwriteing.
Out of the last 100's of web pages, the FIRST thing I write is the check for postback.
So, your code should look like this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadData
End If
End Sub
Sub LoadData()
Dim datos = New DataTable
Using onexiones.Cnn
Using cmd As SqlCommand = New SqlCommand("sp_devolver_empresas", onexiones.Cnn)
cmd.CommandType = CommandType.StoredProcedure
onexiones.Cnn.Open()
datos.Load(cmd.ExecuteReader())
End Using
End Using
cbEmpresas.DataTextField = "Nombre"
cbEmpresas.DataValueField = "Identificador"
cbEmpresas.DataSource = datos
cbEmpresas.DataBind()
End Sub
So, only on the "real" first page load do you want to load up your grids, dropdowns etc. Remember, even a simple button dropped on to the page, and you have a click event? (the page load event fires each time - and every time). So once again, you need the IsPostBack test - and I am quite pressed to find any of my web pages that does not have this all important code stub in the on-load event.
So, remember the above rule - always setup your setup code to run on first time - not every time a button or anything else occurs on the web page. So, page load (unlike desktop) fires each and every time you do ANY operations on that page.
Also, note how I setup the data text, and value field BEFORE we give the drop down list a data source. In fact, I would suggest you put the data text, and data value field in the markup and NOT code (since then multiple different code routines can use that setting - not hard coded in code).
eg do this:
<asp:DropDownList ID="cbEmpresas" runat="server"
DataTextField = "Nombre"
DataValueField = "Identificador" >
</asp:DropDownList>
So, now your code becomes :
cbEmpresas.DataSource = datos
cbEmpresas.DataBind()
I suppsoe some out of habt like to set the text + data settings for the dropdown list in code, but then again, in code you might want more then one palce that loads up the combo box - and thus you now have multiple places for those two settings. And better yet, you can even use the property sheet during design time to make the settings. (this is a "minor" issue, but I just perfer those settings in the markup as opposed to writing them in code for text/data settings).
At the end of the day? Just remember that golden rule: have that "test" for postback so you have a REAL first page load event code inside that if/then. In fact, you really can't even build a fnctional working web page if you break this rule. As noted, I count about 1-2 of my web pages out of 100's tht don't have that not postback code stub. It is quite much as important say compared to humans having to breathe air to function.
And why such a long post about this simple issue? Well on a near daily bases, both c# and vb.net questions are posted about how some combo box, grid view or just about anything else is "broken" and not working. And the answer 9 out of 10 times?
The developer forgot to use a Not IsPostBack code stub in their page load code.
If I was teaching asp.net, this would be the first lesson - ALWAYS use and consider the requirement for the Not IsPost back stub. You need that in 99% of your web pages. Or at the very least in ANY web page in which you have code to run on page load to setup grids, dropdowns, repeaters - don't matter what, you will NEED that code stub. So important, I often wonder if they should have create a even called first page load? It would have eliminated the daily posts and questions on SO that fail as a result of not heeding the above simple advice.
Edit: Now how to get selected value in code
Ok, now that we fixed up the code to setup the dropdown list, we now want to get in our code the value when the user makes a choice in the dropdown list.
You of course have code to fill the dropdown, BUT we also have to set autopostback = true for this dropdown.
So, say code to load:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadData
End If
End Sub
Sub LoadData()
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String =
"SELECT ID, HotelName from tblHotels ORDER BY HotelName"
Using cmdSQL As SqlCommand = New SqlCommand(strSQL, conn)
conn.Open()
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
cboHotels.DataSource = rstData
cboHotels.DataBind()
End Using
End Using
End Sub
And now the selected index changed event:
so, our debug output would then look like:
output:
combo selected value = 82
combo selected Text = Canadian Rocky Mountain Resorts
And as noted, make sure you set auto-post back true in the property sheet, or in the markup. The combo box for above in markup thus is this:
<asp:DropDownList ID="cboHotels" runat="server"
DataValueField="ID"
DataTextField="HotelName" AutoPostBack="True">
</asp:DropDownList>

Populate checklist in another webform

I have checklist with multiple selections now the user will preview the form in another webform after press preview button the issue here that the checklist not populated in the other form with all selections and only item selected
In first form I wrote the below code:
Dim Fruit as String = ChkFruit.SelectedValue
Redirect.response(home.aspx?"fruit=" + Fruit)
In second form I wrote the below code:
ChkFruit1.Selectedvalue = QueryString("Fruit")
Well in your example posted code, if we are to ONLY PASS one selected value, then what you have is a good start.
However, VERY NEW BIG LARGE MASSIVE different problem is now we allow "many" selections in the check box list. So with a NEW HUGE LARGE DIFFERENT kind of question and problem?
Then we will as a result need a VERY different solution. The large new big massive problem here is how to pass 1 value, or 15 choices? This of course as noted is quite a more difficult problem and challenge.
For passing a "list" or "array" of a whole bunch of possbile choices, then I suggest we do NOT use the URL parmaters (query parms in the URL).
So, what we need here is to build up some "list" of choices from the check box list, and pass that to the 2nd page. Now there are more ways to do this then there are flavors of ice cream, and we have a LOT of choices.
However, I going to suggest creating a List of chocies, and we pass that to the 2nd page we jump to.
So, our markup and button in the first page can look like this:
<asp:CheckBoxList ID="CheckBoxList1" runat="server">
<asp:ListItem>Apple</asp:ListItem>
<asp:ListItem>Grapes</asp:ListItem>
<asp:ListItem>Bananna</asp:ListItem>
<asp:ListItem>Cherry</asp:ListItem>
</asp:CheckBoxList>
<br />
<br />
<asp:Button ID="Button2" runat="server" Text="Submit" Width="158px" />
Ok, above is quite nice - not complex.
Now, for our button code? We need to build up, get/grab/obtain the list of selected values - that's what we will pass to the 2nd page.
So, above looks like this:
So, now our button/submit code on this web page:
Protected Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim MyCheckList As List(Of String) = New List(Of String)
For Each MyItem As ListItem In CheckBoxList1.Items
If MyItem.Selected Then
MyCheckList.Add(MyItem.Value)
End If
Next
Session("MyCheckList") = MyCheckList
Response.Redirect("Test2.aspx")
End Sub
So, in place of "url messay parmaters"?
We create a List type variable (they are somewhat the same as an array()
We then add all selected items to that new list
We then stuff/place the new list into Session()
We then jump to the 2nd web page with the Reponse.Redirect
Ok, so now, on the target web page, we have to get that list we passed.
Now, on the 2nd page, the code ONLY needs that list.
but, lets assume that we have the same check box list on that 2nd page - and we want to fill out - show/display/have the Check box list show the same choices.
WHAT IS IMPORTANT here is how we are free to use the "list" we passed to that 2nd page. I can do anything with that nice list , but we have this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim MyCheckList As List(Of String) = Session("MyCheckList")
' display the list of passed check box values
For Each MySelected As String In MyCheckList
Debug.Print(MySelected)
Next
' or say fill out a check box list we have on this new page -
' process EACH check box list item
' check if in our list - if yes, then check box/select it
For Each MyItem As ListItem In CheckBoxList1.Items
MyItem.Selected = MyCheckList.Contains(MyItem.Value)
Next
End If
End Sub
So, in this 2nd page, we demonstrate two examples.
First part of code example - JUST display the list of previous selections. You are thus now free to for each loop and process the check box list of selections.
Second part of code example. We actually take that list and check box a whole new check box list we have on the 2nd target page. Now, I doubt the check box list would be the same and duplicated on that 2nd page, but this code example shows how we could display the check box list "again" on the 2nd new target page.
And the code also demonstrates how to loop/process the list of selections, which is really at a the end of the day the most valuable part of this example code
So, in our 2nd page, if we have this markup:
<asp:CheckBoxList ID="CheckBoxList1" runat="server">
<asp:ListItem>Apple</asp:ListItem>
<asp:ListItem>Grapes</asp:ListItem>
<asp:ListItem>Bananna</asp:ListItem>
<asp:ListItem>Cherry</asp:ListItem>
</asp:CheckBoxList>
<br />
Then we would see this:
So when you have MORE then just one value to pass to the next page?
Then you can use session() in place of messy and difficult to use URL "parmaters". And those URL paramters are not all that great for passing "many" values like this new problem required.
If we were to only pass ONE value, and ONE selection, then the URL parmaters would be ok to use. But now since we need to pass "many" values then using session() to pass that information to the 2nd target page becomes a whole lot less work and efforts on your part.

A populated Table returns no rows

In a web application I am writing, I populate a HTML table with a button press; after the table is populated, then the user can click another button to export the table in a CSV file.
The issue is that, while the table is properly populated at he first button pressing, it appears to be empty when the application query it at the second button press.
A few code to explain the issue:
the HTML in ASPX page
<asp:Button ID="BTNPopulate" runat="server" Text="Populate" />
<table id="Table1" style="border-width: 1px; border-color: Black; padding: 5px" cellspacing="0" runat="server" />
<asp:Button ID="BTNExport" runat="server" Text="Export" />
now the first button
Protected Sub BTNTest_Click(sender As Object, e As EventArgs) Handles BTNTest.Click
Dim row As HtmlTableRow
Dim cell As HtmlTableCell
row = New HtmlTableRow()
row.BgColor = "Gray"
cell = New HtmlTableCell()
cell.Controls.Add(New LiteralControl("Test cell"))
row.Cells.Add(cell)
Table1.Rows.Add(row)
end sub
and the table is properly populated.
I was unable to obtain any info from it and in fact if I call the .Rows.Count method anyway in the second button click code-behind
Protected Sub BTNExport_Click(sender As Object, e As EventArgs) Handles BTNExport.Click
Response.ContentType = "text/csv"
Response.AddHeader("Content-Disposition", "attachment; filename='PFExport.csv'")
CSVBuilder.Append(Table1.Rows.Count)
Response.Write(CSVBuilder.ToString)
Response.Flush()
Response.End()
End Sub
the result in the file is always 0.
On the other hand, if I call the same .Rows.Count property at the end of the populate part of the code, it properly returns the result.
I tried to use the ASPTable instead of the HTMLTable, but the issue is the same.
I assume I am missing something basic here, not sure what.
ASP.NET (or anything on the web ftm) works over HTTP. HTTP is stateless. That means that whatever you do in one request is completely lost when you make a new request.
ASp.NET webforms tries to hide this from you by using something called ViewState. It's essentially a hidden field which it sends back and forth to repopulate your page every time you do a roundtrip. When the server reconstructs the page, it reads the info from the ViewState that was sent in and rebuilds the page from those values.
The problem you're having is that the page is not repopulated yet when your click-handler is triggered. There's two ways to fix this.
(preferred): Instead of reading the data from the table in the UI, just look it up in the database again.
Set a flag on the page in the click-handler and populate the CSV on the PreRender-event.
As explained by Kenneth, my error to think the information to be preserved between requests, while HTTP is stateless.
So I investigate this from a different perspecitve and I ended up using View State to store the information locally and retrieve it to generate the CSV at the Export button press.
So, to store the info I use
ViewState("TableResultsState") = CSVBuilder.ToString
immediately after the table is populated.
For the export button, I do
With Response
.ContentType = "text/csv"
.AddHeader("Content-Disposition", "attachment; filename='PFExport.csv'")
.Write(ViewState("TableResultsState").ToString)
.Flush()
.End()
End With
As the text quantity is limited, from my research I understand this should not have adverse effects.
Again, thanks to Kenneth for pointing out my very basic misunderstanding.

Input field goes blank when Submit is clicked

This is an existing Visual Studio 2003 project (written in VB). There is an input form which contains many fields including a due date field. This field is popultaed based on the value selected in Reason type dropdown and it was also editable. Recently, I had to disable the due date field so that the populated value could not be changed (based on the logged in user). The probelm I am facing is that when the Submit button is clicked, an IE popup window opens and the vlaue in the `due date' field just disappers and becomes blank.
Private Sub btnSubmitOrdersTab_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmitOrdersTab.Click
If Not Me.txtPRCEmail.Value.Length = 0 Or Not hPRCEmail.Value.Length = 0 Then
SubmitClick()
Else
RegisterStartupScript("PRCEmail", "<script language=javascript>window.open (""" & CType(Application("cBaseURL"), String) & "administration/supervisors/Orders/prc_email_reason.aspx"",null,""height=200,width=400,status=yes,toolbar=no,menubar=no,location=no"");</script>")
End If
End Sub
I tried to get the value of the due date just before the RegisterStartupScript() function using duedatevalue = Me.txtDueDate.Value, but it is blank.
Is there any way that I can prevent the due date field from becoming blank. This is not an issue if the due date field is not disabled.
This is the Java Script function I am calling from the onload event of the <body> to disable the due date.
function DisableDueDate()
{
if (udisable == "true")
document.getElementById("divduedate").setAttribute('disabled',true);
else
document.getElementById("divduedate").setAttribute('disabled',false);
}
The reason I used disable is because the due date is in a <td> tag along with a gif next to it (not a server control), which pops up a calender when clicked so that the user can select a date. I want the entire content of the <td> tag disabled- including the gif.
In the btnSubmitOrdersTab_Click event you can save the value of the due date in a Session, and then in the Page_Load you can get the value from the Session and set the due date field with it.
Use readonly instead of using disabling the textbox, if you want to read the value of the texbox on server side.
document.getElementById("divduedate").setAttribute('readonly',true);
OR
document.getElementById("divduedate").readOnly=true
OR
Using jQuery:
$('#readonly').attr("readonly", true)
Disabled attribute will not allow "divduedate" to post its value to the server.
Don't set the Enabled property to False. Instead, use the ReadOnly property and set it to true.

DevExpress - Xtra Reports: VB.NET How to get current page number?

I've searched their site. I just want to find the page number in the vb script. I have a report header, and if it is on page #1 then I want a page break after.
This code should do the trick. It's the PrintOnPage event handler for a label in your Report Header.
Private Sub xrLabel1_PrintOnPage(ByVal sender As Object, ByVal e As DevExpress.XtraReports.UI.PrintOnPageEventArgs) Handles xrLabel1.PrintOnPage
If e.PageIndex > 0 Then
ReportHeader.PageBreak = DevExpress.XtraReports.UI.PageBreak.None
Else
ReportHeader.PageBreak = DevExpress.XtraReports.UI.PageBreak.AfterBand
End If
End Sub
Note that the PageIndex value is zero-indexed. Also, the page index is only available (as far as I know) in the PrintOnPageEventArgs, so this won't work in a Before/AfterPrint event.
See this knowledge base article for reference.

Resources