Call change event in IE8 on <input file> pro

2019-06-02 01:20发布

Primefaces 5

I have <input type="file" class="ui-fileupload-choose> in code to upload the files. This input-Tag is generated automatically from a PrimeFaces component <p:fileUpload>. I want to hide the button for input element and use my own styled button for upload.

So this is the styled button.

<input type="button" onclick="$('#formId\\:uploaderId .ui-fileupload-choose input').click();">

This does function in FF, Chrome and IE9, 10, 11. But in IE8 nothing happens in upload phase. The "choose file" dialog is shown. The generated input file has JQuery change event. I believe that this event will not be called, because if I click on input file button it goes in all browsers.

I've tried

<input type="button" onclick="$('#formId\\:uploaderId .ui-fileupload-choose input').click(); #formId\\:uploaderId ui-fileupload-choose input').trigger('change');">

but it doesn't help.

Also I've tried

$('#formId\\:uploaderId .ui-fileupload-choose input').change(function () {
    // Cause the change() event
    // to be fired in IE8 et. al.
    //some checks against recursion.
     alert("I'm in change");
    $('#formId\\:uploaderId .ui-fileupload-choose input').change();               
});

The function in change is called but it doesn't help either.

What can I do in this situation ?

3条回答
疯言疯语
2楼-- · 2019-06-02 01:26

This is due to a security restriction in IE.

When there's <input type="file"/> which has either of

  • display:none
  • visbilty:hidden
  • opacity: 0

IE blocks the request to upload the file if it's being called manually (javascript click).

In PrimeFaces case the input file has opacity: 0.

Here's how the input file looks like without the CSS extra flavours:

fileupload

The work around is to move that input file outside p:fileUpload component so it can loose the CSS roles, and append it to a span or div with button styling, that would result an actual click on the file input.

Button

<span class="btn btn-primary btn-file">
   <i class="fa fa-upload"></i> Upload File
</span>

javascript

$(document).ready(function() {
   $('.ui-fileupload-buttonbar span input[type=file]').addClass('uploadBtn');
   $('.btn-file').append($('.uploadBtn'));
});

Something link this:

append1

Now to get it to look nice and work in the same time on all browsers including IE, some CSS should be added. First ignore the first two CSS classes btn btn-primary (colors, padding etc..)

The btn-file is the custom trick:

.btn-file {
   position: relative;
   overflow: hidden;
 }

 .btn-file input[type=file] {
    position: absolute;
    top: 0;
    right: 0;
    min-width: 100%;
    min-height: 100%;
    font-size: 999px;
    text-align: right;
    filter: alpha(opacity=0);
    opacity: 0;        
    cursor: inherit;
    display: block;
 } 

The final result is a button with input file in the background:

final

The p:fileUpload component should be hidden:

<p:fileUpload style="display: none" />

In order to display the error messages you can use onchange event for that input file:

$('.uploadBtn').change(function() {
   var a = $('.ui-fileupload-content').html(); var b = $('#editUserUploadMessages').html(a);
})

Where #editUserUploadMessages is a div containing all the messages.

Finally hide the other uploaded files:

#editUserUploadMessages .ui-fileupload-files {
     display: none;
}

You can find a small example on github and a Demo

查看更多
Summer. ? 凉城
3楼-- · 2019-06-02 01:32

Additional solution to an excellent answer of Hatem. It is using this SO answer.

You can use html tag <label> to forward the click to input buton.

<h:form id="formId" >
 <style>

 #formId\:uploaderId .ui-fileupload-buttonbar {
    position: absolute;  
    left: -10000px;
 }

 #formId\:uploaderId .ui-fileupload-content {
    border: none;
 }
 </style>

 <p:fileUpload id="uploaderId" mode="advanced" auto="true" allowTypes="..." fileLimit="...">


 <label for="formId:uploaderId_input">
    <span class="fa fa-upload" />    
 </label>
</h:form>

This way the errors will be shown at point where <p:fileUpload> is included.

查看更多
对你真心纯属浪费
4楼-- · 2019-06-02 01:44
  1. add style display:none to input type="file"
  2. create new text box and button at the position of input type file
  3. create js function when click your button that click the button of file upload
查看更多
登录 后发表回答