Label/Literal control with formatted text field - c#

I have discovered that it is possible to populate resource strings with variable information using string.format, see below:
String.Format(Resources.Temp.TempString, Resources.Contact.PhoneSales)
I can display this on my page using:
<p><%= String.Format(Resources.Temp.TempString, Resources.Contact.PhoneSales) %></p>
In some cases I have a Label or Literal (or any control) which might dynamically hide or show content. Ordinarily I would populate those using:
<asp:Literal ID="Literal1" Text="<%$ Resources:Temp,ContactUs %>" runat="server" />
I now would like the same String.Format functionality whilst still using controls. I found Display value of Resource without Label or Literal control but this doesn't actually work for me, it just writes out '<%= GetGlobalResourceObject("Messages", "ThankYouLabel") %>' on the page (not the content, that actual string).
UPDATE:
I have found a solution which works with some controls:
<asp:Label runat="server" ID="temp"><%= String.Format(Resources.Temp.TempString, Resources.Contact.PhoneSales) %></asp:Label>
However, this works doesn't work for Literal controls as they don't allow child controls. I'd prefer to keep using Literal's as they are the cleanest in terms of code generated, so still seeking a solution.

asp:Literal doesn't support <%= %> construct, and doesn't allow child controls (I mean something like <asp:Literal runat="server"><%= ... %></asp:Literal>).
But if you use data binding, your could use data-binding expresions <%# ... %>:
<asp:Label runat="server" Text="<%# string.Format(...) %>"></asp:Label>
To make this work you should ensure that either implicit or explicit data binding for your controls is used. Otherwise the control like this without binding outputs nothing.
This workaround is a little bit complex. Consider using either asp:Label control, or set the Text property from the code behind.

To solve my problem I have actually had a second look at how I am displaying content and found that a lot of times the Literals and Labels could be dropped in place of plain HTML code. I can then use my preferred method <%= ... %> to display content.

You could use an asp:PlaceHolder control instead of a Literal.
PlaceHolders can contain child controls; they also support <%= … %>-style "displaying expressions".

Related

How to assigning dynamic value to CssClass in .aspx page not working

I am using server side HyperLink control on webform and want to assign dynamic CSS Value to it.
HyperLink control is inside repeater control
It fails if i use it like this CssClass='search-<%#Eval("CSS") %>' and if i do it like this then it works CssClass='<%#Eval("CSS") %>'.
Issue i have is that i have to concatenate search- to field value <%#Eval("CSS") %>
How can i define so that value is assigned to it
in HTML source it shows up like this class="search-<%#Eval("CSS") %>"
SOLVED it by doing in this manner
CssClass='<%# Eval("CSS") +"-type-search "%>'
You need to include whatever text you need to inside <%# %> tag enclosed with ' ' or "" depends on what you used at start of your markup
class='<%# "search-" & Eval("CSS") %>'

Binding the DataSource of a repeater

I am using databinding to iterate through a recordset returned from the database, and one of those recordsets is a comma separated list of items - I'm trying to use a second repeater to display each of those items as a hyperlink. So far this is the code that I have:
<asp:Repeater ID="myRepeater" runat="server" DataSource='<%# DataBinder.Eval(Container.DataItem, "SomeList").ToString().Trim(',') %>'>
<ItemTemplate>
<a href='http://somesite/downloadattachment.aspx?itemid=<%# Container.ItemIndex %>'><%# Container.DataItem %></a>
</ItemTemplate>
</asp:Repeater>
The trouble is that so far there are 3 reasons why this doesnt work:
I get a server tag is not well formed error unless I remove the runat="server" - why is this? (And why does it work without the runat="server"?)
Container.DataItem Evaluates to an instance of System.Data.DataRowView - how do I get the current piece of the string that I split?
More importantly, this only seems to print out 1 Container.DataItem, even when I know there is a comma in the string I've given it - any ideas?
Instead of Eval(), for non-trivial scenarios I generally cast Container.DataItem to the type I want, and then act on it from there in a type-safe way.
The "not well formed" error is caused by the single-quotes around the parameter to Trim(). If you use single quotes on the outside of your attribute definition, you can't use them inside it. In cases like yours where a databinding definition has a lot of code in it, I often create a helper method (either inside a script runat=server for for MVC views and other inline-code-friendly cases, or in code-behind for traditional web forms apps) which handles the code I want to run. By refactoring into a method, it clarifies the HTML and sidesteps the lame single/double-quote restrictions.
Regardless of where you put the code, In your case, you want to:
cast Container.DataItem to DataRowView
extract the SomeList column value using the [] operator
call String.Split() on that string to turn your CSV string it into an array of strings
use that as a data source of your inner repeater
The code should look something like this:
<asp:Repeater ID="myRepeater" runat="server"
DataSource='<%# ((System.Data.DataRowView)Container.DataItem)["SomeList"].ToString().Split(new string[] {","}, StringSplitOptions.RemoveEmptyEntries)%>'>
<ItemTemplate>
<a href='http://somesite/downloadattachment.aspx?itemid=<%# Container.ItemIndex %>'>
<%# Container.DataItem %>
</a>
</ItemTemplate>
</asp:Repeater>
Did you specify the updatecommand, deletecommand to the sqldatasource?
Even if the proper parameters haven't been supplied, the affected rows will always be 0. If it has two parameters for the update command, two parameters have to be supplied through updatecommand.
For more information on this please check this URL: http://www.itpian.com/Coding/4774-Data-binding.aspx

