-->

Format EditorFor() field as Currency during View a

2019-08-08 01:28发布

问题:

I have an EditorFor() on my View for a field [cost]:

<div class="form-group">
        @*@Html.LabelFor(model => model.cost, htmlAttributes: new { @class = "control-label col-md-2" })*@
        <span class="control-label col-md-2">Cost:</span>
        <div class="col-md-10">
            @Html.EditorFor(model => model.cost, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.cost, "", new { @class = "text-danger" })
        </div>
    </div>

What I'd like to do is display this value with a $ whenever it is being viewed (individual record, inside grid, etc.) and have formatting occur while a user is entering a value into a field. For example, when typing 12345 I'd like the value to automatically display as 12,345 when the user is typing.

Is there a simple method to do this?

I'm using MVC5 Code-First with Bootstrap, and in my research I've found several possible options for MVC3/4, but most of them seem cumbersome to implement.


EDIT:

I'm looking for a way to display the value as currency both in my EditorFor() and within a Grid.Mvc (https://gridmvc.codeplex.com) column for the field [cost]:

@try
{
    @Html.Grid(Model).Columns(columns =>
    {
        columns.Add().Encoded(false).Sanitized(false).RenderValueAs(o => @<a href="/INV_Assets/Edit/@o.Id" class="btn btn-primary btn-sm noDecoration"><span class="glyphicon glyphicon-pencil"></span> @*Edit*@</a>).SetWidth(15);
        columns.Add().Encoded(false).Sanitized(false).RenderValueAs(o => @<a href="/INV_Assets/Delete/@o.Id" class="btn btn-danger btn-sm noDecoration"><span class="glyphicon glyphicon-remove-circle"></span> @*Delete*@</a>).SetWidth(15);
        columns.Add().Encoded(false).Sanitized(false).RenderValueAs(o => @<a href="/INV_Assets/Details/@o.Id" class="btn btn-default btn-sm noDecoration"><span class="glyphicon glyphicon-eye-open"></span> @*View*@</a>).SetWidth(15);
        columns.Add(o => o.Status.status_description).Titled("Status").RenderValueAs(o => o.Status.status_description).Sanitized(false).Encoded(false).Sortable(true).Filterable(true).SetWidth(20);
        columns.Add(o => o.Location.location_dept).Titled("Dept").RenderValueAs(o => o.Location.location_dept).SetWidth(20);
        columns.Add(o => o.Location.location_room).Titled("Room").RenderValueAs(o => o.Location.location_room).SetWidth(20);
        columns.Add(o => o.owner).Titled("Owner").RenderValueAs(o => o.owner).SetWidth(20);
        columns.Add(o => o.Type.type_description).Titled("Type").RenderValueAs(o => o.Type.type_description).SetWidth(20);
        columns.Add(o => o.Manufacturer.manufacturer_description).Titled("Manufacturer").RenderValueAs(o => o.Manufacturer.manufacturer_description).SetWidth(20);
        columns.Add(o => o.Model.model_description).Titled("Model").RenderValueAs(o => o.Model.model_description).SetWidth(20);
        columns.Add(o => o.Vendor.vendor_name).Titled("Vendor").RenderValueAs(o => o.Vendor.vendor_name).SetWidth(20);
        columns.Add(o => o.description).Titled("Desc").RenderValueAs(o => o.description).SetWidth(20);
        columns.Add(o => o.asset_tag_number).Titled("Asset Tag #").RenderValueAs(o => o.asset_tag_number).SetWidth(20);
        columns.Add(o => o.serial_number).Titled("Serial #").RenderValueAs(o => o.serial_number).SetWidth(20);
        columns.Add(o => o.ip_address).Titled("IP Addr").RenderValueAs(o => o.ip_address).SetWidth(20);
        columns.Add(o => o.mac_address).Titled("Mac Addr").RenderValueAs(o => o.mac_address).SetWidth(20);
        columns.Add(o => o.po_number).Titled("PO #").RenderValueAs(o => o.po_number).SetWidth(20);
        columns.Add(o => o.invoice_number).Titled("Inv. #").RenderValueAs(o => Convert.ToString(o.invoice_number)).SetWidth(20);
        columns.Add(o => o.cost).Titled("Cost").RenderValueAs(o => "$" + Convert.ToString(o.cost)).SetWidth(20);
        columns.Add(o => o.note).Titled("Note").RenderValueAs(o => o.note).SetWidth(20);
        columns.Add(o => o.acquired_date).Titled("Acq. Date").RenderValueAs(o => Convert.ToString(o.acquired_date)).SetWidth(20);
        columns.Add(o => o.disposed_date).Titled("Disp. Date").RenderValueAs(o => Convert.ToString(o.disposed_date)).SetWidth(20);
        columns.Add(o => o.created_date).Titled("Crtd. Date").RenderValueAs(o => Convert.ToString(o.created_date)).SetWidth(20);
        columns.Add(o => o.created_by).Titled("By").RenderValueAs(o => o.created_by).SetWidth(20);
        columns.Add(o => o.modified_date).Titled("Mod. Date").RenderValueAs(o => Convert.ToString(o.modified_date)).SetWidth(20);
        columns.Add(o => o.modified_by).Titled("By").RenderValueAs(o => o.modified_by).SetWidth(20);
    }).WithPaging(10).Sortable().Filterable().WithMultipleFilters();
}
catch (NullReferenceException ex)
{
    return;
}

