yuezonghe | 824eb0c | 2024-06-27 02:32:26 -0700 | [diff] [blame^] | 1 | /** |
| 2 | * -------------------------------------------------------------------- |
| 3 | * jQuery customfileinput plugin |
| 4 | * Author: Scott Jehl, scott@filamentgroup.com |
| 5 | * Copyright (c) 2009 Filament Group |
| 6 | * licensed under MIT (filamentgroup.com/examples/mit-license.txt) |
| 7 | * -------------------------------------------------------------------- |
| 8 | */ |
| 9 | $.fn.customFileInput = function(){ |
| 10 | var isChanged = false; |
| 11 | var maxLength = 32; |
| 12 | //apply events and styles for file input element |
| 13 | var fileInput = $(this) |
| 14 | .addClass('customfile-input') //add class for CSS |
| 15 | .mouseover(function(){ upload.addClass('customfile-hover'); }) |
| 16 | .mouseout(function(){ upload.removeClass('customfile-hover'); }) |
| 17 | .focus(function(){ |
| 18 | upload.addClass('customfile-focus'); |
| 19 | fileInput.data('val', fileInput.val()); |
| 20 | }) |
| 21 | .blur(function(){ |
| 22 | upload.removeClass('customfile-focus'); |
| 23 | $(this).trigger('checkChange'); |
| 24 | }) |
| 25 | .bind('disable',function(){ |
| 26 | fileInput.attr('disabled',true); |
| 27 | upload.addClass('customfile-disabled'); |
| 28 | }) |
| 29 | .bind('enable',function(){ |
| 30 | fileInput.removeAttr('disabled'); |
| 31 | upload.removeClass('customfile-disabled'); |
| 32 | }) |
| 33 | .bind('checkChange', function(){ |
| 34 | if(fileInput.val() && fileInput.val() != fileInput.data('val')){ |
| 35 | fileInput.trigger('change'); |
| 36 | } |
| 37 | }) |
| 38 | .bind('change',function(){ |
| 39 | isChanged = true; |
| 40 | //get file name |
| 41 | var fileName = $(this).val().split(/\\/).pop(); |
| 42 | //get file extension |
| 43 | var fileExt = 'icon-' + getFileType(fileName);//'customfile-ext-' + fileName.split('.').pop().toLowerCase(); |
| 44 | //update the feedback |
| 45 | var tmpFileName = ''; |
| 46 | var checkLen = 0; |
| 47 | for(var i = 0; i < fileName.length && checkLen < maxLength; i++){ |
| 48 | var c = fileName.charAt(i); |
| 49 | if(getEncodeType(c).encodeType == 'UNICODE'){ |
| 50 | checkLen += 3; |
| 51 | }else{ |
| 52 | checkLen += 1; |
| 53 | } |
| 54 | tmpFileName += c; |
| 55 | } |
| 56 | if(fileName != tmpFileName){ |
| 57 | tmpFileName = tmpFileName + '...'; |
| 58 | } else { |
| 59 | tmpFileName = fileName; |
| 60 | } |
| 61 | uploadFeedback |
| 62 | .html(HTMLEncode(tmpFileName)) //set feedback text to filename |
| 63 | .removeClass(uploadFeedback.data('fileExt') || '') //remove any existing file extension class |
| 64 | .addClass(fileExt) //add file extension class |
| 65 | .data('fileExt', fileExt) //store file extension for class removal on next change |
| 66 | .addClass('customfile-feedback-populated'); //add class to show populated state |
| 67 | upload.attr('title', fileName); |
| 68 | //change text of button |
| 69 | uploadButton.html("<span id='uploadBtn' data-trans='change_btn'>"+$.i18n.prop('change_btn')+"</span>"); |
| 70 | }) |
| 71 | .click(function(){ //for IE and Opera, make sure change fires after choosing a file, using an async callback |
| 72 | fileInput.data('val', fileInput.val()); |
| 73 | setTimeout(function(){ |
| 74 | fileInput.trigger('checkChange'); |
| 75 | },100); |
| 76 | }); |
| 77 | |
| 78 | //create custom control container |
| 79 | var upload = $('<div class="customfile"></div>'); |
| 80 | //create custom control button |
| 81 | var uploadButton = $('<span class="customfile-button" aria-hidden="true"><span id="uploadBtn" data-trans="browse_btn">'+$.i18n.prop('browse_btn')+'</span></span>').appendTo(upload); |
| 82 | //create custom control feedback |
| 83 | var uploadFeedback = $('<span class="customfile-feedback" aria-hidden="true"><span data-trans="no_file_selected">'+$.i18n.prop("no_file_selected")+'</span></span>').appendTo(upload); |
| 84 | |
| 85 | //match disabled state |
| 86 | if(fileInput.is('[disabled]')){ |
| 87 | fileInput.trigger('disable'); |
| 88 | } |
| 89 | |
| 90 | //on mousemove, keep file input under the cursor to steal click |
| 91 | upload |
| 92 | .mousemove(function(e){ |
| 93 | fileInput.css({ |
| 94 | 'left': e.pageX - upload.offset().left - fileInput.outerWidth() + 20, //position right side 20px right of cursor X) |
| 95 | 'top': e.pageY - upload.offset().top - 14 |
| 96 | }); |
| 97 | }) |
| 98 | .insertAfter(fileInput); //insert after the input |
| 99 | |
| 100 | fileInput.appendTo(upload); |
| 101 | |
| 102 | //return jQuery |
| 103 | return $(this); |
| 104 | }; |