Changing a control's style based on validation (ASP.NET)

I've got a very simple form with the following troubled snippet:
<asp:Panel class="normal" ID="Panel1" runat="server">
<strong><asp:Label ID="Panel1Error" class="error" Visible="false" runat="server"/></strong>
<label for="TextBox1"><em>*</em> Don't leave this blank</label>
<asp:TextBox ID="TextBox1" runat="server" />
<asp:RequiredFieldValidator ID="TextBox1RFV" runat="server"
ControlToValidate="TextBox1" ErrorMessage="This field cannot be blank."
Display="None" />
<--- other validators --->
</asp:Panel>
There are two things I want to do when the page fails validation:
Change the style of Panel1 (to one which shows different colors to indicate an error). I was able to do this by calling Page.Validate in Page_Load, then iterating over Page.Validators, getting each validator's parent control, casting it to a Panel, then setting .CssClass Doesn't seem like a superb solution, but it got the job done - is there a better way?
I want to take whatever validation error(s) are thrown and put them in the Panel1Error label, as well as set it to visible. This is where I am a bit baffled. I thought at first I could possibly specify the Label in which a validator writes its ErrorMessage, but I had no such luck. If I just toss the validator inside the Label, its formatting messes up the entire layout of the page, regardless of whether I directly assign it the 'error' CSS class or just leave it in the Label.
Just to clarify, in production, I would be doing this process for multiple Panels on a page, each with one form element, preventing me from calling the Panels explicitly and just saying Panel1.CssClass, etc.
I would recommend a javascript solution. ASP.NET injects a global js variable called Page_Validators, which is an array of all of the validator spans on the page. I wrote about this on my blog. It's a different solution, but it should give you enough insight to get started.
Use ValidationSummary controls with a ValidationGroup for each panel.
Seems fine if it worked.
Use a ValidationSummary control. Or you can inherit from the controls and override the render event.

Creating clickable links in runtime of c# aspx webform

I'm creating asp links using response.write in c#, the same HyperLink code works smoothly when inserted directly in the asp code, but when i copy/paste it to the response.write("...") it appears as an unclickable black text.
Am i forgetting something?
<asp:HyperLink ID='HyperLink1' runat='server' NavigateUrl='Exibe.aspx'> CLICK HERE </asp:HyperLink>
this exact code above thrown in the aspx source works greatly
response.write("<asp:HyperLink ID='HyperLink1' runat='server' NavigateUrl='Exibe.aspx'> CLICK HERE </asp:HyperLink>");
and this turns into a black text
You cannot insert an asp:Hyperlink tag directly into the response stream like that, as the hyperlink is actually a control that needs to "render" itself (if you replaced that with a normal "a" anchor/hyperlink tag it would work fine).
Instead you need to either create the control and add it to the page programatically, or maybe use a repeater control to render the anchors.
You are trying to do totally different things:
the markup (asp:HyperLink) will be compiled.
the Response.Write("asp:HyperLink") will NOT. It will render text as is, and of course you wont't see any link, in fact you should see the text inside the tag asp:HyperLink (inluding the tag itself in the HTML source).
If you want to create a link dunamically you can do it using code snippets below:
<asp:HyperLink ID='HyperLink1' runat='server' NavigateUrl='<%= GetDynamicUrl() %>'> CLICK HERE </asp:HyperLink>
/// Or plain HTML
<%= GetTheLinkText() %>
If you want to generate a hyperlink dynamically on the server-side like this, you can either use Response.Write with an <a> tag like slugster says, or alternatively consider the ASP:Literal control which renders exactly what you give it even if it contains markup e.g.
In your markup:
<asp:literal runat="server" id="MyLiteral" />
In your code:
string myHTMLFragment;
myHTMLFragment = "Hello. I am a link pointing to StackOverflow";
MyLiteral.Text = myHTMLFragment;

