我也有类似的要求,我得到了这个 SO,我很惊讶地发现即使在 3 年后也没有接受的答案!
Primefaces(6.0 版)仍然没有这个功能。我希望它会在下一个版本中添加。
经过一番搜索后,我终于创建了一个自定义复合组件。
这是我拥有的解决方案/解决方法。优雅与否,我把它留给你:)。
顺便说一句,这适用于 JSF 2.2。对于旧版本的 JSF,您可能需要添加更多文件才能使复合组件正常工作。(taglibs 等)。
首先,我们必须为评级创建我们自己的复合组件(别担心,它只有两个文件)。它只不过是p:rating
和p:tooltip
结合在一起。以下是两个文件:
- ratingComposite.xhtml
- ratingComposite.js
将这两个文件添加到项目的 JSF 资源文件夹中。(注:customizedprimefaces 是你的资源库名称)
<YourWarFile>\resources\customizedprimefaces\ratingComposite.xhtml
<YourWarFile>\resources\js\ratingComposite.js
(如果你不熟悉复合组件及其路径,那么我建议先学习它,在 JSF 2.2 中很容易。)
并开始在您的页面中使用它。
我的页面.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"*
xmlns:cp="http://java.sun.com/jsf/composite/customizedprimefaces"
>
...
<cp:ratingComposite id="ratingId" widgetVar="ratingIdWgt"
stars="4"
value="#{bean.rating}"
tooltipValue="Ugly | Bad | OK | Good"
/>
(注意 xmlns 包括xmlns:cp="http://java.sun.com/jsf/composite/customizedprimefaces"
:)
这与p:rating
组件相同,唯一的区别是tooltipValue属性,该属性接受管道分隔的工具提示消息,其顺序与评级中的星星相对应。
这是对javascript文件中发生的事情的粗略解释:
- 通过管道(|)拆分
p:tooltip
元素值并保存在一个数组(tooltipTxt)中,该数组保存
<cp:ratingComposite/>
页面中每个管道分隔的工具提示。该数组由评级组件 ID 索引。
- 为评级组件中的每个星绑定自定义hoverIn和hoverOut事件处理程序。
- 在hoverIn 上,从数组(tooltipTxt)(在与当前悬停的星对应的索引处)获取消息并替换为
<p:tooltip>
消息。在当前悬停的星星的位置显示<p:tooltip>
消息。
- 在hoverOut 上,只需隐藏
<p:tooltip>
消息。
ratingComposite.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="id" />
<composite:attribute name="value" />
<composite:attribute name="readonly" />
<composite:attribute name="widgetVar" />
<composite:attribute name="stars" type="java.lang.Integer" />
<composite:attribute name="tooltipValue"
shortDescription="A pipe(ie.:|) seperated list of tooltip messages. \nEach message in list corresponds to a star in the rating componant." />
<!-- Add other attributes of p:rating component here. -->
</composite:interface>
<composite:implementation>
<h:outputScript name="js/ratingComposite.js" target="head" />
<script type="text/javascript">
<!--
$(document).ready(function(){
rating.init('#{cc.namingContainer.clientId}:_#{cc.attrs.id}', '#{cc.namingContainer.clientId}:_#{cc.attrs.id}-ttId');
});
//-->
</script>
<p:rating id="_#{cc.attrs.id}" widgetVar="#{cc.attrs.widgetVar}"
readonly="#{cc.attrs.readonly}"
value="#{cc.attrs.value}" stars="#{cc.attrs.stars}" />
<p:tooltip id="_#{cc.attrs.id}-ttId" for="_#{cc.attrs.id}" trackMouse="true"
value="#{cc.attrs.tooltipValue}" />
</composite:implementation>
</html>
ratingComposite.js
rating = {
tooltipTxt:{},
init:function(ratingId, tooltipId){
var ratingIdjq = PrimeFaces.escapeClientId(ratingId);
var tooltipIdjq = PrimeFaces.escapeClientId(tooltipId);
var _self = this;
this.tooltipTxt[tooltipId] = $(tooltipIdjq).find(".ui-tooltip-text").html(),
$(ratingIdjq).find(".ui-rating-star").each(function(){
$(this).hover(function(event){return _self.hoverIn(event,tooltipId)},
function(event){$(tooltipIdjq).hide();} //This is on Hoverout
);
});
},
hoverIn:function(event, tooltipId){
var tooltipIdjq = PrimeFaces.escapeClientId(tooltipId);
var ratingArray = this.tooltipTxt[tooltipId].split("|");
var tooptipDiv = $(tooltipIdjq);
tooptipDiv.show();
this.setCoordinate(tooptipDiv, event.pageX, event.pageY);
var currEleIndx = $(event.currentTarget).parent().find(".ui-rating-star").index(event.currentTarget);
var currTooltip = ratingArray[currEleIndx].trim();
tooptipDiv.find(".ui-tooltip-text").html(currTooltip);
},
setCoordinate:function(tooptipDiv, x, y){
var pos = {"left":x, "top":y};
tooptipDiv.offset(pos);
}
}
我希望这有帮助。