How can I set both default decimal and thousands separator for formatting number in asp.net mvc regardless of culture?
You could create a DisplayTemplate that would handle how numbers like this are displayed in your views:
/Views/Shared/DisplayTemplates/float.cshmtl:
#model float
#string.Format("{0:N2}", Model);
and then you can call it like this from your views, if Amount was of type float:
#Html.DisplayFor(m => m.Amount)
To control the thousands separator you'll have to apply your changes to the NumberFormat for the current culture.
If you want this to happen regardless of the current culture you can simply clone the current culture, apply your modified NumberFormat and set it as the current one.
In an MVC app you would typically do this during Application_BeginRequest
protected void Application_BeginRequest(object sender, EventArgs e)
{
newCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
newCulture.NumberFormat.NumberGroupSeparator = "~";
System.Threading.Thread.CurrentThread.CurrentCulture = newCulture;
System.Threading.Thread.CurrentThread.CurrentUICulture = newCulture;
}
Now you can use the 'normal' formatting options of ToString() to further control the formatting according to your needs:
var a = 3000.5;
var s = a.ToString('N:2') // 3~000.50
s = a.ToString('N:4') // 3~000.5000
You need to specify a custom number format in order to achieve what you are looking for. Here is the MSDN on creating custom string formatting functions.
If you really need a custom thousands separator, create your own NumberFormatInfo variable assigning the values that you want to the thousands separator (and the decimal if so needed). Then apply the custom format to your number.
var numberFormatter = new CultureInfo( "en-US", false ).NumberFormat;
numberFormat.NumberDecimalSeparator = ";";
numberFormat.NumberGroupSeparator = "-";
var myNumber = 1234567.89;
var myFormattedNumber = myNumber.ToString("#,###.##", numberFormatter);
//myFormattedNumber -> 1-234-567;89
Some information on the NumberFormat class from the MSDN
variable.ToString("n2") - This worked for me in ASP.Net MVC Razor.
string.Format("{0:N2}", yourLovelyNumber);
I will post the code that finally worked for me. On controller, on OnActionExecuting function:
ViewBag.CurrentNumberFormat = new System.Globalization.CultureInfo("en-US", false).NumberFormat;
ViewBag.CurrentNumberFormat.NumberDecimalDigits = 2;
ViewBag.CurrentNumberFormat.NumberDecimalSeparator = "~";
ViewBag.CurrentNumberFormat.NumberGroupSeparator = " ";
and in View:
#((1234567.435).ToString("#,###.##", ViewBag.CurrentNumberFormat))
I had the same issue and can recommend autoNumeric plugin https://github.com/autoNumeric/autoNumeric
Include plugin:
<script src="~/Scripts/autoNumeric/autoNumeric.min.js" type="text/javascript"></script>
Html:
<input type="text" id="DEMO" data-a-sign="" data-a-dec="," data-a-sep="." class="form-control">
Script:
<script>
jQuery(function($) {
$('#DEMO').autoNumeric('init');
});
</script>
You can type only number, if you type 100000,99 you will see 100.000,99.
Related
I have an input text field, and I want to be able to restore the initial value after the user edits the text.
So, I would say to add a data-{something} attribute, for instance data-init, that will hold the initial value, so it can be restored later.
Result should look like:
<input type="text" val="Some value..." data-init="Some value..." />
Now, I know I can achieve this by using:
#Html.TextBoxFor(m => m.InputText , new { data_init = Model.InputText })
But it's awful, and I have a lot of input fields with this behavior.
Also, I can't create a custom HtmlHelper because I have many input types with this behavior, it will be quite messy if I go this way...
So, what I think should be the practical solution is to use Data Annotations.
public class ExampleVM
{
[HoldInitialValue]
public string InputText { get; set; }
}
The [HoldInitialValue] attribute will be responsible to add the data-init="{value}" to the input tag. The {value} will be taken from the property's value, with also an option to override it.
So, how do I implement this behavior?
Thanks for the helpers.
Even if you were to create a custom attribute, which would need to implement MetadataAware in order to add the value to the AdditionalValues property of ModelMetadata, you still then need to create your own extension methods to read that value and add it to the htmlAttributes.
For an example of how to implement it, refer CustomAttribute reflects html attribute MVC5.
However, that is unnecessary since HTML inputs already store the initial value. For a <input> (other than a checkbox) or <textarea> its defaultValue. For a <input type="checkbox" /> its defaultChecked and for <select> its defaultSelected.
So in the case of your #Html.TextBoxFor(m => m.InputText), your could use for example
using javascript
var element = document.getElementById ("InputText");
var initialValue = elem.defaultValue;
// reset to initial value
element.value = initialValue;
or using jQuery
var element = $('#InputText');
var initialValue = element.prop('defaultValue');
// reset to initial value
element.val(initialValue);
try this one , using htmlAttributes as IDictionary
#Html.TextBoxFor(m => m.InputText , new Dictionary<string,object>()
{
{ "data-init", Model.InputText}
})
I am using Kendo Grid (version 2014.1.318) with inline editing on "de-DE" culture. So the numbers should use a comma(,) as the decimal separator, eg: 79,5.
The Numeric Text Box in the grid is displaying the expected format when in "Edit" mode. No problem here. But when I click on "Update" button, it is sending "79.5" instead of "79,5" back to my server. My server is configured with the "de-DE" culture and the ModelBinder couldn't process numbers in that format and as a result, assigned ZERO to my variable.
Is this a known bug or am I missing something? Everything is fine when i use "en-US" culture or any culture that uses period(.) as its decimal separator.
Did you include the kendo.culture.de-DE.min.js file:
Did you change the kendo culture:
kendo.culture("de-DE");
At last you can also try to change the culture in the numeric text box:
#Html.Kendo().NumericTextBox().Culture("de-DE")
We are having the same problem for a year now. It seems it's on low priority for Telerik to solve this or we missed the solution.
This is how we solved it:
Pass this function to the data function of grid create and update like here:
.Update(update => update.Action("Update", "Gradings").Type(HttpVerbs.Put).Data("convertDecimals")))
function convertDecimals(data) {
for (var property in data) {
var value = data[property];
if (typeof value === "number") {
// if the number is integer
if (value % 1 == 0) {
data[property] = value.toString();
}
else {
data[property] = kendo.toString(value, "n");
}
}
}
}
and this on edit:
.Events(events => events.Edit("replaceDecimalSign"))
function replaceDecimalSign(data) {
var value = $(data).val();
var converted = value.toString().replace('.', ',');
$(data).val(converted);
}
Also you need the correct culture settings like alreay answered by MohQut.
kendo.culture("de-DE");
I have an MVC Kendo Timepicker for that I am using. It works fine except that I can't format the time to Military time. After I add the formatting for Military time, once I select the time the validation doesn't pass and it tells me it must be a date. Is there a way to format the TimePickerFor to allow military time?
#using Kendo.Mvc.UI
#model DateTime?
#(Html.Kendo().TimePickerFor(m=>m)
.Value(#Model)
.Min("05:00")
.Max("00:00")
.Format("{0:HHmm}")
)
Update: This doesn't work with format being changed to .Format("HHmm")
Ok, so thanks to the Kendo people, I found the answer. The script may need some work depending on the situation. My TimePickerFor is in an Editor Template which sits in a grid with other timepickers and numeric text boxes. Only thing with this way of working is that once the script is fired, the numeric boxes used this script also to validate (hence the return $.isNumeric(input.val()) line. Hope this helps someone else out.
TimePickerFor Control:
#using Kendo.Mvc.UI
#model DateTime?
#(Html.Kendo().TimePickerFor(m=>m)
.Value(#Model)
.Format("HHmm")
.HtmlAttributes(new{data_format="HHmm"})
.ParseFormats(new[]{"HHmm"})
)
<script>
var originDate = kendo.ui.validator.rules.mvcdate;
kendo.ui.validator.rules.mvcdate = function(input) {
var format = input.attr("data-format");
if (input.val() == "") {
return kendo.parseDate("0000", format);
}
if (format) {
return kendo.parseDate(input.val(), format);
} else {
return $.isNumeric(input.val());
}
};
</script>
I think you have to remove the curly braces and make sure that is a valid format type. I also don't think the 0 is necessary.
Here's some formating documentation
http://docs.telerik.com/kendo-ui/getting-started/framework/globalization/dateformatting
#(Html.Kendo().TimePickerFor(m=>m)
.Value(#Model)
.Min("05:00")
.Max("00:00")
.Format("yyyy/MM/dd hh:mm tt")
)
Edit:
Is your max and min values correct? I don't see how that is logically correct.
I have converted my MVC3 application to MVC5, I had to change all views to razor. Having a challenge with a select list:
In ASPX view that works I am using the following:
<select id="Profession" name="Profession" style="width: 235px; background-color: #FFFFCC;">
<% List<string> allProfessions = ViewBag.AllProfessions;
string selectedProfession;
if (Model != null && !String.IsNullOrEmpty(Model.Profession))
selectedProfession = Model.Profession;
else
selectedProfession = allProfessions[0];
foreach (var aProfession in allProfessions)
{
string selectedTextMark = aProfession == selectedProfession ? " selected=\"selected\"" : String.Empty;
Response.Write(string.Format("<option value=\"{0}\" {1}>{2}</option>", aProfession, selectedTextMark, aProfession));
}%>
</select>
In Razor I am using:
<select id="Profession" name="Profession" style="width: 235px; background-color: #FFFFCC;">
#{List<string> allProfessions = ViewBag.AllProfessions;
string selectedProfession;}
#{if (Model != null && !String.IsNullOrEmpty(Model.Profession))
{selectedProfession = Model.Profession;}
else {selectedProfession = allProfessions[0];}
}
#foreach (var aProfession in allProfessions)
{
string selectedTextMark = aProfession == selectedProfession ?
"selected=\"selected\"" : String.Empty;
Response.Write(string.Format("<option value=\"{0}\" {1}>{2}</option>",
aProfession, selectedTextMark, aProfession));
}
</select>
The list shows up at the top of the page, I can't figure out where is the problem. Would appreciate your assistance.
Don't create your dropdown manually like that. Just use:
#Html.DropDownListFor(m => m.Profession, ViewBag.AllProfessions, new { style = "..." })
UPDATE
I tried your solution but got this error: Extension method cannot by dynamically dispatched
And, that's why I despise ViewBag. I apologize, as my answer was a little generic. Html.DropDownList requires the list of options parameter to be an IEnumerable<SelectListItem>. Since ViewBag is a dynamic, the types of its members cannot be ascertained, so you must cast explicitly:
(IEnumerable<SelectListItem>)ViewBag.AllProfessions
However, your AllProfessions is a simple array, so that cast won't work when the value gets inserted at run-time, but that can be easily fixed by casting it to a List<string> and then converting the items with a Select:
((List<string>)ViewBag.AllProfessions).Select(m => new SelectListItem { Value = m, Text = m })
There again, you see why dynamics are not that great, as that syntax is rather awful. The way you should be handling this type of stuff is to use your model or, preferably, view model to do what it should do: hold domain logic. Add a property to hold your list of profession choices:
public IEnumerable<SelectListItem> ProfessionChoices { get; set; }
And then, in your controller action, populate this list before rendering the view:
var model = new YourViewModel();
...
model.ProfessionChoices = repository.GetAllProfessions().Select(m => new SelectListItem { Value = m.Name, Text = m.Name });
return View(model);
repository.GetAllProfessions() is shorthand for whatever you're using as the source of your list of professions, and the Name property is shorthand for how you get at the text value of the profession: you'll need to change that appropriately to match your scenario.
Then in your view, you just need to do:
#Html.DropDownListFor(m => m.Profession, Model.ProfessionChoices)
Given that you don't have this infrastructure already set up, it may seem like a lot to do just for a drop down list, and that's a reasonable thing to think. However, working in this way will keep your view lean, make maintenance tons easier, and best of all, keep everything strongly-typed so that if there's an issue, you find out at compile-time instead of run-time.
I believe it's happening because of the Response.Write. Try this:
#Html.Raw(string.Format("<option value=\"{0}\" {1}>{2}</option>", aProfession,
selectedTextMark, aProfession))
I am developing a MVC app. I have some amount fields. by default it showing numbers without comma separation. for e.g. if I have amount 500000000 then I want to display it like 50,00,00,000 I want to show in Indian currency format,in indian format first comma comes after 3 digits then for every 2 digits comma appears.
How to do this ?
I have tried this , but giving an error...
#{
System.Globalization.CultureInfo Indian = new System.Globalization.CultureInfo("hi-IN");
}
#(String.Format(Indian, "{0:N}", modelItem => item.SanctionedAmount))
}
Solved, Thanks to Darin Dimitrov, Answer Is :
#{
var indianCulture = new System.Globalization.CultureInfo("hi-IN");
#string.Format(indianCulture, "{0:N}", item.SanctionedAmount)
}
You seem to have passed some lambda expression to the string.Format function (modelItem => item.SanctionedAmount), but this function doesn't take any delegates.
Try like this:
#{
var indianCulture = new System.Globalization.CultureInfo("hi-IN");
#string.Format(indianCulture, "{0:N}", item.SanctionedAmount)
}
In the same context the following also works if you put in Index.cshtml
<td>#item.Total_Payments.ToString("N")</td>