-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hi,
If I have this constraint set to a datebox: "before 20121130" when I set a wrong date the error message says "Valor fuera de rango: <= 20121130". Is there a way to make the message format the date like 30/11/2012 or just 30112012 ???
Thank you!
I tested this out and it works:
ZUL
<?page title="new page title" contentType="text/html;charset=UTF-8"?> <zk> <window title="new page title" border="normal" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('TestViewModel')"> <datebox id="myDate" constraint="@bind(vm.myDateConstraint)" value="@bind(vm.myDate)" /> </window> </zk>
TestViewModel
import java.text.SimpleDateFormat; import java.util.Date; import java.util.GregorianCalendar; import org.zkoss.zul.SimpleDateConstraint; public class TestViewModel { private static final SimpleDateFormat SDF = new SimpleDateFormat("dd-MM-yyyy"); private SimpleDateConstraint sdc; private Date constraintDate; private Date myDate; public Date getMyDate() { if (myDate == null) { myDate = new GregorianCalendar().getTime(); } return myDate; } public void setMyDate(Date myDate) { this.myDate = myDate; } public SimpleDateConstraint getMyDateConstraint() { constraintDate = new GregorianCalendar(2012, 10, 30).getTime(); sdc = new SimpleDateConstraint("before 20121130: " + "Error! Date " + SDF.format(getMyDate()) + " is before " + SDF.format(constraintDate)); return sdc; } public void setMyDateConstraint(SimpleDateConstraint sdc) { this.sdc = sdc; } }
Or a last question...how would you manage the constraints between these dateboxes?
These are my functions. setConstraint is called from onChange event of both dateboxes. I tried two ways to do it. I show you both ways
setConstraint version 1:
/** * Añade una constraint a los datebox. La fecha del primer datebox no puede ser mayor a la fecha * del segundo y al inrevés. * @param dbDesde Datebox con la fecha DESDE. No puede ser mayor al segundo datebox * @param dbHasta Datebox con la fecha HASTA. No puede ser menor al primer datebox */ public static void setConstraint(Datebox dbDesde, Datebox dbHasta, Datebox dbModificado){ MaestroLiterales ml; int idioma = VariablesSesion.getIdioma(); ml = new MaestroLiterales(idioma); dbDesde.clearErrorMessage(true); dbHasta.clearErrorMessage(true); System.out.println("valor desde -> " + dbDesde.getValue()); System.out.println("valor hasta -> " + dbHasta.getValue()); //Quitamos la constraint del datebox al que se le acaba de introducir el dato dbModificado.setConstraint((String) null); dbModificado.invalidate(); //Lo repintamos porque si no no se actualiza la constraint //Ponemos la constraint al datebox que no se ha modificado if(dbModificado == dbDesde){ setConstraintHasta(dbDesde, dbHasta, ml); dbHasta.getValue(); }else if(dbModificado == dbHasta){ setConstraintDesde(dbDesde, dbHasta, ml); dbDesde.getValue(); } System.out.println("DBDesde constraint-> " + dbDesde.getConstraint()); System.out.println("DBHasta constraint-> " + dbHasta.getConstraint()); dbDesde.clearErrorMessage(true); dbHasta.clearErrorMessage(true); setConstraintHasta(dbDesde, dbHasta,ml); setConstraintDesde(dbDesde, dbHasta,ml); dbDesde.getValue(); dbHasta.getValue(); }
/** * Añade una constraint a los datebox. La fecha del primer datebox no puede ser mayor a la fecha * del segundo y al inrevés. * @param dbDesde Datebox con la fecha DESDE. No puede ser mayor al segundo datebox * @param dbHasta Datebox con la fecha HASTA. No puede ser menor al primer datebox */ public static void setConstraint(Datebox dbDesde, Datebox dbHasta, Datebox dbModificado){ MaestroLiterales ml; int idioma = VariablesSesion.getIdioma(); ml = new MaestroLiterales(idioma); dbDesde.clearErrorMessage(true); dbHasta.clearErrorMessage(true); System.out.println("valor desde -> " + dbDesde.getValue()); System.out.println("valor hasta -> " + dbHasta.getValue()); //Quitamos la constraint del datebox al que se le acaba de introducir el dato dbModificado.setConstraint((String) null); dbModificado.invalidate(); //Lo repintamos porque si no no se actualiza la constraint //Ponemos la constraint al datebox que no se ha modificado if(dbModificado == dbDesde){ setConstraintHasta(dbDesde, dbHasta, ml); dbHasta.getValue(); }else if(dbModificado == dbHasta){ setConstraintDesde(dbDesde, dbHasta, ml); dbDesde.getValue(); } System.out.println("DBDesde constraint-> " + dbDesde.getConstraint()); System.out.println("DBHasta constraint-> " + dbHasta.getConstraint()); }
/** * Añade la constraint al datebox Hasta (su fecha no podrá ser menor que la del datebox Desde) * @param dbDesde Datebox con la fecha DESDE. No puede ser mayor al segundo datebox * @param dbHasta Datebox con la fecha HASTA. No puede ser menor al primer datebox */ private static void setConstraintHasta(Datebox dbDesde, Datebox dbHasta, MaestroLiterales ml){ if(dbDesde.getValue()==null){ //El datebox Desde está vacío. Quitamos la constraint del Hasta dbHasta.setConstraint((String) null); dbHasta.invalidate(); //Lo repintamos porque si no no se actualiza la constraint }else{ //El datebox Desde tiene una fecha GregorianCalendar gcDesde = new GregorianCalendar(); gcDesde.setTime(dbDesde.getValue()); String anyo; String mes; String dia; anyo=String.valueOf(gcDesde.get(Calendar.YEAR)); //Comprobamos que la longitud de la cadena del año sea 4 debido al formateo por parte de la anterior operacion puesto que la constraint de zk espera una cadena de 4 digitos if(anyo.length() < 4){ //En el caso de que no tenga 4 digitos calculamos cuantos le faltan for(int i = 0; i < 4 - anyo.length(); i++ ){ //Añadimos un 0 por cada vuelta del bucle ya que los habrá perdido al formatear la cadena anyo = "0" + anyo; } } //Al mes tenemos que sumarle 1 porque empieza por 0 (enero es 0) if(String.valueOf(gcDesde.get(Calendar.MONTH)+1).length()==1){ //Si el mes es solo un digito le añadimos el 0 delante porque para la constraint //necesitamos que el formato de la fecha sea yyyyMMdd mes = "0"+String.valueOf(gcDesde.get(Calendar.MONTH)+1); }else{ //El mes ya tiene más de un dígito mes = String.valueOf(gcDesde.get(Calendar.MONTH)+1); } if(String.valueOf(gcDesde.get(Calendar.DATE)).length()==1){ //Si el dia es solo un digito le añadimos el 0 delante porque para la constraint //necesitamos que el formato de la fecha sea yyyyMMdd dia = "0"+gcDesde.get(Calendar.DATE); }else{ //El día ya tiene más de un dígito dia = String.valueOf(gcDesde.get(Calendar.DATE)); } //Establecemos la constraint. after yyyyMMdd (sin separadores) String constraint = anyo+mes+dia; SimpleDateConstraint sdc = new SimpleDateConstraint("after " + constraint+": La fecha tiene que ser igual o posteriro a "+ dia+"/"+mes+"/"+anyo); dbHasta.setConstraint(sdc); } } /** * Añade la constraint al datebox Desde (su fecha no podrá ser mayor que la del datebox Hasta) * @param dbDesde Datebox con la fecha DESDE. No puede ser mayor al segundo datebox * @param dbHasta Datebox con la fecha HASTA. No puede ser menor al primer datebox */ private static void setConstraintDesde(Datebox dbDesde, Datebox dbHasta, MaestroLiterales ml){ if(dbHasta.getValue()==null){ //El datebox Hasta está vacío. Quitamos al contraint del Desde dbDesde.setConstraint((String) null); dbDesde.invalidate(); //Repintamos el Datebox porque si no no borra la contraint }else{ //El datebox Hasta tiene una fecha GregorianCalendar gcHasta = new GregorianCalendar(); gcHasta.setTime(dbHasta.getValue()); String anyo; String mes; String dia; anyo=String.valueOf(gcHasta.get(Calendar.YEAR)); //Comprobamos que la longitud de la cadena del año sea 4 debido al formateo por parte de la anterior operacion puesto que la constraint de zk espera una cadena de 4 digitos if(anyo.length() < 4){ //En el caso de que no tenga 4 digitos calculamos cuantos le faltan for(int i = 0; i < 4 - anyo.length(); i++ ){ //Añadimos un 0 por cada vuelta del bucle ya que los habrá perdido al formatear la cadena anyo = "0" + anyo; } } //Al mes tenemos que sumarle 1 porque empieza por 0 (enero es 0) if(String.valueOf(gcHasta.get(Calendar.MONTH)+1).length()==1){ //Si el mes es solo un digito le añadimos el 0 delante porque para la constraint //necesitamos que el formato de la fecha sea yyyyMMdd mes = "0"+String.valueOf(gcHasta.get(Calendar.MONTH)+1); }else{ //El mes ya tiene más de un dígito mes = String.valueOf(gcHasta.get(Calendar.MONTH)+1); } if(String.valueOf(gcHasta.get(Calendar.DATE)).length()==1){ //Si el dia es solo un digito le añadimos el 0 delante porque para la constraint //necesitamos que el formato de la fecha sea yyyyMMdd dia = "0"+gcHasta.get(Calendar.DATE); }else{ //El día ya tiene más de un dígito dia = String.valueOf(gcHasta.get(Calendar.DATE)); } //Establecemos la constraint. before yyyyMMdd (sin separadores) SimpleDateConstraint sdc = new SimpleDateConstraint("before " + anyo+mes+dia+": La fecha tiene que ser igual o anterior a " + dia+"/"+mes+"/"+anyo); dbDesde.setConstraint(sdc); } }
I would really appreciate any suggestion because I've been fighting with it for a long time and I don't have anything clear!
Thank you!
I have something similar with a "from" and "to" date wherein, when the from date is changed, I want to change the value and constraint of the "to" date box so that the "to" date must be after the from date and within a month thereof.
ZUL:
<row> <cell> <label value="Date From:" sclass="strongLabel" ></label> </cell> <cell colspan="4"> <datebox id="fromDate" constraint="no future" value="@bind(vm.fromDate)" ></datebox> <space width="10px" ></space> <label value="to:" sclass="strongLabel" ></label> <space width="10px" ></space> <datebox id="toDate" constraint="@bind(vm.toDateConstraint)" value="@bind(vm.toDate)" ></datebox> <space width="5px" ></space> <button id="submit" dir="reverse" image="assets/images/arrow-right.png" label="go" onClick="@command('showCreditMemoSummary')" ></button> </cell> </row>
ViewModel:
public SimpleDateConstraint getToDateConstraint() { Calendar futureDate = new GregorianCalendar(); futureDate.setTime(fromDate); futureDate.add(Calendar.MONTH, 1); toDateConstraint = new SimpleDateConstraint("between " + CONSTRAINT_DATE.format(fromDate) + " and " + CONSTRAINT_DATE.format(futureDate.getTime())); return toDateConstraint; } public void setToDateConstraint(SimpleDateConstraint constraint) { toDateConstraint = constraint; } public Date getFromDate() { // First time, set to component preference definition. if (fromDate == null) { Calendar now = getNow(); fromDate = now.getTime(); if (componentPreference != null) { if (componentPreference.getFromValueAgo().compareTo(0L) == 0) { fromDate.setTime(now.getTimeInMillis() - (2 * MS_PER_DAY)); } else { long prefMS = componentPreference.getFromValueAgo() * ((long) MS_PER_DAY); fromDate.setTime(now.getTimeInMillis() - prefMS); } } else { fromDate.setTime(now.getTimeInMillis() - (2 * MS_PER_DAY)); } } return fromDate; } public void setFromDate(Date fromDate) { this.fromDate = fromDate; // Adjust to date based on from date. Calendar futureDate = new GregorianCalendar(); futureDate.setTime(getToDateConstraint().getBeginDate()); futureDate.add(Calendar.DATE, 2); toDate = futureDate.getTime(); } public Date getToDate() { // First time, set to component preference definition. if (toDate == null) { Calendar now = getNow(); toDate = now.getTime(); if (componentPreference != null) { if (componentPreference.getToValueAgo().compareTo(0L) == 0) { toDate.setTime(now.getTimeInMillis()); } else { long prefMS = componentPreference.getToValueAgo() * ((long) MS_PER_DAY); toDate.setTime(now.getTimeInMillis() - prefMS); } } } return toDate; } public void setToDate(Date toDate) { this.toDate = toDate; }
The key here is that, in the setFromDate() method, I change the toDateConstraint and force the toDate itself to a value that is after the fromDate. This triggers the BindComposer to update the ZUL toDate box with the appropriate value and constraint.
Note that, if you do it this way, you completely avoid the ability of the user to select an incorrect date range.
But you are always changing the To Date when user changes the From?I think sometimes it will be annoying. So I think change it only when the date is wrong. But it doesn't solve my problem.
Imagine this situation:
User set "From Date" to 23/11/2012, the constraint is set to "To Date". But he can also write to "To Date" a wrong date like 21/11/2012. If he writes it, the exception caused by the constraint is thrown. But in the datebox still appears the date he wrotes (21/11/2012).
Then he decied the wrong date is the one set in "From". So he canges it to 20/11/2012. He thinks that now the period is correct. But the reality is that as the exception has been thrown "To Datebox" doesn't have the value he entered.
With your code I undestand that as user has changed From Date, To Date will be automatically changed.
In my thoughts although user sees in screen a correct period "To Date" will be changed because as the exception has been thrown the datebox really doesn't have the value set. Then user will be annoyed because he has entered a correct period but the application has changed it.
(I know maybe it's difficult to understand my explanation hehe)
So my solution will be...If the exception is thrown the value also has to be set or if the exception is thrown as the datebox won't have the value, clean the text! But I don't know how to do any of it
Correct me if I'm wrong :)
Thank you!
Asked: 2012-11-23 13:06:38 +0800
Seen: 238 times
Last updated: Nov 30 '12