Combine Multiple Data Sources to a Single ASP.NET Repeater? - asp.net

I have a repeater like so:
<asp:Repeater ID="rptrRooms" runat="server" OnItemCommand="Choose_Room">
<ItemTemplate>
<asp:Button ID="btnChooseRoom" runat="server"
CommandName="<%# Container.DataItem.ToString %>" Text="<%# Container.DataItem %>"
/>
</ItemTemplate>
</asp:Repeater>
I bind a data source to the repeater like so:
Dim dbRooms As New pbu_housingEntities
Dim gender As String = Session("gender").ToString
Dim hall As String = CStr(Session("hall"))
Dim selectedRooms = (From sh In dbRooms.Rooms _
Where sh.gender = gender _
Where sh.current_occupancy < sh.max_occupancy _
Where sh.is_available = True _
Where sh.building_name = hall _
Select sh.room1
)
rptrRooms.DataSource = selectedRooms
rptrRooms.DataBind()
Problem is, I also want to show the viewer the available number of spots in the room. But this requires somehow pull in either the current_occupancy / max_occupancy or in performing a calculation (e.g. max_occupancy - current_occupancy = actual_available) and then returning that with the room.
The end result I'm looking for is to return each room in a button control with text that looks like this:
"Room 1 - 2 Open" "Room 8 - 1 Open" and so on

Thanks davemackey :) Something like this.
Select New With {sh.room1, .actual_available = sh.max_occupancy - sh.current_occupancy}

Amit_g's comment above was the key. I needed to put into the select statement actual_available = sh.max_occupancy - sh.current_occupancy. If Amit posts an answer, I'll change the "correct" answer over to Amit to give you the credit for the answer. :)

Related

How to save a null datetime to SqlServer DB? not working

VS-Studio 2012 Web Express, ASP.NET, WebForms , VB , SqlServer , WebSite application having trouble saving a NULL value for DateTime to the strongly typed ROW:
Dim oRowVEHICLES As Main_TblAdap.tVEHICLESRow = odtVEHICLES.Rows(0) ' (0) is the first row.
oRowVEHICLES.[WElectrical] = If(WElectrical.Year < 10, DBNull.Value, WElectrical)
...etc...
Currently the DetailsView template field textbox is < blank> or empty or "" and the BLL function shows it as a date like: #01/01/0001#. So I test the YEAR value of the passed in variable if less than 10 then save DBNull.Value to the oRowVehicles.[WElectrical] but fails since datatype=Date and cannot convert DBNull to Date.
The DB-field is type Date and allows nulls.
The TableAdapter.xsd view shows the default value is < DBNULL>.
So, why is the oRowVehicles not Date nullable?
How do I make the WElectrical column nullable DATE?
I must be overlooking something, because I cannot be the only one to save an optional DATE value to the Sql-DB.
Your comments and solutions are welcome. Thanks...John
EDIT
ASPX code one DATE field in the DetailsView (others are similar):
<asp:TemplateField HeaderText="Electrical End Date" SortExpression="WElectrical">
<EditItemTemplate>
<TGADate:GADate ID="ucdtWElectrical" runat="server" Enabled="True" MinDate="01/01/1980" MaxDate="12/31/2050"
Caption="Electrical End Date" HideCaption="True" Width="100"
IsRequired="false"
UpdateMode="Conditional"
Text='<%# Bind("WElectrical")%>' />
</EditItemTemplate>
<InsertItemTemplate>
<TGADate:GADate ID="ucdtWElectrical2" runat="server" Enabled="True" MinDate="01/01/1980" MaxDate="12/31/2050"
Caption="Electrical End Date" HideCaption="True" Width="100"
IsRequired="false"
UpdateMode="Conditional"
Text='<%# Bind("WElectrical")%>' />
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="lblWElectrical" runat="server" Text='<%# clsGA_Lib1.fnGetDateTextFromObject(Eval("WElectrical"))%>' Style="font-weight: bold;"></asp:Label>
</ItemTemplate>
<ItemStyle Font-Bold="true" />
</asp:TemplateField>
Object DataSource parameter definition in the ASPX.
<asp:Parameter Name="WElectrical" Type="DateTime" />
BLL Code:
<System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, False)> _
Public Function UpdateFromDetailsView(ByVal original_UID_VEHICLE As Int32, _
ByVal VehicleNbr As String, _
...other function parameter variables...
ByVal WElectrical As Date, _
...other function parameter variables...
) As Boolean
' Get the new VEHICLE-row instance to be updated.
Dim odtVEHICLES As Main_TblAdap.tVEHICLESDataTable = Adapter.GetVhclByVhclID(original_UID_VEHICLE)
If odtVEHICLES.Count <> 1 Then
' no matching record found, return false
Return False
End If
' Populate the values of the ROW.
Dim oRowVEHICLES As Main_TblAdap.tVEHICLESRow = odtVEHICLES.Rows(0) ' (0) is the first row.
With oRowVEHICLES
...setting row-field values...
.[WElectrical] = If(WElectrical.Year < 10, Nothing, WElectrical)
...etc...
End With
' Update the oRowVEHICLES.
Dim rowsAffected As Integer = Adapter.Update(odtVEHICLES)
' Return TRUE if precisely one row was INSERTED, otherwise false.
Return CBool(rowsAffected = 1)
End Function
Edit comment for above code
The WElectrical parameter coming into the BLL-function is a DATE with a value of #01/01/0001#.
The code to place the value into the ROW-object
.[WElectrical] = If(WElectrical.Year < 10, Nothing, WElectrical)
places Nothing as the row-object-field-value.
The Adapter.Update(odtVEHICLES) updates the Sql-DB.
So what is causing the #01/01/0001# value to be placed into the Sql-DB?
Sql-DB column definition
//////// end of Edit ///////////
do one thing:
change DBNull.Value to Nothing
Alternatively you can change the datatype in the dataset to System.Object, and
go to the properties of that data colm
then you can select '(Nothing)' in the dropdown.
set Null value to >> Nothing
Thanks to all commentators to the above question.
The solution is to change the Row-column-variable to this sentence which casts the Nothing to Date? (nullable) as follows...
.[WElectrical] = If(WElectrical.Year < 10, CType(Nothing, Date?), WElectrical)
AND -- Changed the dataset-column-definition (in the .xsd) as follows:
DataType ==> System.Object (not Date)
NullValue ==> (Nothing) (not Throw Exception)
My sincere thanks to all contributors -- since elements of each of their suggestions have contributed to this solution.
This is the solution for sending a nullable value into the DataRow-column.
Thank you for all your help.

ASP:NET - GridVIEW - DropDownList selectedvalue

I am new at this forum though I have passed many years looking for answers into it. Now,I will like your help to solve an issue. I am following this link to make my own DropDown List in my Grid and works fine until this line:
ddlCities.Items.FindByValue(country).Selected = True
here,I have got error:
Object reference not set to an instance of an object.
but my code is right in affected fields:
this is relevant code in Code Behind:
Protected Sub RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow AndAlso grdLinea.EditIndex = e.Row.RowIndex;
Dim ddlCities As DropDownList = DirectCast(e.Row.FindControl("ddlFacturarA"), DropDownList)
' Create the command with the sproc name and add the parameter required'
ddlCities.DataSource = GetData("select UPPER(DSCA_ZONA)as Zona from tb_personal where dsca_Zona <> 'NULL'group by dsca_zona order by dsca_zona")
ddlCities.DataTextField = "Zona"
ddlCities.DataValueField = "Zona"
ddlCities.DataBind()
'Add Default Item in the DropDownList
'ddlCountries.Items.Insert(0, New ListItem("Please select"))
Dim country As String = Trim(CType(e.Row.FindControl("lblFacturarA"), Label).Text)
ddlCities.Items.FindByValue(country).Selected = True
End If
End Sub
and this is affected code in design mode:
<EditItemTemplate >
<asp:label ID="lblFacturarA" Value ='<%# Eval("facturar_a")%>' Visible ="false" runat="server" />
<asp:DropDownList
ID="ddlFacturarA"
CssClass="txt"
runat="server"
AutoPostBack="True" ValidationGroup="rfNewLineEmpty">
</asp:DropDownList>
<asp:RequiredFieldValidator
ID="rfNewLineFacturarA"
runat="server"
ErrorMessage="Obligatorio"
ValidationGroup="rfNewLine"
SetFocusOnError="True"
ControlToValidate="ddlFacturarA">
</asp:RequiredFieldValidator>
</EditItemTemplate>
I know I am new at ASP.NET and maybe I am loosing something by the way, but I have been round this code for two days and don't see light.
can you tell me something about reason for this error?
please,let me know if you need more detailed information to solve this.
thanks in advance
If you are sure that error is on line ddlCities.Items.FindByValue(country).Selected = True and country item is in dropdown list, I suggest you double check that is there white space or upper/lower case difference in dropdown list item and country variable.
because FindByValue finds exact item and it is case sensitive.
You should try changin query to RTRIM(LTRIM(UPPER(DSCA_ZONA))) as Zona
and
ddlCities.Items.FindByValue(country.ToUpper()).Selected = True
Sorry for delay as I been outside, i think i've solved in this way
Dim country As String = Trim(CType(e.Row.FindControl("lblFacturarA"), Label).Text)
ddlCities.Items.Insert(0, country)
and now it's working fine, Do you think this is a valid way?
many thanks!!!

