Upload component with single send button?

Upload-component adds 3 components by default: textfield, browse-button and send-button.
How do I use it if I want just “send” button which would open file-browser and send selected file directly?

The three components are sort of required by the browser - one input type=“upload” (the browser adds textfield and ‘browse’ button, nothing you can do about that :-\ ), and one button to submit the form (the only way to get the browser to upload the file w/o using plugins).

However, there are ways to make it look different - below is one method that seems to work (very quickly tested), although I’d say it’s not very robust; the idea is to make the browser upload invisible and place your own (fake) button under that. Since different browsers draw the upload component differently, you might have to make some changes for different browsers. More info about this method can be found at quirksmode.org, I think.

Ok, so here we go - add the code below to your theme (remember to register the ‘render function’ as well:

renderUpload : function(renderer,uidl,target,layoutInfo) {

	var theme = renderer.theme;
	var client = renderer.client;
	var varNode = theme.getVariableElement(uidl,"uploadstream","stream");
	
	// Create containing element
	var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
	if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
	
	// Render default header
	renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);

	// Unique name for iframes
	var frameName = "upload_"+varNode.getAttribute("id")+"_iframe";
    
    var hIframeContainer = renderer.theme.createElementTo(div,"div");
    hIframeContainer.innerHTML = '<iframe style="height:0px;width:0px;0;margin:0;padding:0;border:0;" name="'+frameName+'"></iframe>'

    iframe = hIframeContainer.firstChild;
    ifr = iframe.contentWindow;

    // Ok. Now we are ready render the actual upload form and 
    // inputs.
    var formContainer = renderer.theme.createElementTo(div,"div");
    formContainer.innerHTML = 
    '<form action="'+client.ajaxAdapterServletUrl +
    '" method="post" enctype="multipart/form-data" target="'+frameName+'">'+
    '<input style="z-index:9;" type="button" value="Send" />' +
    '<input style="margin-left:-170px;opacity:0;filter:Alpha(opacity=0);fontSize:13px;z-index:10;" type="file" name="'+varNode.getAttribute("id")+'" />'+
    '</form>'
    ;
    
    var form = formContainer.firstChild;
    form.onsubmit = function() {
        iframe.submitted = true;
    };
	form.childNodes[1]
.onchange = function() {
		form.submit();
	}
	
    iframe.submitted = false;
	// Attach event listeners for processing the chencges after upload.
	if (document.all && !window.opera) {
		iframe.onreadystatechange = function() {
            if (iframe.submitted == true) {
                iframe.onreadystatechange = null;
                client.processVariableChanges(true);
            }
		};
	} else {
		iframe.onload = function() {
			if (iframe.submitted) {
                iframe.onload = null;
                client.processVariableChanges(true);
			}
		};
	}
},

Thinking about this a few more minutes, I think I came up with an idea on how to make it more robust, and also allow for easier styling and allowing both the traditional and this new style…
We’re going to add these changes for sure :slight_smile: