如何为JSF自定义组件动态生成CSS

 未知的明天 发布于 2023-02-13 14:24

我正在开发一个执行"响应式"多列显示的JSF自定义组件.

它使用"CSS多列布局模块"(http://www.w3.org/TR/css3-multicol/)(法语教程:http://www.alsacreations.com/tuto/lire/1557- les-multicolonnes-en-css3.html).

我实际上有以下解决方案,其工作原理:

组件类:

@Log4j
@FacesComponent(ResponsiveMultiColumnsTable.SENAT_COMPONENT_TYPE)
@ResourceDependency(library="senat",name="senat-columns.css")
public class ResponsiveMultiColumnsTable extends UIData {
    public static final String SENAT_COMPONENT_FAMILY = "fr.senat.faces.components";
    public static final String SENAT_COMPONENT_TYPE = SENAT_COMPONENT_FAMILY + ".ResponsiveMultiColumnsTable";
    public static final String DEFAULT_RENDERER = SENAT_COMPONENT_FAMILY + ".ResponsiveMultiColumnsPanelRenderer";

    private enum PropertyKeys { style, styleClass }

    public ResponsiveMultiColumnsTable() {
      setRendererType(DEFAULT_RENDERER);
    }

    @Override
    public boolean getRendersChildren()
    {
        return true;
    }

    public String getStyle() {
        return (String) getStateHelper().eval(PropertyKeys.style);
    }

    public void setStyle(String param) {
        getStateHelper().put(PropertyKeys.style, param);
    }

    public String getStyleClass() {
        return (String) getStateHelper().eval(PropertyKeys.styleClass);
    }

    public void setStyleClass(String param) {
        getStateHelper().put(PropertyKeys.styleClass, param);
    }

}

渲染器类:

@FacesRenderer(componentFamily = ResponsiveMultiColumnsTable.COMPONENT_FAMILY, rendererType = ResponsiveMultiColumnsTable.DEFAULT_RENDERER)
public class ResponsiveMultiColumnsTableRenderer extends CoreRenderer {

    @Override
    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
        ResponsiveMultiColumnsTable detail = (ResponsiveMultiColumnsTable) component;
        ResponseWriter writer = context.getResponseWriter();
        String clientId = detail.getClientId(context);
        String style = detail.getStyle();
        String styleClass = detail.getStyleClass();

        writer.startElement("div", detail);
        writer.writeAttribute("id", clientId, "id");
        String extStyleClass = "senat-details-columns";
        if (styleClass != null) {
            extStyleClass += " " + styleClass;
        }
        writer.writeAttribute("class", "senat-details-columns " + extStyleClass, "styleClass");
        if ((style != null) && !style.isEmpty()) {
            writer.writeAttribute("style", style, "style");
        }
    }

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        writer.endElement("div");
    }

    @Override
    public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        ResponsiveMultiColumnsTable grid = (ResponsiveMultiColumnsTable) component;

        int rowIndex = grid.getFirst();
        int rows = grid.getRows();
        int itemsToRender = rows != 0 ? rows : grid.getRowCount();

        for(int i = rowIndex ; i < itemsToRender ; i++) {
            grid.setRowIndex(i);
            if(!grid.isRowAvailable()) {
                break;
            }

            writer.startElement("div", null);

            renderChildren(context, grid);

            writer.endElement("div");
        }

    }
}

taglib中的组件声明:

    
    
        
    
    responsiveMultiColumnsTable
            
                fr.senat.faces.components.ResponsiveMultiColumnsTable
            

    
                Liste à afficher
                
                value
                true
                java.util.List
    
            
                Nom de la variable d'itération
                var
                true
                java.lang.String
    
    
                Élément de style à ajouter
                style
                false
                java.lang.String
    
    
                Classe à ajouter
                styleClass
                false
                java.lang.String
    

样式表:

.senat-details-columns {
    -webkit-columns: 3;
    -moz-columns: 3;
    columns: 3;
}

@media (max-width: 1024px) {
    .senat-details-columns {
        -webkit-columns: 2;
        -moz-columns: 2;
        columns: 2;
    }
}

@media (max-width: 640px) {
    .senat-details-columns {
        -webkit-columns: 1;
        -moz-columns: 1;
        columns: 1;
    }
}

我希望能够指出数据,例如哪个列数用于哪个分辨率.一种方法是动态生成样式表片段然后包含它.

基本动态样式表如下所示:

.#{dynamic-style} {
    -webkit-columns: #{max-col-count};
    -moz-columns: #{max-col-count};
    columns: #{max-col-count};
}

@media (max-width: #{max-middle-res}px) {
    .#{dynamic-style} {
        -webkit-columns: #{middle-col-count};
        -moz-columns: #{middle-col-count};
        columns: #{middle-col-count};
    }
}

@media (max-width: #{max-min-res}px) {
    .#{dynamic-style} {
        -webkit-columns: #{min-col-count};
        -moz-columns: #{middle-col-count};
        columns: #{middle-col-count};
    }
}

如何动态处理并包含它?

我看到的问题是我可以使用不同参数的相同样式表进行多次使用.如果只有一个用途,只需在样式表中包含EL表达式即可完成工作.

另一种解决方案是在组件之前添加样式,但对我来说似乎有点难看.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有