org.icefaces.ace.component.fileentry.FileEntryRenderer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icefaces-ace Show documentation
Show all versions of icefaces-ace Show documentation
${icefaces.product.name} ACE Component Library
The newest version!
/*
* Copyright 2004-2014 ICEsoft Technologies Canada Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS
* IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.icefaces.ace.component.fileentry;
import org.icefaces.ace.util.JSONBuilder;
import org.icefaces.ace.util.Utils;
import org.icefaces.render.MandatoryResourceComponent;
import org.icefaces.util.EnvUtils;
import javax.faces.FacesException;
import javax.faces.render.Renderer;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.component.UIComponent;
import java.io.IOException;
import java.util.logging.Logger;
import java.util.Locale;
import java.util.ResourceBundle;
@MandatoryResourceComponent(tagName="fileEntry", value="org.icefaces.ace.component.fileentry.FileEntry")
public class FileEntryRenderer extends Renderer {
private static final Logger log = Logger.getLogger(FileEntry.class.getName());
private static final String ACE_MESSAGES_BUNDLE = "org.icefaces.ace.resources.messages";
private static final String MESSAGE_KEY_PREFIX = "org.icefaces.ace.component.fileEntry.";
@Override
public void encodeBegin(FacesContext facesContext, UIComponent uiComponent)
throws IOException {
UIComponent form = Utils.findParentForm(uiComponent);
if (form == null) {
throw new FacesException("FileEntry component must be contained in a form.");
}
FileEntry fileEntry = (FileEntry) uiComponent;
String clientId = uiComponent.getClientId(facesContext);
log.finer("FileEntryRenderer.encode clientId: " + clientId);
ResponseWriter writer = facesContext.getResponseWriter();
writer.startElement("div", uiComponent);
writer.writeAttribute("id", clientId + "_container", "clientId");
renderResetSettings(facesContext, uiComponent);
boolean disabled = fileEntry.isDisabled();
boolean multiple = fileEntry.isMultiple();
boolean autoUpload = fileEntry.isAutoUpload();
/* Ideally we'd add these styles, but Firefox makes the Browse button flow outside
* of the widget bordering.
* ui-widget ui-widget-content ui-corner-all
*/
Utils.writeConcatenatedStyleClasses(writer, "ice-file-entry",
fileEntry.getStyleClass());
writer.writeAttribute("style", fileEntry.getStyle(), "style");
writer.startElement("div", null);
// If multiple then render the buttons for [+]Add Files [^]Upload [x]Delete
// And render the hidden input type=file behind the AddFiles button
/*
*/
Locale locale;
ClassLoader classLoader;
ResourceBundle bundle = null;
if (multiple) {
locale = facesContext.getViewRoot().getLocale();
classLoader = Thread.currentThread().getContextClassLoader();
String bundleName = facesContext.getApplication().getMessageBundle();
if (classLoader == null) classLoader = bundleName.getClass().getClassLoader();
if (bundleName == null) bundleName = ACE_MESSAGES_BUNDLE;
bundle = ResourceBundle.getBundle(bundleName, locale, classLoader);
writer.writeAttribute("class", "buttonbar", "styleClass");
writer.startElement("div", null);
writer.writeAttribute("class", "buttons", "styleClass");
// Add files button (CSS classes are added dynamically in the client)
writer.startElement("span", uiComponent);
writer.writeAttribute("role", "button", null);
writer.writeAttribute("aria-disabled", disabled ? "true" : "false", "disbled");
// +
writer.startElement("span", null);
writer.writeAttribute("class", "ui-button-icon-primary ui-icon ui-icon-plusthick", "styleClass");
writer.writeAttribute("style", "display:none;", null);
writer.endElement("span");
writer.startElement("span", null);
writer.writeAttribute("class", "ui-button-text", "styleClass");
writer.writeAttribute("style", "display:none;", null);
// "Add files"
writer.startElement("span", null);
writer.writeText(bundle.getString(MESSAGE_KEY_PREFIX + "ADD_FILES"), uiComponent, null);
writer.endElement("span");
writer.endElement("span"); // ui-button-text
// goes here
}
writer.startElement("input", null);
writer.writeAttribute("type", "file", "type");
Object accesskey = uiComponent.getAttributes().get("accesskey");
if (accesskey != null) {
writer.writeAttribute("accesskey", accesskey, null);
}
String identifier = fileEntry.getClientId(facesContext);
writer.writeAttribute("id", identifier, "clientId");
writer.writeAttribute("name", identifier, "clientId");
if (!multiple) {
writer.writeAttribute("onkeydown", "ice.ace.fileentry.clearSelectionOnKeyDown(event, this);", null);
}
if (multiple) {
writer.writeAttribute("multiple", "multiple", "multiple");
if (accesskey != null) {
writer.writeAttribute("onfocus", "this.parentNode.className += ' ui-state-hover';", null);
writer.writeAttribute("onblur", "this.parentNode.className = this.parentNode.className.replace( /(?:^|\\s)ui-state-hover(?!\\S)/g, '');", null);
}
}
if (disabled) {
writer.writeAttribute("disabled", "true", "disabled");
}
boolean ariaEnabled = EnvUtils.isAriaEnabled(facesContext);
Integer tabindex = fileEntry.getTabindex();
if (ariaEnabled && tabindex == null) tabindex = 0;
if (tabindex != null) {
writer.writeAttribute("tabindex", tabindex, "tabindex");
}
int size = fileEntry.getSize();
if (size > 0) {
writer.writeAttribute("size", size, "size");
}
if (multiple || autoUpload) {
String onchange = JSONBuilder.create().
beginFunction("ice.ace.fileentry.onchange").
item("event", false).
item(clientId).
item(multiple).
item(autoUpload).
endFunction().toString();
String validateType = "";
String acceptType = fileEntry.getAcceptType();
locale = facesContext.getViewRoot().getLocale();
classLoader = Thread.currentThread().getContextClassLoader();
String bundleName = facesContext.getApplication().getMessageBundle();
if (classLoader == null) classLoader = bundleName.getClass().getClassLoader();
if (bundleName == null) bundleName = ACE_MESSAGES_BUNDLE;
bundle = ResourceBundle.getBundle(bundleName, locale, classLoader);
if (acceptType != null && !"".equals(acceptType)) {
validateType = "var valid = ice.ace.fileentry.validateType(this.id, '" + acceptType + "', "
+"'" + bundle.getString(MESSAGE_KEY_PREFIX + "INVALID_FILE_TYPE") + "'); if (valid) ";
}
writer.writeAttribute("onchange", validateType + onchange, null);
} else {
String validateType = "";
String acceptType = fileEntry.getAcceptType();
locale = facesContext.getViewRoot().getLocale();
classLoader = Thread.currentThread().getContextClassLoader();
String bundleName = facesContext.getApplication().getMessageBundle();
if (classLoader == null) classLoader = bundleName.getClass().getClassLoader();
if (bundleName == null) bundleName = ACE_MESSAGES_BUNDLE;
bundle = ResourceBundle.getBundle(bundleName, locale, classLoader);
if (acceptType != null && !"".equals(acceptType)) {
validateType = "var valid = ice.ace.fileentry.validateType(this.id, '" + acceptType + "', "
+"'" + bundle.getString(MESSAGE_KEY_PREFIX + "INVALID_FILE_TYPE") + "'); if (valid) ";
}
writer.writeAttribute("onchange", validateType + "this.parentNode.setAttribute('title', this.value);", null);
}
writer.endElement("input");
if (multiple) {
writer.endElement("span"); // add-files ...
writeMultipleButton(writer, uiComponent, disabled, bundle.getString(MESSAGE_KEY_PREFIX + "START_UPLOAD"),
"submit", "start", "ui-icon-circle-arrow-e", clientId+"_start");
writeMultipleButton(writer, uiComponent, disabled, bundle.getString(MESSAGE_KEY_PREFIX + "CANCEL_UPLOAD"),
"button", "cancel", "ui-icon-cancel", clientId+"_cancel");
/*
writeMultipleButton(writer, uiComponent, disabled, "Remove file(s)",
"button", "delete", "ui-icon-trash", clientId+"_delete");
writer.startElement("input", uiComponent);
writer.writeAttribute("type", "checkbox", null);
writer.writeAttribute("class", "toggle", null);
if (disabled) {
writer.writeAttribute("disabled", "disabled", null);
}
writer.endElement("input");
writer.startElement("span", uiComponent);
writer.writeAttribute("class", "fileupload-loading", null);
writer.endElement("span");
*/
writer.endElement("div"); // buttons
}
writer.endElement("div");
writer.startElement("div", null);
writer.writeAttribute("class", "inactive", null);
writer.startElement("div", null);
writer.writeAttribute("class", "ui-progressbar ui-widget ui-widget-content ui-corner-all", null);
writer.startElement("div", null);
writer.writeAttribute("class", "ui-progressbar-value ui-widget-header ui-corner-left ui-corner-right", null);
writer.endElement("div");
writer.endElement("div");
writer.endElement("div");
if (multiple) {
writer.startElement("div", null);
writer.writeAttribute("id", clientId + "_multSel", "clientId");
writer.startElement("table", null);
writer.writeAttribute("class", "multiple-select-table", null);
writer.writeAttribute("id", clientId + "_multSelTbl", "clientId");
writer.endElement("table");
writer.endElement("div");
String formId = form.getClientId(facesContext);
writer.startElement("script", null);
writer.writeAttribute("type", "text/javascript", null);
writer.writeText("ice.ace.fileentry.addButtons('" + formId + "');", uiComponent, null);
writer.endElement("script");
}
writer.endElement("div");
}
protected void writeMultipleButton(ResponseWriter writer,
UIComponent uiComponent, boolean disabled, String label,
String buttonType, String buttonClass, String iconClass, String id)
throws IOException {
writer.startElement("button", null);
writer.writeAttribute("id", id, null);
writer.writeAttribute("class", buttonClass + " ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-primary", null);
writer.writeAttribute("type", buttonType, null);
writer.writeAttribute("style", "display:none;", null);
writer.writeAttribute("role", "button", null);
writer.writeAttribute("aria-disabled", disabled ? "true" : "false", null);
if (disabled) {
writer.writeAttribute("disabled", "disabled", null);
}
if (id.endsWith("_cancel")) {
writer.writeAttribute("onclick", "ice.ace.fileentry.clearFileSelection('" + id.substring(0,id.length()-7) + "');return false;", null);
}
writer.startElement("span", null);
writer.writeAttribute("class", "ui-button-icon-primary ui-icon " + iconClass, null);
writer.endElement("span");
writer.startElement("span", null);
writer.writeAttribute("class", "ui-button-text", null);
writer.writeText(label, uiComponent, null);
writer.endElement("span");
writer.endElement("button");
}
@Override
public void decode(FacesContext facesContext, UIComponent uiComponent) {
FileEntry fileEntry = (FileEntry) uiComponent;
String clientId = uiComponent.getClientId(facesContext);
log.finer("FileEntryRenderer.decode clientId: " + clientId);
FileEntryResults results = FileEntry.retrieveResultsFromEarlierInLifecycle(facesContext, clientId);
// If no new files have been uploaded, leave the old upload results in-place.
if (results != null || fileEntry.isRequired()) {
log.finer(
"FileEntryRenderer.decode\n" +
" results ve: " + uiComponent.getValueExpression("results") + "\n" +
" results : " + results);
fileEntry.setResults(results);
}
boolean filesUploadedThisLifecycle = (results != null);
FileEntryEvent event = new FileEntryEvent(
fileEntry, filesUploadedThisLifecycle);
fileEntry.queueEvent(event);
}
protected void renderResetSettings(FacesContext context, UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
FileEntry fileEntry = (FileEntry) component;
String clientId = component.getClientId(context);
JSONBuilder jb = JSONBuilder.create();
jb.beginArray();
jb.item("fileentry");
jb.beginArray();
jb.item(clientId);
jb.item(fileEntry.isMultiple());
jb.endArray();
jb.endArray();
writer.writeAttribute("data-ice-reset", jb.toString(), null);
}
}