Convert a gridview templatefield to pdf iTextSharp

I have a GridView which is programatically filled from the DB (not a SqlDataSource or such). There are 4 columns which are TemplateFields as I format their text. They are Dates and Times and this is the one of their TemplateField:
<ItemTemplate>
<asp:Label ID="Label1" Text='<%# FormatDate(Eval("tDate")) %>' runat="server"></asp:Label>
</ItemTemplate>
This is the function to format that date:
Function FormatDate(objTime As Object) As String
Dim d As String
If objTime.Equals(DBNull.Value) Then
d = ""
Else
d = Convert.ToDateTime(objTime).ToString("MM-dd-yyyy")
End If
Return d
End Function
I've been using the method in this Post which was converted to VB code from this to convert the GridView to a PDF using iTextSharp.
My issue is that I'm getting a Null Reference exception here when adding the GridView data to the PDF(inside the For Loops):
Dim lc As DataBoundLiteralControl = TryCast(gvReport.Rows(rowNo).Cells(colNo).Controls(0), DataBoundLiteralControl)
s = lc.Text.Trim()
And if I remove this If statement and just run the Else part here:
s = gvReport.Rows(rowNo).Cells(colNo).Text.Trim()
ph = New Phrase(s, FontFactory.GetFont("Arial", ReportTextSize, iTextSharp.text.Font.NORMAL))
mainTable.AddCell(ph)
These Date/Time columns show up as empty on the PDF while all other columns show up with no issues.
I'm very lost on how to resolve this issue and have been unsuccessful in finding a solution online.
While I wasn't able to fix the solution I was following up above, I found a different way to access data from a TemplateField:
Dim s As String = CType(gvReport.Rows(rowNo).FindControl("Label1"), Label).Text
This gives me access to the data in the specified column. Now I just need to figure out a way iterate through the row and get each of the different TemplateFields which will probably involve reworking my For loops and a Select Case statement.
You are getting Nothing because TryCast will store Nothing if it cannot cast the value.
In bound columns, the control is 0, but in an edit item template like that, it is 1.
So you have to change
Dim lc As DataBoundLiteralControl = TryCast(gvReport.Rows(rowNo).Cells(colNo).Controls(0), DataBoundLiteralControl)
to
Dim lc As Label = TryCast(gvReport.Rows(rowNo).Cells(colNo).Controls(1), Label)

Subquery returned more than 1 value

