Skip to main content

5.2 - attribute field as combobox using custom store

Category: Shopware
shopware-logo

First we need to define our attribute-field as usual.

$service->update(
  's_blog_attributes',
  'my_attribute',
  'integer',
  [
    'label' => 'Label',
    'helpText' => '',
    'translatable' => false,
    'displayInBackend' => true,
    'position' => 1,
    'custom' => true
  ]
);

Now we need to define and load our custom field handler:

$this->subscribeEvent(
  'Enlight_Controller_Action_PostDispatch_Backend_Base',
  'ExtendAttr'
);

...

public function ExtendAttr(Enlight_Event_EventArgs $args)
{
  $view = $args->getSubject()->View();

  $view->addTemplateDir($this->Path() . '/Views/');

  $view->extendsTemplate(
    'backend/attributes/store/my_store.js'
  );

  $view->extendsTemplate(
    'backend/attributes/Form.js'
  );
}

Form.js

//{block name="backend/base/attribute/form"}
//{$smarty.block.parent}

//{include file="backend/MyAttribute/MyAttribute.FieldHandler.js"}

Ext.define('Shopware.attribute.Form-MyAttribute', {
    override: 'Shopware.attribute.Form',

    registerTypeHandlers: function() {
        var handlers = this.callParent(arguments);

        return Ext.Array.insert(handlers, 0, 
        [ Ext.create('MyAttribute.FieldHandler') ]);
    }
});
//{/block}

MyAttribute.FieldHandler.js

//{block name="backend/MyAttribute/FieldHandler"}
Ext.define('MyAttribute.FieldHandler', {

    extend: 'Shopware.attribute.FieldHandlerInterface',

    supports: function(attribute) {
        var name = attribute.get('columnName');
        if (attribute.get('tableName') !== 's_blog_attributes') {
            return false;
        }
        return (name === 'my_attribute');
    },

    create: function(field, attribute) {
        var disyplayField = 'title';
        var store = Ext.create(
                      'Shopware.apps.MyAttribute.store.MyStore'
                    ).load();

        return Ext.apply(field, {
            xtype: 'combobox',
            store: store,
            displayField: disyplayField,
            queryMode: 'local',
            valueField: "id",
            listeners: {
                change: function(field, value)
                {
                    if(value) field.setValue(parseInt(value));
                }
            }
        });
    }
});
//{/block}

The change listener ist taking care that all selected values will be associated correctly if type is integer.