我有一个ASP.Net MVC 5 Web应用程序,我需要接受美国货币的用户输入。一些有效的输入可能是:
100
$100.21
$ 1,234
$1,234.56
输入无效可能是:
10,12
1o0.21
我的(简化)模型看起来像:
public class Claim {
[DisplayName("$ Amount)]
[DataType(DataType.Currency)]
[Required]
[Range(0.0, 200000.0)]
public decimal? DollarAmount { get; set; }
}
我的cshtml标记看起来像:
@Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-9">
@Html.EditorFor(model => model.DollarAmount, new { htmlAttributes = new { @class = "form-control margin-bottom" } })
@Html.ValidationMessageFor(model => model.DollarAmount, "", new { @class = "text-danger" })
</div>
我使用这个建议this advice来构建一个将用户输入转换为十进制的绑定器,但客户端验证不会让用户输入美元符号或逗号。我需要做什么才能允许用户输入有效的货币值,但是如果她输入了无效值,则会发出警告?我宁愿尽可能多地在客户端进行验证。
你可能想看看https://github.com/globalizejs/globalize#currency-module。帮助分配这种东西。至于您的问题是否能够使用美元符号,您将无法将此值作为十进制格式存储在数据库中,仅作为字符串。
您可以执行一些操作,使用引导程序使用input-group-addon
在您的TextBox前面放置一个美元符号。不确定它是否能正常工作,因为我看到你在文本框上设置了Margin-bottom,告诉我你可能没有使用上面的bootstrap表单标签。
您可能想要查看AutoNumeric jQuery插件,它维护良好,他们基本上“想到了我想要的所有货币”。
// View
@Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-9 input-group">
<span class="input-group-addon">$</span>
@Html.EditorFor(model => model.DollarAmount, new { htmlAttributes = new { @class = "form-control margin-bottom" } })
@Html.ValidationMessageFor(model => model.DollarAmount, "", new { @class = "text-danger" })
</div>
// Class
public class Claim {
[DisplayName("$ Amount)]
[DataType(DataType.Currency)]
// {0:C} Will show as currency {0:N} to show Numbers
[DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = true))]
[Required]
[Range(0.0, 200000.0)]
public decimal? DollarAmount { get; set; }
}
另一种选择是使用javascript隐藏字段,将字段从字符串复制到十进制,并且可以是您提交的字段,如下所示。
// MODEL
public class Claim {
[DisplayName("$ Amount)]
[DataType(DataType.Currency)]
[Required]
[Range(0.0, 200000.0)]
public decimal? DollarAmount { get; set; }
}
// View
@Html.HiddenFor(model => model.DollarAmount, new { @id = "DollarAmount" })
@Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-9 input-group">
<span class="input-group-addon">$</span>
<input id="DollarSave" type="text" name="DollarSave" pattern="^\$?([0-9]{1,3},([0-9]{3},)*[0-9]{3}|[0-9]+)(.[0-9][0-9])?$" title="You must enter in proper currency">
@Html.ValidationMessageFor(model => model.DollarAmount, "", new { @class = "text-danger" })
</div>
<script type="text/javascript">
jQuery(document).ready(function($){
$('#DollarSave').change(function(){
var sourceField = $("#DollarSave").val(); //source field key
$("#DollarAmount").val(sourceField); //destination field key
$("#DollarAmount").change(); //destination field key
});
});
</script>
Pool pro的答案在解决我的问题方面提供了很大的帮助但是我无法获得他的输入标记模式来显示消息。它在JSFiddles中有效,但在我的Asp.Net视图模板中没有。所以,我在javascript中进行了模式验证和消息更新。我也使用了不同的正则表达式。为了完整起见,我在这里发布我的解决方案:
@Html.HiddenFor(model => model.DollarAmount, new { @id = "DollarAmount" })
@Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-9>
<input id="DollarSave" type="text" name="DollarSave" class="form-control text-box single-line">
<p id="BadDollarSave" class="text-danger"></p>
</div>
<script type="text/javascript">
jQuery(document).ready(function($){
$('#DollarSave').on('blur', function () {
validateDollarSave();
});
function validateMoney(inputId) {
var errorMsg = '';
var currency = $('#DollarSave').val();
var good = currency.match(/^(\$|\$ )?[0-9]{1,3}(?:(,[0-9]{3})*|([0-9]{3})*)(?:(\.|\.[0-9]{2}))?$/);
if (!good) {
errorMsg = "$ Amount must be US currency";
} else {
var num = currency.replace(/[, $]/g, "");
$('#DollarAmount').val(num);
}
document.getElementById('BadDollarSave').innerHTML = errorMsg;
};
});
</script>