Source:
<code>public void doRender(final WComponent component, final WebXmlRenderContext renderContext) { WMultiFileWidget widget = (WMultiFileWidget) component; XmlStringBuilder xml = renderContext.getWriter(); String uploadId = widget.getFileUploadRequestId(); if (uploadId != null) { handleFileUploadRequest(widget, xml, uploadId); return; } boolean readOnly = widget.isReadOnly(); xml.appendTagOpen("ui:fileupload"); xml.appendAttribute("id", component.getId()); xml.appendOptionalAttribute("class", component.getHtmlClass()); xml.appendOptionalAttribute("track", component.isTracking(), "true"); xml.appendOptionalAttribute("hidden", widget.isHidden(), "true"); if (readOnly) { xml.appendAttribute("readOnly", "true"); } else { long maxFileSize = widget.getMaxFileSize(); int maxFiles = widget.getMaxFiles(); WComponent dropzone = widget.getDropzone(); WImageEditor editor = widget.getEditor(); xml.appendOptionalAttribute("disabled", widget.isDisabled(), "true"); xml.appendOptionalAttribute("required", widget.isMandatory(), "true"); xml.appendOptionalAttribute("tabIndex", widget.hasTabIndex(), widget.getTabIndex()); xml.appendOptionalAttribute("toolTip", widget.getToolTip()); xml.appendOptionalAttribute("accessibleText", widget.getAccessibleText()); xml.appendOptionalAttribute("acceptedMimeTypes", typesToString(widget.getFileTypes())); xml.appendOptionalAttribute("maxFileSize", maxFileSize > 0, maxFileSize); xml.appendOptionalAttribute("maxFiles", maxFiles > 0, maxFiles); if (dropzone != null) { xml.appendAttribute("dropzone", dropzone.getId()); } if (editor != null) { xml.appendAttribute("editor", editor.getId()); if (editor.getUseCamera()) { xml.appendAttribute("camera", true); } } <START> if (widget.getFileAjaxAction() != null) { <END> xml.appendAttribute("ajax", "true"); } } if (widget.getColumns() != null) { xml.appendAttribute("cols", widget.getColumns()); } if (widget.getFiles().isEmpty()) { xml.appendEnd(); } else { xml.appendClose(); int i = 0; for (FileWidgetUpload file : widget.getFiles()) { FileWidgetRendererUtil.renderFileElement(widget, xml, file, i++); } xml.appendEndTag("ui:fileupload"); } }</code><technical_language>need check if AJAX honored in Readonly</technical_language>

Target:
public void doRender(final WComponent component, final WebXmlRenderContext renderContext) { WMultiFileWidget widget = (WMultiFileWidget) component; XmlStringBuilder xml = renderContext.getWriter(); String uploadId = widget.getFileUploadRequestId(); if (uploadId != null) { handleFileUploadRequest(widget, xml, uploadId); return; } boolean readOnly = widget.isReadOnly(); xml.appendTagOpen("ui:fileupload"); xml.appendAttribute("id", component.getId()); xml.appendOptionalAttribute("class", component.getHtmlClass()); xml.appendOptionalAttribute("track", component.isTracking(), "true"); xml.appendOptionalAttribute("hidden", widget.isHidden(), "true"); if (readOnly) { xml.appendAttribute("readOnly", "true"); } else { long maxFileSize = widget.getMaxFileSize(); int maxFiles = widget.getMaxFiles(); WComponent dropzone = widget.getDropzone(); WImageEditor editor = widget.getEditor(); xml.appendOptionalAttribute("disabled", widget.isDisabled(), "true"); xml.appendOptionalAttribute("required", widget.isMandatory(), "true"); xml.appendOptionalAttribute("tabIndex", widget.hasTabIndex(), widget.getTabIndex()); xml.appendOptionalAttribute("toolTip", widget.getToolTip()); xml.appendOptionalAttribute("accessibleText", widget.getAccessibleText()); xml.appendOptionalAttribute("acceptedMimeTypes", typesToString(widget.getFileTypes())); xml.appendOptionalAttribute("maxFileSize", maxFileSize > 0, maxFileSize); xml.appendOptionalAttribute("maxFiles", maxFiles > 0, maxFiles); if (dropzone != null) { xml.appendAttribute("dropzone", dropzone.getId()); } if (editor != null) { xml.appendAttribute("editor", editor.getId()); if (editor.getUseCamera()) { xml.appendAttribute("camera", true); } } } if (widget.getColumns() != null) { xml.appendAttribute("cols", widget.getColumns()); } if (widget.getFileAjaxAction() != null) { xml.appendAttribute("ajax", "true"); } if (widget.getFiles().isEmpty()) { xml.appendEnd(); } else { xml.appendClose(); int i = 0; for (FileWidgetUpload file : widget.getFiles()) { FileWidgetRendererUtil.renderFileElement(widget, xml, file, i++); } xml.appendEndTag("ui:fileupload"); } }