美国货币的客户端验证

Client-side validation of US currency

我有一个 ASP.Net MVC 5 网络应用程序,我需要接受美国货币的用户输入。一些有效的输入可能是:

100
0.21
$ 1,234
,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。帮助分配这类东西。至于您的问题是能够使用美元符号,您将无法将此值作为十进制格式存储在数据库中,只能作为字符串存储。

您可以做一些事情,使用 bootstrap 使用 input-group-addon 在您的文本框前面放置一个美元符号。不确定它是否会正常工作,因为我看到你在文本框上设置了 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>