Forum Moderators: open

Message Too Old, No Replies

Image upload preview OK in FF but not in IE

         

makuk

5:07 am on Feb 15, 2010 (gmt 0)

10+ Year Member



First post here, never had to post before because I have always found what I have been looking for, great forum and great members, big ups to you all.

I have a image upload preview script that I am using, here is the .js file that is called:



function ImageUploadPreview(input, opt_onSuccess, opt_onFail) {
this.construct(input, opt_onSuccess, opt_onFail);
}

ImageUploadPreview.BLANK_IMAGE_SRC = 'images/all/cleardot.gif';

ImageUploadPreview.BASE64_IMG_URL_PATTERN =
/^data:image\/((png)|(gif)|(jpg)|(jpeg)|(bmp));base64/i;

ImageUploadPreview.prototype.input_ = null;

ImageUploadPreview.prototype.onChangeHandler_ = null;

ImageUploadPreview.prototype.onPreviewSuccessHandler_ = null;

ImageUploadPreview.prototype.onPreviewFailHandler_ = null;

ImageUploadPreview.prototype.image_ = null;

ImageUploadPreview.prototype.isCompatible_ = null;

ImageUploadPreview.prototype.maxWidth_ = 200;

ImageUploadPreview.prototype.maxHeight_ = 200;

ImageUploadPreview.prototype.construct =
function(input, opt_onSuccess, opt_onFail) {
if (typeof input == 'string') {
input = document.getElementById(input);
}

this.onPreviewFailHandler_ = opt_onFail;
this.onPreviewSuccessHandler_ = opt_onSuccess;
this.input_ = input;
this.bindEvents_();
this.image_ = this.createImage_();
};


/**
* @public
*/
ImageUploadPreview.prototype.dispose = function() {
var fn = this.onChangeHandler_;

// Already disposed.
if (!fn) return;

var el = this.input_;

if (el.addEventListener) {
el.removeEventListener('change', fn, false);
} else if (el.attachEvent) {
el.detachEvent('onchange', fn);
}

this.onChangeHandler_ = null;
this.input_ = null;
this.image_ = null;
};

/**
* @public
*/
ImageUploadPreview.prototype.preview = function() {
var that = this;

var onLoad = function(imgInfo) {
// Do thing now, maybe do something later.
that.maybeCallFunction_(that.onPreviewSuccessHandler_, imgInfo);
};

var onError = function(src) {
if (!tryLoad()) {
that.showEmptyImage_();
that.maybeCallFunction_(that.onPreviewFailHandler_, src);
}
};

var loadMethods = [
this.maybeShowImageWithDataUri_,
this.maybeShowImageByPath_
];

var tryLoad = function() {
if (!loadMethods.length) {
return false;
}
var fn = loadMethods.shift();
fn.call(that, onLoad, onError);
return true;
};
tryLoad();
};


/**
* @public
* @return {HTMLImageElement}
*/
ImageUploadPreview.prototype.getImageElement = function() {
return this.image_;
};


/**
* @public
* @return {HTMLInputElement}
*/
ImageUploadPreview.prototype.getInputElement = function() {
return this.input_;
};

ImageUploadPreview.prototype.setMaxImageSize = function(maxW, maxH) {
this.maxHeight_ = isNaN(maxH) ? 200 : maxH;
this.maxWidth_ = isNaN(maxW) ? 300 : maxW;
};


/**
* @private
* @return {HTMLImageElement}
*/
ImageUploadPreview.prototype.createImage_ = function() {
var doc = this.input_.document || this.input_.ownerDocument;
var img = doc.createElement('img');
img.src = ImageUploadPreview.BLANK_IMAGE_SRC;
img.width = 0;
img.height = 0;
this.input_.parentNode.insertBefore(img, this.input_.nextSibling || null);
return img;
};



