It comes close, yes, but on EyeOS we have more than 20 SearchFields and they
increase as you open more apps. So copy-paste this code will not solve the
problem, that's why I created a widget.

I don't want a composit, I need a widget with the same API and functionality
as the TextField, plus a clickable image (the original idea was to use a IMG
element as button because I just need the click event, nothing else)
configurable by a new property.

Maybe a better example is the Sprite class I talked before, I don't want to
add widgets to the image, I want to change a little bit its behaviour. I
just want a class who has Image API and Image behaviour, but just with two
more properties and overwrite a few methods to use the new properties. So
the most correct way to do it than I can see is OO inheritance.

I know there are so many ways to do the same on programming, I just want to
highlight the way getContentElement is used on TextField and Image.

---
Seldaiendil



2011/10/5 thron7 <[email protected]>

> **
> I think you are mixing OO inheritance with composition. You want to create
> a composit, but still retain the API as if it were a child class (which
> certainly is not what OO inheritance is about).
>
> You might want to look at the implementation of the search field in the
> Demobrowser. In demobrowser.DemoBrowser, you find code starting with
>
>     // search
>     var searchComposlite = new qx.ui.container.Composite();
>     searchComposlite.setLayout(new qx.ui.layout.HBox(3));
>     searchComposlite.setAppearance("textfield");
>     leftComposite.add(searchComposlite);
>
>     var searchIcon = new
> qx.ui.basic.Image("icon/16/actions/edit-find.png");
>     searchComposlite.add(searchIcon);
>
>     this._searchTextField = new qx.ui.form.TextField();
>     this._searchTextField.setLiveUpdate(true);
>     this._searchTextField.setAppearance("widget");
>     this._searchTextField.setPlaceholder("Filter...");
>
>     ...
>
> That comes probably close to what you want to achieve.
>
> T.
>
>
>
> On 10/05/2011 01:15 PM, Seldaiendil D. Flourite wrote:
>
> Hi Tron, thanks for the response,
>
>  Yes, I did it this way because I found no other way to do it. But you
> think it's ok to have to wrap (this is create a *getValue* method to call
> the *TextField* *getValue* method) all *TextField* methods? There are so
> many, why I have to create so many dummy methods instead of focus on the
> development I have to do?
>
>  Isn't it against *Object Oriented* that I cannot inherit from *TextField*and 
> modify it's structure? I found it is again its fur to use
> *getContentElement*() and expect it to be the DOM INPUT, I found it's
> overload the *getContentElement* with two responsabilities: Return the
> content element and return the INPUT element, than in the current code are
> the same element, but someday it can change.
>
>  I mean, I don't see right, for example, to add a listener '*change*' to
> the element returned by *getContentElement*() why if someday someones
> changes the content element? why not add the '*change*' listener directly
> where we want to add it, to the INPUT element.
>
>  And as I understand, *Object Oriented Programming* is a elegant way to
> reuse code, I don't see here to reuse code nor elegant code.
> *
> *
> Here is how my *SearchField* class looks like:
>
>   - My code with spaces: ~*145* lines
>  - Fake inheritace from TextField: ~*170* lines
>
>  -------------------------------------------------------------
>
>
>  qx.Class.define("eyeos.ui.form.SearchField",
> {
>  extend : qx.ui.core.Widget,
>
>  construct : function(value, icon)
>  {
>  this.base(arguments);
>   this._timer = new qx.event.Timer(0);
>  this._timer.addListener('interval', this.__fireExecuteEvent, this);
>
>  this._setLayout(new qx.ui.layout.HBox);
>
>  // Create childs if they doesn't exist
>   this.getChildControl('input');
>  this.getChildControl('button');
>  },
>
>
>  events :
>  {
>  /**
>  * The event is fired when the user press enter key inside the field
>   */
>  'execute': "qx.event.type.Data",
>
>
>  /**
>  * The event is fired on every keystroke modifying the value of the field.
>  */
>  'change': "qx.event.type.Data",
>
>  /**
>  * The event is fired when the user clicks the remove button and clears
> the textfield
>  */
>  'clear': "qx.event.type.Data"
>  },
>
>
>  properties :
>  {
>  appearance: {
>  refine: true,
>  init: "searchfield"
>  },
>  icon: {
>  check: "String",
>  apply: "_applyIcon",
>  nullable: true,
>  themeable: true,
>  event: "changeIcon"
>  },
>  showButton: {
>  check: "Boolean",
>  themeable: true,
>  init: true
>  },
>  delay: {
>  check: "Number",
>  apply: "_applyDelay",
>  nullable: false,
>  init: 0
>  }
>  },
>
>
>  members :
>  {
>  _timer: null,
>
>
>  _updateClearButton: function() {
>  // If button can be showed and input is empty
>  if (this.getShowButton() && !!this.getChildControl('input').getValue()) {
>  this.getChildControl('button').show();
>  } else {
>  this.getChildControl('button').exclude();
>  }
>  },
>   _clearField: function() {
>  this.getChildControl('input').setValue("")
>  this._updateClearButton();
>  this.fireDataEvent('clear');
>  this.__fireExecuteEvent();
>  },
>
>
>  __fireExecuteEvent: function() {
>  this._timer.stop();
>  var value = this.getChildControl('input').getValue();
>  this.fireDataEvent('change', value);
>  this.fireDataEvent('execute', value);
>  },
>
>  __inputKeydown: function(e) {
>  if (e.getKeyIdentifier() === 'Enter') {
>  this.__fireExecuteEvent();
>  }
>  },
>
>  __inputChange: function(e) {
>  this._updateClearButton();
>  this.fireDataEvent('change', e.getData(), e.getOldData());
>  this.__scheduleDelayedEvent();
>  },
>
>  __scheduleDelayedEvent: function() {
>  if (this.getDelay() === 0)
>  return;
>   this._timer.restart();
>  },
>   // properties
>  _applyIcon: function(value) {
>  this.getChildControl('button').setIcon(value);
>  },
>  _applyDelay: function(value) {
>  this._timer.setInterval(value);
>  },
>
>  // overridden
>  _createChildControlImpl: function(id, hash)
>  {
>  var control;
>
>  switch(id) {
>  case "input":
>  control = new qx.ui.form.TextField;
>  control.addListener('keydown', this.__inputKeydown, this);
>  control.addListener('input', this.__inputChange, this);
>  this._add(control, { flex: 1 });
>  break;
>   case "button":
>  control = new qx.ui.toolbar.Button;
>  control.addListener('execute', this._clearField, this);
>  control.exclude();
>  this._add(control);
>  }
>
>  return control || this.base(arguments, id);
>  },
>
>
>  /**
>  * Fake inheritance
>  */
>  // Implement and include same Interfaces and Mixins as TextField to full
> compatibility
>  implement: [ qx.ui.form.IStringForm, qx.ui.form.IForm ],
>  include: [ qx.ui.form.MForm ]
>  // Propagate TextField events
>  __propagateDataEvent: function(event) {
>  this.fireDataEvent(event.getName(), event.getData(), event.getOldData());
>  },
>  __propagateTextFieldEvents: function() {
>  var input = this.getChildControl('input');
>  input.addListener('changeInvalidMessage', this.__propagateDataEvent,
> this);
>  input.addListener('changeReadOnly', this.__propagateDataEvent, this);
>  input.addListener('changeRequired', this.__propagateDataEvent, this);
>  input.addListener('changeValid', this.__propagateDataEvent, this);
>  input.addListener('changeValue', this.__propagateDataEvent, this);
>  }
>  // TextField wrappers
>  clearTextSelection: function() {
>  return this.getChildControl('input').clearTextSelection();
>  },
>  getFilter: function() {
>  return this.getChildControl('input').getFilter();
>  },
>  getFocusElement: function() {
>  return this.getChildControl('input').getFocusElement();
>  },
>  getInvalidMessage: function() {
>  return this.getChildControl('input').getInvalidMessage();
>  },
>  getLiveUpdate: function() {
>  return this.getChildControl('input').getLiveUpdate();
>  },
>  getMaxLength: function() {
>  return this.getChildControl('input').getMaxLength();
>  },
>  getPlaceholder: function() {
>  return this.getChildControl('input').getPlaceholder();
>  },
>  clearTextSelection: function() {
>  return this.getChildControl('input').clearTextSelection();
>  },
>  getReadOnly: function() {
>  return this.getChildControl('input').getReadOnly();
>  },
>  getRequired: function() {
>  return this.getChildControl('input').getRequired();
>  },
>  getRequiredInvalidMessage: function() {
>  return this.getChildControl('input').getRequiredInvalidMessage();
>  },
>  getTextAlign: function() {
>  return this.getChildControl('input').getTextAlign();
>  },
>  getTextSelection: function() {
>  return this.getChildControl('input').getTextSelection();
>  },
>  getTextSelectionEnd: function() {
>  return this.getChildControl('input').getTextSelectionEnd();
>  },
>  getTextSelectionLength: function() {
>  return this.getChildControl('input').getTextSelectionLength();
>  },
>  getTextSelectionStart: function() {
>  return this.getChildControl('input').getTextSelectionStart();
>  },
>  getValid: function() {
>  return this.getChildControl('input').getValid();
>  },
>  getValue: function() {
>  return this.getChildControl('input').getValue();
>  },
>  isLiveUpdate: function() {
>  return this.getChildControl('input').isLiveUpdate();
>  },
>  isReadOnly: function() {
>  return this.getChildControl('input').isReadOnly();
>  },
>  isRequired: function() {
>  return this.getChildControl('input').isRequired();
>  },
>  isValid: function() {
>  return this.getChildControl('input').isValid();
>  },
>  resetFilter: function() {
>  return this.getChildControl('input').resetFilter();
>  },
>  resetInvalidMessage: function() {
>  return this.getChildControl('input').resetInvalidMessage();
>  },
>  resetLiveUpdate: function() {
>  return this.getChildControl('input').resetLiveUpdate();
>  },
>  resetMaxLength: function() {
>  return this.getChildControl('input').resetMaxLength();
>  },
>  resetPlaceholder: function() {
>  return this.getChildControl('input').resetPlaceholder();
>  },
>  resetReadOnly: function() {
>  return this.getChildControl('input').resetReadOnly();
>  },
>  resetRequired: function() {
>  return this.getChildControl('input').resetRequired();
>  },
>  resetRequiredInvalidMessage: function() {
>  return this.getChildControl('input').resetRequiredInvalidMessage();
>  },
>  resetTextAlign: function() {
>  return this.getChildControl('input').resetTextAlign();
>  },
>  resetValid: function() {
>  return this.getChildControl('input').resetValid();
>  },
>  resetValue: function() {
>  return this.getChildControl('input').resetValue();
>  },
>  selectAllText: function() {
>  return this.getChildControl('input').selectAllText();
>  },
>  setFilter: function(value) {
>  return this.getChildControl('input').setFilter(value);
>  },
>  setInvalidMessage: function(value) {
>  return this.getChildControl('input').setInvalidMessage(value);
>  },
>  setLiveUpdate: function(value) {
>  return this.getChildControl('input').setLiveUpdate(value);
>  },
>  setMaxLength: function(value) {
>  return this.getChildControl('input').setMaxLength(value);
>  },
>  setPlaceholder: function(value) {
>  return this.getChildControl('input').setPlaceholder(value);
>  },
>  setReadOnly: function(value) {
>  return this.getChildControl('input').setReadOnly(value);
>  },
>  setRequired: function(value) {
>  return this.getChildControl('input').setRequired(value);
>  },
>  setRequiredInvalidMessage: function(value) {
>  return this.getChildControl('input').setRequiredInvalidMessage(value);
>  },
>  setTextAlign: function(value) {
>  return this.getChildControl('input').setTextAlign(value);
>  },
>  setTextSelection: function(value) {
>  return this.getChildControl('input').setTextSelection(value);
>  },
>  setValid: function(value) {
>  return this.getChildControl('input').setValid(value);
>  },
>  setValue: function(value) {
>  return this.getChildControl('input').setValue(value);
>  },
>  toggleLiveUpdate: function() {
>  return this.getChildControl('input').toggleLiveUpdate();
>  },
>  toggleReadOnly: function() {
>  return this.getChildControl('input').toggleReadOnly();
>  },
>  toggleRequired: function() {
>  return this.getChildControl('input').toggleRequired();
>  },
>  toggleValid: function() {
>  return this.getChildControl('input').toggleValid();
>  }
>  }
> });
>
>
> ------------------------------------------------------------------------------
> All the data continuously generated in your IT infrastructure contains a
> definitive record of customers, application performance, security
> threats, fraudulent activity and more. Splunk takes this data and makes
> sense of it. Business sense. IT sense. Common 
> sense.http://p.sf.net/sfu/splunk-d2dcopy1
>
>
> _______________________________________________
> qooxdoo-devel mailing 
> [email protected]https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel
>
>
>
> ------------------------------------------------------------------------------
> All the data continuously generated in your IT infrastructure contains a
> definitive record of customers, application performance, security
> threats, fraudulent activity and more. Splunk takes this data and makes
> sense of it. Business sense. IT sense. Common sense.
> http://p.sf.net/sfu/splunk-d2dcopy1
> _______________________________________________
> qooxdoo-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel
>
>
------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure contains a
definitive record of customers, application performance, security
threats, fraudulent activity and more. Splunk takes this data and makes
sense of it. Business sense. IT sense. Common sense.
http://p.sf.net/sfu/splunk-d2dcopy1
_______________________________________________
qooxdoo-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel

Reply via email to