How to edit CSS style of a div using C# in .NET

I'm trying to grab a div's ID in the code behind (C#) and set some css on it. Can I grab it from the DOM or do I have to use some kind of control?
<div id="formSpinner">
<img src="images/spinner.gif" />
<p>Saving...</p>
</div>
Add the runat="server" attribute to it so you have:
<div id="formSpinner" runat="server">
<img src="images/spinner.gif">
<p>Saving...</p>
</div>
That way you can access the class attribute by using:
formSpinner.Attributes["class"] = "classOfYourChoice";
It's also worth mentioning that the asp:Panel control is virtually synonymous (at least as far as rendered markup is concerned) with div, so you could also do:
<asp:Panel id="formSpinner" runat="server">
<img src="images/spinner.gif">
<p>Saving...</p>
</asp:Panel>
Which then enables you to write:
formSpinner.CssClass = "classOfYourChoice";
This gives you more defined access to the property and there are others that may, or may not, be of use to you.
Make sure that your div is set to runat="server", then simply reference it in the code-behind and set the "class" attribute.
<div runat="server" id="formSpinner">
...content...
</div>
Code-behind
formSpinner.Attributes["class"] = "class-name";
This question makes me nervous. It indicates that maybe you don't understand how using server-side code will impact you're page's DOM state.
Whenever you run server-side code the entire page is rebuilt from scratch. This has several implications:
A form is submitted from the client to the web server. This is about the slowest action that a web browser can take, especially in ASP.Net where the form might be padded with extra fields (ie: ViewState). Doing it too often for trivial activities will make your app appear to be sluggish, even if everything else is nice and snappy.
It adds load to your server, in terms of bandwidth (up and down stream) and CPU/memory. Everything involved in rebuilding your page will have to happen again. If there are dynamic controls on the page, don't forget to create them.
Anything you've done to the DOM since the last request is lost, unless you remember to do it again for this request. Your page's DOM is reset.
If you can get away with it, you might want to push this down to javascript and avoid the postback. Perhaps use an XmlHttpRequest() call to trigger any server-side action you need.
Add the runat="server" attribute to the tag, then you can reference it from the codebehind.
Add runat to the element in the markup
<div id="formSpinner" runat="server">
<img src="images/spinner.gif">
<p>Saving...</p>
</div
Then you can get to the control's class attributes by using
formSpinner.Attributes("class")
It will only be a string, but you should be able to edit it.
How do you do this without runat="server"? For example, if you have a
<body runat="server" id="body1">
...and try to update it from within an Updatepanel it will never get updated.
However, if you keep it as an ordinary non-server HTML control you can. Here's the Jquery to update it:
$("#body1").addClass('modalBackground');
How do you do this in codebehind though?
If you do not want to make your control runat server in case you need the ID or simply don't want to add it to the viewstate,
<div id="formSpinner" class="<%= _css %>">
</div>
in the back-end:
protected string _css = "modalBackground";
If all you want to do is conditionally show or hide a <div>, then you could declare it as an <asp:panel > (renders to html as a div tag) and set it's .Visible property.
To expand on Peri's post & why we may not want to use viewstate the following code:
style="<%= _myCSS %>"
Protected _myCSS As String = "display: none"
Is the approach to look at if you're using AJAX, it allows for manipulating the display via asp.net back end code rather than jquery/jscript.

Categories