How to Handle Model Binding After Using DisplayFormat Attribute











up vote
0
down vote

favorite












I am working on financial software which uses a lot of currency values and percentages. Without putting any thought into usability, if you create a default TextBox and bind it to a decimal 0.00M, it appears to the user as 0.00. It is ambiguous whether they should enter 6% as 6.00 or 0.06. You also run into the problem where .065 displays as 0.06, which makes the value appear incorrect to the user.



To clarify the intent of the numbers, I am using display attributes like this:



[Display(Name = "State Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal StateRate { get; set; }

[Display(Name = "Combined Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CombinedRate { get; set; }

[Display(Name = "County Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CountyRate { get; set; }


Now 6.5% is displayed as 6.50%, which is better from a usability standpoint, but when you post the form to an ASP.Net Core MVC controller, the values do not bind. Simply stripping the percentage sign causes it to bind at 650%. The approach I am taking is to use JQuery to clean up the data before the post takes place:



// deal with percentages:
// 6.5% does not bind, but is displayed to the user.
// 6.5 binds incorrectly (650%)
// .065 is desired format
$(function () {
$('#my-form').on('submit', function (e) {
e.preventDefault(); // avoid default post routine

// change "6.50%" to 6.5
var stateRate = parseFloat($('#StateRate').val().replace('%', ''));
var combinedRate = parseFloat($('#EstCombinedRate').val().replace('%', ''));
var countyRate = parseFloat($('#EstCountyRate').val().replace('%', ''));

// change 6.5 to .065 - leave 0.065 alone.
if (stateRate > 1) {
stateRate = stateRate / 100.0;
}
if (combinedRate > 1) {
combinedRate = combinedRate / 100.0;
}
if (countyRate > 1) {
countyRate = countyRate / 100.0;
}

// put the cleaned up values back into the form fields
$('#StateRate').val(stateRate);
$('#CombinedRate').val(combinedRate);
$('#CountyRate').val(countyRate);

// make ajax request
$.post(
'/MyController/EditTaxRates'
$(this).serialize(),
function (data, status, jqXHR) {
$.notify('Data saved successfully!', { position: "top center" });
}
).fail(function () {
$.notify('Error saving data.', { position: "top center" });
});
});
});


This is working properly for the most part, but I need to implement this a lot of places, and this adds a lot of code to solve a seemingly fundamental and simple issue. Also, it fails for a county tax rate such as 0.5%, which binds as 50% when using this code as written. Are there are any built-in tricks such as attributes or Razor magic that will cause the data to bind properly without using javascript, or is there a best practice that addresses this problem?










share|improve this question
























  • You might want to look at mvc-numericinput as an option
    – Stephen Muecke
    4 hours ago










  • In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.
    – Stephen Muecke
    4 hours ago















up vote
0
down vote

favorite












I am working on financial software which uses a lot of currency values and percentages. Without putting any thought into usability, if you create a default TextBox and bind it to a decimal 0.00M, it appears to the user as 0.00. It is ambiguous whether they should enter 6% as 6.00 or 0.06. You also run into the problem where .065 displays as 0.06, which makes the value appear incorrect to the user.



To clarify the intent of the numbers, I am using display attributes like this:



[Display(Name = "State Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal StateRate { get; set; }

[Display(Name = "Combined Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CombinedRate { get; set; }

[Display(Name = "County Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CountyRate { get; set; }


Now 6.5% is displayed as 6.50%, which is better from a usability standpoint, but when you post the form to an ASP.Net Core MVC controller, the values do not bind. Simply stripping the percentage sign causes it to bind at 650%. The approach I am taking is to use JQuery to clean up the data before the post takes place:



// deal with percentages:
// 6.5% does not bind, but is displayed to the user.
// 6.5 binds incorrectly (650%)
// .065 is desired format
$(function () {
$('#my-form').on('submit', function (e) {
e.preventDefault(); // avoid default post routine

// change "6.50%" to 6.5
var stateRate = parseFloat($('#StateRate').val().replace('%', ''));
var combinedRate = parseFloat($('#EstCombinedRate').val().replace('%', ''));
var countyRate = parseFloat($('#EstCountyRate').val().replace('%', ''));

// change 6.5 to .065 - leave 0.065 alone.
if (stateRate > 1) {
stateRate = stateRate / 100.0;
}
if (combinedRate > 1) {
combinedRate = combinedRate / 100.0;
}
if (countyRate > 1) {
countyRate = countyRate / 100.0;
}

// put the cleaned up values back into the form fields
$('#StateRate').val(stateRate);
$('#CombinedRate').val(combinedRate);
$('#CountyRate').val(countyRate);

// make ajax request
$.post(
'/MyController/EditTaxRates'
$(this).serialize(),
function (data, status, jqXHR) {
$.notify('Data saved successfully!', { position: "top center" });
}
).fail(function () {
$.notify('Error saving data.', { position: "top center" });
});
});
});


This is working properly for the most part, but I need to implement this a lot of places, and this adds a lot of code to solve a seemingly fundamental and simple issue. Also, it fails for a county tax rate such as 0.5%, which binds as 50% when using this code as written. Are there are any built-in tricks such as attributes or Razor magic that will cause the data to bind properly without using javascript, or is there a best practice that addresses this problem?










share|improve this question
























  • You might want to look at mvc-numericinput as an option
    – Stephen Muecke
    4 hours ago










  • In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.
    – Stephen Muecke
    4 hours ago













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am working on financial software which uses a lot of currency values and percentages. Without putting any thought into usability, if you create a default TextBox and bind it to a decimal 0.00M, it appears to the user as 0.00. It is ambiguous whether they should enter 6% as 6.00 or 0.06. You also run into the problem where .065 displays as 0.06, which makes the value appear incorrect to the user.



To clarify the intent of the numbers, I am using display attributes like this:



[Display(Name = "State Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal StateRate { get; set; }

[Display(Name = "Combined Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CombinedRate { get; set; }

[Display(Name = "County Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CountyRate { get; set; }


Now 6.5% is displayed as 6.50%, which is better from a usability standpoint, but when you post the form to an ASP.Net Core MVC controller, the values do not bind. Simply stripping the percentage sign causes it to bind at 650%. The approach I am taking is to use JQuery to clean up the data before the post takes place:



// deal with percentages:
// 6.5% does not bind, but is displayed to the user.
// 6.5 binds incorrectly (650%)
// .065 is desired format
$(function () {
$('#my-form').on('submit', function (e) {
e.preventDefault(); // avoid default post routine

// change "6.50%" to 6.5
var stateRate = parseFloat($('#StateRate').val().replace('%', ''));
var combinedRate = parseFloat($('#EstCombinedRate').val().replace('%', ''));
var countyRate = parseFloat($('#EstCountyRate').val().replace('%', ''));

// change 6.5 to .065 - leave 0.065 alone.
if (stateRate > 1) {
stateRate = stateRate / 100.0;
}
if (combinedRate > 1) {
combinedRate = combinedRate / 100.0;
}
if (countyRate > 1) {
countyRate = countyRate / 100.0;
}

// put the cleaned up values back into the form fields
$('#StateRate').val(stateRate);
$('#CombinedRate').val(combinedRate);
$('#CountyRate').val(countyRate);

// make ajax request
$.post(
'/MyController/EditTaxRates'
$(this).serialize(),
function (data, status, jqXHR) {
$.notify('Data saved successfully!', { position: "top center" });
}
).fail(function () {
$.notify('Error saving data.', { position: "top center" });
});
});
});


This is working properly for the most part, but I need to implement this a lot of places, and this adds a lot of code to solve a seemingly fundamental and simple issue. Also, it fails for a county tax rate such as 0.5%, which binds as 50% when using this code as written. Are there are any built-in tricks such as attributes or Razor magic that will cause the data to bind properly without using javascript, or is there a best practice that addresses this problem?










share|improve this question















I am working on financial software which uses a lot of currency values and percentages. Without putting any thought into usability, if you create a default TextBox and bind it to a decimal 0.00M, it appears to the user as 0.00. It is ambiguous whether they should enter 6% as 6.00 or 0.06. You also run into the problem where .065 displays as 0.06, which makes the value appear incorrect to the user.



To clarify the intent of the numbers, I am using display attributes like this:



[Display(Name = "State Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal StateRate { get; set; }

[Display(Name = "Combined Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CombinedRate { get; set; }

[Display(Name = "County Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CountyRate { get; set; }


Now 6.5% is displayed as 6.50%, which is better from a usability standpoint, but when you post the form to an ASP.Net Core MVC controller, the values do not bind. Simply stripping the percentage sign causes it to bind at 650%. The approach I am taking is to use JQuery to clean up the data before the post takes place:



// deal with percentages:
// 6.5% does not bind, but is displayed to the user.
// 6.5 binds incorrectly (650%)
// .065 is desired format
$(function () {
$('#my-form').on('submit', function (e) {
e.preventDefault(); // avoid default post routine

// change "6.50%" to 6.5
var stateRate = parseFloat($('#StateRate').val().replace('%', ''));
var combinedRate = parseFloat($('#EstCombinedRate').val().replace('%', ''));
var countyRate = parseFloat($('#EstCountyRate').val().replace('%', ''));

// change 6.5 to .065 - leave 0.065 alone.
if (stateRate > 1) {
stateRate = stateRate / 100.0;
}
if (combinedRate > 1) {
combinedRate = combinedRate / 100.0;
}
if (countyRate > 1) {
countyRate = countyRate / 100.0;
}

// put the cleaned up values back into the form fields
$('#StateRate').val(stateRate);
$('#CombinedRate').val(combinedRate);
$('#CountyRate').val(countyRate);

// make ajax request
$.post(
'/MyController/EditTaxRates'
$(this).serialize(),
function (data, status, jqXHR) {
$.notify('Data saved successfully!', { position: "top center" });
}
).fail(function () {
$.notify('Error saving data.', { position: "top center" });
});
});
});


This is working properly for the most part, but I need to implement this a lot of places, and this adds a lot of code to solve a seemingly fundamental and simple issue. Also, it fails for a county tax rate such as 0.5%, which binds as 50% when using this code as written. Are there are any built-in tricks such as attributes or Razor magic that will cause the data to bind properly without using javascript, or is there a best practice that addresses this problem?







jquery asp.net-core-mvc model-binding usability






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 7 hours ago

























asked 7 hours ago









Elemental Pete

2,1021722




2,1021722












  • You might want to look at mvc-numericinput as an option
    – Stephen Muecke
    4 hours ago










  • In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.
    – Stephen Muecke
    4 hours ago


















  • You might want to look at mvc-numericinput as an option
    – Stephen Muecke
    4 hours ago










  • In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.
    – Stephen Muecke
    4 hours ago
















You might want to look at mvc-numericinput as an option
– Stephen Muecke
4 hours ago




You might want to look at mvc-numericinput as an option
– Stephen Muecke
4 hours ago












In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.
– Stephen Muecke
4 hours ago




In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.
– Stephen Muecke
4 hours ago

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53400530%2fhow-to-handle-model-binding-after-using-displayformat-attribute%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53400530%2fhow-to-handle-model-binding-after-using-displayformat-attribute%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Berounka

Sphinx de Gizeh

Different font size/position of beamer's navigation symbols template's content depending on regular/plain...