diff --git a/pom.xml b/pom.xml index a73152a..fc5c9a0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ co.cfly jsf-components jar - 6.0.10 + 6.0.11-SNAPSHOT JSF Components diff --git a/src/main/java/co/cfly/faces/components/PopoverContainerComponent.java b/src/main/java/co/cfly/faces/components/PopoverContainerComponent.java new file mode 100644 index 0000000..461cb97 --- /dev/null +++ b/src/main/java/co/cfly/faces/components/PopoverContainerComponent.java @@ -0,0 +1,75 @@ +package co.cfly.faces.components; + +import java.io.IOException; + +import co.cfly.faces.utils.RendererTools; +import jakarta.faces.component.FacesComponent; +import jakarta.faces.component.UIComponent; +import jakarta.faces.context.FacesContext; +import jakarta.faces.context.ResponseWriter; + +@FacesComponent(value = "co.cfly.faces.components.PopoverContainerComponent", namespace = Families.NAMESPACE) +public class PopoverContainerComponent extends ComponentBase { + + @Override + public String getFamily() { + return Families.OUTPUT_COMPONENT_FAMILY; + } + + @Override + public boolean getRendersChildren() { + return true; + } + + @Override + public void encodeBegin(FacesContext context) throws IOException { + final ResponseWriter writer = context.getResponseWriter(); + writer.startElement("span", this); + writeId(context); + + String styleClass = (String) getAttributes().getOrDefault("styleClass", ""); + String styleClassValue = RendererTools.spaceSeperateStrings("inline-edit popover-source", styleClass); + writeAttribute("class", styleClassValue, context); + + writeAttributeIfExists("style", "style", context); + writeStandardAttributes(context); + + // Popover attributes for JS initialization + writeAttribute("data-bs-dual-toggle", "popover", context); + writeAttributeIfExistsOrDefault("title", "data-bs-title", "test title", context); + writeAttribute("data-bs-placement", "bottom", context); + writeAttribute("data-bs-html", "true", context); + writeAttribute("data-bs-delay", "{\"show\":500,\"hide\":5000}", context); + writeAttribute("data-bs-container", "false", context); + + // Write label text + String label = (String) getAttributes().getOrDefault("label", "test label"); + writer.writeText(label, "label"); + + // Render children in a hidden template for popover content + writer.startElement("template", this); + writer.writeAttribute("id", getClientId(context) + "_popoverContent", null); + for (UIComponent child : getChildren()) { + child.encodeAll(context); + } + writer.endElement("template"); + + // Reference the template in the popover content attribute + writeAttribute("data-bs-content", "document.getElementById('" + getClientId(context) + "_popoverContent').innerHTML", context); + } + + @Override + public void encodeChildren(FacesContext context) { + // Since Children are rendered manually in the encodeBegin we don't want to render them twice + } + + + @Override + public void encodeEnd(FacesContext context) throws IOException { + final boolean editable = getAttribute("editable", true); + final ResponseWriter writer = context.getResponseWriter(); + if (editable) { + writer.endElement("span"); + } + } +} diff --git a/src/main/resources/META-INF/faces.taglib.xml b/src/main/resources/META-INF/faces.taglib.xml index d84afbd..0467c16 100644 --- a/src/main/resources/META-INF/faces.taglib.xml +++ b/src/main/resources/META-INF/faces.taglib.xml @@ -585,4 +585,28 @@ boolean + + popoverContainer + + co.cfly.faces.components.PopoverContainerComponent + + + CSS Style + style + java.lang.String + + + CSS Style Classes + styleClass + java.lang.String + + + label + java.lang.String + + + title + java.lang.String + +