扩展 Shopware Emotion 横幅滑块
Extend Shopware Emotion Banner Slider
我们尝试在 Shopware 中为情感创建自定义横幅滑块。此自定义横幅源自标准情感横幅滑块,并向其添加了一些额外的列。一切正常,没有错误,但是,模型被完全忽略,即来自网格的数据没有保存,所以 add/save 事件没有被触发。 (此问题出现 here 德文)
这是我们的 ExtJS 组件:
/**
* ExtJS Component for Media Widget Plugin
*/
Ext.define('Shopware.apps.Emotion.view.components.AdvancedBannerSlider', {
/**
* Extend from the base emotion component.
*/
extend: 'Shopware.apps.Emotion.view.components.BannerSlider',
/**
* Set the defined xtype of the component as the new widget alias.
*/
alias: 'widget.emotion-components-advancedbannerslider',
/**
* Snippets for the component.
* @object
*/
snippets: {
'select_banner': '{s name=select_banner}Select banner(s){/s}',
'banner_administration': '{s name=banner_administration}Banner administration{/s}',
'path': '{s name=path}Image path{/s}',
'actions': '{s name=actions}Action(s){/s}',
'link': '{s name=link}Link{/s}',
'altText': '{s name=altText}Alternative text{/s}',
'title': '{s name=title}Title{/s}',
'size': '{s name=size}Größe{/s}',
'cols': '{s name=cols}Spalten{/s}',
'filter': '{s name=filter}Filter{/s}',
banner_slider_title: '{s name=banner_slider_title}Title{/s}',
banner_slider_arrows: '{s name=banner_slider_arrows}Display arrows{/s}',
banner_slider_numbers: {
fieldLabel: '{s name=banner_slider_numbers/label}Display numbers{/s}',
supportText: '{s name=banner_slider_numbers/support}Please note that this setting only affects the "emotion" template.{/s}'
},
banner_slider_scrollspeed: '{s name=banner_slider_scrollspeed}Scroll speed{/s}',
banner_slider_rotation: '{s name=banner_slider_rotation}Rotate automatically{/s}',
banner_slider_rotatespeed: '{s name=banner_slider_rotatespeed}Rotation speed{/s}'
},
/**
* Creates the fieldset which holds the banner administration. The method
* also creates the banner store and registers the drag and drop plugin
* for the grid.
*
* @public
* @return [object] Ext.form.FieldSet
*/
createBannerFieldset: function() {
var me = this;
me.mediaSelection = Ext.create('Shopware.form.field.MediaSelection', {
fieldLabel: me.snippets.select_banner,
labelWidth: 155,
albumId: -3,
listeners: {
scope: me,
selectMedia: me.onAddBannerToGrid
}
});
me.bannerStore = Ext.create('Ext.data.Store', {
fields: [ 'position', 'path', 'link', 'altText', 'title', 'mediaId', 'size', 'cols', 'filter' ]
});
me.ddGridPlugin = Ext.create('Ext.grid.plugin.DragDrop');
me.cellEditing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 2
});
me.bannerGrid = Ext.create('Ext.grid.Panel', {
columns: me.createColumns(),
autoScroll: true,
store: me.bannerStore,
height: 200,
plugins: [ me.cellEditing ],
viewConfig: {
plugins: [ me.ddGridPlugin ],
listeners: {
scope: me,
drop: me.onRepositionBanner
}
},
listeners: {
scope: me,
edit: function() {
me.refreshHiddenValue();
}
}
});
return me.bannerFieldset = Ext.create('Ext.form.FieldSet', {
title: me.snippets.banner_administration,
layout: 'anchor',
defaults: { anchor: '100%' },
items: [ me.mediaSelection, me.bannerGrid ]
});
},
/**
* Helper method which creates the column model
* for the banner administration grid panel.
*
* @public
* @return [array] computed columns
*/
createColumns: function() {
var me = this, snippets = me.snippets;
return [{
header: '⚌',
width: 24,
hideable: false,
renderer : me.renderSorthandleColumn
}, {
dataIndex: 'path',
header: snippets.path,
flex: 1
}, {
dataIndex: 'link',
header: snippets.link,
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: true
}
}, {
dataIndex: 'altText',
header: snippets.altText,
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: true
}
}, {
dataIndex: 'title',
header: snippets.title,
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: true
}
}, {
dataIndex: 'size',
header: snippets.size,
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: true
}
}, {
dataIndex: 'cols',
header: snippets.cols,
flex: 1,
editor: {
xtype: 'numberfield',
allowBlank: true,
minValue: 1,
decimalPrecision: 0
}
}, {
dataIndex: 'filter',
header: snippets.filter,
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: true
}
}, {
xtype: 'actioncolumn',
header: snippets.actions,
width: 60,
items: [{
iconCls: 'sprite-minus-circle',
action: 'delete-banner',
scope: me,
handler: me.onDeleteBanner
}]
}];
},
/**
* Event listener method which will be triggered when one (or more)
* banner are added to the banner slider.
*
* Creates new models based on the selected banners and
* assigns them to the banner store.
*
* @public
* @event selectMedia
* @param [object] field - Shopware.MediaManager.MediaSelection
* @param [array] records - array of the selected media
*/
onAddBannerToGrid: function(field, records) {
var me = this, store = me.bannerStore;
Ext.each(records, function(record) {
var count = store.getCount();
var model = Ext.create('Shopware.apps.Emotion.model.AdvancedBannerSliderModel', {
position: count,
path: record.get('path'),
mediaId: record.get('id'),
link: record.get('link'),
altText: record.get('altText'),
title: record.get('title'),
size: record.get('size'),
cols: record.get('cols'),
filter: record.get('filter')
});
store.add(model);
});
// We need a defer due to early firing of the event
Ext.defer(function() {
me.mediaSelection.inputEl.dom.value = '';
me.refreshHiddenValue();
}, 10);
},
getGridData: function() {
var me = this,
elementStore = me.getSettings('record').get('data'), advancedBannerSlider;
Ext.each(elementStore, function(element) {
if(element.key === 'advanced_banner_slider') {
advancedBannerSlider = element;
return false;
}
});
if(advancedBannerSlider && advancedBannerSlider.value) {
Ext.each(bannerSlider.value, function(item) {
me.bannerStore.add(Ext.create('Shopware.apps.Emotion.model.AdvancedBannerSliderModel', item));
});
}
},
});
//{block name="backend/emotion/controller/massive_widgets"}
//{namespace name=backend/emotion/controller}
Ext.define('Shopware.apps.Emotion.controller.AdvancedBannerSlider', {
/**
* Defines an override applied to a class.
* @string
*/
extend: 'Shopware.apps.Emotion.controller.Detail'
});
//{/block}
/**
* Shopware Model - Emotion backend module.
*/
//{block name="backend/emotion/model/banner_slider"}
Ext.define('Shopware.apps.Emotion.model.AdvancedBannerSliderModel', {
/**
* Extends the standard Ext Model
* @string
*/
extend: 'Shopware.apps.Emotion.model.BannerSlider',
/**
* The fields used for this model
* @array
*/
fields: [
//{block name="backend/emotion/model/field/banner_slider"}{/block}
'position', 'path', 'mediaId', 'link', 'altText', 'title', 'size', 'cols', 'filter'
]
});
//{/block}
这是我们插件的结构:
所以如果有必要我可以提供一个 GitLab link。提前致谢!
感谢大家的帮助!问题是 json 格式的横幅滑块的隐藏字段被遗漏了,它给模型带来了数据。所以,解决方案:
1. 将此字段添加到新组件
$element = $installer->createOrUpdate(
$this->getName(),
'advancedbannerslider',
[
'name' => 'advancedbannerslider',
'xtype' => 'emotion-advanced-banner-slider',
'template' => 'emotion_advanced_banner_slider',
'cls' => 'emotion_advanced_banner_slider',
'description' => 'advancedbannerslider'
]
);
$element->createHiddenField([
'name' => 'banner_slider',
'valueType' => 'json',
]);
- 对上面的代码进行一些调整:
alias: 'widget.emotion-advanced-banner-slider',
和
getGridData: function() {
var me = this,
elementStore = me.getSettings('record').get('data'), bannerSlider;
Ext.each(elementStore, function(element) {
if(element.key === 'banner_slider') {
bannerSlider = element;
return false;
}
});
if(bannerSlider && bannerSlider.value) {
Ext.each(bannerSlider.value, function(item) {
me.bannerStore.add(Ext.create('Shopware.apps.Emotion.model.AdvancedBannerSliderModel', item));
});
}
},
我们尝试在 Shopware 中为情感创建自定义横幅滑块。此自定义横幅源自标准情感横幅滑块,并向其添加了一些额外的列。一切正常,没有错误,但是,模型被完全忽略,即来自网格的数据没有保存,所以 add/save 事件没有被触发。 (此问题出现 here 德文) 这是我们的 ExtJS 组件:
/**
* ExtJS Component for Media Widget Plugin
*/
Ext.define('Shopware.apps.Emotion.view.components.AdvancedBannerSlider', {
/**
* Extend from the base emotion component.
*/
extend: 'Shopware.apps.Emotion.view.components.BannerSlider',
/**
* Set the defined xtype of the component as the new widget alias.
*/
alias: 'widget.emotion-components-advancedbannerslider',
/**
* Snippets for the component.
* @object
*/
snippets: {
'select_banner': '{s name=select_banner}Select banner(s){/s}',
'banner_administration': '{s name=banner_administration}Banner administration{/s}',
'path': '{s name=path}Image path{/s}',
'actions': '{s name=actions}Action(s){/s}',
'link': '{s name=link}Link{/s}',
'altText': '{s name=altText}Alternative text{/s}',
'title': '{s name=title}Title{/s}',
'size': '{s name=size}Größe{/s}',
'cols': '{s name=cols}Spalten{/s}',
'filter': '{s name=filter}Filter{/s}',
banner_slider_title: '{s name=banner_slider_title}Title{/s}',
banner_slider_arrows: '{s name=banner_slider_arrows}Display arrows{/s}',
banner_slider_numbers: {
fieldLabel: '{s name=banner_slider_numbers/label}Display numbers{/s}',
supportText: '{s name=banner_slider_numbers/support}Please note that this setting only affects the "emotion" template.{/s}'
},
banner_slider_scrollspeed: '{s name=banner_slider_scrollspeed}Scroll speed{/s}',
banner_slider_rotation: '{s name=banner_slider_rotation}Rotate automatically{/s}',
banner_slider_rotatespeed: '{s name=banner_slider_rotatespeed}Rotation speed{/s}'
},
/**
* Creates the fieldset which holds the banner administration. The method
* also creates the banner store and registers the drag and drop plugin
* for the grid.
*
* @public
* @return [object] Ext.form.FieldSet
*/
createBannerFieldset: function() {
var me = this;
me.mediaSelection = Ext.create('Shopware.form.field.MediaSelection', {
fieldLabel: me.snippets.select_banner,
labelWidth: 155,
albumId: -3,
listeners: {
scope: me,
selectMedia: me.onAddBannerToGrid
}
});
me.bannerStore = Ext.create('Ext.data.Store', {
fields: [ 'position', 'path', 'link', 'altText', 'title', 'mediaId', 'size', 'cols', 'filter' ]
});
me.ddGridPlugin = Ext.create('Ext.grid.plugin.DragDrop');
me.cellEditing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 2
});
me.bannerGrid = Ext.create('Ext.grid.Panel', {
columns: me.createColumns(),
autoScroll: true,
store: me.bannerStore,
height: 200,
plugins: [ me.cellEditing ],
viewConfig: {
plugins: [ me.ddGridPlugin ],
listeners: {
scope: me,
drop: me.onRepositionBanner
}
},
listeners: {
scope: me,
edit: function() {
me.refreshHiddenValue();
}
}
});
return me.bannerFieldset = Ext.create('Ext.form.FieldSet', {
title: me.snippets.banner_administration,
layout: 'anchor',
defaults: { anchor: '100%' },
items: [ me.mediaSelection, me.bannerGrid ]
});
},
/**
* Helper method which creates the column model
* for the banner administration grid panel.
*
* @public
* @return [array] computed columns
*/
createColumns: function() {
var me = this, snippets = me.snippets;
return [{
header: '⚌',
width: 24,
hideable: false,
renderer : me.renderSorthandleColumn
}, {
dataIndex: 'path',
header: snippets.path,
flex: 1
}, {
dataIndex: 'link',
header: snippets.link,
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: true
}
}, {
dataIndex: 'altText',
header: snippets.altText,
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: true
}
}, {
dataIndex: 'title',
header: snippets.title,
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: true
}
}, {
dataIndex: 'size',
header: snippets.size,
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: true
}
}, {
dataIndex: 'cols',
header: snippets.cols,
flex: 1,
editor: {
xtype: 'numberfield',
allowBlank: true,
minValue: 1,
decimalPrecision: 0
}
}, {
dataIndex: 'filter',
header: snippets.filter,
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: true
}
}, {
xtype: 'actioncolumn',
header: snippets.actions,
width: 60,
items: [{
iconCls: 'sprite-minus-circle',
action: 'delete-banner',
scope: me,
handler: me.onDeleteBanner
}]
}];
},
/**
* Event listener method which will be triggered when one (or more)
* banner are added to the banner slider.
*
* Creates new models based on the selected banners and
* assigns them to the banner store.
*
* @public
* @event selectMedia
* @param [object] field - Shopware.MediaManager.MediaSelection
* @param [array] records - array of the selected media
*/
onAddBannerToGrid: function(field, records) {
var me = this, store = me.bannerStore;
Ext.each(records, function(record) {
var count = store.getCount();
var model = Ext.create('Shopware.apps.Emotion.model.AdvancedBannerSliderModel', {
position: count,
path: record.get('path'),
mediaId: record.get('id'),
link: record.get('link'),
altText: record.get('altText'),
title: record.get('title'),
size: record.get('size'),
cols: record.get('cols'),
filter: record.get('filter')
});
store.add(model);
});
// We need a defer due to early firing of the event
Ext.defer(function() {
me.mediaSelection.inputEl.dom.value = '';
me.refreshHiddenValue();
}, 10);
},
getGridData: function() {
var me = this,
elementStore = me.getSettings('record').get('data'), advancedBannerSlider;
Ext.each(elementStore, function(element) {
if(element.key === 'advanced_banner_slider') {
advancedBannerSlider = element;
return false;
}
});
if(advancedBannerSlider && advancedBannerSlider.value) {
Ext.each(bannerSlider.value, function(item) {
me.bannerStore.add(Ext.create('Shopware.apps.Emotion.model.AdvancedBannerSliderModel', item));
});
}
},
});
//{block name="backend/emotion/controller/massive_widgets"}
//{namespace name=backend/emotion/controller}
Ext.define('Shopware.apps.Emotion.controller.AdvancedBannerSlider', {
/**
* Defines an override applied to a class.
* @string
*/
extend: 'Shopware.apps.Emotion.controller.Detail'
});
//{/block}
/**
* Shopware Model - Emotion backend module.
*/
//{block name="backend/emotion/model/banner_slider"}
Ext.define('Shopware.apps.Emotion.model.AdvancedBannerSliderModel', {
/**
* Extends the standard Ext Model
* @string
*/
extend: 'Shopware.apps.Emotion.model.BannerSlider',
/**
* The fields used for this model
* @array
*/
fields: [
//{block name="backend/emotion/model/field/banner_slider"}{/block}
'position', 'path', 'mediaId', 'link', 'altText', 'title', 'size', 'cols', 'filter'
]
});
//{/block}
这是我们插件的结构:
所以如果有必要我可以提供一个 GitLab link。提前致谢!
感谢大家的帮助!问题是 json 格式的横幅滑块的隐藏字段被遗漏了,它给模型带来了数据。所以,解决方案: 1. 将此字段添加到新组件
$element = $installer->createOrUpdate(
$this->getName(),
'advancedbannerslider',
[
'name' => 'advancedbannerslider',
'xtype' => 'emotion-advanced-banner-slider',
'template' => 'emotion_advanced_banner_slider',
'cls' => 'emotion_advanced_banner_slider',
'description' => 'advancedbannerslider'
]
);
$element->createHiddenField([
'name' => 'banner_slider',
'valueType' => 'json',
]);
- 对上面的代码进行一些调整:
alias: 'widget.emotion-advanced-banner-slider',
和
getGridData: function() {
var me = this,
elementStore = me.getSettings('record').get('data'), bannerSlider;
Ext.each(elementStore, function(element) {
if(element.key === 'banner_slider') {
bannerSlider = element;
return false;
}
});
if(bannerSlider && bannerSlider.value) {
Ext.each(bannerSlider.value, function(item) {
me.bannerStore.add(Ext.create('Shopware.apps.Emotion.model.AdvancedBannerSliderModel', item));
});
}
},