如何使用jquery来验证动态填充的表单字段?

时间:2018-05-08 19:01:13

标签: javascript jquery asp.net-mvc razor

我有10个问题列表,用于对用户进行评分,如下所示:enter image description here

根据用户占用情况动态获取列表。这就是我获取列表的方式:

@for (int i = 0; i < Model.AppraisalQuestions.ToList().Count; i++)
{
    @Html.HiddenFor(m => m.AppraisalQuestions[i].QuestionId)
    @Html.HiddenFor(m => m.AppraisalQuestions[i].QuestionDescription)
    <p>
        @Html.DisplayFor(m => m.AppraisalQuestions[i].QuestionDescription)
        @Html.ValidationMessageFor(m => m.AppraisalQuestions[i].SelectedAnswer, "", new { @class = "text-danger" })
    </p>
    <div class="row lead evaluation">
        <div id="colorstar" class="starrr ratable"></div>
        <span id="count">0</span> star(s) - <span id="meaning"> </span>
        @foreach (var answer in Model.AppraisalQuestions[i].PossibleAnswers)
        {
            //var inputId = Model.AppraisalQuestions[i].QuestionId + "-" + answer.ID;
            @Html.HiddenFor(m => m.AppraisalQuestions[i].SelectedAnswer, new { id = "SelectedAns", required = "required" })
        }
    </div> 
}

这是模型:

public class AppraisalInputModel
{
    public int AppraisalId { get; set; }

    public AppraisalInputModel()
    {
        AppraisalQuestions = new List<AppraisalQuestionInputModel>();
    }
    public string FullName { get; set; }
    public string JobTitle { get; set; }
    public int StaffId { get; set; }
    public int ScorerId { get; set; }
    public int BranchId { get; set; }
    public string AppraisalTitle { get; set; }

    public IList<AppraisalQuestionInputModel> AppraisalQuestions { get; set; }
}

这是AppraisalQuestionInputModel

 public class AppraisalQuestionInputModel
{
    public int QuestionId { get; set; }
    public string QuestionDescription { get; set; }
    public bool IsGeneral { get; set; }

    [Required]
    [Display(Name = "Score")]
    public int? SelectedAnswer { get; set; }

    public IEnumerable<AnswerVM> PossibleAnswers => new List<AnswerVM>()
    {
        new AnswerVM {ID = 1, Text = "1 - Poor"},
        new AnswerVM {ID = 2, Text = "2 - Below Expectation"},
        new AnswerVM {ID = 3, Text = "3 - Meets Expectation"},
        new AnswerVM {ID = 4, Text = "4 - Good"},
        new AnswerVM {ID = 5, Text = "5 - Excellent"},
    };
}

