How to dynamically assign datasource to listview - asp.net

I am having a problem with dynamically assigning datasource to listview.
For example I have list of receivedBonuses(Bonus), receivedLeaves(Leave) and I want listview to display those list items depending on what link button user clicked.
Researching internet and stackoverflow.com i found 3 solutions:
Using repeater inside the listview. But in my case, I could not apply it to my case and i got totally confused
Using nested listviews. I tried to do like this:
<asp:ListView ID = "bonuses" runat="server" DataSource ='<%# Eval("received_bonuses") %>' >
<ItemTemplate>
<tr>
<td><%# Eval("bonus_desc")%></td>
<td><%# Eval("bonus_type")%></td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table>
<tr>
<th>Bonus Description</th>
<th>Bonus Received Date</th>
</tr>
<tr ID="itemPlaceholder" runat="server" />
</table>
</LayoutTemplate>
<table>
<tr>
<th>Bonus Description</th>
<th>Bonus Received Date</th>
</tr>
<tr ID="itemPlaceholder" runat="server" />
</table>
</LayoutTemplate>
</asp:ListView>
<br />
and on back code I tried to write like this:
protected void dataBound(object sender, ListViewItemEventArgs e)
{
this.DataBindChildren();
}
It didn't give any errors it just didn't work.
Using data pager
I have no idea how to apply it to my case.
Any help is appreciated.
Thanks a lot.

All you have to do on the server side is change the DataSource or DataSourceID property and call DataBind on the ListView.
You have to make sure when using <%# Eval("") %> syntax that the objects you are binding to have those properties that are named in the Eval. So you may have a problem with with switching datasources when your properties are prepended with the typename and underscore.
That being said. There are 2 options you have an changing a data source. In the click event of the button or whatever switching mechanism you are using you can just write something like.
Not using a DataSource in the markup:
List<Bonus> bonusList = GetBonuses();
MyListView.DataSource = bonusList;
MyListView.DataBind();
Using a DataSource in the markup:
//where bonus list would be the id of the datasource in the markup
MyListView.DataSourceID= "BonusList";
MyListView.DataBind();

Do you need to do this dynamically? If you only have "bonuse" and "leave" can you not create two listviews and then just do display logic to visible=true/false the listview based upon the link button clicked?

Related

ID of items in ASP.NET ListView is automatically extended

I have programmed a simple blog page - http://www.3don.net.br/Blog.aspx (another language, here only to show the structure). I want to use hashtags for pointing to the topics. For example, http://www.3don.net.br/Blog.aspx#19/04/16 should scroll the page to the topic created at 19/04/16.
However, I cannot get it!
The topics of the blog are ItemTemplates of a ListView control. When I define an ID="lblDatum" for the label control of the data of each topic (which is the first control of each topic), then this ID is modified by the NET machine to
id="ctl00_ContentPlaceHolder_lstBlog_ctrl0_ctl01_lblDatum" (you can see it in the source code of the page for the second topic, for example).
So, if I access in the browser www.3don.net.br/Blog.aspx#ctl00_ContentPlaceHolder_lstBlog_ctrl0_ctl01_lblDatum
the page indeed will scroll correctly. I can also programmatically change the ID for each topic differently and it still works for each topic.
However, the hashtag-name "ctl00_ContentPlaceHolder_lstBlog_ctrl0_ctl01_lblDatum" is not nice! Is there a possibility to suppress the ctl00_ContentPlaceHolder_lstBlog_ctrl0_ctl01_-part?
Or another idea for getting it?
Use ClientIdMode="Static" in your ListItem, which removes the autoGenerate ID, you got ID="lblDatum" on client.
ok, I added the clientIDMode="static" property to the Label control of the data:
<table id="table_intern" runat="server" >
<tr id="tr_intern" runat="server">
<td id="td_intern" runat="server">
<asp:Label ID="lblDatum" runat="server" Text='<%# Eval("data") %>' CssClass="rotfettschrift" clientidmode="static"/>
</td>
</tr>
<tr> ... </tr>
<tr> ... </tr>
</table>
... and, in code-behind, set the ID of this control of each topic igual of the text property of this control (the data):
lbl = CType(e.Item.FindControl("lblDatum"), Label)
lbl.ID = lbl.Text
However, the HTML-output is:
<tbody>
<tr id="ctl00_ContentPlaceHolder_lstBlog_ctrl0_ctl00_tr_intern">
<td id="ctl00_ContentPlaceHolder_lstBlog_ctrl0_ctl00_td_intern">
<span id="ctl00_ContentPlaceHolder_lstBlog_ctrl0_ctl00_19/05/16" class="rotfettschrift" clientidmode="static">19/05/16</span>
</td>
</tr>
<tr> ... </tr>
<tr> ... </tr>
</tbody>
Why is the ID of the span element ctl00_ContentPlaceHolder_lstBlog_ctrl0_ctl00_19/05/16 and not just 19/05/16 ???
Ok, i tested here, using reapeater, but with any other control works. You must set the id individually to each control, to make unique.
*I redid, using date.
MARKUP:
<table id="table_intern">
<asp:Repeater runat="server" ID="repeater" OnItemDataBound="repeater_ItemDataBound">
<ItemTemplate>
<tr>
<td>
<asp:Label Text="" runat="server" ID="label" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
BACKEND:
protected void Page_Load(object sender, EventArgs e)
{
var list = new List<string>();
for (int i = 0; i < 10; i++)
{
list.Add(string.Format("Item_{0}", i.ToString().PadLeft(2, '0')));
}
repeater.DataSource = list;
repeater.DataBind();
}
protected void repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var label = (Label)e.Item.FindControl("label");
var item = (DateTime)e.Item.DataItem;
label.ID = item.ToShortDateString();
label.Text = item.ToShortDateString();
label.ClientIDMode = ClientIDMode.Static;
}
}
RESULT:
<table id="table_intern">
<tbody><tr>
<td>
<span id="23/05/2016">23/05/2016</span>
</td>
</tr>
<tr>
<td>
<span id="24/05/2016">24/05/2016</span>
</td>
</tr>...
Sorry, for bad formatting, i will improve my answers if necessary.
Daniel,
thank you for dedicating your time.
You are defining the ClientIDMode property of the Label control in the code behind, ok. I do so, but I see that it does not work here:
screenshot
When I go with the mouse pointer over the ClientIDMode at the left it advices: "'ClientIDMode' is not a member of 'Label'"
and over the ClientIDMode at the right, it pops "'ClientIDMode' is not declared. It may be inaccessible due to its protection level."
Is there something undefined in my system?
Ok, i understand you using Framework2.0 in your project. Can you change Framework to 4.0 or upper? Otherwise you need use a .js approach, to scroll like wish.
ClientIdMode is from .net 4.0, how you have said .net4.6 installed, I assumed that the project was also 4.6.
IF, you can't change the version, you need use something like jquery to scroll. OR maybe a more hard solution creating a item in your itemTemplate like:
<span id='<%# Eval("data") %>'></span>
I don't have tested this solution, later I'll be testing;
Daniel,
I always suspected that, but the
"About Visual Studio" window tells another story.
Adicionally, in the registry I can find the v4/Full key and the Version information (at the right side) confirms the (installed and activated?) version 4.6.01055.
???
Or is framework v4 installed but not "activated"? Does this exist? Where can I see this?

Control placed in runat=server table sets SQL parameter at NULL on Update

I have a page with FormView and a plain html table inside. The table serves for layout and contains child controls data-bind to SqlDataSource. My problem is that if I add runat=server attribute to the table declaration, all controls inside the table set my SQL parameters at NULL in DataSource_Updating event and thus the record gets updated with NULLs instead of actual values. If I don't add runat=server, everything works fine. Sample of my code:
<asp:FormView ID="SettingsFormView" runat="server" DataKeyNames="Id" DataSourceID="SettingsDataSource"
DefaultMode="Edit" Width="560px">
<EditItemTemplate>
<strong>Settings</strong>
<table runat="server" width="350px">
<tr>
<td width="160">
Time (sec)
<dx:ASPxSpinEdit ID="textTime" runat="server"
Height="21px" Number="0" Value='<%# Bind("Time") %>' Width="104px" />
<br />
</td>
<td>
</td>
</tr>
</table>
</EditItemTemplate>
</asp:FormView>
I want to be able to remove (set invisible) some rows in code behind, that's why I need to set runat=server. However I can't get anywhere with this because SQL record updates with NULLs. Please, advice what might be wrong in my code.
Try using this.
<!-- toggle through OnLoad (can use ID as well) -->
<asp:PlaceHolder runat="server" OnLoad="MakeVisibleOrNot">
<tr>
...
</tr>
</asp:PlaceHolder>
and in the code behind:
protected void MakeVisibleOrNot(object sender, EventArgs e)
{
((Control) sender).Visible = ConfigUtil.DisplaySummaryComment;
}

how to hide and display a particular column of repeater using code behind?

I have a repeater, on its item_command event i am binding another repeater. And i want to show data according to role in the second repeater. For it i want to hide and show some column according to role of users. how can we do it using code behind. Thanks in advance.
My code is
<table id="table1" class="yui" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>
EmpID #
</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
<asp:Repeater ID="Repaddressorbbl" runat="server" OnItemCommand="Repaddressorbbl_ItemCommand">
<ItemTemplate>
<tr id="gh" style="cursor: pointer" onclick="Select(this);">
<td style="text-align: center;">
<%#Eval("empid")%>
</td>
<td>
<asp:LinkButton ID="lknumber" runat="server" Text="Edit" CommandName="searchbybbloraddress" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
<tfoot>
</tfoot>
</table>
protected void Repaddressorbbl_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "searchbybbloraddress")
{
bind_rep2();
}
}
If you want to databind the second repeater from the ItemCommand in your code behind you have two options.
You could modify the dataset you set as the DataSource of the second repeater and set the sensitive data to an empty string or **.
The other option you have is add a IsVisibleToUser boolean property to your dataset and in your second repeater bind the Visible property to this property.
You can easily modify the data that is given to your DataSource by using a Linq query that produces an anonymous object.
Something like:
Repeater2.DataSource = from d in MyData
select new
{
FirstName = d.FirstName,
LastName = d.LastName,
Salary = d.Salary,
IsVisibleToUser = CurrentUser.IsInRole(...)
}
Simple way is use javascript and use Display:none when hide and create function which is Show it when you want.

Enable/Disable table with javascript for multple instances on a single asp age

I just posted one question and got it answered very quickly, thank you.
I have a new problem, being I have a asp label which gets text dynamically set on it during instanation and then I have a onmousedown function tied to it call a javascript function to enable a table area that sitting below that is display - none by default. It all works fine until I put two of these user controls on a page. They both have the specificed label text correct but the javascript enable seems to set the display style attribute of the first usercontrol's table to block instead of the one that is sitting below the label that was clicked. I am sure this is because the script is running on the client side (which I really would like to keep) and all the user controls have the same id name (since they are all instaniations of the same user control) so the javascript to set the style display attribute just gets the first table. I can't seem to think of a good way to either dynamically name the table on instationation so i can specify this "uniquie" id name to the javascript or any other way to do this work.
the user control asp code is below:
function enableDivArea(objName) {
document.getElementById(objName).style.display = "block";
}
function disableDivArea(objName) {
document.getElementById(objName).style.display = "none";
document.forms[0].submit();
}<asp:Label style="cursor:pointer;color:#EA9156;font-family:Arial,Helvetica,sans-serif;font-weight:bold;" ID="m_emailAddressLabel" onmousedown="enableDivArea('EmailFormDivArea');" runat="server" Text="someone#emailaddress.com"></asp:Label>
<table id="EmailFormDivArea" style="display:none; border-style: outset; border-width: thin">
<tr>
<td>To: <asp:Label ID="m_sendEmailToLabel" runat="server" Text=""></asp:Label></td>
<td align="right"><asp:Label onmousedown="disableDivArea('EmailFormDivArea');" id="m_closeLabel" runat="server" Text="close"></asp:Label></td>
</tr>
<tr>
<td><asp:Label ID="m_fromLabel" runat="server" Text="First Name:" Visible="True"></asp:Label></td>
<td><asp:TextBox ID="m_firstNameBox" runat="server" Visible="True"></asp:TextBox></td>
</tr>
<tr>
<td><asp:Label ID="Label1" runat="server" Text="Last Name:" Visible="True"></asp:Label></td>
<td><asp:TextBox ID="m_lastNameBox" runat="server" Visible="True"></asp:TextBox></td>
</tr>
<tr>
<td><asp:Label ID="Label2" runat="server" Text="E-mail:" Visible="True"></asp:Label></td>
<td><asp:TextBox ID="m_emailBox" runat="server" Visible="True"></asp:TextBox></td>
</tr>
<tr>
<td><asp:Label ID="Label3" runat="server" Text="Phone number:" Visible="True"></asp:Label></td>
<td><asp:TextBox ID="m_phoneNumberBox" runat="server" Visible="True"></asp:TextBox></td>
</tr>
<tr>
<td><asp:Label ID="Label4" runat="server" Text="Message:" Visible="True"></asp:Label></td>
<td><asp:TextBox ID="m_messageBox" runat="server" Visible="True" Rows="6" TextMode="MultiLine"></asp:TextBox></td>
</tr>
<tr>
<td colspan="2" align="center"><asp:Button ID="m_sendMessageButton" runat="server" Text="Send Message"
onclick="m_sendMessageButton_Click" /></td>
</tr>
<tr>
<td colspan="2" align="center"><asp:Label runat="server" ID="m_statusLabel" Text="" Visible="true"></asp:Label></td>
</tr>
</table>
and the code behind looks like this:
protected void Page_Load(object sender, EventArgs e)
{
m_emailAddressLabel.Text = this.Parameter;
m_sendEmailToLabel.Text = this.Parameter;
}
Have the table runat server, and let the user control implement INamingContainer.
Construct the ID for the table, and set it programmatically (HtmlTable) in an overridden CreateChildControls, to for instance string.Concat(ID, "table").
EDIT: You also need dynamic ID references in the javascript.
You could use some <asp:PlaceHolder>'s for this, and then set this from code-behind in CreateChildControls,
but maybe it is just easier to move these small scripts inline, and emit scripts from code-behind,
setting client attributes on the asp:Label
Just a quick idea, do the tables both have the same ID? so the script only picks the first it finds?
make the ID unique!
use a asp:table and then
onmousedown="enableDivArea('<%=tableName.ClientID%>');"
First of all you can set the CssClass property for the style.
for hidding:
document.getElementById(theIdOfYourTable).style.display = 'none';
enabled goes the same
oops, I'm sorry, forgot that you can't use <%%> in a server tag (and doing this out of my head). Better for you would be to call the script like this:
onmousedown="enableDivArea(this);"
In your script you don't have to do document.getElementById anymore, since you get the element as a param already now.
I will keep that mind on the last reponse by Henk.
I acutally "cheated" in a new way with the help of your guys information. I dynamically added an attribute to the label that I wanted the javascript to run from the onmousedown from the Page_Load event and formatted the string how I wanted. Here is the line, it works fantastically (at least what I was looking for).
m_emailAddressLabel.Attributes.Add("onmousedown", "enableDivArea('" + EmailFormDivArea.ClientID + "');");
Thanks for all your help.

