MVC html Custom helper for a status inidicator - c#

I am trying to create a server status icon on the top of my application. When it is off appear as red, and on the other hand when it is on appear as green.
I have done all the dirty job in my DAL, BL, Controller and ViewModel and as a result i have a div element on my page which change colors subjected on the service status. My problem is that i cannot add a label next to the div.
public static class ServerStatusIconHelper
{
public static MvcHtmlString ServerStatusIconHelper(this HtmlHelper htmlHelper, bool isServerActive)
{
// Main container
var div = new TagBuilder("div");
bool isActive = isServerActive;
var labelValue = isActive ? "The server status is On" : "The server status is Off";
if (isActive)
{
div.Attributes.Add("id", "server-warning-on");
div.Attributes.Add("style", "background-color: green; height:25px; margin-bottom: 10px; border-radius: 25px; width: 25px; margin-left: 10px;");
}
else
{
div.Attributes.Add("id", "server-warning-off");
div.Attributes.Add("style", "background-color: red; height:25px; margin-bottom: 10px; border-radius: 25px; width: 25px; margin-left: 10px;");
}
return new MvcHtmlString(div.ToString());
}
}
I would appreciate some help since i dont know to add a div with a paragraph element which will provide the labelValue. In addition if anyone has any idea for something better would be nice.

When using TagBuilder you can set tag content using InnerHtml property or SetInnerText method:
InnerHtml: Gets or sets the inner HTML value for the element.
SetInnerText: Sets the InnerHtml property of the element to an HTML-encoded version of the specified string.
Here is an example:
var div = new TagBuilder("div");
div.AddCssClass("someClass");
div.MergeAttribute("id", "someId");
div.InnerHtml = "Some Text or Html Tag";
var result= div.ToString();
Which generates this output:
<div class="someClass" id="someId">Some Text or Html Tag</div>

You can combine label and div tags this way.
Also, you need to add display: inline-block; to your style to display label next to div.

You can use InnerHtml property of the tag.
var labelValue = isActive ? "The server status is On" : "The server status is Off";
div.InnerHtml = labelValue;
or if you want to concatenate a span element with div, you can do
var span = new TagBuilder("span");
span.InnerHtml = labelValue;
and return as
return new MvcHtmlString(div.ToString() + span.ToString());

Related

Setting #Font-Face From C# Code Behind

In my stylesheet I have this declared
#font-face {
font-family: 'light';
src: url('Fonts/HelveticaNeueLTStd-Lt.otf') format('opentype');
}
Now in my C# code behind I try to set the class like this
row.CssClass = light;
But I get a compile error of
The name 'light' does not exist in the current context
Is it possible to reference a css class #font-face from C# codebehind?
EDIT
This is how I am attempting to use this - I have tried the below
.lightfontface {
font-family: 'light';
}
#font-face {
font-family: 'light';
src: url('Fonts/HelveticaNeueLTStd-Lt.otf') format('opentype');
}
row.CssClass = lightfontface;
I believe your
row.CssClass = light;
needs to be
row.CssClass = "className";
and your css will need a .className entry.
Imagine your html row:
<tr class="className">stuff</tr>
Your CssClass assignment is assigning the value to class, and your css can use a class selector to format that row.
To sum up some of the comments, the style sheet entry should simply be:
.className { font-family: 'light'; }
Ordering on your style sheet is important. Put the font-face definition above the .className style entry. See: https://www.w3.org/TR/CSS2/cascade.html#cascading-order

How do I implement a checkbox list in ASP.NET Core?