这是脚本部分代码:

 @section Scripts{
@Scripts.Render("~/bundles/jqueryval")
    <script type="text/javascript">
// Starrr plugin (https://github.com/dobtco/starrr)
        var __slice = [].slice;

        (function($, window) {
            var Starrr;

            Starrr = (function() {
                Starrr.prototype.defaults = {
                    rating: void 0,
                    numStars: 5,
                    change: function(e, value) {}
                };

                function Starrr($el, options) {
                    var i,
                        _,
                        _ref,
                        _this = this;

                    this.options = $.extend({}, this.defaults, options);
                    this.$el = $el;
                    _ref = this.defaults;
                    for (i in _ref) {
                        _ = _ref[i];
                        if (this.$el.data(i) != null) {
                            this.options[i] = this.$el.data(i);
                        }
                    }
                    this.createStars();
                    this.syncRating();
                    this.$el.on('mouseover.starrr', 'span', function(e) {
                        return _this.syncRating(_this.$el.find('span').index(e.currentTarget) + 1);
                    });
                    this.$el.on('mouseout.starrr', function() {
                        return _this.syncRating();
                    });
                    this.$el.on('click.starrr', 'span', function(e) {
                        return _this.setRating(_this.$el.find('span').index(e.currentTarget) + 1);
                    });
                    this.$el.on('starrr:change', this.options.change);
                }

                Starrr.prototype.createStars = function() {
                    var _i, _ref, _results;

                    _results = [];
                    for (_i = 1, _ref = this.options.numStars; 1 <= _ref ? _i <= _ref : _i >= _ref; 1 <= _ref ? _i++ : _i--) {
                        _results.push(this.$el.append("<span class='glyphicon .glyphicon-star-empty'></span>"));
                    }
                    return _results;
                };

                Starrr.prototype.setRating = function(rating) {
                    if (this.options.rating === rating) {
                        rating = void 0;
                    }
                    this.options.rating = rating;
                    this.syncRating();
                    return this.$el.trigger('starrr:change', rating);
                };

                Starrr.prototype.syncRating = function(rating) {
                    var i, _i, _j, _ref;

                    rating || (rating = this.options.rating);
                    if (rating) {
                        for (i = _i = 0, _ref = rating - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
                            this.$el.find('span').eq(i).removeClass('glyphicon-star-empty').addClass('glyphicon-star');
                        }
                    }
                    if (rating && rating < 5) {
                        for (i = _j = rating; rating <= 4 ? _j <= 4 : _j >= 4; i = rating <= 4 ? ++_j : --_j) {
                            this.$el.find('span').eq(i).removeClass('glyphicon-star').addClass('glyphicon-star-empty');
                        }
                    }
                    if (!rating) {
                        return this.$el.find('span').removeClass('glyphicon-star').addClass('glyphicon-star-empty');
                    }
                };

                return Starrr;

            })();
            return $.fn.extend({
                starrr: function() {
                    var args, option;

                    option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
                    return this.each(function() {
                        var data;

                        data = $(this).data('star-rating');
                        if (!data) {
                            $(this).data('star-rating', (data = new Starrr($(this), option)));
                        }
                        if (typeof option === 'string') {
                            return data[option].apply(data, args);
                        }
                    });
                }
            });
        })(window.jQuery, window);

        $(function() {
            return $(".starrr").starrr();
        });

        $(document).ready(function () {
            var starCount;

            var correspondence = ["", "Poor", "Below Expectation", "Above Expectation", "Good", "Excelent"];

            $('.ratable').on('starrr:change', function(e, value) {

                $(this).closest('.evaluation').children('#count').html(value);
                $(this).closest('.evaluation').children('#SelectedAns').val(value);

                starCount = $(this).closest('.evaluation').children('#SelectedAns').val(value);

                if (starCount === null) {
                    swal("", "Please Enter First Name", "error");
                }
                $(this).closest('.evaluation').children('#meaning').html(correspondence[value]);

                var currentval = $(this).closest('.evaluation').children('#count').html();


                var target = $(this).closest('.evaluation').children('.indicators');
                target.css("color", "black");
                target.children('.rateval').val(currentval);
                target.children('#textwr').html(' ');





            });

            $('#hearts-existing').on('starrr:change', function(e, value) {
                $('#count-existing').html(value);
            });
        });



</script>
    <script type="text/javascript">
        $(document).ready(function () {

            $('[data-toggle="tooltip"]').tooltip();
        });


    </script>

}

所有问题都必须回答。我如何验证以确保所有问题都得到解答?

我尝试了form.Validate(),但它无效。

1 个答案:

答案 0 :(得分:2)

您的视图为同一SelectedAnswer生成5个隐藏输入。您只需要一个(只有第一个的值将被DefaultModelBinder约束),您需要在starrr:change事件中设置其值。

但是,默认情况下不会验证隐藏的输入,因此您还需要配置$.validator以进行客户端验证。

首先,修改视图以删除foreach循环并将其替换为单个隐藏输入。另请注意,id属性已替换为类名(重复id属性无效html)

@for (int i = 0; i < Model.AppraisalQuestions.ToList().Count; i++)
{
    @Html.HiddenFor(m => m.AppraisalQuestions[i].QuestionId)
    @Html.HiddenFor(m => m.AppraisalQuestions[i].QuestionDescription)
    <p>
        @Html.DisplayFor(m => m.AppraisalQuestions[i].QuestionDescription)
        @Html.ValidationMessageFor(m => m.AppraisalQuestions[i].SelectedAnswer, "", new { @class = "text-danger" })
    </p>
    <div class="row lead evaluation">
        <div class="starrr ratable"></div> // remove invalid id attribute
        <span class="count">0</span> star(s) - <span class="meaning"> </span> 
        @Html.HiddenFor(m => m.AppraisalQuestions[i].SelectedAnswer, new { @class = "rating" }) 
    </div> 
}

然后设置输入的值,以便在提交表单时将其回发

$('.ratable').on('starrr:change', function(e, value) {
    var container = $(this).closest('.evaluation'); // cache it
    container.children('.count').html(value); // modify
    container.children('.rating').val(value); // set value of input
    container.children('.meaning').html(correspondence[value]); // modify
    ....
})

请注意,与starCount相关的代码似乎没有必要,并且不清楚该方法中的某些其他代码正在做什么或为什么有这些代码(例如currentval也是一样的值为value

最后,要获得客户端验证,请添加以下脚本(document.ready()

$.validator.setDefaults({ 
    ignore: ":hidden:not('.rating')"
});