sairn
sairn

Reputation: 490

p:calendar: Is it possible to enable a user either pick or enter a date, and then clear the input, if needed?

I want to use <p:calendar>, but I can't seem to find a way to enable a user to clear a previously entered value. For example, using "select-all" and "backspace" to clear the input only results in a validation (conversion) error. To complicate matters, I have put a jQuery mask "99/99/9999" on the input field as well.

Is it possible to enable a user either pick or enter a date in a <p:calendar> widget and, most importantly, allow them to clear the input, if needed?

Again, the user needs to be able to enter the date value manually or by using the date picker.

So far, it appears as if the jquery date mask -- i.e., __/__/____ -- is related to the user's inability to simply space over their input...I.e., the original manually inputted value simply reappears when submit button pressed. --Unfortunately I am required to provide a date input mask to guide the user as to the correct input format for when they enter the date manually.

Here is an example of what the widget looks like:

<p:calendar 
    pattern="MM/dd/yyyy"
    widgetVar="birthDate_var"
    id="birthDate"
    requiredMessage="birth date required"
    validatorMessage="invalid birth date "
    converterMessage="invalid birth date format"
    readonly="false"
    readonlyInput="false"
    navigator="true" 
    showOn="button" 
    value="#{testBean.parmMap['birthDate']}"                               
    size="10"                            
    maxlength="10"
    yearRange="c-120:c+0"  
    onfocus="$('#queryForm\\:msgs > div').hide();$('#queryForm\\:msgs > div').eq(1).show();$(this).mask('99/99/9999');return false;">
    <p:ajax event="dateSelect" listener="#{testBean.updateBirthDate}" process="@this" />                        
    <p:ajax event="change" listener="#{testBean.updateBirthDate}" process="@this" />  
</p:calendar> 

How can I achieve this? I am using Mojarra 2.1.11 and PrimeFaces 3.4.2.

Upvotes: 0

Views: 3662

Answers (1)

sairn
sairn

Reputation: 490

I dunno whether this is considered a "hack" or a legitmate solution, however, it appears the issue I was having is solved by creating a custom converter for the date input...i.e., something like this...

UPDATE: appears not to be a valid solution. Though it appears to work, a class cast exception is issued by the "calendar.validator"[?]

i.e.,

INFO: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
    at org.primefaces.component.calendar.Calendar.validate(Calendar.java:452)
    at javax.faces.component.UIInput.executeValidate(UIInput.java:1233)

for the widget...

 <p:calendar
    pattern="MM/dd/yyyy"
    widgetVar="birthDate_var"
    id="birthDate"
    requiredMessage="birth date required"
    validatorMessage="invalid birth date "
    converter="dpConverter"
    converterMessage="invalid birth date format"
    readonly="false"
    readonlyInput="false"
    navigator="true"
    showOn="button"
    value="#{testBean.parmMap['birthDate']}"
    size="10"
    maxlength="10"
    yearRange="c-120:c+0"
    onfocus="$('#queryForm\\:msgs > div').hide();$('#queryForm\\:msgs > div').eq(1).show();$(this).mask('99/99/9999');return false;"
    onblur="$(this).unmask();return false;">
    <p:ajax event="dateSelect" update="@this" />
    <p:ajax event="change" update="@this"/>
</p:calendar>

Used this custom converter...

package aaa.bbb.ccc.war;

import java.text.SimpleDateFormat;
import java.util.Date;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

@FacesConverter("dpConverter")
public class DPConverter implements Converter
{

    private static SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value)
    {
        try
        {
            if (null == value || String.valueOf(value).contains("__/__/____"))
            {
                return null;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return value; //(null==value?null:value);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value)
    {
        String v = null;
        try
        {
            if (String.valueOf(value).contains("__/__/____"))
            {
                return null;
            }

            if (value instanceof String)
            {
                v = (String) value;
            }
            else if (value instanceof Date)
            {
                v = dateFormat.format((Date) value);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return v;
    }
}   

Upvotes: 1

Related Questions