UGC conditional statement is not working - tridion

I am using UGC feature of Tridion 2011. I have done almost but stuck in one place. actually, i have to display one text when user have entered comments, it will display if comments are greater then 0. i am using for this condition but it does not go in the condition.
<ugc:ItemStats ItemURI="#PhysicalUri" runat="server">
<ugc:Choose runat="server">
<ugc:When test=" ugcItemStats.numberOfComments equals 0 " runat="server">
html1
</ugc:When>
<ugc:Otherwise runat="server">
html2
</ugc:Otherwise>
</ugc:Choose>
</ugc:ItemStats>
Could any one please help me to resolve his issue

Use this code, i hope will be work.
<%
HttpContext.Current.Item["variable"] = 0;
%>
<ugc:ItemStats ItemURI="#PhysicalUri" runat="server">
<ugc:Choose runat="server">
<ugc:When test="ugcItemStats.numberOfComments equals variable " runat="server">
html1
</ugc:When>
<ugc:Otherwise runat="server">
html2
</ugc:Otherwise>
</ugc:Choose>
</ugc:ItemStats>

The When statement accesses the ugcItemStates object from the HttpContext.Current.Items collection.
I suspect that by nesting the statement in the ItemStats control causes this object not to be available yet.

Related

__EVENTTARGET Contains Invalid Control ID

Googled variations of the title and everything was related to a null value.
I have an issue where the return value from Page.Request.Params["__EVENTTARGET"] duplicates the unique id of the control.
ctl00$MainContent$ActivityTabset$TabNewActivity$cbxActivityCode$ctl00$MainContent$ActivityTabset$TabNewActivity$cbxActivityCode
cbxActivityCode.UniqueID returns
ctl00$MainContent$ActivityTabset$TabNewActivity$cbxActivityCode
The following is the code that fails in the comparison. It is in the Page_Load event, and is the only code to execute right now if it is a postback.
string controlName = Page.Request.Params["__EVENTTARGET"];
if (cbxActivityCode.UniqueID == controlName)
{
ConfigureActivityUnits();
}
Here is the definition of the control
<obout:ComboBox ID="cbxActivityCode" runat="server"
DataSourceID="ObjectDataSourceDAOActivity"
FilterType="StartsWith" EmptyText="Select..."
AutoPostBack="true"
OnSelectedIndexChanged="cbxActivityCode_SelectedIndexChanged"
AllowCustomText="false" AutoValidate="true" DataValueField="Id"
DataTextField="Description" EnableViewState="true"
OpenOnFocus="true" MenuWidth="425" AllowEdit="False"
Width="300px">
</obout:ComboBox>
I am new to ASP.net and am wondering if it is possible one of the control attributes is causing this behavior?
Is it possibly a bug with the control?
Are there hooks in ASP.net where someone can manipulate a value which will effect Page.Request.Params["__EVENTTARGET"]? (This is a big messy legacy system, and I have no prior developers as a resource.)
If not any of the above, anyone have any ideas as to what could be causing this?

Is there a way to insert text into a page without "Response.Write"?

I 'm trying to make a "login information" on the top panel, like "Welcome Back XXX", so I use
<% Response.Write(Session["username"]); %>
inside the aspx page.
It works, but is there anyway to use the variable directly without Response.Write here? It seems unnecessary.
There is a simple "shortcut" in the ASP.NET page syntax to Response.Write.
<%= Session["username"] %>
is functionally equivalent to
<% Response.Write(Session["username"]); %>
Typically you want to encode your session variables as HTML using Html.Encode, in case they contain characters which are not in the accepted HTML range. If you're using ASP.NET 4, you can use <%: %>, which is equivalent to Response.Write(Html.Encode(string)).
You can do it like this:
<%= Session["username"] %>
And if you use ASP.NET 4.0 you can automatically HTML encode the value by using this syntax:
<%: Session["username"] %>
put a asp.net label on your page, like
<asp:Label id=lblUserName runat="server" />
and on your codebehind page, on page_load event or on proper event
lblUserName.Text = String.Format("welcome back {0}",Session["username"]);
use a label and assign user name to it
In aspx (html code)
<asp:Label id=lblUserName runat="server" />
In aspx.cs (Code behind)
lblUserName .Text = "Welcome back"+Session["username"].ToString();
The correct way.
First is to check if the value is null
Second because you write it on a page, use the HTMLEncode to be sure that you avoid any type of injection, or problems.
now, if you like to use a Literal or a Label, or just direct write it, is up to you. If you going to place it inside an UpdatePanel you must use a Literal.
Now, if you use Literal avoid to set the ViewState to gain space from it, ether way you need to set it on PageLoad. And it will be
<asp:Literal runat="server" id="txtUserName" EnableViewState="false" />
and on page load.
if(Session["username"] != null)
{
Debug.Assert(Session["username"].ToString.Length > 0 , "Check out why I have zero user name");
txtUserName.Text = Server.HTMLEncode(Session["username"].ToString);
}

Hiding the Null Fields

I have a data repeater that is reading a few different fields. However, some information being pulled is empty. I would like to hide these fields in this case.
I am not sure how best to go about this. I have tried the following methods:
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:db %>"
SelectCommand="SELECT GrName, GrRoom
FROM [Group] WHERE GrName LIKE 'A%' ORDER BY GrName && * IS NOT NULL">
</asp:SqlDataSource>
<!-- output to page -->
<div data-role="collapsible-set">
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
<ItemTemplate>
<div data-role="collapsible" data-collapsed="true">
<p>Room: <%# Eval("GrRoom")%></p>
</div>
</ItemTemplate>
</asp:Repeater>
Or, do I do something like this in the head?
<script type="text/vbscript">
If (GrRoom = NULL) Then
display: none;
End If
</script>
I'm not sure I'm grasping this concept right now. Basically, I want the following to function to run as:
"If GrRoom is empty, do not display"
Any thoughts on this? I appreciate your insight. I'm relatively new to ASP and .NET, so I'm still learning a lot.
Thank you for your time and help.
<ItemTemplate>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"
Visible='<%# Not [String].IsNullOrEmpty(If(TypeOf Eval("GrRoom") Is DbNull, [String].Empty, DirectCast(Eval("GrRoom"), String))) %>'>
<div data-role="collapsible" data-collapsed="true">
<p>
Room:
<%# Eval("GrRoom")%></p>
</div>
</asp:PlaceHolder>
</ItemTemplate>
Edit
I didn't test it at first, now I've properly tested this code. I'm also checking now and for empty strings. Please try it.
Edit 2
I was using C# syntax, sorry, now is edited with VB
Edit 3
I added and the DbNull check
If your objective is not to retrieve the data at all where the field is null, your SQL syntax is close but needs a tweak:
SELECT GrName, GrRoom
FROM [Group]
WHERE GrName LIKE 'A%'
AND IsNull(GrRoom, '') <> ''
ORDER BY GrName
"* is not null" is not valid - IS NOT NULL must refer to a single value, and * refers to all columns in the collected tables utilized in the result set.
&& is also not a valid WHERE construct - you must use "AND" and "OR" not && and ||
Your WHERE conditionals all have to occur before the ORDER BY clause
And finally - Like 'A%' will automatically filter out null values because a null cannot be like something with a value.
So if you use the sql as I've written it, that will ensure that GrName is always populated, and so on your ASP side, logic to show/hide controls isn't necessary.
Of course there are reasons to show/hide controls as well - but if you can eliminate unwanted rows from the data being sent to the server, that's less traffic overall, and "as little as necessary and possible" is always a goal when it comes to data transmission.

How can I replicate If...Then logic as a Web control?

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.

In ASCX-control not doing IF/ELSE condition

There ASCX-controls that the program-loaded onto the page.
In a Repeater control in which, depending on the conditions displayed a different set of COLUMNS and DataTable with a different set of columns.
So, on the ASPX-page, this construction work Good.
<ItemTemplate>
<tr class="objectrow" href="<%# GetCompleteViewObjectLink(Convert.ToInt32(Eval("ID_Object")))%>">
<td align="center" class="c1">
<%# Eval("ID_Object") %>
</td>
<% if (GetObjectTypeName() == "Sot")
{ %>
<td align="center" class="c6">
<%# Eval("SOTName") != DBNull.Value ? Eval("SOTName") : ""%>
</td>
<% } %>
............................
But in program-loaded to page ASCX-control I have an Exception:
Error: DataBinding:
'System.Data.DataRowView' does not
contain a property named SOTName.
and another does not conform: in aspx-page my breakpoint on row
<% if (GetObjectTypeName() == "Sot")
was work off. But in ascx-control NOT.
Please, help! Why behaviour is so different? How to be?
Check your data for actual rows, i.e. row count? I would bet your DataSource is null.
I don't think you're getting data when you think you should be.
The Page Load event of the user control will execute before the aspx Page Load. If you are getting some type of parameter for your query in the .ascx in the Page Load of the .aspx, you ought to grab that in the Page_Init of the .aspx.
As TheGeekYouNeed points out, it's crucial to know when the DataSource of the Repeater is defined, as the control's events are processed before the page events.
You can add code like
<td>GetObjectTypeName='<%# GetObjectTypeName() %>'</td>
to find out whether the if() condition applies for your data.

Resources