I have a list of files (stored in a database) that I would like the user to be able to upload in asynchronous callbacks.
I have got as far as displaying AJAX Control Toolkit's AsyncFileUpload controls next to the name of each file I'm expecting:
<asp:Repeater ID="SourceTables" runat="server">
<ItemTemplate>
<tr>
<td>
<%#DataBinder.Eval(Container.DataItem, "LongName")%>
</td>
<td>
<ajax:AsyncFileUpload runat="server" ClientIDMode="AutoID" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
All of these async upload controls will end up calling the same method in code behind, which is fine, but when I come to save the file I need some way to identify which control is causing the postback (i.e. which of the several files has just been uploaded). However, I have been unable to set the ID dynamically inside the repeater (I believe it is only possible from code behind).
Clearly this doesn't work:
<ajax:AsyncFileUpload ID=<%#DataBinder.Eval(Container.DataItem, "ShortName")%> runat="server" ClientIDMode="AutoID" />
Is there another way I can set the ID of each of the upload controls dynamically inside the repeater (or otherwise) or another approach I can take?
You can add controls dynamically in "ItemDatabound" event of the repeater.
How are you handling the postback events?
If you are using the UploadedComplete event of the AsyncFileUpload control, you get the uploaded file through the AsyncFileUploadEventArgs object.
You could also cast sender to your AsyncFileUpload control and then get the file through the PostedFile property.
protected void AsyncFileUpload1_UploadedComplete(object sender, AsyncFileUploadEventArgs e)
{
string savePath = MapPath("~/Uploads/" + Path.GetFileName(e.filename));
}
Something like this
<ajax:AsyncFileUpload runat="server" id="afuMyUpload" ClientIDMode="AutoID" OnClientUploadComplete="MyFunction" />
foreach (Control c in SourceTables.Items)
{
var myUpload = c.FindControl("afuMyUpload") as AsyncFileUpload;
//Do stuff with your control
}
You can't bind the ID property of controls. You will need to create the control in code behind and add it to the repeater.
Example:
protected void GridDataBind(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) {
IEnumerable list = PremiumUnitFees.PremiumAmenities.ObtainFeesForProject(IntranetUser.Current.ProjectId);
foreach (PremiumUnitFees.PremiumAmenities feature in list) {
e.Row.Cells(3).Controls.Add(new CheckBox {
ID = feature.Id.ToString(),
Text = feature.NickName,
Checked = PremiumUnitFees.PremiumUnitView.IsUnitPremium(feature.Id, Convert.ToInt64(DataBinder.Eval(e.Row.DataItem, "Id")))
});
}
}
}
Related
This is what I wrote inside the Repeater
<td style="text-align: center; width: 60px">
<asp:CheckBox ID="DeleteCheckBox" runat="server" CommandArgument='<%# Eval("Id")%>' AutoPostBack="True" OnCheckedChanged="DeleteCheckBox_Click" />
td>
and this is the C#
protected void DeleteLinkbtn_Click(object sender, EventArgs e)
{
try
{
LinkButton BtnId = (LinkButton)(sender);
string ButtonId = BtnId.CommandArgument;
long Active = 1;
if (ButtonId !=string.Empty)
{
if (DeleteCheckBox.Checked==true)
{
objdalTransactionEntry.RentSettingsIsActiveUpdate(Convert.ToInt64(ButtonId), Active);
}
}
}
catch (Exception) { }
}
The Problem is that it is not being able to find the ID of the checkbox DeleteCheckBox in C# code
Based on you code, I have the following comments:
Change you function name, it's confusing. It should either be DeleteCheckBox_Changed or it should not be used for the OnCheckedChanged event
Your sender is not a LinkButton it is the checkbox itself. So you can access the checkbox control with CheckBox checkBoxThatChanged = (CheckBox)(sender)
DeleteCheckBox does not really exist. You have multiple DeleteCheckBoxs due to your repeater, so you won't be able to access it this way.
If you are indeed using a LinkButton, and you want to find a checkbox, then you should add a value to the link button, indicating the row of the table it refers to and iterate through all the checkbox controls until you find your target one.
I have two nested repeaters. In the nested one's footer I have text box and file upload controls. I was able to get an instance of the file upload without any problem, but the instance of the text box is null, though both are placed in the footer.
Here is the aspx part representing the footer of the inner repeater:
<FooterTemplate>
<tr class="add_comment">
<td>Add comment </td>
</tr>
<tr>
<td>
<asp:TextBox runat="server" Columns="20" Rows="3" ID="comment_txt" TextMode="MultiLine" Width="60%" CssClass="new_comment" ViewStateMode="Inherit"></asp:TextBox>
</td>
</tr>
<tr class="add_comment">
<td>
<asp:FileUpload ID="uploadImageBtn" runat="server" Text="Add image" OnClick="uploadImage" CssClass="comment_buttons" />
<asp:Button ID="comment_btn" runat="server" OnClick="submitComment" Text="Comment" CssClass="comment_buttons" />
</td>
</tr>
</table>
</FooterTemplate>
This is the C# code where I'm trying to access the controls:
protected void commentsRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Footer ))
{
Repeater childRepeater = (Repeater)sender;
TextBox commentTextBox = (TextBox)e.Item.FindControl("comment_txt");
String postText = commentTextBox.Text.ToString();
FileUpload upFile = (FileUpload)e.Item.FindControl("uploadImageBtn");
}
}
When running the page I get this error,
Object reference not set to an instance of an object
Which is caused by this line:
String postText = commentTextBox.Text.ToString();
I tried to remove the text box code and retrieve only the upload file and it worked very well. The problem is in accessing the text box.
Edit: The accessed text of the text box and the instance of upload button should be accessed in an onclick event handler of a button in the same page. Thus, I have defined both globally, assigned them the values while executing some nested repeater event of the Repeater like ItemDataBound or the event suggested by Adrian Iftode, which is ItemCreated. Then, in the onclick of the button I used them assuming that they have values since the nested repeater event should be fired before onclick of the button. Upload file instance is retrieved successfully, but the text box is always null.
Global variables declaration:
TextBox commentTextBox;
FileUpload upFile;
Repeater childRepeater;
String postText;
Code inside nested repeater event:
protected void commentsRepeater_ItemCreated(object sender, RepeaterItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Footer))
{
childRepeater = (Repeater)sender;
commentTextBox = (TextBox)(e.Item.FindControl("comment_txt"));
postText = commentTextBox.Text.ToString();
upFile = (FileUpload)e.Item.FindControl("uploadImageBtn");
}
}
Code inside onclick:
protected void submitComment(object sender, EventArgs e)
{
Boolean insert = true;
if (upFile.HasFile || !String.IsNullOrEmpty(postText))
{
//some code.
}
The above if statement is only executed if upFile has file, postText is always seen as null.
Can anyone please help me, what is causing this error?
Thank you.
ItemDataBound is not the right event to handle in this situation, because the header and footer templates are not instantiated in for the repeater items.
The proper event is ItemCreated
protected void rp_ItemCreated(Object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Footer)
{
e.Item.FindControl(ctrl);
}
if (e.Item.ItemType == ListItemType.Header)
{
e.Item.FindControl(ctrl);
}
}
I've been trying to get this working for a couple of hours now but nothing from google could help me fix the problem.
I have a very simple repeater control:
<asp:Panel ID="userDefDiv" Visible="false" runat="server">
<asp:Repeater ID="userDefRepeater" EnableViewstate="false" runat="server">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" EnableViewState="false"></asp:TextBox><br/>
</ItemTemplate>
</asp:Repeater>
</asp:Panel>
the userDefDiv panel is inside another panel, which is inside contentPLaceHolder.
the parent panel to userDefDiv does NOT have the "enableviewstate="false"".
So.
Everything on this page happens after a couple of linkbuttons_click. so nothing happens during page_load. And after i click another linkbutton i want to get the data from the different textboxes that is within the repeater.
C# code:
This is the code to create all the repeater items.
public void createUserDef()
{
DataTable userDefData;
userDefData = ..... (data from Database.)
userDefDiv.Visible = true;
userDefRepeater.DataSource = userDefData;
userDefRepeater.DataBind();
}
The code for the linkbutton:
protected void linkButton_Click(object sender, EventArgs e)
{
createUserDef();
Label2.Visible = true;
foreach (RepeaterItem item in userDefRepeater.Items)
{
TextBox box = (TextBox)item.FindControl("TextBox1");
string b = box.Text;
Label2.Text += b + " . ";
}
}
As you see i create the repeater once again during the click. But the only thing i can read in label2. is a a number of " .", on dot for each textbox.
but the text from the textbox is empty..
What am I doing wrong??
thanks for reading!
Mattias
SOLUTION:
add EnableVIewState="true" to textbox & repeater.
Dont call call dataBind() before you get the values.
Thanks!
You need to set EnableViewState to 'true' for linkbuttons to work properly in a repeater
How can i get current MainNavigationMenu hyprelink in code behind and check if is current menu clicked then i will change him default CSS.
I try with this code but is always null
HyperLink mainNavigationMenu = siteMapAsBulletedList.FindControl("MainNavigationMenu") as HyperLink;
full repeater code:
<asp:Repeater runat="server" ID="siteMapAsBulletedList" DataSourceID="smdsMenu">
<HeaderTemplate>
<li><asp:HyperLink ID="MainNavigationMenu" runat="server" NavigateUrl='<%#SiteMap.RootNode.Url%>'
Text='<%#SiteMap.RootNode.Title%>'></asp:HyperLink></li>
</HeaderTemplate>
<ItemTemplate>
<li><asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#Eval("Url")%>' Text='<%#Eval("Title")%>'></asp:HyperLink></li>
</ItemTemplate>
</asp:Repeater>
Are you verifying which type of repeater item you are looking at ?
Attach an ItemDataBound to your repeater and do something like this :
private void rptPanier_ItemDataBound(Object sender , RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Header)
{
var myItem = (Hyperlink)e.Item.FindControl("YourControlName");
}
}
Then you will have a reference on it and you can do whatever you want !
Beware tho, the ItemData item, which can be found in the repeateritemeventargs, is always null when the repeater is creating the header.
Hope this helps !
The repeater has a collection of Items. Each Item is a RepeaterItem, which has an ItemType property. For header items, this value will be "ListItemType.Header". Therefore, you want to perform .FindControl() upon that particular repeater item, not the entire Repeater itself.
I have this linkbutton within a datalist and I'm trying to get access to the datalist on the pageload so i can set the linkbutton to be enabled or not based on the user's role.
<asp:DataList id="dlRecommendations" runat="server" DataKeyField="Key" Width="900">
<ItemTemplate>
<asp:LinkButton id="lnkEdit" Text="Edit" Runat="server" CommandName="Edit">
</asp:LinkButton>
</ItemTemplate>
</asp:DataList>
Within the page load I want to be able to access the linkbutton to enable or disable it based on the user's role.
private void Page_Load(object sender, System.EventArgs e) {
//perhaps something like this:
lnkEdit.Enabled = false;
....
}
I think you will be populating the datalist the first time page is loaded. So just wireup ItemDataBound, find link and disable it.
void dlRecommendations_ItemDataBound(object sender, DataListItemEventArgs e)
{
var link = e.Item.FindControl("lnkEdit") as LinkButton;
if (link != null)
{
link.Enabled = UserHasRight;//if user has right then enabled else disabled
}
}
DataList is a databound control - it builds rows only when data is supplied.
To access link inside row use ItemDataBound event and access e.Item.FindControl("linkId");