简体   繁体   中英

How do I use jquery to validate form fields, that was populated dynamically?

I have a list of 10 questions, used in rating a user, something like this: 在此处输入图片说明

The list is gotten dynamically, based on the users Occupation. This is how I am getting the list:

@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> 
}

This is the model:

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; }
}

and this is the 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"},
    };
}

This is the script section code:

 @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>

}

And all questions must be answered. How Do I validate to make sure that all questions are answered?

I have tried form.Validate() but it is not working.

Your view is generating 5 hidden inputs for the same SelectedAnswer . You need only one (only the value of the first one will be bound by the DefaultModelBinder ), and you need to set its value in the starrr:change event.

However, hidden inputs are not validated by default so you also need to configure the $.validator to give you client side validation.

First, modify your view to delete the foreach loop and replace it with a single hidden input. Note also the id attributes have been replaced with class names (duplicate id attributes is invalid 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> 
}

Then to set the value of the input so it is posted back when you submit the form

$('.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
    ....
})

Note the code relating to starCount does not seem necessary, and its not clear what some of the other code in that method is doing or why you have it (for example currentval is just the same value as value )

Finally, to get client side validation, add the following script (but not inside document.ready() )

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM