DropDownList SelectedIndex value not updating on AutoPostback - asp.net

It looks like this question was addressed here, but his solution did not work for me. I am creating a dynamic dropdown menu system that populates a secondary dropdownlist with the results of a query based on the selected item in the first dropdown.
First dropdown getting populated:
Dim db As New linqclassesDataContext
Dim categories = (From c In db.faq_cats)
NewFaqDropDownCategory.DataSource = categories
NewFaqDropDownCategory.DataTextField = "category"
NewFaqDropDownCategory.DataValueField = "category_id"
NewFaqDropDownCategory.DataBind()
Unset(categories)
Unset(db)
Second dropdown getting populated:
Protected Sub NewFaqDropDownCategory_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim temp As Integer = CInt(Val(NewFaqDropDownCategory.SelectedIndex))
MsgBox(theDrop.SelectedValue)
Return
'Dim db As New linqclassesDataContext
'Dim faqs = (From f In db.faqs Where f.category = NewFaqDropDownCategory.SelectedValue)
'NewFaqDropDownList.DataSource = faqs
'NewFaqDropDownList.DataTextField = "question"
'NewFaqDropDownList.DataValueField = "id"
'NewFaqDropDownList.DataBind()
'NewFaqLabel.Visible = True
'NewFaqDropDownList.Visible = True
'Unset(faqs)
'Unset(db)
End Sub
The markup for the first dropdown...
<asp:DropDownList ID="NewFaqDropDownCategory" AutoPostBack="true" runat="server" OnSelectedIndexChanged="NewFaqDropDownCategory_SelectedIndexChanged">
</asp:DropDownList>
And the second...
<asp:DropDownList ID="NewFaqDropDownList" runat="server" Visible="false">
</asp:DropDownList>
No matter what I have tried, I always get "1" (the value of the first item in the second dropdown). The post I referenced earlier said this had to do with AutoPostBack and the server not knowing the list was updated yet.
Can anyone clarify this for me a little more?

Set a break point on the line that reads: NewFaqDropDownCategory.DataBind() and one in your event handler (NewFaqDropDownCategory_SelectedIndexChanged).
I suspect the databind is being called right before your NewFaqDropDownCategory_SelectedIndexChanged event fires causing your selected value to change.
If so, you need either to make sure you only databind if you aren't in the middle of your autopostback or instead of using NewFaqDropDownCategory.SelectedIndex on the first line of your event handler you can cast the sender parameter to a DropDownList and use its selected value.

I had the same problem. Found I forgot to look if I was posting back to the page or not and I was binding my DropDownList control in the Page_Load event of the page.
I had forgot to use:
if (!IsPostBack)
{
.... do databind ....
}

I think there is a bug in your LINQ query for the second drop down box
Dim faqs = (From f In db.faqs Where f.category = NewFaqDropDownCategory.SelectedValue)
Here you are comparing SelectedValue to category. Yet in the first combobox you said that the DataValueField should be category_id. Try changing f.category to f.category_id

Related

color styling tablecell based upon value

I am trying to style tablecells based upon the text value of the cell. This is being done on specific fields to draw user attention These tablecells are hosted inside of a formview with an itemTemplate of asp:table object. The cells have an ID and are set to run at the server side so that I can grab them from codebehind.
I attempted to hook into the individual cells by handling the onDatabound, onPrerender, onLoad events of the tablecell. onPreRender is used in my code snippet but results were same on all three tablecell events. In handling these events I always had a string.empty for the text property instead of the actual value (even after databind was called). Because I didn't have the actual value my comparisons did not pass and my color styling did not get set as desired.
edit: I also tried handling the databound event of my formview to get to my cell values. No luck there either.
Here's relevant markup:
<asp:FormView ID="fvShipments" runat="server" DefaultMode="readonly">
<ItemTemplate>
<asp:Table ID="tblShipments" runat="server" GridLines="Both">
<asp:TableRow runat="server">
<asp:TableCell runat="server" ID="tbcCartonSizeOverride" CssClass="table-displayrow centerText" OnPreRender="tbcCartonSizeOverride_PreRender"><%#Eval("CartonSizeOverRide")%></asp:TableCell>
Here's relevant codebehind
Protected Sub tbcCartonSizeOverride_PreRender(sender As Object, e As EventArgs)
markAflag(CType(sender, TableCell))
End Sub
Private Sub markAflag(ByRef cell As TableCell)
If cell.Text.Trim.Length > 0 Then
cell.BackColor = Drawing.Color.Orange
Else
cell.BackColor = Drawing.Color.White
End If
End Sub
I'm not understanding why this isn't working. Unless my Eval markup solves AFTER prerender event?
Thanks for reading. I don't work with asp often so it's possible I have something simple confused here.
Ok I solved this issue by setting some datakeys on my formview object and doing a findcontrol call at runtime to get a reference to my table on the page. Here's some sample code that demonstrates what I did.
Private Sub colorReturncode()
Dim schedreturncode As Integer
schedreturncode = FormView1.DataKey(1)
Dim qtable As New Table
qtable = CType(FormView1.FindControl("table1"), Table)
If schedreturncode = 0 Then
qtable.Rows(4).Cells(2).BackColor = System.Drawing.Color.Green
qtable.Rows(4).Cells(2).ForeColor = System.Drawing.Color.White
ElseIf schedreturncode = -1 Then
qtable.Rows(4).Cells(2).BackColor = System.Drawing.Color.White
Else
qtable.Rows(4).Cells(2).BackColor = System.Drawing.Color.Red
qtable.Rows(4).Cells(2).ForeColor = System.Drawing.Color.White
End If
End Sub