I am looking to implement a checkboxlist in ASP.NET Core, but am facing some difficulties.
My ViewModel:
public class GroupIndexViewModel
{
public Filter[] Filters { get; set; }
}
public class Filter
{
public int Id { get; set; }
public string Name { get; set; }
public bool Selected { get; set; }
}
My View:
#model GroupIndexViewModel
<form asp-action="Index" asp-controller="Group" method="get">
<ul>
#for (var i = 0; i < Model.Filters.Length; i++)
{
<li>
<input type="checkbox" id="#Model.Filters[i].Name" asp-for="#Model.Filters[i].Selected" value="#Model.Filters[i].Selected" checked="#Model.Filters[i].Selected" />
<label for="#Model.Filters[i].Name">#Model.Filters[i].Name</label>
</li>
}
</ul>
<button type="submit" name="action">Filtrer</button>
</form>
When posting to my controller, the Filter property in my viewmodel shows selected false even though it is selected in the view.
I would do following way.
#model GroupIndexViewModel
<form asp-action="Index" asp-controller="Group" method="get">
<ul>
#for (var i = 0; i < Model.Filters.Count; i++)
{
<li>
<input type="checkbox" asp-for="#Model.Filters[i].Selected" />
<label asp-for="#Model.Filters[i].Selected">#Model.Filters[i].Name</label>
<input type="hidden" asp-for="#Model.Filters[i].Id" />
<input type="hidden" asp-for="#Model.Filters[i].Name" />
</li>
}
</ul>
<button type="submit" name="action">Filtrer</button>
</form>
Here I assuming that you have proper implementation of controller and action.
The question might be already answered but I wanted to explain your issue, so others can understand what's happening.
You are not aware that you are already specifying the false value to your input, since you're implementing a bad use of attributes.
Let's take a look at your view
#model GroupIndexViewModel
<form asp-action="Index" asp-controller="Group" method="get">
<ul>
#for (var i = 0; i < Model.Filters.Length; i++)
{
<li>
<input type="checkbox" id="#Model.Filters[i].Name" asp-for="#Model.Filters[i].Selected" value="#Model.Filters[i].Selected" checked="#Model.Filters[i].Selected" />
<label for="#Model.Filters[i].Name">#Model.Filters[i].Name</label>
</li>
}
</ul>
<button type="submit" name="action">Filtrer</button>
</form>
So, first. You are creating input elements from an array of Filter. Now let's take a closer look at your input element.
<input type="checkbox" id="#Model.Filters[i].Name" asp-for="#Model.Filters[i].Selected" value="#Model.Filters[i].Selected" checked="#Model.Filters[i].Selected" />
Now, let me explain this.
You are specifying a type, using the type attribute.
You are specifying an id, using the id attribute.
You bind the input to the model, using the asp-for tag helper.
You specify a value for the input, using the value attribute.
Finally, you set the input as checked, with the checked attribute.
If you take a look at the Tag Helpers Documentation, you'll find the relationship between the .Net Type and the Input Type, understanding that:
Checkboxes holds a boolean value, corresponding to the model, and formatted by the tag helper as type="checkbox".
Since you're using the type="checkbox" attribute, the Tag Helper value can only be true or false. So, if we go back and look at the input element, you're already specifying a value to the input. Even though the tag-helper can assign a value to the input, it can't override the one already specified. Therefore, your input, will always have the value you've specified, in this case, a boolean is always false by default.
Now you might think that your input element, has a false value, and for instance, adding the checked="checked" will not change the value to true, since the value attributes, overrides the checked attribute. Causing a bad implementation of both attributes.
Therefore, you must use only one of the attributes. (Either the value or the checked). You can use them, for convenience. But in this case, you must use the default checked attribute. Since you're implementing a Tag Helper, and the input value, have to be of type boolean. And the checked attribute value, returns a boolean and for instance, is the one used by the Tag Helper.
So the implementation provided by #dotnetstep should work, since it only declares the tag helper in the input element. So the Tag Helper, handles itself the corresponding attributes of the input.
#model GroupIndexViewModel
<form asp-action="Index" asp-controller="Group" method="get">
<ul>
#for (var i = 0; i < Model.Filters.Count; i++)
{
<li>
<input type="checkbox" asp-for="#Model.Filters[i].Selected" />
<label asp-for="#Model.Filters[i].Selected">#Model.Filters[i].Name</label>
<input type="hidden" asp-for="#Model.Filters[i].Id" />
<input type="hidden" asp-for="#Model.Filters[i].Name" />
</li>
}
</ul>
<button type="submit" name="action">Filtrer</button>
</form>
Building on #dotnetstep's answer, I created a Tag Helper that takes a model of IEnumerable of SelectListItem and generates the fields described in his answer.
Here is the Tag Helper code:
[HtmlTargetElement(Attributes = "asp-checklistbox, asp-modelname")]
public class CheckListBoxTagHelper : TagHelper
{
[HtmlAttributeName("asp-checklistbox")]
public IEnumerable<SelectListItem> Items { get; set; }
[HtmlAttributeName("asp-modelname")]
public string ModelName { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
var i = 0;
foreach (var item in Items)
{
var selected = item.Selected ? #"checked=""checked""" : "";
var disabled = item.Disabled ? #"disabled=""disabled""" : "";
var html = $#"<label><input type=""checkbox"" {selected} {disabled} id=""{ModelName}_{i}__Selected"" name=""{ModelName}[{i}].Selected"" value=""true"" /> {item.Text}</label>";
html += $#"<input type=""hidden"" id=""{ModelName}_{i}__Value"" name=""{ModelName}[{i}].Value"" value=""{item.Value}"">";
html += $#"<input type=""hidden"" id=""{ModelName}_{i}__Text"" name=""{ModelName}[{i}].Text"" value=""{item.Text}"">";
output.Content.AppendHtml(html);
i++;
}
output.Attributes.SetAttribute("class", "th-chklstbx");
}
}
You will need to add the following to the _ViewImports.cshtml file:
#addTagHelper *, <ProjectName>
Then to drop the check list box into your razor view it's as easy as:
<div asp-checklistbox="Model.Brands" asp-modelname="Brands"></div>
You might notice that I'm adding a class attribute to the div to style the box and it's content. Here is the CSS:
.th-chklstbx {
border: 1px solid #ccc;
padding: 10px 15px;
-webkit-border-radius: 5px ;
-moz-border-radius: 5px ;
-ms-border-radius: 5px ;
border-radius: 5px ;
}
.th-chklstbx label {
display: block;
margin-bottom: 10px;
}
Standing on the shoulders of #dotnetstep and #gsxrboy73, this approach adds an optional control title and "Check All" type of checkbox. It also serializes "id" attributes so you can safely have multiple Check Box Lists on a page. This is tailored for .NET 5 binding to MVC Models in a Bootstrap environment.
I prefer thin and light models that don't rope in giant mvc libraries:
public class CheckBoxListItem
{
public string Key { get; set; }
public string Value { get; set; }
public bool IsChecked { get; set; } = false;
public bool IsDisabled { get; set; } = false;
}
A List<CheckBoxListItem> drives the Tag Helper:
/// <summary>check-box-list Tag Helper</summary>
[HtmlTargetElement("Check-Box-List", Attributes = "asp-title, asp-items, asp-model-name, asp-check-all-label", TagStructure=TagStructure.NormalOrSelfClosing)]
public class CheckBoxListTagHelper : TagHelper
{
/// <summary>HTML element ID of the tracking form element</summary>
[HtmlAttributeName("asp-form-id")]
public string FormId { get; set; }
/// <summary>Optional bolder title set above the check box list</summary>
[HtmlAttributeName("asp-title")]
public string ListTitle { get; set; }
/// <summary>List of individual child/item values to be rendered as check boxes</summary>
[HtmlAttributeName("asp-items")]
public List<CheckBoxListItem> Items { get; set; }
/// <summary>The name of the view model which is used for rendering html "id" and "name" attributes of each check box input.
/// Typically the name of a List[CheckBoxListItem] property on the actual passed in #Model</summary>
[HtmlAttributeName("asp-model-name")]
public string ModelName { get; set; }
/// <summary>Optional label of a "Check All" type checkbox. If left empty, a "Check All" check box will not be rendered.</summary>
[HtmlAttributeName("asp-check-all-label")]
public string CheckAllLabel { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
string id = context.UniqueId;
output.TagName = "div";
string html = "";
output.PreElement.AppendHtml($"<!-- Check List Box for {(string.IsNullOrEmpty(ListTitle) ? ModelName : ListTitle)} -->\r\n");
if (!string.IsNullOrEmpty(ListTitle))
{
// Prepend a Title to the control
output.PreContent.AppendHtml($"\r\n\t<label id=\"check-box-list-label-{id}\" class=\"cblTitle\">\r\n"
+ $"\t\t<strong>{ListTitle}</strong>\r\n"
+ $"\t</label>\r\n");
}
if (!string.IsNullOrEmpty(CheckAllLabel))
{
// Prepend a "Check All" type checkbox to the control
output.PreContent.AppendHtml("\t<div class=\"form-check\">\r\n"
+ $"\t\t<input id=\"check-box-list-all-{id}\"\r\n"
+ "\t\t\tclass=\"cblCheckAllInput form-check-input\"\r\n"
+ "\t\t\ttype=\"checkbox\"\r\n"
+ $"\t\t\tvalue=\"true\"\r\n"
);
if (Items.All(cbli => cbli.IsChecked))
{
output.PreContent.AppendHtml("\t\t\tchecked=\"checked\"\r\n");
}
output.PreContent.AppendHtml("\t\t\t/>\r\n"
+ $"\t\t<label id=\"check-box-list-all-label-{id}\" class=\"cblCheckAllLabel form-check-label\" for=\"check-box-list-all-{id}\">\r\n"
+ $"\t\t\t {CheckAllLabel}\r\n"
+ "\t\t</label>\r\n"
+ "\t</div>\r\n"
) ;
}
// Begin the actual Check Box List control
output.Content.AppendHtml($"\t<div id=\"cblContent-{id}\" class=\"cblContent\">\r\n");
// Create an individual check box for each item
for (int i = 0; i < Items.Count(); i++)
{
CheckBoxListItem item = Items[i];
html = "\t\t<div class=\"form-check\">\r\n"
+ $"\t\t\t<input id=\"{ModelName}_{i}__IsChecked-{id}\"\r\n"
+ $"\t\t\t\tname=\"{ModelName}[{i}].IsChecked\"\r\n"
+ $"\t\t\t\tclass=\"cblCheckBox form-check-input\"\r\n"
+ $"\t\t\t\tform=\"{FormId}\"\r\n"
+ "\t\t\t\tdata-val=\"true\"\r\n"
+ "\t\t\t\ttype=\"checkbox\""
+ "\t\t\t\tvalue=\"true\""
;
if (item.IsChecked)
{
html += "\t\t\t\tchecked=\"checked\"\r\n";
}
if (item.IsDisabled)
{
html += "\t\t\t\tdisabled=\"disabled\"\r\n";
}
html += "\t\t\t\t/>\r\n"
+ $"\t\t\t<label id=\"check-box-list-item-label-{id}-{i}\" class=\"cblItemLabel form-check-label\" for=\"{ModelName}_{i}__IsChecked-{id}\">\r\n"
+ $"\t\t\t\t {item.Value}\r\n"
+ "\t\t\t</label>\r\n"
+ $"\t\t\t<input type=\"hidden\" id=\"{ModelName}_{i}__IsChecked-{id}-tag\" name=\"{ModelName}[{i}].IsChecked\" form =\"{FormId}\" value=\"false\">\r\n"
+ $"\t\t\t<input type=\"hidden\" id=\"{ModelName}_{i}__Key-{id}\" name=\"{ModelName}[{i}].Key\" form =\"{FormId}\" value=\"{item.Key}\">\r\n"
+ $"\t\t\t<input type=\"hidden\" id=\"{ModelName}_{i}__Value-{id}\" name=\"{ModelName}[{i}].Value\" form =\"{FormId}\" value=\"{item.Value}\">\r\n"
+ "\t\t</div>\r\n"
;
output.Content.AppendHtml(html);
}
output.Content.AppendHtml("\t</div>\r\n");
output.Attributes.SetAttribute("id", $"check-box-list-{id}");
output.Attributes.SetAttribute("class", "cblCheckBoxList");
}
}
Revealing prototype JS makes the "Check All" box play nice with the others:
// Attach event handlers to controls
$(function () {
// Toggle child check boxes per the "Check All" check box state
$("div.cblCheckBoxList").on("click", "input.cblCheckAllInput", function (event) {
let chkBoxListDiv = $(event.target).closest("div.cblCheckBoxList");
let chkBoxList = new checkBoxList($(chkBoxListDiv).attr("id"), $(event.target).attr("id"));
chkBoxList.onCheckAllClick();
});
// Sync the "Check All" box w/ the child check boxes' check box states
$("div.cblCheckBoxList").on("click", "input.cblCheckBox", function (event) {
let chkBoxListDiv = $(event.target).closest("div.cblCheckBoxList");
let chkBoxList = new checkBoxList($(chkBoxListDiv).attr("id"), null);
chkBoxList.onCheckItemClick();
});
});
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Check Box List
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var checkBoxList = function (checkBoxListDivId, checkAllInputId) {
this.listDivId = checkBoxListDivId;
this.allInputId = (checkAllInputId ?? $("#" + this.listDivId).find("input.cblCheckAllInput")?.first()?.attr("id"));
};
checkBoxList.prototype = function () {
// If a "Check All" type check box is clicked, update the individual child check boxes accordingly
var onCheckAllClick = function () {
// Find the "Check All" check box that was clicked
let checkAllInput = $('#' + this.allInputId);
// Determine whether the "Check All" check box is checked or unchecked
let chkd = $(checkAllInput).prop('checked');
// Get a list of child/item check boxes
let chks = $('#' + this.listDivId).find('input.cblCheckBox');
// Make the child/item check boxes match the value of the "Check All" check box
chks.prop('checked', chkd);
},
// If an individual child check box is clicked and a "Check All" type checkbox exists, update it accordingly
onCheckItemClick = function () {
if (!((this.allInputId === undefined) || (this.allInputId.length === 0))) {
// Get an array of check boxes that are NOT checked
let notChkd = $('#' + this.listDivId).find("input.cblCheckBox:not(:checked)");
// Update the "Check All" check box accordingly
$("#" + this.allInputId).prop('checked', (notChkd.length === 0));
}
};
return {
onCheckAllClick: onCheckAllClick,
onCheckItemClick: onCheckItemClick
};
}();
Slap some CSS lipstick on:
/* For CheckBoxList form control */
.cblCheckBoxList {
border: 1px solid #ccc;
padding: 10px 15px;
margin-right: 10px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
border-radius: 5px;
}
.cblCheckBoxList .cblContent {
height: 150px;
overflow-y: scroll;
padding: 0;
margin: 0;
}
.cblCheckBoxList .cblTitle {
font-weight: bolder;
}
.cblCheckBoxList .cblCheckAllLabel {
margin-bottom: 10px;
}
.cblCheckBoxList .cblCheckAllInput {
margin-bottom: 0;
}
.cblCheckBoxList .cblItemLabel {
margin-bottom: 0;
font-size: small;
}
.cblCheckBoxList .cblCheckBox {
margin-bottom: 0;
font-size: small;
}
And drop the Check Box List onto a page:
#* On the passed in View Model, "IceCreamFlavors" is a property that is a List of type CheckBoxListItem *#
<check-box-list
asp-title="Ice Cream Flavors"
asp-items="Model.IceCreamFlavors"
asp-model-name="IceCreamFlavors"
asp-form-id="my-form-id"
asp-check-all-label="All Flavors"
>
</check-box-list>
Botta boom, botta bing.
I just tried this and it worked:
<input asp-for="filter.type[i].IsEnabled"/>
without the checkbox, and then corresponding boolean value in model with hidden id and name.

