All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.future.earth.gwt.client.TimeEditBox Maven / Gradle / Ivy

The newest version!
package eu.future.earth.gwt.client;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.TextBox;

import eu.future.earth.gwt.client.ui.events.enter.HasKeyEnterEventHandlers;
import eu.future.earth.gwt.client.ui.events.enter.KeyEnterEvent;
import eu.future.earth.gwt.client.ui.events.enter.KeyEnterHandler;
import eu.future.earth.gwt.client.ui.popup.PopupRenderer;
import eu.future.earth.gwt.client.ui.popup.SelectPopup;

/**
 * Box for editing time entries
 */
public class TimeEditBox extends TextBox implements HasKeyEnterEventHandlers {

	public final static String DEFAULT_TIME_FORMAT = "HH:mm";

	private static int convert(int keyCode) {
		// convert 0 - 9 keys on number pad down into normal 0 - 9 range
		if (keyCode >= 96 && keyCode <= 105) {
			return keyCode - 48;
		}
		return keyCode;
	}

	private static boolean isTimeKey(int keyCode) {
		boolean result = false;
		// 0 - 9 keys above qwerty
		if (keyCode >= 48 && keyCode <= 57) {
			result = true;
		}
		// 0 - 9 keys on number pad
		if (keyCode >= 96 && keyCode <= 105) {
			result = true;
		}
		// A, M, P keys
		if (keyCode == 65 || keyCode == 77 || keyCode == 80) {
			result = true;
		}
		if (keyCode == KeyCodes.KEY_BACKSPACE) {
			result = true;
		}
		return result;
	}

	private String format = DEFAULT_TIME_FORMAT;

	private DateTimeFormat date = null;

	private final SelectPopup panel = new SelectPopup(new PopupRenderer() {

		@Override
		public String getId(String newRow) {
			return newRow;
		}

		@Override
		public String getLabel(String item) {
			return item;
		}
	});

	public TimeEditBox() {
		this(DEFAULT_TIME_FORMAT);
	}

	public TimeEditBox(boolean showPopup) {
		this(DEFAULT_TIME_FORMAT, showPopup);
	}

	public TimeEditBox(String format) {
		this(format, false);
	}

	public TimeEditBox(String format, boolean showPopup) {
		super.sinkEvents(Event.ONKEYDOWN);
		setFormat(format);
		addStyleName("ftr-time-box");
		// getElement().getStyle().setWidth(50, Unit.PX);
		for (int i = 0; i < 24; i++) {
			if (i < 10) {
				panel.addValue("0" + i + ":00");
				panel.addValue("0" + i + ":30");
			} else {
				panel.addValue(i + ":00");
				panel.addValue(i + ":30");
			}

		}
		if (showPopup) {
			super.addFocusHandler(new FocusHandler() {

				@Override
				public void onFocus(FocusEvent event) {
					panel.showRelativeTo(TimeEditBox.this);
					panel.setValue(getValue());
					panel.scrollToValue();
				}
			});
		}
		panel.addValueChangeHandler(new ValueChangeHandler() {

			@Override
			public void onValueChange(ValueChangeEvent event) {
				setText(event.getValue());
			}
		});

	}

	@Override
	public HandlerRegistration addValueChangeHandler(ValueChangeHandler handler) {
		return panel.addValueChangeHandler(handler);
	}

	@Override
	public HandlerRegistration addKeyEnterHandler(KeyEnterHandler handler) {
		return super.addHandler(handler, KeyEnterEvent.getType());
	}

	private void checkState() {
		if (isValid()) {
			super.removeStyleName("ftr-field-error");
		} else {
			super.addStyleName("ftr-field-error");
		}
	}

	public String getFormat() {
		return format;
	}

	public Date getValue(Date dateToAttachTo) {
		Date result = null;
		if (dateToAttachTo != null && getText() != null && getText().length() == format.length()) {
			if (!getText().equals(format)) {
				try {
					final Date time = DateTimeFormat.getFormat(format).parse(getText());
					final GregorianCalendar thelper = new GregorianCalendar();
					thelper.setTime(time);
					final GregorianCalendar helper = new GregorianCalendar();
					setHelper(dateToAttachTo, thelper, helper);
					return helper.getTime();
				} catch (IllegalArgumentException ex) {
				}
			}
		}
		return result;
	}

	@SuppressWarnings("static-method")
	private void setHelper(Date dateToAttachTo, final GregorianCalendar thelper, final GregorianCalendar helper) {
		helper.setTime(dateToAttachTo);
		helper.set(Calendar.HOUR_OF_DAY, thelper.get(Calendar.HOUR_OF_DAY));
		helper.set(Calendar.MINUTE, thelper.get(Calendar.MINUTE));
		helper.set(Calendar.SECOND, 0);
		helper.set(Calendar.MILLISECOND, 0);
	}

