带有工具提示的无线电组无法正常工作
radiogroup with tooltip not working properly
我和前面一个问题的情况一样:
但是这次只能从相同的数据中 selected 1 个值,所以我想使用单选而不是复选框。
值来自 viewScope 选择的重复
<xp:repeat id="repeat4" rows="100" value="#{viewScope.choices}"
indexVar="rownumber" var="row" first="0">
<xp:radio id="radio1" groupName="selection">
<xp:this.text><![CDATA[#{javascript:row[3]}]]></xp:this.text>
<xp:this.value><![CDATA[#{viewScope.selected[rownumber]}]]></xp:this.value>
</xp:radio>
<xe:tooltip id="tooltip3" for="radio1">
<xe:this.label><![CDATA[#{javascript:return viewScope.choices[rownumber].get(3)}]]></xe:this.label>
</xe:tooltip>
</xp:repeat>
工具提示似乎是正确的,但是:
1) 如果需要,我可以 select 所有单选框,而不是只有一个
2) 数据似乎没有更新(所以我不知道哪个盒子被 selected)
问题 1:
更新:
您必须为重复控件的每一行计算一个唯一的组名。
您必须为所有单选按钮计算一个公共 groupName
。
问题来了,每个 xp:radio
控件都会用自己的组名渲染,让我们看看渲染后的 html 代码:
一种可能的解决方法是使用本机 html:
<input id="radio1" type="radio" name="selection" value="#{viewScope.selected[rownumber]}">
</input>
如果您需要 xp:radio
按钮核心控件的全部功能,那么另一种选择是在渲染后重命名 xp:radio
按钮的 name
属性 (例如,客户端 javascript).
问题 2:
我为此使用了 valueChangeListener
。
示例(来自我自己的项目):
XPage:
<xp:repeat var="entry" rows="30" value="#{accessBean.entries}" removeRepeat="true" repeatControls="false">
<xp:radio id="rbReadAccess" rendered="#{javascript:docData.isEditable()}"
title="Set read access" value="#{entry.accessLevelAsString}" selectedValue="READACCESS"
groupName="#{entry.name}" valueChangeListener="#{accessBean.accessLevelChanged}">
<xp:eventHandler event="onchange" submit="true" refreshMode="partial"
refreshId="pnlAccessControl">
</xp:eventHandler>
</xp:radio>
<xp:radio id="rbEditAccess" rendered="#{javascript:docData.isEditable()}"
title="Set edit access" value="#{entry.accessLevelAsString}" selectedValue="EDITACCESS"
groupName="#{entry.name}" valueChangeListener="#{accessBean.accessLevelChanged}">
<xp:eventHandler event="onchange" submit="true" refreshMode="partial"
refreshId="pnlAccessControl">
</xp:eventHandler>
</xp:radio>
<xp:radio id="rbFullAccess" rendered="#{javascript:docData.isEditable()}"
title="Set full access" value="#{entry.accessLevelAsString}" selectedValue="FULLACCESS"
groupName="#{entry.name}" valueChangeListener="#{accessBean.accessLevelChanged}">
<xp:eventHandler event="onchange" submit="true" refreshMode="partial"
refreshId="pnlAccessControl">
</xp:eventHandler>
</xp:radio>
</xp:repeat>
AccessControlBean:
public class AccessControlBean implements Serializable {
public Set<AccessControlEntry> getEntries() {
Set<AccessControlEntry> entries = new TreeSet<AccessControlEntry>(accessControlUserService.getEntries());
entries.addAll(accessControlGroupService.getEntries());
return entries;
}
public void accessLevelChanged(ValueChangeEvent valueChangeEvent) {
XspInputRadio component = (XspInputRadio) valueChangeEvent.getComponent();
System.out.println("phaseId: " + valueChangeEvent.getPhaseId());
System.out.println("accessLevelChanged");
System.out.println(component.getGroupName());
System.out.println("oldValue: " + valueChangeEvent.getOldValue());
System.out.println("newValue: " + valueChangeEvent.getNewValue());
}
}
访问控制条目:
public class AccessControlEntry implements Comparable<AccessControlEntry> {
// Enumerations
public static enum AccessLevel {
READACCESS,
EDITACCESS,
FULLACCESS;
}
// Fields
private String name;
private AccessLevel accessLevel;
private boolean accessLevelRestricted = false;
// Constructors
public AccessControlEntry(String name, AccessLevel accessLevel) {
this.name = name;
this.accessLevel = accessLevel;
}
// Getter & Setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public AccessLevel getAccessLevel() {
return accessLevel;
}
public void setAccessLevel(AccessLevel accessLevel) {
this.accessLevel = accessLevel;
}
// nessecary for EL (managed bean)
public String getAccessLevelAsString() {
return accessLevel.toString();
}
// nessecary for EL (managed bean)
public void setAccessLevelAsString(String accessLevel) {
this.accessLevel = AccessLevel.valueOf(accessLevel.toUpperCase());
}
// Operations
public boolean isReadAccess() {
return accessLevel == AccessLevel.READACCESS;
}
public void setEditAccess(boolean editAccessRestricted) {
accessLevel = AccessLevel.EDITACCESS;
accessLevelRestricted = editAccessRestricted;
}
public boolean isEditAccess() {
return accessLevel == AccessLevel.EDITACCESS;
}
public boolean isEditAccessRestricted() {
return isEditAccess() && accessLevelRestricted;
}
public void setFullAccess(boolean fullAccessRestricted) {
accessLevel = AccessLevel.FULLACCESS;
accessLevelRestricted = fullAccessRestricted;
}
public boolean isFullAccess() {
return accessLevel == AccessLevel.FULLACCESS;
}
public boolean isFullAccessRestricted() {
return isFullAccess() && accessLevelRestricted;
}
public int compareTo(AccessControlEntry aControlEntry) {
return getName().compareTo(aControlEntry.getName());
}
@Override
public String toString() {
return getClass().getSimpleName() + ": name=\"" + name +
"\", accessLevel=\"" + accessLevel +
"\", isEditAccessRestricted=\"" + isEditAccessRestricted() +
"\", isFullAccessRestricted=\"" + isFullAccessRestricted() + "\"";
}
}
您可以使用广播组吗?
<xp:radioGroup id="radioGroup1"></xp:radioGroup>
将此 onClientLoad CSJS 代码添加到您的 XPage:
<xp:eventHandler
event="onClientLoad"
submit="false">
<xp:this.script><![CDATA[
dojo.query("input").forEach(function(node){
var attr = node.getAttributeNode("name");
if (attr.value.indexOf(':selection') >= 0) {
attr.value = 'selection';
}
});
]]></xp:this.script>
</xp:eventHandler>
它 "repairs" 输入元素的 name 属性,因此它们都具有相同的名称 "selection" 而没有 "repeat"-part:
来自
到
我和前面一个问题的情况一样:
但是这次只能从相同的数据中 selected 1 个值,所以我想使用单选而不是复选框。
值来自 viewScope 选择的重复
<xp:repeat id="repeat4" rows="100" value="#{viewScope.choices}"
indexVar="rownumber" var="row" first="0">
<xp:radio id="radio1" groupName="selection">
<xp:this.text><![CDATA[#{javascript:row[3]}]]></xp:this.text>
<xp:this.value><![CDATA[#{viewScope.selected[rownumber]}]]></xp:this.value>
</xp:radio>
<xe:tooltip id="tooltip3" for="radio1">
<xe:this.label><![CDATA[#{javascript:return viewScope.choices[rownumber].get(3)}]]></xe:this.label>
</xe:tooltip>
</xp:repeat>
工具提示似乎是正确的,但是:
1) 如果需要,我可以 select 所有单选框,而不是只有一个
2) 数据似乎没有更新(所以我不知道哪个盒子被 selected)
问题 1:
更新:
您必须为重复控件的每一行计算一个唯一的组名。
您必须为所有单选按钮计算一个公共 groupName
。
问题来了,每个 xp:radio
控件都会用自己的组名渲染,让我们看看渲染后的 html 代码:
一种可能的解决方法是使用本机 html:
<input id="radio1" type="radio" name="selection" value="#{viewScope.selected[rownumber]}">
</input>
如果您需要 xp:radio
按钮核心控件的全部功能,那么另一种选择是在渲染后重命名 xp:radio
按钮的 name
属性 (例如,客户端 javascript).
问题 2:
我为此使用了 valueChangeListener
。
示例(来自我自己的项目):
XPage:
<xp:repeat var="entry" rows="30" value="#{accessBean.entries}" removeRepeat="true" repeatControls="false">
<xp:radio id="rbReadAccess" rendered="#{javascript:docData.isEditable()}"
title="Set read access" value="#{entry.accessLevelAsString}" selectedValue="READACCESS"
groupName="#{entry.name}" valueChangeListener="#{accessBean.accessLevelChanged}">
<xp:eventHandler event="onchange" submit="true" refreshMode="partial"
refreshId="pnlAccessControl">
</xp:eventHandler>
</xp:radio>
<xp:radio id="rbEditAccess" rendered="#{javascript:docData.isEditable()}"
title="Set edit access" value="#{entry.accessLevelAsString}" selectedValue="EDITACCESS"
groupName="#{entry.name}" valueChangeListener="#{accessBean.accessLevelChanged}">
<xp:eventHandler event="onchange" submit="true" refreshMode="partial"
refreshId="pnlAccessControl">
</xp:eventHandler>
</xp:radio>
<xp:radio id="rbFullAccess" rendered="#{javascript:docData.isEditable()}"
title="Set full access" value="#{entry.accessLevelAsString}" selectedValue="FULLACCESS"
groupName="#{entry.name}" valueChangeListener="#{accessBean.accessLevelChanged}">
<xp:eventHandler event="onchange" submit="true" refreshMode="partial"
refreshId="pnlAccessControl">
</xp:eventHandler>
</xp:radio>
</xp:repeat>
AccessControlBean:
public class AccessControlBean implements Serializable {
public Set<AccessControlEntry> getEntries() {
Set<AccessControlEntry> entries = new TreeSet<AccessControlEntry>(accessControlUserService.getEntries());
entries.addAll(accessControlGroupService.getEntries());
return entries;
}
public void accessLevelChanged(ValueChangeEvent valueChangeEvent) {
XspInputRadio component = (XspInputRadio) valueChangeEvent.getComponent();
System.out.println("phaseId: " + valueChangeEvent.getPhaseId());
System.out.println("accessLevelChanged");
System.out.println(component.getGroupName());
System.out.println("oldValue: " + valueChangeEvent.getOldValue());
System.out.println("newValue: " + valueChangeEvent.getNewValue());
}
}
访问控制条目:
public class AccessControlEntry implements Comparable<AccessControlEntry> {
// Enumerations
public static enum AccessLevel {
READACCESS,
EDITACCESS,
FULLACCESS;
}
// Fields
private String name;
private AccessLevel accessLevel;
private boolean accessLevelRestricted = false;
// Constructors
public AccessControlEntry(String name, AccessLevel accessLevel) {
this.name = name;
this.accessLevel = accessLevel;
}
// Getter & Setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public AccessLevel getAccessLevel() {
return accessLevel;
}
public void setAccessLevel(AccessLevel accessLevel) {
this.accessLevel = accessLevel;
}
// nessecary for EL (managed bean)
public String getAccessLevelAsString() {
return accessLevel.toString();
}
// nessecary for EL (managed bean)
public void setAccessLevelAsString(String accessLevel) {
this.accessLevel = AccessLevel.valueOf(accessLevel.toUpperCase());
}
// Operations
public boolean isReadAccess() {
return accessLevel == AccessLevel.READACCESS;
}
public void setEditAccess(boolean editAccessRestricted) {
accessLevel = AccessLevel.EDITACCESS;
accessLevelRestricted = editAccessRestricted;
}
public boolean isEditAccess() {
return accessLevel == AccessLevel.EDITACCESS;
}
public boolean isEditAccessRestricted() {
return isEditAccess() && accessLevelRestricted;
}
public void setFullAccess(boolean fullAccessRestricted) {
accessLevel = AccessLevel.FULLACCESS;
accessLevelRestricted = fullAccessRestricted;
}
public boolean isFullAccess() {
return accessLevel == AccessLevel.FULLACCESS;
}
public boolean isFullAccessRestricted() {
return isFullAccess() && accessLevelRestricted;
}
public int compareTo(AccessControlEntry aControlEntry) {
return getName().compareTo(aControlEntry.getName());
}
@Override
public String toString() {
return getClass().getSimpleName() + ": name=\"" + name +
"\", accessLevel=\"" + accessLevel +
"\", isEditAccessRestricted=\"" + isEditAccessRestricted() +
"\", isFullAccessRestricted=\"" + isFullAccessRestricted() + "\"";
}
}
您可以使用广播组吗?
<xp:radioGroup id="radioGroup1"></xp:radioGroup>
将此 onClientLoad CSJS 代码添加到您的 XPage:
<xp:eventHandler
event="onClientLoad"
submit="false">
<xp:this.script><![CDATA[
dojo.query("input").forEach(function(node){
var attr = node.getAttributeNode("name");
if (attr.value.indexOf(':selection') >= 0) {
attr.value = 'selection';
}
});
]]></xp:this.script>
</xp:eventHandler>
它 "repairs" 输入元素的 name 属性,因此它们都具有相同的名称 "selection" 而没有 "repeat"-part:
来自
到