I'm trying to design a joda time based DateTime field. There are two reasons
 - I use joda time only
 - I have to wire tree components - start date, finish date and duration, so
I have to add

I managed to get it working but I'm concerned about the approach I took. So
please critics are welcome. Below is the source code of the component.

My question is about the isAjaxRequest() method. I believe I should check
whether the AjaxFormComponentUpdatingBehavior's request target is handled.
But I don't know how. Please suggest.

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.behavior.IBehavior;
import org.apache.wicket.datetime.DateConverter;
import org.apache.wicket.datetime.StyleDateConverter;
import org.apache.wicket.datetime.markup.html.form.DateTextField;
import org.apache.wicket.extensions.yui.calendar.DateField;
import org.apache.wicket.markup.html.form.FormComponentPanel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.protocol.http.WebRequest;
import org.joda.time.DateTime;

public class JodaDateField extends FormComponentPanel<DateTime> {

    protected class LocalDateField extends DateField {

        protected final class LocalDateTextField extends DateTextField {
            public LocalDateTextField(String id, IModel<Date> model,
DateConverter converter) {
                super(id, model, converter);
            }

            @Override
            protected void onModelChanged() {
                super.onModelChanged();
                if (isAjaxRequest()) {
                    Date date = getModelObject();
                    LocalDateField.this.setModelObject(date);
                }
            }
        }

        public LocalDateField(String id, IModel<Date> model) {
            super(id, model);
        }

        @Override
        protected DateTextField newDateTextField(String id, PropertyModel
dateFieldModel) {
            @SuppressWarnings("unchecked")
            IModel<Date> model = dateFieldModel;
            return new LocalDateTextField(id, model, new
StyleDateConverter(true));
        }

        @Override
        protected void onModelChanged() {
            super.onModelChanged();
            if (isAjaxRequest()) {
                Date date = getModelObject();
                JodaDateField.this.setModelObject(date == null ? null : new
DateTime(date));
            }
        }
    }

    private DateField dateField;;

    public JodaDateField(String id, IModel<DateTime> model) {
        super(id, model);

        dateField = new LocalDateField("field", new Model<Date>());
        add(dateField);
    }

    @Override
    public Component add(IBehavior... behaviors) {
        List<IBehavior> correct = new ArrayList<IBehavior>();
        for (IBehavior behavior : behaviors) {
            if (behavior instanceof AjaxFormComponentUpdatingBehavior)
                dateField.get("date").add(behavior);
            else
                correct.add(behavior);
        }
        return super.add(correct.toArray(new IBehavior[correct.size()]));
    }

    @Override
    protected void convertInput() {
        Date date = dateField.getConvertedInput();
        setConvertedInput(date == null ? null : new DateTime(date));
    }

    @Override
    public String getInput() {
        return dateField.getInput();
    }

    private boolean isAjaxRequest() {
        return getRequest() instanceof WebRequest && ((WebRequest)
getRequest()).isAjax();
    }

    @Override
    protected void onBeforeRender() {
        DateTime date = getModelObject();
        dateField.setDate(date == null ? null : date.toDate());
        dateField.setRequired(isRequired());
        super.onBeforeRender();
    }
}

Reply via email to