/**
* @private
*/
ImageUploadPreview.prototype.bindEvents_ = function() {
var that = this;

var fn = this.onChangeHandler_ = function(e) {
e = e || window.event;

if (!e.target && e.srcElement) {
e.target = e.srcElement;
}

that.handleOnchange_.call(that, e);
};

var el = this.input_;

if (el.addEventListener) {
el.addEventListener('change', fn, false);
} else if (el.attachEvent) {
el.attachEvent('onchange', fn);
}
};


/**
* @param {Event} e
* @private
*/
ImageUploadPreview.prototype.handleOnchange_ = function(e) {
this.preview();
};


/**
* @private
*/
ImageUploadPreview.prototype.showEmptyImage_ = function() {
this.showImage_(ImageUploadPreview.BLANK_IMAGE_SRC, 0, 0)
};


/**
* @private
* @param {string} src
* @param {number} w
* @param {number} h
*/
ImageUploadPreview.prototype.showImage_ = function(src, w, h) {

if (w > h) {
if (w > this.maxWidth_) {
h = h * this.maxWidth_ / w;
w = this.maxWidth_;
}
} else {
if (h > this.maxHeight_) {
w = w * this.maxHeight_ / h;
h = this.maxHeight_;
}
}

var img = this.image_;
img.src = src;

var imgStyle = img.style;
imgStyle.maxHeight = this.maxHeight_ + 'px';
imgStyle.maxWidth = this.maxWidth_ + 'px';
imgStyle.width = (w >= 0) ? Math.round(w) + 'px' : 'auto';
imgStyle.height = (h >= 0) ? Math.round(h) + 'px' : 'auto';
};


/**
* @param {Function?} fn
* @param {Object?} var_args
*/
ImageUploadPreview.prototype.maybeCallFunction_ = function(fn, var_args) {
if (typeof fn != 'function') return;
var_args = Array.prototype.slice.call(arguments, 1);
fn.apply(this, var_args);
};


/**
* Note: Only Firefox 3 can do file.getAsDataURL() by 6/1/2009.
* See {@link https://developer.mozilla.org/En/NsIDOMFile}.
* @private
* @param {Function?} opt_onload
* @param {Function?} opt_onerror
*/
ImageUploadPreview.prototype.maybeShowImageWithDataUri_ =
function(opt_onload, opt_onerror) {
var el = this.input_;
var file = el.files && el.files[0];
var src;
var fileName = el.value;

// Check if we can access the serialized file via getAsDataURL().
if ((file && file.getAsDataURL) &&
(src = file.getAsDataURL()) &&
(ImageUploadPreview.BASE64_IMG_URL_PATTERN.test(src))) {

var that = this;
var img = this.image_;


if ('naturalWidth' in this.image_) {
// Firefox has naturalWidth.
this.image_.src = src;

setTimeout(function() {
that.showImage_(src, img.naturalWidth, img.naturalHeight);
that.maybeCallFunction_(opt_onload, {
width: img.naturalWidth,
height: img.naturalHeight,
fileName : fileName,
fileSize: el.files[0].fileSize
});
}, 10);

} else {
// Use default CSS max-width / max-height to render the size.
that.showImage_(src, -1, -1);

this.maybeCallFunction_(opt_onload, {
fileName : fileName,
width: img.offsetWidth,
height: img.offsetHeight,
fileSize: el.files[0].fileSize
});
}
} else {
this.maybeCallFunction_(opt_onerror, fileName);
}
};


