如何获取 p:dataTable 中当前验证行的行索引?
How to get row index of currently validating row in p:dataTable?
我正在使用 cellEditors 为用户的 ip 范围制作 p:dataTable,其中包括 p:inputMask。 dataTable 由 2 个可编辑的列组成。
要验证我必须:
- 检查指定的ip-address是否匹配RegEx,
- 确保范围的起点实际上早于终点,
- 确保指定的范围不与之前输入的范围相交。
前两部分没有发出太大的声音。
第三个要求我检查指定的范围是在先前输入的范围之前还是之后。您只需检查 start 和 finish 是否在每个其他 ip 范围之前或之后。简单吧?
验证周期。
for (Groupip gip : searchResults) {
long ipend = ipToLong(InetAddress.getByName(gip.getIpend()));
long ipstart = ipToLong(InetAddress.getByName(gip.getIpstart()));
boolean validLeft = true, validRight = true;
validLeft = validLeft && ipstart < ipValidated;
validLeft = validLeft && ipend < ipValidated;
validLeft = validLeft && ipstart < ipValidating;
validLeft = validLeft && ipend < ipValidating;
validRight = validRight && ipstart > ipValidated;
validRight = validRight && ipend > ipValidated;
validRight = validRight && ipstart > ipValidating;
validRight = validRight && ipend > ipValidating;
if (validLeft || validRight) {
//OK
} else {
//ERROR
}
}
数据表。
<p:dataTable id="ips1" widgetVar="ips1" var="ip" value="#{groupipController.searchResults}" editable="true"
rowKey="#{ip.groupcode}-#{ip.ipstart}-#{ip.ipend}" selection="#{groupipController.selected}" selectionMode="single"
>
<f:facet name="header">
Диапазон IP
</f:facet>
<p:ajax event="rowEditCancel" listener="#{groupipController.onRowCancel}" />
<p:ajax event="rowEditInit" listener="#{groupipController.onRowEditInit}" />
<p:ajax event="rowEdit" listener="#{groupipController.onRowEdit}" update=":form:msgs :form:ips1 :form:growlmsgs" process=":form:ips1"/>
<p:column headerText="От" style="min-height: 16px" id='from_col'>
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{ip.ipstart}" /></f:facet>
<f:facet name="input">
<p:inputMask mask="999.999.999.999" value="#{ip.ipstart}" id="fromip" autoClear="false" slotChar="0"
validator="#{groupipController.validate}"
class="ui-inputfield ui-inputmask ui-widget ui-state-default ui-corner-all p-0-1 w-100 h-100"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="До" style="min-height: 16px" id='to_col'>
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{ip.ipend}" /></f:facet>
<f:facet name="input">
<p:inputMask mask="999.999.999.999" value="#{ip.ipend}" id="toip" autoClear="false" slotChar="0"
validator="#{groupipController.validate}"
class="ui-inputfield ui-inputmask ui-widget ui-state-default ui-corner-all p-0-1 w-100 h-100"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column width="10%" >
<p:rowEditor rendered="#{armgroupController.update}" />
</p:column>
</p:dataTable>
但还有更多。 searchResults
是一个变量,它是 dataTable 的源,其中包含一个 List<Groupip>
。但它也包含当前正在编辑的行。所以我必须排除它,否则我将无法通过将范围与自身进行比较的验证。
我该怎么做呢?我可以找到编辑行的行索引的唯一方法是使用以下代码获取 cliendId 的前最后一个值(在浏览器中看起来像这样:form:ips1:2:toip
):
if (gip == searchResults.get(Integer.parseInt(component.getClientId().split(":")[2]))) {
continue;
}
这不合适,因为命名容器可能会更改。
所以,我想知道,有没有其他方法可以获取行索引?
您当前组件的 id 始终是完整 clientID 列表中的最后一个,并且您自己声明采用前最后一个值,但实际上您采用了第三个值(索引 2)
如果您实际上将最后一个索引(base-0)作为行索引,那么您(大部分)总是没问题。
String[] fields = component.getClientId().split(":");
int index = Integer.parseInt(fields[fields.length-2]);
if (gip == searchResults.get(index)) {
continue;
}
如果有人将此 'current' 组件包装在命名容器中,索引将不是最后一个而是最后一个,而是之前的一个,甚至更早。因此,您可以将其添加到循环中以获取拆分 clientId 的第一部分,这是一个数字,因为 JSF (html) id's cannot start with a number 因此不能是一个数字,所以您是 'safe'然后。
String[] fields = component.getClientId().split(":");
int indexPos = fields.length-2;
int index = -1;
do {
try {
index = Integer.parseInt(fields[indexPos]);
} catch {
indexPos--;
}
} while (index == -1)
if (gip == searchResults.get(index)) {
continue;
}
您也可以尝试将组件的父级转换为 Datatable
并查看它是否包含可以使用的 getCurrentRow()
之类的东西,但是您还应该创建一个循环来获取如果父项不是数据表,则为父项的父项。
要调查的示例是 http://showcase.omnifaces.org/validators/validateUniqueColumn
的来源
我正在使用 cellEditors 为用户的 ip 范围制作 p:dataTable,其中包括 p:inputMask。 dataTable 由 2 个可编辑的列组成。 要验证我必须:
- 检查指定的ip-address是否匹配RegEx,
- 确保范围的起点实际上早于终点,
- 确保指定的范围不与之前输入的范围相交。
前两部分没有发出太大的声音。 第三个要求我检查指定的范围是在先前输入的范围之前还是之后。您只需检查 start 和 finish 是否在每个其他 ip 范围之前或之后。简单吧?
验证周期。
for (Groupip gip : searchResults) {
long ipend = ipToLong(InetAddress.getByName(gip.getIpend()));
long ipstart = ipToLong(InetAddress.getByName(gip.getIpstart()));
boolean validLeft = true, validRight = true;
validLeft = validLeft && ipstart < ipValidated;
validLeft = validLeft && ipend < ipValidated;
validLeft = validLeft && ipstart < ipValidating;
validLeft = validLeft && ipend < ipValidating;
validRight = validRight && ipstart > ipValidated;
validRight = validRight && ipend > ipValidated;
validRight = validRight && ipstart > ipValidating;
validRight = validRight && ipend > ipValidating;
if (validLeft || validRight) {
//OK
} else {
//ERROR
}
}
数据表。
<p:dataTable id="ips1" widgetVar="ips1" var="ip" value="#{groupipController.searchResults}" editable="true"
rowKey="#{ip.groupcode}-#{ip.ipstart}-#{ip.ipend}" selection="#{groupipController.selected}" selectionMode="single"
>
<f:facet name="header">
Диапазон IP
</f:facet>
<p:ajax event="rowEditCancel" listener="#{groupipController.onRowCancel}" />
<p:ajax event="rowEditInit" listener="#{groupipController.onRowEditInit}" />
<p:ajax event="rowEdit" listener="#{groupipController.onRowEdit}" update=":form:msgs :form:ips1 :form:growlmsgs" process=":form:ips1"/>
<p:column headerText="От" style="min-height: 16px" id='from_col'>
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{ip.ipstart}" /></f:facet>
<f:facet name="input">
<p:inputMask mask="999.999.999.999" value="#{ip.ipstart}" id="fromip" autoClear="false" slotChar="0"
validator="#{groupipController.validate}"
class="ui-inputfield ui-inputmask ui-widget ui-state-default ui-corner-all p-0-1 w-100 h-100"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="До" style="min-height: 16px" id='to_col'>
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{ip.ipend}" /></f:facet>
<f:facet name="input">
<p:inputMask mask="999.999.999.999" value="#{ip.ipend}" id="toip" autoClear="false" slotChar="0"
validator="#{groupipController.validate}"
class="ui-inputfield ui-inputmask ui-widget ui-state-default ui-corner-all p-0-1 w-100 h-100"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column width="10%" >
<p:rowEditor rendered="#{armgroupController.update}" />
</p:column>
</p:dataTable>
但还有更多。 searchResults
是一个变量,它是 dataTable 的源,其中包含一个 List<Groupip>
。但它也包含当前正在编辑的行。所以我必须排除它,否则我将无法通过将范围与自身进行比较的验证。
我该怎么做呢?我可以找到编辑行的行索引的唯一方法是使用以下代码获取 cliendId 的前最后一个值(在浏览器中看起来像这样:form:ips1:2:toip
):
if (gip == searchResults.get(Integer.parseInt(component.getClientId().split(":")[2]))) {
continue;
}
这不合适,因为命名容器可能会更改。 所以,我想知道,有没有其他方法可以获取行索引?
您当前组件的 id 始终是完整 clientID 列表中的最后一个,并且您自己声明采用前最后一个值,但实际上您采用了第三个值(索引 2)
如果您实际上将最后一个索引(base-0)作为行索引,那么您(大部分)总是没问题。
String[] fields = component.getClientId().split(":");
int index = Integer.parseInt(fields[fields.length-2]);
if (gip == searchResults.get(index)) {
continue;
}
如果有人将此 'current' 组件包装在命名容器中,索引将不是最后一个而是最后一个,而是之前的一个,甚至更早。因此,您可以将其添加到循环中以获取拆分 clientId 的第一部分,这是一个数字,因为 JSF (html) id's cannot start with a number 因此不能是一个数字,所以您是 'safe'然后。
String[] fields = component.getClientId().split(":");
int indexPos = fields.length-2;
int index = -1;
do {
try {
index = Integer.parseInt(fields[indexPos]);
} catch {
indexPos--;
}
} while (index == -1)
if (gip == searchResults.get(index)) {
continue;
}
您也可以尝试将组件的父级转换为 Datatable
并查看它是否包含可以使用的 getCurrentRow()
之类的东西,但是您还应该创建一个循环来获取如果父项不是数据表,则为父项的父项。
要调查的示例是 http://showcase.omnifaces.org/validators/validateUniqueColumn
的来源