Display Special Character in Repeater Based on the DataItem Value - asp.net

I'm calling a stored procedure by passing the input from the webpage and saving the results in ArrayList. Each record in the ArrayList has column with name: type. If type is "A",
then I need display a special character on web page for the column value for the associated row.For the remaining type records in the results ArrayList,
i don't need to display anything for the associated rows..
in code behind file:
Dim array As New ArrayList
array = outPutFromTheSporedProcedure
repeater1.DataSource = array
repeater1.DataBind()
On aspx.page:
<asp:Repeater ID="repeater1" runat="server">
<HeaderTemplate>
<tr>
<th> type </th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lbl123" runat="server"><%#DataBinder.Eval(Container.DataItem, "type")%></asp:Label></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table></td></tr>
</FooterTemplate>
</asp:Repeater>
On Aspx Page
I have a repeater and binding a data item to repeater in itemTemplate.
Now i need to display special character(i.e *, $, &, basically to differentiate from other type of rows)
for type of rows "A", for remaining rows, i need to display nothing for the records for the associated column.
Please let me know how to solve this one. Thanks in Advance!

Since you want to display nothing for the non-special conditions you must first change this:
<asp:Label ID="lbl123" runat="server"><%#DataBinder.Eval(Container.DataItem, "type")%></asp:Label></td>
To This:
<asp:Label ID="lbl123" runat="server"></asp:Label></td>
Now, set your special character in the Repeater_ItemDataBound Event Handler if the conditions are met:
Private Sub repeater1_ItemDataBound(sender As Object, e As RepeaterItemEventArgs) Handles repeater1.ItemDataBound
If e.Item.ItemType = ListItemType.AlternatingItem OrElse e.Item.ItemType = ListItemType.Item Then
If CType(e.Item.DataItem, UnderlyingTypeOfArrayList).type = "A" Then
CType(e.Item.FindControl("lbl123"), Label).Text = "*" 'Special Character
End If
End If
End Sub
You see above that I check for the correct RepeaterItemType, if tghe DataItem's type Property = A, and if so, I get an instance of the label using FindControl and Casting to set its Text to the special character.
Note: You'll have to change UnderlyingTypeOfArrayList to the Type contained in the ArrayList.

Related

Reading data in a listview without a selection

I have a timer running on an Update Panel with a Listview showing a page size of 1. The timer increments the data pager as it cycles through many records.
In the Protected Sub timer_Tick Event I would like to read a few values from the ListView Page. Is there an easy way to do this?
The data is currently binding via a SQLDataSource, but this is temporary while other page development is underway. So I cannot rely on that data set for getting the info needed.
Something like....
val1 = listviewName.SelectedItems(0).SubItems(3).Text
val2 = listviewName.SelectedItems(0).SubItems(4).Text
One issue is that the record will not be selected. The Listview is displaying the data set in an ItemTemplate.
<ItemTemplate>
<tr>
<td>Position C:</td>
<td><asp:Label ID="Label50" runat="server" Text='<%# Eval "Pos_C") %>' />
</td>
</tr>
<tr>
<td>Position D</td>
<td><asp:Label ID="Label51" runat="server" Text='<%# Eval("Pos_D") %>' />
</td>
</tr>
</ItemTemplate>
Abbreviated layout of itemtemplate.
For anyone interested, I solved the above question with the code below....
Protected Sub ListView1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles ListView1.ItemDataBound
'Get the item object.
Dim dataItem As ListViewDataItem = CType(e.Item, ListViewDataItem)
Dim item As ListViewItem = e.Item
' Get the Label control in the item.
Dim myVal1Lbl As Label = CType(item.FindControl("Label50"), Label)
Dim myVal2Lbl As Label = CType(item.FindControl("Label51"), Label)
Dim myVal1 As String = myVal1Lbl.Text
Dim myVal2 As String = myVal2Lbl.Text
End Sub
Works great.

How to hide an item in datalist

