Is there anyway to do conditional formatting with Webgrid in ASP.NET MVC 3?
I know I can say:
... grid.Column("PropertyName", "Header Name", style: "bold") ...
and it will render HTML that for the TD that says: class="bold".
What I want, is to render some TDs in one style and other TDs in another style. Like:
... grid.Column("PropertyName", "Header Name", style: (item) => (item.Property > 100) ? "bold" : "normal")) ....
but this causes the error "Best overloaded method match ... has some invalid arguments."
Any idea if this is possible?
Thanks
.Jim Biddison
I know I'm kind of late with the answer, but if someone is still looking for that kind of conditional formating / column value binding for WebGrid here's somehting that works :
#grid.GetHtml(
columns: grid.Columns(
grid.Column(format: (item) => (item.someproperty !=null) ?
Html.Raw("I've got value") :
Html.Raw("I don't :("))
)
)
You can do this with some JQuery:
<script type='text/javascript'>
$(document).ready(function () {
jQuery.each($('tbody tr td'), function () {
if (this.textContent == "some value") {
$(this).addClass("some class");
}
});
});
</script>
Of course, you'll have to modify the logic inside the each loop...
Hope that helps.
I don't think the style property accepts functions. You can use jQuery or here is a hack:
Hack
For googler, an improved version of the Torm answer:
#grid.GetHtml(
columns: new[]
{
grid.Column(format:item => Html.Raw("<span" + (item.Property > 100 ? " style='bold'" : "") + ">" + item.Property + "</span>")),
}
)
Related
Using the example from Kendo's ComboBox: (ASP.NET MVC | template.cshtml)
#(Html.Kendo().ComboBox()
.Name("customers")
.DataTextField("ContactName")
.DataValueField("CustomerID")
.HtmlAttributes(new { style = "width: 400px" })
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetCustomers", "Home");
});
})
.Filter("startswith")
.Height(300)
.Template("<img src=\"" + Url.Content("~/Content/web/Customers/") + "${data.CustomerID}.jpg\" alt=\"${data.CustomerID}\" />" +
"<dl>" +
"<dt>Contact:</dt><dd>${ data.ContactName }</dd>" +
"<dt>Company:</dt><dd>${ data.CompanyName }</dd>" +
"</dl>")
)
Inside the Template if you want to use a value that is a DateTime, for example ${ data.StartDate } you would end up with something like this: 2012-06-13T00:00:00
What would the syntax be to format that to a readable Date inside that Template?
The quick and dirty solution would be to create a new property that outputs your date as a string.
The more correct solution would be to feed the output of the property to a javascript date formatting function. You could use something like date.js.
Add this code:
"<dt>StartDate:</dt><dd>" + Date.parse('${ data.StartDate}').toString("M/d/yyyy") + "</dd>" +
The best solution to your date formatting would be to create a DisplayTemplate at Views/Shared/DisplayTemplates/DateTime.cshtml
#model DateTime
#String.Format("{0:dd/MM/yyyy}", Model))
that would change it universally
source
in my mvc application i have a checkbox. but dont know why its value is always true. pls help
my view page
<div id="maindiv">
<%: Html.CheckBoxFor(m => m.status)%>
<%: Html.LabelFor(m => m.status)%>
</div>
and the script is here how i am getting the value TRUE always
<script type="text/javascript">
$('#status').change(function () {
alert(" active " + $('#status').val());
});
</script>
use instead:
var status = ( $("#status").attr("checked") ? 'checked' : 'unchecked' );
alert(" active " + status);
Explanation:
you were reading the value of the checkbox which is always true, you need to check whether its checked attribute is checked or unchecked.
I used the ternary operator to check check whether it's checked or not
You could have also used $("#status").is(":checked") but it is slower.
$('#status').change(function () {
alert(" active " + this.checked);
});
I recommend this answer by Jab because it works.
var myValue = $("#status").is(":checked");
If checked, myValue = true, else myValue = false.
I would like to change the background color of the first row in a WebHelper WebGrid for MVC without the use of JQuery.
Any Thoughts?
#model IEnumerable<MyViewModel>
#{
var indexedModel = Model.Select((item, index) => new { Element = item, Index = index });
var grid = new WebGrid(indexedModel);
}
#grid.GetHtml(
columns: grid.Columns(
grid.Column(
columnName: "item.MyProperty",
header: "Myproperty",
format:
#<text>
<div#Html.Raw(item.Index == 0 ? " class=\"firstRow\"" : "")>
#item.Element.MyProperty
</div>
</text>
)
)
)
and in your CSS:
.firstRow {
background-color: Red;
}
One suggestion could be in each columns's format parameter, use an if-else situation based on a distinct variable that will wrap the data in a span with a css. A bit cumbersome but should work.
For this reason some JQuery would potentially be easier.
Q: How to set width for #Html.DropDownList (and not in css)?
#Html.DropDownList("ListId", String.Empty, new {style="width: 250px;"}) #* no go!*#
The second argument of the DropDownList helper must be an IEnumerable<SelectListItem>. You are passing a string (an empty one to be more precise). So in order to use this helper you will have to respect its signature:
#Html.DropDownList(
"ListId",
Enumerable.Empty<SelectListItem>(),
new { style = "width: 250px;" }
)
Obviously generating an empty dropdown list is of little use. You probably have a view model (you should by the way) that you want to use to bind to:
#Html.DropDownList(
"ListId",
Model.MyList,
new { style = "width: 250px;" }
)
and of course because you have a view model you should prefer to use the DropDownListFor helper:
#Html.DropDownListFor(
x => x.ListId,
Model.MyList,
new { style = "width: 250px;" }
)
and finally to avoid cluttering your HTML with styles you should use an external CSS:
#Html.DropDownListFor(
x => x.ListId,
Model.MyList,
new { #class = "mycombo" }
)
where in your external CSS you would define the .mycombo rule:
.mycombo {
width: 250px;
}
Now you have what I consider a proper code.
You should use the View Model approach. However the lazy way out is just to give the 2nd parameter a null.
#Html.DropDownList("ListId", null, new {style="width: 250px;"})
#Html.DropDownListFor(model => model.Test,
new SelectList(new List<YourNamespace.Modelname>(), "Id", "Name"),
null, new { #id = "ddlTest", #style="width: 250px;" })
There is a jquery technique that allows you to set the width without having to deal with the #Html.DropDownList constructor.
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$("#ListId").width(300);
});
</script>
Using jQuery unobtrusive validation within a .NET MVC project and that seems to be working fine. I'm now trying to show a green checkmark when the field validates correctly (client-side and/or remote).
Here's a sample field declaration:
<div class="clearfix">
#Html.LabelFor(model => model.Address1, "Street")
<div class="input">
#Html.TextBoxFor(model => model.Address1, new { #class = "xlarge", #maxlength = "100", #placeholder = "e.g. 123 Main St" })
<span class="help-message">
#Html.ValidationMessageFor(model => model.Address1)
<span class="isaok">Looks great.</span>
</span>
<span class="help-block">Enter the street.</span>
</div>
</div>
What I'd like to do is add a class 'active' to the "span.isaok" which in turn has a checkmark for a background image.
I tried using highlight/unhighlight:
$.validator.setDefaults({
onkeyup: false,
highlight: function (element, errorClass, validClass) {
$(element).addClass(errorClass).removeClass(validClass);
$(element.form).find("label[for=" + element.id + "]").addClass("error");
$(element).parent().find("span.isaok").removeClass("active");
},
unhighlight: function (element, errorClass, validClass) {
$(element).removeClass(errorClass).addClass(validClass);
$(element.form).find("label[for=" + element.id + "]").removeClass("error");
if ($(element).val().length > 0) {
$(element).parent().find("span.isaok").addClass("active");
}
}
});
but that shows a green checkmark for all fields even if they're empty! (hence obviously wrong)
I then tried using the 'success' option but that never seems to be fired.
What am I missing?
Edit: So I found this blog post and was able to tap into the success function i.e.
$(function () {
var settings = $.data($('form')[0], 'validator').settings;
settings.onkeyup = false;
settings.onfocusout = function (element) { $(element).valid(); };
var oldErrorFunction = settings.errorPlacement;
var oldSuccessFunction = settings.success;
settings.errorPlacement = function (error, inputElement) {
inputElement.parent().find("span.isaok").removeClass("active");
oldErrorFunction(error, inputElement);
};
settings.success = function (label) {
var elementId = '#' + label.attr("for");
$(elementId).parent().find("span.isaok").addClass("active");
oldSuccessFunction(label);
};
});
but now if the form isn't valid it shows both the error message and the valid mark...
and the latter disappears as soon as I click anywhere on the page.
This appears to be an issue with the jquery.validate.unobtrusive interfering with the settings added later in $.validator.setDefault. The trick is to load the unobtrusive script after the custom settings. See here and vote to fix it here.
In case any one has a similar problem, I finally got this working by using the un-minified version of jquery.validate.unobtrusive.js and adding my js to the onError and onSuccess methods. Existing code was left as it. Use the re-minified version during deployment.
Thanks.
This is not a direct answer to your question. I am going to offer an alternative approach to this: TwitterBootstrapMVC.
With this library all you'd have to write for each input is:
#Html.Bootstrap().ControlGroup().TextBoxFor(m => m.Address1)
And that's it. You will have label, input, and validation message - all taken care of, without javascript. It generates proper html mark up for you. You just need to make sure that you have proper standard css for classes like .field-validation-error, .field-validation-valid...