com.sksamuel.jqm4gwt.form.elements.JQMFlip Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jqm4gwt-standalone Show documentation
Show all versions of jqm4gwt-standalone Show documentation
jqm4gwt bundled with all of its dependencies
The newest version!
package com.sksamuel.jqm4gwt.form.elements;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasChangeHandlers;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.GwtEvent.Type;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.ListBox;
import com.sksamuel.jqm4gwt.HasCorners;
import com.sksamuel.jqm4gwt.HasMini;
import com.sksamuel.jqm4gwt.HasText;
import com.sksamuel.jqm4gwt.JQMCommon;
import com.sksamuel.jqm4gwt.button.JQMButton;
import com.sksamuel.jqm4gwt.events.HasTapHandlers;
import com.sksamuel.jqm4gwt.events.JQMComponentEvents;
import com.sksamuel.jqm4gwt.events.JQMHandlerRegistration;
import com.sksamuel.jqm4gwt.events.JQMHandlerRegistration.WidgetHandlerCounter;
import com.sksamuel.jqm4gwt.events.TapEvent;
import com.sksamuel.jqm4gwt.events.TapHandler;
import com.sksamuel.jqm4gwt.form.JQMFieldContainer;
import com.sksamuel.jqm4gwt.html.FormLabel;
/**
* @author Stephen K Samuel [email protected] 18 May 2011 04:21:09
*
*
*
*/
public class JQMFlip extends JQMFieldContainer implements HasText, HasValue,
HasChangeHandlers, HasClickHandlers, HasTapHandlers, HasMini, HasCorners {
private final FormLabel label = new FormLabel();
// The GWT widget to use as the select element
private final ListBox select = new ListBox();
private String value1;
private String value2;
private boolean valueChangeHandlerInitialized;
// There are three internal states: null, value1, value2 AND only two ui states: value1, value2.
// Three internal states are needed to properly support data binding libraries (Errai for example).
private String internVal;
/** setValue() in progress */
private boolean inSetValue;
private String trackTheme;
/**
* Creates a new {@link JQMFlip} widget with the given label text and
* initialized with two options taking their details from the given
* parameters.
*
* This constructor sets the label of each toggle to be the same as the
* value. If you want a seperate label and value use the JQMFlip(String,
* String, String, String, String) constructor.
*
* @param text
* the label text to use
* @param value1
* the value and label of the first toggle
* @param value2
* the value and label of the second toggle
*
*/
public JQMFlip(String text, String value1, String value2) {
this(text, value1, value1, value2, value2);
}
/**
* Creates a new {@link JQMFlip} widget with the given label text and
* initialized with two options taking their details from the given
* parameters.
*
* @param text
* the label text to use
* @param value1
* the value of the first toggle
* @param label1
* the text to display for the first toggle
* @param value2
* the value of the second toggle
* @param label2
* the text to display for the second toggle
*
*/
public JQMFlip(String text, String value1, String label1, String value2, String label2) {
this();
setText(text);
select.addItem(label1, value1);
select.addItem(label2, value2);
setValue1(value1);
setValue2(value2);
}
public JQMFlip() {
String id = Document.get().createUniqueId();
label.setFor(id);
select.setName(id);
select.getElement().setId(id);
JQMCommon.setDataRole(select.getElement(), "flipswitch");
addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
if (inSetValue) return;
switch (getSelectedIndex()) {
case 0:
internVal = getValue1();
break;
case 1:
internVal = getValue2();
break;
default:
internVal = null;
}
}
});
add(label);
add(select);
}
public String getLabel1() {
return select.getItemText(0);
}
public void setLabel1(String label1) {
if (select.getItemCount() > 1)
select.setItemText(0, label1);
else
select.addItem(label1, getValue1());
}
public String getLabel2() {
return select.getItemText(1);
}
public void setLabel2(String label2) {
if (select.getItemCount() > 2)
select.setItemText(1, label2);
else
select.addItem(label2, getValue2());
}
@Override
public HandlerRegistration addChangeHandler(ChangeHandler handler) {
// May be it makes sense to create wrapper over passed handler to make ChangeEvent and
// ValueChangeEvent to work the same way (currently inSetValue doesn't affect ChangeEvent).
return select.addChangeHandler(handler);
}
@Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
return flow.addDomHandler(handler, ClickEvent.getType());
}
@Override
public HandlerRegistration addTapHandler(TapHandler handler) {
// this is not a native browser event so we will have to manage it via JS
return JQMHandlerRegistration.registerJQueryHandler(new WidgetHandlerCounter() {
@Override
public int getHandlerCountForWidget(Type> type) {
return getHandlerCount(type);
}
}, this, handler, JQMComponentEvents.TAP_EVENT, TapEvent.getType());
}
@Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler handler) {
// Initialization code
if (!valueChangeHandlerInitialized) {
valueChangeHandlerInitialized = true;
addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
if (!inSetValue) {
ValueChangeEvent.fire(JQMFlip.this, getValue());
}
}
});
}
return addHandler(handler, ValueChangeEvent.getType());
}
public int getSelectedIndex() {
return select.getSelectedIndex();
}
/**
* Returns the value of the legend text.
*/
@Override
public String getText() {
return label.getText();
}
/**
* Returns the currently selected value or null if there is no currently
* selected button
*/
@Override
public String getValue() {
switch (getSelectedIndex()) {
case 0:
if (internVal == null) return null;
internVal = getValue1();
return internVal;
case 1:
internVal = getValue2();
return internVal;
default:
return null;
}
}
public void refresh() {
refresh(select.getElement());
}
private static native void refresh(Element elt) /*-{
if ($wnd.$ === undefined || $wnd.$ === null) return; // jQuery is not loaded
var w = $wnd.$(elt);
if (w.data('mobile-flipswitch') !== undefined) {
w.flipswitch('refresh');
}
}-*/;
private static native boolean isReady(Element elt) /*-{
if ($wnd.$ === undefined || $wnd.$ === null) return false; // jQuery is not loaded
var w = $wnd.$(elt);
return w.data('mobile-flipswitch') !== undefined;
}-*/;
/**
* Sets the currently selected index, fires change events (if attached).
*/
public void setSelectedIndex(int i) {
select.setSelectedIndex(i);
refresh(); // updates UI and always resets invalid index to 0
}
/**
* @param fireEvents - if false then ValueChangeEvent won't be raised (though ChangeEvent will be raised anyway).
* @param i - possible values 0 and 1.
*/
public void setSelectedIndex(int i, boolean fireEvents) {
if (fireEvents) {
setSelectedIndex(i);
return;
}
inSetValue = true;
try {
setSelectedIndex(i);
} finally {
inSetValue = false;
}
}
/**
* Sets the value of the legend text.
*/
@Override
public void setText(String text) {
label.setText(text);
}
@Override
public JQMFlip withText(String text) {
setText(text);
return this;
}
public void setTextHidden(boolean value) {
JQMCommon.setLabelHidden(this, value);
}
/**
* Sets the currently selected value, ValueChangeEvent won't be raised (though ChangeEvent will be raised anyway).
*/
@Override
public void setValue(String value) {
setValue(value, false);
}
/**
* Sets the currently selected value.
*
* @param fireEvents - if false then ValueChangeEvent won't be raised (though ChangeEvent will be raised anyway).
*/
@Override
public void setValue(String value, boolean fireEvents) {
int newIdx = value == null ? 0 : value.equals(getValue1()) ? 0
: value.equals(getValue2()) ? 1 : 0;
int oldIdx = getSelectedIndex();
String oldVal = fireEvents ? getValue() : null;
internVal = value;
if (oldIdx != newIdx) {
inSetValue = true;
try {
setSelectedIndex(newIdx);
} finally {
inSetValue = false;
}
}
if (fireEvents) {
boolean eq = internVal == oldVal || internVal != null && internVal.equals(oldVal);
if (!eq) ValueChangeEvent.fire(this, internVal);
}
}
/**
* Sets the value of the first option to the given string
*/
public void setValue1(String newValue) {
value1 = newValue;
}
public String getValue1() {
return value1;
}
/**
* Sets the value of the second option to the given string
*/
public void setValue2(String newValue) {
value2 = newValue;
}
public String getValue2() {
return value2;
}
@Override
public boolean isMini() {
return JQMCommon.isMini(select);
}
/**
* If set to true then renders a smaller version of the standard-sized element.
*/
@Override
public void setMini(boolean mini) {
JQMCommon.setMini(select, mini);
}
/**
* If set to true then renders a smaller version of the standard-sized element.
*/
@Override
public JQMFlip withMini(boolean mini) {
setMini(mini);
return this;
}
@Override
public String getTheme() {
return JQMCommon.getTheme(select);
}
@Override
public void setTheme(String themeName) {
JQMCommon.applyTheme(select, themeName);
}
public String getDataWrapper() {
return JQMCommon.getDataWrapper(select);
}
public void setDataWrapper(String wrapper) {
JQMCommon.setDataWrapper(select, wrapper);
}
@Override
public boolean isCorners() {
return JQMCommon.isCorners(select);
}
@Override
public void setCorners(boolean corners) {
JQMCommon.setCorners(select, corners);
}
@Override
public JQMFlip withCorners(boolean corners) {
setCorners(corners);
return this;
}
public String getTrackTheme() {
return trackTheme;
}
/** Sets the theme for the track button */
public void setTrackTheme(String value) {
// data-track-theme is not available for flipswitch, so we have to hack it
trackTheme = value != null ? value.trim() : value;
refreshTrackTheme();
}
private void refreshTrackTheme() {
Element elt = select.getElement();
if (!select.isAttached() || !isReady(elt)) return;
Element par = elt.getParentElement();
if (par == null) return;
Element track = JQMCommon.findChild(par, "ui-flipswitch-on");
if (track != null && JQMCommon.hasStyle(track, "ui-btn")) {
if (trackTheme != null && !trackTheme.isEmpty()) {
track.removeClassName("ui-btn-inherit");
JQMButton.setTheme(track, trackTheme);
} else {
JQMButton.setTheme(track, "inherit");
track.removeAttribute("data-theme");
}
}
}
private static native void bindCreated(Element elt, JQMFlip flip) /*-{
$wnd.$(elt).on( 'flipswitchcreate', function( event, ui ) {
[email protected]::created()();
});
}-*/;
private static native void unbindCreated(Element elt) /*-{
$wnd.$(elt).off( 'flipswitchcreate' );
}-*/;
private void created() {
refreshTrackTheme();
}
@Override
protected void onLoad() {
super.onLoad();
if (trackTheme != null && !trackTheme.isEmpty()) {
bindCreated(getElement(), this);
}
}
@Override
protected void onUnload() {
unbindCreated(getElement());
super.onUnload();
}
}