Multiple ajax requests or one shot?

I encounter some design problems.
I have a page with a JQuery Calendar (full-calendar) and I need to retrieve two IDs depending on the current month.
Which is the best solution ?
Retrieve the IDs using an Ajax Request each time the calendar is re-rendered (the month changed)
Loading all the Ids (I use Asp.Net Mvc) once and then filtering.
I tried to use the first solution but when the user switch the month too fast (January to February per example), it affects January IDs to February because the user switched too fast (before the first requests actually finished).
Hope I'm clear.
Thank you in advance.
The First Method is prefereable. What you can do is add a time disable ,for me a loader is of best usage in this type of situations
Css :
body.loading {
overflow: hidden;
}
body.loading .modal1 {
display: block;
}
.modal1 {
display: none;
position: fixed;
z-index: 1000;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba( 255, 255, 255, .8 )
url('Loaderurl')
50% 50%
no-repeat;
}
View -
add this at bottom
<div class="modal1"></div>
Script-
$body = $("body");
$(document).on({
ajaxStart: function () {
$body.addClass("loading");
},
ajaxStop: function (e) {
$body.removeClass("loading");
}
});
Thanks for the help.
What I chose to do is to initialize an array where I put all the needToCancel ajax requests and created a cancelAjaxRequests method that I call each time I change the month.
var lastMonthAjaxRequests = [];
lastMonthAjaxRequests.push(... my ajax requests...)
function abortAjaxRequests(ajaxRequests) {
$.each(ajaxRequests,
function() {
this.abort();
});
}
Then each time my calendar is re-rendered :
abortAjaxRequests(lastMonthAjaxRequests);
lastMonthAjaxRequests = [];

How can I get text in an HTML tr (table row) to center?

I'm building some HTML in a StringBuilder like so:
builder.Append("<tr align='center' valign='top' class=\"skyBlueBackground textAlignCenter\">");
List<String> columnHeadings = GetColumnHeadings(monthCount, _begindate);
foreach (String s in columnHeadings)
{
if (s.Equals("Grand Total"))
{
builder.Append("<td align='left' valign='top' class=\"forestGreenBackground whiteText\"><b>");
}
else
{
builder.Append("<td align='left' valign='top'><b>");
}
builder.Append(s);
builder.Append("</b></td>");
}
builder.Append("</tr>");
Although I've got a class for centering text:
builder.Append("</style>");
. . .
builder.Append(".textAlignCenter { text-align: center; }");
builder.Append("</style>");
...the text is aligned left; it works other than that (skyblue background), it just stays magnetized to the left:
What must I do to get the text to center?
You should either set the textAlignCenter on the TD, not the TR or change the CSS definition to:
builder.Append(".textAlignCenter td { text-align: center; }");
And you should remove the explicit "align='left'" from your TD because that will still overrule the CSS.
If you are asking for how to vertically align the text, you could use the vertical-align CSS property. See here for more info.
You could also use the valign attribute, but it is deprecated in HTML5 and it is not a recommended approach.
Your problem is simply, you have created correctly the css class property .textAlignCenter, but your attribute align="left" on the <td> has style priority.
I think you can do two solutions:
Put the class .textAlignCenter on the td you want to align
center.
Remove the align="center" of the td and add a css like
this:
tr td {text-align:left}
tr td.textAlignCenter {text-align:center}
With this last solution you overwrite the last style.

