【问题标题】:Additional onchange event for FileUpload with validators带有验证器的 FileUpload 的附加 onchange 事件
【发布时间】:2014-12-10 03:02:26
【问题描述】:

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


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

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

【问题讨论】:

    标签: c# javascript asp.net


    【解决方案1】:

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

    如果你这样做

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

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

    【讨论】:

    • 是否也必须在 postBacks 上调用 ClientScript.RegisterStartupScript,还是第一次加载就足够了?
    • 如果可能,我仍然建议将其添加到客户端(ASPX/JS)。否则是的,每次页面加载时都必须调用它 - 初始和回发。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    相关资源
    最近更新 更多