6

property:

public decimal Cost { get; set; }

html helper:

<%: Html.TextBoxFor(m => m.Cost)%>

Question: when I am setting the Cost property, how do I format it? for example show a precision of two decimal points?

Neil Knight
  • 47,437
  • 25
  • 129
  • 188
VoodooChild
  • 9,776
  • 8
  • 66
  • 99

6 Answers6

14

I've tweaked Jamiec's answer above a little to (a) make it compile and (b) use the same underlying methods as the framework does:

public static MvcHtmlString DecimalBoxFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, decimal?>> expression, string format, object htmlAttributes = null)
{
    var name = ExpressionHelper.GetExpressionText(expression);

    decimal? dec = expression.Compile().Invoke(html.ViewData.Model);

    // Here you can format value as you wish
    var value = dec.HasValue ? (!string.IsNullOrEmpty(format) ? dec.Value.ToString(format) : dec.Value.ToString())
                : "";

    return html.TextBox(name, value, htmlAttributes);
}
Gaz
  • 4,064
  • 3
  • 32
  • 34
11

I recommend DisplayFor/EditorFor template helper.

// model class
public class CostModel {
  [DisplayFormat(DataFormatString = "{0:0.00}")]
  public decimal Cost {get;set;}
}

// action method
public ActionResult Cost(){
  return View(new CostModel{ Cost=12.3456})
}

// Cost view cshtml
@model CostModel

<div>@Html.DisplayFor(m=>m.Cost)</div>
<div>@Html.EditorFor(m=>m.Cost)</div>

// rendering html
<div>12.34</div>
<div><input class="text-box single-line" id="Cost" name="Cost" type="text" value="12.34" /></div>

Hope this help.

takepara
  • 10,413
  • 3
  • 34
  • 31
10

You could define your own extension method, something like:

public static MvcHtmlString DecimalBoxFor<TEntity>(
            this HtmlHelper helper,
            TEntity model,
            Expression<Func<TEntity, Decimal?>> property,
            string formatString)
        {
            decimal? dec = property.Compile().Invoke(model);

            // Here you can format value as you wish
            var value = !string.IsNullOrEmpty(formatString) ? 
                              dec.Value.ToString(formatString) 
                            : dec.Value.ToString();
            var name = ExpressionParseHelper.GetPropertyPath(property);

            return helper.TextBox(name, value);
        }

And then usage would be:

<%Html.DecimalBoxFor(Model,m => m.Cost,"0.00")%>
SteveC
  • 15,808
  • 23
  • 102
  • 173
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • 1
    Thanks. This looks more work than I was hoping for, so I won't be going with this at this moment. I will keep it for future references. On a related note, is this what you have to do when your types are not simple strings, especially if they are numeric? You would think that there has to be a simpler solution, no? – VoodooChild Jan 06 '11 at 17:48
  • 3
    when we can simply `decimal.ToString("N2")` to format a decimal to two places 12 lines a code *is a bit much* in comparison. The fact is that the built-in HTML helpers/extensions should have an overload for formatting the results. – David Murdoch Mar 14 '11 at 23:47
  • 1
    oh, and `htmlAttributes` isn't a parameter but is referenced within the method. – David Murdoch Mar 14 '11 at 23:52
3

The solution to the described problem is quite simple: you just have to apply the following attribute to your addressed model class property:

[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:0.00}")]
public decimal Cost { get; set; }

Where DataFormatString describes your desired display format and the ApplyFormatInEditMode flag indicates that you also want to apply this formatting in editable mode, too (and not only in read-only mode, which is the case if you omit this).

(See also DisplayFormatAttribute Class)

Gustin
  • 918
  • 7
  • 12
0

I dont think there is a way to do it using the HTML helper, however you could send the value for the textbox pre-formatted with the 2 decimal precision.

diagonalbatman
  • 17,340
  • 3
  • 31
  • 31
0

If using the For method is not a must, you can simply do like this.

<%: Html.TextBox("Cost", Model.Cost.ToString("N2")) %>
newcoder
  • 302
  • 3
  • 15