New File Uploader
I'm working on a new File Uploader if anyone would like to try it. I'll post it as a Helper for testing, but it will most likely be included by default as a replacement or enhancement to the current File field.
10 Answers
Alright, sort of complex instructions, but you'll see it's WELL worth it. MANY thanks to the team over at http://www.phpletter.com/ for developing such a great jQuery AJAX File Uploader!
Add an Input Helper to your File column:<pre><script type="text/javascript"> function ajaxFileUpload_<?php echo $name; ?>() { jQuery.ajaxFileUpload ( { url:'/wp-content/plugins/pods/ajax/doajaxfileupload.php?id=<?php echo $name; ?>_upload', secureuri:false, fileElementId:'<?php echo $name; ?>_upload', dataType: 'json', success: function (data, status) { if(typeof(data.error) != 'undefined') { if(data.error != '') { alert(data.error); }else { jQuery('input.<?php echo $name; ?>').val(data.msg); jQuery('#<?php echo $name; ?>_upload').val(''); jQuery("input.<?php echo $name; ?>").animate({marginTop:"20px"},100).animate({marginTop:"0"},100).animate({marginTop:"20px"},100).animate({marginTop:"0"},100); } } }, error: function (data, status, e) { alert(e); } } )
return false;
} </script> <input type="text" class="form file <?php echo $name; ?>" value="<?php echo $value; ?>" /> (current) <br /> <input type="file" name="<?php echo $name; ?>_upload" id="<?php echo $name; ?>_upload" value="" /> <input type="button" value="Upload file" onclick="return ajaxFileUpload_<?php echo $name; ?>();" /></pre>
- Add this script to manage_content.php or form.php in /wp-content/plugins/pods/core/ (depending on if you want to see it in Public Forms and/or WP-Admin):<pre> <script type="text/javascript" src="<?php echo $pods_url; ?>/js/ajaxfileupload.js"></script></pre>
Here's the source code for the AJAX file upload script, upload it to /wp-content/plugins/pods/js/ - from http://www.phpletter.com/Our-Projects/AjaxFileUpload/ - Thanks guys!<pre> jQuery.extend({
createUploadIframe: function(id, uri) { //create frame var frameId = 'jUploadFrame' + id;
if(window.ActiveXObject) { var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" ></iframe>'); if(typeof uri== 'boolean'){ io.src = 'javascript:false'; } else if(typeof uri== 'string'){ io.src = uri; } } else { var io = document.createElement('iframe'); io.id = frameId; io.name = frameId; } io.style.position = 'absolute'; io.style.top = '-1000px'; io.style.left = '-1000px'; document.body.appendChild(io); return io}, createUploadForm: function(id, fileElementId) { //create form
var formId = 'jUploadForm' + id; var fileId = 'jUploadFile' + id; var form = jQuery('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
var oldElement = jQuery('#' + fileElementId); var newElement = jQuery(oldElement).clone(); jQuery(oldElement).attr('id', fileId); jQuery(oldElement).before(newElement); jQuery(oldElement).appendTo(form); //set attributes jQuery(form).css('position', 'absolute'); jQuery(form).css('top', '-1200px'); jQuery(form).css('left', '-1200px'); jQuery(form).appendTo('body');
return form; },ajaxFileUpload: function(s) { // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
s = jQuery.extend({}, jQuery.ajaxSettings, s); var id = new Date().getTime()
var form = jQuery.createUploadForm(id, s.fileElementId); var io = jQuery.createUploadIframe(id, s.secureuri); var frameId = 'jUploadFrame' + id; var formId = 'jUploadForm' + id;
// Watch for a new set of requests if ( s.global && ! jQuery.active++ ) { jQuery.event.trigger( "ajaxStart" ); }
var requestDone = false; // Create the request object var xml = {}
if ( s.global ) jQuery.event.trigger("ajaxSend", [xml, s]); // Wait for a response to come back var uploadCallback = function(isTimeout) {
var io = document.getElementById(frameId); try {
if(io.contentWindow) { xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null; xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;}else if(io.contentDocument) { xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null; xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document; } }catch(e) { jQuery.handleError(s, xml, null, e); } if ( xml || isTimeout == "timeout") { requestDone = true; var status; try { status = isTimeout != "timeout" ? "success" : "error"; // Make sure that the request was successful or notmodified if ( status != "error" ) { // process the data (runs the xml through httpData regardless of callback) var data = jQuery.uploadHttpData( xml, s.dataType ); // If a local callback was specified, fire it and pass it the data if ( s.success ) s.success( data, status ); // Fire the global callback if( s.global ) jQuery.event.trigger( "ajaxSuccess", [xml, s] ); } else jQuery.handleError(s, xml, status); } catch(e) { status = "error"; jQuery.handleError(s, xml, status, e); } // The request was completed if( s.global ) jQuery.event.trigger( "ajaxComplete", [xml, s] ); // Handle the global AJAX counter if ( s.global && ! --jQuery.active ) jQuery.event.trigger( "ajaxStop" ); // Process result if ( s.complete ) s.complete(xml, status); jQuery(io).unbind() setTimeout(function() { try { jQuery(io).remove(); jQuery(form).remove(); } catch(e) { jQuery.handleError(s, xml, null, e); } }, 100) xml = null } } // Timeout checker if ( s.timeout > 0 ) { setTimeout(function(){ // Check to see if the request is still happening if( !requestDone ) uploadCallback( "timeout" ); }, s.timeout); } try { // var io = jQuery('#' + frameId); var form = jQuery('#' + formId); jQuery(form).attr('action', s.url); jQuery(form).attr('method', 'POST'); jQuery(form).attr('target', frameId); if(form.encoding) { form.encoding = 'multipart/form-data'; } else { form.enctype = 'multipart/form-data'; } jQuery(form).submit(); } catch(e) { jQuery.handleError(s, xml, null, e); } if(window.attachEvent){ document.getElementById(frameId).attachEvent('onload', uploadCallback); } else{ document.getElementById(frameId).addEventListener('load', uploadCallback, false); } return {abort: function () {}};},
uploadHttpData: function( r, type ) { var data = !type; data = type == "xml" || data ? r.responseXML : r.responseText; // If the type is "script", eval it in global context if ( type == "script" ) jQuery.globalEval( data ); // Get the JavaScript object, if JSON is used. if ( type == "json" ) eval( "data = " + data ); // evaluate scripts within html if ( type == "html" ) jQuery("<div>").html(data).evalScripts(); //alert(jQuery('param', data).each(function(){alert(jQuery(this).attr('value'));})); return data; } })</pre>
- Create a new file using this code and upload it to /wp-content/plugins/pods/ajax/doajaxfileupload.php:<pre><?php include(realpath('../../../../wp-config.php')); if (!current_user_can('upload_files')) wp_die(__('You do not have permission to upload files.')); if (!isset($_GET['id'])) wp_die(__('No file ID given.'));
include_once realpath("../../../../wp-admin/includes/file.php"); $_POST['action'] = 'wp_handle_upload'; $fileElementName = $_GET['id']; $error = ""; $msg = ""; $info = wp_handle_upload($_FILES[$fileElementName]); if(isset($info['error'])){$error = $info['error'];} else{$msg = str_replace(get_bloginfo('url'),'',$info['url']);} echo "{"; echo "error: '" . $error . "',"; echo "msg: '" . $msg . "'"; echo "}"; ?></pre> Let me know if you have any questions! Looking forward to adding this to a future Pods release!
Could you send me an e-mail with access to your WP installation, as well as how you receive the error (what steps do you do that returns this error)?
sc0ttkclark (at) gmail . com
I'm also getting an error when clicking upload: SyntaxError: Parse error
I'm going to try to figure out what's going on here, but could you send access to your WP installation to my e-mail?
sc0ttkclark (at) gmail . com
@casey - Could you send access to your WP installation to us at pods (at) uproot . us and we'll take a look and see what's causing this.
Could you also provide which Browser / Browser version you are using so we can test that for the error?
This specific file uploader is for files, not images. I'm working on a separate image uploader that integrates with the Media Library a bit more.
The scary shaking thing is just something I added, not necessarily going to be on the final version released to everyone else. I believe we'll be creating a new column type specifically for Images (with an image preview).
Anyways, lots of great things coming, thanks for the feedback!
I see what you mean, we'll be thinking this out more and getting a better picture once we reach that point, but WP 2.9 is supposed to introduce tons of Media stuff that should make it possible for closer integration between Pods and the Media Library.
Integrating with WordPress as seamlessly as possible, is one of our goals in the upcoming months. Eventually we'd like to flesh out a new UI that looks like WP itself.
Also, regarding the Pods menu showing up, we'll be releasing a fix for this in an upcoming version.
I keep getting the following error when trying to upload a JPG:
SyntaxError: missing ; before statement
This happens when I click the 'Upload file' button. Any ideas?
What about just including a standard HTML input type="file" form element that uploads the file when the 'Save changes' button is clicked?
Is there someone that could help me do this?
@casey - Improving the file picker is #3 on my list, behind the API and the "dot-traversal" feature.