/**
* Note: IE6 ~ IE8 can access image with local path. By 6/1/2009.
* However, this may still not work if the security setting changes.
* @private
* @param {Function?} opt_onload
* @param {Function?} opt_onerror
*/
ImageUploadPreview.prototype.maybeShowImageByPath_ =
function(opt_onload, opt_onerror) {

var that = this;
var el = this.input_;
var img = new Image();
var timer;
var fileName = el.value.split(/[\\\/]/ig).pop();

var dispose = function() {
if (timer) {
window.clearInterval(timer);
}
img.onload = null;
img.onerror = null;
timer = null;
dispose = null;
img = null;
that = null;
checkIsComplete = null;
handleError = null;
handleComplete = null;
};

// Handle the case whether the File is not a image file or the path is not a
// valid path to access.
var handleError = function() {
that.maybeCallFunction_(opt_onerror, el.value);
dispose();
};

var handleComplete = function() {
var w = img.width;
var h = img.height;
that.showImage_(img.src, w, h);
that.maybeCallFunction_(opt_onload, {
src:fileName,
width: w,
height: h,
fileSize: img.fileSize // Note that FileSize is an IE's only attribute.
});
dispose();
};

var checkIsComplete = function(e) {
e = e || window.event;
var type = e && e.type;

if (type == 'error') {
// If the onError event is called.
handleError();
} else if (img.complete || type == 'load') {
// Sometimes IE does not fire "onload" event if the image was cahced.
// So we have to check the "complete" state to know whether it's ready.
if (!img.width || !img.height) {
// Even it's not a real image, the onload event may still gets fired.
// Check if its width or height is 0. If true, it's not a real image.
handleError();
} else {
handleComplete();
}
}
};


img.onload = checkIsComplete;
img.onerror = checkIsComplete;
timer = window.setInterval(checkIsComplete, 50);

// In IE, el.value us the full path of the file rather than just the fileName,
// and we'd test if we can load image from this path.
img.src = el.value;

};


And this is the code I am using in my html:


<input type="file" name="file" id="upload" size="15" style="background-color: #FFFFFF" onKeyUp="highlight(event)" onClick="highlight(event)">

<?php
if ($task=="editRoom"){echo '<input type="hidden" name="file_hidden" id="file_hidden" value="'.$editroom->image.'" />';} ?>

<script type="text/javascript">
(function() {
var demo = new ImageUploadPreview(

// Upload Input Element
document.getElementById('upload'),

// onPreviewSuccess handler.
function(imgInfo) {
var info = [];
for (var i in imgInfo) {
info.push('<li>', i, ' = ', imgInfo[i], '</li>');
}

if (info.length) {
info.unshift('<ul>');
info.push('</ul>');
}
this.getImageElement().className = 'preview-image';
document.getElementById('file-info').innerHTML = info.join('');
},

// onPreviewFail handler.
function() {
this.getImageElement().className = '';
});

demo.setMaxImageSize(demo.getInputElement().offsetWidth, 150);


// If the value already exists, try display image.
demo.preview();
})();
</script>


There are a couple of issues that I have, the first is that in FF when I select an image, the first one does not preview, if I select another image it will preview just fine and all other images I preview work just fine, but in IE, I do not get a preview of the image I have selected at all.

Would anyone know why this is doing this and perhaps have a solution to the problem.

Thank you for your help.

Regards

Mark.

Fotiman

3:14 pm on Feb 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Welcome to WebmasterWorld!

That is a LOT of code. You might want to read this thread:
[webmasterworld.com...]
In particular:
Please don't post a "code dump" with dozens of lines of irrelevant markup. Also, please don't simply copy/paste your entire HTML page and script files. Doing this means that you are very unlikely to get a useful answer to your problem as the amount of extra code is overwhelming! Make it easy for other members to help you.


You are much more likely to get replies if you can limit the code to only the specific pieces that are causing you problems.

makuk

3:35 pm on Feb 16, 2010 (gmt 0)

10+ Year Member



Hi, yes I appreciate it is a lot of code, but I cannot edit the code because I don't know where the error is, if I did I would not be posting! Does not look like anyone knows what the problem is anyway

But thanks anyway.

Fotiman

3:57 pm on Feb 16, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Does not look like anyone knows what the problem is anyway

More likely, no one is bothering to take a closer look because the code dump is overwhelming.

My suggestion would be to use Firebug to step through the code. Add break points in the methods and then 'watch' what values the variables contain. This might help you determine where in the code the problem is occurring and then you might be able to refine you post.