Search code examples
sapui5

Extend control with HBox container and inherited but customized event


The idea is to have a HBox container under the MultiComboBox control to which selected tokens will be pushed. I have followed different tutorials and couldn't get a success. A multiComboBox is simply now shown.

The idea:

enter image description here

Simplified (testing) implementation of custom control:

sap.ui.define([
  'sap/m/MultiComboBox',
  'sap/m/HBox'
], function (MultiComboBox, HBox) {
  'use strict';

  /**
   * Constructor for a new MultiCombobox with tokens.
   */
  return MultiComboBox.extend('drex.control.DropDownWithTags', {
    metadata: {
      aggregations: {
        _tokensContainer: { type: 'sap.m.HBox', multiple: false }
      },
    },

    init: function () {
      MultiComboBox.prototype.init.apply(this, arguments);
      this.setAggregation('_tokensContainer', new HBox());
    },

    _addToken: function () {
      this.getAggregation('_tokensContainer').insertItem({text: 'test'});
    },

    _handleSelectionLiveChange: function(oControlEvent) {
      this._addToken();
      MultiComboBox.prototype._handleSelectionLiveChange.apply(this, arguments);
    },

    renderer: function (rm, DropDownWithTags) {
      rm.write('<div');
      rm.writeControlData(DropDownWithTags);
      rm.write('>');
      rm.renderControl(DropDownWithTags.getAggregation('_tokensContainer'));
      rm.write('</div>');
    }
  });
});

XML (no change, except for a name, could that be a problem?). Adding HBox aggregation to it does not help.

<drex:DropDownWithTags
    items="{
            path: 'diseaseList>/allDiseases'
    }"
    selectedKeys="{filterModel>/disease}"
    selectionFinish="onSelectDisease">
    <core:Item key="{diseaseList>id}" text="{diseaseList>Name}"/>
</drex:DropDownWithTags>

Any idea why it happens ? I cannot see my mistake.


Solution

  • there are many ways to do this. here is one way

    sap.ui.define([
        'sap/ui/core/Control',
        'sap/ui/core/Item',
        'sap/m/MultiComboBox',
        'sap/m/HBox',
        'sap/m/Text'
        ], function (Control, Item, MultiComboBox, HBox, Text) {
        Control.extend('DropDownWithTags', {
            metadata: {
            aggregations: {
                combo: { type: 'sap.m.MultiComboBox', multiple: false },
                _hbox: { type: 'sap.m.HBox', multiple: false }
            },
            },
    
            init: function () {
            Control.prototype.init.apply(this, arguments);
            this.setAggregation('_hbox', new HBox({
                items: [
                ]
            }));
            },
    
            renderer: function (rm, oControl) {
            rm.write('<div');
            rm.writeControlData(oControl);
            rm.write('>');
            rm.write('<div>');
            rm.renderControl(oControl.getAggregation('combo'));
            rm.write('</div>');
            rm.write('<div>');
            rm.renderControl(oControl.getAggregation('_hbox'));
            rm.write('</div>');
            rm.write('</div>');
            },
    
            onAfterRendering: function() {
            var combo = this.getAggregation('combo')
            var hbox = this.getAggregation('_hbox');
            combo.attachEvent("selectionChange", function() {
                hbox.destroyItems();
                var text = this.getSelectedItems().map(function(item) {
                return item.getText();
                });
                if (text.length > 0) {
                hbox.addItem(new Text({ text: text.join(",")}))
                }
            })
            }
        });
    
        var combo = new DropDownWithTags({
            combo: new MultiComboBox({
            items: [
                new Item({
                key: "test",
                text: "test"
                }),
                new Item({
                key: "test1",
                text: "test1"
                })
            ]
            })
        });
        combo.placeAt("content")
    });