I've defined [cost] in my model as decimal, but the grid requires the value to be a string. I think that this Convert.ToString() is keeping the annotations [DataType(DataType.Currency)] and [DisplayFormat(DataFormatString="{0:C}", ApplyFormatInEditMode=true)] on public decimal cost { get; set; } from taking effect?

 [DataType(DataType.Currency)]
 [DisplayFormat(DataFormatString="{0:C}", ApplyFormatInEditMode=true)]
  public decimal cost { get; set; }

Ideally want to display (Ex.) the value 1222345.47 as $1,222,345.47 at all times, letting the user enter the value as a plain decimal and when clicking away from the EditorFor() have the value visually formatted into currency format.

Can anyone offer a way to go about this?


EDIT2:

I got the EditorFor() displaying the value correctly by using the custom format string below:

[DisplayFormat(DataFormatString = "{0:#,###0.00}", ApplyFormatInEditMode=true)]

As mentioned by Chris, I must strip out the "," in order for the model to accept the value as valid -- this I believe I can do when form attempts to post.

Still trying to figure out how to display the value in my MVCGrid in currency format.

回答1:

This is a two-pronged answer. As far as viewing the data goes, you can simply decorate your property with:

[DisplayFormat(DataFormatString = "{0:C}")]
public Decimal cost { get; set; }

Or

[DataType(DataType.Currency)]
public Decimal cost { get; set; }

Will work just as well.

However, for editing the value, things are a bit more complicated. DisplayFormat takes a parameter in addition to DataFormatString called ApplyInEditMode. Setting this to true, will cause the value rendered by Razor to also be in the chosen format. But, before you run off and do that, the problem here is that a posted value of something like "$1,234.56", won't be able to be processed by the modelbinder as a decimal value.

For this and the format-as-you-type functionality you want, you should simply employ JavaScript. There's a metric ton of JavaScript plugins that can format input values. Just Google something like "javascript format input value" and you should get more results than you'd care to. Find one that works for you and use it.



回答2:

I think the editor part of your question has been answered well.

Grid MVC allows you to format a decimal using the .Format() option like this:

columns.Add(model => model.Cost).Titled("Cost PA").Format("£{0:#,###0.00}").SetWidth(10); columns.Add(model => model.CoTermDays).Titled("Days").SetWidth(10);

The result look like this: currency format in grid