	public boolean isValid() {
		if (super.getText() == null || super.getText().isEmpty() || super.getText().equalsIgnoreCase(format)) {
			return true;
		}
		return getValue(new Date()) != null;
	}

	@Override
	public void onBrowserEvent(Event event) {
		int eventType = DOM.eventGetType(event);
		int keyCode = event.getKeyCode();

		switch (eventType) {
		case Event.ONKEYDOWN: {
			if (KeyEnterEvent.isValidKeyCode(keyCode)) {
				KeyEnterEvent.fire(this);
			} else {
				if (keyCode == KeyCodes.KEY_DOWN) {
					panel.showRelativeTo(TimeEditBox.this);
					panel.setValue(getValue());
					panel.scrollToValue();
					panel.focusSelected();
				}

				if (keyCode == KeyCodes.KEY_TAB) {
					panel.hide();
				}

				if (keyCode == 37 || keyCode == 39 || keyCode == 18 || keyCode == 9) {
					super.onBrowserEvent(event);
					checkState();
					return;
				}

				if (isTimeKey(keyCode)) {
					final int cursor = super.getCursorPos();
					if (cursor >= format.length() && keyCode != KeyCodes.KEY_BACKSPACE) {
						// This block is empyt as intended.
					} else {
						final String temp = super.getText();
						if (keyCode == KeyCodes.KEY_BACKSPACE) {
							if (cursor < 1) {
								return;
							}
							final char rep = format.charAt(cursor - 1);
							final String newString = temp.substring(0, cursor - 1) + rep + temp.substring(cursor, format.length());
							super.setText(newString);
							checkState();
							super.setCursorPos(cursor - 1);

						} else {
							final char rep = format.charAt(cursor);

							if (rep == ':') {
								super.setCursorPos(cursor + 1);
							} else {

								char next = (char) -1;

								if (format.length() > cursor + 1) {
									next = format.charAt(cursor + 1);
								}
								char newChar = (char) convert(keyCode);
								boolean allow = false;

								if (rep == 'H' && next == 'H') {
									if (newChar == '0' || newChar == '1' || newChar == '2') {
										allow = true;
									}
								} else {
									if (rep == 'H') {
										char prev = temp.charAt(cursor - 1);
										if (prev == '2') {
											if (newChar == '0' || newChar == '1' || newChar == '2' || newChar == '3') {
												allow = true;
											}
										} else {
											allow = true;
										}

									}
								}

								if (rep == 'h' && next == 'h') {
									if (newChar == '0' || newChar == '1') {
										allow = true;
									}
								} else {
									if (rep == 'h') {
										char prev = temp.charAt(cursor - 1);
										if (prev == '1') {
											if (newChar == '0' || newChar == '1' || newChar == '2') {
												allow = true;
											}
										} else {
											allow = true;
										}

									}
								}

								if (rep == 'm' && next == 'm') {
									if (newChar == '0' || newChar == '1' || newChar == '2' || newChar == '3' || newChar == '4' || newChar == '5') {
										allow = true;
									}
								} else {
									if (rep == 'm') {
										final char prev = temp.charAt(cursor - 1);
										if (prev == '0' || prev == '1' || prev == '2' || prev == '3' || prev == '4' || prev == '5') {
											allow = true;
										} else {
											if (newChar == '0') {
												allow = true;
											}
										}
									}
								}

								if (rep == 'a' && next == 'a') {
									if (newChar == 'A' || newChar == 'a') {
										newChar = 'A';
										allow = true;
									} else if (newChar == 'P' || newChar == 'p') {
										newChar = 'P';
										allow = true;
									}

								} else {
									if (rep == 'a') {
										if (newChar == 'M' || newChar == 'm') {
											newChar = 'M';
											allow = true;
										}
									}
								}

								if (allow) {
									final String newString = temp.substring(0, cursor) + newChar + temp.substring(cursor + 1, format.length());
									super.setText(newString);
									checkState();
									if (keyCode == KeyCodes.KEY_BACKSPACE) {
										super.setCursorPos(cursor - 1);

									} else {
										if (next == ':') {
											super.setCursorPos(cursor + 2);
										} else {
											super.setCursorPos(cursor + 1);
										}
									}
								}
							}
						}
					}
					checkState();
					event.preventDefault();

					return;

				}

				checkState();
				event.preventDefault();
				return;

			}

		}
		//$FALL-THROUGH$
		default:
			super.onBrowserEvent(event);
		}
		checkState();
	}

	public void setDate(Date newValue) {
		if (newValue != null) {
			super.setText(date.format(newValue));
		} else {
			super.setText(format);
		}
		checkState();
	}

	public void setFormat(String format) {
		this.format = format;
		date = DateTimeFormat.getFormat(format);
		super.setText(format);
		super.setMaxLength(format.length());
		super.setVisibleLength(format.length());
		checkState();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy