-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hello,
I am sorry for my English. I am trying to implementate a validator to ensure the user has chosen at least one element in a list selection.
In the ViewModel there is a property:
private List<EvidenciaBean> evidenciasSeleccionadas;
The ZUL has defined a validator:
<vlayout vflex="1" form="@id('fx') @load(vm) @save(vm, before='continuar') @validator('es.aeat.frns.nuix.web.zkuais.creacion.evidencias.SeleccionarEvidenciasOcrCdValidator')">
<listbox model="@load(vm.listaEvidenciasDisponibles)"
selectedItems="@bind(fx.evidenciasSeleccionadas)"
forward="onOK=botonContinuarOcrEvidenciasCd.onClick"
multiple="true" checkmark="true"
vflex="1">
<template name="model" var="evidencia">
<listitem>
<listcell label="@load(evidencia.nombre)"></listcell>
</listitem>
</template>
</listbox>
The code of the validator is simple, check if list is empty.
public class SeleccionarEvidenciasOcrCdValidator extends AbstractValidator {
@Override
public void validate(ValidationContext ctx) {
@SuppressWarnings("unchecked")
AbstractCollection<EvidenciaBean> evidenciasSeleccionadas = (AbstractCollection<EvidenciaBean>) ctx.getProperties("evidenciasSeleccionadas")[0].getValue();
//Debe haber seleccionado alguna evidencia
if ( (evidenciasSeleccionadas == null) || (evidenciasSeleccionadas.isEmpty()) ) {
String mensajeValidacion = "Debe seleccionar alguna evidencia.";
addInvalidMessage(ctx, mensajeValidacion);
Messagebox.show(mensajeValidacion, "Error de validación", Messagebox.OK, Messagebox.ERROR);
return;
}
}
}
The problem is that sometimes it works fine, sometimes it works wrong. When it is wrong the error message is: org.zkoss.bind.proxy.ListProxy incompatible with java.util.AbstractCollection
It is very strange because ctx.getProperties('myProperty') has 2 elements. The first element usually contains the correct value as LinkedHasSet object but sometimes the first element contains a ListProxy.
Does anybody know why the order change when property is recovered?
The ZK version I use is 8.0.4
Thanks in advance.
It's actually a very simple explication.
If you set your selected items as null
=> the listbox implementation will take default a new LinkedHashSet
.
Now I was thinking of initializing it would help it, but it won't fix your problem without the proxy.
This fiddle show you the default selection :
http://zkfiddle.org/sample/3kvld74/205-Simple-MVVM-sample
Then of course you have the extra step of the proxy between it.
So I'm guessing the proxy would take the instane of the type with what it's created.
You set some selection first => it will be ListProxy (because you use List)
The other time it's initialized with LinkedHashSet => that's the other fault.
The best way is to make your selected items a LinkedHashSet => so every time the proxy is initialized, it will be the correct class.
chill.
Hello chillworld,
You have made me find the light, thanks!
Blockquote If you set your selected items as null => the listbox implementation will take default a new LinkedHashSet. Blockquote
In the ViewModel class, I used an @Init method where the property was inicializated.
private List<EvidenciaBean> evidenciasSeleccionadas;
public List<EvidenciaBean> getEvidenciasSeleccionadas() {
return evidenciasSeleccionadas;
}
public void setEvidenciasSeleccionadas(List<EvidenciaBean> evidenciasSeleccionadas) {
this.evidenciasSeleccionadas = evidenciasSeleccionadas;
}
@Init
public void inicializacion(@ExecutionArgParam("listaEvidencias") List<EvidenciaBean> lista) {
listaEvidenciasDisponibles = lista;
evidenciasSeleccionadas = new ArrayList<>();
}
I have changed the inicialization of evidenciasSeleccionadas to:
@Init
public void inicializacion(@ExecutionArgParam("listaEvidencias") List<EvidenciaBean> lista) {
listaEvidenciasDisponibles = lista;
evidenciasSeleccionadas = null;
}
After this change, validator works fine using:
AbstractCollection<EvidenciaBean> evidenciasSeleccionadas = (AbstractCollection<EvidenciaBean>) ctx.getProperties("evidenciasSeleccionadas")[0].getValue();
Regards.
Could you change AbstractCollection<EvidenciaBean>
to List
? since List
should be the matched type.
Since you originally declare below in your ViewModel:
private List<EvidenciaBean> evidenciasSeleccionadas;
Hello hawk,
I have tried this:
@Override public void validate(ValidationContext ctx) {
List<evidenciabean> evidenciasSeleccionadas = (List<evidenciabean>) ctx.getProperties("evidenciasSeleccionadas")[0].getValue();
Sometimes it works fine, sometimes it does not work, in this case the error is: java.util.LinkedHashSet incompatible with java.util.List
This error is due to the original problem, sometimes the object received in [0] index is a linkedHashSet. In other cases the object received in [0] index is a List.
I am sorry but I have not karma enought to attach some screens to explain it better.
Thanks for your help.
Hello again,
After solving this problem, I have found the opposite.
In the previous ViewModel the list I would like to validate was empty. The user had to choose at least one element of this list.
Now the user hast to selected at least one element in the list showed. The validator has to check at least one element of this list is selected (by default the list has one element selected).
This new ViewModel is similar, the list I would like to validate is inicializated with one element.
private List<ConfiguracionOcr.IdiomaOcr> idiomasSeleccionados;
@Init
public void inicializacion() {
this.idiomasSeleccionados = new ArrayList<>();
this.idiomasSeleccionados.add(ConfiguracionOcr.IdiomaOcr.IDIOMA_ESPANOL);
}
The ZUL has this code:
<vlayout vflex="1" form="@id('fx') @load(vm) @save(vm, before='aceptar') @validator('es.aeat.frns.nuix.web.zkuais.gestion.resultados.PasarOcrDocumentosCdValidator')">
<listbox model="@load(vm.idiomasDisponibles)"
selectedItems="@bind(fx.idiomasSeleccionados)"
forward="onOK=botonAceptarOcrDocumentosCd.onClick"
multiple="true" checkmark="true"
vflex="1">
<listhead>
<listheader label="Idiomas"/>
</listhead>
<template name="model" var="idioma">
<listitem>
<listcell label="@load(idioma.descripcion)"></listcell>
</listitem>
</template>
</listbox>
....
The validator is implemented in the same way:
@Override
public void validate(ValidationContext ctx) {
@SuppressWarnings("unchecked")
AbstractCollection<ConfiguracionOcr.IdiomaOcr> idiomasSeleccionados = (AbstractCollection<ConfiguracionOcr.IdiomaOcr>) ctx.getProperties("idiomasSeleccionados")[0].getValue();
//Debe haber seleccionado algún idioma
if ( (idiomasSeleccionados == null) || (idiomasSeleccionados.isEmpty()) ) {
String mensajeValidacion = "Debe seleccionar algún idioma.";
addInvalidMessage(ctx, mensajeValidacion);
Messagebox.show(mensajeValidacion, "Error de validación", Messagebox.OK, Messagebox.ERROR);
return;
}
}
}
But sometimes I get the error: org.zkoss.bind.proxy.ListProxy incompatible with java.util.AbstractCollection
So I am confused. Any idea?
I think the best is just to use the Collection
interface.
You can ask the size, an iterator and ListProxy
as AbstractCollection
implements this interface.
Asked: 2018-07-18 20:25:00 +0800
Seen: 22 times
Last updated: Jul 27 '18