I know this topic is all over the place, but I am not doing an INSERT, UPDATE, DELETE. My statement is a plain and simple SELECT statement and so far has worked with 116 different items in my database until I got to one.
I have a search engine and am going through every single product in our database to add information to it. This is all done through the website, but when I search for ProductID 331 and click on it, it goes to the error page that says Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
It doesn't make any sense to me that the website would error with only this one product.
This is the statement I am using. Does anyone know why 1 product would be causing this error?
WebService:
Public Class ProductSearch
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function GetProducts(ByVal prefixText As String, ByVal count As Integer)
As String()
Dim ProductSql As String = "Select DISTINCT ProductID, ProductName
FROM Product WHERE ProductName
LIKE '%' & #prefixText & '%'
ORDER BY ProductName ASC"
Using sqlConn As New SqlConnection
(System.Configuration.ConfigurationManager.ConnectionStrings
("LocalSqlServer").ConnectionString)
sqlConn.Open()
Dim myCommand As New SqlCommand(ProductSql, sqlConn)
myCommand.Parameters.Add("#prefixText", SqlDbType.VarChar, 50)
.Value = prefixText
Dim myReader As SqlDataReader = myCommand.ExecuteReader()
Dim myTable As New DataTable
myTable.TableName = "ProductSearch"
myTable.Load(myReader)
sqlConn.Close()
Dim items As String() = New String(myTable.Rows.Count - 1) {}
Dim i As Integer = 0
For Each dr As DataRow In myTable.Rows
Dim id As String = dr("ProductID").ToString()
Dim name As String = dr("ProductName").ToString()
Dim item As String = AjaxControlToolkit.AutoCompleteExtender
.CreateAutoCompleteItem(name, id)
items.SetValue(item, i)
i += 1
Next
Return items
End Using
End Function
End Class
The aspx page that calls the webservice:
<%# Page Title="Product Search" Language="VB" MasterPageFile="~/MasterPage.master"
AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="Default" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit"
TagPrefix="asp" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<script type="text/javascript">
function AutoCompleteClientMethod(source, eventArgs) {
var value = eventArgs.get_value();
window.location = ("/Product/Default.aspx?id=" + value)
}
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="body" Runat="Server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="ProductSearch.asmx" />
</Services>
</asp:ScriptManager>
<asp:TextBox ID="Search" runat="server" AutoComplete="off"></asp:TextBox>
<asp:AutoCompleteExtender ID="AutoCompleteExtender1" runat="server"
TargetControlID="Search" ServicePath="~/ProductSearch.asmx"
ServiceMethod="GetProducts" MinimumPrefixLength="1" CompletionSetCount="120"
EnableCaching="true" OnClientItemSelected="AutoCompleteClientMethod">
</asp:AutoCompleteExtender>
</div><!--End of main div -->
</asp:Content>
UPDATE: 11/9/2011 - I have found a couple more records that have this problem. They are ProductID 331-335. I have no idea what is going on here. Could it be that those products don't really exist or that they have some kind of bug?
Here is a list of ProductIDs and their corresponding ProductNames that have this error:
122 'Managed account section of the Web Site'
331 'Elliott Wave Principle Key to Market Behavior'
332 'Targeting Profitable Entry & Exit Points'
333 'Essentials of Trading It's not WHAT You Think, It's HOW You Think'
334 'Exceptional Trading The Mind Game'
335 'Fibonacci Analysis'
I assume this is the sub-select query, DISTINCT doesn't mean one result. You can use TOP 1 to guarantee one result, but it doesn't guarantee it is the one you want.
Select TOP 1 DISTINCT ProductID, ProductName
FROM Product WHERE ProductName
LIKE '%" & prefixText & "%'
ORDER BY ProductName ASC
Besides Rick's answer, I would add that you should never concatenate strings to form SQL statements. Use parametrized queries instead. String concatenation exposes you to SQL Injection attacks. Also, by using parametrized queries you may gain performance if the query plans can be reused.
See this other StackOverflow post for a good discussion regarding parametrized queries on VB.NET.
I figured out what the problem is. For some reason, these problematic products have more than one value assigned to them in data fields that SHOULD have only one item. The database has been changed recently so that doesn't happen, but I guess these 5 products were already messed up and have now been found out.
Thanks for all the help guys! I wish I would've thought to check further into the database sooner. (There are about 15 tables, so it's usually what I think of to do last)

asp.net vb listview concatenate data items in code behind

I have a listview with some data bound to it.
In this data are column for an address.
How would I go about accessing these data items in code behind so I can concatenate them into one easy variable and miss out columns that have no data in, i have fields:
address
address1
town
county
postcode
I don't have a problem with the concatenation just accessing the data items.
Thanks J.
UPDATED
I am getting data out via a dataset and binding it to a listview.
Is it possible to access data items in the code behind to format or do whatever i want with them then showing it in the list view such as, concatenating the address fields into one variable?
so instead of writing:
DataBinder.Eval(Container.DataItem, "address") & ", " & DataBinder.Eval(Container.DataItem, "address1") & ", " & DataBinder.Eval(Container.DataItem, "town") etc...
in the actual list view i could do this in the code behind in a string variable then show the variable in the list view?
'select command
Dim cmdSchedule As SqlCommand = New SqlCommand()
cmdSchedule.Connection = keypadSQL
cmdSchedule.CommandText = "spSchedule"
cmdSchedule.CommandType = CommandType.StoredProcedure
'data adapter
Dim daSchedule As SqlDataAdapter = New SqlDataAdapter
daSchedule.SelectCommand = cmdSchedule
'data set
Dim dsSchedule As DataSet = New DataSet()
daSchedule.Fill(dsSchedule, "Schedule")
lvSchedule.DataSource = dsSchedule
lvSchedule.DataBind()
cmdSchedule.Dispose()
First put your items into accessible controls in the ListView, such as a label or literal.
<asp:ListView ID="ListView1" runat="server">
<ItemTemplate>
<asp:Label ID="lblAddress" runat="server" Text="<%= Eval("address") %>" />
</ItemTemplate>
</asp:ListView>
Then you can loop through the items and using FindControl, pull each string out individually.
Dim items As List(Of ListViewDataItem) = ListView1.Items
For Each item As ListViewDataItem In items
Dim strAddress As String = CType(item.FindControl("lblAddress"), Label).Text
Next
UPDATED
I'd think the best way would be to format it in SQL Stored Procedure and return it as a new field. Something like this:
SELECT *, address + ', ' + address1 + ', ' + town ', ' + county + ', ' postcode AS fullAddress
FROM ...
Then you'd just have to use <%= DataBinder.Eval(Container.DataItem, "fullAddress") %> to get the formatted address. You could even format it with HTML in the SP as long as you're weary of potential injection attacks (not sure of the original address input method).

Resources