This forum is a community forum meant for users of the plugin to collaborate and help solve issues with implementation, etc. Unfortunately, as the creator of the plugin, I do not have much time to attend to every request here as this is only a side project and I must work a full-time job to provide for my family. This is how I keep the Flash version free and the HTML5 version low cost.
UploadiFive 1.1.1 has been released which includes a small fix for added support on touch devices including iOS 6 devices.
Language translations ?
  • Hi guys,

    I'm a french canadian programmer and I use the Uploadify component in my project. Great work!
    But I was surprised that there is no way to specify the language yet.

    Would it be a good idea to create a new configuration key, like :

    $('#"fileUpload"').fileUpload({
    'language': 'fr', // default value would be english when unspecified

    'uploader': 'uploader.swf',
    'script': 'upload.php',
    'folder': 'my_files',
    'cancelImg': 'cancel.png',
    });

    I see those possible translations in the uncompressed version of the jquery.uploadify.js file :
    - Line 175, sentence "Do you want to replace the file"
    - Line 216, "Completed"
    - Measures units (KB and MB) between lines 130 and 140

    This might be implemented easily with a hash table :

    translations['replace_sentence'] = 'Do you want to replace the file';
    translations['completed'] = 'Completed';
    translations['unit_kb'] = 'KB';
    translations['unit_mb'] = 'MB';

    Let me know if you need help on this.

    http://code18.blogspot.com
  • code18 said:

    Would it be a good idea to create a new configuration key, like :

    $('#"fileUpload"').fileUpload({
    'language': 'fr', // default value would be english when unspecified

    'uploader': 'uploader.swf',
    'script': 'upload.php',
    'folder': 'my_files',
    'cancelImg': 'cancel.png',
    });


    The easier solution is to pass an object containing the language strings as in:


    $('#fileUpload').fileUpload({
    locale: {
    error: 'Error',
    complete: 'Done',
    overwrite: \"Do you want to replace the file '%'?\"
    },
    'uploader': 'uploader.swf',
    'script': 'upload.php',
    'folder': 'my_files',
    'cancelImg': 'cancel.png',
    });


    which overwrites the defaults.

    You can do it this way, or you can do it one string at a time:


    $('#fileUpload').fileUpload({
    errorString: 'Error',
    completeString: 'Done',
    overwriteString: \"Do you want to replace the file '%'?\",
    'uploader': 'uploader.swf',
    'script': 'upload.php',
    'folder': 'my_files',
    'cancelImg': 'cancel.png',
    });


    When using the first method you must remember to supply all members of
    the locale element.

    When dealing with the replace confirmer, use:


    if (confirm(settings.locale.overwrite.replace(/%/, data[key]))
    ...


    to expand it out when needed.

    Passing a language 'key' is certainly needed if the SWF needs localization - thankfully it doesn't.

    Injecting the language strings into the plug-in means you're not constantly messing with the
    plug-in, making it larger, thereby incurring a size penalty for every other language. Keeping
    all the translations inside the plug-in may be to your advantage depending on how you deal
    with translations in the first place.
  • Hi guys,

    about this topic, I did some changes on the last version of Uploadify and I submit here my contribution (btw, I agree with Barbossa, we can use a simpler approach).
    I hope it will help those who are looking for translations and i18n for this component.

    English is used as the default language and you do not have to configure anything unless you want to override some labels or change the language.

    The code below is based on version 1.6.2 but a few things changed:
    I added a translation object and all labels refers to this object (internal: settings.translations.browseButton).


    translations: $.extend({
    browseButton: 'Browse',
    error: 'An error occured',
    completed: 'Completed',
    replaceFile: 'Do you want to replace the file',
    unitKb: 'KB',
    unitMb: 'MB'
    }, options.translations )


    How to implement

    You can replace one or many default labels like this (french in my example):

    <body>
    <input type=\"file\" name=\"fileInput\" id=\"fileInput\" />
    <script type=\"text/javascript\">
    $(document).ready(function() {

    $('#fileInput').fileUpload ({
    'uploader' : 'uploader.swf',
    'script' : 'upload.php',
    'cancelImg' : 'cancel.png',
    'auto' : true,
    'folder' : '/uploads',

    [b]translations: {
    browseButton: 'Parcourir',
    error: 'Une erreur s\'est produite',
    completed: 'Terminé',
    replaceFile: 'Voulez-vous remplacer le fichier',
    unitKb: 'Ko',
    unitMb: 'Mo'
    }[/b]


    });
    });
    </script>
    </body>


    Note that the buttonText property has been replaced by the label browseButton in the translations object.

    New version - jquery.uploadify.js

    I've label it version 1.7 to illustrate the new functionnality but I'll leave it to authors to choose whether they want to officially support this version.


    /*
    Uploadify v1.7
    Copyright (C) 2009 by Ronnie Garcia
    Co-developed by Travis Nickels
    Internationalization by Infinite Loop (http://code18.blogspot.com)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.
    */

    var flashVer = -1;
    if (navigator.plugins != null &amp;&amp; navigator.plugins.length > 0) {
    if (navigator.plugins[\"Shockwave Flash 2.0\"] || navigator.plugins[\"Shockwave Flash\"]) {
    var swVer2 = navigator.plugins[\"Shockwave Flash 2.0\"] ? \" 2.0\" : \"\";
    var flashDescription = navigator.plugins[\"Shockwave Flash\" + swVer2].description;
    var descArray = flashDescription.split(\" \");
    var tempArrayMajor = descArray[2].split(\".\");
    var versionMajor = tempArrayMajor[0];
    var versionMinor = tempArrayMajor[1];
    var versionRevision = descArray[3];
    if (versionRevision == \"\") {
    versionRevision = descArray[4];
    }
    if (versionRevision[0] == \"d\") {
    versionRevision = versionRevision.substring(1);
    } else if (versionRevision[0] == \"r\") {
    ersionRevision = versionRevision.substring(1);
    if (versionRevision.indexOf(\"d\") > 0) {
    versionRevision = versionRevision.substring(0, versionRevision.indexOf(\"d\"));
    }
    }
    var flashVer = versionMajor + \".\" + versionMinor + \".\" + versionRevision;
    }
    } else if ( $.browser.msie ) {
    var version;
    var axo;
    var e;
    try {
    axo = new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash.7\");
    version = axo.GetVariable(\"$version\");
    } catch (e) {
    }
    flashVer = version.replace(\"WIN \",\"\").replace(\",\",\".\");
    }
    flashVer = flashVer.split(\".\")[0];

    if(jQuery)(
    function($){
    $.extend($.fn,{
    fileUpload:function(options) {
    if (flashVer >= 9) {
    $(this).each(function(){

    settings = $.extend(true, {
    uploader: 'uploader.swf',
    script: 'uploader.php',
    folder: '',
    height: 30,
    width: 110,
    cancelImg: 'cancel.png',
    wmode: 'opaque',
    scriptAccess: 'sameDomain',
    fileDataName: 'Filedata',
    displayData: 'percentage',
    onInit: function() {},
    onSelect: function() {},
    onCheck: function() {},
    onCancel: function() {},
    onError: function() {},
    onProgress: function() {},
    onComplete: function() {},

    translations: $.extend({
    browseButton: 'Browse',
    error: 'An error occured',
    completed: 'Completed',
    replaceFile: 'Do you want to replace the file',
    unitKb: 'KB',
    unitMb: 'MB'
    }, options.translations )

    }, options );

    var pagePath = location.pathname;
    pagePath = pagePath.split('/');
    pagePath.pop();
    pagePath = pagePath.join('/') + '/';
    var data = '&amp;pagepath=' + pagePath;
    if (settings.buttonImg) data += '&amp;buttonImg=' + escape(settings.buttonImg);

    if (settings.translations.browseButton) data += '&amp;buttonText=' + escape(settings.translations.browseButton);
    if (settings.rollover) data += '&amp;rollover=true';
    data += '&amp;script=' + settings.script;
    data += '&amp;folder=' + escape(settings.folder);
    if (settings.scriptData) {
    var scriptDataString = '';
    for (var name in settings.scriptData) {
    scriptDataString += '&amp;' + name + '=' + settings.scriptData[name];
    }
    data += '&amp;scriptData=' + escape(scriptDataString);
    }
    data += '&amp;btnWidth=' + settings.width;
    data += '&amp;btnHeight=' + settings.height;
    data += '&amp;wmode=' + settings.wmode;
    if (settings.hideButton) data += '&amp;hideButton=true';
    if (settings.fileDesc) data += '&amp;fileDesc=' + settings.fileDesc + '&amp;fileExt=' + settings.fileExt;
    if (settings.multi) data += '&amp;multi=true';
    if (settings.auto) data += '&amp;auto=true';
    if (settings.sizeLimit) data += '&amp;sizeLimit=' + settings.sizeLimit;
    if (settings.simUploadLimit) data += '&amp;simUploadLimit=' + settings.simUploadLimit;
    if (settings.checkScript) data += '&amp;checkScript=' + settings.checkScript;
    if (settings.fileDataName) data += '&amp;fileDataName=' + settings.fileDataName;
    if ($.browser.msie) {
    flashElement = '<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\"' + settings.width + '\" height=\"' + settings.height + '\" id=\"' + $(this).attr(\"id\") + 'Uploader\" class=\"fileUploaderBtn\">\
    <param name=\"movie\" value=\"' + settings.uploader + '?fileUploadID=' + $(this).attr(\"id\") + data + '\" />\
    <param name=\"quality\" value=\"high\" />\
    <param name=\"wmode\" value=\"' + settings.wmode + '\" />\
    <param name=\"allowScriptAccess\" value=\"' + settings.scriptAccess + '\">\
    <param name=\"swfversion\" value=\"9.0.0.0\" />\
    </object>';
    } else {
    flashElement = '<embed src=\"' + settings.uploader + '?fileUploadID=' + $(this).attr(\"id\") + data + '\" quality=\"high\" width=\"' + settings.width + '\" height=\"' + settings.height + '\" id=\"' + $(this).attr(\"id\") + 'Uploader\" class=\"fileUploaderBtn\" name=\"' + $(this).attr(\"id\") + 'Uploader\" allowScriptAccess=\"' + settings.scriptAccess + '\" wmode=\"' + settings.wmode + '\" type=\"application/x-shockwave-flash\" />';
    }
    if (settings.onInit() !== false) {
    $(this).css('display','none');
    if ($.browser.msie) {
    $(this).after('<div id=\"' + $(this).attr(\"id\") + 'Uploader\"></div>');
    document.getElementById($(this).attr(\"id\") + 'Uploader').outerHTML = flashElement;
    } else {
    $(this).after(flashElement);
    }
    $(\"#\" + $(this).attr('id') + \"Uploader\").after('<div id=\"' + $(this).attr('id') + 'Queue\" class=\"fileUploadQueue\"></div>');
    }
    $(this).bind(\"rfuSelect\", {'action': settings.onSelect}, function(event, queueID, fileObj) {
    if (event.data.action(event, queueID, fileObj) !== false) {
    var byteSize = Math.round(fileObj.size / 1024 * 100) * .01;
    var suffix = settings.translations.unitKb;
    if (byteSize > 1000) {
    byteSize = Math.round(byteSize *.001 * 100) * .01;
    suffix = settings.translations.unitMb;
    }
    var sizeParts = byteSize.toString().split('.');
    if (sizeParts.length > 1) {
    byteSize = sizeParts[0] + '.' + sizeParts[1].substr(0,2);
    } else {
    byteSize = sizeParts[0];
    }
    if (fileObj.name.length > 20) {
    fileName = fileObj.name.substr(0,20) + '...';
    } else {
    fileName = fileObj.name;
    }
    $('#' + $(this).attr('id') + 'Queue').append('<div id=\"' + $(this).attr('id') + queueID + '\" class=\"fileUploadQueueItem\">\
    <div class=\"cancel\">\
    <a href=\"javascript:$(\'#' + $(this).attr('id') + '\').fileUploadCancel(\'' + queueID + '\')\"><img src=\"' + settings.cancelImg + '\" border=\"0\" /></a>\
    </div>\
    <span class=\"fileName\">' + fileName + ' (' + byteSize + suffix + ')</span><span class=\"percentage\">&amp;nbsp;</span>\
    <div class=\"fileUploadProgress\" style=\"width: 100%;\">\
    <div id=\"' + $(this).attr('id') + queueID + 'ProgressBar\" class=\"fileUploadProgressBar\" style=\"width: 1px; height: 3px;\"></div>\
    </div>\
    </div>');
    }
    });
    if (typeof(settings.onSelectOnce) == 'function') {
    $(this).bind(\"rfuSelectOnce\", settings.onSelectOnce);
    }
    $(this).bind(\"rfuCheckExist\", {'action': settings.onCheck}, function(event, checkScript, fileQueue, folder, single) {
    var postData = new Object();
    postData.folder = pagePath + folder;
    for (var queueID in fileQueue) {
    postData[queueID] = fileQueue[queueID];
    if (single) {
    var singleFileID = queueID;
    }
    }
    $.post(checkScript, postData, function(data) {
    for(var key in data) {
    if (event.data.action(event, checkScript, fileQueue, folder, single) !== false) {
    var replaceFile = confirm(settings.translations.replaceFile + ' \'' + data[key] + '\'?');
    if (!replaceFile) {
    document.getElementById($(event.target).attr('id') + 'Uploader').cancelFileUpload(key);
    }
    }
    }
    if (single) {
    document.getElementById($(event.target).attr('id') + 'Uploader').startFileUpload(singleFileID, true);
    } else {
    document.getElementById($(event.target).attr('id') + 'Uploader').startFileUpload(null, true);
    }
    }, \"json\");
    });
    $(this).bind(\"rfuCancel\", {'action': settings.onCancel}, function(event, queueID, fileObj, data) {
    if (event.data.action(event, queueID, fileObj, data) !== false) {
    $(\"#\" + $(this).attr('id') + queueID).fadeOut(250, function() { $(\"#\" + $(this).attr('id') + queueID).remove()});
    }
    });
    $(this).bind(\"rfuClearQueue\", {'action': settings.onClearQueue}, function() {
    if (event.data.action() !== false) {
    $('#' + $(this).attr('id') + 'Queue').contents().fadeOut(250, function() {$('#' + $(this).attr('id') + 'Queue').empty()});
    }
    });
    $(this).bind(\"rfuError\", {'action': settings.onError}, function(event, queueID, fileObj, errorObj) {
    if (event.data.action(event, queueID, fileObj, errorObj) !== false) {
    $(\"#\" + $(this).attr('id') + queueID + \" .fileName\").text(settings.translations.error + ' (' + errorObj.type + ') - ' + fileObj.name);
    $(\"#\" + $(this).attr('id') + queueID).css({'border': '3px solid #FBCBBC', 'background-color': '#FDE5DD'});
    }
    });
    $(this).bind(\"rfuProgress\", {'action': settings.onProgress, 'toDisplay': settings.displayData}, function(event, queueID, fileObj, data) {
    if (event.data.action(event, queueID, fileObj, data) !== false) {
    $(\"#\" + $(this).attr('id') + queueID + \"ProgressBar\").css('width', data.percentage + '%');
    if (event.data.toDisplay == 'percentage') displayData = ' - ' + data.percentage + '%';
    if (event.data.toDisplay == 'speed') displayData = ' - ' + data.speed + settings.translations.unitKb + '/s';
    if (event.data.toDisplay == null) displayData = ' ';
    $(\"#\" + $(this).attr('id') + queueID + \" .percentage\").text(displayData);
    }
    });
    $(this).bind(\"rfuComplete\", {'action': settings.onComplete}, function(event, queueID, fileObj, response, data) {
    if (event.data.action(event, queueID, fileObj, unescape(response), data) !== false) {
    $(\"#\" + $(this).attr('id') + queueID).fadeOut(250, function() { $(\"#\" + $(this).attr('id') + queueID).remove()});
    $(\"#\" + $(this).attr('id') + queueID + \" .percentage\").text(' - ' + settings.translations.completed);
    }
    });
    if (typeof(settings.onAllComplete) == 'function') {
    $(this).bind(\"rfuAllComplete\", settings.onAllComplete);
    }
    });
    }
    },
    fileUploadSettings:function(settingName, settingValue) {
    $(this).each(function() {
    document.getElementById($(this).attr('id') + 'Uploader').updateSettings(settingName,settingValue);
    });
    },
    fileUploadStart:function(queueID) {
    $(this).each(function() {
    document.getElementById($(this).attr('id') + 'Uploader').startFileUpload(queueID, false);
    });
    },
    fileUploadCancel:function(queueID) {
    $(this).each(function() {
    document.getElementById($(this).attr('id') + 'Uploader').cancelFileUpload(queueID);
    });
    },
    fileUploadClearQueue:function() {
    $(this).each(function() {
    document.getElementById($(this).attr('id') + 'Uploader').clearFileUploadQueue();
    });
    }
    })
    })(jQuery);
  • I agree with Barbossa. With just a few strings that require translation, it would be easiest to include a locale object as one of the settings. (I would recommend against the one string at a time approach, however.)
  • Has this been implemented yet... I can't see it in the docs.
  • No it hasn't been.