Created
June 17, 2019 13:53
-
-
Save johnspackman/6ee9ddb793547b8f4ff78d5f7c341e7d to your computer and use it in GitHub Desktop.
Example input field with button
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"searchfield": { | |
include: "textfield", | |
style: function(states, style) { | |
style = qx.lang.Object.clone(style); | |
style.padding = 0; | |
style.margin = 0; | |
return style; | |
} | |
}, | |
"searchfield/field": { | |
style: function(states, style) { | |
return { | |
padding: 0, | |
margin: 2 | |
}; | |
} | |
}, | |
"inlinebutton" : { | |
alias : "atom", | |
style : function(states) { | |
return { | |
padding: 2, | |
margin: 0, | |
decorator : states.pressed | |
|| (states.checked && !states.hovered) | |
|| (states.checked && states.disabled) ? "inlinebutton-checked" | |
: states.hovered && !states.disabled ? "inlinebutton-hovered" | |
: undefined | |
}; | |
} | |
}, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Presents a search field, with an inline search button at the right hand end, | |
* fires a "search" event when the user pressed Enter or clicks the button. | |
* Optional timeout is used to fire the search event after a period of | |
* inactivity, although the search event is only fired by timeout if the value | |
* is different to the last search event. | |
*/ | |
qx.Class.define("grasshopper.af.ui.SearchField", { | |
extend: qx.ui.core.Widget, | |
implement: [ qx.ui.form.IStringForm, qx.ui.form.IForm ], | |
include: [ qx.ui.form.MForm ], | |
construct: function() { | |
this.base(arguments); | |
this._setLayout(new qx.ui.layout.HBox()); | |
this._add(this.getChildControl("field"), { | |
flex: 1 | |
}); | |
this._add(this.getChildControl("buttons")); | |
this.__timeout = new grasshopper.utils.Timeout(0, this._onInactivityTimeout, this); | |
this.bind("timeout", this.__timeout, "duration"); | |
this.addListenerOnce("appear", function(evt) { | |
if (this.isAllowEmptyValue()) | |
this.__doSearch(); | |
}, this); | |
}, | |
properties: { | |
/** Alignment of the text */ | |
textAlign: { | |
check: [ "left", "center", "right" ], | |
nullable: true, | |
themeable: true, | |
apply: "_applyXxxx" | |
}, | |
/** Whether the field is read only */ | |
readOnly: { | |
check: "Boolean", | |
apply: "_applyXxxx", | |
event: "changeReadOnly", | |
init: false | |
}, | |
/** Maximal number of characters that can be entered in the TextArea. */ | |
maxLength: { | |
check: "PositiveInteger", | |
apply: "_applyXxxx", | |
init: Infinity | |
}, | |
/** | |
* Whether the {@link #changeValue} event should be fired on every key | |
* input. If set to true, the changeValue event is equal to the | |
* {@link #input} event. | |
*/ | |
liveUpdate: { | |
check: "Boolean", | |
init: false, | |
apply: "_applyXxxx" | |
}, | |
/** | |
* String value which will be shown as a hint if the field is all of: unset, | |
* unfocused and enabled. Set to null to not show a placeholder text. | |
*/ | |
placeholder: { | |
check: "String", | |
nullable: true, | |
apply: "_applyXxxx" | |
}, | |
/** | |
* RegExp responsible for filtering the value of the textfield. the RegExp | |
* gives the range of valid values. The following example only allows digits | |
* in the textfield. | |
* | |
* <pre class='javascript'> | |
* field.setFilter(/[0-9]/); | |
* </pre> | |
*/ | |
filter: { | |
check: "RegExp", | |
nullable: true, | |
init: null, | |
apply: "_applyXxxx" | |
}, | |
/** Inactivity timeout (milliseconds) */ | |
timeout: { | |
check: "Number", | |
init: 500, | |
nullable: false, | |
event: "changeTimeout" | |
}, | |
/** Whether the auto search should fire if the field is empty */ | |
allowEmptyValue: { | |
check: "Boolean", | |
init: true, | |
nullable: false, | |
event: "changeAllowEmptyValue" | |
}, | |
// overridden | |
appearance: { | |
refine: true, | |
init: "searchfield" | |
}, | |
// overridden | |
allowGrowY: { | |
refine: true, | |
init: false | |
}, | |
// overridden | |
allowShrinkY: { | |
refine: true, | |
init: false | |
} | |
}, | |
events: { | |
/** | |
* Fired when the search button is clicked, data is the value | |
*/ | |
"search": "qx.event.type.Data", | |
/** | |
* The event is fired on every keystroke modifying the value of the field. | |
* | |
* The method {@link qx.event.type.Data#getData} returns the current value | |
* of the text field. | |
*/ | |
"input": "qx.event.type.Data", | |
/** | |
* The event is fired each time the text field looses focus and the text | |
* field values has changed. | |
* | |
* If you change {@link #liveUpdate} to true, the changeValue event will be | |
* fired after every keystroke and not only after every focus loss. In that | |
* mode, the changeValue event is equal to the {@link #input} event. | |
* | |
* The method {@link qx.event.type.Data#getData} returns the current text | |
* value of the field. | |
*/ | |
"changeValue": "qx.event.type.Data" | |
}, | |
members: { | |
__timeout: null, | |
__lastSearchValue: null, | |
/** | |
* Callback for inactivity timeout | |
*/ | |
_onInactivityTimeout: function(evt) { | |
if (!this.__lastSearchValue || this.__lastSearchValue != this.getValue()) | |
this.__doSearch(); | |
}, | |
/** | |
* Callback for any keypress | |
* | |
* @param evt | |
*/ | |
__onKeyPress: function(evt) { | |
if (evt.getKeyIdentifier() == "Enter") { | |
this.__timeout.killTimer(); | |
this.__doSearch(); | |
} else | |
this.__timeout.resetTimer(); | |
}, | |
/** | |
* Callback for keypress which caused input | |
* | |
* @param evt | |
*/ | |
__onKeyInput: function(evt) { | |
this.__timeout.resetTimer(); | |
}, | |
/** | |
* Callback for a timeout | |
* | |
* @param userData | |
* @param timerId | |
*/ | |
__doSearch: function(userData, timerId) { | |
var str = this.getValue(); | |
this.debug("__doSearch: str=" + str + " getValue=" + this.getValue()); | |
if (!str) | |
str = ""; | |
this.setValue(str); | |
if (str || this.isAllowEmptyValue()) { | |
this.__lastSearchValue = str; | |
this.fireDataEvent("search", str); | |
} | |
}, | |
/** | |
* ApplyXxxx | |
*/ | |
_applyXxxx: function(value, oldValue, name) { | |
this.getChildControl("field")["set" + qx.lang.String.firstUp(name)](value); | |
}, | |
/** | |
* set accessor for psuedo property | |
*/ | |
setValue: function(value) { | |
this.__timeout.killTimer(); | |
return this.getChildControl("field").setValue(value); | |
}, | |
/** | |
* get accessor for psuedo property | |
*/ | |
getValue: function() { | |
var str = this.getChildControl("field").getValue(); | |
if (str) { | |
str = str.trim(); | |
if (!str.length) | |
return null; | |
} | |
return str; | |
}, | |
/** | |
* reset accessor for psuedo property | |
*/ | |
resetValue: function() { | |
this.__timeout.killTimer(); | |
return this.getChildControl("field").resetValue(); | |
}, | |
/* | |
* @Override | |
*/ | |
_createChildControlImpl: function(id, hash) { | |
switch (id) { | |
case "field": | |
var fld = new qx.ui.form.TextField; | |
fld.addListener("input", function(evt) { | |
this.fireDataEvent("input", evt.getData()); | |
}, this); | |
fld.addListener("changeValue", function(evt) { | |
this.fireDataEvent("changeValue", evt.getData()); | |
}, this); | |
fld.addListener("keypress", this.__onKeyPress, this); | |
fld.addListener("keyinput", this.__onKeyInput, this); | |
return fld; | |
case "buttons": | |
var comp = new qx.ui.container.Composite(new qx.ui.layout.HBox()); | |
comp.add(this.getChildControl("btnSearch")); | |
return comp; | |
case "btnSearch": | |
var btn = new grasshopper.af.ui.SearchFieldButton("Search", "grasshopper/icon/16/search.png"); | |
btn.addListener("execute", this.__doSearch, this); | |
return btn; | |
} | |
return this.base(arguments, id, hash); | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment