Formview cascading dropdown issue - asp.net

I'm working on a Formview where in the EditTemplate, I have 1 dropdownlist dependent on another dropdownlist value.
I've looked at some examples and have found this one to be the most concise and I am working off of it:
http://mikepope.com/blog/AddComment.aspx?blogid=1629
It's pretty straight-forward but it's not working for my ddl. Can you tell me what I am missing or not implementing properly? I have removed some of the code in order to troubleshoot but still, nothing. For example, I am not setting the selectedValue as nothing is being returned...
Any advice would be appreciated.
Thanks
HTML:
<EditItemTemplate>
...
...
...
<tr>
<td colspan="6" align="left">
<asp:DropDownList ID="ddTeams" runat="server" CssClass="myDropDownIndent" DataSourceID="sqlGetTeams" DataTextField="Team" DataValueField="Team" SelectedValue='<%# DetermineTeamValue(Eval("Team")) %>' AutoPostBack="true" OnSelectedIndexChanged="DropDownList_SelectedIndexChanged">
</asp:DropDownList>
</td>
<td colspan="4" align="left">
<asp:DropDownList ID="DropDownOwner" runat="server" CssClass="myDropDown" DataSourceID="sqlGetMembers2" DataTextField="EmployeeName" DataValueField="EmployeeName" OnSelectedIndexChanged="DropDownList_SelectedIndexChanged">
</asp:DropDownList>
<asp:SqlDataSource ID="sqlGetMembers2" runat="server" ConnectionString="<%$ ConnectionStrings:ProjectDashboardConnectionString %>"
SelectCommand="usp_GetMembers" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Name="Type" />
<asp:Parameter Name="TeamID" />
</SelectParameters>
</asp:SqlDataSource>
</td>
</tr>
Code Behind:
Protected Sub fvTask_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles fvTask.DataBound
If fvTask.CurrentMode = FormViewMode.Edit Then
Dim dv As System.Data.DataRowView = fvTask.DataItem
Dim ddTeams2 As DropDownList = fvTask.FindControl("ddTeams")
Dim DropDownOwner As DropDownList = fvTask.FindControl("DropDownOwner")
Dim a As String = "A"
Dim dsc As SqlDataSource = fvTask.FindControl("sqlGetMembers2")
dsc.SelectParameters("TeamID").DefaultValue = String.Empty
dsc.SelectParameters("Type").DefaultValue = String.Empty
DropDownOwner.DataBind()
'If Not IsDBNull(dv("EmployeeName")) Then
' DropDownOwner.SelectedValue = dv("EmployeeName")
'End If
End If
Catch ex As Exception
ErrMessage = ex.ToString
End Try
End Sub
So, my 2nd dropdownlist is null.

Related

Report error, value cannot be null