I want to hide an item in datalist according to some condition suing ItemBound, how ?
Wrap a PlaceHolder control around the entire content of the ItemTemplate.
Then in your ItemDataBound event, you could do something like:
Protected Sub myDataList_ItemDataBound(sender As Object, e As System.Web.UI.WebControls.DataListItemEventArgs) Handles myDataList.ItemDataBound
If Not Value = Value2 Then
Ctype(e.Item.FindControl("myPlaceHolder"), PlaceHolder).Visible = False
End If
End Sub
A better approach (however I've not had chance to test it), would be to hide the whole item using e.Item.Visible. This way no HTML table elements would be rendered for the item. It would also mean no PlaceHolder would have to be added.
Protected Sub myDataList_ItemDataBound(sender As Object, e As System.Web.UI.WebControls.DataListItemEventArgs) Handles myDataList.ItemDataBound
If Not Value = Value2 Then
e.Item.Visible = False
End If
End Sub
Alternatively, if the values you are checking are from a database source, you could filter the items out before binding:
WHERE Value=#Value2
A simple solution could be to set the visibility of your Item container by evaluating your desired condition in your ItemTemplate:
<ItemTemplate>
<div id="itemdiv" visible='<%# (Convert.ToInt32(Eval("YourValue")) == 5) %>' runat="server">
<%# Eval("SomeOtherValue") %>
</div>
</ItemTemplate>
My example uses a constant but you could use any variable in scope.
Pitfall!
DataList will insist to create empty rows for hidden items, so you may have to use ListView instead to fully control creating your filtered itemlist.
Update
Using a ListView instead will only create rows for visible items:
<ItemTemplate>
<tr id="itemdiv" visible='<%# (Convert.ToInt32(Eval("YourValue")) == 5) %>' runat="server">
<td><%# Eval("SomeOtherValue") %></td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table border="1">
<tr runat="server" id="itemPlaceholder" />
</table>
</LayoutTemplate>

Looping through a repeater control to get values of Textbox in asp.net

I am trying to loop through my repeater control and get the textbox values.
However, I am getting an error:
{"Object reference not set to an instance of an object."}
my code is:
Dim txtField As TextBox
Dim j As Integer = 0
'Confirm if user has entered atleast one quantity
For Each item In rptRequestForm.Items
txtField = rptRequestForm.FindControl("txtBox")
If txtField.Text <> Nothing Then
j += 1
Else
End If
Next
UPDATE: aspx code is:
<td><asp:Repeater ID="rptRequestForm" runat="server">
<HeaderTemplate>
<table border="0" width="100%">
<tr>
<td style="width:50%" class="TextFontBold"><asp:Label runat="server" ID="Label1" Text="Product"></asp:Label></td>
<td style="width:25%" class="TextFontBold"><asp:Label runat="server" ID="Label2" Text="Quantity"></asp:Label></td>
<td style="width:25%" class="TextFontBold"><asp:Label runat="server" ID="Label3" Text="Price (ea.)"></asp:Label></td>
</tr>
</table>
</HeaderTemplate>
<ItemTemplate>
<table border="0" width="100%">
<tr>
<td style="width:50%" class="TextFont"><span><%#Trim(Eval("Product_Title"))%></span></td>
<td style="width:25%"><asp:TextBox ID="txtBox" runat="server" Width="30%" onblur="Javascript:numberonly(this)"></asp:TextBox></td>
<td style="width:25%" class="TextFont"><span><%#Trim(FormatCurrency(Eval("Price")))%></span></td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
try
Dim someString as String = "Not set" <-- used later to hold the values of the string
Dim txtField As TextBox
Dim j As Integer = 0
'Confirm if user has entered atleast one quantity
For Each item In rptRequestForm.Items
txtField = item.FindControl("txtBox")
If Not IsNothing(txtField) Then ' <--- this is the line I changed
j += 1
someString = txtField.Text ' <-- once you've checked and know that the textbox exists, you just grab the value like so.
' do whatever you like with the contents of someString now.
Else
End If
Next
The problem is that you're trying to access the ".Text" property of a TextBox that it didn't find. The TextBox itself is the object to which there is no reference.
Incidentally, the .Text property of an actual Textbox (one that exists and was found) can't be "Nothing". It can only be String.Empty or a valid string.
Edited my line of code
Sorry, my VB is rusty.
Final edit
AARGH! I'm blind. I can't believe I didn't see this. There were TWO problems withthe original code. This is the answer to the second issue:
Change
txtField = rptRequestForm.FindControl("txtBox")
to
txtField = item.FindControl("txtBox")
The ITEM has to find the control, not the repeater itself!
I created a small web app just to check to see if I was grabbing the textbox's text and finally found the issue above. my code is NOT the same as yours in the aspx, but here's a complete code listing so that you can see how it works:
vb code
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim t As New System.Data.DataTable
t.Columns.Add("Name")
Dim newRow(1) As Object
t.Rows.Add(New Object() {"Frank"})
t.Rows.Add(New Object() {"Dave"})
t.Rows.Add(New Object() {"Muhammad"})
rptRequestForm.DataSource = t
rptRequestForm.DataBind()
Dim txtField As TextBox
Dim j As Integer = 0 'Confirm if user has entered atleast one quantity
For Each item As RepeaterItem In rptRequestForm.Items
txtField = item.FindControl("txtBox")
If Not IsNothing(txtField) Then ' <--- this is the line I changed
j += 1
System.Diagnostics.Debug.WriteLine(item.ItemType.ToString())
System.Diagnostics.Debug.WriteLine(txtField.Text)
Else
System.Diagnostics.Debug.WriteLine(item.ItemType.ToString())
End If
Next
End Sub
aspx code
<asp:Repeater ID="rptRequestForm" runat="server">
<HeaderTemplate>
Hello!
</HeaderTemplate>
<ItemTemplate>
<asp:TextBox ID="txtBox" runat="server" Text='<%#Bind("Name") %>'></asp:TextBox>
<br />
</ItemTemplate>
</asp:Repeater>
produces the following output in the System.Diagnostics.Debug window:
Item
Frank
AlternatingItem
Dave
Item
Muhammad
The thread 0x321c has exited with code 0 (0x0).
The thread 0x39b8 has exited with code 0 (0x0).
You have to properly cast it as Textbox e.g.
TextBox txtField = (TextBox)rptRequestForm.FindControl("txtBox") // C# code
Here is VB.NET code:
Dim txtField As TextBox = CType(rptRequestForm.FindControl("txtBox"), TextBox)
Dim myText as string
Dim j As Integer = 0
'Confirm if user has entered atleast one quantity
For Each myItem as repeateritem In rptRequestForm.Items
If NOT string.isnullorempty(CTYPE(myItem.FindControl("txtBox"),textbox).text) then
j += 1
End If
Next
I wouldn't use nothing -- not sure that causes a problem or not, but usually I see that for objects, not properties. String.IsNullOrNothing() is made for checking strings for null or empty ("").
You don't need to worry about whether or not the textbox exists, because if it exists in one row of the repeater, it will exist in all rows. I guess you could check it for 'nothing' if you weren't sure what "txtBox" was at design time...but otherwise, not necessary.
You should definately use the cast (CTYPE()). I think you might be able to get away with not using it if all you want is .text, but the CTYPE gives you access to all of the textbox's properties (not just it's inherited properties), and also, you might need to do checkboxes or other controls at some point where you pretty much have to CTYPE in order to get to .ischecked, etc.
I made a generic method for set the property visible, I think you can take it as an example
Sub SetVisibleControlRepeater(ByRef repetidor As Repeater, ByVal idControl As String, ByVal esVisible As Boolean)
For Each item As RepeaterItem In repetidor.Items
Dim boton As System.Web.UI.WebControls.Button = CType(item.FindControl(idControl), Button)
boton.Visible = esVisible
Next
End Sub

