1

编辑2013-11-07:我看到很多关于这个问题的观点。如果此问题和答案对您没有帮助,请以某种方式告诉我,以便我解决。


我的 .aspx 文件中有一个FileUpload控件。我有几个与之相关的验证器(一个CustomValidator用于文件大小和一个RegularExpressionValidator用于文件扩展名类型)。我想在验证器触发后onchange向我添加一个客户端事件以触发,但是当我这样做时......FileUpload

<asp:FileUpload runat="server" ID="upl1" onchange="disableEnableUploadButton()" />

... onchange 处理程序似乎被验证器覆盖。当我将它作为属性添加到 CodeBehind 的Page_Load方法中时,也会发生同样的事情。

有没有一种简单的方法来解决这个问题,希望不添加客户端加载事件来挖掘页面并修改结果文件输入的属性?

我目前的解决方案是添加另一个CustomValidator或修改已经存在的那个,并将我想要的代码放在它的ClientValidationFunction脚本块中。但是,当用户取消文件输入的文件对话框时,这不会触发。它真的很粗糙。


编辑:这是一个可行的(据我所知)解决方案,稍微修剪了一下。解决我遇到的问题的重要部分是最后四行。这不是 Yuriy 的确切解决方案,但他的解决方案导致了这一点。.bind() 是一个旧的 jQuery 函数;我可能会使用不同的函数,如 .on(),但我们正在运行一个旧的 jQuery 库。

 <script type="text/javascript" >
    function disableEnableUploadButton(btnID, uplID) {
        var button = document.getElementById(btnID);
        var uploader = document.getElementById(uplID);
        button.disabled = false;
        for (var i = 0; i < uploader.Validators.length; i++) {
            // Looping through each validator.
            if (uploader.Validators[i].isvalid == false) {
                // Looks like this validator isn't valid.  Better disable the upload button.
                button.disabled = true;
                break;
            }
        }
    }
    function validateFileSize(source, e) {
        var maxSize = document.getElementById('<%=hdnMaxFileSize.ClientID %>').value;
        var fileInput = document.getElementById('<%=upl1.ClientID %>');
        if (!window.FileReader || !fileInput.files || !fileInput.files[0]) {
            // No files attached.  That means no files that are too large are attached.
            e.IsValid = true;
        }
        else if (fileInput.files[0].size > maxSize) {
            // Looks like someone's trying to give us a lot of bytes.  No, thank you, Mister User.
            e.IsValid = false;
        }
    }
</script>

<asp:FileUpload runat="server" ID="upl1" />
<asp:Button ID="btnUpload" runat="server" Text="Upload file" OnClick="btnUpload_Click" CausesValidation="false" />
<asp:RegularExpressionValidator ID="valExtension" ControlToValidate="upl1" runat="server" ErrorMessage="Unallowed file type for upload" />
<asp:CustomValidator ID="valFileSize" runat="server" ControlToValidate="upl1" ClientValidationFunction="validateFileSize" ErrorMessage="File too large" OnServerValidate="valFileSize_ServerValidate" >
    <asp:HiddenField ID="hdnMaxFileSize" runat="server" />
</asp:CustomValidator>
<script type="text/javascript">
    // This is not in a function, so it fires when the markup is being processed.  That's why it appears after everything else.
    var upl = document.getElementById('<%=upl1.ClientID %>');
    $(upl).bind('change', function () { disableEnableUploadButton('<%=valExtension.ClientID %>', '<%=valFileSize.ClientID %>', '<%=btnUpload.ClientID %>'); });
</script>
4

1 回答 1

1

您必须在客户端而不是服务器端执行此操作。您可以使用语句将多个事件处理程序附加到元素的事件$addHandler(您必须将 ScriptManager 添加到您的 ASPX 页面才能工作)。

在你的情况下,如果你这样做

$addHandler($get("upl1"), "change", disableEnableUploadButton);

它将把这个新的处理程序链接到已经发生的任何事情上。如果您不想将此代码直接添加到客户端代码中,您可以通过以下方式在服务器端生成它ClientScript.RegisterStartupScript

于 2013-09-17T21:28:13.997 回答