how can is set id dynamic with Eval method and setting the id from sql database to a controller , like this
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="articlesqlfetch">
<ItemTemplate>
<strong > <%# Eval("title") %> </strong>
<br>
<-! this is the line ->
<asp:HyperLink ID="_<%# Eval("id") %>" runat="server">قراءة المزيد</asp:HyperLink>
</ItemTemplate>
when do this it give me a Parser Error
Using Eval() to provide dynamically generated ID is not allowed because you cannot bind to ID property of server controls, hence this code is wrong:
<asp:HyperLink ID="_<%# Eval("id") %>" runat="server">some text</asp:HyperLink>
Instead, use ItemDatabound event for repeater control like this (assumed your ID is auto-generated identity field):
Markup (ASPX)
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="articlesqlfetch"
OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<%-- repeater contents --%>
<asp:HyperLink ID="Hyperlink1" runat="server">some text</asp:HyperLink>
</ItemTemplate>
</asp:Repeater>
Code-behind
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
HyperLink hyperlink = e.Item.FindControl("Hyperlink1") as HyperLink;
if (hyperlink != null)
{
hyperlink.ID = "_" + (e.Item.ItemIndex + 1).ToString(); // set ID from bound data
hyperlink.ClientIDMode = ClientIDMode.Static;
hyperlink.NavigateUrl = "some/uri/here"; // optional
// other stuff
}
}
Related
I have seen many resources on SO that say that I can use following syntax to pass value to CommandArguement of `LinkButton'
<%forearch(var comment in Comments){%>
<asp:LinkButton ID="del" CommandArguement='<%= comment.CommentId%>' onCommand="delete_click" Text="Delete"/>
<%}%>
But when I write this in my ascx file and click on the link the value passed to command argument is "<%=comment.CommentId%>" instead of commentId itself. Please guide what am I doing wrong?
Edit 1
based on answers and comments, I have moved to use repeater instead of foreach and plain code. Here is the code I have come up with
<asp:Repeater ID="commRepeater" SelectMethod="GetPageComments" runat="server">
<ItemTemplate>
<p>
<%#Eval("Comment") %>
<%if(Page.User.Identity.IsAuthenticated && Page.User.Identity.GetUserId() == Eval("UserId")){ %>
<span>
<asp:LinkButton Text="Edit" runat="server" ID="EditLink" CommandArgument='<%#Eval("CommentId")%>' OnClick="Update_Comment" />
<asp:LinkButton Text="Delete" runat="server" ID="DeleteLink" CommandArgument='<%#Eval("CommentId")%>' OnClientClick="if (!confirm('Are you sure you want delete?')) return false;" OnCommand="Delete_Comment" />
</span>
<%} %>
</p>
</ItemTemplate> </asp:Repeater>
you can see that I am trying to show the edit and delete links if user is logged in and his Id matches with user who commented but it tells me that I can on use Eval in databound controls. how would I hide/show edit/delete links conditionally within repeater
You could simply use codebehind, for example in Page_Load:
protected void Page_Load(Object sender, EventArgs e)
{
if(!IsPostBack)
{
del.CommandArgument = comment.CommentId;
}
}
Maybe a better approach would be to use the Comments-collection(which seems to be a list or array of a custom class) as DataSource of a Repeater(or other web-databound control). Then you can add the LinkButtons to the Itemtemplate.
You can then either use ItemCreated or ItemDataBound events of the repeater in codebehind or inline ASP.NET tags to bind the CommandArgument.
For example:
CommandArguement='<%# DataBinder.Eval( Container.DataItem, "CommentId" ) %>'
What you are doing currently is not recommended and is highly error prone. You can easily achieve this with ASP.NET Repeater control like this:-
<asp:Repeater ID="MyRepeater" runat="server">
<ItemTemplate>
<asp:LinkButton ID="del" CommandArguement='<%# Eval("CommentId") %>'
OnCommand="del_Command" Text="Delete" runat="server" />
</ItemTemplate>
</asp:Repeater>
In Page_Load simply bind it:-
if (!Page.IsPostBack)
{
MyRepeater.DataSource = CommentsRepository();
MyRepeater.DataBind();
}
Or Else if you are have ASP.NET 4.5 then use strongly type Data Bound controls like this:-
<asp:Repeater ID="MyRepeater" runat="server" ItemType="MyNamespace.Comment"
SelectMethod="MyRepeater_GetData">
<ItemTemplate>
<asp:LinkButton ID="del" CommandArguement='<%# Item.CommentId %>'
OnCommand="del_Command" Text="Delete" runat="server" />
</ItemTemplate>
</asp:Repeater>
And you method in code behind should be something like this(just for Demo):-
public IEnumerable<MyNamespace.Comment> MyRepeater_GetData()
{
return new List<Comment>
{
new Comment { CommentId =1, Name= "foo"},
new Comment { CommentId =2, Name= "bar"},
};
}
<%
foreach (training t in traininglist)
{
%>
<tr>
<td><%=t.TrainingId%></td>
<td><%=t.TrainingName%></td>
<td>
<asp:LinkButton runat="server" ID="EditBtn"
Text="Edit" OnCommand="editbtn_OnCommand"
CommandArgument='<%# t.TrainingId %>' CommandName="edit" />
</td>
</tr>
<% } %>
where,
training is the class and traininglist is List<training> defined in Page_Load() function in codebehind.
I am trying to call the
public void editbtn_OnCommand(object sender, CommandEventArgs e)
{
String myeid = e.CommandArgument.ToString();
....
}
Here, myeid is not getting value but always shows <%# t.TrainingId %>
i have already tried all other options like <%: t.TrainingId %> or <%=t.TrainingId %>
The output of Tag "<%= %>" is more likely similar to use Response.Write in your code. so these tags are used to display the value to the response object.
That's why,as per my understanding, You can't used these tags to set commandargument property of controls unless you are using DataBinding. If you are using DataBinding then these tags "<%= %>" are used to set the property of controls.
Because you are here looping through each item in list on html table, my suggestion is to use GridView or Repeater and then Bind through your List Object. if you are using this way, you can get rid of unwanted formatting issues of html tables also.
Refer http://msdn.microsoft.com/en-us/library/6dwsdcf5(VS.71).aspx
If you want to use repeater then you can use these specific tags, and this should be your code(not actual code, just sample one)
<asp:Repeater id="myRepeater" runat="server" >
<ItemTemplate>
<div>
<asp:LinkButton runat="server" id="EditBtn" CommandName="edit"
CommandArgument="<%#Container.DataItem.TrainingId %>" Text="Edit"
OnCommand="editbtn_OnCommand" />
</div>
</ItemTemplate>
</asp:Repeater>
here is my problem:
I've got a repeater on my asp.net (VB):
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("Question_Number") %>' />
<%#Eval("Question_Desc")%>
Now what I want to do is, check a value that I haven't used called "Question_Type" which could be = 1, 2 or 3 depending if it is multiple choice, short answer, etc.
I have tried this:
<%
if Eval("Question_type") = 1 then
Response.Write(" <asp:RadioButton runat=""server"">test1</asp:RadioButton>")
Response.Write(" <asp:RadioButton runat=""server"">test2</asp:RadioButton>")
Response.Write(" <asp:RadioButton runat=""server"">test3</asp:RadioButton>")
end if
%>
and I get this error:
Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.
HOW can I use this value in a if statement???
You are going to need to handle the ItemDataBound event and manually handle the values there.
Here is how I might approach the problem given this repeater:
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="HandleQuestionType">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("Question_Number") %>' />
<%#Eval("Question_Desc")%>
<asp:PlaceHolder ID="phQuestions" runat="server" />
</ItemTemplate>
</asp:Repeater>
Here is my event handler for getting the possible answers to a radio button list:
protected void HandleQuestionType(object sender, RepeaterItemEventArgs e)
{
// Execute the following logic for Items and Alternating Items.
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var question = e.Item.DataItem as Question;
var placeHolder = e.Item.FindControl("phQuestions") as PlaceHolder;
if(question != null && placeHolder != null)
{
if(question.Question_Type == QuestionTypeEnum.MultipleChoice)
{
var radioList = new RadioButtonList
{
DataTextField = "Answer",
DataValueField = "ID",
DataSource = GetPossibleAnswers()
};
radioList.DataBind();
placeHolder.Controls.Add(radioList);
}
}
}
}
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<li class="closed" >
<asp:HyperLink runat="server" CssClass="toggler off"
ImageUrl="/_layouts/images/NEXT.GIF"
Text="<%#Container.DataItem%>" ID="HyperLink1">
</asp:HyperLink>
</li>
</ItemTemplate>
</asp:Repeater>
I want to get the text in the hyperlink from the arraylist
in my ascx code
I am trying to do this bt its showing error
HyperLink hypl = (HyperLink)Repeater1.FindControl("HyperLink1");
hypl.Text = ar.ToString();
hypl.NavigateUrl = "http//www.yahoo.com";
Anyone is having idea how to resolve this problem
With a repeater control, you can't use FindControl to locate the hyperlink by name because there can be more than one (this is a template, and it gets rendered 0 to n times).
You need to do the assignment of values to the hyperlink multiple times, once for each item that is bound. This is a job for the repeater's ItemDataBound event. Try something like this:
<asp:Repeater ID="Repeater1" runat="server" onitemdatabound="Repeater1_ItemDataBound">
<ItemTemplate>
<li class="closed" >
<asp:HyperLink runat="server" CssClass="toggler off"
ImageUrl="/_layouts/images/NEXT.GIF"
Text="<%#Container.DataItem%>" ID="HyperLink1">
</asp:HyperLink>
</li>
</ItemTemplate>
</asp:Repeater>
Then you need to handle the event like so:
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
HyperLink hypl = (HyperLink)e.Item.FindControl("HyperLink1");
hypl.Text = ar.ToString();
hypl.NavigateUrl = "http//www.yahoo.com";
}
<asp:GridView DataSource="Reports">
<ItemTemplate>
<asp:TextBox Text='<%# Bind("ReportId") %>'
<asp:Repeater DataSource="Something that is different than the GridView's DS">
<a href='<%# Bind("ReportId", "reports.aspx?report={0}") %>'/>
</asp:Repeater>
</ItemTemplate>
</asp:GridView>
I know this is inachievable, I am looking for a way to use ReportId from the parent gridview in the nested repeater, is there a way to do it with server side code <%# %>?
Set the gridview
DataKeyField="ReportId"
and in the event GridView1_ItemDataBound inside it
protected void GridView1_ItemDataBound(object sender, GridViewItemEventArgs e)
((TextBox)e.Item.FindControl("TextBox1")).text = GridView1.DataKeys[0].ToString();
and in this case u set the textbox with the value of the ID, try it and hope that it will be usefull.