Getting value of anchor tag from repeater?

I have a regular html anchor link that is bound to an Id column. I want to loop through the repeater and get the value of the Id column, but can't figure out how. I have some code below my repeater markup. I can't figure out how to do it with just a client side anchor tag.
<asp:Repeater ID="repSearchResults" runat="server">
<ItemTemplate>
<tr>
<td><a href='<%#Eval("Id")%>'><%#Eval("Id")</a></td>
</tr>
</asp:Repeater>
Protected Sub btnGetIds_Click(ByVal sender As Object, ByVal e As System.EventArgs)
For Each item As RepeaterItem In repSearchResults.Items
If (item.ItemType = ListItemType.Item) Then
'Get Id here
End If
Next
End Sub
You could add a hidden field inside each template:
<ItemTemplate>
<asp:HiddenField ID="hid" runat="server" Value='<%#Eval("Id")%>' />
...
</ItemTemplate>
and then inside the loop:
If item.ItemType = ListItemType.Item Then
Dim ctrl As HiddenField = TryCast(item.FindControl("hid"), HiddenField)
If ctrl IsNot Nothing Then
Dim id As String = ctrl.Value
' do something with the id
End If
End If
You would need to make the anchor runat=server, name it, and then access it with the FindControl method.

ASP ListView - Eval() as formatted number, Bind() as unformatted?

I have an ASP ListView, and have a very simple requirement to display numbers as formatted w/ a comma (12,123), while they need to bind to the database without formatting (12123). I am using a standard setup - ListView with a datasource attached, using Bind().
I converted from some older code, so I'm not using ASP.NET controls, just form inputs...but I don't think it matters for this:
<asp:SqlDataSource ID="MySqlDataSource" runat="server"
ConnectionString='<%$ ConnectionStrings:ConnectionString1 %>'
SelectCommand="SELECT NUMSTR FROM MY_TABLE WHERE ID = #ID"
UpdateCommand= "UPDATE MY_TABLE SET NUMSTR = #NUMSTR WHERE ID = #ID">
</asp:SqlDataSource>
<asp:ListView ID="MyListView" runat="server" DataSourceID="MySqlDataSource">
<LayoutTemplate>
<div id="itemplaceholder" runat="server"></div>
</LayoutTemplate>
<ItemTemplate>
<input type="text" name="NUMSTR" ID="NUMSTR"
runat="server" value='<%#Bind("NUMSTR")%>' />
<asp:Button ID="UpdateButton" runat="server" Text="Update" Commandname="Update" />
</ItemTemplate>
</asp:ListView>
In the example above, NUMSTR is a number, but stored as a string in a SqlServer 2008 database. I'm also using the ItemTemplate as read and edit templates, to save on duplicate HTML. In the example, I only get the unformatted number. If I convert the field to an integer (via the SELECT) and use a format string like Bind("NUMSTR", "{0:###,###}"), it writes the formatted number to the database, and then fails when it tries to read it again (can't convert with the comma in there).
Is there any elegant/simple solution to this? It's so easy to get the two-way binding going, and I would think there has to be a way to easily format things as well...
Oh, and I'm trying to avoid the standard ItemTemplate and EditItemTemplate approach, just for sheer amount of markup required for that.
Thanks!
As seen in my comment above, I ended up just stripping commas from the NewValues collection in the ListView ItemUpdating event, and adding in commas on the ItemDataBound event.
If there are other ways to do this in a clean way, I'm interested!
Code in VB.NET, comment syntax made to be compatible with stackoverflow's highlighting:
Protected Sub myListView_OnItemDataBound(ByVal sender As Object, ByVal e As ListViewItemEventArgs) Handles myListView.ItemDataBound
Dim intNumber As Integer
For Each c As Control In e.Item.Controls
If TypeOf c Is TextBox Then /*ASP textbox controls*/
Dim numberText As TextBox
numberText = DirectCast(c, TextBox)
If Integer.TryParse(numberText.Text, intNumber) Then /*If the text can be parsed, format it*/
numberText.Text = String.Format("{0:###,##0}", intNumber)
End If
Next
End Sub
Protected Sub myListView_OnItemUpdating(ByVal sender As Object, ByVal e As ListViewUpdateEventArgs) Handles myListView.ItemUpdating
Dim cleanNumber As String
Dim intNumber As Integer
For Each key As String In e.NewValues.Keys
cleanNumber = e.NewValues(key).ToString().Replace(",", Nothing) /*Remove all commas*/
If Integer.TryParse(cleanNumber, intNumber) Then /*If the text can be parsed, format it*/
e.NewValues(key) = intNumber.ToString()
End If
Next
End Sub
Cannot you use <%# Bind("expression"[, "format"]) %> style?
So in your case, devise a format string (I think it should be "#,###") and ASP.NET would be able to format the string both on input and output.

Resources