开发者

Replacing normal file upload input with an image

Bit of a newbie question here.

I have a form and one of it's fields is for a file upload. Instead of having the boring old usual text input box with a 'choose file' button beside it, I'd like to have an image which when you click opens the dialog box to browse for the photo.

The way I was hoping to be able to do this was with two forms. IE when the user clicks the image a modal box appears with form upload input in it. User chooses file and clicks submit the user is returned to the form.

开发者_开发知识库

That doesn't seem to work because having a form inside a form must be bad practice i suppose :) Is there a way to do it like this?

The alternative is that I can somehow replace the usual text input box with the 'choose file' button with my own graphic but despite google I ain't found out how to do that.

Any ideas


Very simple solution - simply put a label tag for your input

<label for="uploadFile">
    <div id="image"></div>
</label>
<input type="file" id="uploadFile" style="display:none" />

And the just add a background-image property to the #image div :)


Because of the heap of security issues around how file inputs work, they're pretty hard to fix. What does work, however, is a scheme like this:

  • Design your own look for a file input that's fairly close to the default one in size and shape
  • Position your file input and a real file input at the same place in your form, with the real one on top of yours
  • Make the real input be transparent (that is, set the opacity to zero)

Now clicks on your elements styled the way you want them to look will actually be interpreted by the browser as clicks on the file input. You have to tweak things somewhat for IE, because IE7 allows the user to type directly into the input while other browsers all immediately launch the file chooser when the element is clicked anywhere.

edit — here is a jsfiddle that works in Chrome at least. The HTML:

<div class='fancy-file'>
    <div class='fancy-file-name'>&nbsp;</div>
    <button class='fancy-file-button'>Browse...</button>
    <div class='input-container'>
        <input type='file'>
    </div>
</div>

That wraps the "fake" file input that I'll style with my own CSS, as well as the real <input> element. Here's the CSS:

div.fancy-file {
    position: relative;
    overflow: hidden;
    cursor: pointer;
}

div.fancy-file-name {
    float: left;
    border-radius: 3px;
    background-color: #aaa;
    box-shadow:
        inset 1px 1px 3px #eee,
        inset -1px -1px 3px #888,
        1px 1px 3px #222;
    font-weight: bold;
    font-family: Courier New, fixed;
    width: 155px;
    font-size: 12px;
    padding: 1px 4px;
}

button.fancy-file-button {
    float: left;
    border-radius: 3px;
    border: 1px solid red;
    background-color: #F5BD07;
    font-weight: bold;
    vertical-align: top;
    margin: 0 0 0 3px;
}

div.input-container {
    position: absolute;
    top: 0; left: 0;
}

div.input-container input {
    opacity: 0;
}

The outer container is made "position: relative" to make it easy to position the real <input> over the fake stuff. The fake stuff has my made-up fancy styles, and it's sized so that it's just about the same as the overall size of a real file input. The real one is absolutely positioned and transparent.

Here's some jQuery to drive it:

$('div.fancy-file input:file').bind('change blur', function() {
    var $inp = $(this), fn;

    fn = $inp.val();
    if (/fakepath/.test(fn))
        fn = fn.replace(/^.*\\/, '');

    $inp.closest('.fancy-file').find('.fancy-file-name').text(fn);
});

Browsers won't give you the complete pathname, but they'll give you a part of it. Some browsers (Chrome and IE) give you an obviously-fake path prefix, so the code strips that out (because it's useless).


File upload fields are quite limited. See: http://www.quirksmode.org/dom/inputfile.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