I am stymied by the above error.
I have a report with a parameter called loc.
The intended purpose of the report is to allow users to select a location from the dropdownlist and then records associated with that location are displayed to the users.
The dropdownlist is getting populated with values just fine.
However, when I select a location from the dropdownlist, I get an error that says:
Value cannot be null. Parameter name: reportParameters
Everything works fine when I pass a value as textbox but not as dropdown.
Any ideas what I am doing wrong?
Below are relevant code. Please forgive me in advance for posting a lot of code.
'---Dropdownlist control
<asp:Panel runat="server" ID="pnlLoc" Font-Names="Calibri" BorderStyle="Solid" BorderWidth="1" Style="margin: 0 auto; width:300px;">
<table>
<tr>
<td>
<asp:Label runat="server" ID="lblLoc" Text="Location: " />
</td>
<td>
<asp:DropDownList runat="server" ID="ddLoc" DataSourceID="dslocator6" AutoPostBack="True">
</asp:DropDownList>
</td>
</tr>
</table>
</asp:Panel
--Report viewer control
<rsweb:ReportViewer ID="ReportViewer1" runat="server" AsyncRendering="true" SizeToReportContent="true" Font-Names="Arial"
Height="675px" Width="750px">
<LocalReport EnableExternalImages="true" ReportPath="">
</LocalReport>
</rsweb:ReportViewer></center>
<asp:ObjectDataSource ID="LOC" runat="server" SelectMethod="GetData" TypeName="ManageReportsTableAdapters.searchBylocationsTableAdapter">
<SelectParameters>
<asp:ControlParameter ControlID="ddLoc" Name="Location" DefaultValue=" " />
</SelectParameters>
</asp:ObjectDataSource>
--This code populates the ddLoc dropdownlist
Protected Sub btnLoc_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnLoc.Click
ReportViewer1.LocalReport.ReportPath = ""
pnlLoc.Visible = True
which.Value = "P"
dslocator6.SelectCommand = "SELECT location FROM Locations ORDER BY [location]"
ddLoc.DataTextField = "location"
ddLoc.DataValueField = "location"
End Sub
'Define report parameter
Dim params(0) As ReportParameter
ReportViewer1.LocalReport.DataSources.Add(New ReportDataSource("locs", LOC.ID))
ReportViewer1.LocalReport.ReportPath = "locations.rdlc"
ReportViewer1.LocalReport.Refresh()
If Not String.IsNullOrEmpty(ddLoc.SelectedValue) Then
params(0) = New ReportParameter("loc", ddLoc.SelectedValue)
Else
params(0) = New ReportParameter("loc", sel, False)
End If
ReportViewer1.LocalReport.SetParameters(params) '<-- error points to this line
I was getting this error and the problem was me setting an extra index in my array
Dim params(2) As ReportParameter
params(0) = New ReportParameter("SignatureImg", "SomeBase64StringHere")
params(1) = New ReportParameter("SignatureImgMimeType", "image/png")
ReportViewer1.LocalReport.SetParameters(params)
Because of I defined my array like this Dim params(2) As ReportParameter and i was just adding values for the first two index the value on index 3 was null and it was creating the problem.
The solution was just defined the array like this Dim params(1) As ReportParameter.

Add data to gridview, from textbox, on button click

I am working on an aspx site that lets an admin-level user fill out a form with potential member data. Once the form is filled out, the user will click submit and the data will go off to different tables. One part of the form that is stumping me involves filling out three textboxes (txtFirstName, txtLastName, txtGrade). I have a button (btnAddStudent), that, when clicked, should add the information from the textboxes to a table-like display area. I am trying to use a gridview, but there is nothing to bind it to. There is no memberID number to load a blank record from the Student table (which is a many-to-one relation to Member table). The member record is what this form is creating, and the student data will be added to the Student table when the Submit button is clicked.
I am currently working with the code found in the reply here. But when I click the "Add Student" button, I get a new blank row, but my textbox values are not inputted in the gridview.
Can this work, or do I need to look at using a table and adding rows of textboxes dynamically?
Here is relevant source code:
<tr>
<td class="style8">
<asp:Label ID="Label18" runat="server" Text="Chidren:" Font-Bold="True" Font- Underline="True" Font-Names="Tahoma"></asp:Label>
</td>
</tr>
<tr>
<td class="style8">
<asp:Label ID="Label19" runat="server" Text="First Name:"></asp:Label>
</td>
<td class="style7">
<asp:TextBox ID="txtChildFirstName" runat="server" CssClass="textbox"></asp:TextBox>
</td>
<td class="">
<asp:Label ID="Label20" runat="server" Text="Last Name:"></asp:Label>
</td>
<td class="style6">
<asp:TextBox ID="txtChildLastName" runat="server" CssClass="textbox"></asp:TextBox>
</td>
<td class="style5" align="right">
<asp:Label ID="Label21" runat="server" Text="Grade:"></asp:Label>
</td>
<td class="style4">
<asp:TextBox ID="txtGrade" runat="server" Width="52px" CssClass="textbox"></asp:TextBox>
</td>
<td>
<asp:Button ID="btnAddChild" runat="server" Text="Add Child" OnClick="btnAddChild_Click" />
</td>
</tr>
<tr>
<td valign="top" class="style8">
<asp:Label ID="Label22" runat="server" Text="Student List:"></asp:Label>
</td>
<td colspan="3">
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="gvStudentList" runat="server" AutoGenerateColumns="False"
PageSize="5" Height="42px">
<AlternatingRowStyle BackColor="#E0E0E0" />
<Columns>
<asp:BoundField AccessibleHeaderText="FirstName" HeaderText="First Name" />
<asp:BoundField AccessibleHeaderText="LastName" HeaderText="Last Name" />
<asp:BoundField AccessibleHeaderText="Grade" HeaderText="Grade" />
</Columns>
<HeaderStyle BackColor="#CCCCCC" Height="25px" />
<RowStyle Height="22px" />
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
And the Code Behind:
'A method that will BIND the GridView based on the TextBox
'values and retain its values on post backs.
Private Sub BindGrid(rowcount As Integer)
Dim dt As New DataTable()
Dim dr As DataRow
dt.Columns.Add(New System.Data.DataColumn("FirstName", GetType([String])))
dt.Columns.Add(New System.Data.DataColumn("LastName", GetType([String])))
dt.Columns.Add(New System.Data.DataColumn("Grade", GetType([String])))
If ViewState("CurrentData") IsNot Nothing Then
For i As Integer = 0 To rowcount
dt = DirectCast(ViewState("CurrentData"), DataTable)
If dt.Rows.Count > 0 Then
dr = dt.NewRow()
dr(0) = dt.Rows(0)(0).ToString()
End If
Next
dr = dt.NewRow()
dr(0) = txtChildFirstName.Text
dr(1) = txtChildLastName.Text
dr(2) = txtGrade.Text
dt.Rows.Add(dr)
Else
dr = dt.NewRow()
dr(0) = txtChildFirstName.Text
dr(1) = txtChildLastName.Text
dr(2) = txtGrade.Text
dt.Rows.Add(dr)
End If
' If ViewState has a data then use the value as the DataSource
If ViewState("CurrentData") IsNot Nothing Then
gvStudentList.DataSource = DirectCast(ViewState("CurrentData"), DataTable)
gvStudentList.DataBind()
Else
' Bind GridView with the initial data assocaited in the DataTable
gvStudentList.DataSource = dt
gvStudentList.DataBind()
End If
' Store the DataTable in ViewState to retain the values
ViewState("CurrentData") = dt
End Sub
Protected Sub btnAddChild_Click(sender As Object, e As EventArgs) Handles btnAddChild.Click
' Check if the ViewState has a data assoiciated within it. If
If ViewState("CurrentData") IsNot Nothing Then
Dim dt As DataTable = DirectCast(ViewState("CurrentData"), DataTable)
Dim count As Integer = dt.Rows.Count
BindGrid(count)
Else
BindGrid(1)
End If
txtChildFirstName.Text = String.Empty
txtChildLastName.Text = String.Empty
txtGrade.Text = String.Empty
txtChildFirstName.Focus()
End Sub
With "BindGrid()" being called in the Page_Load event. (And yes, I have ScriptManager)
Try to use
Session("CurrentData") = dt on your BindGrid()
Then Create Method that just refreshes the grid after postback:
Private Sub RefreshGrid()
{
If ViewState("CurrentData") IsNot Nothing Then
gvStudentList.DataSource = DirectCast(Session("CurrentData"), DataTable)
gvStudentList.DataBind()
Else
gvStudentList.DataSource = null;
gvStudentList.DataBind()
EndIf
}
On your page load just call:
If IsPostBack Then
Return
End If
RefreshGrid()
Regards

Passing a variable to a dynamic dropdownlist

I have 2 dropdownlists, one is State and the second is City. I am trying to create it so, when a user clicks the State, the second dropdownlist is populated with City names from a datatable.
Here is the code
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<%--<cc2:CascadingDropDown ID="CascadingDropDown1" runat="server"> </cc2:CascadingDropDown>--%>
<h1>Live Event Search Engine</h1><br />
State: <asp:DropDownList ID="ddlState" runat="server" AutoPostBack="True" DataSourceID="SqlDataSource1" DataTextField="ST_Code" DataValueField="ST_Code" /><asp:SqlDataSource
ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:dbConnection %>"
SelectCommand="SELECT [ST_Code] FROM [State]">
</asp:SqlDataSource>
City: <asp:DropDownList ID="ddlCity" runat="server" DataSourceID="SqlDataSource2" DataTextField="RS_City" DataValueField="RS_City" /><asp:SqlDataSource
ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:dbConnection %>"
SelectCommand="web_PublicProgramListbyState" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:SessionParameter Name="State" SessionField="ST_Code" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
<asp:Button ID="Submit" runat="server" Text="Submit" />
</asp:Content>
and the code behind is
Public Sub ddlState_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ddlState.SelectedIndexChanged
Me.ddlCity.Items.Clear()
Dim da As New SqlDataAdapter("web_PublicProgramListbyState", New SqlConnection(ConfigurationManager.AppSettings("dbConnection")))
Dim ds As New DataSet
da.Fill(ds, "#State")
da.Dispose()
Me.ddlCity.DataSource = ds.Tables("Products")
Me.ddlCity.DataTextField = "ProductName"
Me.ddlCity.DataValueField = "ProductID"
Me.ddlCity.DataBind()
End Sub
End Class
Looks like you are trying to bring a dataset into this when you already have a SqlDataSource defined. Just modify the parameters of the SqlDataSource and re-bind:
Public Sub ddlState_SelectedIndexChanged(...)
SqlDataSource2.SelectParameters.Clear()
SqlDataSource2.SelectParameters.Add(New Parameter("#State", DbType.String, ddlState.SelectedValue))
ddlCity.DataBind()
End Sub
Edit: Or you can use a ControlParameter referencing ddlState.SelectedValue in SqlDataSource2.SelectParameters as mentioned in another answer. Only trick there is you have to manage your default values carefully so ddlCity only binds when you want it to.
I would change it to a control param and just call the databind. No need to do the fill yourself.
<asp:ControlParameter Name="State" ControlID="ddlState" Type="String" />
and then in the select event just call:
Me.ddlCity.DataBind()
Or if you want to remove the codebehind all together put it in an update panel with a trigger.
I don't see where the ddlState_SelectedIndexChanged event writes the session variable. This is required.

LinqDataSource - filtering for null values

I am writing an ASP.Net web application. I have listview, it's datasource is a LinqDataSource. In my database, I have a staff table and I am trying filter for records by their team using a dropdownlist. This works fine, until I select "All" in the dropdownlist. It returns all staff except for the ones where the teamID is null. How can I return the records where teamID is null?
This is my code:
<asp:ListView ID="ListView1" runat="server" DataSourceID="ldsStaff" DataKeyNames="staffID">
<LayoutTemplate>
<table>
<tr>
<th>Name</th>
<th>Team</th>
</tr>
<tr>
<td>&nbsp</td>
<td><asp:DropDownList ID="ddlTeamFilter" runat="server" DataSourceID="ldsTeams" DataTextField="Team" DataValueField="TeamID" AppendDataBoundItems="true" AutoPostBack="true">
<asp:ListItem Text="[All]" Value=""></asp:ListItem>
</asp:DropDownList>
</td>
</tr>
<tr ID="itemPlaceHolder" runat="server"></tr>
</table>
</LayoutTemplate>
....
</asp:Listview>
<asp:LinqDataSource ID="ldsStaff" runat="server"
ContextTypeName="ProjectDatabase.ProjectDatabaseUsersDataContext" OrderBy="name"
TableName="Staffs" EnableUpdate="True" Where="inService == #inService && TeamID == #TeamID">
<WhereParameters>
<asp:Parameter DefaultValue="true" Name="inService" Type="Boolean" />
<asp:ControlParameter ControlID="ctl00$ContentPlaceHolder1$ListView1$ddlTeamFilter" Name="TeamID" Type="Int32" PropertyName="SelectedValue"/>
</WhereParameters>
</asp:LinqDataSource>
In my code behind I handle the LinqDataSource selecting event:
Private Sub ldsStaff_Selecting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.LinqDataSourceSelectEventArgs) Handles ldsStaff.Selecting
Dim ddl As DropDownList = CType(ListView1.FindControlRecursive("ddlTeamFilter"), DropDownList)
If ddl.SelectedValue = "" Then
e.WhereParameters.Remove("TeamID")
End If
I thought that if I removed the whereparameter when the dropdownlist is "All" it would force it to return all the records, but it doesn't work.
Please help!
Thanks,
Emma
If you are handling the selecting event anyway I would remove the Where clause in your datasource all together and handle everything in the selecting event setting the e.Result value to your linq query.
Then in your ddlTeamFilter rebind the listview on change.
Hope this helps.

Custom Paging in Child (Inner) Nested Repeaters

I am using nested repeaters with Dataset (not using Datatable) to retrieve information by passing parameters. So far I have bind the two repeaters clearly and everything is working fine.
Here the list of messages created by each user datawise(parameter passed) will be displayed, and there could be more than 50 messages created by each user daily. So now I want to do custom paging for each user.
But I am unable to proceed further, as the next, previous, back, first links are placed inside the child repeaters footer template and I couldn't access these links even by findcontrol method.
Example:
User1
No Msg Code
1 abcd Cl-6
2 some Cl-4
3 swedf Cl-3
4 sddf Cl-1
1,2,3,4,5 (Paging)
User2
No Msg Code
1 dgfv Cl-96
2 abcd Cl-4
3 sjuc Cl-31
4 liot Cl-1
1,2,3,4,5 (Paging)
In this ways goes for every user:
Public Sub CreateNestedRepeater()
Dim strSql_1 As String, strsql_2 As String
Dim strCon_1 As New SqlConnection
Dim strCon_2 As New SqlConnection
Dim ds As New DataSet()
frmDate = AMS.convertmmddyy(txtFromDate.Text)
toDate = AMS.convertmmddyy(txtToDate.Text)
strCon_1 = New SqlConnection(ConfigurationManager.ConnectionStrings("connectionString").ConnectionString)
strSql_1 = "select User_Login, User_Id from V_mst_UserMaster Where User_Flag = 1 and User_Type='CO'"
Dim daCust As New SqlDataAdapter(strSql_1, strCon_1)
daCust.Fill(ds, "RptCoord_Name")
WhereClause1 = "where MsgHdr_Id NOT IN (Select a.MsgHdr_Id from V_AMS_GetSentMsg as a Join V_AMS_GetSentMsg as b " _
& "on a.MsgHdr_Id = b.MsgHdr_PrevMsgId) and MsgHdr_Date >= '" & frmDate & "' and MsgHdr_Date <= '" & toDate & _
"'AND MsgHdr_MsgFlag='I' and MsgHdr_AckReq <> 'N'"
OrderBy = "order by MsgHdr_Date asc"
strCon_2 = New SqlConnection(ConfigurationManager.ConnectionStrings("conn_Ind_AKK_TRAN").ConnectionString)
strsql_2 = "select User_Login,MsgHdr_Date, Client_Code, MsgHdr_RefNo, MsgType_Name, MsgHdr_Subject " _
& " from V_AMS_GetSentMsg " & WhereClause1 & OrderBy
Dim daOrders As New SqlDataAdapter(strsql_2, strCon_2)
daOrders.Fill(ds, "RptCd_Record")
Dim rel As New DataRelation("CrdRelation", ds.Tables("RptCoord_Name").Columns("User_Login"), ds.Tables("RptCd_Record").Columns("User_Login"), False)
ds.Relations.Add(rel)
rel.Nested = True
Rep1.DataSource = ds.Tables("RptCoord_Name").DefaultView
Rep1.DataBind()
strCon_1.Close()
strCon_2.Close()
End Sub
Protected Sub Rep1_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.RepeaterCommandEventArgs) Handles Rep1.ItemCommand
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
DirectCast(e.Item.FindControl("Rep2"), Repeater).DataSource = DirectCast(e.Item.DataItem, DataRowView).CreateChildView("CrdRelation")
DirectCast(e.Item.FindControl("Rep2"), Repeater).DataBind()
End If
End Sub
Protected Sub Pagging(ByVal index As Integer)
Dim PDS As New PagedDataSource
PDS.DataSource = ds.Tables("RptCoord_Name").DefaultView
PDS.CurrentPageIndex = index
PDS.AllowPaging = True
PDS.PageSize = 4
Dim rep2 As Repeater = CType(e
rep2.DataSource = PDS
Rep2.DataBind()
Dim ddl As DropDownList = DirectCast(rep2.Controls(rep2.Controls.Count - 1).FindControl("PageCount"), DropDownList)
If ddl IsNot Nothing Then
For i As Integer = 1 To PDS.PageCount - 1
ddl.Items.Add(i.ToString())
Next
End If
End Sub
Public Sub PageIndex(ByVal sender As Object, ByVal e As EventArgs)
Dim ddl As DropDownList = DirectCast(rep2.Controls(rep2.Controls.Count - 1).FindControl("PageCount"), DropDownList)
Pagging(Integer.Parse(ddl.SelectedItem.Text) - 1)
End Sub
XML:
<asp:Repeater id="Rep1" runat="server" OnItemCommand="Rep1_ItemCommand" EnableViewState = "false" >
<ItemTemplate>
<table width="100%" border="0.8" cellpadding="0" cellspacing="0" CssClass="bodytext" >
<tr><td align="center" class="RepHeader" >
Incoming Messages - Pending Ack for
<%#getUser(DataBinder.Eval(Container.DataItem, "User_Login"))%> from <%= txtFromDate.Text %>
to <%=txtToDate.Text%>
<%-- OnItemDataBound="Rep2_ItemDataBound" --%>
<asp:Repeater id="Rep2" runat="server" datasource='<%#(Container.DataItem).Row.GetChildRows("CrdRelation") %>' >
<HeaderTemplate>
<table border="1" width="100%" >
<tr class="RepHeader" >
<td>Msg Date</td><td>CL Code</td><td>INCRefNo</td><td>Contents</td><td>Subject</td></tr></HeaderTemplate><ItemTemplate>
<tr class="RrpList">
<td><%#getdate(CType(Container.DataItem, System.Data.DataRow)("MsgHdr_Date"))%> </td>
<td><%#CType(Container.DataItem, System.Data.DataRow)("Client_Code")%> </td>
<td><asp:LinkButton ID="lnkRef" runat="server"></asp:LinkButton>
<a id="hrefRefNo" runat="server" href="#" class="Link" >
<%#CType(Container.DataItem, System.Data.DataRow)("MsgHdr_RefNo")%></a></td>
<td><%#CType(Container.DataItem, System.Data.DataRow)("MsgType_Name")%> </td>
<td><%#CType(Container.DataItem, System.Data.DataRow)("MsgHdr_Subject")%> </td>
</tr>
</ItemTemplate>
<FooterTemplate>
<%--Starts Here - (Paging for Pending Nested Repeaters) --%>
<tr align="center" class = "RepHeader">
<td colspan="5">
<asp:LinkButton ID="lnkFirst" runat="server" ForeColor="Black" Text="First" >
</asp:LinkButton>
<asp:LinkButton ID="lnkPrevious" runat="server" ForeColor="Black" Text="Previous" >
</asp:LinkButton> Now Showing Page
<asp:DropDownList ID="ddlpageNumbers" runat="server" AutoPostBack="true" >
</asp:DropDownList> of <asp:Label ID="lblTotalPages" runat="server"> </asp:Label>
Pages.
<asp:LinkButton ID="lnkNext" runat="server" ForeColor="Black" Text="Next" >
</asp:LinkButton>
<asp:LinkButton ID="lnkLast" runat="server" ForeColor="Black" Text="Last" >
</asp:LinkButton>
</td> </tr>
<%--Ends Here (Paging for Pending Nested Repeaters)--%>
</td></tr>
<br />
</table>
</FooterTemplate>
</asp:Repeater>
</ItemTemplate>
<SeparatorTemplate><br /><br /></SeparatorTemplate>
</asp:Repeater>
I couldn't understand how to do paging.
You shroud read about it:
http://idunno.org/archive/2004/10/30/145.aspx
http://support.microsoft.com/kb/306154

Resources