Seeking Advice: Updating a FormView Based on DropdownList Value

Greetings!
I'm looking for some advice regarding an approach to displaying data in a FormView based on a selection of a DropDownList within that FormView control. For example, I have a UserControl with the following:
<asp:XmlDataSource ID="xdsMyXmlData" runat="server" EnableCaching="false" XPath="Root/Membership" />
<asp:FormView ID="fvwMyFormView" runat="server" DataSourceID="xdsMyXmlData">
<ItemTemplate>
<div>
<h2><%# XPath("Title") %></h2>
<fieldset>
<asp:DropDownList ID="ddlMemberTypes" runat="server" DataSource='<%# XPathSelect("MenuItems/*") %>'></asp:DropDownList>
</fieldset>
<table>
<thead>
<tr>
<th><%# XPath("Columns/Name") %></th>
<th><%# XPath("Columns/Age") %></th>
<th><%# XPath("Columns/DateJoined")%></th>
</tr>
</thead>
<tbody>
<asp:Repeater ID="rptMembershipInfo" runat="server" DataSource='<%# XPathSelect("Members/*") %>'>
<ItemTemplate>
<tr>
<th><%# XPath("Data/Name") %></th>
<td><%# XPath("Data/Age") %></td>
<td><%# XPath("Data/DateJoined") %></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
</table>
</div>
</ItemTemplate>
</asp:FormView>
The UserControl's OnLoad() looks like this so far:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
string l_XmlData = MyControllerClass.GetMembershipTableXml(0);
xdsMyXmlData.Data = l_XmlData;
}
I would like to be able to pass the value of the DropDownList's selected item into GetMembershipTableXml() in order to retrieve the corresponding XML and then use it to populate the values of the FormView. What would the best way be to do this? Doing a Response.Redirect back to the current page using the selected DropDownList value as a query string variable? I'm hoping there's a better approach. What do you think?
You can create an event for OnSelectedItemChanged on your DropDownList; when this occurs, you can grab the selected item, and call your GetMembershipTableXml function.
Finally, dont forget to call DataBind on your FormView control to update the values :)
I think that's what you're after, hopefully it helps!

Resources