Easy Way to Change Style of Cents in Money Text - asp.net

I have a label (literal, whatever), that is being filled with currency ($5000.00). Is there an easy way to style the cents, like make the font-size smaller.
I know I can split the two up, but I am using MVP, and am looking for an easy way than passing all these new properties to the control (4+ of these labels are present).
Open to any suggestions, like a new control instead of the label, whatever you got.

I would suggest creating a new control that simply extends to Label/Literal. You can call it MoneyLabel, though Literal would probably be easier to work with. From that point, you can override the Render method to change the HTML output, format the string as you like.
Referencing it is not that tricky, the pages would need to reference the assembly where the class is stored.
In this way, you are not introducing CSS and HTML from the codebehind, not having to create extra JavaScript from what you need, and this is extremely reusable and its into how you code .NET already

I suppose in an ideally semantic world you'd probably do something like:-
<span class="currency-symbol">£</span>
<span class="major-currency-unit">5000</span>
<span class="decimal-point">.</span>
<span class="minor-currency-unit">00</span>
and then style away to your heart's content.

I would inherit from the label class, then create a newlabel class, StyledMoneyLabel.
I haven't tested this code, but hopefully you'll get the idea.
class StyledMoneyLabel : Label
{
double money = 0.0;
Render(HtmltextWriter)
{
HtmlSpan dollars = new HtmlSpan(CSS_CLASS);
dollars.Text = money.ToString(FORMAT_STRING_FOR_GETTING_DOLLARS.
///etc for decimals and so forth
}
}

Ideally you need to format it like the following.
$5000.<span class="Cents">00</span>
How you accomplish this is a bit tricky, you can have a "Dollars" and a "Cents" property and then manipulate the string into the format.

You could use javascript and let the client do all the heavy lifting...eg, in jquery (you'd have to define the putSpansAroundDollarsAndCents() function)
<div class="currencyToSplit">$5000.00</div>
$(".currencyToSplit").each(function() { putSpansAroundDollarsAndCents($(this)) });

Related

How to output results in color to a web page? (Response.Write alternative?)

I am converting an old script from ASP to ASP.NET and would like some advice. The original ASP script used Response.Write to output information about what happened during execution. I have rewritten the entire thing in ASP.NET but it is new to me as an old-school C programmer. The job requirements include using the VB flavor of ASP.NET, btw.
I originally put up a TextBox and edited the text property to dump my final report. Now they want different colors for different message importance and I find that the TextBox can only do one color for all lines. I fell back to the old standby R.W but I get a message that it's not declared and from looking around I see that it's an issue because I'm calling it from the code behind and that is 'out of scope' from the HTML elements of the page itself.
My question is what is the best way to output information to the web page with different lines being different colors from a page's code-behind?
Secondary question - if I have misunderstood anything feel free to correct my thinking. :)
Thanks!
Literal is the correct approach in my opinion too, to prevent messiness you can wrap it nicely with some functions.
First, have one literal control that will be the messages placeholder:
<asp:Literal id="litMessages" runat="server" />
Second, use CSS for the colors it's more elegant and flexible.. for example:
<style type="text/css">
.msg_information { color: blue; }
.msg_error { color: red; }
.msg_warning { color: purple; }
</style>
Now have this function:
void AddMessage(string message, string type)
{
string strHTML = string.Format("<div class=\"msg_{0}\">{1}</div>", type, message);
litMessages.Text += strHTML;
}
And finally to add message have such code anywhere in your code:
AddMessage("method started successfully", "information");
AddMessage("Failed to do this: " + someErrorMessage, "error");
AddMessage("Value is empty", "warning");
You can make it even more elegant by using enum for message type and more, but the above is enough for basic needs. :)
By having each message in its own <div> you make it be in its own line automatically and you can control each message easier with CSS.
Edit: my code is C# but can be converted easily to VB.NET as well.
Why not just wrap your Response.Write in a span with a color attribute based on what you are outputting? e.g.
Response.Write(String.Format(#"<span style=""color: #{0}"">{1}</span>", System.Drawing.ColorTranslator.ToHtml(Color.Red),yourMessage))
To make it simpler, you could then do something like this:
private void ReponseWriteEx(string output, Color color)
{
Response.Write(String.Format(#"<span style=""color: #{0}"">{1}</span>", System.Drawing.ColorTranslator.ToHtml(color),output))
}
And then call it, e.g. ResponseWriteEx("Hello World!",Color.Blue);
#Deverill,
Could you use a grid view and each row is a message? That way you can apply colors to the grid view.
I am not sure why you were using a text box and not a label.
Wince you were using Response.Write i am going to assume that you do not need user input.
your best bet here is the Literal control.
LiteralControl Class Unlike a label (or textbox) it can contain any html. This will let you place spans with classes around any text that you need. You may have to set some options on the literal to allow html

Formatting strings in ASP.NET Razor

I am currently writing a small templating system in ASP.NET to allow users to add content. For example, the user can enter the string (variable type is string).
topHeader[x] = "They think it's all over. It is now!";
However, one change that's needed is the ability to add some basic HTML tags within this content, so the following can be done
topHeader[x] = "They think it's all over. <strong>It is now!</strong>";
or
topHeader[x] = "They think it's all over. <a title="Football News" href="URL">It is now!</a>";
If you add such things into strings now they are not formatted as HTML, but I want to somehow escape them so that they can be. Naturally I've looked on the Internet for the answer, but as Razor is fairly new there's not much out there to help me out.
Anyone have an idea of how to do this?
You need to create an IHtmlString implementation holding your HTML source.
Razor plans to have a helper method to do this for you, but, AFAIK, it doesn't yet, so I believe you'll need to create your own class that implements the interface and returns your HTML from the GetHtmlString() method.
EDIT: You can use the HtmlString class.
You can either change your topHeader dictionary to hold IHtmlStrings instead of Strings, or you can leave your code as is, but wrap it in an HtmlString in the Razor view:
<tag>#new HtmlString(topHeader[x])</tag>
Make sure to correctly escape any non-HTML special characters.
The helper method they added is called Html.Raw() and it is much cleaner.
Here is an example:
#Html.Raw("Hello <a>World</a>!")
SLaks is right, but you don't need to write your own implementation of IHtmlString, there's one built in to System.Web called HtmlString. So:
topHeader[x] = new HtmlString("They think it's all over. <a title=\"Football News\" href=\"URL\">It is now!</a>");
Should do the trick.

ASP.NET Custom Control in VS - How to make VS format correctly

This is probably a pretty simple answer, but I haven't written a lot of controls, and I can't really think of the right words to Google it properly:
I have a custom control that I built, and when I create an instance in the HTML editor in VS, I type the following:
<cc1:MyControlName id="id1" runat="server">
When I type that closing angle bracket, VS reformats it to
<cc1:MyControlName id="id1" runat="server" />
the way it does with Buttons and other tags that are typically self-closing.
My control has inner content that I want to use, so I have to change the ending, and manually add the closing tag. I'd like it to behave like TextBox, where upon typing the closing bracket, it would add the and leave the cursor in the inside.
I'm assuming this is done via an attribute or something else defined in the class, but I can't seem to find what it is. Any ideas?
Obviously this isn't all that important, since it's just a few extra keystrokes, but I'd just like to make it as convenient to use as possible.
Thanks
Using the ParseChildrenAttribute class, declare the ParseChildren attribute for your control class. This will specify that the inner content should be read into a specific property (Name in the example). The PersistenceMode attribute specifies how to serialize the inner content.
[ParseChildren(true, "Name"),
DefaultProperty("Name")]
public class Foo
{
//...
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public string Name
{
get ; set;
}
}
There's also a broader explanation here.

asp.net best practice string concatenation

I am trying to find the best practice for generating and outputting html which would require a database query first to obtain the info. Currently in the aspx page I have a div with runat server:
<div runat="server" id="leaflet"></div>
Now just as a start to do a bit of testing I have a method that runs on page_load that basically does:
private void BuildLeaflet(string qnid)
{
//gets leaflet details
QueryLeafletDetails();
//return concatenated content string
leaflet.InnerHtml "<h1>" + dr["LSC Descriptor"] + "</h1>";
}
In the real solution the return is a concatenation of about 10 fields some very long as they are content.
I don't by any means think this is the best solution, but what is? A StringBuilder? Can I Write Each Part in turn to the site avoiding the concatenation in the method? Is the server div even best?
Edit: Forgot to put some of my content sections have simple (limited) html in them already such as paragraph, list... This allows me to easily produce documents for web and printing, I just use different stylesheets.
I would use <asp:Literal runat="server" enableViewState="false" id="leaflet" />. This doesn't generate any tags on the page, and doesn't stuff all the text in the ViewState.
And yes, use StringBuilder if you need to concatenate many long strings. This will be way more memory efficient.
The other solution would be to see if you can make some fixed markup on the page and put the contents of each DB field in it's own control (<asp:Literal />?).
I'd use either string.Format, if the number of fields is fixed (and relatively small), or a StringBuilder, otherwise. Readability of the code would be my guide, less so performance. You might also want to think about abstracting this out into a UserControl if you plan to reuse it. Then you could give it settable properties and build the render logic into the control to avoid repeating yourself.
Various people have benchmarked this - iirc format is fine for <4 items, simple concats for <7, stringbuilding above that.
I strongly advise against creating HTML as strings btw.

How can I use a traditional HTML id attribute with an ASP.net runat='server' tag?

I am refactoring some CSS on a website. I have been working on, and noticed the absence of traditional HTML IDs in the code.
There is heavy use of CssClass='…', or sometimes just class='…', but I can't seem to find a way to say id='…' and not have it swapped out by the server.
Here is an example:
<span id='position_title' runat='server'>Manager</span>
When the response comes back from the server, I get:
<span id='$aspnet$crap$here$position_title'>Manager</span>
Any help here?
Use jQuery to select the element:
$("span[id$='position_title']")....
jQuery's flexible selectors, especially its 'begins with'/'ends with selectors' (the 'end with' selector is shown above, provide a great way around ASP.NET's dom id munge.
rp
The 'crap' placed in front of the id is related to the container(s) of the control and there is no way (as far as I know) to prevent this behavior, other than not putting it in any container.
If you need to refer to the id in script, you can use the ClientID of the control, like so:
<script type="text/javascript">
var theSpan = document.getElementById('<%= position_title.ClientID %>');
</script>
Most of the fixes suggested her are overkill for a very simple problem. Just have separate divs and spans that you target with CSS. Don't target the ASP.NET controls directly if you want to use IDs.
<span id="FooContainer">
<span runat="server" id="Foo" >
......
<span>
</span>
You can embed your CSS within the page, sprinkled with some server tags to overcome the problem. At runtime the code blocks will be replaced with the ASP.NET generated IDs.
For example:
[style type="text/css"]
#<%= AspNetId.ClientID %> {
... styles go here...
}
[/style]
[script type="text/javascript"]
document.getElementById("<%= AspNetId.ClientID %>");
[/script]
You could go a bit further and have some code files that generate CSS too, if you wanted to have your CSS contained within a separate file.
Also, I may be jumping the gun a bit here, but you could use the ASP.NET MVC stuff (not yet officially released as of this writing) which gets away from the Web Forms and gives you total control over the markup generated.
Ok, I guess the jury is out on this one.
#leddt, I already knew that the 'crap' was the containers surrounding it, but I thought maybe Microsoft would have left a backdoor to leave the ID alone. Regenerating CSS files on every use by including ClientIDs would be a horrible idea.
I'm either left with using classes everywhere, or some garbled looking IDs hardcoded in the css.
#Matt Dawdy: There are some great uses for IDs in CSS, primarily when you want to style an element that you know only appears once in either the website or a page, such as a logout button or masthead.
The best thing to do here is give it a unique class name.
You're likely going to have to remove the runat="server" from the span and then place a within the span so you can stylize the span and still have the dynamic internal content.
Not an elegant or easy solution (and it requires a recompile), but it works.
.Net will always replace your id values with some mangled (every so slightly predictable, but still don't count on it) value. Do you really NEED to have that id runat=server? If you don't put in runat=server, then it won't mangle it...
ADDED:
Like leddt said, you can reference the span (or any runat=server with an id) by using ClientID, but I don't think that works in CSS.
But I think that you have a larger problem if your CSS is using ID based selectors. You can't re-use an ID. You can't have multiple items on the same page with the same ID. .Net will complain about that.
So, with that in mind, is your job of refactoring the CSS getting to be a bit larger in scope?
I don't know of a way to stop .NET from mangling the ID, but I can think of a couple ways to work around it:
1 - Nest spans, one with runat="server", one without:
<style type="text/css">
#position_title { // Whatever
}
<span id="position_titleserver" runat="server"><span id="position_title">Manager</span></span>
2 - As Joel Coehoorn suggested, use a unique class name instead. Already using the class for something? Doesn't matter, you can use more than 1! This...
<style type="text/css">
.position_title { font-weight: bold; }
.foo { color: red; }
.bar { font-style: italic; }
</style>
<span id="thiswillbemangled" class="foo bar position_title" runat="server">Manager</span>
...will display this:
Manager
3 - Write a Javascript function to fix the IDs after the page loads
function fixIds()
{
var tagList = document.getElementsByTagName("*");
for(var i=0;i<tagList.length;i++)
{
if(tagList[i].id)
{
if(tagList[i].id.indexOf('$') > -1)
{
var tempArray = tagList[i].id.split("$");
tagList[i].id = tempArray[tempArray.length - 1];
}
}
}
}
If you're fearing classitus, try using an id on a parent or child selector that contains the element that you wish to style. This parent element should NOT have the runat server applied. Simply put, it's a good idea to plan your structural containers to not run code behind (ie. no runat), that way you can access major portions of your application/site using non-altered IDs. If it's too late to do so, add a wrapper div/span or use the class solution as mentioned.
Is there a particular reason that you want the controls to be runat="server"?
If so, I second the use of < asp : Literal > . . .
It should do the job for you as you will still be able to edit the data in code behind.
I usually make my own control that extends WebControl or HtmlGenericControl, and I override ClientID - returning the ID property instead of the generated ClientID. This will cause any transformation that .NET does to the ClientID because of naming containers to be reverted back to the original id that you specified in tag markup. This is great if you are using client side libraries like jQuery and need predictable unique ids, but tough if you rely on viewstate for anything server-side.
If you are accessing the span or whatever tag is giving you problems from the C# or VB code behind, then the runat="server" has to remain and you should use instead <span class="some_class" id="someID">. If you are not accessing the tag in the code behind, then remove the runat="server".

Resources