Is it possible to run JavaScript within a webBrowser Control without accessing a specific page?

I am building a web page live as output for my application. This means that I'm editing the document text directly, instead of pointing the control to a file. I have the following code:
<html>
<head>
<style type = "text/css">
.circle {
position:relative;
moz-border-radius: 10px;
-webkit-border-radius: 10px;
-khtml-border-radius: 10px;
border-radius: 10px;
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #000;
height: 10px;
width: 10px;
background-color:#33FF00;
}
</style>
<script type="text/javascript">
var step = 0;
var color= '#0000FF';
function timer()
{
var t=setTimeout("switchColor()",125);
}
function switchColor()
{
if (step == 0) {color='#33FF00';}
if (step == 1) {color='#33FF00';}
if (step == 2) {color='#22AA55';}
if (step == 3) {color='#1155AA';}
if (step == 4) {color='#0000FF';}
if (step == 5) {color='#0000FF';}
if (step == 6) {color='#1155AA';}
if (step == 7) {color='#22AA55';}
step = step+1;
if (step > 7) { step = 0;}
var elements = document.getElementsByClassName('circle')
for (var i = 0;i <elements.length;i++)
{
elements[i].style.backgroundColor=color;
}
timer()
}
</script>
</head>
<body onload="timer()" >
<div id="test" class="circle1"></div>
<div class="circle"></div><div class="circle"></div>
<br>
<br>
</body>
</html>
That code is then set as the documentText of a webBrowser control by using a stringBuilder, adding each line with the StringBuilder.AppendLine() function, and then converting the entire stringBuilder to a string.
I get the error that the getElementsByClassName function is not supported, and nothing happens. The html runs perfectly on its own.
The WebBrowser Control can run javascript live, but it has the same limitations as Internet Explorer. Any commands used within the control need to be able to run in Internet Explorer on the associated machine.
You´ll need to use getElementsByTagName('*'), iterate over the list and verify if each item has the desired className.
As an answer for you, I propose that you use jQuery. It can find elements that have a certain class and works great in IE. Specifically look at the class selector.
www.jquery.com
http://api.jquery.com/class-selector/

Categories

Resources