ASP.NET Losing listbox binding on viewchange?

Ok so what seems like a basic problem is getting the better of me and my exstensive google efforts have come up short. Perhaps I don't understand enough to ask the right questions.
Here's my problem:
I have a formview control, or rather a series of them, each page displaying entry from previous forms, for a higher level access to approve/edit as needed. So, on form "B", I have the contents of form "A" and the blank part of "B" to filled out...So two seperate fromviews on the page.."A" and "B"
That works fine, the issue is when I change the mode to edit previous entry. So if I have a button or the default linkbutton to change from ReadOnly to Edit I not only lose bindings but any efforts to counteract that have left me with issues when I postback.
DUE TO LENGTH I'M LEAVING SOME CODE OUT
On my button I'm using FormView2.ChangeMode(FormViewMode.Edit) to change view, the default link button I've not changed
Bindings on my listboxes are setup like:
If Not Page.IsPostBack Then
'pulling bindings from table
cmd = New OleDbCommand("SELECT * FROM mslToi", objCon)
objReader = cmd.ExecuteReader
lst1.DataValueField = "listing"
lst1.DataTextField = "listing"
lst1.DataSource = objReader
lst1.DataBind()
'pre-selecting input data from form "A"
cmd = New OleDbCommand("SELECT [type_of_injury] FROM S2childToi WHERE ID = " & qs & "", objCon)
objReader = cmd.ExecuteReader
Do While objReader.Read
For Each y As ListItem In lst1.Items
If y.Text = objReader.Item(0) Then
y.Selected = True
End If
Next
Loop
end if
In the page load event.
MARKUP FOR THE FORMVIEW AS ASKED
<asp:FormView ID="FormView2" runat="server"
Width="100%" DataSourceID="AccessDataSource4">
<ItemTemplate>
</ItemTemplate>
<EditItemTemplate>
</EditItemTemplate>
</asp:FormView>
'''that is the short and sweet of the formview markup as requested. It may also be worth noting that it doesn't matter what mode I start in, if I change modes it equals same result'''
That works fine so far...it's when I change view to Edit that my listbox appears to no longer be bound (controls appear but have no content). My thought is that obviously I'm blocking out my code from postback events (I have a reason for this). I can use this code (without the If Not Page.IsPostBack) to force the selections and bindings but whenever I postback they will defualt to the table data, which can't happen, each listbox needs to postback so I can check for a certain selection. So what happens is the user input is trumped. Short and sweet.
I'm sorry that I can't explain better, any advice is much appreciated. If I can asnwer any questions or post code let me know.
Try this:
<asp:FormView ID="FormView1" runat="server">
<ItemTemplate>
<asp:ListBox ID="ListBoxReadonly" runat="server"></asp:ListBox>
</ItemTemplate>
<EditItemTemplate>
<asp:ListBox ID="ListBoxEdit" runat="server"></asp:ListBox>
</EditItemTemplate>
</asp:FormView>
Then, in your FormView's databound event, bind the data into your listbox depending on the current view.
Protected Sub FormView1_DataBound(sender As Object, e As EventArgs) Handles FormView1.DataBound
Dim myListBox As ListBox
If FormView1.CurrentMode = FormViewMode.ReadOnly Then
myListBox = DirectCast(FormView1.FindControl("ListBoxReadonly"), ListBox)
ElseIf FormView1.CurrentMode = FormViewMode.Edit Then
myListBox = DirectCast(FormView1.FindControl("ListBoxEdit"), ListBox)
End If
If myListBox IsNot Nothing Then
myListBox.DataValueField = "listing"
myListBox.DataTextField = "listing"
myListBox.DataSource = GetListingData()
myListBox.DataBind()
' your pre-select code here...
End If
End Sub

