I have a problem and I can't figure it out how to solve it. I search for solutions but they did not work. So, I have a Datalist with ItemTemplate. I need to add google analytics on onclick event to <a> tags. I tried to add the onclick event like
onclick="_gaq.push(['_trackEvent', 'Homepage', 'Click on',<%#DataBinder.Eval(Container.DataItem,"URL")%>']);" <br />
but I get a yellow error screen with the message "..tag is not formatted correctly".
I also tryed replacing double qoutes with &qout; but no success. I also tried
onclick='<%# string.Format("_gaq.push(['_trackEvent','Homepage','Click on last awarded company','{0}']);", DataBinder.Eval(Container.DataItem, "URL") %>' <br />
but this also not worked.
Have you got any idea how could I solve this problem?
You really should do this kind of complex databinding in the "OnItemDataBound" event in the code behind. Have a look at the relevant MSDN page.
<asp:DataList id="ItemsList" OnItemDataBound="Item_Bound" runat="server">
Code Behind:
public void Item_Bound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
// find your link
HyperLink link = (HyperLink)e.Item.FindControl("MyFirstHyperLink");
// so something nice with your link here, for example add attributes.
string a = DataBinder.Eval(e.Item, "URL", "_gaq.push(['_trackEvent','Homepage','Click on last awarded company','{0}']);");
link.Attributes.Add("onclick", a);
}
}
disclaimer: I haven't actually tested this code so you might need to make adjustments here and there. It merely serves to give you an idea of the direction to go.
Could you please try below?
Test
I've met the following scenario: I had to reuse some function that returns a collection of dynamic objects, from other assembly. Generally, there is a possibility to publish the dynamic object to other assembly, by using [assembly: InternalsVisibleTo("Some.Assembly")], because the dynamic objects are internal to their assembly. Not having the choice, I've tried the item data binding method solution to add the script, but dynamic objects are not accessible there, even if I used Eval. But Eval works in the markup, and there the quote/apostrophe problem occurs. My solution was HTML escaping:
onclick='<%# "doSomething('" + Eval("DataProperty") + "', this);"%>'
Related
I'm trying to reference a query string parameter inside an HyperLink element :
<asp:HyperLink runat="server" NavigateUrl='<%# Eval(Request["id"], "~/PATH/Page.aspx?id={0}") %>' Text="reload" />
I tought it was simple... but it's not: NavigateUrl property probably fails evaluation an the resulting url is empty.
Of course Request["id"] is valid at the time the page is evaluated.
I tried also using string.format() instead Eval() with the same result.
This means <%# ... %> data-binding expression
The data-binding expression creates binding between a server control property and a data source when the control's DataBind method of this server control is called on the page.
But you are only formatting a string to set for your NavigateUrl
Inline code block is not allowed to any server tag controls
those that have runat="server"
You can only set it via code either eg: inside the Page_Load
protected void Page_Load(object sender, EventArgs e)
{
HyperLink1.NavigateUrl = string.Format("~/PATH/Page.aspx?id={0}", Request["id"]);
}
Your second post work's because it's a pure html client control and not a server control.
Source: Inline Expressions
I didn't fully understand what the problem was but the following code works:
<a href="~/PATH/Page.aspx?id=<%= Request.QueryString["id"].ToString() %>" >reload</a>
I tried several times including one using <a></a> tag with runat="server" property (not working).
Inside repeater i have a html checkbox , now i want to access this checkbox in code behind file to check whether the checkbox is checked or not. but i dont want to user runat="server" tag , how can i do this my code as above
<input id="cbfdgroup" class="checkitem" type="checkbox" name="fd_cb_group[]" value='<%#Eval("FoodItemsUid") %>'>
in code behind file i am trying to access like this
foreach (RepeaterItem ri in rptMenu.Items)
{
if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem)
{
HtmlInputCheckBox chk = (HtmlInputCheckBox)ri.FindControl("cbfdgroup");
if (chk.Checked)
{
}
}
}
but this is giving error as object referrence is not set to instance of an object.. how should i get this control in code behind file without using runat = "server" tag
It is not possible. To clarify, the runat="server" portion is doing just what it says. It is saying that this control should be made available and accessible to the server.
Code which is in the code-behind is code which is running on/executed by the server. So logistically, if the control is not made available to the server, the it cannot be manipulated by code (hence when it will not show up in intellisense either.)
I don't believe what you are asking is possible. runat=server is what makes controls available to the code behind. If you remove that attribute, your code behind is simply not aware of the control in any way.
A little bit more explanation:
The codebehind executes on the server. Therefore, any control you want to access in your codebehind must have runat=server in order to be available. The two are inseparable.
you don't need to read the items from repeater
assuming that you are sending a postback to the server (http post)
you can read the selected checkbox by simply:
string x = Request["fd_cb_group[]"];
it is more than 1 it will separate by comma, just use split the get a list of string of selected values.
the whole thing would be something like that:
protected void Button1_Click(object sender, EventArgs e)
{
string x = Request["fd_cb_group[]"];
string[] allSelectedOnes = x.Split(',');
foreach(string item in allSelectedOnes)
{
//your custom code for the selected checkboxes
}
}
I am trying to get an asp: literal to work but apparently I am doing something wrong because I am getting an
Object Referece not set to an instance
of the Object
error
This is my code:
in the ascx page:
<span class="span1">
<asp:Literal ID="litFile" runat="server"></asp:Literal>
<strong><asp:Literal ID="litFile2" runat="server"></asp:Literal></strong>
</span>
and
in the ascx.cs page:
protected void _ItemBound(object sender, RepeaterItemEventArgs e)
{
((Literal)e.Item.FindControl("litFile")).Text = "a";
}
Any idea please?
C
We need more code to know for sure, but what this looks like to me is that the literal is actually outside the repeater that's firing the _ItemBound method. Otherwise, e.Item.FindControl should be able to find it. Make sure litFile is inside the ItemTemplate in your repeater control, rather than elsewhere in the page.
You shouldn't need to cast it, nor should you need to search for it.
Try just:
litFile.Text = "a";
If this doesn't work, we will need to see more code to work out what's going on.
Since your using FindControl I assume your in a repeater or something, so try this
Literal litFile = repeaterName.FindControl("litFile");
litFile.text = "a";
I code in VB so sorry if my syntax is off.
I have a designer working at the ASPX level. He doesn't do C#, doesn't do code-behinds, doesn't compile, etc. He's a pure designer, working with HTML and server controls.
I need a conditional control -- an If...Then-ish type thing. Normally, I would do this:
<asp:Placeholder Visible='<%# DateTime.Now.Day == 1 %>' runat="server">
It's the first day of the month!
</asp:PlaceHolder>
Is there any way to do something like this without the databinding syntax? Something like:
<asp:If test="DateTime.Now.Day == 1" runat="server">
It's the first day of the month!
</asp:If>
Is there some kind of way to extend a placeholder to allow this? I've fiddled around a bit, but in the end, I have a conditional that I essentially have to compile.
Now, there's nothing wrong with the databinding syntax, but's just one more bit of...weirdness, the a designer is going to have to understand. Additionally, it doesn't give me "else" statements. Something like this would be great...
<asp:If test="DateTime.Now.Day == 1" runat="server">
It's the first day of the month!
<asp:Else>
It's not the first day of the month!
</asp:Else>
</asp:If>
Instead of writing control
asp:If
why not use:
<% if expression
{ %>
Yellow
<% } %>
<% else
{%>
Red
<% } %>
Taking into account that codebehind files are out as the designer probably not got VS, I think a simpler solution with less code may be more preferential:
<%# Page Language="C#"%>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (DateTime.Now.Day == 1)
{
DateTestPanelFirst.visible = true;
DateTestPanelOther.visible = false;
}
}
</script>
<html>
<body>
<asp:panel runat="server" id="DateTestPanelFirst" visible="false">
It's the first day of the month!
<asp:panel>
<asp:panel runat="server" id="DateTestPanelOther">
It's not the first day of the month!
<asp:panel>
</body>
</html>
the <asp:panel> could be changed to another type of web control, like <asp:label> etc. I think almost all dot net controls have the visible property, so you can hide/show them at any time.
The data-binding syntax has two problems: first it's a little weirder for your designer vs. using plain text, and second it requires the designer to remember to invert the "if" test in your "else" block.
The first problem may annoy your designer a little, but the second problem is much more severe, because it forces your designer to think like a programmer (inverting boolean logic!) and makes every if/else block into a possible bug you need to test for after your designer hands over a template.
My suggestion: use data-binding syntax, but fix the more severe problem by creating custom controls that only require data-binding test code on the If control, but not on the Else control. Sure your designers will have to type a few more characters, but the other more severe problems won't apply and your performance won't suffer as it would if you had to dynamically compile code each time your page ran.
Here's an example I coded up to illustrate:
<%# Page Language="C#"%>
<%# Register Assembly="ElseTest" TagPrefix="ElseTest" Namespace="ElseTest"%>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
}
</script>
<html>
<body>
<ElseTest:IfControl runat="server" visible="<%#1 == 1 %>">
This should be visible (in "if" area)
</ElseTest:IfControl>
<ElseTest:ElseControl runat="server">
This should not be visible (in "else" area)
</ElseTest:ElseControl>
<br /><br />
<ElseTest:IfControl runat="server" visible="<%#0 == 1 %>">
This should not be visible (in "if" area)
</ElseTest:IfControl>
<ElseTest:ElseControl runat="server">
This should be visible (in "else" area)
</ElseTest:ElseControl>
</body>
</html>
Here's the underlying controls, which are simply wrappers around asp:Literal:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
[assembly: TagPrefix("ElseTest", "ElseTest")]
namespace ElseTest
{
// simply renames a literal to allow blocks of data-bound-visibility
[ToolboxData("<{0}:IfControl runat=\"server\"></{0}:IfControl>")]
public class IfControl : Literal
{
}
[ToolboxData("<{0}:ElseControl runat=\"server\"></{0}:ElseControl>")]
public class ElseControl : Literal
{
public override bool Visible
{
get
{
// find previous control (which must be an IfControl).
// If it's visible, we're not (and vice versa)
for (int i = Parent.Controls.IndexOf(this)-1; i >= 0; i--)
{
Control c = Parent.Controls[i];
if (c is IfControl)
return !c.Visible; // found it! render children if the if control is not visible
else if (c is Literal)
{
// literals with only whitespace are OK. everything else is an error between if and then
Literal l = c as Literal;
string s = l.Text.Trim();
if (s.Length > 0)
throw new ArgumentException("ElseControl must be immediately after an IfControl");
}
}
throw new ArgumentException("ElseControl must be immediately after an IfControl");
}
set
{
throw new ArgumentException("Visible property of an ElseControl is read-only");
}
}
}
}
If you want it more concise, you can easily shorten the tag name (by changing the class names and/or tag prefix). You can also create a new property (e.g. "test") to use instead of "Visible".
If you really want to get rid of the <%# %>, there are likley many different tricks you can use to leverage CodeDOM or other ways to dynamically compile code, although performance will be a challenge since you'll probably end up dynamically compiling code each time the page runs, it may introduce pesky security issues, and more. I'd stay away from that.
I am building a pop-out menu, and the client wants it to be able to pop out continously based on a heirarchy.
For example, the first pane is a list of options. When they are hovered over, another pane should pop up next to it with the next level of options, and so on until the last level of options is reached.
I can handle all the javascript and stuff, but I can't think of a way to continously embed repeaters inside repeaters. I know I could do it once by putting a repeater inside another, but then I would only have two layers.
I need to be able to continously embed repeaters for each layer of options, or achieve this with a similar technique using a different control.
Any help is great, thanks!
You won't be able to build this in mark up. You'll have to add the controls dynamically in your code behind by building the Repeater for each level and adding it to the previous Repeater's template. It will require a full postback for each option selected because the nested Repeater could potentially be of different depth depending on which option is chosen.
You might be better off doing this all client-side, though, using AJAX and javascript. When an option is chosen, fire off an AJAX request to see if that option has sub-options. If it does (return them), then dynamically build the new options control using javascript and add it to the page. When a different option is chosen, you'll remove the elements from the DOM holding the previously chosen options sub-options.
If you can get your menu out in form of a list of MenuItem objects, each of which has a (sometimes empty) list of sub items (and I really mean a List<MenuItem> here... we're going to use this collection as a datasource for a sub-repeater, so it needs to implement IEnumerable<T>) as a property MenuItem.SubItems, you could probably make use of a UserControl that loops out one menu level, and calls upon itself for the next.
In the UserControl you'd have something like this:
<li><a href='<%= this.MenuItem.Url %>'><%= this.MenuItem.LinkText %></a></li>
<asp:Repeater ID="UCRepeater" runat="server">
<HeaderTemplate>
<ul>
<ItemTemplate>
<menu:MenuItem ID="MenuItemUC" runat="server" />
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
The UserControl in the ItemTemplate is the same one, so for each item template the same thing will be rendered.
Below is the Code Behind for this user control, and this is where the magic happens:
public partial class MenuItemUserControl : UserControl
{
// A property we'll use as the data source
public MenuItem MenuItem { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
// If the current menu item has sub items, we bind the repeater to them
// And by the way, there is no use doing this on every postback. First
// page load is good enough...
if(!Page.IsPostBack) {
{
if(MenuItem.SubItems.Count > 0)
{
UCRepeater.DataSource = MenuItem.SubItems;
UCRepeater.DataBind();
}
}
}
protected void UCRepeater_OnItemDataBound(object sender,
RepeaterDataBoundEventArgs e)
{
// Every time an Item is bound to the repeater, we take the current
// item which will be contained in e.DataItem, and set it as the
// MenuItem on the UserControl
// We only want to do this for the <ItemTemplate> and
// <AlternatingItemTemplate>
if(e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
var uc = (MenuItemUserControl)e.Item.FindControl("MenuItemUC");
if(uc != null)
{
// This is the magic. Abrakadabra!
uc.MenuItem = (MenuItem)e.DataItem;
}
}
}
}
So in order to get this to work, the only thing missing is really a nice way of getting your data out as a hierarchical list of MenuItems. This I'll leave to your data access layer (and it would be cheap easy using LINQ to SQL or Entity Framework... ;) )
DISCLAIMER: This code is provided as is, and I wrote it off the top of my head. I have not tested it, but I think it will work - and if it doesn't, it could at least give you an idea of how to solve the problem. If you have problems, please post them in comments and I'll try to help out - but there are no promises of success here. Just a willingness to help out! =)