3

サーバーとクライアントの両方の検証があるフォームにASP.NETMVC3を使用しています。入力の上にバルーンとしてエラーメッセージを表示しています。エラーが表示されるため、一度に1つのエラーのみを表示する必要があります。そうしないと、バルーンがエラーになっている可能性のある他のフィールドを覆い隠す傾向があります。

最初のエラーメッセージのみを表示するように検証動作をカスタマイズするにはどうすればよいですか?

編集:フォームにはサーバーとクライアントの両方の検証があり、フォーム全体(フィールドごとではなく)の最初のエラーメッセージのみを表示したいことに注意してください。

4

4 に答える 4

2

誰かがそれを必要とする場合に備えて、私が思いついた解決策は、ページの下部に次のスクリプトを追加することです。これは、既存のjavascript検証にフックして、フォームの最初のエラーを除くすべてを動的に非表示にします。

<script>
    $(function() {
        var form = $('form')[0];
        var settings = $.data(form, 'validator').settings;
        var errorPlacementFunction = settings.errorPlacement;
        var successFunction = settings.success;

        settings.errorPlacement = function(error, inputElement) {
            errorPlacementFunction(error, inputElement);
            showOneError();
        }
        settings.success = function (error) {
            successFunction(error);
            showOneError();
        }
        function showOneError() {
            var $errors = $(form).find(".field-validation-error");
            $errors.slice(1).hide();
            $errors.filter(":first:not(:visible)").show();
        }
    });
</script>
于 2012-05-31T16:37:24.740 に答える
0

最初のエラーのみを表示するカスタム検証サマリーを作成できます。これは、HtmlHelperクラスの拡張機能を作成するか、独自のHtmlHelperを作成することによって実行できます。前者の方が簡単です。

public static class HtmlHelperExtensions
{
    static string SingleMessageValidationSummary(this HtmlHelper helper, string validationMessage="") 
    {
        string retVal = "";
        if (helper.ViewData.ModelState.IsValid)
            return "";
        retVal += @"<div class=""notification-warnings""><span>";
        if (!String.IsNullOrEmpty(validationMessage))
            retVal += validationMessage;
        retVal += "</span>";
        retVal += @"<div class=""text"">";
        foreach (var key in helper.ViewData.ModelState.Keys) 
        {
            foreach(var err in helper.ViewData.ModelState[key].Errors)
            retVal += "<p>" + err.ErrorMessage + "</p>";
            break;
        }
        retVal += "</div></div>";
        return retVal.ToString();
    }
}

これはValidationSummaryの場合ですが、についても同じことができますValidationMessageFor

参照:カスタムValidationSummaryテンプレートAsp.net MVC 3

編集:クライアント側...

jquery.validate.unobstrusive.jsを更新します。特に、onErrorそれが言うところの機能error.removeClass("input-validation-error").appendTo(container);

テストされていませんが、その行を次のように変更します。error.removeClass("input-validation-error").eq(0).appendTo(container);

于 2012-05-29T20:04:06.930 に答える
0

これをコントローラーのアクションに当てはめることができます

var goodErrors = ModelState.GroupBy(MS => MS.Key).Select(ms => ms.First()).ToDictionary(ms => ms.Key, ms => ms.Value);
ModelState.Clear();

foreach (var item in goodErrors)
{
    ModelState.Add(item.Key, item.Value);
}

各プロパティエラーを1つだけ選択し、すべてのエラーをクリアしてから、個々のエラーを追加し直しています。

これは完全にテストされていませんが、機能するはずです。

于 2012-05-29T19:54:28.277 に答える
0

html helper extension1つのメッセージのみをレンダリングするを作成します。

public static MvcHtmlString ValidationError(this HtmlHelper helper)
{
  var result = new StringBuilder();
  var tag = new TagBuilder("div");
  tag.AddCssClass("validation-summary-errors");

  var firstError = helper.ViewData.ModelState.SelectMany(k => k.Value.Errors).FirstOrDefault();

  if (firstError != null)
  {
    tag.InnerHtml = firstError.ErrorMessage;
  }

  result.Append(tag.ToString());
  return MvcHtmlString.Create(result.ToString());
}

jquery.validate.unobtrusive.js OnErrors以下のように関数を更新します。

function onErrors(form, validator) {  // 'this' is the form element
   // newly added condition 
   if ($(form.currentTarget).hasClass("one-error")) {
      var container = $(this).find(".validation-summary-errors");
      var firstError = validator.errorList[0];

      $(container).html(firstError.message);
    }
    else {
      var container = $(this).find("[data-valmsg-summary=true]"),
            list = container.find("ul");

      if (list && list.length && validator.errorList.length) {
        list.empty();
        container.addClass("validation-summary-errors").removeClass("validation-summary-valid");

        $.each(validator.errorList, function () {
          $("<li />").html(this.message).appendTo(list);
        });
      }
    }
  }

基本的にOnError、フォームに名前付きのcssクラスが含まれているかどうかを確認する条件をに追加しました。含まれているone-error場合は単一のエラーを表示し、そうでない場合はすべてを表示します。

于 2012-05-31T05:34:46.977 に答える