Why is My GridView FooterRow Referencing the Wrong Row?

I have a GridView and, using a fairly common method, I'm using a FooterRow and TemplateFields to provide the missing insert ability. So far so good.
The footer contains a TemplateField with a LinkButton to provide the postback that does the insertion. In the handler for the LinkButton's click, the Insert() method is called on the ObjectDataSource that the GridView is bound to. The ObjectDataSource's insert parameters are populated in the handler for its Inserting event. The code for all of this (abridged) looks like this:
Markup:
<asp:GridView ID="gvComplexRates" runat="server" AutoGenerateColumns="False"
DataKeyNames="id" DataSourceID="odsComplexMileageRates"
EnableModelValidation="True" ShowFooter="True">
<Columns>
<asp:TemplateField ShowHeader="False">
:
:
<FooterTemplate>
<asp:LinkButton ID="addLinkButton" runat="server" CausesValidation="false"
CommandName="Insert" Text="Add"></asp:LinkButton>
</FooterTemplate>
</asp:TemplateField>
:
:
</asp:GridView>
Code Behind:
Private Sub gvComplexRates_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvComplexRates.RowCommand
Select Case e.CommandName
Case "Insert"
odsComplexMileageRates.Insert()
End Select
End Sub
Private Sub odsComplexMileageRates_Inserting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ObjectDataSourceMethodEventArgs) Handles odsComplexMileageRates.Inserting
Dim fuelTypeDropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddFuelTypeInsert")
Dim engineTypeDropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddEngineTypeInsert")
Dim rateTextBox As TextBox = gvComplexRates.FooterRow.FindControl("tbRateInsert")
Dim vatRateTextBox As TextBox = gvComplexRates.FooterRow.FindControl("tbVatRateInsert")
e.InputParameters("expense_type_id") = ddExpenseTypeSelect.SelectedValue
e.InputParameters("fuel_type_id") = fuelTypeDropDown.SelectedValue
e.InputParameters("engine_type_id") = engineTypeDropDown.SelectedValue
e.InputParameters("rate") = rateTextBox.Text
e.InputParameters("vat_rate") = vatRateTextBox.Text
End Sub
Two of the fields in my FooterRow are DropDownLists that are populated from other tables. Again this works fine and I can add, edit and remove rows without problem.
The problem comes when I use a modal dialog from this page to insert extra rows into the tables used to populate the DropDownLists in the FooterRow. The insert operations work fine and the modal dialog closes and at this point I use a javascript postback (basically a call to __doPostBack()) so that my FooterRow DropDownLists can be updated. The code for this is:
Protected Sub updateFuelEngineDropdowns()
odsFuelTypes.Select()
odsEngineTypes.Select()
Dim dropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddFuelTypeInsert")
dropDown.DataBind()
dropDown = gvComplexRates.FooterRow.FindControl("ddEngineTypeInsert")
dropDown.DataBind()
End Sub
This sub, updateFuelEngineDropdowns(), is called from the Page Load event. The first time I called it it worked fine. For some reason in subsequent runs through the debugger I'm getting NullReferenceExceptions. Digging into the debug object viewer it is apparent that the GridView FooterRow is referencing the row above the footer which contains no controls (at least not at this non-editing stage) and so, quite reasonably, gives my the Null reference.
The debug QuickView expressions I use are:
gvComplexRates.FooterRow.Controls(3)
DirectCast(gvComplexRates.FooterRow.Controls(3),System.Web.UI.WebControls.DataControlFieldCell).Controls(1)
The first of these shows a tag of td. Which makes sense. The second shows text of "10" which is the content for the row above the footer.
Does anybody know why this is happening?
Thanks Dan
Where are you "providing the missing insert ability"?
You have to rebuild the footer-controls on every postback, the GridView.RowCreated-Event would be a good place.
Update:
You have to Databind your GridView after you inserted new rows into your Dropdowns' Tables.
Right, this is a bit embarrassing. I gave a little white lie in the original question. By omission rather than a deliberate attempt to mislead. I am not, in fact, using a GridView but a subclass of it that will display rows when the datasource contains no data. This enables the user to insert new rows when the table is empty. This subclass overrides the FooterRow property and, to my shame, it was this that was getting things wrong. So I made two errors here: first I failed to test my GridView subclass properly and second I sought to prevent what I thought would be unnecessary attention on my subclass by not showing its use in the code snippets I included in the question. My bad. Thanks to Tim for taking the time to try and help me.
Dan

