代码之家  ›  专栏  ›  技术社区  ›  Georgi Koemdzhiev

为什么我的JQuery自定义数据验证在提交时没有执行?

  •  0
  • Georgi Koemdzhiev  · 技术社区  · 6 年前

    IsEmailValid 方法)在按下下面的“提交”(即共享)按钮时不会执行。这个 Required 一个执行得很好,但我的自定义验证属性- IsEmailAttribute

    那是我的 index.cshtml索引 我的表格是通过 Html.RenderPartial :

    @using System.Security.Principal
    @using DNAAnalysisCore.Resources
    @model DNAAnalysisCore.ViewModels.WorkbookViewModel
    
    @section BodyFill
        {
        <div id="shareFormContainer">
            @{ Html.RenderPartial("_ShareView", new WorkbookShareModel());}
        </div>
    
        <table class="table">
            <tbody>
            @foreach (var workbook in Model.Workbooks)
            {
                <tr class="@trClassName">
                    <td>@Html.ActionLink(linkText, "Open", "OpenAnalytics", new { id = Model.Id, workbook = workbook.Name })</td>
                    <td class="last-modified-date" title="Last Modified Date">@workbook.ModifiedDate.ToShortDateString()</td>
                    <td class="share">
                        <button title="Share" class="share-button" onclick='showSharingView("@workbook.Name", "@workbook.Id", "@Model.Id")'>&nbsp;</button>
                    </td>
                </tr>
            }
            </tbody>
        </table>
    }
    
    @section Scripts
        {
        <!--Load JQuery 'unobtrusive' validation -->
        @await Html.PartialAsync("_ValidationScriptsPartial")
        <script type="text/javascript">
    
            function showSharingView(title, workbookId, id) {            
                var isEmailAdapterName = 'isEmail';        
                $('#shareFormModal').modal("show");
    
                // client-side email validation
                $.validator.addMethod(isEmailAdapterName, IsEmailValid);
                // register the 'isEmail' attribute with the 'unobtrusive' validation
                $.validator.unobtrusive.adapters.add(isEmailAdapterName,
                    [],
                    function(options) {
                        // add a 'isEmail' rule to the options so that JQuery can find it when it's checking the rules collection
                        options.rules.isEmail = {};
                        // add a message for the 'isEmail' rule ('message' will have the 'ShareModel' attribute 'ErrorMessage' value)
                        options.messages[isEmailAdapterName] = options.message;
                    });
            }
    
            function hideDialog() {
                var form = $("#partialform");
                // only hide the dialog if the form is valid
                if (form.valid()) {
                    $('#shareFormModal').modal("hide");
                }
            }
    
            // Helper method that validates list of emails
            function IsEmailValid(emailList, element, parameters) {
                // EMAIL VALIDATION LOGIC HERE
            }
        </script>
    }
    

    public class WorkbookShareModel
    {
        [HiddenInput]
        public string Id { get; set; }
        [HiddenInput] 
        public string WorkbookId { get; set; }
        [HiddenInput]
        public string Title { get; set; }
        [Required(ErrorMessageResourceType = typeof(Resources.BaseLanguage), ErrorMessageResourceName = "Email_Requirement_Warning")]
        [IsEmailAttribute(ErrorMessageResourceType = typeof(Resources.BaseLanguage), ErrorMessageResourceName = "Email_Invalid_Message")]
        public IList<string> Emails { get; set; }
    }
    
    public class IsEmailAttribute : ValidationAttribute, IClientModelValidator
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var share = (WorkbookShareModel)validationContext.ObjectInstance;
    
            foreach (var email in share.Emails)
            {
                var convertedEmail = email.Trim().ToLower();
                var match = Regex.Match(convertedEmail, Constants.EmailPattern);
                // if one of the emails does not match the pattern, break out of the look and return the error message
                if (!match.Success)
                    return new ValidationResult(ErrorMessage);
            }
    
            return ValidationResult.Success;
        }
    
        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-isEmail", errorMessage);
        }
    
        private void MergeAttribute(IDictionary<string, string> attributes, string key, string value)
        {
            if (attributes.ContainsKey(key))
                return;
    
            attributes.Add(key, value);
        }
    }
    }
    

    这是我的表格:

    @using DNAAnalysisCore.Resources
    @model DNAAnalysisCore.Models.WorkbookShareModel
    
    <!-- Modal -->
    <div onclick="activateShareButtons()" class="modal fade" id="shareFormModal" role="dialog">
        <div class="modal-dialog modal-md">
            <!-- Modal content-->
            <div class="modal-content">
                <div class="modal-header">
                    <h4 id="dialogDisplayTitle" class="modal-title">THIS VALUE IS SET VIA JAVASCRIPT</h4>
                </div>
    
                @using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post, new { @id = "partialform" }))
                {
                    <div class="modal-body">
    
                        <label>@BaseLanguage.Share_workbook_Instruction_text</label>
                        <div class="form-group">
                            <textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="@BaseLanguage.ShareDialogPlaceholder"></textarea>
                            <span asp-validation-for="Emails" class="text-danger"></span>
                        </div>
    
                        <input asp-for="Title" />
                        <input asp-for="Id" />
                        <input asp-for="WorkbookId"/>
                    </div>
                    <div class="modal-footer">
                        <button onclick="hideDialog()" type="submit" class="btn btn-primary">Share</button>
                        <button onclick="activateShareButtons()" id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
                    </div>
                }
    
            </div>
        </div>
    </div>
    
    0 回复  |  直到 6 年前
        1
  •  0
  •   Georgi Koemdzhiev    6 年前

    我设法通过移动 $.validator.addMethod $.validator.unobtrusive.adapters.add showSharingView 方法。成功了,我的自定义错误显示正确。但是,我不知道为什么:

    <script type="text/javascript">
    
        var isEmailAdapterName = 'isEmail';
        // client-side email validation
        $.validator.addMethod(isEmailAdapterName, IsEmailValid);
        // register the 'isEmail' attribute with the 'unobtrusive' validation
        $.validator.unobtrusive.adapters.add(isEmailAdapterName,
            [],
            function(options) {
                // add a 'isEmail' rule to the options so that JQuery can find it when it's checking the rules collection
                options.rules[isEmailAdapterName] = {};
                // add a message for the 'isEmail' rule ('message' will have the 'ShareModel' attribute 'ErrorMessage' value)
                options.messages[isEmailAdapterName] = options.message;
            });
    
        function showSharingView(title, workbookId, id) {
            $('.share-button').prop('disabled', true); // Disable all share buttons to avoid opening multiple dialogs
            // reset the 'Emails' textarea 
            $('#Emails').val('');
            // set the dialog's control values
            $('#Title').val(title);
            $('#Id').val(id);
            $('#WorkbookId').val(workbookId);
            // set the dialog's title 
            $('#dialogDisplayTitle').html("Share Workbook - " + title);
    
            $('#shareFormModal').modal("show");
        }