RangeValidator not working when selecting DropDownList value using jQuery

I inherited a site which I am in the middle of updating which has a DropDownList and a RangeValidator assigned to it. The data is bound to the dropdown on Page_Load. The values are retrieved from the database so the value property of each item is set to the unique ID of the item in the DB.
The RangeValidator looks something like:
<asp:rangevalidator id="ddRangeValidator" runat="server" ControlToValidate="ddMenu" ErrorMessage="Please select value in range" MinimumValue="1" MaximumValue="100000" Type="Integer">*</asp:rangevalidator>
I have a method which automatically populates this value in jQuery e.g.
$("#ddMenu").val("An Option");
This works, however, when I try to post the page the range validation fails. Then even if I manually select that value, or select another valid value it still won't validate. The only way to make it validate is to select non-valid value and then re-selecting a valid one.
Any ideas?
Update
Here is the data binding code:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load, Me.Load
If Not Page.IsPostBack Then
Dim ds As New DataSet()
Dim myDbObject As New myDbObject()
ds = myDbObject.ToDataSet() // retrieves all objects from the database
// store the results in a temporary view to filter
Dim dv As DataView
dv = New DataView(ds.Tables(0), "IsLive = True", "ID", DataViewRowState.CurrentRows)
Dim i As Integer = 0
ddMenu.Items.Add("Select a value")
ddMenu.Items.Item(0).Value = 0
// add all objects from filtered list into drop down menu
For i = 0 To dv.Count - 1
With ddMenu.Items
// add a new item
.Add(dv.Item(i).Item("Name"))
// set the Value property as unique ID of object
.Item(i + 1).Value = dv.Item(i).Item("ID")
End With
Next
End If
End If
Turns out it was an issue with my page loading twice...so now the issue is going to be tracking down why it is loading twice!
I guess the Range validator verifies the actual "value" of the dropdown list. May it be possible that by using jQuery to populate your dropdown the actual entry doesn't get a proper option "value"? Could you maybe post the rendered HTML code of your dropdown list?

Getting edit value from ListView

I'm missing something here, but I've stared at it too long to see it. I've got a simple ListView, with the typical Edit/Update/Cancel buttons. I've got the following set up in my EditITemTemplate when the row goes into edit mode:
<EditItemTemplate>
<asp:Label ID="AccountIdLabel" runat="server" Text='<%#Eval("lan_id")%>' />
<asp:TextBox ID="EmployeeIdTextBox" runat="server" Text='<%#Eval("emp_id")%>' Columns="5" />
</EditItemTemplate>
At this point the user types a value in the EmployeeIdTextBox. When they press Update, it's trying to do the following:
Private Sub ListView_ItemUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewUpdateEventArgs) Handles EmployeeListView.ItemUpdating
Dim accountId = CType(EmployeeListView.EditItem.FindControl("AccountIdLabel"), Label).Text
Dim employeeId = CType(EmployeeListView.EditItem.FindControl("EmployeeIdTextBox"), TextBox).Text
UpdateMap(accountId, employeeId)
EmployeeListView.EditIndex = -1
GetData()
End Sub
The problem is that "employeeId" is coming back with the original value in the text box, not what the user entered. What am I missing?
UPDATE: Found it. As usual, caused by other code not included here in an effort to ask a simple question. :)
Found it - I had code in the ItemCommand event that was handling other events, but it was doing the GetData() at the end regardless of the command, so basically the data was being refreshed right before the ItemUpdating event fired. I tightened up ItemCommand, and it's now working as expected.
I think this is because the ItemUpdating event fires before the ListView updates the record. You probably want to put this code in the ItemUpdated event instead.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listview.itemupdating.aspx

Resources